From 9d481aaaf3e80df942104a706dcff7bea3b04485 Mon Sep 17 00:00:00 2001
From: zhipin <zhipin.deng@bytedance.com>
Date: Mon, 23 Nov 2020 12:31:14 +0800
Subject: [PATCH] JVET-S0176-Item5: constrain the value of
 sps_num_subpics_minus1 when SLI SEI shows up

---
 .gitlab-ci.yml                                |   10 +-
 CMakeLists.txt                                |   16 -
 COPYING                                       |    2 +-
 README.md                                     |   10 +-
 cfg/encoder_intra_vtm.cfg                     |   23 +-
 cfg/encoder_lowdelay_P_vtm.cfg                |   23 +-
 cfg/encoder_lowdelay_vtm.cfg                  |   23 +-
 cfg/encoder_randomaccess_vtm.cfg              |   36 +-
 cfg/encoder_randomaccess_vtm_gop16.cfg        |   34 +-
 cfg/examples_SEI_CTI/readMe.txt               |    7 +
 cfg/examples_SEI_CTI/seiCti_hdrPq_to_sdr1.cfg |   24 +
 cfg/examples_SEI_CTI/seiCti_hdrPq_to_sdr2.cfg |   21 +
 cfg/examples_SEI_CTI/seiCti_sdr_to_hdrPq1.cfg |   22 +
 cfg/hbd/12-bit.cfg                            |    3 +-
 cfg/hbd/16-bit.cfg                            |    3 +-
 cfg/hbd/hbd.cfg                               |   18 +-
 cfg/lossless/lossless.cfg                     |    2 +-
 cfg/lossless/lossless_mixed.cfg               |    2 +-
 cfg/per-class/classH1.cfg                     |    2 +
 .../H1_BalloonFestival_420_12bit.cfg          |   11 +
 .../H1_FireEater2_420_12bit.cfg               |   11 +
 cfg/per-sequence-HBD/H1_Hurdles_420_12bit.cfg |   11 +
 cfg/per-sequence-HBD/H1_Market3_420_12bit.cfg |   11 +
 .../H1_Starting_420_12bit.cfg                 |   11 +
 .../H2_DayStreet_420_12bit.cfg                |   11 +
 .../H2_DayStreet_422_12bit.cfg                |    8 +-
 .../H2_DayStreet_444_12bit.cfg                |    8 +-
 .../H2_NightStreet_420_12bit.cfg              |   11 +
 .../H2_NightStreet_422_12bit.cfg              |    8 +-
 .../H2_NightStreet_444_12bit.cfg              |    8 +-
 .../H2_PeopleInShoppingCenter_420_12bit.cfg   |   11 +
 .../H2_PeopleInShoppingCenter_422_12bit.cfg   |    8 +-
 .../H2_PeopleInShoppingCenter_444_12bit.cfg   |    8 +-
 .../H2_StainedGlass_420_12bit.cfg             |   11 +
 .../H2_StainedGlass_422_12bit.cfg             |    8 +-
 .../H2_StainedGlass_444_12bit.cfg             |    8 +-
 cfg/sei_vui/alpha_channel_info.cfg            |   10 +
 cfg/sei_vui/annotated_regions/anno_reg_0.txt  |   48 +
 cfg/sei_vui/annotated_regions/anno_reg_1.txt  |   31 +
 cfg/sei_vui/annotated_regions/anno_reg_2.txt  |   43 +
 cfg/sei_vui/annotated_regions/anno_reg_3.txt  |   25 +
 cfg/sei_vui/annotated_regions/anno_reg_4.txt  |   23 +
 cfg/sei_vui/depth_representation_info.cfg     |   14 +
 cfg/sei_vui/display_orientation.cfg           |    6 +
 cfg/sei_vui/multiview_acquisition_info.cfg    |   26 +
 cfg/sei_vui/multiview_view_position.cfg       |    4 +
 cfg/sei_vui/scalability_dimension_info.cfg    |   10 +
 doc/jvetdoc.cls                               |    2 +-
 doc/mainpage.h                                |    2 +-
 doc/software-manual.pdf                       |  Bin 1659641 -> 1677197 bytes
 doc/software-manual.tex                       |  616 ++-
 .../BitstreamExtractorApp.cpp                 |  218 +-
 .../BitstreamExtractorApp.h                   |   11 +-
 .../BitstreamExtractorAppCfg.cpp              |    2 +-
 .../BitstreamExtractorAppCfg.h                |    2 +-
 .../App/BitstreamExtractorApp/CMakeLists.txt  |   22 +-
 .../bitstreamextractormain.cpp                |    2 +-
 source/App/DecoderAnalyserApp/CMakeLists.txt  |   22 +-
 source/App/DecoderApp/CMakeLists.txt          |   22 +-
 source/App/DecoderApp/DecApp.cpp              |  432 +-
 source/App/DecoderApp/DecApp.h                |   11 +-
 source/App/DecoderApp/DecAppCfg.cpp           |   18 +-
 source/App/DecoderApp/DecAppCfg.h             |    9 +-
 source/App/DecoderApp/decmain.cpp             |    2 +-
 source/App/EncoderApp/CMakeLists.txt          |   22 +-
 source/App/EncoderApp/EncApp.cpp              |  239 +-
 source/App/EncoderApp/EncApp.h                |    4 +-
 source/App/EncoderApp/EncAppCfg.cpp           |  874 +++-
 source/App/EncoderApp/EncAppCfg.h             |  186 +-
 source/App/EncoderApp/encmain.cpp             |   12 +-
 source/App/Parcat/CMakeLists.txt              |    2 +-
 source/App/Parcat/parcat.cpp                  |   38 +-
 source/App/SEIRemovalApp/CMakeLists.txt       |   22 +-
 source/App/SEIRemovalApp/SEIRemovalApp.cpp    |    2 +-
 source/App/SEIRemovalApp/SEIRemovalApp.h      |    2 +-
 source/App/SEIRemovalApp/SEIRemovalAppCfg.cpp |    2 +-
 source/App/SEIRemovalApp/SEIRemovalAppCfg.h   |    2 +-
 source/App/SEIRemovalApp/seiremovalmain.cpp   |    2 +-
 source/App/StreamMergeApp/CMakeLists.txt      |   22 +-
 source/App/StreamMergeApp/StreamMergeApp.cpp  |  499 +-
 source/App/StreamMergeApp/StreamMergeApp.h    |   55 +-
 .../App/StreamMergeApp/StreamMergeAppCfg.cpp  |    2 +-
 source/App/StreamMergeApp/StreamMergeAppCfg.h |    2 +-
 source/App/StreamMergeApp/StreamMergeMain.cpp |    2 +-
 source/App/SubpicMergeApp/CMakeLists.txt      |   22 +-
 source/App/SubpicMergeApp/SubpicMergeApp.cpp  |  259 +-
 source/App/SubpicMergeApp/SubpicMergeApp.h    |    7 +-
 source/App/SubpicMergeApp/SubpicMergeMain.cpp |    2 +-
 source/Lib/CommonAnalyserLib/CMakeLists.txt   |   24 +-
 source/Lib/CommonLib/AdaptiveLoopFilter.cpp   |   12 +-
 source/Lib/CommonLib/AdaptiveLoopFilter.h     |    2 +-
 source/Lib/CommonLib/AffineGradientSearch.cpp |    2 +-
 source/Lib/CommonLib/AffineGradientSearch.h   |    2 +-
 source/Lib/CommonLib/AlfParameters.h          |    4 +-
 source/Lib/CommonLib/BitStream.cpp            |    2 +-
 source/Lib/CommonLib/BitStream.h              |    2 +-
 source/Lib/CommonLib/Buffer.cpp               |  202 +-
 source/Lib/CommonLib/Buffer.h                 |   20 +-
 source/Lib/CommonLib/CMakeLists.txt           |   24 +-
 source/Lib/CommonLib/CacheModel.cpp           |    9 +-
 source/Lib/CommonLib/CacheModel.h             |    2 +-
 source/Lib/CommonLib/ChromaFormat.cpp         |    2 +-
 source/Lib/CommonLib/ChromaFormat.h           |    2 +-
 source/Lib/CommonLib/CodingStatistics.h       |    2 +-
 source/Lib/CommonLib/CodingStructure.cpp      |  747 ++-
 source/Lib/CommonLib/CodingStructure.h        |   33 +-
 source/Lib/CommonLib/Common.h                 |   29 +-
 source/Lib/CommonLib/CommonDef.h              |   49 +-
 source/Lib/CommonLib/ContextModelling.cpp     |  218 +-
 source/Lib/CommonLib/ContextModelling.h       |  152 +-
 source/Lib/CommonLib/Contexts.cpp             |   18 +-
 source/Lib/CommonLib/Contexts.h               |   35 +-
 .../{LoopFilter.cpp => DeblockingFilter.cpp}  |   70 +-
 .../{LoopFilter.h => DeblockingFilter.h}      |   19 +-
 source/Lib/CommonLib/DepQuant.cpp             |  311 +-
 source/Lib/CommonLib/DepQuant.h               |    2 +-
 source/Lib/CommonLib/HRD.cpp                  |    2 +-
 source/Lib/CommonLib/HRD.h                    |    2 +-
 source/Lib/CommonLib/Hash.cpp                 |    5 +-
 source/Lib/CommonLib/Hash.h                   |    2 +-
 source/Lib/CommonLib/IbcHashMap.cpp           |    2 +-
 source/Lib/CommonLib/IbcHashMap.h             |    2 +-
 source/Lib/CommonLib/InterPrediction.cpp      |  118 +-
 source/Lib/CommonLib/InterPrediction.h        |    6 +-
 source/Lib/CommonLib/InterpolationFilter.cpp  |   56 +-
 source/Lib/CommonLib/InterpolationFilter.h    |   11 +-
 source/Lib/CommonLib/IntraPrediction.cpp      |    6 +-
 source/Lib/CommonLib/IntraPrediction.h        |    2 +-
 source/Lib/CommonLib/MCTS.cpp                 |    2 +-
 source/Lib/CommonLib/MCTS.h                   |    2 +-
 .../Lib/CommonLib/MatrixIntraPrediction.cpp   |    2 +-
 source/Lib/CommonLib/MatrixIntraPrediction.h  |    4 +-
 source/Lib/CommonLib/MipData.h                |    4 +-
 source/Lib/CommonLib/MotionInfo.h             |  111 +-
 source/Lib/CommonLib/Mv.cpp                   |    2 +-
 source/Lib/CommonLib/Mv.h                     |    2 +-
 source/Lib/CommonLib/NAL.h                    |    2 +-
 source/Lib/CommonLib/ParameterSetManager.cpp  |    2 +-
 source/Lib/CommonLib/ParameterSetManager.h    |    4 +-
 source/Lib/CommonLib/PicYuvMD5.cpp            |    4 +-
 source/Lib/CommonLib/Picture.cpp              |  302 +-
 source/Lib/CommonLib/Picture.h                |   63 +-
 source/Lib/CommonLib/ProfileLevelTier.cpp     |   39 +-
 source/Lib/CommonLib/ProfileLevelTier.h       |    5 +-
 source/Lib/CommonLib/Quant.cpp                |   35 +-
 source/Lib/CommonLib/Quant.h                  |   12 +-
 source/Lib/CommonLib/QuantRDOQ.cpp            |   68 +-
 source/Lib/CommonLib/QuantRDOQ.h              |    2 +-
 source/Lib/CommonLib/RdCost.cpp               |   33 +-
 source/Lib/CommonLib/RdCost.h                 |   25 +-
 .../Lib/CommonLib/RdCostWeightPrediction.cpp  |    2 +-
 source/Lib/CommonLib/RdCostWeightPrediction.h |    2 +-
 source/Lib/CommonLib/Reshape.cpp              |   46 +-
 source/Lib/CommonLib/Reshape.h                |    6 +-
 source/Lib/CommonLib/Rom.cpp                  |   59 +-
 source/Lib/CommonLib/Rom.h                    |   17 +-
 source/Lib/CommonLib/RomLFNST.cpp             |    2 +-
 source/Lib/CommonLib/RomTr.cpp                |    6 +-
 source/Lib/CommonLib/SEI.cpp                  |  303 +-
 source/Lib/CommonLib/SEI.h                    |  336 +-
 source/Lib/CommonLib/SEIColourTransform.cpp   |  199 +
 source/Lib/CommonLib/SEIColourTransform.h     |   71 +
 source/Lib/CommonLib/SampleAdaptiveOffset.cpp |    2 +-
 source/Lib/CommonLib/SampleAdaptiveOffset.h   |    2 +-
 source/Lib/CommonLib/Slice.cpp                |  769 ++-
 source/Lib/CommonLib/Slice.h                  |  230 +-
 source/Lib/CommonLib/TrQuant.cpp              |    9 +-
 source/Lib/CommonLib/TrQuant.h                |    6 +-
 source/Lib/CommonLib/TrQuant_EMT.cpp          |    2 +-
 source/Lib/CommonLib/TrQuant_EMT.h            |    2 +-
 source/Lib/CommonLib/TypeDef.h                |  130 +-
 source/Lib/CommonLib/Unit.cpp                 |    6 +-
 source/Lib/CommonLib/Unit.h                   |   30 +-
 source/Lib/CommonLib/UnitPartitioner.cpp      |    2 +-
 source/Lib/CommonLib/UnitPartitioner.h        |    2 +-
 source/Lib/CommonLib/UnitTools.cpp            | 1115 +++-
 source/Lib/CommonLib/UnitTools.h              |   17 +-
 source/Lib/CommonLib/WeightPrediction.cpp     |    7 +-
 source/Lib/CommonLib/WeightPrediction.h       |    2 +-
 source/Lib/CommonLib/dtrace.cpp               |  277 +-
 source/Lib/CommonLib/dtrace.h                 |    2 +-
 .../Lib/CommonLib/dtrace_blockstatistics.cpp  |   24 +-
 source/Lib/CommonLib/dtrace_blockstatistics.h |    2 +-
 source/Lib/CommonLib/dtrace_buffer.h          |    2 +-
 source/Lib/CommonLib/dtrace_codingstruct.h    |    2 +-
 source/Lib/CommonLib/dtrace_next.h            |    2 +-
 source/Lib/CommonLib/version.h                |    2 +-
 .../Lib/CommonLib/x86/AdaptiveLoopFilterX86.h | 1017 +++-
 .../CommonLib/x86/AffineGradientSearchX86.h   |  456 +-
 source/Lib/CommonLib/x86/BufferX86.h          |  773 ++-
 source/Lib/CommonLib/x86/CommonDefX86.cpp     |    2 +-
 source/Lib/CommonLib/x86/CommonDefX86.h       |    2 +-
 source/Lib/CommonLib/x86/IbcHashMapX86.h      |    2 +-
 source/Lib/CommonLib/x86/InitX86.cpp          |    2 +-
 .../CommonLib/x86/InterpolationFilterX86.h    | 1335 ++++-
 source/Lib/CommonLib/x86/RdCostX86.h          | 2410 ++++++++-
 source/Lib/DecoderAnalyserLib/CMakeLists.txt  |   22 +-
 source/Lib/DecoderLib/AnnexBread.cpp          |    7 +-
 source/Lib/DecoderLib/AnnexBread.h            |    2 +-
 source/Lib/DecoderLib/BinDecoder.cpp          |   14 +-
 source/Lib/DecoderLib/BinDecoder.h            |    7 +-
 source/Lib/DecoderLib/CABACReader.cpp         |   94 +-
 source/Lib/DecoderLib/CABACReader.h           |    4 +-
 source/Lib/DecoderLib/CMakeLists.txt          |   22 +-
 source/Lib/DecoderLib/DecCu.cpp               |   22 +-
 source/Lib/DecoderLib/DecCu.h                 |    3 +-
 source/Lib/DecoderLib/DecLib.cpp              |  637 ++-
 source/Lib/DecoderLib/DecLib.h                |   40 +-
 source/Lib/DecoderLib/DecSlice.cpp            |    2 +-
 source/Lib/DecoderLib/DecSlice.h              |    2 +-
 source/Lib/DecoderLib/NALread.cpp             |    9 +-
 source/Lib/DecoderLib/NALread.h               |    2 +-
 source/Lib/DecoderLib/SEIread.cpp             |  547 +-
 source/Lib/DecoderLib/SEIread.h               |   17 +-
 source/Lib/DecoderLib/VLCReader.cpp           |  232 +-
 source/Lib/DecoderLib/VLCReader.h             |   19 +-
 source/Lib/EncoderLib/AQp.cpp                 |    2 +-
 source/Lib/EncoderLib/AQp.h                   |    2 +-
 source/Lib/EncoderLib/Analyze.h               |  160 +-
 source/Lib/EncoderLib/AnnexBwrite.h           |    7 +-
 source/Lib/EncoderLib/BinEncoder.cpp          |    2 +-
 source/Lib/EncoderLib/BinEncoder.h            |    7 +-
 source/Lib/EncoderLib/CABACWriter.cpp         |  652 ++-
 source/Lib/EncoderLib/CABACWriter.h           |    4 +-
 source/Lib/EncoderLib/CMakeLists.txt          |   22 +-
 .../Lib/EncoderLib/EncAdaptiveLoopFilter.cpp  |  189 +-
 source/Lib/EncoderLib/EncAdaptiveLoopFilter.h |    2 +-
 source/Lib/EncoderLib/EncCfg.h                |  520 +-
 source/Lib/EncoderLib/EncCfgParam.h           |    9 +-
 source/Lib/EncoderLib/EncCu.cpp               | 1823 ++++---
 source/Lib/EncoderLib/EncCu.h                 |   28 +-
 source/Lib/EncoderLib/EncGOP.cpp              | 1065 +++-
 source/Lib/EncoderLib/EncGOP.h                |   44 +-
 source/Lib/EncoderLib/EncHRD.cpp              |    2 +-
 source/Lib/EncoderLib/EncHRD.h                |    2 +-
 source/Lib/EncoderLib/EncLib.cpp              |  352 +-
 source/Lib/EncoderLib/EncLib.h                |   77 +-
 source/Lib/EncoderLib/EncLibCommon.cpp        |    2 +-
 source/Lib/EncoderLib/EncLibCommon.h          |    2 +-
 source/Lib/EncoderLib/EncModeCtrl.cpp         |  556 +-
 source/Lib/EncoderLib/EncModeCtrl.h           |  466 +-
 source/Lib/EncoderLib/EncReshape.cpp          |  172 +-
 source/Lib/EncoderLib/EncReshape.h            |    6 +-
 .../EncoderLib/EncSampleAdaptiveOffset.cpp    |   33 +-
 .../Lib/EncoderLib/EncSampleAdaptiveOffset.h  |    6 +-
 source/Lib/EncoderLib/EncSlice.cpp            |  366 +-
 source/Lib/EncoderLib/EncSlice.h              |    4 +-
 source/Lib/EncoderLib/EncTemporalFilter.cpp   |  251 +-
 source/Lib/EncoderLib/EncTemporalFilter.h     |   23 +-
 source/Lib/EncoderLib/InterSearch.cpp         | 4561 ++++++++++++++---
 source/Lib/EncoderLib/InterSearch.h           |  158 +-
 source/Lib/EncoderLib/IntraSearch.cpp         |  764 ++-
 source/Lib/EncoderLib/IntraSearch.h           |   25 +-
 source/Lib/EncoderLib/NALwrite.cpp            |    4 +-
 source/Lib/EncoderLib/NALwrite.h              |    2 +-
 source/Lib/EncoderLib/RateCtrl.cpp            |  223 +-
 source/Lib/EncoderLib/RateCtrl.h              |    2 +-
 source/Lib/EncoderLib/SEIEncoder.cpp          |  395 +-
 source/Lib/EncoderLib/SEIEncoder.h            |   15 +-
 source/Lib/EncoderLib/SEIwrite.cpp            |  469 +-
 source/Lib/EncoderLib/SEIwrite.h              |   18 +-
 source/Lib/EncoderLib/VLCWriter.cpp           |  228 +-
 source/Lib/EncoderLib/VLCWriter.h             |    8 +-
 source/Lib/EncoderLib/WeightPredAnalysis.cpp  |    2 +-
 source/Lib/EncoderLib/WeightPredAnalysis.h    |    2 +-
 source/Lib/Utilities/CMakeLists.txt           |   22 +-
 source/Lib/Utilities/VideoIOYuv.cpp           |    4 +-
 source/Lib/Utilities/VideoIOYuv.h             |    2 +-
 source/Lib/Utilities/program_options_lite.cpp |    2 +-
 source/Lib/Utilities/program_options_lite.h   |    2 +-
 source/Lib/libmd5/MD5.h                       |    2 +-
 source/Lib/libmd5/libmd5.h                    |    2 +-
 272 files changed, 25960 insertions(+), 6501 deletions(-)
 create mode 100644 cfg/examples_SEI_CTI/readMe.txt
 create mode 100644 cfg/examples_SEI_CTI/seiCti_hdrPq_to_sdr1.cfg
 create mode 100644 cfg/examples_SEI_CTI/seiCti_hdrPq_to_sdr2.cfg
 create mode 100644 cfg/examples_SEI_CTI/seiCti_sdr_to_hdrPq1.cfg
 create mode 100755 cfg/per-sequence-HBD/H1_BalloonFestival_420_12bit.cfg
 create mode 100755 cfg/per-sequence-HBD/H1_FireEater2_420_12bit.cfg
 create mode 100755 cfg/per-sequence-HBD/H1_Hurdles_420_12bit.cfg
 create mode 100755 cfg/per-sequence-HBD/H1_Market3_420_12bit.cfg
 create mode 100755 cfg/per-sequence-HBD/H1_Starting_420_12bit.cfg
 create mode 100755 cfg/per-sequence-HBD/H2_DayStreet_420_12bit.cfg
 create mode 100755 cfg/per-sequence-HBD/H2_NightStreet_420_12bit.cfg
 create mode 100755 cfg/per-sequence-HBD/H2_PeopleInShoppingCenter_420_12bit.cfg
 create mode 100755 cfg/per-sequence-HBD/H2_StainedGlass_420_12bit.cfg
 create mode 100644 cfg/sei_vui/alpha_channel_info.cfg
 create mode 100644 cfg/sei_vui/annotated_regions/anno_reg_0.txt
 create mode 100644 cfg/sei_vui/annotated_regions/anno_reg_1.txt
 create mode 100644 cfg/sei_vui/annotated_regions/anno_reg_2.txt
 create mode 100644 cfg/sei_vui/annotated_regions/anno_reg_3.txt
 create mode 100644 cfg/sei_vui/annotated_regions/anno_reg_4.txt
 create mode 100644 cfg/sei_vui/depth_representation_info.cfg
 create mode 100644 cfg/sei_vui/display_orientation.cfg
 create mode 100644 cfg/sei_vui/multiview_acquisition_info.cfg
 create mode 100644 cfg/sei_vui/multiview_view_position.cfg
 create mode 100644 cfg/sei_vui/scalability_dimension_info.cfg
 rename source/Lib/CommonLib/{LoopFilter.cpp => DeblockingFilter.cpp} (94%)
 rename source/Lib/CommonLib/{LoopFilter.h => DeblockingFilter.h} (95%)
 create mode 100644 source/Lib/CommonLib/SEIColourTransform.cpp
 create mode 100644 source/Lib/CommonLib/SEIColourTransform.h

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 48c3d9200..6b8a4ef46 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -27,11 +27,6 @@ build_macos:
    tags:
       - macos
 
-build_ubuntu1604:
-   extends: .build_template_linux
-   tags:
-      - ubuntu1604
-
 build_ubuntu1804:
    extends: .build_template_linux
    tags:
@@ -47,6 +42,11 @@ build_ubuntu1804-gcc8:
    tags:
       - ubuntu1804-gcc8
 
+build_ubuntu2004:
+   extends: .build_template_linux
+   tags:
+      - ubuntu2004
+
 build_vc191x:
    extends: .build_template
    tags:
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 10a86aa00..7d8b3d739 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -52,22 +52,6 @@ set_property( GLOBAL PROPERTY USE_FOLDERS ON )
 # Include a utility module providing functions, macros, and settings
 include( ${CMAKE_SOURCE_DIR}/cmake/CMakeBuild/cmake/modules/BBuildEnv.cmake )
 
-# Enable multithreading
-bb_multithreading()
-
-find_package(OpenMP)
-
-if( OpenMP_FOUND )
-  set( CMAKE_C_FLAGS          "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}" )
-  set( CMAKE_CXX_FLAGS        "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}" )
-  set( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}" )
-  
-  set( SET_ENABLE_SPLIT_PARALLELISM OFF CACHE BOOL "Set ENABLE_SPLIT_PARALLELISM as a compiler flag" )
-  set( ENABLE_SPLIT_PARALLELISM     OFF CACHE BOOL "If SET_ENABLE_SPLIT_PARALLELISM is on, it will be set to this value" )
-  set( SET_ENABLE_WPP_PARALLELISM   OFF CACHE BOOL "Set ENABLE_WPP_PARALLELISM as a compiler flag" )
-  set( ENABLE_WPP_PARALLELISM       OFF CACHE BOOL "If SET_ENABLE_WPP_PARALLELISM is on, it will be set to this value" )
-endif()
-
 # Enable warnings for some generators and toolsets.
 # bb_enable_warnings( gcc warnings-as-errors -Wno-sign-compare )
 # bb_enable_warnings( gcc -Wno-unused-variable )
diff --git a/COPYING b/COPYING
index a328b7da3..9d1ebfbff 100644
--- a/COPYING
+++ b/COPYING
@@ -3,7 +3,7 @@ License, included below. This software may be subject to other third party
 and contributor rights, including patent rights, and no such rights are
 granted under this license.   
 
-Copyright (c) 2010-2020, ITU/ISO/IEC
+Copyright (c) 2010-2021, ITU/ISO/IEC
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
diff --git a/README.md b/README.md
index d2853b793..fa74ff6f7 100644
--- a/README.md
+++ b/README.md
@@ -1,14 +1,20 @@
 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.
+This software package is the reference software for Rec. ITU-T H.266 | ISO/IEC 23090-3 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).
+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 Joint Video Coding Team(s) with ITU-T SG 16, Working Group 5 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.
 
+The source code is stored in a Git repository. The most recent version can be retrieved using the following commands:
+```bash
+git clone https://vcgit.hhi.fraunhofer.de/jvet/VVCSoftware_VTM.git
+cd VVCSoftware_VTM
+```
+
 Build instructions
 ==================
 
diff --git a/cfg/encoder_intra_vtm.cfg b/cfg/encoder_intra_vtm.cfg
index 4509605d9..d3c22b385 100644
--- a/cfg/encoder_intra_vtm.cfg
+++ b/cfg/encoder_intra_vtm.cfg
@@ -31,15 +31,15 @@ RDOQ                          : 1           # RDOQ
 RDOQTS                        : 1           # RDOQ for transform skip
 
 #=========== Deblock Filter ============
-LoopFilterOffsetInPPS         : 1           # Dbl params: 0=varying params in SliceHeader, param = base_param + GOP_offset_param; 1 (default) =constant params in PPS, param = base_param)
-LoopFilterDisable             : 0           # Disable deblocking filter (0=Filter, 1=No Filter)
-LoopFilterBetaOffset_div2     : 0           # base_param: -12 ~ 12
-LoopFilterTcOffset_div2       : 0           # base_param: -12 ~ 12
-LoopFilterCbBetaOffset_div2   : 0           # base_param: -12 ~ 12
-LoopFilterCbTcOffset_div2     : 0           # base_param: -12 ~ 12
-LoopFilterCrBetaOffset_div2   : 0           # base_param: -12 ~ 12
-LoopFilterCrTcOffset_div2     : 0           # base_param: -12 ~ 12
-DeblockingFilterMetric        : 0           # blockiness metric (automatically configures deblocking parameters in bitstream). Applies slice-level loop filter offsets (LoopFilterOffsetInPPS and LoopFilterDisable must be 0)
+DeblockingFilterOffsetInPPS         : 1           # Dbl params: 0=varying params in SliceHeader, param = base_param + GOP_offset_param; 1 (default) =constant params in PPS, param = base_param)
+DeblockingFilterDisable             : 0           # Disable deblocking filter (0=Filter, 1=No Filter)
+DeblockingFilterBetaOffset_div2     : 0           # base_param: -12 ~ 12
+DeblockingFilterTcOffset_div2       : 0           # base_param: -12 ~ 12
+DeblockingFilterCbBetaOffset_div2   : 0           # base_param: -12 ~ 12
+DeblockingFilterCbTcOffset_div2     : 0           # base_param: -12 ~ 12
+DeblockingFilterCrBetaOffset_div2   : 0           # base_param: -12 ~ 12
+DeblockingFilterCrTcOffset_div2     : 0           # base_param: -12 ~ 12
+DeblockingFilterMetric        : 0           # blockiness metric (automatically configures deblocking parameters in bitstream). Applies slice-level loop filter offsets (DeblockingFilterOffsetInPPS and DeblockingFilterDisable must be 0)
 
 #=========== Misc. ============
 InternalBitDepth              : 10          # codec operating bit-depth
@@ -110,9 +110,10 @@ FastLFNST                    : 1
 
 # Encoder optimization tools
 AffineAmvrEncOpt             : 0
-ALFStrength                  : 1.0
 ALFAllowPredefinedFilters    : 1
-CCALFStrength                : 1.0
+ALFStrengthTargetLuma        : 1.0
+ALFStrengthTargetChroma      : 1.0
+CCALFStrengthTarget          : 1.0
 ### DO NOT ADD ANYTHING BELOW THIS LINE ###
 ### DO NOT DELETE THE EMPTY LINE BELOW ###
 
diff --git a/cfg/encoder_lowdelay_P_vtm.cfg b/cfg/encoder_lowdelay_P_vtm.cfg
index 35b2291f4..5c1c492a5 100644
--- a/cfg/encoder_lowdelay_P_vtm.cfg
+++ b/cfg/encoder_lowdelay_P_vtm.cfg
@@ -43,15 +43,15 @@ RDOQ                          : 1           # RDOQ
 RDOQTS                        : 1           # RDOQ for transform skip
 
 #=========== Deblock Filter ============
-LoopFilterOffsetInPPS         : 1           # Dbl params: 0=varying params in SliceHeader, param = base_param + GOP_offset_param; 1 (default) =constant params in PPS, param = base_param)
-LoopFilterDisable             : 0           # Disable deblocking filter (0=Filter, 1=No Filter)
-LoopFilterBetaOffset_div2     : 0           # base_param: -12 ~ 12
-LoopFilterTcOffset_div2       : 0           # base_param: -12 ~ 12
-LoopFilterCbBetaOffset_div2   : 0           # base_param: -12 ~ 12
-LoopFilterCbTcOffset_div2     : 0           # base_param: -12 ~ 12
-LoopFilterCrBetaOffset_div2   : 0           # base_param: -12 ~ 12
-LoopFilterCrTcOffset_div2     : 0           # base_param: -12 ~ 12
-DeblockingFilterMetric        : 0           # blockiness metric (automatically configures deblocking parameters in bitstream). Applies slice-level loop filter offsets (LoopFilterOffsetInPPS and LoopFilterDisable must be 0)
+DeblockingFilterOffsetInPPS         : 1           # Dbl params: 0=varying params in SliceHeader, param = base_param + GOP_offset_param; 1 (default) =constant params in PPS, param = base_param)
+DeblockingFilterDisable             : 0           # Disable deblocking filter (0=Filter, 1=No Filter)
+DeblockingFilterBetaOffset_div2     : 0           # base_param: -12 ~ 12
+DeblockingFilterTcOffset_div2       : 0           # base_param: -12 ~ 12
+DeblockingFilterCbBetaOffset_div2   : 0           # base_param: -12 ~ 12
+DeblockingFilterCbTcOffset_div2     : 0           # base_param: -12 ~ 12
+DeblockingFilterCrBetaOffset_div2   : 0           # base_param: -12 ~ 12
+DeblockingFilterCrTcOffset_div2     : 0           # base_param: -12 ~ 12
+DeblockingFilterMetric        : 0           # blockiness metric (automatically configures deblocking parameters in bitstream). Applies slice-level loop filter offsets (DeblockingFilterOffsetInPPS and DeblockingFilterDisable must be 0)
 
 #=========== Misc. ============
 InternalBitDepth              : 10          # codec operating bit-depth
@@ -136,9 +136,10 @@ FastLocalDualTreeMode        : 2
 # Encoder optimization tools
 AffineAmvrEncOpt             : 0
 MmvdDisNum                   : 6
-ALFStrength                  : 1.0
 ALFAllowPredefinedFilters    : 1
-CCALFStrength                : 1.0
+ALFStrengthTargetLuma        : 1.0
+ALFStrengthTargetChroma      : 1.0
+CCALFStrengthTarget          : 1.0
 ### DO NOT ADD ANYTHING BELOW THIS LINE ###
 ### DO NOT DELETE THE EMPTY LINE BELOW ###
 
diff --git a/cfg/encoder_lowdelay_vtm.cfg b/cfg/encoder_lowdelay_vtm.cfg
index 5818fb1f7..d4643fc94 100644
--- a/cfg/encoder_lowdelay_vtm.cfg
+++ b/cfg/encoder_lowdelay_vtm.cfg
@@ -43,15 +43,15 @@ RDOQ                          : 1           # RDOQ
 RDOQTS                        : 1           # RDOQ for transform skip
 
 #=========== Deblock Filter ============
-LoopFilterOffsetInPPS         : 1           # Dbl params: 0=varying params in SliceHeader, param = base_param + GOP_offset_param; 1 (default) =constant params in PPS, param = base_param)
-LoopFilterDisable             : 0           # Disable deblocking filter (0=Filter, 1=No Filter)
-LoopFilterBetaOffset_div2     : 0           # base_param: -12 ~ 12
-LoopFilterTcOffset_div2       : 0           # base_param: -12 ~ 12
-LoopFilterCbBetaOffset_div2   : 0           # base_param: -12 ~ 12
-LoopFilterCbTcOffset_div2     : 0           # base_param: -12 ~ 12
-LoopFilterCrBetaOffset_div2   : 0           # base_param: -12 ~ 12
-LoopFilterCrTcOffset_div2     : 0           # base_param: -12 ~ 12
-DeblockingFilterMetric        : 0           # blockiness metric (automatically configures deblocking parameters in bitstream). Applies slice-level loop filter offsets (LoopFilterOffsetInPPS and LoopFilterDisable must be 0)
+DeblockingFilterOffsetInPPS         : 1           # Dbl params: 0=varying params in SliceHeader, param = base_param + GOP_offset_param; 1 (default) =constant params in PPS, param = base_param)
+DeblockingFilterDisable             : 0           # Disable deblocking filter (0=Filter, 1=No Filter)
+DeblockingFilterBetaOffset_div2     : 0           # base_param: -12 ~ 12
+DeblockingFilterTcOffset_div2       : 0           # base_param: -12 ~ 12
+DeblockingFilterCbBetaOffset_div2   : 0           # base_param: -12 ~ 12
+DeblockingFilterCbTcOffset_div2     : 0           # base_param: -12 ~ 12
+DeblockingFilterCrBetaOffset_div2   : 0           # base_param: -12 ~ 12
+DeblockingFilterCrTcOffset_div2     : 0           # base_param: -12 ~ 12
+DeblockingFilterMetric        : 0           # blockiness metric (automatically configures deblocking parameters in bitstream). Applies slice-level loop filter offsets (DeblockingFilterOffsetInPPS and DeblockingFilterDisable must be 0)
 
 #=========== Misc. ============
 InternalBitDepth              : 10          # codec operating bit-depth
@@ -140,9 +140,10 @@ FastLocalDualTreeMode        : 2
 # Encoder optimization tools
 AffineAmvrEncOpt             : 0
 MmvdDisNum                   : 6
-ALFStrength                  : 1.0
 ALFAllowPredefinedFilters    : 1
-CCALFStrength                : 1.0
+ALFStrengthTargetLuma        : 1.0
+ALFStrengthTargetChroma      : 1.0
+CCALFStrengthTarget          : 1.0
 ### DO NOT ADD ANYTHING BELOW THIS LINE ###
 ### DO NOT DELETE THE EMPTY LINE BELOW ###
 
diff --git a/cfg/encoder_randomaccess_vtm.cfg b/cfg/encoder_randomaccess_vtm.cfg
index 9ca9d6f62..82064508d 100644
--- a/cfg/encoder_randomaccess_vtm.cfg
+++ b/cfg/encoder_randomaccess_vtm.cfg
@@ -17,7 +17,7 @@ GOPSize                       : 32          # GOP Size (number of B slice = GOPS
 IntraQPOffset                 : -3
 LambdaFromQpEnable            : 1           # see JCTVC-X0038 for suitable parameters for IntraQPOffset, QPoffset, QPOffsetModelOff, QPOffsetModelScale when enabled
 #        Type POC QPoffset QPOffsetModelOff QPOffsetModelScale CbQPoffset CrQPoffset QPfactor tcOffsetDiv2 betaOffsetDiv2 CbTcOffsetDiv2 CbBetaOffsetDiv2 CrTcOffsetDiv2 CrBetaOffsetDiv2 temporal_id #ref_pics_active_L0 #ref_pics_L0   reference_pictures_L0 #ref_pics_active_L1 #ref_pics_L1   reference_pictures_L1
-Frame1                        : B   32  -1        0.0                      0.0            0          0          1.0      0            0                0             0                0               0              0             2                3          32 48 64                    2                2           32 48 
+Frame1                        : B   32  -1        0.0                      0.0            0          0          1.0      0            0                0             0                0               0              0             2                3          32 64 48                    1                2           32 48 
 Frame2                        : B   16   0       -4.9309                   0.2265         0          0          1.0      0            0                0             0                0               0              1             2                2          16 32                       2                2           -16 16 
 Frame3                        : B    8   0       -4.5000                   0.2353         0          0          1.0      0            0                0             0                0               0              2             2                2          8 24                        2                2           -8 -24 
 Frame4                        : B    4   3       -5.4095                   0.2571         0          0          1.0      0            0                0             0                0               0              3             2                2          4 20                        2                3           -4 -12 -28 
@@ -69,15 +69,15 @@ RDOQ                          : 1           # RDOQ
 RDOQTS                        : 1           # RDOQ for transform skip
 
 #=========== Deblock Filter ============
-LoopFilterOffsetInPPS         : 1           # Dbl params: 0=varying params in SliceHeader, param = base_param + GOP_offset_param; 1 (default) =constant params in PPS, param = base_param)
-LoopFilterDisable             : 0           # Disable deblocking filter (0=Filter, 1=No Filter)
-LoopFilterBetaOffset_div2     : 0           # base_param: -12 ~ 12
-LoopFilterTcOffset_div2       : 0           # base_param: -12 ~ 12
-LoopFilterCbBetaOffset_div2   : 0           # base_param: -12 ~ 12
-LoopFilterCbTcOffset_div2     : 0           # base_param: -12 ~ 12
-LoopFilterCrBetaOffset_div2   : 0           # base_param: -12 ~ 12
-LoopFilterCrTcOffset_div2     : 0           # base_param: -12 ~ 12
-DeblockingFilterMetric        : 0           # blockiness metric (automatically configures deblocking parameters in bitstream). Applies slice-level loop filter offsets (LoopFilterOffsetInPPS and LoopFilterDisable must be 0)
+DeblockingFilterOffsetInPPS         : 1           # Dbl params: 0=varying params in SliceHeader, param = base_param + GOP_offset_param; 1 (default) =constant params in PPS, param = base_param)
+DeblockingFilterDisable             : 0           # Disable deblocking filter (0=Filter, 1=No Filter)
+DeblockingFilterBetaOffset_div2     : 0           # base_param: -12 ~ 12
+DeblockingFilterTcOffset_div2       : 0           # base_param: -12 ~ 12
+DeblockingFilterCbBetaOffset_div2   : 0           # base_param: -12 ~ 12
+DeblockingFilterCbTcOffset_div2     : 0           # base_param: -12 ~ 12
+DeblockingFilterCrBetaOffset_div2   : 0           # base_param: -12 ~ 12
+DeblockingFilterCrTcOffset_div2     : 0           # base_param: -12 ~ 12
+DeblockingFilterMetric        : 0           # blockiness metric (automatically configures deblocking parameters in bitstream). Applies slice-level loop filter offsets (DeblockingFilterOffsetInPPS and DeblockingFilterDisable must be 0)
 
 #=========== Misc. ============
 InternalBitDepth              : 10          # codec operating bit-depth
@@ -89,12 +89,6 @@ TransformSkipFast             : 1           # Fast Transform skipping (0: OFF, 1
 TransformSkipLog2MaxSize      : 5
 SAOLcuBoundary                : 0           # SAOLcuBoundary using non-deblocked pixels (0: OFF, 1: ON)
 
-#=========== TemporalFilter =================
-TemporalFilter                : 0           # Enable/disable GOP Based Temporal Filter
-TemporalFilterFutureReference : 1           # Enable/disable reading future frames
-TemporalFilterStrengthFrame8  : 0.95        # Enable filter at every 8th frame with given strength
-TemporalFilterStrengthFrame16 : 1.5         # Enable filter at every 16th frame with given strength, longer intervals has higher priority
-
 #============ Rate Control ======================
 RateControl                         : 0                # Rate control: enable rate control
 TargetBitrate                       : 1000000          # Rate control: target bitrate, in bps
@@ -172,10 +166,14 @@ ChromaTS                     : 1
 # Encoder optimization tools
 AffineAmvrEncOpt             : 1
 MmvdDisNum                   : 6
-TemporalFilter               : 1
-ALFStrength                  : 1.0
 ALFAllowPredefinedFilters    : 1
-CCALFStrength                : 1.0
+ALFStrengthTargetLuma        : 1.0
+ALFStrengthTargetChroma      : 1.0
+CCALFStrengthTarget          : 1.0
+TemporalFilter                : 1           # Enable/disable GOP Based Temporal Filter
+TemporalFilterFutureReference : 1           # Enable/disable reading future frames
+TemporalFilterStrengthFrame8  : 0.95        # Enable filter at every 8th frame with given strength
+TemporalFilterStrengthFrame16 : 1.5         # Enable filter at every 16th frame with given strength, longer intervals has higher priority
 ### DO NOT ADD ANYTHING BELOW THIS LINE ###
 ### DO NOT DELETE THE EMPTY LINE BELOW ###
 
diff --git a/cfg/encoder_randomaccess_vtm_gop16.cfg b/cfg/encoder_randomaccess_vtm_gop16.cfg
index e44197cf9..48f3b2d00 100644
--- a/cfg/encoder_randomaccess_vtm_gop16.cfg
+++ b/cfg/encoder_randomaccess_vtm_gop16.cfg
@@ -53,15 +53,15 @@ RDOQ                          : 1           # RDOQ
 RDOQTS                        : 1           # RDOQ for transform skip
 
 #=========== Deblock Filter ============
-LoopFilterOffsetInPPS         : 1           # Dbl params: 0=varying params in SliceHeader, param = base_param + GOP_offset_param; 1 (default) =constant params in PPS, param = base_param)
-LoopFilterDisable             : 0           # Disable deblocking filter (0=Filter, 1=No Filter)
-LoopFilterBetaOffset_div2     : 0           # base_param: -12 ~ 12
-LoopFilterTcOffset_div2       : 0           # base_param: -12 ~ 12
-LoopFilterCbBetaOffset_div2   : 0           # base_param: -12 ~ 12
-LoopFilterCbTcOffset_div2     : 0           # base_param: -12 ~ 12
-LoopFilterCrBetaOffset_div2   : 0           # base_param: -12 ~ 12
-LoopFilterCrTcOffset_div2     : 0           # base_param: -12 ~ 12
-DeblockingFilterMetric        : 0           # blockiness metric (automatically configures deblocking parameters in bitstream). Applies slice-level loop filter offsets (LoopFilterOffsetInPPS and LoopFilterDisable must be 0)
+DeblockingFilterOffsetInPPS         : 1           # Dbl params: 0=varying params in SliceHeader, param = base_param + GOP_offset_param; 1 (default) =constant params in PPS, param = base_param)
+DeblockingFilterDisable             : 0           # Disable deblocking filter (0=Filter, 1=No Filter)
+DeblockingFilterBetaOffset_div2     : 0           # base_param: -12 ~ 12
+DeblockingFilterTcOffset_div2       : 0           # base_param: -12 ~ 12
+DeblockingFilterCbBetaOffset_div2   : 0           # base_param: -12 ~ 12
+DeblockingFilterCbTcOffset_div2     : 0           # base_param: -12 ~ 12
+DeblockingFilterCrBetaOffset_div2   : 0           # base_param: -12 ~ 12
+DeblockingFilterCrTcOffset_div2     : 0           # base_param: -12 ~ 12
+DeblockingFilterMetric        : 0           # blockiness metric (automatically configures deblocking parameters in bitstream). Applies slice-level loop filter offsets (DeblockingFilterOffsetInPPS and DeblockingFilterDisable must be 0)
 
 #=========== Misc. ============
 InternalBitDepth              : 10          # codec operating bit-depth
@@ -73,12 +73,6 @@ TransformSkipFast             : 1           # Fast Transform skipping (0: OFF, 1
 TransformSkipLog2MaxSize      : 5
 SAOLcuBoundary                : 0           # SAOLcuBoundary using non-deblocked pixels (0: OFF, 1: ON)
 
-#=========== TemporalFilter =================
-TemporalFilter                : 0           # Enable/disable GOP Based Temporal Filter
-TemporalFilterFutureReference : 1           # Enable/disable reading future frames
-TemporalFilterStrengthFrame8  : 0.95        # Enable filter at every 8th frame with given strength
-TemporalFilterStrengthFrame16 : 1.5         # Enable filter at every 16th frame with given strength, longer intervals has higher priority
-
 #============ Rate Control ======================
 RateControl                         : 0                # Rate control: enable rate control
 TargetBitrate                       : 1000000          # Rate control: target bitrate, in bps
@@ -156,10 +150,14 @@ ChromaTS                     : 1
 # Encoder optimization tools
 AffineAmvrEncOpt             : 1
 MmvdDisNum                   : 6
-TemporalFilter               : 1
-ALFStrength                  : 1.0
 ALFAllowPredefinedFilters    : 1
-CCALFStrength                : 1.0
+ALFStrengthTargetLuma        : 1.0
+ALFStrengthTargetChroma      : 1.0
+CCALFStrengthTarget          : 1.0
+TemporalFilter                : 1           # Enable/disable GOP Based Temporal Filter
+TemporalFilterFutureReference : 1           # Enable/disable reading future frames
+TemporalFilterStrengthFrame8  : 0.95        # Enable filter at every 8th frame with given strength
+TemporalFilterStrengthFrame16 : 1.5         # Enable filter at every 16th frame with given strength, longer intervals has higher priority
 ### DO NOT ADD ANYTHING BELOW THIS LINE ###
 ### DO NOT DELETE THE EMPTY LINE BELOW ###
 
diff --git a/cfg/examples_SEI_CTI/readMe.txt b/cfg/examples_SEI_CTI/readMe.txt
new file mode 100644
index 000000000..04fb12dbe
--- /dev/null
+++ b/cfg/examples_SEI_CTI/readMe.txt
@@ -0,0 +1,7 @@
+example encoding command line
+encoder -c encoder_randomaccess_vtm.cfg -c classH1.cfg -c H1_BalloonFestival.cfg -c seiCti_hdrPq_to_sdr1.cfg
+        -i BalloonFestival_1920x1080p_24_10b_pq_709_ct2020_420_rev1.yuv -ip 32 -fs 0 -f 33 -q 22 
+        -b BalloonFestival_1920x1080p_24_10b_pq_709_ct2020_420_rev1.bin -o /dev/null --InternalBitDepth=10 --OutputBitDepth=10 
+
+example decoding command line
+decoder -b BalloonFestival_1920x1080p_24_10b_pq_709_ct2020_420_rev1.bin -o dec.yuv --SEICTIFilename=dec_cti.yuv
\ No newline at end of file
diff --git a/cfg/examples_SEI_CTI/seiCti_hdrPq_to_sdr1.cfg b/cfg/examples_SEI_CTI/seiCti_hdrPq_to_sdr1.cfg
new file mode 100644
index 000000000..8ac807a9a
--- /dev/null
+++ b/cfg/examples_SEI_CTI/seiCti_hdrPq_to_sdr1.cfg
@@ -0,0 +1,24 @@
+# example mapping SDR BT.2020 std range to BT.2100 HDR-PQ-like Std range 
+# this is provided as indicative example, but in principle the mapping curve should be dynamically tuned depending on the content
+
+SEICTIEnabled                 : 1
+SEICTIId                      : 1
+
+SEICTISignalInfoFlag          : 1
+SEICTIFullRangeFlag           : 0
+SEICTIPrimaries               : 9
+SEICTITransferFunction        : 14
+SEICTIMatrixCoefs             : 9
+
+SEICTICrossCompFlag           : 1
+SEICTICrossCompInferred       : 1
+SEICTILut0                    : 64 00 41 41 41 41 44 50 56 62 70 78 87 97 109 79 00 # Lut Y 
+
+SEICTIChromaOffset            : 0      # chroma scaling offset
+
+### DO NOT ADD ANYTHING BELOW THIS LINE ###
+### DO NOT DELETE THE EMPTY LINE BELOW ###
+
+
+
+
diff --git a/cfg/examples_SEI_CTI/seiCti_hdrPq_to_sdr2.cfg b/cfg/examples_SEI_CTI/seiCti_hdrPq_to_sdr2.cfg
new file mode 100644
index 000000000..715d8756e
--- /dev/null
+++ b/cfg/examples_SEI_CTI/seiCti_hdrPq_to_sdr2.cfg
@@ -0,0 +1,21 @@
+# example mapping BT.2100 HDR-PQ Std range to SDR-like BT.2020 std range
+# this is provided as indicative example, but in principle the mapping curve should be dynamically tuned depending on the content
+
+SEICTIEnabled                 : 1
+SEICTIId                      : 1
+
+SEICTISignalInfoFlag          : 1
+SEICTIFullRangeFlag           : 0
+SEICTIPrimaries               : 9
+SEICTITransferFunction        : 14
+SEICTIMatrixCoefs             : 9
+
+SEICTICrossCompFlag           : 1      # cross-component scaling mode enabled or not
+SEICTICrossCompInferred       : 0      # chroma LUT inferred (1) or not (0) from luma LUT
+SEICTINbChromaLut             : 1      # nb of chroma LUT (1 or 2)
+SEICTILut0                    : 64 00 41 41 41 41 44 50 56 62 70 78 87 97 109 79 00 # Lut Y 
+SEICTILut1                    : 64 56 47 47 47 48 51 56 60 66 72 78 85 93 87  70 64 # Lut chroma 
+SEICTIChromaOffset            : 0      # chroma scaling offset
+
+### DO NOT ADD ANYTHING BELOW THIS LINE ###
+### DO NOT DELETE THE EMPTY LINE BELOW ###
diff --git a/cfg/examples_SEI_CTI/seiCti_sdr_to_hdrPq1.cfg b/cfg/examples_SEI_CTI/seiCti_sdr_to_hdrPq1.cfg
new file mode 100644
index 000000000..08efe7406
--- /dev/null
+++ b/cfg/examples_SEI_CTI/seiCti_sdr_to_hdrPq1.cfg
@@ -0,0 +1,22 @@
+# example mapping BT.2100 HDR-PQ Std range to SDR-like BT.2020 std range
+# this is provided as indicative example, but in principle the mapping curve should be dynamically tuned depending on the content
+
+SEICTIEnabled                 : 1
+SEICTIId                      : 1
+
+SEICTISignalInfoFlag          : 1
+SEICTIFullRangeFlag           : 0
+SEICTIPrimaries               : 9
+SEICTITransferFunction        : 16
+SEICTIMatrixCoefs             : 9
+
+SEICTICrossCompFlag           : 1
+SEICTICrossCompInferred       : 1
+SEICTILut0                    : 64 00 103 101 97 79 72 67 58 54 47 46 42 39 41 50 00 # Lut Y 
+SEICTIChromaOffset            : 0      # chroma scaling offset
+
+### DO NOT ADD ANYTHING BELOW THIS LINE ###
+### DO NOT DELETE THE EMPTY LINE BELOW ###
+
+
+
diff --git a/cfg/hbd/12-bit.cfg b/cfg/hbd/12-bit.cfg
index 55af5e790..9f9bba34c 100755
--- a/cfg/hbd/12-bit.cfg
+++ b/cfg/hbd/12-bit.cfg
@@ -1,3 +1,2 @@
 InternalBitDepth:  12
-MaxBitDepthConstraint: 12
-ExtendedPrecision: 0
+MaxBitDepthConstraint: 12
\ No newline at end of file
diff --git a/cfg/hbd/16-bit.cfg b/cfg/hbd/16-bit.cfg
index c9254b5be..ea7124764 100755
--- a/cfg/hbd/16-bit.cfg
+++ b/cfg/hbd/16-bit.cfg
@@ -1,3 +1,2 @@
 InternalBitDepth:  16
-MaxBitDepthConstraint: 16
-ExtendedPrecision: 1
+MaxBitDepthConstraint: 16
\ No newline at end of file
diff --git a/cfg/hbd/hbd.cfg b/cfg/hbd/hbd.cfg
index 0a984507a..88af1fdb6 100755
--- a/cfg/hbd/hbd.cfg
+++ b/cfg/hbd/hbd.cfg
@@ -5,4 +5,20 @@ MaxTTLumaISlice:  16
 MaxTTNonISlice:   16
 LFNST:            0
 TemporalFilter:   0
-Profile:          none
+Profile:          auto
+#Updates for JVET-U2018
+LMCSEnable:       0
+BCW:              0
+MMVD:             0
+SMVD:             0
+Geo:              0
+BIO:              0
+DMVR:             0
+Affine:           0
+ISP:              0
+TSRCRicePresent:  1
+
+ExtendedPrecision: 1
+ExtendedRiceRRC               : 1
+GolombRiceParameterAdaptation : 1
+ReverseLastSigCoeff : 1
diff --git a/cfg/lossless/lossless.cfg b/cfg/lossless/lossless.cfg
index 793b2bedb..42c6884ba 100644
--- a/cfg/lossless/lossless.cfg
+++ b/cfg/lossless/lossless.cfg
@@ -11,7 +11,7 @@ ISP                          : 0
 MTS                          : 0
 LFNST                        : 0
 JointCbCr                    : 0
-LoopFilterDisable            : 1
+DeblockingFilterDisable      : 1
 SAO                          : 0
 ALF                          : 0
 CCALF                        : 0
diff --git a/cfg/lossless/lossless_mixed.cfg b/cfg/lossless/lossless_mixed.cfg
index 5fbdd0bed..e7d38327f 100644
--- a/cfg/lossless/lossless_mixed.cfg
+++ b/cfg/lossless/lossless_mixed.cfg
@@ -11,7 +11,7 @@ ISP                          : 0
 MTS                          : 0
 LFNST                        : 0
 JointCbCr                    : 0
-LoopFilterDisable            : 0
+DeblockingFilterDisable      : 0
 SAO                          : 1
 ALF                          : 1
 CCALF                        : 0
diff --git a/cfg/per-class/classH1.cfg b/cfg/per-class/classH1.cfg
index a6b09ffa1..5a2c188cd 100644
--- a/cfg/per-class/classH1.cfg
+++ b/cfg/per-class/classH1.cfg
@@ -25,3 +25,5 @@ VerCollocatedChroma           : 1
 
 #======== HDR Metrics ============
 CalculateHdrMetrics           : 1           # Calculate HDR metrics for Class H1 (PQ) content
+
+PrintWPSNR                    : 1
\ No newline at end of file
diff --git a/cfg/per-sequence-HBD/H1_BalloonFestival_420_12bit.cfg b/cfg/per-sequence-HBD/H1_BalloonFestival_420_12bit.cfg
new file mode 100755
index 000000000..e6588836d
--- /dev/null
+++ b/cfg/per-sequence-HBD/H1_BalloonFestival_420_12bit.cfg
@@ -0,0 +1,11 @@
+#======== File I/O ===============
+InputFile                     : BalloonFestival_1920x1080p_24_12b_pq_709_ct2020_420.yuv
+InputBitDepth                 : 12          # Input bitdepth
+InputChromaFormat             : 420         # Ratio of luminance to chrominance samples
+FrameRate                     : 24          # Frame Rate per second
+FrameSkip                     : 0           # Number of frames to be skipped in input
+SourceWidth                   : 1920        # Input  frame width
+SourceHeight                  : 1080         # Input  frame height
+FramesToBeEncoded             : 240         # Number of frames to be coded
+
+Level                         : 4.1
diff --git a/cfg/per-sequence-HBD/H1_FireEater2_420_12bit.cfg b/cfg/per-sequence-HBD/H1_FireEater2_420_12bit.cfg
new file mode 100755
index 000000000..92f264ecd
--- /dev/null
+++ b/cfg/per-sequence-HBD/H1_FireEater2_420_12bit.cfg
@@ -0,0 +1,11 @@
+#======== File I/O ===============
+InputFile                     : FireEater2Clip4000r1_1920x1080p_25_12b_pq_709_ct2020_420.yuv
+InputBitDepth                 : 12          # Input bitdepth
+InputChromaFormat             : 420         # Ratio of luminance to chrominance samples
+FrameRate                     : 25          # Frame Rate per second
+FrameSkip                     : 0           # Number of frames to be skipped in input
+SourceWidth                   : 1920        # Input  frame width
+SourceHeight                  : 1080        # Input  frame height
+FramesToBeEncoded             : 200         # Number of frames to be coded
+
+Level                         : 4.1
diff --git a/cfg/per-sequence-HBD/H1_Hurdles_420_12bit.cfg b/cfg/per-sequence-HBD/H1_Hurdles_420_12bit.cfg
new file mode 100755
index 000000000..7aec9ed6a
--- /dev/null
+++ b/cfg/per-sequence-HBD/H1_Hurdles_420_12bit.cfg
@@ -0,0 +1,11 @@
+#======== File I/O ===============
+InputFile                     : EBU_04_Hurdles_1920x1080p_50_12b_pq_709_ct2020_420.yuv
+InputBitDepth                 : 12          # Input bitdepth
+InputChromaFormat             : 420         # Ratio of luminance to chrominance samples
+FrameRate                     : 50          # Frame Rate per second
+FrameSkip                     : 0           # Number of frames to be skipped in input
+SourceWidth                   : 1920        # Input  frame width
+SourceHeight                  : 1080        # Input  frame height
+FramesToBeEncoded             : 500         # Number of frames to be coded
+
+Level                         : 4.1
diff --git a/cfg/per-sequence-HBD/H1_Market3_420_12bit.cfg b/cfg/per-sequence-HBD/H1_Market3_420_12bit.cfg
new file mode 100755
index 000000000..d4c493d37
--- /dev/null
+++ b/cfg/per-sequence-HBD/H1_Market3_420_12bit.cfg
@@ -0,0 +1,11 @@
+#======== File I/O ===============
+InputFile                     : Market3Clip4000r2_1920x1080p_50_12b_pq_709_ct2020_420.yuv
+InputBitDepth                 : 12          # Input bitdepth
+InputChromaFormat             : 420         # Ratio of luminance to chrominance samples
+FrameRate                     : 50          # Frame Rate per second
+FrameSkip                     : 0           # Number of frames to be skipped in input
+SourceWidth                   : 1920        # Input  frame width
+SourceHeight                  : 1080        # Input  frame height
+FramesToBeEncoded             : 400         # Number of frames to be coded
+
+Level                         : 4.1
diff --git a/cfg/per-sequence-HBD/H1_Starting_420_12bit.cfg b/cfg/per-sequence-HBD/H1_Starting_420_12bit.cfg
new file mode 100755
index 000000000..bc8e6af00
--- /dev/null
+++ b/cfg/per-sequence-HBD/H1_Starting_420_12bit.cfg
@@ -0,0 +1,11 @@
+#======== File I/O ===============
+InputFile                     : EBU_06_Starting_1920x1080p_50_12b_pq_709_ct2020_420.yuv
+InputBitDepth                 : 12          # Input bitdepth
+InputChromaFormat             : 420         # Ratio of luminance to chrominance samples
+FrameRate                     : 50          # Frame Rate per second
+FrameSkip                     : 0           # Number of frames to be skipped in input
+SourceWidth                   : 1920        # Input  frame width
+SourceHeight                  : 1080        # Input  frame height
+FramesToBeEncoded             : 500         # Number of frames to be coded
+
+Level                         : 4.1
diff --git a/cfg/per-sequence-HBD/H2_DayStreet_420_12bit.cfg b/cfg/per-sequence-HBD/H2_DayStreet_420_12bit.cfg
new file mode 100755
index 000000000..3bdaf26ad
--- /dev/null
+++ b/cfg/per-sequence-HBD/H2_DayStreet_420_12bit.cfg
@@ -0,0 +1,11 @@
+#======== File I/O ===============
+InputFile                     : DayStreet_1920x1080_60p_12bit_420_hlg.yuv
+InputBitDepth                 : 12          # Input bitdepth
+InputChromaFormat             : 420         # Ratio of luminance to chrominance samples
+FrameRate                     : 60          # Frame Rate per second
+FrameSkip                     : 0           # Number of frames to be skipped in input
+SourceWidth                   : 1920        # Input  frame width
+SourceHeight                  : 1080        # Input  frame height
+FramesToBeEncoded             : 600         # Number of frames to be coded
+
+Level                         : 4.1
diff --git a/cfg/per-sequence-HBD/H2_DayStreet_422_12bit.cfg b/cfg/per-sequence-HBD/H2_DayStreet_422_12bit.cfg
index d0688d68a..3fd3b59f1 100755
--- a/cfg/per-sequence-HBD/H2_DayStreet_422_12bit.cfg
+++ b/cfg/per-sequence-HBD/H2_DayStreet_422_12bit.cfg
@@ -1,11 +1,11 @@
 #======== File I/O ===============
-InputFile                     : DayStreet_3840x2160_60p_12bit_422_hlg.yuv
+InputFile                     : DayStreet_1920x1080_60p_12bit_422_hlg.yuv
 InputBitDepth                 : 12          # Input bitdepth
 InputChromaFormat             : 422         # Ratio of luminance to chrominance samples
 FrameRate                     : 60          # Frame Rate per second
 FrameSkip                     : 0           # Number of frames to be skipped in input
-SourceWidth                   : 3840        # Input  frame width
-SourceHeight                  : 2160        # Input  frame height
+SourceWidth                   : 1920        # Input  frame width
+SourceHeight                  : 1080        # Input  frame height
 FramesToBeEncoded             : 600         # Number of frames to be coded
 
-Level                         : 5.1
+Level                         : 4.1
diff --git a/cfg/per-sequence-HBD/H2_DayStreet_444_12bit.cfg b/cfg/per-sequence-HBD/H2_DayStreet_444_12bit.cfg
index cab0cf34b..ed95d68b2 100755
--- a/cfg/per-sequence-HBD/H2_DayStreet_444_12bit.cfg
+++ b/cfg/per-sequence-HBD/H2_DayStreet_444_12bit.cfg
@@ -1,11 +1,11 @@
 #======== File I/O ===============
-InputFile                     : DayStreet_3840x2160_60p_12bit_444_hlg.yuv
+InputFile                     : DayStreet_1920x1080_60p_12bit_444_hlg.yuv
 InputBitDepth                 : 12          # Input bitdepth
 InputChromaFormat             : 444         # Ratio of luminance to chrominance samples
 FrameRate                     : 60          # Frame Rate per second
 FrameSkip                     : 0           # Number of frames to be skipped in input
-SourceWidth                   : 3840        # Input  frame width
-SourceHeight                  : 2160        # Input  frame height
+SourceWidth                   : 1920        # Input  frame width
+SourceHeight                  : 1080        # Input  frame height
 FramesToBeEncoded             : 600         # Number of frames to be coded
 
-Level                         : 5.1
+Level                         : 4.1
diff --git a/cfg/per-sequence-HBD/H2_NightStreet_420_12bit.cfg b/cfg/per-sequence-HBD/H2_NightStreet_420_12bit.cfg
new file mode 100755
index 000000000..5a7133629
--- /dev/null
+++ b/cfg/per-sequence-HBD/H2_NightStreet_420_12bit.cfg
@@ -0,0 +1,11 @@
+#======== File I/O ===============
+InputFile                     : NightStreet_1920x1080_60p_12bit_420_hlg.yuv
+InputBitDepth                 : 12          # Input bitdepth
+InputChromaFormat             : 420         # Ratio of luminance to chrominance samples
+FrameRate                     : 60          # Frame Rate per second
+FrameSkip                     : 0           # Number of frames to be skipped in input
+SourceWidth                   : 1920        # Input  frame width
+SourceHeight                  : 1080        # Input  frame height
+FramesToBeEncoded             : 600         # Number of frames to be coded
+
+Level                         : 4.1
diff --git a/cfg/per-sequence-HBD/H2_NightStreet_422_12bit.cfg b/cfg/per-sequence-HBD/H2_NightStreet_422_12bit.cfg
index 22ea3fae8..c5e44eafc 100755
--- a/cfg/per-sequence-HBD/H2_NightStreet_422_12bit.cfg
+++ b/cfg/per-sequence-HBD/H2_NightStreet_422_12bit.cfg
@@ -1,11 +1,11 @@
 #======== File I/O ===============
-InputFile                     : NightStreet_3840x2160_60p_12bit_422_hlg.yuv
+InputFile                     : NightStreet_1920x1080_60p_12bit_422_hlg.yuv
 InputBitDepth                 : 12          # Input bitdepth
 InputChromaFormat             : 422         # Ratio of luminance to chrominance samples
 FrameRate                     : 60          # Frame Rate per second
 FrameSkip                     : 0           # Number of frames to be skipped in input
-SourceWidth                   : 3840        # Input  frame width
-SourceHeight                  : 2160        # Input  frame height
+SourceWidth                   : 1920        # Input  frame width
+SourceHeight                  : 1080        # Input  frame height
 FramesToBeEncoded             : 600         # Number of frames to be coded
 
-Level                         : 5.1
+Level                         : 4.1
diff --git a/cfg/per-sequence-HBD/H2_NightStreet_444_12bit.cfg b/cfg/per-sequence-HBD/H2_NightStreet_444_12bit.cfg
index 23e48c460..a5fa00261 100755
--- a/cfg/per-sequence-HBD/H2_NightStreet_444_12bit.cfg
+++ b/cfg/per-sequence-HBD/H2_NightStreet_444_12bit.cfg
@@ -1,11 +1,11 @@
 #======== File I/O ===============
-InputFile                     : NightStreet_3840x2160_60p_12bit_444_hlg.yuv
+InputFile                     : NightStreet_1920x1080_60p_12bit_444_hlg.yuv
 InputBitDepth                 : 12          # Input bitdepth
 InputChromaFormat             : 444         # Ratio of luminance to chrominance samples
 FrameRate                     : 60          # Frame Rate per second
 FrameSkip                     : 0           # Number of frames to be skipped in input
-SourceWidth                   : 3840        # Input  frame width
-SourceHeight                  : 2160        # Input  frame height
+SourceWidth                   : 1920        # Input  frame width
+SourceHeight                  : 1080        # Input  frame height
 FramesToBeEncoded             : 600         # Number of frames to be coded
 
-Level                         : 5.1
+Level                         : 4.1
diff --git a/cfg/per-sequence-HBD/H2_PeopleInShoppingCenter_420_12bit.cfg b/cfg/per-sequence-HBD/H2_PeopleInShoppingCenter_420_12bit.cfg
new file mode 100755
index 000000000..1c78855b4
--- /dev/null
+++ b/cfg/per-sequence-HBD/H2_PeopleInShoppingCenter_420_12bit.cfg
@@ -0,0 +1,11 @@
+#======== File I/O ===============
+InputFile                     : PeopleInShoppingCenter_1920x1080_60p_12bit_420_hlg.yuv
+InputBitDepth                 : 12          # Input bitdepth
+InputChromaFormat             : 420         # Ratio of luminance to chrominance samples
+FrameRate                     : 60          # Frame Rate per second
+FrameSkip                     : 0           # Number of frames to be skipped in input
+SourceWidth                   : 1920        # Input  frame width
+SourceHeight                  : 1080        # Input  frame height
+FramesToBeEncoded             : 600         # Number of frames to be coded
+
+Level                         : 4.1
diff --git a/cfg/per-sequence-HBD/H2_PeopleInShoppingCenter_422_12bit.cfg b/cfg/per-sequence-HBD/H2_PeopleInShoppingCenter_422_12bit.cfg
index 3041cb930..5f7b2fa3b 100755
--- a/cfg/per-sequence-HBD/H2_PeopleInShoppingCenter_422_12bit.cfg
+++ b/cfg/per-sequence-HBD/H2_PeopleInShoppingCenter_422_12bit.cfg
@@ -1,11 +1,11 @@
 #======== File I/O ===============
-InputFile                     : PeopleInShoppingCenter_3840x2160_60p_12bit_422_hlg.yuv
+InputFile                     : PeopleInShoppingCenter_1920x1080_60p_12bit_422_hlg.yuv
 InputBitDepth                 : 12          # Input bitdepth
 InputChromaFormat             : 422         # Ratio of luminance to chrominance samples
 FrameRate                     : 60          # Frame Rate per second
 FrameSkip                     : 0           # Number of frames to be skipped in input
-SourceWidth                   : 3840        # Input  frame width
-SourceHeight                  : 2160        # Input  frame height
+SourceWidth                   : 1920        # Input  frame width
+SourceHeight                  : 1080        # Input  frame height
 FramesToBeEncoded             : 600         # Number of frames to be coded
 
-Level                         : 5.1
+Level                         : 4.1
diff --git a/cfg/per-sequence-HBD/H2_PeopleInShoppingCenter_444_12bit.cfg b/cfg/per-sequence-HBD/H2_PeopleInShoppingCenter_444_12bit.cfg
index 103fe4a0a..d1f9d02b8 100755
--- a/cfg/per-sequence-HBD/H2_PeopleInShoppingCenter_444_12bit.cfg
+++ b/cfg/per-sequence-HBD/H2_PeopleInShoppingCenter_444_12bit.cfg
@@ -1,11 +1,11 @@
 #======== File I/O ===============
-InputFile                     : PeopleInShoppingCenter_3840x2160_60p_12bit_444_hlg.yuv
+InputFile                     : PeopleInShoppingCenter_1920x1080_60p_12bit_444_hlg.yuv
 InputBitDepth                 : 12          # Input bitdepth
 InputChromaFormat             : 444         # Ratio of luminance to chrominance samples
 FrameRate                     : 60          # Frame Rate per second
 FrameSkip                     : 0           # Number of frames to be skipped in input
-SourceWidth                   : 3840        # Input  frame width
-SourceHeight                  : 2160        # Input  frame height
+SourceWidth                   : 1920        # Input  frame width
+SourceHeight                  : 1080        # Input  frame height
 FramesToBeEncoded             : 600         # Number of frames to be coded
 
-Level                         : 5.1
+Level                         : 4.1
diff --git a/cfg/per-sequence-HBD/H2_StainedGlass_420_12bit.cfg b/cfg/per-sequence-HBD/H2_StainedGlass_420_12bit.cfg
new file mode 100755
index 000000000..76af78772
--- /dev/null
+++ b/cfg/per-sequence-HBD/H2_StainedGlass_420_12bit.cfg
@@ -0,0 +1,11 @@
+#======== File I/O ===============
+InputFile                     : StainedGlass_1920x1080_60p_12bit_420_hlg.yuv
+InputBitDepth                 : 12          # Input bitdepth
+InputChromaFormat             : 420         # Ratio of luminance to chrominance samples
+FrameRate                     : 60          # Frame Rate per second
+FrameSkip                     : 0           # Number of frames to be skipped in input
+SourceWidth                   : 1920        # Input  frame width
+SourceHeight                  : 1080        # Input  frame height
+FramesToBeEncoded             : 600         # Number of frames to be coded
+
+Level                         : 4.1
diff --git a/cfg/per-sequence-HBD/H2_StainedGlass_422_12bit.cfg b/cfg/per-sequence-HBD/H2_StainedGlass_422_12bit.cfg
index 2a4f9157d..8be6ffdf5 100755
--- a/cfg/per-sequence-HBD/H2_StainedGlass_422_12bit.cfg
+++ b/cfg/per-sequence-HBD/H2_StainedGlass_422_12bit.cfg
@@ -1,11 +1,11 @@
 #======== File I/O ===============
-InputFile                     : StainedGlass_3840x2160_60p_12bit_422_hlg.yuv
+InputFile                     : StainedGlass_1920x1080_60p_12bit_422_hlg.yuv
 InputBitDepth                 : 12          # Input bitdepth
 InputChromaFormat             : 422         # Ratio of luminance to chrominance samples
 FrameRate                     : 60          # Frame Rate per second
 FrameSkip                     : 0           # Number of frames to be skipped in input
-SourceWidth                   : 3840        # Input  frame width
-SourceHeight                  : 2160        # Input  frame height
+SourceWidth                   : 1920        # Input  frame width
+SourceHeight                  : 1080        # Input  frame height
 FramesToBeEncoded             : 600         # Number of frames to be coded
 
-Level                         : 5.1
+Level                         : 4.1
diff --git a/cfg/per-sequence-HBD/H2_StainedGlass_444_12bit.cfg b/cfg/per-sequence-HBD/H2_StainedGlass_444_12bit.cfg
index 64dc9d0a2..3ed647d98 100755
--- a/cfg/per-sequence-HBD/H2_StainedGlass_444_12bit.cfg
+++ b/cfg/per-sequence-HBD/H2_StainedGlass_444_12bit.cfg
@@ -1,11 +1,11 @@
 #======== File I/O ===============
-InputFile                     : StainedGlass_3840x2160_60p_12bit_444_hlg.yuv
+InputFile                     : StainedGlass_1920x1080_60p_12bit_444_hlg.yuv
 InputBitDepth                 : 12          # Input bitdepth
 InputChromaFormat             : 444         # Ratio of luminance to chrominance samples
 FrameRate                     : 60          # Frame Rate per second
 FrameSkip                     : 0           # Number of frames to be skipped in input
-SourceWidth                   : 3840        # Input  frame width
-SourceHeight                  : 2160        # Input  frame height
+SourceWidth                   : 1920        # Input  frame width
+SourceHeight                  : 1080        # Input  frame height
 FramesToBeEncoded             : 600         # Number of frames to be coded
 
-Level                         : 5.1
+Level                         : 4.1
diff --git a/cfg/sei_vui/alpha_channel_info.cfg b/cfg/sei_vui/alpha_channel_info.cfg
new file mode 100644
index 000000000..de33a9664
--- /dev/null
+++ b/cfg/sei_vui/alpha_channel_info.cfg
@@ -0,0 +1,10 @@
+#======== Alpha Channel Information SEI message =====================
+SEIACIEnabled                               : 1
+SEIACICancelFlag                            : 0
+SEIACIUseIdc                                : 0
+SEIACIBitDepthMinus8                        : 0
+SEIACITransparentValue                      : 0
+SEIACIOpaqueValue                           : 255
+SEIACIIncrFlag                              : 0
+SEIACIClipFlag                              : 0
+SEIACIClipTypeFlag                          : 0
diff --git a/cfg/sei_vui/annotated_regions/anno_reg_0.txt b/cfg/sei_vui/annotated_regions/anno_reg_0.txt
new file mode 100644
index 000000000..8e8c98532
--- /dev/null
+++ b/cfg/sei_vui/annotated_regions/anno_reg_0.txt
@@ -0,0 +1,48 @@
+SEIArCancelFlag: 0
+SEIArNotOptForViewingFlag: 0
+SEIArTrueMotionFlag: 0
+SEIArOccludedObjsFlag: 0
+SEIArPartialObjsFlagPresentFlag: 0
+SEIArObjLabelPresentFlag: 1
+SEIArObjConfInfoPresentFlag: 1
+SEIArObjDetConfLength: 7
+SEIArObjLabelLangPresentFlag: 1
+SEIArLabelLanguage: ENGLISH
+SEIArNumLabelUpdates: 2
+SEIArLabelIdc[c]: 0
+SEIArLabelCancelFlag[c]: 0
+SEIArLabel[c]: car
+SEIArLabelIdc[c]: 1
+SEIArLabelCancelFlag[c]: 0
+SEIArLabel[c]: person
+SEIArNumObjUpdates: 3
+SEIArObjIdx[c]: 0
+SEIArObjCancelFlag[c]: 0
+SEIArObjLabelUpdateFlag[c]: 1
+SEIArObjectLabelIdc[c]: 0
+SEIArBoundBoxUpdateFlag[c]: 1
+SEIArObjTop[c]: 10
+SEIArObjLeft[c]: 10
+SEIArObjWidth[c]: 50
+SEIArObjHeight[c]: 50
+SEIArObjDetConf[c]: 90
+SEIArObjIdx[c]: 1
+SEIArObjCancelFlag[c]: 0
+SEIArObjLabelUpdateFlag[c]: 1
+SEIArObjectLabelIdc[c]: 0
+SEIArBoundBoxUpdateFlag[c]: 1
+SEIArObjTop[c]: 100
+SEIArObjLeft[c]: 100
+SEIArObjWidth[c]: 50
+SEIArObjHeight[c]: 50
+SEIArObjDetConf[c]: 90
+SEIArObjIdx[c]: 2
+SEIArObjCancelFlag[c]: 0
+SEIArObjLabelUpdateFlag[c]: 1
+SEIArObjectLabelIdc[c]: 1
+SEIArBoundBoxUpdateFlag[c]: 1
+SEIArObjTop[c]: 200
+SEIArObjLeft[c]: 200
+SEIArObjWidth[c]: 80
+SEIArObjHeight[c]: 100
+SEIArObjDetConf[c]: 85
diff --git a/cfg/sei_vui/annotated_regions/anno_reg_1.txt b/cfg/sei_vui/annotated_regions/anno_reg_1.txt
new file mode 100644
index 000000000..5508a22a7
--- /dev/null
+++ b/cfg/sei_vui/annotated_regions/anno_reg_1.txt
@@ -0,0 +1,31 @@
+SEIArCancelFlag: 0
+SEIArNotOptForViewingFlag: 0
+SEIArTrueMotionFlag: 0
+SEIArOccludedObjsFlag: 0
+SEIArPartialObjsFlagPresentFlag: 0
+SEIArObjLabelPresentFlag: 1
+SEIArObjConfInfoPresentFlag: 1
+SEIArObjDetConfLength: 7
+SEIArObjLabelLangPresentFlag: 1
+SEIArLabelLanguage: ENGLISH
+SEIArNumLabelUpdates: 0
+SEIArNumObjUpdates: 2
+SEIArObjIdx[c]: 0
+SEIArObjCancelFlag[c]: 0
+SEIArObjLabelUpdateFlag[c]: 0
+SEIArBoundBoxUpdateFlag[c]: 1
+SEIArObjTop[c]: 20
+SEIArObjLeft[c]: 20
+SEIArObjWidth[c]: 50
+SEIArObjHeight[c]: 50
+SEIArObjDetConf[c]: 90
+SEIArObjIdx[c]: 3
+SEIArObjCancelFlag[c]: 0
+SEIArObjLabelUpdateFlag[c]: 1
+SEIArObjectLabelIdc[c]: 0
+SEIArBoundBoxUpdateFlag[c]: 1
+SEIArObjTop[c]: 300
+SEIArObjLeft[c]: 300
+SEIArObjWidth[c]: 80
+SEIArObjHeight[c]: 100
+SEIArObjDetConf[c]: 90
diff --git a/cfg/sei_vui/annotated_regions/anno_reg_2.txt b/cfg/sei_vui/annotated_regions/anno_reg_2.txt
new file mode 100644
index 000000000..fd334b850
--- /dev/null
+++ b/cfg/sei_vui/annotated_regions/anno_reg_2.txt
@@ -0,0 +1,43 @@
+SEIArCancelFlag: 0
+SEIArNotOptForViewingFlag: 0
+SEIArTrueMotionFlag: 0
+SEIArOccludedObjsFlag: 0
+SEIArPartialObjsFlagPresentFlag: 0
+SEIArObjLabelPresentFlag: 1
+SEIArObjConfInfoPresentFlag: 1
+SEIArObjDetConfLength: 7
+SEIArObjLabelLangPresentFlag: 1
+SEIArLabelLanguage: ENGLISH
+SEIArNumLabelUpdates: 1
+SEIArLabelIdc[c]: 2
+SEIArLabelCancelFlag[c]: 0
+SEIArLabel[c]: dog
+SEIArNumObjUpdates: 3
+SEIArObjIdx[c]: 1
+SEIArObjCancelFlag[c]: 0
+SEIArObjLabelUpdateFlag[c]: 0
+SEIArBoundBoxUpdateFlag[c]: 1
+SEIArObjTop[c]: 150
+SEIArObjLeft[c]: 150
+SEIArObjWidth[c]: 50
+SEIArObjHeight[c]: 50
+SEIArObjDetConf[c]: 90
+SEIArObjIdx[c]: 2
+SEIArObjCancelFlag[c]: 0
+SEIArObjLabelUpdateFlag[c]: 0
+SEIArBoundBoxUpdateFlag[c]: 1
+SEIArObjTop[c]: 220
+SEIArObjLeft[c]: 220
+SEIArObjWidth[c]: 80
+SEIArObjHeight[c]: 100
+SEIArObjDetConf[c]: 85
+SEIArObjIdx[c]: 4
+SEIArObjCancelFlag[c]: 0
+SEIArObjLabelUpdateFlag[c]: 1
+SEIArObjectLabelIdc[c]: 2
+SEIArBoundBoxUpdateFlag[c]: 1
+SEIArObjTop[c]: 400
+SEIArObjLeft[c]: 400
+SEIArObjWidth[c]: 30
+SEIArObjHeight[c]: 60
+SEIArObjDetConf[c]: 25
diff --git a/cfg/sei_vui/annotated_regions/anno_reg_3.txt b/cfg/sei_vui/annotated_regions/anno_reg_3.txt
new file mode 100644
index 000000000..492368462
--- /dev/null
+++ b/cfg/sei_vui/annotated_regions/anno_reg_3.txt
@@ -0,0 +1,25 @@
+SEIArCancelFlag: 0
+SEIArNotOptForViewingFlag: 0
+SEIArTrueMotionFlag: 0
+SEIArOccludedObjsFlag: 0
+SEIArPartialObjsFlagPresentFlag: 0
+SEIArObjLabelPresentFlag: 1
+SEIArObjConfInfoPresentFlag: 1
+SEIArObjDetConfLength: 7
+SEIArObjLabelLangPresentFlag: 1
+SEIArLabelLanguage: ENGLISH
+SEIArNumLabelUpdates: 1
+SEIArLabelIdc[c]: 2
+SEIArLabelCancelFlag[c]: 1
+SEIArNumObjUpdates: 2
+SEIArObjIdx[c]: 0
+SEIArObjCancelFlag[c]: 0
+SEIArObjLabelUpdateFlag[c]: 0
+SEIArBoundBoxUpdateFlag[c]: 1
+SEIArObjTop[c]: 30
+SEIArObjLeft[c]: 30
+SEIArObjWidth[c]: 50
+SEIArObjHeight[c]: 50
+SEIArObjDetConf[c]: 90
+SEIArObjIdx[c]: 4
+SEIArObjCancelFlag[c]: 1
diff --git a/cfg/sei_vui/annotated_regions/anno_reg_4.txt b/cfg/sei_vui/annotated_regions/anno_reg_4.txt
new file mode 100644
index 000000000..86406d191
--- /dev/null
+++ b/cfg/sei_vui/annotated_regions/anno_reg_4.txt
@@ -0,0 +1,23 @@
+SEIArCancelFlag: 0
+SEIArNotOptForViewingFlag: 0
+SEIArTrueMotionFlag: 0
+SEIArOccludedObjsFlag: 0
+SEIArPartialObjsFlagPresentFlag: 0
+SEIArObjLabelPresentFlag: 1
+SEIArObjConfInfoPresentFlag: 1
+SEIArObjDetConfLength: 7
+SEIArObjLabelLangPresentFlag: 1
+SEIArLabelLanguage: ENGLISH
+SEIArNumLabelUpdates: 0
+SEIArNumObjUpdates: 2
+SEIArObjIdx[c]: 1
+SEIArObjCancelFlag[c]: 0
+SEIArObjLabelUpdateFlag[c]: 0
+SEIArBoundBoxUpdateFlag[c]: 1
+SEIArObjTop[c]: 180
+SEIArObjLeft[c]: 180
+SEIArObjWidth[c]: 50
+SEIArObjHeight[c]: 50
+SEIArObjDetConf[c]: 90
+SEIArObjIdx[c]: 3
+SEIArObjCancelFlag[c]: 1
diff --git a/cfg/sei_vui/depth_representation_info.cfg b/cfg/sei_vui/depth_representation_info.cfg
new file mode 100644
index 000000000..74d2eac35
--- /dev/null
+++ b/cfg/sei_vui/depth_representation_info.cfg
@@ -0,0 +1,14 @@
+#======== Depth Representation Information SEI message =====================
+SEIDRIEnabled                                   : 1
+SEIDRIZNearFlag                                 : 1
+SEIDRIZFarFlag                                  : 1
+SEIDRIDMinFlag                                  : 1
+SEIDRIDMaxFlag                                  : 1
+SEIDRIDepthRepresentationType                   : 3
+SEIDRIDisparityRefViewId                        : 0
+SEIDRIZNear                                     : 448.251214
+SEIDRIZFar                                      : 11206.280350
+SEIDRIDMin                                      : 1.891
+SEIDRIDMax                                      : 16.28
+SEIDRINonlinearNumMinus1                        : 4
+SEIDRINonlinearModel                            : 1  3 4 12 5
\ No newline at end of file
diff --git a/cfg/sei_vui/display_orientation.cfg b/cfg/sei_vui/display_orientation.cfg
new file mode 100644
index 000000000..bac5e6ea6
--- /dev/null
+++ b/cfg/sei_vui/display_orientation.cfg
@@ -0,0 +1,6 @@
+#======== Display orientation SEI message =====================
+SEIDisplayOrientationEnabled                           : 1
+SEIDisplayOrientationCancelFlag                        : 0
+SEIDisplayOrientationPersistenceFlag                   : 1
+SEIDisplayOrientationTransformType                     : 0
+
diff --git a/cfg/sei_vui/multiview_acquisition_info.cfg b/cfg/sei_vui/multiview_acquisition_info.cfg
new file mode 100644
index 000000000..cfde992c5
--- /dev/null
+++ b/cfg/sei_vui/multiview_acquisition_info.cfg
@@ -0,0 +1,26 @@
+#======== Multiview Acquisition Information SEI message =====================
+SEIMAIEnabled                         : 1
+SEIMAIIntrinsicParamFlag              : 1
+SEIMAIExtrinsicParamFlag              : 1             # see software manual for list format
+SEIMAINumViewsMinus1                  : 0
+SEIMAIIntrinsicParamsEqualFlag        : 1
+SEIMAIPrecFocalLength                 : 31
+SEIMAIPrecPrincipalPoint              : 31
+SEIMAIPrecSkewFactor                  : 31
+SEIMAISignFocalLengthX                : 0
+SEIMAIExponentFocalLengthX            : 0
+SEIMAIMantissaFocalLengthX            : 0
+SEIMAISignFocalLengthY                : 0
+SEIMAIExponentFocalLengthY            : 0
+SEIMAIMantissaFocalLengthY            : 0
+SEIMAISignPrincipalPointX             : 0
+SEIMAIExponentPrincipalPointX         : 0
+SEIMAIMantissaPrincipalPointX         : 0
+SEIMAISignPrincipalPointY             : 0
+SEIMAIExponentPrincipalPointY         : 0
+SEIMAIMantissaPrincipalPointY         : 0
+SEIMAISignSkewFactor                  : 0
+SEIMAIExponentSkewFactor              : 0
+SEIMAIMantissaSkewFactor              : 0
+SEIMAIPrecRotationParam               : 31
+SEIMAIPrecTranslationParam            : 31
\ No newline at end of file
diff --git a/cfg/sei_vui/multiview_view_position.cfg b/cfg/sei_vui/multiview_view_position.cfg
new file mode 100644
index 000000000..bec090b0e
--- /dev/null
+++ b/cfg/sei_vui/multiview_view_position.cfg
@@ -0,0 +1,4 @@
+#======== Multiview View Position SEI message =====================
+SEIMVPEnabled                         : 1
+SEIMVPNumViewsMinus1                  : 0
+SEIMVPViewPosition		      : 0
diff --git a/cfg/sei_vui/scalability_dimension_info.cfg b/cfg/sei_vui/scalability_dimension_info.cfg
new file mode 100644
index 000000000..17701479f
--- /dev/null
+++ b/cfg/sei_vui/scalability_dimension_info.cfg
@@ -0,0 +1,10 @@
+#======== Scalability Dimension Information SEI message =====================
+SEISDIEnabled                               : 1
+SEISDIMaxLayersMinus1                       : 1
+SEISDIAuxiliaryInfoFlag                     : 1
+SEISDIMultiviewInfoFlag                     : 1
+SEISDIViewIdLenMinus1                       : 3
+SEISDILayerId                               : 0 1
+SEISDIViewIdVal                             : 0 1
+SEISDIAuxId                                 : 0 1
+SEISDINumAssociatedPrimaryLayersMinus1      : 0 1
\ No newline at end of file
diff --git a/doc/jvetdoc.cls b/doc/jvetdoc.cls
index f76648848..6480d8aac 100644
--- a/doc/jvetdoc.cls
+++ b/doc/jvetdoc.cls
@@ -106,7 +106,7 @@
 	\IfFileExists{logos/iec}{\includegraphics[height=0.74cm]{logos/iec}}{}
 	\\
 	\textbf{Joint Video Experts Team (JVET)}\\[0ex]
-	\textbf{of ITU-T SG16 WP3 and ISO/IEC JTC1/SC29/WG11}
+	\textbf{of ITU-T SG16 WP3 and ISO/IEC JTC1/SC29/WG5}
 		\hfill Document: JVET-\@jvetdocnum\\[0ex]
 	\@jvetmeeting
 
diff --git a/doc/mainpage.h b/doc/mainpage.h
index 69186d6f6..51667fa84 100644
--- a/doc/mainpage.h
+++ b/doc/mainpage.h
@@ -24,7 +24,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/doc/software-manual.pdf b/doc/software-manual.pdf
index fdc5c89e55e95d511a0eea1cab4f0a66de2321be..d1ea637e32e7a984f99112f89c9190acb94f0cdd 100644
GIT binary patch
delta 185220
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
BsaXI3

delta 167601
zcmY(pV{D*Z+lJeAYTNBhZA@+3wryK?ZQHhOdunrP+ni!Q?@o5Izh5g^>)(}?oJX$n
zh^aGsD>04d09g3=V4Yo@Obu;eJvOeiW#cy4kb7R#Pm#ijIPv{JLXjXc!FnLJwC97a
zrk@w^ohEi}ZnKh2q?y<@O$@<9jU`EUx;>fk6F2rQenHB84;vgBG#jrVq%pYcxxarf
z|NDBfe7#kK4`d$8!Oqn?twe{9!OPA4=5nCV;}rkX0d&r_<;QWxqH=D5x`R81yC)aK
zJ;^WV9{F&8U&#EFaGz@{iKD-oo`16k)Tug$oVER84+5h;L0S&d4tC@L<W5Bp;gmfH
z3wn1dhC9Q2vEXH-1gJ%q7ZG*KUy8X<onYV!=nA0Ww~(&BO4j)a!O?xZl$smh<)iwN
zpOY-Pz_+Yflys-t1a@qA*zJ|<`>kT@hjdv+Lnf^(BI6&aa|GT59u#Wgg8erRuzo|S
z_4x>4BSG`rL^!!Wa*w>G3jyjEzdJ;FNQ38y@k<V-oVcSSna_TKmJkJL3R3AIF`!U_
z>M)`~I8R{G@LunB5C^I*%?E8NmZ69jWGq2619AqcxFgI}ZGqb&)x|UmH1ElR|4w|m
zZvUR(YFF|U*m3!WdB$%TM-MYrZtr1b6m-DicplLRysVD6Dd^=*s1zjowcXR}?$bkE
zoD8z6;Wg#JY}m^Wtp)@%arodtgQ4jl7KxGv<Mb}kgf`~24)qP?4V9%6awip&DN}OC
z0&0x7)I>_mBEci(y`nr3TzH>V5_m$S`jhccSd`c$&G5+NZ}MhWo!Q}V81$jPj)#4t
zAk8yYI!lO97U$-?hZ!kY1NKs3rmVOrkSph%!4I4VjvzsZNRyW4({M^v#a)m;lF_Pj
z1tnq5PzjO<{3BlJi?*+#XJtS7nj@zE0USG2d(M+YLd48kEj}iZD=-BxI$iKmuK9(o
z9vDiAH8GYX{CFgPt*NGUxN!y{0u|cyEdDeS7s7>GTXhR!azKJ{HKGC+CZJ3espIFM
zY$j{yUCiMT-OleisEW3B<B8m>86;}r;$AGwc#sIsvD?3PjVxCZIa|t@Y}B>vfs<l^
zZYxq0T3C3Kg)&nT&H>KA2V3L`#>yBT0Ry!+XvkRj=$bTK3WbUaY)U%g3Qnoo47Ry`
zC4{Gp)_m3`le8PKa3bZ%cqu<hR>L8e%sgsak#g{dCml3W@uRBA6mh$pkfOzMNlI9X
zMPL3vsf>wZKPg|lyvdbypOUI9zz9y}-lgUCnpyYEw#FwSH8}%-2$5!W6akeK>is_9
zS|9n4!l+v6=wyrv@dW|1{ESC+Cv8?yB(GuLuN(a<U`i*mfL6c~hHWI2;<g1=$c(Tm
z2|FsHDVI`1`a{z!lr19DuQNk@eWB2%7#xd9@Ny1s*ZQBZjuJZ5Cb@+kut7EzOMFd^
zTEgO-JXhwyh6@^sGgS>;Ep|v<QZW{^sgG%>r(3hENhNvW)DlNf`dpqSd$oXSYMsAs
z4nEN(KvQC4ubQ{pV$gyxWA!H(WlH|Mg3MOIWgZs-J|$qyJRzj^qKxqlWB!2|l!s+;
zi|VArPfNws&@TxwA~y~PAP5%WO#2GU?hE^_aZ*%WPBN^WZed?4!DzB5Js)gSQLoEG
z2-s_g!g*E=+{sb+65o4T+9BaF&e&((J0s>{6t`Wx#5J33#O-95f9czG0bdR0NOL#T
zH<fl{i=;+KU%!iAcTdxkZ||Y%vAoM~H&HXr33a{$X{~tc^lkP8cvn*g1v5&~pEuzG
zVNknzeknZuBvWZH)I-kRS7R1X51=o$XkMJ2LzPc=*JlU$VSwupdWizZulFdUWAZ{_
zM@HamidQgRSAks{Cax`CX(mllS0dX5vPsfSxG3zwpMUFxrF)H>TR74aue^6gFbF4Z
z^|gC-f374l8JrUU_)y--wvc1b==kq7yY+3%G1i(}F{|26AG<4Th`3G*on4_8rc6m>
z7Xah8UC=cY>-N%vy;e&~{4JlpBNoo^?S0rWZjX!;+7O$SieVyw*4ndG^EBR3RY4kk
z<C#eJ8asVejF~hNSF@|*bc=&>t{RgI>adk(tqoSO<4@DToc8u`=B}TOQBTSxCU{U+
zBm2U6P?i}<A-+g)i!&cR{7tIM#jRah<vKlr*P`y0LvHr-X%7_g{2Jj!VFSBSRHO%;
zYlBPbfuY}P`$orI&QSG3*zk^J`;(m>QkyB6)lBd}1?s<pNc9NbReaC2w>?qdy`zGS
z0jIBRFX0Z@kqP9zGdsg~3j#-&!<CjLTf^6BCrK@W*y>$RsO7cilfDLZ7;ATB2Ir>q
zmN*lSH@x9<-g(2(8Zz;`s2Hzb&r_(dV~t|HX|-vmm)bK7$H@&_^Mj>&meWq#Z-!hE
zV*Fux)4$acq9|V$J4pY<D!z_1bbQo$j8N+&)ZGFQ=I*jddk3!?%S)Rqq`sv7ty&pM
zn)w;<$R}*SZ`RZ)%?rnSBr#~ZdFTS1u0M{_vQ+fpBc8;6_!X>eHn5|!BFC6w0A5=P
zm)t<`J~zV1_B6T3;&Gsil)*&0A<F`zv5jxniaXJ1?cv%dm0m@MmBQJvyu*TY!d=|G
z3LpAl;BgkaJ@JE&Z{+JD!#8NQ^J`5~9~2kB&iQ|mIY&C~oDJRo<rCv0!12>hf&?>V
zLuyMkQ+F9+=<iu&)YrG{)v()4!w*tIFq80F<iCvAC$Ed1o0ngk4Fpf$Ycsbw^RXIj
z++P<AAJ;#>4^Q;B-T1#p-DFUSSa*7SL*pcba@Kl$Kc1whzKc}|sQ}dt{;97Jn)5p9
z>$=WIe#7V3H*=~_;WzQuXoS4=@6YG4>s9s-SD!IT$EAi_R~fW|qw5ir8I=z?@)w3F
z4y;f_eY{ZAyS+Y*3dWQ#8k5|_r90h?Z_{*_-0(~eoIl~Fo#_aheXq0Xbtdcs$~Sg(
z<b9p(v`SX{$<(POT1g+!q`(W|*OcDa7Wy{6<4h{r=58m0nFs6ki8J{JGun^x4Cb&W
z)K3|7M<4|P%=4J~b~ry&S#pRBlJ&6uKyK8XIEo+(^1R<N(SW{t<tSz<{(bSDJBNvO
z^T21K`@WtF$zaBUIU{|pWO>R(!A753Irl8te>0%W`Oxs3UOGfs7-*-uu~ZIj+B5oU
zp+2H~8GM{=B3cZT7+n-_bC?p*(TTkS32jg^SSN5s8JhK+unyd3N~ENku(Zdgo5o9h
z!SZ0%<F-nLbP7`X7j1%HR-Q-h)=sPx;RK7vjWm%%tuECH0kOTR=ovkfziXqSFOK~>
zf$lDr!u}!ZgZP}J3lPW>98W}c*vYNca0nZv<utM4F^iGirP_y6H=0G+^{{|c41EYZ
zp0hQl-$5=l#$)WK=5(?CWHt*gwS%T<<SSC-j<Krb(}mhDK`AtS%6v*-Q(vxTU%~{1
zhwH##9Dr8FjNLzw8AUPa$*7JlC3O13&X_tP!|v?KJZB}M1N^X1LKT)JP=37&L9G8{
zfohze;krB~>yp+Oyl$0=C+@ym^Q+|H;N;;LE13pCTrtRK@wcxd?L#ezrxtT2BInJq
zZq!6_2i>)q^p+k<8*XywB^`6LMy10otmB1B7TCztB3b!ne#!wD&x7m%T{IqM+c|#i
zTf3%cuo6eOEYN-jjZpM^Z1zAnyAFglQrqp|c8dMemHD=QS5;dmjq{>T65rM2cE*~X
zIe#sn49j`{mXtm6S^!TEY`H`Kftv^WCh?W>aa>I`pg+GcmnwK%wdO*-%&7}1_b7Ce
zcYp>{xTVCMb9MNF89&H`HO&e}VXJ^xO)jCB<;Ll`8Av}fledS&#q744>~q`;A6yQ9
z5gh91br^|L9}5eCL{Rhnh8(A!8;V+q%tZ}W4E?b)(e6f%&r;9hCSi7{kpUK3OW=!y
zeS_m#*Y1c=a$g+vA{ckDz2EY7vfv##swVWh9g*_K$FQKhHJagtTna0|j;%oXeU8G2
zME>L&3>f)Q_f~mb2i77bI4v{g*D>_i>P|0I)<J#q_SSr6GDyv)1=5tvc;X<E1tVRX
zRyJOoJf@LZ6jZ)QbE_N6m<b9`J&@~)T30&hGJbd`MYt2z`$uJ2fTh{nnIb#^Gpu%<
zUQcGHFw;8)Toaaze_)knuQ(8&`nQj`E?Y)bCJ>%#3tm9Afx{6w`jrZC2A5xp?)1$K
z7E3kIKwO)cNqu<hV`T*%jG4_rriPn+I=+HL{%War`(q8!K?Fe<G~T^?PI82(3pz8h
z^W_O2gha-@F)1)Kc2~+F?)+4~wBk5Fgq$eC0XHmJlQW~IwNBV$wMOrTy=0W>w+dUs
z05GYJzjp1}N^sTCLpK0EAE=J%P0PxLlk2sP7r7&ZyKk~LBdi)6qDL=T=HnMVh=wJj
zx(;3MuU;S2W7NqipkYM=0lgD!M`I2*9qv-D1-@_vxt7~ZpibNtj)Z9?VB|@FcD2r=
zm{anpmo3D0F(oED3bSKFBPWJJ4Z#+H1C$+tuQwOtz_zO}o%;vJ>lBs69Nh-zvSA9)
z$gQ9rfwLu+w^?t*A|`L~Y(YWxoY#5DU(R<^pxj@VCZ5%}uABJZvbbt5Mi*x@{`nnB
zS>&SD?C_xAWe%ROwpe*tk^1qG_RF6eN~tb^a1A3(uXjTA-j_C546_e{s5IOS9*7I%
zA@y!>cJYBbjM;DMYF`UkS~)X{qyO~rZzsX$RI7}<nI$BcAN!Y|#MzRTyEgU-x)L2%
znP1D;mROz_rpKTfdFOYu|L0a^a(giLa99IMeEuW_i7(~QY4RU8$NZs`gh)t}&Dk`U
zP)!ACGr7DslO!uR9c9RQqCgRLH$X>0cVX@crmM%p);Qp5E82=)h;i@Hi);%Xj#)jJ
z5WX^~Xrrsm9ew>vWe5jZ7zFZZj){IDCyHoYbTCo7B1(k;5N_*e4wNw5rOe;VCgMLf
zlDkj+l3{Umc8!PTi>bK&r`efGKBQ_q50<t#tcf7bDFCH2u0F?}2xo&G0;I5zn%3X)
z+8baPEK9KXAFU=+22eBJoPviPYUJ&lx@#7hI`Hicq~H)jZMT?K+@RMhI`b--HO8M5
znURa9_COHQ`+@|C4OCnmvhP`0W9$uFlLc9~=yv`ZDBeX}s#6aM5bjkleN}sv#B?$1
zA(pjRirR39&qN*d4(D_=02~&)yhbe^^9$2?1HGRF2ux4qad~%}xuOkuet+%akP#qC
z@26zf<?&@kBjifZutlPnK@5u(A`B9(Cb5}5E2>n8E-d6fv{}<RJfm;Y7qN6nJIztN
zNVA0IfVbfP9B|KsN6q!3k<daV;Q+TB*Le6Tz^!4Tva7UJ(g%-S0x+~1U=e#9V_piO
z*T~>Vx0}XO>E`J%Uhh!v>SSMe=m<W~gKsKN8ejR#hQjQ$+HI25W~(oQ4Vc^#-nkU6
zH;f32i8}%4d0&l6#xH-^FqyQ?TN~OV#C%v(MKmPhM0u?|U1?pa1~NRxe;?;FMlCNf
z@$mYWC4;%qj*G{v0(Z398HTAG*S}a0-3ud5-_^*}3Iy=o9=88MP@9L)=GHl>K?}6y
zfbA|bB|x4P424W+{_L*$!SUrP_H2ewv)WLpKYq-u_7tVPWXs*qvJ~v}g9wcC^pV+4
z_XcNetL`t&={kQhKTH~v1kJjy?)Wau6AGrk9e0~5jd-#kC4hl*_MWz$h(s#*M(oW#
z2Vyh?1=L)0K7ESc$JX=wT;UyDv<Vr59`vX!*Yr6KuNuLH*W9Mb8f0w3$3~jN!*d_N
zEY$i(zqaqD_12JSQS^(y@eW<z?|!u*wJdUr!c<qnUY6>@=$!d(Psf8|f<}7?;dc=G
zGL}gOkfwaZPmKozt)ic(9nYL!TkVr+^v3zF6=cQ9gUzyhY6$!Add1%6@qZ$jZjMSO
zq4c1o%@cr90Ickc{|DT(q~l225PDD4mwsAk-as*)1_ccJ+qa%z9x7}#<w*O~Grawq
z4@#C$b#<S<G}~j17B%#)B#k8I=PNmC6QyJNR+gTVzLgwq)&Zs&{KjYd*uR1APM;T~
z9!jc287t2ox(T?0tHSKt-?Vl1-#$Qs(#S{qgXCHAecp!jnTwx_UtluZ{>_6VcZT?y
zwqNa==7aOP57mM4zn$&(H0vTG<$_pySv~0!$M;D4Y;f3K-jzYF2IYyqB{+p2dUW?^
zTm*~9Tu|R6TYQak{NEQ(V@Ef2NZ_T)$QxynM&~|_sv1Y?rH^C(o?MJqsP}+UTT{!*
zNuDRF^k#)n!#_y0>!C2@t`N8|{*fXr+S_h9RQ&>(E!vNI@#3sH4FW3_&7T@&elI^f
z5kzmqcUFaR8#KG=9q;@Ib_u|d4yp}K-t8{4lTp<yBXj%bluMvC{(2Qg5_~kGGBnM+
z4<@L-pKcuzPQSd9KDjCuBuM~&rUSjhQu`SF5RFXtUxF;=)ky0owf4RDF|AG@NjgGN
z-*6R$^ROz+R9NyJzGGC9;=fo5tTtAmP)rIP-~}w<e!(F5O9l~3VJnH|q~R!Fmsd_)
z`tPE&P+^5cq8S4|CBEE!v4c@mzi8w$UWz6y6F#9sR=IXV7(0KGxI6%myv*lwTp%PV
zHT>lnA$|UjbOLb~)dsV@KfU?N?h_4f?pqqhG+*Jocfg+8XM}7acm{K|k}*2i=0ifK
zJagcQGs3|yuLo@sXD%vPW|wFr(}}4ryx;_zFu_R0oT$lZY-o@c-Q?S=*#;$OwWIMG
zdg`PWS`(*maP)umT5ABj0v!RC+5{=}(|eAwqUXi5mIv`SX5qfAAwnZUn$AHxh}twc
zS#ukd0@Lw>kkW+_PI;adW4;Wis46y>^@*11&*RD|7)NcGmpPri&A}VRiJniI%9tf4
z%ccVvC^G>oHoqDf&V29PixKn(|EA(1)_v((g6Hqma>O}pZJz?{YwIcKSgxg#=3z<~
z7b#-uPIG1sX$?lpYW|@jB{qZW6qJZsIR5&FB{kY)s-&qWe+Eddy~wb`>lf5ek>1Kt
zC4%Kn3fA;ASCiX`Y1+o!siM`gYiwjIB4%jcF;y(lTEz-IJO4;iZGF|Us+o@dx=TFk
z%DfulX<~Cv$cX{&+ASj3dey9ObD)(3DO=ZdDnfA&T0q-ls=$^{gB3)wbJyn<p=9BY
z`5dYH|D@CqB5S-yoVDGJJnmtsrROeGtAH>L`_7y@&s~nFY1IT47Qu`1FN=hrgjtH8
zlDIL3_lCZwPUvL?L{<O=H|CNukJ@sBazu0ys>6Kt?)HESJDbdk$O?(=j~&x{3A$`<
zeq7}(ECS6esXFoDrb?K!zv=~~YNwlzM(m}HIz!f)f5js?f99|1VL^Y!kk(4gXXwK4
zxs?5_*x<`^;nfIZi>*KTb*UQmw_LS~i^fGo*U;I$KIY2+<OkyXM1XU;Ga2SiN@7GR
z3t9R4ENcXy5XVw%?r5GMnSM##m=hg3SZmFyOcN0?RFGg?MvPd<JJcRql+(F}VUFsv
zhqqZlsAPh3l>i0X6Oa9f&oSavT?~_Qmm)a-JG_INH)BGZ^!X^GZLNsuSv==0CRq`0
zjsr5&YM?#Jb!ZEIa?&o>*fI(E6XvC|TZg7$UGo*NbARMSJm53J?op}swrS>y!ywzW
z*CiFKW>r`mfAXJ6zOZfVWV6~56w;n`#Sge_Mi;}AxvEG>6~*Y>>I9YV>K<0fv~LiR
zAlz~5r~IB8VW+-eWWh7r*{mpZ_=n4zr7&e;0cie4a<xBB;3=N=O%L<0u#%Nkg}^1l
zO-TXD`nKHTSnKue$c2T5RE8N};K7J6czBh2%~b+oO8qz$Vk=eD7p8Zf1>zxHgAHSU
z!z0|u2{C(|d7m{3hbMjJKh`Y7BNd&kk{%WPGibbJFxl37<8`YH_wI;Ys;PP9IBS0{
zc^&;U@ejz*S`+y9tE=1SJS&`M%l;s%A$kbN;MM0}y4Key)bS=bk{X@m?~mJYk27~c
z=VYIfn;=Wz@v3kGzz7$I3%0d*i&-3Z$3yMIkTI+;kY(lG<W>qU8V|$qi;I^SWlAJF
zXP=>>K>e?o6t??N@}ctkCT&s{DsJ+M4jx+Xx+gKB73NQl9*|aNe@aWr!kLdYdt(D1
zb73=T$awnq8*Mt9dQzk(R+|^W)#;ScEo;w%OC|&~*{UMtxC`g|ru}kJ(n8KOb{30S
zNbZX?s4DDTId9>#BF-?1#sp`f6n<7Ot>Vj%WwQFXTSFQ(_sk1O{yUrA(Z8i9I4ErT
z-tU*-U*`O9U_zCOoQ<x=TNLM5!0iEAN7TSTWTn*yZ$@A(o|P)RoQKV1>n@ZwFXBoq
zvsAVEFX1{=6zxa6N^I#80j~UJtK-ZSu{8NlSEbR69@C0jzU?9O&4uVU*{n;%=O->y
zhpo*HJQr>-266jE!`h9Kk&ai&cj<?n4G-kca1m*?2QoSXW8KUZxcFxt33-4nmVrR(
zjfWB))PqcDjzE6S=V<!*#GSqynreFK8b45`txF{GVc7P=XIJGW10!s1??T?Cr3R%-
zgrVrNIAw^E#d*g&r^U{rhoke#rQ`bYUwXmIpov0(<Zp26DOmxWZl7X=3@0lT{G+kf
zc$OZ5gWMd<7RB@kzjG=Uzcau$@e6WR`CNa5`mpRdn$6?QN<Z9NwHTW0$har~GeT~7
z9(BGgH8thsy~qb@q+k$lAuqsnEf*=ru_a;diR@orL+y=T!0Q~fhM3o_L(l6Un>|iQ
zn5sczz;S_X&vRJY>@T)blVQ-cAK_E>TgKfErlFEt<#!ill8D36R~Ybn@Z|A+b%c_x
zTl!!bNYzixb4dD)MYO%bt3?qw^Xk3=OEC}fh~>su0uf4K$_diV<3d?K+w<8`ofE(I
zwTrR&Q`KlEKW*@3VRGCJ0sEh_`E25{1ocFv+Cf;3i+zgqlFW8@KTZnhRo#m&6`uQ6
zO@{PB{>8ldXSUNhnk_&mdhJ&3ror&<tX*sG>IXwDy|2uZw?I0B9sQ;^F>Dj^vBq<{
zafYsYN8DpZ^LPsEB1N~=yASqgk5fir8HD_m7LC)O(c-wohN%nwKw;FXc%gLBUnKEI
zIa0jGO+&m`Wf*#mc$#UGYLdHIJ1v^vgO#S0YV(@XZLbR_Yb_ufRD7(RDy+QpO$xiu
zvh10_NO6v9i@EJ*!c8kE2QDNjV{CRWJHtM?V|_ChRjYc;<Q03<q-(s>MR$8>MU4%A
z+vBedoD9inJ59`fDdTCOpo6>2Xx5}XS$322ivA_HnzeIri<c&*%*_Vm-8fz5g${=%
zBHFTiVL8`-q6IX^fhu2>B^TGiVU_@<eaK@ssB;^x0iA34YajSYWZ%}d=}g|&GrvF_
z#?}9z5tK2_P#v2b;9z9>KiG&n8H>k$xm}n3v%d1>hsI@r0A79@x;Kqiz57A7m&Dh%
zf)X)nq8K56CW2DF##Ag_1nN$)1cN?ii^S{yM~vNH2tR)AzIA(k-#31IWN9U%{^9KD
z&PG{+`8jld|9p~^JTXwT+b|3Cd;q;4?~Okyd9zc!JP>Z_r7ZRLIET=3kr<y<#PBaK
zd3Znx^(1#5x{p~gsOQTMP|PjNC%x~ZLvsuor+fk_?xT6;J3O`%a@+R<^XR&dtV_8T
zsYDYciE^NbAM;}vnNUl_P|U#VwxQM9>bYQWz!>A#j6un=;-g8>#Kuv*FM&HQP7<1j
z$cKs4+#CWGQyV@kO%UvgGF1znZD>0Zur8E)`0wbEiV^OED$6kikNCS1=9CFq9^^$t
zE!ZNuCc8mIW8^1lSyB7ddLqoin0fhP>tf?@5%OJ)@Uwi}V-yps@v9e`HDxiaK^S2^
z^~A4MZdH!bff7~pWnvR%B;X&7tW8`qUn;?a7jtdjcd(T7Y>33ii-aL&st)1=v^iQt
z1?%ioc=I_YAt)1HJMz3g7h6lUiSCTUm|mO3ku?RFHh+$%9qC{xH9YCP2=)Zz0gVys
zn0XTJh43?TD1=->l^`ptD@9VSZiq2OG99LRzAm;~L_-5v%r!Kj4sbMu1{0oc&yuGw
z%Tr@D8VPz`?G)~q3oDz4SC+WG=s7cU4y$ES>BOice6EgO@eZfW-xB(ZyBqgKZ#l8}
zU}b%#h?8w`4FX!8ImX%DX~dMLfzp}TIs1Ks_KIL<l;Z+(hg$ZzlGd^{d^MG6Y2NUA
z+nl|-!TvKA3p`M-2_V$--4|g@J9wTZeVl*YY$zX9n-cr=uRj=EKQGK)zfsRxLcCeO
zdT~%{T&`PUltG`L?&RnIdb^a(ErQt7{<l>Xh_?WU5;e?0cuFcQEgsyj6T!0V)^U^g
zD1fF&B9KpCppCaq8V%X8EEtBhEB}(zS$?dH-0mo0sZu7x9(c<+v3D#pJz`lN@6uyi
z3;fwhVGD1mkozPHrg%5yrFe@U(^}m@WP^Q$q8{tk&^{NcwvwMBY}1^QT2Zjt^5fgh
zGEcm3Tl$r#<Tm*90t2ZO7d2wuWJlPl^R92q9K+p6<qt0rF%CdPJRfN(V)SuOHn2+u
znrpQUOR2nE4crmO7YyniR}rnMt*AaMgDTm#+4nkpqac2L-xc_MbQ&*d4W=7?dz?=_
zB?>c2foF-Wb*%qP#*ni1Ajz%ZgkF~JaRN8LNih9+mnEDrPCGJDXRw=B2uK+6Gm)_L
zzfFKP?)DVcRl=lux#@Nq<R(N!heL(jRZP_<33t(j0|mGN`*Z9_#o&#K$_Yr3?RRSQ
z7~4efxx7xVh-2jgzek6$rdX{n1E*PT)<W~G)kDaU?y4T9P&0QbI;{tIke%2hb{3k_
zkk+<Ykqk7Zl4uj;a!tbBHA+Fn!>pciQ!}!|iFhqCd2f;Ivc$YlWNmDi(*vO^$+h(5
zO1@*Z0Bp2@kI$FZtlHXn%_K|uxHKEn(js=z-ai;-O0nw#w$^yw$#&K(SPXKbHEH*m
zKJLj`ds?ii*w^*4b58YtUUOS5$<hJFxb<U@553lkfTYX`?{gI;CE7(#{IU2jZw0kr
zYsbGs^aB`IELKPDHS%niPZ!COE0OsF)pQF60Lx}}&jgWaQauQx0GAWUIH3>86LxdJ
z`#*ck6(PA6rpGN6y(Z?}uERTC6<$c99A9<SF{Vy0MtFq&wsNlz`%1512dqJo%56bn
zxAOfdYG*Hjk(>o$skWaNU|VfY-Cde{*~`B)pKM`aXFLphY^h<j4L5CQ;}{3T4U=;9
z08xfjcS8C_{kW31{izOtOIW^!GaY29mh8DF3LCA-!x(&bYDaEgv`z%=iLSB2_tuY{
zj?%woG<@KEJ~@(tct0d5Purv7eW-SzxrzwN!^5!N+muGsqvv)>QmoS5|7w=0o6g#>
zu(%O+{rbzfc9_gPJ@BKvrrc%eI=`!f8(6cyCD;h+IqdW0p5;{C^t6Q&hI0Kg6X+M*
z4;k5KJ2Ch+rRDgLWNj5tHQn1V-?rYNv@eEMdC?x4RaY$-C;G%=1kb6x;XWeXLavj~
zE#sDz^|x%A0;<!FQM{aHdH=8y6<@+7$qs{VitJ1Wt13hljpH?z{fUQJHsoGr42W->
zywuZM*`9wclG+`xs6}52H0L~Oq@IFrU9~+4S?VVW*A%LpW&ry@&<3Y#-m;n3Jk#>*
zE(_A-aBYH74Zl9DFH0}_8@a$J=-YMKKJgbn&-S7(dG<P?>qEE2qA%zbP`(nkt-QM6
z2}X(PQ-el66|&teFBF6|YjL?iA`=*#3!||bj0tRh=YSS~GPcpSJ83Ik;09(6NJ@VK
z?@)5#nOOgCVE+DJV3Gk$?7unw|B2ax+Z9XNLHDAb+{E2a66FPFA!E?b*T24=g@YyY
za;f8lcS-)`tBfR-ET#Lo#tIpdt0YM}!cJwY&%Q?bHE_Iqtcy-$m&U+x3&+>jw$tak
z@%4_>5`eBKw#MgMOs3Yp+a`bW%_&*&Srzqay$oDLF}?Nq$0aR*<2NwHc=&KXpd^Vo
z<VL)vH;(!gXV@YL)u+8{n`^JHlqsf&-Oj)IQC&RHP8t?7*s2XW>@lKVcO(Av06wo4
z`P=${4TmPSEB?<9z8+su$Zmg>i9xe!RIyQn?C=fS9X|V?n{^LXGZIY@C^^g#al0YP
zet`EKv6ps6Mml(!P^MU@mZ_X8smXH<3{U)WR00^g?p~F~da6b-8d^M!5`|6LJ=~Qv
zCLF2aT}MU^N9FeI=auR|WwXCgN|KKeW*n+!6pH=OwlPm2exG0x?D?p>P!WSPO}M(U
zyf!GT1C)b3y?NCj=Fdkpl@@PW1*E5%9l(=Z%4B#Ak7{;l^={fd>*Nedap(TRN|gzu
zW}{?Nb3M75Bdf_eVy4<f>{55!E+}+-q7aR+(>J1OnijYNzu0Qg*cNZ~#c4UXQ7RbD
zL!EwUfIXZGTO{^V_{<2k93^zNl*OWlut=?Z`m>44r)vl;HA)Olf+h2hEe7G#d;kt7
zjYwL>FBZWU1Qrj(ueB1F2Rm2-7o6=3oX<{ju3n8Z8q^WY|C)EO!rG&??D8069g5SU
zRDZp2989IfM|xv>XKrwSS)18}$X;^~?N5@pHxYFTrWWLaeJ^5Vk$Orgrcxq?$<HJ)
zek@jl)c7DnRFAKd&51ln6~8F2XrLFm0$L`i$@ZU7w!aumB~M1-JE@?FaE_(_HC7@L
zSPS}!0F0Li3Zvaru>*xU6niV$B4g3N*fdBl2O_Oi4;|kH%5h#jRnY`u?#OiqEq^ds
zwc_p-#5XWTcP%l}v3ZQ>4&^e(T$^)Cn`w~`KDa&2eroaYbrF2CE9P|AKERaF?<`Mu
z<fI*nod;e&V5g~^XLdt530XP1E^F@h+EpLkD1roW6IkGOugz$F-PsSo=3C5N_bJ?y
z$dEC~TM^qW{@Pe^r!fg}xgfWaBPeH@^y+$C<uWlkr9&px_ymNSeq_*b8l#C&mHy;r
z)xqdkQzRaQtoXQJ?&U*O4A^zKS8J0!fYC#uw7bu|KgncE$aR}8b}7H_5}UrHSaL)Z
z>MniCNVA!g6gzOc_~1CYlOF`tHP$O$Qy)_?<Q>2rsrO$t=>?O3=X5{fR2$4Ht>QUm
zPROt$pe*%HKP;N;w}3`UHi^>V9`igFu!oHGy}GsFfe2FMF||5?1Q35%wd__0R9cnc
zUx-e4sp$>YXD+NL4XR9Q4hqsSO2Q=;@98x6Q|cw{g1cv;=FK%kS2}SwQ+OIFxbu1g
z)Qg!%=2Qk9o)8^jVWbpAbAr>we3u6|iGO{0hMLJT9g@tUh_K3^4G<!Ud`~rRHF%x$
z_!YD*5s0xjt!P+Y0e^iY>#8i)R7eth%|zCcVkuQon)dCAwZXUrL9eDKI{upyCaJjh
zeErN4mjIzBWi7#`?rP(L0Uj*lKa6*PzIw5K*!^<DezALwpEMegGP|m+<<Iw`YvFl4
z!hu5s!-12B*DF7pPNS-25^xkHWI5b*sj^|B7d;NKY{$lEAj`@lZjs-q^8UM<x(q;9
z$DETkG-IbJe4$@8E%zhjsU)}iD(m~uG2>wSA?>8j|NVBN`^Q&4!#bEPc0%W>$RY7#
z=IOnaLCN2dZHC6xfK|W_jNtI2V5VX{$ug#_OLkjeDxfx_TdZ{;=?XpR{z9)nFu^%d
z9r5C)?upVaAl2LdJUVQwix`$s{kK46&n#~U57gi!<k0#N$}{>VAE6i(ciN8p+MAmj
z<X1PlybW%@;Xcx&Zdra|JCxeVvG(j1jey)?<P-U1%VC_47m%tv4@0wsbfQwpR1`?T
zQSz$<X^&5?B#c;V<y^X9ZexswXA<|D6i@*vc#O>ixHmkhe?d*j&GuZ<$-Zp+oE#)u
zW=Ki8#vR7$STb;BW5`iN7{VfIu=}mMIFw&EAnBgr6q9R6s2Q?yy{Ne;sB(}OadK@?
z`oNF8t=bWgjjyLDi32_O>}|jBF7%8)1l$OWOps!s=PoGbJAbjfZpK<{v<&KwwL;b4
zY`I7QyIMUZn%a{~&#Jo=7+q{}dl2p;vwwgJ@MuoRrlc%V8fDF?E}eqJtEUJ8*F*Mm
zxYV0avhin~e^#cs7a<~5dpj1>8q4f5OP|!vua>#loe>aYP*HOQ^Ug?F+<X=k{w`~S
zn(J)(s1$wze^Aou(ws0=m4aEg(EYJOd#CgPGDM!e@r$d4;6}dgQ`BEh#!mj!|1t|;
zGG`A$(Mzi}VWU_Brxqa1&8~_!xI0!^qA?V^t$Cgb-DyprKwmP1d3iY5LP}iV3bZOt
zUPWjqR+1Gr+SR<QuF20fR^-p1_O>Y8B;KKvR<OI6!5jPGZc6I77pr;vE(l4of=h+~
z#q*VBzl+*tKJ&%@+{woj@{yog#g#L!%Rfd!Qk4#2NbAN+70l*djErzBVjgGQnQO~i
z&kxgz(yY)|Pp9>|4DwnJ%-kj#!X*sTDJM!B&EFC-2|07#?VA~38J?v9&5<tl97bmk
zb;I7q8N|sM)x7##6?HS&uMN+?jHdSivF*+!ciZAbhH0PoB{3$@+D68><F>g^ZEnx~
z4V{(6J3sAJIaH1)kLXF}SuV{%p(GGy{Pi65wzv>jLpKYZ?i#lrA0{Zes<Ty(WBDOZ
zR4yvz^*%9jvqpPb3SBcBArb4QCI++GPinO<d7Dz35SiTed0h%kt9G|dd`vk2-JAz$
zb^6WR3m4jJG^;QCSIZ$WnmN>q^jTr0q3<O(d>h}X!$3UYM6TL@OL;{xi$RM?G*jHp
z1A_rE8XIsk`(bFpbQK4A$kI-ypXsM?Z8N)Ni>lHW?Fgx^Scrf`5N-{Q^%;Zun#;TD
zjI+CWod$MA=KIc(J|?$=y7D9t;C27Ybj<sl|NT#iZB^<({uI&`y0h!_`0bDYHoH);
zVEyGY<mDP{5iBjL=V@`1?8#rurAyY!eU3)s3QY%J<`}{;pTT6qmlR2shmTf%CCa9-
zuV}9!r5<HJ#NWAUA2`I6)i3EG);OOo0ZuMZ>LcBijb6{wQ8{jTd%Z@0n{R>L%=c#W
zUM+=ty^RaijMl!+#lqLlOGk4v5nOI%X3&SHYn8EQ-6SXSskhcpSFUK*KL)oL<ogPH
zEBf=jiL3qMdW%<@L+H)O9$yLX%ifiicWKMDttN0(Yu-SM5!2kd<1KXPur8u;tCD2X
zPg*Gion+G^9oUqVFi|9+E0o8;UXV^@h?BYQa@9w%>_V@<{#}WN-(wAQgHjkVMNy%S
zgWw&*0EFtxiWj=<82RjiyI?V@K7P&|Zx$<h3_Mz+=1l0pr0&d0PV=I6x*p%F$x(a?
zmfOs70?}+|cSD`<q-D?BNjW9|$?{lX5~h|l+~p<{p(7%eqIXkJtqI@Z<k`|o>LNzo
zeKBP$IiVUeGUSJ!>O$;va_RmwZ@hfm)M5{bJG1>gXP;SLqh3Yf_rt5qSsn2HvxZ5K
z`F}8*<WE8lFf;yU{r{8fl@7N(Z5P7z15K+8ti0ILzd;9-Uoi3X{#~RYJtrKhkssgW
zxCx2nt5cU=vmO00hS<+mETp1J9}>LJ_d8MT)qCPPv^v#yQ4eVsfY6Zs&`saN4u6l{
z*DF?gxa(aNR@!RZ6-E!XIYZsf*IhSId)`^Q(aj@CH%MVCJn8-FS|RFrUexBNjr3(=
ztxEl&Tjk#RW%Lhxvn-|*u5WWwAkR4N_Jz(FvQVt2#V>)cx$b8{80#MY>1$2Z9L8*p
zqfMhT6|sAksY*B5)2f0bR&Ep{HOUn@f@Ff_GRdEh1Bq~HyXhivKGWzQ9duGaS!)6?
zO!4jYsa?OH6d$!>GD2BHOY)b4bW#*2(5znz*RuE_L90-X;K}{yKS?#8c1amkG|0(v
zyUXEKjt;d4qS{;R?TJ;{=%BbwOiyT|h>*`y($0}3S9aoM%JPt6z)q_CR>cV~{bMF2
z=H-WYDj8#241b(#$sI+H@y;;7+?&(A;8aDOM^5pxQPDgG!y9q?NNS9)6h2Tn(&&JD
zk;oi35;E>{N22%8sE9A)cv9KvPA;WoxH9o9X1mT)MTvDH=i;!NkE&eO^(?}gIdl5S
z!D;e-W^OIomi<R`HX;u$e0yMFXCkFQlR(0p$rLJ-g`Qd1xcoTh{`VPRtN!PH=CtQ$
z7d*QyTUFhZ+3$1WxQ$|6os4uBn{e8ff&pn6NaZo=+6wG{x}(Ddf@sDy^1-Lmf9KU7
zJKrJ=1e7eA9|W`DRUv{kFX;PZo~H1_S;PxiGg%fYWCED*JHUF`9eq;7(@*qjLYUOZ
zJy{e}%Vc%y`N2<80+Nz}jymGE$zr@r6-6@=cAhW+{6RRSvQ$Gk^t@qt_2CcM*L3kc
zG&Ue2^4R`ZvvBRQjtR^qJO3|eFG|e&BKNEZEQTpfF1uJfvG<$G5%a4L;gM8t*t*h0
zKY6lT`xT`!*RaE%eFGOR?EyHxGKp-0x<~0++<(iSu~xbat*4|wM5zaN;D%7m3<R3G
zs^rfyuTuS^!jBs871p$DIM3(r7MYl6Y_^esL+Q0lvU;8Zi_g+kaa_T9HY6(LwL@x5
zIeZh=H4=&|n7ok{SXnN~CBAfASR|$<2gYPW6KZk-#+Gs+K)FA;&_t3nt}k_jFUgzz
z4N2(;CG*c4UveB^9amqBF6Rm}R?fa)yQt|g4O?%A@5T=?L*#4Q7|Y|J98M07wL{#%
z-xmvKGyrE*FYU0=&vuK@F8yB@Eco3^jva%ZWrS<s$TT<N4z`M%#rB<6${`mp$7;&4
z3O4<FHe9|kJ%}!|4=2Ut%39i|(@?P>q`#HVSs=E@#pM;)bR{_=c81?NK4&u@fOkb*
zf^JoU{VlJT1fPmJX-#L7^nOh7yV#U072Y5Rguyw(THEL3MJ2Ts+>A&~h*;q(0|k@z
zKIvlh5`{*&N+D&rz+5!9asFTG(EQcPywmR$vWs$~0_-8)EFU+M-xzvf30PGtNr5mT
zwIgt{3(B=Xg=CA#ICaiN%RFAwo;UU@xl4x+w_Q?AhJz((5W}0?um$^G#*p0+&YYBH
zjerdPtDJtl6%3)<1eVahjpDyQyKlzTv-PuUav(mAQJuzkMKt+18H?+4sZ@9OqouA`
zF)6Gn@~$D7i^P3<RmpVre>=eVFmwcu!)c|v{Z1AI>;yUlAJk;*`&O^K7tiIOZmkjw
z_zplyC2zy#PHY7%)x{C^^1|x)LC2ezar|d1U-jS@8hnpIM1WloV=rT<UxY>JAgVmz
zoQ@#-Vu*9S5QiY$J?<b4Vy^rNfmt>$N!y^in0sg~e6s5T1YvI6(Heac7h)U>Bf7i>
zv@1&g{lCu2VPkY_)SRC@Ap#wuK|BhHz4DTR-&$V+WM_FLqz9N~HfZMkX(Bufgr|lJ
zhC;2n-ce4DAzxPzKN|3=)BOq2*@^znBMQ}KynQM8Xr<wO<YXsmsl67vW&Rn)S~w@+
z)z!Q%-DtB=9UWe{?;(`l#sXuWqPJ*)%&VmZR!lXG^mkc(uH~)SIluIjmjfI_(D}92
z3V)R{t(5LsR3?(5u&D4#|JCsPor@)7+rckaB3<Zm^;!&3-dwipaZG<W%KM=PV@~*k
zZ1?4@RmZTQ9}9a5U&vYW;K1*&f4N1wTJb46t~5~PdW3G|u-P(J{6Q>j(+j&-vQ#<_
zC_lK7RV1eS(YTf*T+NdegQA{0NNnn)qVw_RbB)WTMXMh(puSv-yCwEOsc55L+*v-s
zO~*`xoucF=O4LynrIS_EA92yS53Mp0WwC$>FJx#2+_cdFqCEf%eTRX9Oal2+LZdMz
z5q^|y+&Y~Q-f1%^g1}PFI-FbC7=q;jaEP(D$7-~>QTC_%QJvN*DBO|;qALk4yj0`C
zvERVfRl>zk&3&B2;nFiA9-Uk(?Dd;Y*ig$usD=1m6RpwapojBUet}kKpn0zd1g+VT
zYIob#XVMxg1mZN9tR_G5gOx7`A-1ipYI-$MI9zmV-?zEJBh=+#C6k+?obpdlU}@-q
z@Rh;!?I;Z;0i;;0S;Ro>@J)`E$?3PAig%>x(W{?AqoC}}(wlmA98PjK7g$Mqy*F-h
z_r?#hx|zVl8#cTICpf9K8&b+Ys`AU;sM(RdjFG$vk^f|>v@x{_7?jj^IsqHYfr$4U
zMa|0&BsmXE5>WL2yk*SdP?CK(z^UnXEU_UDZ_;V4M3@qR_2nyLEOyPIVHK&WT-<av
zB&{-ND$3SC5|u%Qa6gl`e+inw2pV$Z0VfOEJw9k^1qjXaf4bTvrS`57k62ef&M@{h
zydW*nEPR{P*}dgo)CJo6wjgcTB_kQ?!u!fZ-@E;{CWw^fsHMWuT2+Tjz$t7kgm=a$
zZF7X)-OF{+)jZWmT5rqgJXL67QmduRDiX0R+r|-Yd2>1)u{FAO#wLTFF9XE}$5~A~
z;cGoJ@?wD1>$Z$!!axMS)yx=wRQPj!7@vv<q&696AcaZ1C8g24KuYzbS;c)^Jp)Gt
zgOIsgXd|p8#iBrJJ;O2?$PmPkO3JT1z0yOY<_)4umUI3@rbU?U2vclter9HbHL1Y$
zgZp*#XjE(^086N50&!od`KpaEM74JWDyJBi#39;4!4V=aZ#(qvRwKq({bzP|f2k6&
z#k+De@-&!>U<xsb_}EvY1c0dS6vZ+Q?nm=;i6^}0pqW}=H(D_UoSb8Io6FYepsuJN
zcQJ=teaZ~n<o9$2T#t*t+jo`1Akw&kjMQ8q(l+E7Lm|>CVd<Z+ix6cwg4uTR^s3}r
zdE563BmWVKG$Bu*e>NdsA<qq$-OA83rK>XYEXL7vE)nNzGDeHf5ZTKRV(2zQIG|32
zZ-Y-Ao{^A+$gO(-3N~%o#avwq<@st?x}sQjhoV@OFT+L!RWmuRV;&79!b}u$tL6J*
zr2j5sR~$s}2mTu}#K^+ScJfw@zUu0?`*KNNWbIE4myBiljZDa5LJgM+h+w-|4b`fk
z^V{~2#<pri>ZUfXa=D*v3U1g!_YL$ue(&iayec;cs#w%OOCI6fOl+Q^s_RGV@S78b
zReOV}yuFPfm=lSbZ|8aA@^R`FTbtPdK7{DM`so@eYkiDW^^qr4$IsWuNo=e*%ciEl
z+KB1Qb=ZZi@jXt#CJ*I21hoyGCb}4^v#Z<B_o*9|hIjGXEA{u`xG<Qtw+(oLMGu7s
zzqbfOb-_2F#4JH7&c}51er;Y!F0H)$$-n9J+5=%5|7YKbb71-7K*<7usc~S2T}R}(
zn1`g{0Tp_Q`RXF$w5>?lSJJ~EE$ep5O#SAWhKmXmg<@yi`=v7#^#ZQdzfU$Fm8QBM
z9_$Q{u27r^{0~oH=dTxFN@_{cxt$<P4?oQN87h`-!p5rL(z$fK^0FoE`uvUD252%!
zefuN_1^sNj-E^yab2$D{N1dho=1STMZurv9|FwiZu`!v15HNMz6$EzUGZJY`N5!&s
zOe3Ho=ZW4GW}w_i(4e}AbM@$6^00RHy|yj&{<8ClG(=GB{y*pkV`gb8<Dw-8V`fiU
zHrNJZ=16KW{O{mQyTJwfnbd4#h4%Xw<1Zx!Q4be!Wfwyi(_g=tS(APnvqCbn{qG?S
zv=#-wDcqR$M_N2TC^^8y`G1u|ZSFXHcGQ_q8uI2K%Lhdt&<g}acdq^n|LJHrGx6N0
z=%8=Fh%eFvBkMEXo=#&>2-`-Uy-VY!vW}zk!!H2~<@-;RGM4$!{?O5vcK6-Q>)Xxo
z4$!UR_wkECiB=HY)6-KYSvz?V%M$Zq>*xqrWRMra#^LAl3r5c0*MFe(?MAvI1n(|8
z*zx{Y^RS)d1^Kw1U`D&md6nS}j(>mSXW$n{L_ZRc(r8vo=xglyc=TD;8l#bYV+>I{
zJgSVA&?zMl{$~aa^aApYq`CcVDap=Z+)K-?wG$tc&sPEN=iIgg6RMUJfApisqpbmZ
z;jMz2hw_$TM}6^*4w9R;=cU4_SiYF9$?9dGC%f$#1GDN|-`ZY#X>x@655l=HQ@Q90
ze*sf=QK-vTHPPgRtndoPUz;a8LmrxISSH8(s`YD&jr-@E%XiAhrh8sp*Hbys(fQvK
zh>T9%PSK6@=yawh`j(QBHo-KNpVYvU(Xae_c2#IY(kb3G=00KSWTlrIU10-o9{nS<
z7(8cT(8LHrTBXYq(Q}?-rq6$oUm27-7l$r(dz!|Dlm1<Z3m+NSD}KKlM{lv4a(6DW
z<@P)7gjRlzwxicma)NtG@RbzSq^!zgyLGOH&{mvs)y+0yf;_3(CQwy_wa)=HFhf<A
zUmKIUG50-QziWG4H%qrf?lbbs(Fsf1iwJInQ|Y@Ev&_F-eAFp)Hv+!#n^og@tZ*=D
zX5I~IGs6^<&IanXAT3o>)ww$tgEUH1A4ZW56ylt$%*tZe-I%2{QNrEBF=^CmG&cB%
zyo)%zl55#&Ig3rB8*_VXD*=GhF66Y~PiA5I{L<ge#thSY5-85T_6P>Eti}s5;}-t1
zhV3f8GEw=g72W^JO5L`Z(pIU&m7UGbp}#iPHkDF;mMtp%%DQ;H5VsRbQ%@Srnn@2_
z#3pN4jLTf`;}m~`o2!v6p?a0hHK$G+)q}B<+^Q)qa4*?<q4qmfs>J|g${t17b1gT#
z)y!c?dc~TWz89hI14%wEy2iO*I%jZ(pmkqX&0sr}S^;$kH4->?HH`KF>buq>G`F?~
z7!Qc*y^ig~F?!Vx`e60_+y-w#{v+K7DfS?BkB0L*2>-kCr0Fl*0iDbOOD#7c!>q}t
z&R8<sx>&H5hn)8I0VMUg%IY>K%|(}NWD7+n89f9$nC<H~->EYP_#6@q9LUIf?&%~G
zINKXqgj;4+b5+$%r}v3cJu&VQYD__C?!L0*=&4`trcb{ihl^Kzwa++JYvGt(zK?2M
zl&>RWjlu_rlX1p8p%BX;;I~>Z&A<+=PWP0j&|asXBKenP06o?}V~`3v$U0944Z(s(
zj%pt9_biv5<IZx{P8A@iYn43<;WUg1DLEIqN-NS>rxk5y`Kgq0XJCEbXJJcVen|XN
z@1lLD+q7;^hX_#(MD(i(YX+A?Ji(ge{fbb?PQCN#^uv`p!A+42G};->F>XbJHxwYj
z9~p@qNX!=j086>>1ywaB&k)|!ZG*+8h%C!VCRfRNYSpd%C_O{^rw|o_9kroC3udAj
zII)MP(g&lja^4=8#1kX;c$rc^+!L$*!tdT2-^(EGY|5DNH!3}k(!{O|Dc2KfMREu@
z35BTUTG7my02`Iog7F>lf{G<n(m2_^j80l+6qJHtpguN4nuEPR11AtH^GZuuMbStk
z2}GgFZ@CG-$ry1Wa$8T6+?{pUn%%!Zfhzl%%6TI8Sq5^1d*o$m;)OOUqo1^*stLV=
zoOPR2D)517Fs|sL^+a=V*EFUPHtbYN23=wMU|b;{L|Dc3f=<%xx@8{CS0;&jLk4Lr
z7ynNyz}j-QY6QntA)pf644>qVk8HU@mgbv(<yflES1~r)150!0V-(Ml=@jx9oJrIZ
z6uqn#ErwY|CEiPdH;uU^NjhNQ>e<U|2{EQ#({8VVOG`6*0nczVHdm*EfHZuDGAT(=
z!&owRVAF8RBj51vu6;30APxyEL_}JpDRIvjcz>C@2O>lDe!sGNXDuTkM`6QCa1Lfj
ztp=Q3KywxllrY+7;=f9CA*5UO<Pz-q43HFe45p++fpc5ncaE}KHAAb6d7~L`duq3N
zV4)bYOcYj=fOvz+Rs{y+j#QXoyV8Wtf3kax?K&7dy-cDSNjAP=rFp<aB~kD9)O$bx
zXJu)hSQ+X^m?uJ9ZD4)v`HKfX`9H|%zdv@4j6d4wyrPL1tr}Xt>c#&bs?M=H6JXiG
zv2EM7J+W=unb>(_+qN^YZ9AFRw(UFj+%Na6)&HQ^>gw9N_EUGzUoM#xmRhGI@|1m5
z#M8cfSwyPKC%{9!I3sjErfk_VWWi^h;-vBZuF=>M7HbcS&{w&39@;U1@>7_Flmq1}
zPz13%kMmb4I0klFl{48}83&mF43HJ^)VR1%*$g#m4Ra)8lZosliqcV0V^>)+Ywgnq
z!(5Vvb2WMcx;OBVh_h-uE$;)$^P>nK61~Nk<<Jr2eD#20p)mW6XVRTIU<Z>%+zv|q
zLnL~os7&of(^f}!_;hkGsh0Lf^R2b($`Y!LYzxbvtZKK_%wsJ#TyJRrpAk>W^i%HL
z1D=H$MUjO$4IdOrOz%QJL){)t(Jj&IAqT-H=p=E6nq;@d`!mL?0Hs|9!g;**V!~y2
zckQofUh&4Q07=ba8`bOP%4O2@E?if#T!W$aI@%(%Zf<v(Hcf?k-JVIN!U~0TpBYE^
zJziW18HzErQC;Z*YN`o9(!<os$Wzd2jk678a^x92cYc!f3gjd9Q7U>0iPb}98oU+w
zTfT~O4RbH0r+D_4k9c#dr(PC;6Ed^mvWjf_RoG)0%a8cm(Wp3EkeKroL3vbx6jMDb
zOsSi=Rc@-h|4}zo-h0kaS;vY#7y6D<$*;~89y3gH4Kewv7Y$#)wb~B5o|KaH$KC<8
zbauF%LB(pN(uGNhpR4>ODSHm48@YysSxfv>ue_9BmdrM^IMbt6BB7P_jkOG0vJVAg
z-lv@7CN}?R-5zjjttcWbpZ8`tO}9{{QAaf2xr42#Qf9P53KM)JwZtsD&Y->3fj_>@
zh>HKOp3jTDcMT%s{mPZnFG1jev(cMxpm-c}&i~8_uq6eMk^?x|SpUDax}?ePu)&11
z^+C(k5`?{d7fUF#S0JR4ucPQ-7e*o6!S<{4`-`BLOe@utw>b$5xZpLGWQUiZz*AKL
zCOJV+ks!rgDXjdOVE9&S{buc?ET*GF99&!iRoIRIjmd_hR^75t{I|99&sP!ia;;u6
zB_M$<^_htNkA~zpjB&un(}Xr{?`_(ngq8ZI?a+XHW*Ws8*I3q-J5>vx^0m~slg=@6
zn9;`clk<a`@3zZaUUCa_-FsExB7rbc(UPb-KMgIJE>!nf+<U1#&PINbbMjaraSU-n
zb8&UQG=@otnlPE7&;`1xpNhS{TjymdH=xzwl0q|Kemjg_eTi)l2F@DO<Q%i9i0M7p
zM`KW11O}xLE6K~6Gi#c|a<Ut}U9+e~G)bL6$INSP1SW)xF?Q=!4FB}}v6%Y#*Ro=C
zXz+N%VV0~v$V#ciG}g$X3Sz)MjtGh#9m@3n!(!bjl;$;F-B8-{ulo;UnG54i03ZNC
z|L^=PZ7p!|30WmHqu?xURJbdX3ypcrVMMm$JKXK^YJ22$O(DG08o7jkhBfQ&XDxT}
z^rUq-Qvr<o0490h_5o?d27>kP0O;pJhJk-)KTU9mw<s!@p+Hxe|NS1B%Pr%uukTt;
zoUJ7mWaBxwD@B8gy6z;vn+4wmKwFg~zBw#3G8x5YpkMrUPcrQ~Yg4wBxCrq<u&jDz
z!1l}KHlJWoE?|JYgB#t1UurprOah}-#U;w#j}rfbfM<$V^%ROm##ce|h<y)XFXY?3
zaQ^uUe^p0p$%ySUkV>EW+#6i<rx!zCS;(cPL`Ej-V;o%7yt4xWOFion(Db0m)cr$T
z@TTYmFQZ)B|HhngCnRj`xGgA;wMZC~bZ*XLjm7yd^#gw;<Vi%IS-U?T)KcflIWJoh
zxdUKLx?usEpD3C=0^~fk&>qagMc#INq+FHg{ryc}-T{8JF$~{qgU9QUDQbNy=w67g
zJG9yL0V&T8t_NdgZ|dxlgxL+B<mE^K#>&dfm9*+Y41man-kx$}TC6%5!lhc+;f$kc
z@OZ-eP**gBDq1s28aA#!uL`<s{pz@j3Hf<7A2yHK$=QjmE!cC|d&t}SV9aYJ1nlFU
zbgpRI=IyjbC3enRA9!)j*yr_rKEyEF4}^uqeLvpJ0(QRN-=cvyJFlRjM$-|%REdhk
zUR(B10UM8HQHlbOb1Y5es~|gYUdg$8CJT>(-((y!ZnJy}s4$Hmw}5t;V?zP#W2II;
z4IHb78&U3iBSAefOow){Zuf`Zr`Q{@w^w@^5k;nWM+qD)$=JG9?VW{2wwaAnM)5lf
zg}Cn#MY1v}N)fa@$1v_hPDxzWWQkr~gO%K|fM48aZhkZeHiIYg&M_>KHt!`90g|c#
zsw)eg;tfg)nsZ|9Hb=tL6D=a{GiB?WRG4XAm{SmqP&?(i&q;S<4G;m`s)weu1|U@|
z4KzL&64$5{eu!UeQ3@ioh=oZYI;ZM~7%^Gkkr_iL6N_Q8<}EV@t$JQ%tviWpRCX;<
zfagvWw~r3$DmPkBtGAoyxT_OPaeun4>lh`aWP46sTg*xKX|71+Lo+m)$#vYdqy9hb
ztpNu9NSbP@iA~yJp;?_etumBh*HSX@P-mJm7{RPsh0UF<(<lXI)XBW0LR9q;X1Dup
z8q0Q=vu^rBBz>PKjdexU6a_8yhFIB00Ln{A8DwDpZkoVw#dNmefNwma!J<H%Q&eWQ
zxv_w_1x)Jv^ePN@9K?0ZXlBc>`LUEA)87!%zbe2WQi19Qmcg{@N)k{{Ve`RyfxLD#
z@S`}KV(4ksD`MPmd~tjxZF43bT4Am|ALm;6q!N88TdIC%TW^8^>&To?Cr`fk0w$cK
zGNiQwii<+WK=I1fT>gqDT`AqkUB*)Cegu4B``RqYBkQ&yOvL0AT4&NZCD@)PMP{W7
z(N`2jD+Dqkbx^@Tp$IYZPkyZm@6}y}ZG`t}dL`IR(Tn{?>8&7{2}XqRgl2|)=unYC
zFcBgrji)u)Pol+veCObOr3gCr0OS+4I*4{7d)lvZiiz~hv7nDk9;cNL7OKi-oOM%)
z`FWM(E<QSfkE;7kI;F8xl#}MRJ8>MD^^cOYsI;6JoUE|2%P9>AXKMtMl=qQS)XyDs
z2T&gZ{l=FI<=S|G3s!nT(e*1(WC=7bMteea1!rO}bj=Sc&4*SIq6(8#19-SA>HrY`
zG9U-#5Wm=F?LsT*p#b2jI)Wan>zF{}I~XWFw!8--y7e&;+)Ggrn&^TDbHKBt2bkGe
zCG8}z1+^g2lSV8=yE2}q%*-=Ug++>KW22FnIIF@_HB2eh<(J3LCSdjP&?ya<AXC;N
z_!&2&c$~a6JurE$QH-zY0UHLqoaMjIsYw>1g5e`y!L{lPx@g|`l%Kp(&4<-MpJ*eH
z>HCTG-;=TtPu*6bt5LZ@!Ett@^aTrMU7CpdHRtm-=;~;yoYIwxzf~z>Nf{vk<lLpZ
zI6lylvODq0i4lDUFV);OfzsJU7=yZ^tWr@7tghM!pX=utv^!b|fHrIYnols&a6ZtK
zMibVYv9As^=CgtaXP5)|>Cbgw<ym0j>)3^=t#JhxIX4`w;xc%~%6Xh*VS93xNoE{t
zyM|?2&8leH-VA5hDAGiL8}_)p`EH6TMr4#U|Mfy@*<;04MM(^mUI~9aEZj}wMaSs;
zG@HC*b4QrvaE8M%K%S1cEW;0u*Eu{U78G=BMos@h<#$F7PR%JSlohHklw%_ZyW<4C
zAo-)`*n#I5%qbc1bFM6Wwe*dAo1NkL6440{@<d^Dp?VbEp0Y?;oNVC6=Mlbm14WwF
z$VX8PR5R?}Y$fQBYXtLNK5wWJTJOB?Tf9?0lF*D(UR>HcfPcf7{S|YUsnWab_9GMT
zNH(@A!fD6|a>qf#2E)F@$}@Uq-s*bA11%b}W;G3l<YDhrJ{+Z_va&IQ_a&4{udtJW
zu*TQvlA<pQMV=C6zO-U!j|PFJ%#<{7b<7bXPCl|c$iCZ9NR_q<oDKcetRiY=_G^^J
zG=5%>ksN{=05z4F<q<bBd-NC7lfdLOja=(=$ue^uOI4%7n(nc%NA`tJX@$&raB5qT
zwk>V?K$!wk*m0gP6b_O2GQJze!aI0+ZC!SNoAGicOmv*xrpxXlP>8lVO4-=_!b-Q^
zwYID)mA^@}3@Hw0do)o%x}PIsRF^_!$f>x8qkbG2fGRLUp~0otKvWHZ@VIbLVU|6A
zSXW^XOV4ya>$SAbIZ|OLQ_za{*`oh$C+1H2^ubZoAKvw6sAgHrnxnA#xKvHPl3gfl
z=pb9JK1fnrLB^PQa@Qc=f5yslGi!^vUQg9O!Nuiaus5A4iKk<&{qKg@O(~wZw5Y#(
zG2J*2fWggNHZ)o&S&C>vO(w;JP|3U+{2PfiRLkT}-w$u3UpT|f?ZYlf_HyClisay~
z{CHzUF4Ny_bD6^FcIh``#%6m`K~ZYw?)f!K@ZAn&{)L;`hn{!0W3%_B3h&w?ET`Lw
zQ2^%n%h35dSU`pV0#!;&JLEOepV6M8{?RvV0L{$&W3?KgPih6?T{$bQsP-~T*~3%k
zBDHS)GGD6sENv&>3v}b_1!xg{g(s$oG(8T&Zt*YY0ka**JU|gQ$d*KVM(*t4_X>}K
zo>`e4?d2uE!*u`j#T|!wsi_0!11a31>HG91IV5o}MGMQg6ybA0h3dWJHSg@zhOVm@
zfbWi1B2O9qJyScgaoS69$Ht5x#v%(<`~DCQ!kmXY3^<Z88=`Lt^)gV465V$2?edZH
zX%vd<wX2iL1qWW|O_I%)TufkNCnhj8Lrz<&d1C@Gd{f!2?{MHi>Z0O^U>ZjKn?@!;
zyH4$I;KKuJp4G69b5+@B6|$6VmDsN>K(TI<_EB2gQL+M19@EZB#1m_|gGjCj{CrsF
zR+_Y#4$`thas)05qS;hbCeHdV?u|h+9Btu2@KWO!v{sp$Qv1Ez+~aC%$%=cJjh)uy
z$H%I5!qa)NNDg_?zf?B;^;qmj>iO!kd|6P`59PQ#IeZ&a;kjfj?j$hhgyC0-fOl1d
z`y$t@U<xx`4ahKcoL(wV5~Yg6Umt2*-sKFU8Y$g*WZxx!4v7Rt3muSDc8G9y>S7g_
zNP7x~D^eWhrm?RoOYO&EsN@cXpPXX-w+NzAW>#Q)4}$djrGgJ%o)0Vi14zm=Cx?u@
zd`<BcIh@&B4KuMJ1D+o;tvuFj0SX4oGh$Ivy%vZfOtz`PgdF;|iqE#4mC8#|J0)-^
z&JP}Du82lR6Mv6{h^|HXRM24j3>te;?r@?N)-r8L?sp^}?Y6$#QNcYQTL~`EZ@FLv
zR&YK-N@#B89rYXsk_Kg2AsUOJngtew6mjg`b2_uEf|<1_FgEuaKO@d!0gJDpVinNQ
z=!U*6bY<^m&1k0$*?vA+Lhb617(UbJ0x-krdMvE^dy<vKpLpuNX4njdWaULoZ0!(X
zX@*K2Ps(&=0j`)Q6YTMKOBqUewjmZrrRL5Cf(+`H!nxx!F*lK`zsI8w*g3i-`8`z7
z0+rkcxWQM{JQ@mk!ngyX0I@6quzvd5=ex!uH#iKpmAR)~Fzvr37$}xxeBSP*o%d$k
zy>~;0+%XCZnx>~r$e?%iSC8vVx=OcRvyowsSDIvcY2SBGcHa^L!^a6o>wOq4e7Q`=
zsH5gP-I@&xeQ1?VOFik_HM}no2QQo0Y|e(IPk#|FrV{CCAWf`H0}hLWA-`m3e9U3z
z+>d#xeMel^OY?1R@J0^08f047Qk0IjMSPSw(`uk!3=>k*alSbi&mz7T+^MBE$8c(w
zC?vYFbp_9k4vvQhZm{|Vum`%d4L^Uat6%I)97zf459hb2iNm)nUAeKsuB(@R`)IC5
zd$Z7~edpRWQ}Mrl0XFY_lw8!7Z|)<1be3eGFVjg+yceQ0TK5x3FrRWpADxnFnwj(d
z6$_f9#)8ioc^SIP!z&gKo-U86%rw7@>{+gHlMCCyVMj)SDI=pEF@&tV(lj*5jB<cc
zIa*+PHb(r)ig+f9%1_M=^YPrYjZH&us_u*TdPn%cg7arK!1_!DC!<-LOpbs7EURnt
zn&lP}kDr;t5>aqT!>zJ*n%VYSY@+h(bm8O<)(lfJjBr8Kud?EjTJ8vu&{dL{a88w4
z^(V7e5mhdvs8(L3Q(ezotX*CE^^F`uB5Vu8Izegxl}{b5eN6jRphE))J_12$KxF!R
zH86f>2vp<;z^DBM5hg^MrSs%!HM{Qqy!k0|zUx|Xq7kEk%F^R!PwAnwNvR}sRjxBM
zJMR5B@~(#~We_!5dX)9(KAQbGA38S+jZTZ@){5~%1qE3L!wOZp-ixNFYSxx>Gp;?E
z=PI<sxI@?5ss62(!|~P#EBJ51M&u>k?Em^9rzEUyIAHewNCT{F?EmeX=<>#qwj=-Z
zP0+3(&TV?u`V2up1wawt@VYWq0*bl0@4zwNZnEMkjqjG|ucqE@2Q}fEta~aW2``4N
zbNu)t7ID5Kl9DJbT8ACVHW>H%2?uv}I%jtP++Vjvd=ai|%W~O0n}dL_25D~;FK7U(
zkLSn5WCzWQb?a?~>nrQt4Z-*4h1U72>gw&wvzNMbh=UWX9p`0Z%?1A>tBozRLI_-=
zln=@YD~S(}kMV#m#Ury(aRjZFCUq+fmdUR3v<((y9>pvXm~x~3U<X&3e=g^1?`)Ba
zN6WVU&-0N&nV=8x_@|fl-{a}CyfQ$eY81zF)2UpZAGZ}IS&``Xd)%UdydeJ)CfRk`
zv^GBYH74!h8QqX^mr%gu6kS5rm;xD$6=r?AkjXVofO~g<tWRpUV|(XA)P3az!7y4#
zmZ)b|4F=c(t2+iT$q4iJ?YJzS#J`Tjer+>T(F4PNekO0mT2B;NW|ay(JQWZC9D!A5
zhKc^UbK1}eZE&kwu_+N^F=6_qiF(K&B|tSoHUQVNIvp;Ct<e3Kyh+zF07$`VUsw^y
zom^iiQ^UWuiE-=xHhK5j5Od+Dp8YDU!~thTdKA__dsShy@DX;W#fb_<0#jZ_SIyzE
zx`=(EK)~FDVYlxKuYK9ER35<M7(GXY&G+os$+llTfIlHP?#rLkDy9?UbhC^Asn>>C
zioqw4F^;aCFoWB7z>_;(L`PPhhQ25MC9GUAD*eD3(cnqxow!1Md(1baN5fj|+k5k;
z0sb#(xoDBB@-bVelqTu-4b!q?^E*y#m5JrlPPE0S!>^@Z)$k~W5Q>12Olo7_0%rD1
zF&0MJY;ox0evE^G-mHzPm`}0ni0M|ezSsdC6t^uF@&!^PD}sq+ZTPupbMqrwd?kj4
zTz(m&G(*zDZCEVB-<06+%Q6VzMtyHwITT&Sl$`0=5Do)2eRNmp`DLlpM$;vPI^>zw
zeC!Z9h3&`E0_kR!%-I0Q*%zTk=R~W2Ib+=u0n!+VBE~7Rb`<~xGwGSt@VM+K8!J&I
z1M)O!cj&83Sz#NmF0DnFmHlObgoVky?5{Il(02s-%NL=-g;-*x_T`S_XN-tjm%yP-
z9uZ@EY+~ltsd%XB^7>|6<p>bcERA^+w_#lGHDG<CV~E<@zf%CVufI1$D_z6a05oa*
zz+sRxT0EOoQ)f`lb<FPZ0~FPVe3%~mYDiR8YHS#v$Rn~0JMaMVRbgH62%I|RP3wky
zD=Lul`rZ|INOGS@Vx4;wXF*+1;}A<ncFj#ZnDa~-VA{@KxsiB}2x`0?)`;MhZJr-l
zOXBD^!eadMTABdC-HPEzNh1zp^0+<C@hd#qxf9?&eVe?R)XoKM(Iy2R1rFv<BYeg}
zJ?rZqqV_J`7;pNBl5|$v3HArMR>B5FoWK?u*I63lFmsE?nSwGjzbaPdUKiX7Oy-W*
zN$@&)$RP`bF30j|nXi7<jW&gx4wJL?iBNwIiF!w)>cjx$9vI>9b!#fHp_V}&)%hX&
z$Kzu(0~;1s^VrNVRfenrL6Eql^pku2^(qc@?ih{EX&MT!SYuV?!gC1n0j6OMhY+aG
zf=s;)PKb&ypi`1Laq90)tFx+f^NX++k-75!rhjOv>sfkXdgVfZAi2aEia(gj8t>C_
zde#aZW2^w5!@R4HOU;m8cHMI6c7oii;>0;W%?CM;T+QUzHaPKkg^8O}97}~+ulx6v
zE0`SZLEmYYH7eG?wymg9NZ`IAC8O(f`T}LtE~zKzX;BJ3q>vu>iiw$CCeQvydUMt(
z=p>OA7iVF^63)8fAjNN*$zTeaK$3V=p$Z!KZzBMVQArrqX>k^l(L3T7dE@AwHe%K8
z9*CX?Z2EYt*9mmVHiBcHMoJF~d$YJ#XiNt!0KLwXx<k}LgW(n3V=6+=ZmNd?)~d|d
z^Rh{PA;dmLW@<|28q_$_-rS(KVT9x7LY^OUlQM1A1;oM&w*pM85}R-{LVE!O;Te@t
zq$=PgT%IB@QK+TG!dJmq;gm9#39FDc3qQQ}I!mbJda+8Umw9@tUB>K&Akza3Ne9Tu
zU$l7~vLxNR5N&TGNLe)tOEVz<Y-uDpuB%a$mFs{<j{z@6wT=-dJCbFcy@;5bQkF#-
z&yC5!%==cIO~zsLMQ|U^z3;9F214a+7!ojgidSnAk%=g*TgX9U0jv}px(aqJg1g#<
z8PN#t&_slDaoz@K>`&DLVGx{09A|ibzOqk!+))MlYomd*`A0^tJ;_XsFYaXkv#1b9
z&si(OHusYHaVH%(`3bA=R6no{334WJxkI#od^axC%LTkR8L+)mH8T<03u#lxn*->D
z2GuaYEe&U8kFNni<)`w-s=edJsk&rJvvK<4=dYiBtEM-gQQ)1*WYLC9FtJ#7tJr{F
zUV9{5^+zLmXnYvrrCjt%0&far4v%I!2Y@`7$r*o*tLw9q>++!Es!jWv0K=16pz%n`
zOgN)l_2iImB2iEjo8+gI<<*;*R0-(pUYVuhuFxi@d?J-*sC7CVLve+cP29<=PqBz(
zP*IMl;Z|c6)9|oF$H)DJCWoH$?V#-P{1bWoPn}g}RJOkqDeo-c<m+<CA@0hw$18ZT
zpf7!!R&rIi-avU*jCJyWkr8O(2_frV?ne`|5i#8w`Do>E;3?NWs17`ungCRr|2D0!
z3_9n)<B8ee>JS^Eaf{UR?#)-)=%{BSY;z_wrnJAFg*qp8yL2B!;57+6lTx7x5{JrA
zn}TzOruQa)QI=T_GL!fdVU$}~dH}8Kx2P7Dovh<XDFSkrsCWE;mh4u<|J8a5Qr}ry
zm{{gvYyjT+__jgtP$6NOdkwhs0obX{Pu=BHM&$fWl1_Vb%`ipxcyTf)k+Zv?Z04B)
zE&t1Nnopszwry(KS@>#4QhVWj_zB07lA{_|bGl8O>I>`=(6h0k;1zxXIYv5tP2ah)
zP0ArP=l)bv(onyI=7+=dabTSj4N|Q#oK<6PbEC;uH5Rk*x+h_z$qZ;(Z5ckmUoR5`
z%;<TvyI69Tkacy|lRz``!(Lc&L}_D2Ec(2^pFQ}aHIK=$2SceT?bm(TApM;5v-ml#
z3lZKuJ^1G|HW@prbCy&z{xWL!&g_M6Wwkk+chgpw5!QRAfe!7;M|zJ_&Dbif`Zzn^
z2<|Kv@4Cq*-47Y$ng;Y*#C;AC#4K%w^QJWZMaoo!N_IZJ<WY`kym3j9Vr34~Q6lI;
zW3%!5;#URzTLtn$l$2vp=49QiLX#8u?*@MABz;s_U>>px{XE&h4@|W^_*n<(kK9hk
zgf3z$LI}dJzm%1$4eC66>}s~}btP(;4FlRoY;})tRAeZ1CjYU$te3PG=;Px5Vs%R*
zEppt!iGuF8jbK5X+lB9O_&MIx)kT&KNRcYq@La@RLrqAIZd698O~L|s0C=A4D;FoE
zc}clJ;22G7sU=ntQ`jum_JQ9yHT+O1D?6bsZ{%VpCEZ~#DixVAV(~ielD#`lN{(LT
zLJ;Y!iPzI<#{dh0d}rpHe-l;)mE}jmHD!hs4A3~eiA~5xd44Z`nY}TkyyVkH-hKXN
zY*D6<;jUhvmK8Eh_)^(R@{v3*h0U{7p;QwoJ4de?ADh=dN}=l&7MT?9G|x(m?jlWM
z4+XB<df;>lFbP{aXJ<GVY50A~!KU>0K~sr?VcP|f=No{&56ebC9oUJfA?!vXotA^K
zH_NJlR~1<y<2cTo(^elZIrpJAOU!IULFsC;nt$FvxQZAuY#f4q$-C*y{v@F0npeI~
zQnabhoE5lH+!=mVX)w(<6VbxD2qnhjA~C@}%T$s(I<7>WNVOVY+NCU6+hLq|EA4bq
zXYqRB;0uVLSZOY9KYKy~?RiX@UsAohUVI`mUMhZmXqBi=2-hwWFPFQ*w|3q+qlIzG
ztf{I=i@tP8#39y*!f3ZTL~0LVDg4J_*Rf$-f@=1>9uLJYTq@U-dxO*7ad(PEI&XZc
zrg^5H6pTD3$Ftu6_N~{ZUyj2=M-xmI!ckzkGXdE8c5}QGYr<TQm`x@gdPitZ^7A*?
z)&Qt&ZO`gl>ZQK;sowAP`}$0nk&dPf8WT0tM|&GSQgkX>Q`5Gi4$M7gCpmg%mV719
zR6jh1Qnxz|X)xhKp4tsqB-EpZ)UiG+;=mt1r;U%WX)hI%&h^$dUa%n)EPX2NNTA`y
zi2yoU$iGZtr3UUmB0q1IXkDWDTgv{>ai5v&jOh9fd|{sxwvS{1Dah?q2cjNl$bi|E
zx1qCUNgjJlL7qzORSdX2)2z1i$U^(yJ(6sU91MTP=u>q6bqha{zo#p=d1%vzLtI$s
z+3u-s)Wrr^*&i^*7U+dy+vPFayjGpz4Fh;8J0-UQ#{BT?cDuDdjZkp`i)FenTytVQ
zhm^}qx;~P^{d}m4$q0QoQap)A*&MGkZ6{ZQwD=6(?LR2;);pTe08eVMk-T)RE&1m4
zONk(3G3oD(w`#nLE#vA#LEoUb(%w{OF7uO<EZtpW*iEi8j1#^bzlB4QOf!=W2GXs%
z{lVp4&BWJ|$Y@o>qScc~nZ6%*`cXgSv$CBpSXiz<^8Yb%|8;AP6#sb0od4g*z0#G5
zBjrT+4_B{F{RYzTkyywrpc{OnRSdyip(|~gxa{-mR9Nb7mF}}k8Kp22(|SoFRYdVv
zTruB9E$&A7&nU+rXAyqAedqT+?)Q=45AL_$Psi6mo{vc~*ZJzR*Mk9lfv$rrio)L0
zBw!Yh4D(Q!^Fv$mL-o`C7U#?Dh^?LRoX5yWNgNE=pXu#97D!&mx+$~tIMBg<`Rid1
z{fPDekh53HO}+O`Caf5c#W9z50FPF>O)KS24(O#(GNh{w?RoQLm4o1~z1=ERT4<fW
zm{h3!+4l3G&wg_y9nfn2YRPFMQa+23q-+Hka9HtKfXT%D?0h$Vy(${)wvo%*U}M=w
znEUWDizl09?D5&P&~Y*dG9)<4rL+3QRM3WX%RutgN4!iFUyq;|4bSn{Q8RHi+;?P8
zvzl&hMtGttL0mDm{#kW&0Am_PvatL+fXXV0)0qQC{-*&P1OMq(ot&ESTW=Y<3HloV
zk);%YxsEbI%a{&Vxi3i4lbWijj@_C2r~H7)OzCp9l`qAtFN-lpWCUCKMpiDs@QEm6
zb1~&=58ceH?uom`n@@U0x*LycV^O(-poOc_gij{ZX<rug-+#g>*Ihwcwhfap!CC*S
zEK-h`;<zW}-auKm-^1cL8uxAryb&7^e$X?FbU{frG9NoAno!j89v%vq97Y!agQ?-m
zaQQ^aW4i@6MQ_jaO&#tjUkZJ5t8$2bhA?H?L7s~hP+=&SD=~?;u7ahT>bw6s4)(Wl
zdDmAx%PfP`=!1HwDU}2-E(kwr$t6tKL|lovjv=c@to{A~`JAyhvMbF?7=Q<;TKTEh
zC}rHE+BWTm$UJR+9FGQCT*QFDVRSK&JU5Ox5*#hx>tb}L%LeR3-sM+BSHSHQ8If4H
zb7ok;NQQ%}b%Ic^o=3AemsUVORQOFF>83l;06U9Tr9Zo>u17#j?ak6RTG%3HElmb4
zp1L`SLVTi?%xN!e@uT}js`CS!4IcUTeL#vd+K03p)xxeGIgh|GZeyVbaQ<N6F7ICd
z)2Q10L@mAirsPEjOMYrTfzHBF?ll!nGV_lUZ9|a6qSrhw^j)QyK>jd})rP=R$yV-7
z>gO*)aP#g(lJX6qY9kea_Od<ME|i!V-W7cRS{+DE6JcuICW3J#vM&H6YElc3+Xvul
z%Y&IrV-#2oCwY^Ow22`x3`$Z){IMOcZ22cA*o(s;dlE;xi-n+PnABS|AQq$<i&AkG
zR*HA`S4nfWX0BLshcZKhe<?u<k2^nIO=&w^>D_GR9n<7<Z|Eq6OFi2;CWaftmopJ1
zj?2Rh34bZCF*|aF4DSK{)^JJxc*_h2C=_yUxjeWHJ$zS>$O}%#7`fV7p^?sKQH$eu
zmtmRl^F}%*@(6+F;^PnY5fSoL)X8bMm6TF}Z60(Mdh7BXPlf$<0RwX!EjVKFkHfuu
zUKhd!iU~2nY+`8#N+Wb@3a&XRxcpRhHOG*gXFSvFH~vl6OQ8l}qBGBD_FUugLcC-V
zj`<S3wNrh$FWuGIqIL5URJnXTt}#x_pp2v^nSt-78%#h`ulGabmX=mPsqHl7Zamke
zkO*gHlKV3pg5Tq30_c)vVl*gN<=(qZ=ZAVT!POpahZx|#MvBZse!4y_ZPiSTn2=4a
zxZ&3tcm<CRS`q@-!ubl*V&`Pi{HbDiv~ZAI%+WmiGq`E_QRRI?IlXwxiMs;j?J(A+
zizMmlRA}V*1kXWzvAg97c1r>8#_BoDrME70(6Q*lplQXPw3w()Ei*~yRBT6<Mr?))
zC#pZmakgM)Ywn+fE8e7pC2(8{zUyNSM)`NlP1M@UZAczKMjkSH%VK&&Z}b;Gs+cae
z*tkaehz*|sy*f$+oVNWEoRAjkYDjt@EIxob&|8y{<e-{teQlks?(R07*c?UF858Pt
zcUQ7Pf@PriJ2}3>R$1A&+MWYi&Sqp2mo-#w6N%b4{F<J;0FHbGqa$%HkYsZSPOnL9
zO*<uBQfnKqACa@k7#TCtb*DFM7jP&~;gV1PazD&I0rIh}^Hlr_N_5F0nA3gUrBL0O
z-yj9T!Pg_7myX7<&xc{1JdqwKo=5LIIzp;Bbn@DweUg3S5=7?QgQBw!QpBx_IW(`o
z*D10T6ik@!n_=J`>?MoeKN_d)kyC`$W8OV*9})+s3IMy$_!Izi`+7=58q~K&AoQM8
z@?d*?m<j$4wRl6C$%@2wnJ*yemkA9624SEt;DJzBLYZ!I(Nw~sygn=d*XUek$?@yw
zwS}Mu58LUmw(coIHtXl5%^ZO-WgbFUk?z$=)OHpG+fZLK-o)DSZ~FDRUBea2V&{*@
z|1Jq2zw+%XhB<nXZYubgFuE{PHbbW|6hXBKO}vK66`1p^B<4laIfjyF-%ye%YtL`L
zU|TXOtBB>6t97$qQ5q@tI=fn6>uyalzP_R;V^;6A2Un%l&4N*24os4(y3V8UmHlBm
zGx;d<%v)WrnS4@6O0efqCdph>L8&1L_VNbol1AxE$r=lplTRcS`zft*p)^y)c9%f$
z#i+!TP#rka#}uaHq9Km7>kFDkv@LAppSO%R8is`F(V+<pjaXVBl7qrtZGkd9A^48$
z8EtN=YNQcwAI9bj+o&{(p5~%E*lWqsmm*q(@NhbtMoC>%r!4nc1X)%1j2X)NWS{|H
z{rsCx-3)Ysu))1hStG?;S+CNSPUo}cXM#()<I)wUUvr^Dh8bn4=t|iOV6nnO^kdA8
zpzADhFF!Zxd}5810G@*^GXGLaSTPV2%pyu1W23u`xH1MwpxCj;`^!1y(u{9iO;{#b
z_791K7Vf1{$lQiuz83-!d#_}nI_Ln~BjMvHhmf~8uxclZMbg2W2AoTyd>6(v_i$gn
zQS~i5-H>yr#7Z^0KzDa+vnRXZ$4t|B@}(1o96DZS+6UcXLVfEqtl2C%kHU;fIkU@v
zjdCXWqm&TGefn0|rERyU{Zh$fXG~`1u7J+|r4X5<euqdD=XVEY9nASQ1~ot-ze=kj
znLuY&*mX&YQ_pG=;sO{NEvH&0L(+A9mht->I*#`(ObmoU2@;=m<;TKqBX-`t+3}-Y
z8gj`BvD@L&*nuqY``rmMMLmBVn=XRc5q&R*%}zT}vI=XR1q8Eiq4H_ki=BvRV1I`<
zE`HkNp0Px<@8%b-?hFJ>2^)Y!5&1p-z;j4@&l`G1=pWX;<u}j3iU&%gU|{6$sed+4
zpI`ArC3ekadde?q-y)zzm39u+o>mJuOrxcmn~fPAn(;r4!>t_7IBvK(2m*#aT7rb4
z+J-;O{rex5W5WeHr-NcS>I@S8R$vi=i0mX$H$AN{vAEZ1JM-{8F$Dk}EO)f80MewY
zyUO>}+gL`psW1X!<l4~Q3uKhzU1XF$qox&N3|MI9**ZqDv=En5t|AZ<(=(WjjEKtE
zjd30Cq%K?wR(>P*@OTj?^Y?=^e$@n52w)wmz7wY!g}C8>NJ;rZxkKx})}%?{aP<<8
zm;Er{($Bg5zeRn{g@*ty*mNnV;yyyZyC`9_WMUf?HP09x8>r$3>@JZxZ!J)>Y%dy|
z`l;v^NT<9Y>+f$#tt!1M2wvB`;Z9fgQFMA{Oe|k(fv|dJlCn}Y{I6rz+D*;j_GaFI
zH<3(in*-+cg6K_kJ*{iHFIAO+Uq^H6mkRjPIxXvMDdr5cWge04I%(R#wg^7%I(LA@
z_<J?~6Cb}1pa3wla{M<sP<K3b^WPG$6WUkM>E8xGMTiiIK<(JqSqVX<kXKQ@x8uEp
z3~I_!^iQc)5Lh^%!i#8P4ck>TN@~Tch!h!;fJD#Xt|&fHx6fRdZ|TvM#)nbRk1vJc
z;$0=taRf?=k`rYJ3U~#2JpEoDB#{q5chs4!ERQXZ{2A0o4okags7u$iyY_{y2CR_^
zewA`gdMs&$19+3M8P7+3v93Z%eeN`LttR{veKz>t$KNyj+<)lxgB5F@bG)gVV{ZZe
zEh-sY*FW5!)8AatT%U%zqlRk=sYAQs)FX0im%Oa~zcGJ(y~X&N=UrFAzCsWHa#*qT
zr*k50Dal)fNxCXwco16Qdf}9C#!DQnqMIv0+F=_Yig}K7Y+MQ35Z?cE$mL@}G7)fk
z%lK!*wk8FXO^6E6tpy&e;{!#W%tsYE^B%P`bFdS&We<{60cll5Qnd5@hTTlF(PTXM
zt!oLi4EcrKOq@~ym6<jf7HLoi*qng24{m3>ibOfFR(G-+)Rf^>{HqA52@zRIC?p(J
zfi`7O&aAoqD_xHof-Q3l$ZlNf?oObHB483rD6a)5YYB4BDWe^kE2xwo(xI&Bpg(J<
z<pdf{RKmZ~{6O^UL6q|;cyjtLeibn;WYci5e$x7+s@{mxxCcS9tu*>0Aa-SF6H;!w
zQZdp*G2d_$2JO8y!Krx}g&NWymL1Hr5#)YLb+*4J#9YIB-~=d^Nk{k1ZoK^Kph;pJ
z+%dKR12>DRcabMVN15Rh<LC)SS>I2JGqrYJuO@r`iZVX_ywh?U2)o)D{<O7Zn{=R|
zCA}1S-7md0HNm?VA!7j=Kt$9mgOqz}i0o%OAJFUy`2pe&5r5G1_o?y>7HC~qe^Yrj
zo)l;{43Dt0efWBpL-Z9wv9qH2JD*}e5Yd|b@z3-x6+4dG<2|q7OsJh@i4zIagwMxG
zgB1;;uSW^;7`1+zIkdOnSM*>*OS%ia1!s(?duOJRS5+c5WW`)b0BXoLxVVXA`jEQJ
zM72%!!hZQci1#*mjEpo#utXK^fhujEUiXjO*|Uv$J4<CxwNp^(&p6B3g<kspa+Uh(
z5iKFG*;GEf3WViUqFzJaiQq?#Rz?u=M!WHo@L3T?8?bg!{63D}={2dR-4(;%HnDM#
zZ1IX_)W=kDdPivxK!jjSM#%~<{%MNO<mBL6YHR6n@3At*ZcH+;f8*okMG(SM3mc9$
zfz~UN`MCx5$A;C^N@P;3>3lFb>G^$z7iiy$B46b)dOj|f9Webnffe}xr$5d^WvWoD
z04Q08nOHw3btPAKsP`3&M@T5Re`7R_<MqEi0}#nJEDb{9fbB+9J<uYhsm13<kosun
zb#+FNVWWT{J&~9JL1s-c!kw0tLk{GgX<6vBK{sf2m>r6GJEH9b?`xKJIbcgv>E@0_
z(HAbQ=nEy=u2`Gl$b)$mK7_%lE0XPWGDgjKAVyyU#d4wg#p3s9js_?<=v5X<GmJj=
zeAm@55;-6#00flMn-w9<bxQw^OaC`%K<>-0hu_#-O{Y42HtCI#A#V8NIHy|aQo?A;
z%g8@Y6N7d_?D<IUZ6Rk$hD$zKavABP`W8{&EL;bN{4JSEsl^bXu^px6pyA>dA9WHN
z7dV0-LPgPZkE<uFroep<pe$yKg?VmlFJ(utKsa0&Ry&<0chmS$r(5;mobGfqHx`)o
z?ZA7XjA)V(qaiVG49By)q8+mYQ5>zu2HhtEX~aH>Bwj5K6V5lFTefzzcN6#JN1qR%
z=|@>q{qZtn_pv*1W0Q=<6c)gGyFVp9Z(pGby<e~-`N&B~-DpXZasOUiuKy0)9qEk6
z9&*6_dvQNOOXhokVtByDz{c$2d%(F>+f~|45u7J(Bw(pk8uTVznuCTcv1(E)LgJ#R
zG6{O%jd$-9;N%fzAdUx_{9@n*M=xgAzD8H}7A?4;W<U^)J-XpUxF~`NgUua-S6X-U
zxiqc;mcP1e@EK8SWx77^h+M7F1@s+8gOq9JX=db#nOPQsJz|2le`5`Yd$>1~3&vF!
zY(9bKVSztFT;oyUZ!XGWRJ>(4TTO0Sh03xII3SvgatIIr0AFUWXU+S!c7`+_te^a%
z9O<b}hCHWx7x~@h9Iy8`27|SOX<?SY2D5>HW}g14^b{j5sQze7s9L({<)h=H6LJ{(
z^f`{2`grMGUec<7Dw%Wbu^fwuD(v=%d`noS*s4Y`q2nq1V2gzG+c0{Y-<#*a`CJ%y
zvpnwcu~v5bK-m${7)ltFNy{Ncw~R^RW?vD}VgfLr@T@r)tM_=W<<_FMNx)5v&3Q0@
z&}}ACiZSGKxW?(o?6GLWiC5_oI;tv0NsDHQr<eTVHQjsV*}p_^IsKdp4ajP&+zIsw
z+**D%K;!iO$yOTv6TUZKGDT9Y{`kcWQ@r>kmzrROs0KGkZj?BS-b09Cx;W{3O%gIh
zQ-XxnE5Bl@fNDDg+jxOE=B`m!(RN4yo564JKCQeo4<ZAM>EtoV7VKu^(CA;IvDN-8
zZ4k<(7yj#g+Wu8tAYb{Ci<b`I!pM2BtrAfeKt7tAU_*aHh3ruwic$SRqEvlq_xyv{
zSEunP!;r5Ca)^!ma3Ry|;-Y(GD3^ljfFB*|Kwv89IVg#@>I9YO{FOn?e%&(x2ycQ7
zNA$FViKiS4p>fQAdr$M*ow%S#SnR%n&<=1-1}twxR0aEkb$neTatc*p{0bOE+mE<p
zK9IO(j2cgQNanAyz|!MVYM6$@{QS8g5uc|gH^%6jaPi`?9|&hxkrm$P^SX-(24VJc
zid-)-LlLSh=TYQ<K^K=~ghomNgd!j4<?glHd<_T;!hoov69dz>Rs*#JgsctV^Nhbw
z+=>jfkJ2^YIa`!t_N|Srvmvis(@DA)zOD9sHY{?+Wis`~9E`8j5Z?ry)@dc?4br*Q
zN_m0wiCam)^GdGTOe6r+^|xTha@1M}tHfrB9I+)1CB=<`G*);_MSE`otOt2CU+qod
z>#SlFkguGqGE!rysVz&eII1zyd>sfWKN#wdyuEcR@|t3yEl9f6rm&q2pw05hlTWqb
zBK!C>5!&@PPq7tT-PXA=d`9Mip|<|AfF8~eG>S+VWuQQ}^l9lX;+MqgGGG6sNJ|_t
zYnmq)^NCE-&~SRusq(M@?6-b1ZL;zffK+5A7i7WqMyguQn3mJQ=IAsV=?k1XN3!tm
zJ0~_zzUS5IJKVKXoTmpM@?ZIE(^2tu3yJcbsxKOgSW3k>SjUa+N}tQTl`gm8R{aIn
zfVp+Kn(ww%9N5ss-?CFQ?S@gvJSNu4&1H~@+=F5?bH@Hvf>c}w=%3P+Yn)Vt928bg
z^!TaJ&bsZPYee@wPokMF7lXLSu2hu9OYWv9as_~pS0V&L{Xu6Uzc9=9%THkbJ7*a9
z4|^A$0QXW8iP9>=RE0+;I$Ay?foo4YGBfvxuE^%PlomnI-%p1L(q!6p>iOhkc#8&n
zAQR+u+2!w*`@ZD{s1zGP1TM}3Ash0wvQf@$KfO^>J>i<d?sACc%l48D=jg4K6qx8p
z`|gGjs12n3nFf;`J-4LxXIi1RwBA7=@>!b;2t3#huH8$2->>M+L#kpfAN6QZuDJv%
zgbGIt>vMtOBU;VG9s}*M&+Lv1#tmtP?=GExicIrfsl0vw^l|=XVMe-xrY*VKASj51
zM6S^P7aC+lGg+i)V}wQHHb0VCT+)9e&0FJYyIo?oZrY$dDD;xcL&wHZW32S;T$&vS
z5|=!(6qn;^s+HfEFAoP}%q1nM(K+%F^^izv!A9B+fHN<}LMkb{jfx$*T76#@_e$JJ
z-nKi`klpJBgew>g4TcMbR{3c;6AbVHoi(Dp^&(gll@b#;1;z-nIjgCp85?E%3fjC_
zv=EDxT42If*kj*d0fFb2j<7`7l<#+PF`Y#yxNGdE9YvyN9%$ch$x=dX-W{5(36K`B
zW}_@*Q^~9UDt4MaeySj3g<LO>@3=$w>c~n6sU%bY)ZmAVrIt<=yJ*CURG+#UifkeI
zBFUy(Na|~?jZ12|nwf-_5$)aYI3cN8K|?&YWo$*3IM?8(8^%m$KcK&8H*-)3Xf4p-
zL7#}ODX{*rTnfbe5`yn6P(zu)J?<*j%jPa{uuOB9F}s0%M%O^Pq^-dW{JQUwZk>zP
zqw={1jM|*x+U>gAY&GSQS9jXvW-M1nM?6MpL-MT{l)HZVRkO}6@?`V~AJ@zhY~HE0
zBY9MpVcCTj@yMWrt~R6^cP$-AQ>=@1AaOfVJL4bt!C@bOOO?0HLKL3MEh(T19xe-c
zRF9vd(U8BM=M18~Zm2@aDK8lKy+S(Z=2XBWp>(4FbNrtv!1P}X*sFiZce2+1o#5j6
z3;yfw3uqY^s}7C})hFY~&>iDq2nOx!ChA|{WsJhxOTDO*m52_4b^5r7fUqiZc>O9(
z&X(^xVtRaft<Pt*MsPF~Ff<Er-vNAd`ThiLf>{JW*8BSH1Ru*@AoXfx?>%hv0`mTq
z<F(M&YS+*7SI;=YAD;xC=13$#hgr-LRiDJ0lDzg(fxC?%ztB-m@qS#;9Xv0tOKd?5
z?}rtxv>198Kd{G+0S5!|)76pM*`K%1*{hp8T7_O)S#XCIgVrdEgzcEK{MI~9I}nuy
zzAuN5mFEL|eqs4sa2r>QBs1w(z!eD?tA2jA>0ZM^rq%2tbPd)^LeGK<$SjXPoliog
zV@d0StY`CueW6ejII@0Pl$g<_W@q@To$dhwE=FP7JR#V==5M}(V-oCE`%bDEQS|Uf
zpiI%13pl*`EA7|B4k}J)<|vY8a3Gz`gOYIZH7ZFBv82`6vGMdVJva+pK*ahlt-f4H
zks2a*vO;5qsC)D}J#8Vu45FQGDN_ia1<)dGjsfb%c6_Xv-hi{m4WyBW&RkDj>YD)e
zVVYQF8pj+n<Yx1XF-cb?np7h6mB^gQb)bgg_|ML%c(_0~wM>yCb-VPm@2Cln<T&h8
z@imaExD-syoF?<_Bg58v07UQ(>u<{T{1{ee&-1X!q`Ay$SBDUHmaPY6v(}a)euE)%
z$}=)4GK50A(yv82Mt}D?_d7Bvi@5o;ti6w>p8M#XpZstw*1+~ta7D&<7~k@<C^WFe
z%V`_k1N5fzbf<HM>d4)Ovg+RLtYOJa>gsYa<WH4{s5aE83oe5Tzzsx2%L^-B-zTbR
zULLO!C09@Xaww`UdBJEG5U1V_)e}uxU@V7o47`sp<~|w~0JszOxqTQ%OVFnitTaiY
zwufx7h8iNIQfUPHBEAm#bb<lS67Tm16K#GpR&h-<UmeITh6{uOj0?^9=goAbarnF^
zvqxUFd#wKN7F+Oe09qotzpHJ(;*wV4gUw5-m$T2aTv&*S=R#p}uBDQpZW5ZXzi>p}
zJ%rOJ?~#YGSaS4yVV98@USr`fdn5ah&Kng}(n70j>O6$=vXv!!=F%pMip7PEsh4(C
z_e|i3ck_fHj5IAWeyk{Eb9z`gw6^&O=*pko-#Rv)gC0UZfaW_a>P7bF7G$Qosin0P
zRE*$v+6H$fjHpi2z)DN{Km6h;yO~xMgvdSI+~))16%Q4@N>Nb>IolrsI0Nwwfe@%A
znY^1SDa>9%CSjco0*=BZW|1W61x4b~n+i&*UfE8<$1fd38-$ffwvE}g0zI@rO-_aN
zX~(%_%z2^=fHJ+5Vk&>vf3&JBceg^5y}A0dr}_|xL^Bt7Ah=-6_Tg9a6c~*scz7{s
z8A@{7X>Cj-Ftx~g-JW*x#NT}cq9ff!=Txgw_~Z#(NpF2>AI=S>!$k&G2U08rh1lh&
z#yDemiWJkxW(%(Y4GV#tAg*B5qShs1?p1#?=()GK0XX*`42LfY^rK41%oI826FF`(
zx4((DoWh0K&_3J~3)dI~ieqoes~`zwP+^vOad4K&z|^~I{{WBfR_=URxvW=s8f2sf
z7A}M6A)V9m59VUhkoT>7Qe>zqDew%We~@U{jf^!nA?+g<k|$n`2-#-g2ia;3<AojT
zXDEd!0IZ%CYFpq+d3%t7+cI-}jO<7_<VaP5Jr7LUp?SY~l}v1!+NFjuv#6EBm@jw$
zC^`HC5$P{<A!!U@K-|lp&(gEoYZa-KY>lqZWIJGmhdjyW4PB7Bp!}k^kDCB}T=JJ_
zO3Y0hm!nj)?q<DWKQ|mQE7M-Jc#0tn*L2A;fVMfxOwOHbRv8Ya%+XQaoGcid_|4F`
z+gB#_^qZH6$#A(%Z^W8@_N~!0GZ_tAhDm1RWTHA>!k=I}w1g#IwqW4ez?W01%yN@)
zeBov$Mlg4;OcFvo^B%i&OC9Ql$y)jyD$li|AvA@g>ji7`WHK!mTdk5UK@Jis=4eTJ
z03p7k3on{N#T}Ppgp-sz@d-n?{wa8Z2$6oLDrq-T`vO7E`E{qXwgH^fcyyExt&t|&
zKblsyvHr($6YBOEbLV7XUz-$5QmoX4ye@{+bQh|@QA@c~1)8(AtFFkRHcRWsr9(`x
z8HK21r71?0Z85z(qmh`A?T<QseqAUvfHvGLCU2~ms>~EW9n+ejn-+ei5_8Qg0~go?
z0(XoE`vwPx*P8eZwSCKqDQt>PyW-I{G+v&9iQ5-x!R$QIQa@MCW4&5m^e~-;OjRbW
z3E>wz<M0j2tWvl**y{U@=p(Y*k*dcIQ70`uKxk0r?~zMrwN-$F><<1~D^?m3Aelm`
z#O_b{;4C>1EiIC7n*AH2QE5a(T!T!`oZjV(Lj#*pLr0B`PWN>6e1+@0TZ@AVvwB!y
zu5fFNx{1jS+_~zehbABKF;Ia^Q^P{65n3@(2!*&liwzOz+m?Z#9Lo;#qa}<@;6VGO
zxv_zTj6f1}o(L9&309tYavp^Y;M@ZTUFYI)(Ov!L(W=2MnT+y8eN}G$XZ;jFZ9~|f
z(9v!;^P0}+Uo=)5O_>6@3+2!$@30bVG&)%H8|}J3;TtFxgK0k}Mhr{qxC;OmjW9j`
z!y3)gdUAS)WF7h}(Mz5ESoEiN8@awbXO*^6<JahI`;-Ll1_vW3b=$!zU=I<AW7_o7
zsOH%QrjyaC{nzSWBd7c!VIS$*aYqATrS$fhU;)fJ-*kV<urn_!Z<e-?w#45xPTE(D
z`%~zwDsd|NG^kJH=$VbK0GcO9^IIJynqYR&|Do!fx-$u|D4GsBwr!(h+qP}n{?f5+
z+qP}nwrx(&yv<tm8>;T9d-mO=^SqL4-kpt!n>&iEFD;2W$ElPZks>B3CAKbZG4&U(
zvTL0al4_cO@*2+`hWLJx1*Ij>C&{3f^_^zbzLFNw@WTk6znd)}r7vQ?#;+<vpj&`c
zhH-w42chPUtAi$<EG)@^lq>G^`P=hboB<uZd6IxBTX>KMIkq>`{VlWuIs*;8jV=7e
zuOyBS6nH3VdSFf~-lck91>^ym+_9s0<wt7UPU^q}Xdo&MLEru>d3!cq909QCfdkIx
zg1Dn}j}}$DO-xQ=DYvV83f#i9LbP%KBbl2=mAr|sdAzm*Ttdqk;djkij>(7UFbv1{
zxZbpYXcn2d%`vs*b$&cocc@(6U${Jfk4-N#9zJ)YzDzcIpeK)Na?xYJwod4cf^5Ux
z`=#9ix>w>kgY%3FRd|@8o?VbN<l=FTc7lJh&&!Eb(`_;jbqvt7ugW$oD!M%^Fddjg
z-phOctlUZpSh*jm?}F1dtNbzJm}?Z3;MbF`(llqHEt203CYw7)!tF+dqjH4xb!#|(
z)<fc!@@aPZ`z`?{b^sl5RQm|EOyA*~t*AB!AX-tGc`x-B4nY?C`zAB8PvF25)zr-T
z3AttRqDS}C13;6g9(bFam+>79lgoPA-0Sw;bK1?DJz49|FzcP$^ZjbrE{&ZQ{wd2P
z27Br-jSRh3y26mnXoy27RWJS_IC5>><b0^<72G|^t?v6hCAdgcrqEk#qBAhX01n2)
zO6Q2U>FO}gaKc@s?pI-D;dmwk-k{0R#iaW8R?Et=9$N7bdpzOXPKo+Qf@d-Y@CI9{
z{O5nI7GO5U6a!hzf8wA2_k3${#8Cf_LEwD+y?@W^7Xk_64$H3P&bZMRiFY`NZQTgi
z=`2_0Zr3Uxp8;7O=AUKGP}@?$FS}a#zwxzaFt}%Mrl<IZugmryT+P;}u`6I*(;_2|
zH_|F&j%Mcm_5SiFlllc<DD=6^=_~!Yxj)jQT_{_%PwU&=t(~Y?R&%l$`udI4qjPEG
zj&(L4`U?33`&_!i*d$<AFs?bgXs0Wh!6{|QhUWR;HeD3NF`9V>&|8VJ`Fy{hS?RF_
z_==nZwo;+Ct$S?HDbvCp8F3$<CyKNFy?gIpZ?5b%X7JCo+RgzQwW{RBzlWo?=>+Ky
z!01)b1i{e?X`#x}+$3U)DhmHqNXoU2?XIu6m2_pcWQ@a`lcH9(mWYH*_v!jac(?@d
z8!zh)tc6X&jr#5?Ezk|pAWi=}$r?f1%`0)9>3)Wi>0s_qYPsBMLPWNwz9B5>SVVXu
z+_Y(69~bE{Ap?}>)PlyLvOFGjRXR&=1Wg(kHswv;W+TuUFr#^_eIAmgGe_rt<rF8u
zhH_OMoA=PD>|8M_v!*%hOxd?@In&VC<ev_TKn(;+abBn&vZ2bZD==~>1rpowTX?up
z5R4>Rgj3D?7ekDR5QfblC~kc-1r@?-biLC$@gOcIc>+2QbL1ym;3L|Qe>MBd9WFhR
z?is0sgAdw3Kc$JjrLGeH>i1E<G(hsQ<v{VmbRv14H$w5U0IQRu78}M1!~JmUC+-+3
zQMeQ%E?bqFP(*3%2zmvZ(LUKArMHnedM`zZdHdUu)o3uz8V8-_&F{3#V1#%M7=!mN
zUzqlP?*S|fqy2oiu2Wo-vtNY_R=1{WmvAC_;W`mKuNxtF*;E<oRaL?dZoez-&28;3
z5IhgW316Cg`IJ=g&RGN)ZeBI!AoT(8d3QbFyh`pFlQovm6`L%2o;}T_=iwG&C}m<|
zIDpU^!&NL5$8#~<UId_TP&ECB^b&yedK7d61_AXR{SDxhz6iRj;Lt=yF2=!!(POb`
zcpeCWRx-#SH@J)f;A4Rz;;gt48^NPEe&F2qn`<|~ctA;v$(!vZ^{iKn$JV1T__c$1
z5z1wduS8*#{_aVZhCy2=ikubdf-#_W%&Li}BRPg>>uAW5Ot#cYKd&*XS0U?C3A)Lc
zHvmg~1+H0ItFcPR(ep!VnXSy~Z|G05_sK40C!)p&xhzvRPd)}BFXCGI%puU*KA?P9
zUY8+~sk8tJhfxx*UXqDI=TYLv=WzFVx@=?4ArvW9{sW%O(O=4x6P*u2Kq69_?|Bq*
z3pB9%!DV}RpP6m_=Lx{75~^S*3N<dyDF6(|C8)`FG}Q5Op_T@SwD(wJoCYcPmgGSV
zmnU+SQrg2~wri%vZZ9vLAZTT9WS51KODT)FLI(*ItLC)q)U>Cr;PH#Md6ae5*nAdx
zoty>`4Z?C$iF8_%iDn;JLFFQ{Y-d+r5m%V7(ph{%u=+l<fVdo4=@D&-$AYlaDuA$h
z(LXg0!KQZr9Ex53<O_-J$|duR`CjfJFIny*Eu+BSrH`>c{3^)e{w_Q_#`m`KZe#<L
zX-S_gNj1dV$LpyfVXfJM{UFx1zl2^95?WuY(uBY$k?7XrT3ZuBxz{$hcsymzil_K5
zs_iE25U(lZ4B{Bk@wAy=nB9~MD*=v;vO#U{S*J{tbIARS*_NVthtf<?uvj{mf@uux
zYjp&9!3wR>rj9wWWpw%3P$Dc8$zp=hl;8}4EXl1t@3+l4oTnuva4~%a%_KPO72#$8
zCxD3CcsB<n1thtQ7U>O;1*z_Fp|bjzKVcR-ZK389&`|~Bw^RgO7o3`LCEyW=Y^k%P
zkxp*ni}|<KGltf-;_x!&HAPa)v)T4JR!g{FlFlQs55BTx#Tk$A!$8t`JZ$wX9ow#H
z_xg*M7w<TZ!5{ZrsPD0SqCVJQ7HMW+6dTq0fX`(a{b~Xy?H5MaCT6Ou40u6&HX~ml
z+x$xitvs4bU0gnXwn6^<AV8~f95uFKL4Ig0|BEAgKzNc}f6O~3Cxy%bA-XXHMF^a=
z6KLg}3_RDTl86~XR<9pGbxX<a4;Jxv(^-yYuVC*;|5b_zM@D9qzh`ny__sPQ#@a0^
zFx#_VN@eoWRm8Gp5jgwWy)%@F!Ay4idV0QCKH_7{&Mxd=eK+b!HK6_kl0(h?`KU~q
zQpaO6^=l9A5x8k@)rgIWnyChPHwk=giYdg~K~4~tg4>U1C!U9nfq4qdNmq#<CjFVd
zF(g==tn)G?u{b0IhrgGKzC;Blmpfr!7Up$b=g)yWYz<vBp_7hKbh5;ull^XB_=k8@
zoU~OZw5hd~Ch*w{3_wGdFe0ncRP>drCf4I=t2&kxODEC$)S^<R!<qxTzEjxLLvbP%
z2ntbrKV__P-0u!yP-m91lVw>)Tzwl$i!<n2TT0fzvLumxvhswe9sH29w<1m)`q1Zt
zUW(P3Uya#pL^G0{U5$Wp`pSK{OxulCrX2MKqWIJ{56mEj1_0`U=DF{E{PrY|FX~s2
z$4!YtRJiAPN%z3%?8ucYe7aC4;FUe%k6MFmny~cl!w%tMH00Ia^Z+aTfhMi4^$Ur~
zv@C#=3QJ~3b*Z|JM?HJG#HL{xhpGSE`@Oo{?IiO(@TWoso^=Zqe1W6hL(qC-;OsWH
z2Z~KhnNLXM84x-R+*o-!d4RA<A;-n`3!<~|!?BtIKY9hFaJ`{pTp)phl3$s990|%t
zYD4P^cR)Aw8BW4Ft?tg=z^=oQmUL#s5zXBT*C_Pt&Xi)^D~CDj+{MV2AOU@^8{u_Q
znsqL3ZO4{!U<nmp6epw@Ul^Hpmp?ggn+GP+haCME8vq83k2NA_KQ$|Y!@JiE9epeN
zJoQ;vy0$_%jl_i{6adpZHpv9lnUMLbl{Z|+hkXFro+H8*ar&l~AHKX}ucG*4Jp9xV
z$v_U_5vbmAO~<s1A07BWqR9WB!3%BGKk?1vGkXiXm2oBf0UeRR1S<Zxsptmc!sw@5
z(?0ug8ITiIQxG4B4|zua_dp-%s(i~?-5Xtd2mM9a2k8B>j}-{)uC=3Q&IAj-9#OG~
z@5RVS0~o3jo5Igc@N5cLDpEdrRy|EDXoenC`0V(x5n%z>{W_jGh3Pm}xIGx^k6`<s
zl1|?cy{Xu9yiLY?yqiMk1$KIU?l$Iq2TKS17(iv7snHeBkv^tSmI&TTQUJRh9e9;a
zG&@;FwQ#||FO>Ucq>hHvRvPXM(24p24C=m;K#fC-mqTGC^I+WfHnmJKTs}0V0lFK@
zeVsx3i#Lj)4HqK$ue)xVtHOGogeicPl%gfst@nCttk-kF7|d-%0Ct6Mhx$pX^WS{d
zS)NAl$4od5AVecRy!c3y#QKLvH<G1HlSN>bO^IyyPui(i>ZVYp<D5c@`>6}0+a7@z
ziQ2xLpIiLcUT@(4mOxS%&e8wf_hDmYOOWkC0~9!8q~C-PQ}g>(#sNWEyW6edFgK{y
z`d#(b{W^IV5R0RUU*ajy!DIk7Adq3xph3IP5wYR3H9WWzvzE2}?;g_ijhFY8(f7OU
z^ZQ`qs)5ZBITH+T@cG#TS&)J5l8iY5VY~b11LS0!XB`1xh090gn|(0Cmt80;H$>_S
z*yhVlRJ5Qu*&Ka!aF_)9Msuj#gY=Ktq4Au6R`zUExLxkGgG0diWQEkkotnv%(lQ`O
zJ+sp@J$;ST!~3~={<D#@%}Vvz%7EIr=DQ}V$auh39I)NJ)2K9wt<~+@;?v;s6`#ki
zHRIpJ8OKU*+nj*lkY1XYWRkM*jqEE3usrSxhe*ytVyyx}7)S}AuZD5UrZjZVZ*Jxv
zn7Fo#!<tx@?H7y0UDxrc7mBb#_9Kc08)0h53N%TcxGH2vj-p_^mK8}%qU35oOh&RX
zO9JwEV0ALYG6hva3~2`F$@(5@?4lpx>%WlsOmym47`_}ADx^7@?S9`6ve6&_v~jVt
zVQZg+Kj``E>|2vI7G9jZwBGoxPReqq0kVt~^Pwf-=#kIN!<aohkY5zij8|{2P|{jT
za;N?l$*y*EU(EF=dO(bsM!XXff(<WO-73dTQeMX{%15@4t%PYSa;d*Xmpv{psZ>Z5
z)_-H~4mzP!-)k4p_TtOxWK?GWU@{dj+j?w=JI@(F*I>LRtvL3%5sz5py9GH0*{rTA
zwf0aLr`?^s$!c{WrZsb}pgzmeqL4h0COMNXCy3UFUQ7Q)8b_k_I8$-)W6Ah##@97d
zP+l)$X8#JEMe=&_w=MJ+6Hs0Da;>E%e&9@x0X9xxd2VvcnnubQZZ}N8Ef*cfuZ_W`
zf@G@$-Nu6U+Wrm&8gcLr4|Frc2u-qlj$?5)vZZVnW5bO>xcc*nZ#Tw3k4q=TpvCn&
z{l?s6R)^3A4+y0=*>s0B5^UxIix8ubyS{g*`)DAFG`Cax^i=}|pk9n>2x-kgYI1(;
z<495gx3paQ=--m-<MKCv>zg<R>Ccae;)1?o2d$D*X%5VIhlaUQj=5}@;VPl!xGE$b
zSvoAoD?~BY7;;0>9H?SUBk1)D9#f1-m~}=>LFaj*l#224d?FuX12Fi}!SZuAQdO`Y
ziZc@x9-0S=dQ}jEMAuo7AsX;vYqp7ef=bv2q^vqHl>-4*y4*|v-Du<akUZ)OJfTL`
zkiR+hUwJ#I)y9@31UK_qmX&5zwUvS2zxdejRNPoH1SogB*)noj<rGuJuMy7hP?H_i
zM(HXPQhv}2m(96W&1!f{n-fEJKI8iSq+NOpu-2U3;`we7H?Bm}SECsm9ekirLiJn~
zTy1>PjwTKDO-DZf=>G8FR9;*81n->L`Xmb}Ear^@MVRl(;3m^vilN#J`s?~6(Dw6Z
zGbX2V;HCwsl&A2#JA-Ft@ev{>k_D1MI-pph=8H#eFUe2b`p9k{F>6v9t94Q(Jyi0$
z&co$NX>!OyePjp*L~2M%M-IwJgla_-A7GBBr;c>&d)SZy_R&ZcvoFga&}+kQy^n}7
z0^qmU3sGovOT_p`HI+9%D^Z+7@Op#A<*l<5K3ZWT-c4gwclH_BjHuaBBbHi~-QJjw
z_tGO`abKj~D4sMGPf?QlKd;JBk~u&im*P;GTLMs$OBztnU}zi>VHh8;%$Ks$ojm&o
z|6vJv55Q%BvUUF)K?8qmkON8uR$NCJ&Szq5;|%Ev2@}It?!vM2g08`JF_}7z3>c;H
zf|zW_Sk`5R(XcoPl2T(HPF`7@3uDc)!@I-PHU$gJ56H3ouSGkUL}!@9LOBLivZgSH
zMEkEf!4|C&nzCJzdm;sD_hQfNF9PgI56P}ix%xgpt<;bb4%cNp?>h115~Wq=I8u--
zRd7|_oCt3LG0WCpoK=%%Q<gXanCV^f;-+BpA3Nb@QhFn<wRmS}T?F||U<`Q0Wk?eK
zk;sd3Y)g0r7p;OgK{=>`kF;!$Jze9LBo=s)JW8tyXeFn^ZV2SgGALXc%*jq=_UF71
zh@d<GX9;r-5(;x<cB0qcP*^cc@{Ahk<2b!qR-a}?b5oI-VhJIf5YxN`o}(F+*(Ctb
z1B82SCvSe7`srx}OH8E^PF%D|oa}zl8dzD`#Sl7b@wzn&>LgtPGzm>}F`9Pbb0g`R
z4LPlbGqNikX=BN1!w}I5u+v;9u&v>+rYjcU^yGI%HNZQQF<iho=AUjdE?N{SRH1>3
ziYAY{S7RbsW~0pBA;D0B8b%;>=<iBg>GA!+1J<5C*R#Vo+<`J!J&Gz;v1w?8DO-Ca
zq*P-AcJ{V9f2u5Mha4NlZgOYq>;?w0A(1i3qqGOI3vD?zn`*O;87mtIFt=~s0?IzX
z!tao9$q}MV>=#jCVQX4}pPYd|nzQSIN+57$%q<o9v!1bjqc=ZgTOkTdH03U~7$aY#
z#61Lkt-<IGpKAlypCCBUZiA(&7j8iBacsoKrzOn<TTFP&NkvEDxbw<mVd0Z;LS^Y0
z&9d|S5`m8Y^URHdwo*~oJmCc)DJ2g;IoH4-{#j*<eh)06sj#QuH%d7Q%jVYVa-0t2
z#%YnlUB{)tvg4b@!EbHV;CLr=sc9Pc0uS>;xP}m=Y-RkSv|W9B*FtYCZl+a1--#I`
zb?rwzPb&u?J%Tm7$Hq?)uY|p6!Z_@9eX8Z%z{pgXNt8*DDq^i%wAuuD>S_(ZLAKon
z2P2O%oe2_0eQ$&1kCmaS^=NdeLa=9=l3Y7E9C=NKGcpV(K3|SZM!^^d%W6j?WyEl6
z?q&(7holVun0m161YsA)I&5m3s9Fai51E0dethtfc4CCxB(zdg{Nx{0X02&cc#V)J
z-bfaqX$uLI@wI_ALTYDYY)?EuRaYP0o$R-Cf@b4hNRZwyW3ji3tI?9<j7%HR3Me!9
zKsk1|gdI&W)ez`hxQoJ<u1ucZ-|JX%3Jrn-@7Twx0Fd>7-81KUdh9HkVV6l9;6Unb
zYIbw-As)pK`W91)oMI(NuVr59r!8+8jVt-J-f7K(L}7s!c??{XL0c`rQDNk$xF3a)
z0UmrrIxgy;KAZh70q)qem+P4q@{^nHZ>Y~-0UOLTN{S`X#8VB59bVmhka;)RbbLP-
zJ1@c|v5S+OT~CmDo8(GPY8hgpA;JuMmRKiFNH|JWH>0gy`FWzZ?8Y{wn7O&8*&S|f
z{(_{UO)M1vTx3~7Mw)p*he@!CH;JdtQB7R@<~Gk)h$ijR$Z4{2URjE~>xz8!A`1#A
z?p9xV^2e7?d}H`h2)?*qCdWs*`rU;(B7*YZJ{73bgF$*qZPFUYU5>f1kXhKrqtNT-
z+!>4X1V>0yb8`Gx3%dwzo_?A&&I{O7yugyP+#D$1r?g|CG3O*e#}tHQ$hfrC`}Iu5
z_@B~|*ZV`~Q)s)3JcjW7Prc$BJhO60uJ0SHhjO}um_+t=9QWPzH<QNV{K;axB7?22
z#nkLd;Q}2GA^lTnW&8Xj#TX*-UPsDm<&-QyGJ4N3*~whb+{S*ZNoAV80Br>g%PJ9^
zT&32}@uFsy);0uS>)@r-(yGI1m166_wK#3#o~kKfCFkr5q6KQ5E-*Yq8?6nzuESjx
zOa15+zOrxm+?kWyNF%Zm`1Q}@TNr!cM{hIKJjPR$kRa43QAB;E4n}V@K3{<Ho>tv_
zGbn<$Zn9M~#BF#Ah+})|86B#K_cq02ppQB9nk0U6GzS6Tg@!GMyG^lBhFh$she#8{
zcA+B`6nXI@y;)Q7=#SR!#2c_!#*MT|qBuim+S~dFvN0qJO&O%M<$71(Ea=)rItj2Q
zWzA;1At~8dQ);*3bHIP@*~>a!zOtWdQ%%tV-}y>8us5lJ-wSbfsSyeya&61)F-#2&
zV6;5H{#XJo8$dixK`q*TX)HmK=${_rX3`P4n_CYGIX{Ux+u+6-uR!P3Gr34^qHL8c
z4&xeP7-ytKGg!c&;aL(Jt!I;eWGi>U?VhJ@Aj1m9s7Pfsa{aNVzyfV|i)*5CN{yNL
zBicPxHWruHR$6^_{O&R!lPR#}E>s9xTFn~s(3B6L+@Yxq<}e`l#lX(=`E#6mpK$is
zw$do^$_I@Iu48<RW;Tgkm9cz70wP1@7DGCn2pT42W})<4IwiNZXPDu`PYU28O$Gm!
zDHxOX4k5()1k0hq7uwpq)T&5crM0@&b#4&T$v&d(77x-0glB}kR1B-Eo1u>8($IT|
zw{8F+l&-n$_makGKP0DD10R@<D;{r-!6qFit%D*SNar*qW^l!zFycjDo~NjVHfQMc
zXo9z{V?C$dEGK;=?kOeM|53dC=#P#<v58K15cjATbdB1KpgOttL~hr`apYZdn@>Y;
zr$)Z?W*%D3D(P0PNOp6v6kW!OWH-nR;!p>;Dtv?LH_|sze`xNyxFCWgl+CFztwe;)
zLc;l&2vU;y*qLD}9wWHkp6Z8h^urZ|G<*3dZG7#Qqf>yu28S2VB^Ib><8g!!Yuj85
zeqd}U)<4+fLVj!i*sfkTkz<S0y1>~rY7Jxv-(1H3F&RBT(4aBs36KJ;J&o@q%hCca
zPGmI2`q#F!?Xm{u5^$>vZhE;p12;u+cJ?fY{|JqPf<GN~kuSb#e_F@x_8*t!1oV9&
zcen|Cda@Zuv%*)$rIi#tN`6@TQvUc3ekC>?K)tMP+HS9pfsqIw9OY%$8tO=;9`g62
z>?pwb=Tv8r{2>gRFR1nnam78@w`&FnN9@^N`gNgb1oy5&9KX32q|mK3O)f5U8hZw~
ztj|I@i9T;G#Ti8!l^XXWjA2mej8RjbhsriK%SNn7E5Vo9YvvTj8zASD_*@>g4Lh5*
z-Rs}_*o1|<!o7qpx{j)>H3{z9mswE67N;?O-9)=5Dj8n=Ys$oHWe-j3K%R;dv<NU7
z!CVv6#5|`@*T{0T4(;ya3BK2W{dY@pJPq`dMEb6|3NhnZYgWq=&VbW>B%g}&b$m((
ziXRBHrTqHt_5-H#$?)|*zQOMw_{+q~_J1pqA#JGy91g_p2kQ4#WZ@JkyRfXRf#0cq
zyR~rM12~@Rc=my?R-K@q-ik4aiYjI2=XH0(qIMlBid0GCBPo<iIJ~%n2EjjrePaO)
z2KRgRZxFCOAu~IwJA9qIo$i$IhS~i%gL_X40uX$V7}Spd&>z6p^PiW8%FO`S+bR}s
z81L-e1AJM<5!GK+f_?vpXbDQxkC_K+l1GQ4oV1%ebZ;7Ox>=B(yb{FKiBj$uh9j@(
z0%=U#ji{mRhXZb@2xiF|skfFt4+0zB9<LV{e0aVu?bV+P28w+d0{}R3E)81v1i1Ix
zyWFS@fBQGUNytDBe2wjy=HXe1ewFOL^8!u(9?76_C%?yd=k&NuGXEjMYqozwui-V7
zf_Yx(fY}{(N(UDoWsT}qg0)TDz6m?_s8LfZG6m2h>BT_uU*>993dX-;wz5>N>G}4u
zmf6C{VPlgeS1%qQ3GF;4!~e{$d7Fh@)fcE#ELKbak25Q3B;*IOz62PF3Zb~LKD1x)
z$O<!fcRR1bed0$W#1+>Zi@V>D-;zGz)1q`E2lKMLM|fk7<JVBRU_a4bvTA0UH;b;-
z&imJV`A19370aq`Ek$C>nQ!(`3C+dg+);m;O=pKIj#k>Vq)vVO=sYz&MsUZw3jRR8
zQm=OaEOm!aB=S*kH0HpLRJ`;!^&0l2w9ec1-A+=*@lxw0wVOs68FKe{$3-mW9v@Ix
zD9dHn9Z6c0L@*Vgx5T%lg^3XtLMKJ^OL3euHob{!21zq)t13B6#>X<ty?*x~l3{j{
zg66dAhgH{z>+&Y?)JK7Zd8+ve4Jrno7wL%rioULmG4-Vt+8UpOENP|PtCSb%8w}UT
zR4fHWqbP`Jng9J>S$1L~{`$vbf{F<_A>*^ekoB%}zL3>Ry%iBZZ|8*$KBKaTB_xPY
zHFT5HjXxXkNw~5W;7Z6PTZwn1ma2l+<;!mw6w}*JI3;HDOO9EXv<EwCofViqRh{Mo
zxO5+6ohtw|!3ttz6lg->H3d2i=gsqd>+ur3qUYNhkJ`()d~wymchnGAXXVKH!djB=
zs~m5O=QUc1d%sLiHrKi;&|0=TVEIXw3Zt%pWG%1+^G{&!L}^0?i_PHI{N6aFiBem`
zVu{^*kk9xiA}o_<yCaR9o$zpf10v1=Z(!_z$n`!KFI1zTg#-kNMFgHe`YH?3mMx=Y
zcHeo$K_HV~jlsC=x*cO2cM-d<?c)T$EHZ49iY#c-tc;e;b;HKAW<~9#6Rhh0icpCN
z2>8Rd|Mo&;CMlsECo|3s{~32!olLMJQf8JXvW0<8G#fx#G4WxA6>3yPh6ud_Y#|G0
zf_NUQX0>q5HHS^}7<!>9Zg$G^I*Q-;HnG?lqevK@aE63`Ddjqb>*#E8al(hZUjbXH
z7b^FP-&|kSW63i-LZPUHjtQ2a`IGRouzi?!BU3<V&QRI!rq@sT3kQvS!h-NK3?gjp
zHGMk9key$OQ7>Ly=AEY4ThZAAjLr3H1RThWG%Q)!uuD#0_s61Dy^gW<U^QJiZdi7)
zF?3qg+~BJO9O{ZL<I^ggT!g3?pHbHXZu}A}IF#umuA43EN@07~>G={?JsFQTdCub1
zWzfnj&d)Cd9X4gEkIU_IMqN{r=_X{i!grU%ZI}L1E0I=~#jiEP19Kt*7C6|@5pfIR
z_kH6OT+0Mpm3w9WT#3I8NrlSN!fAjZHd_BvhtN#vTnif|Mf;&@NCYPQVLnmC9^<89
zBnyj~>PbdZ(2RghLS)u}0i9U<p5sOHq2)yf9Zu#ARu;b0pN0*0l!+^Km8pP<pq53`
zml)*9S}B3BA+w0N&R3KH_$W{!*?~PP4_*04-5L4Orok4I!nF4Rt!tLh{|d?n-PvJK
z1_J451FAYG=}2H4$<f`;3Va@UI647*Lyu4}ifY*Z6qhg4yrumTOy*tfD{Nd{tMpPl
z3jh@^INcN<kFSPH*2vtrTWNmG#qB3)viziohB*91q@P1PfKa;+2sgmP-}(8}+7-jw
z`FecV`FXsFF*8*h#fYr8Sx(D9^_ETQ0XU7s*71vM@{5QM$Ns9Cj`dWv$mh@!n`%ow
zWp|0UMPhsm@0}zWWZszV#Nh<(3Y3+!Vr>~D$B2Ire>^UFt=omIZOrl~cWucluU}D?
z$k$~N#m%;eoT$wKyr*y~COX+ww@*MHO9+yAh6fW4|Ayp97G(Jx*cy8~s7RR{?*z)a
z-5MuIcXR-%N31J!o7cp{XKzSCW9*RU8J76%l*z$EpHNG(-t>j7ipuG?NK)2;k}9YV
z?EDnnPQ*mq0x#GHhau2)Vwlwxpj@kWs_i=v4nx#VgBy7Oz#(JT7<!xV-D!Hdu;1#K
zRM+!g^pd?jdVO>JzKveP?!~}5uEDi<x@z-k5HIPT(+%>d?^Epf$!-W5YdwxvckYQ3
z8g-iX7x&#=M$J(ik`mInk+T|KSw^IO9&T0saT#6VWrKO8AH8_~!%rf}m@Px&;BIRW
zM3nsGO6D;E2&>4ok0~yh^uCuI4+F<&2hmPK(-IaGFG}tvi&-Prgdm!4tuZpnrE&z;
zV$a-PvpsD#Kmi_4^UKf<=JwxEgFx<!C^8b$`Jy_5YMil-Z*@&d!`!C=JLzCd-Z&#N
zn-*G^fPj;V;yxUC0JM1ol8T?f-pp<plTh`!0pVu?xO}~T;FGa-CEY-p_U0M9Q?2?x
zq6>1#%$^k8XV81r5cB>4=_KoTU%fIQ{dSlqIwBoeo&hz>JAxhHXKba+1QN9?W*(+C
zM}}WM7>=@4JolxHM7P>$nZap&h&^jsg5d<nto2gzR&$F%KOM0VInUp|h~!3dD|$7W
z5MX}+N^Mv5K~fN&q~<a7xN8zg+#xNZ@i|O|&7~VzrJCaX#O!(kP%=pLIPWS)GYte|
zP4;A_pudSy^4gI_Dhrc<!)%WN#E`=3lx@+E(w5d(ROjWFn@H|1rGqKCQ>Xd^GK_;5
z2Dr&DqlP@HM;=bxDj(|0g6BA|`&P9O3qAV*1vqcsJ$(MmmhYTR)Zaa-beu>~fl&;{
z58%7vI6HdVUGH(U+oKYb!H`X!1Qdijn_aaa0JwK+pdXq?4a2`x=UVfUV$q^#qp}>H
zzk5osDy2mtT#Bo|W3%}{LW<WdXOteZJ$}E5F9+zNT+JUzvD}BdDNi$QD^x`z-$M-p
zQYKfCeQ;SHxQ=^C5ZcV-`iFdfX_hx{F@mZV{ccLmqqa#|rn{(AieUu9BIY<LC?@E}
zGlmL|dQM;LqyIkFkO3~7&0(Zaq>!6irR|sP+GlHbl;3xvl%d8l*Y1`<n+Z1wgJF&i
zU~UWG{@M)SuFWJhKEF4(%wt>8@VdhRq?9y?mfj{u(3OJL;2YwVC+Z`+jXO0d=~2?b
z(=U$yM&2ShXc3vVduYNFRGOV@vimxw!#O`9wIM2U-lS!5;v_MtD%;;HU3^?sEO*2u
z74d50tW5D7nNHLV$QpB61X<$#8J=c_Q%f<YVjGhqX|E7k-V70}+VuB5EQ{6#R5kp=
z&CFsR@(Wx%MPAAlJJ+jdkkpV~weQk2*{8<jet)Ge6HHO3=PwLRCl$Z`dt{aFE6dF#
zV>9A&pWX${Iu9b78#;0hfalv_;I>|rOHwiFs~31~g2KDd3m4YoYM9!_9Uj6O>v{Cf
zJlS-YF$RMvNU`t>ZQZ}M20;N9Yh0<zmDLNWjsSMY9Oge&<XaT1ubmY)q~q^4VbAD}
z*trF$28aIRx)W7Ss(|>n=SNSJ9;AgU)U327;*Q45coe!CL|P-QRPZ|5^&TeeLJFhM
zuL^=w0T0jUIKhdd_wiSirPjd(0`VxKm#U|KWj`o*!P&@8Yq_8m4@Ce@@og4Zi&g11
zml28@=5&w&R`-<5Cqh5H@}Ik)x|cz02v0K(v7J^o*0<iJZOn#EE~B&UqLb5(q!j3{
zshP5*Bi<;j0lKV)dTu5&6BC%a`Z`v4o0<`qIWO`~l`e4#*CZ{Sso`@G1{qzhvTT81
zT59P=OXi7I2k0Jaq6t8~KaYas+yqVFxlzk-#sOr-^50J0KwrUkuXv8cjQw%wVJ9=6
zH_^D#TX{RAMZL}=0yk3&7K_c5(METkZ~xB-9<8fdOs6;b(>qilG?nx;o)ELRBd8Ag
zQAg;4%ZJV|VP2Agb&r4u85BnN>)E;007+5S;BT3|&$}>f$r?b5*qSAGqo(1eC2!>>
z_1LuT7xcAd7A}v8o8|T?9TTz0fkz&FtmH#w=g8hyp|x-Pz@rxL!lV|jQ|^+LvreLZ
zSq*k5-O=<}(M1#+Oz?`|M+f{NZo$dY)R%G6)Q#U5Hth+CcRZlpUasQhtjn)DJBMZi
z%`5A&9>Xi5EejAhZTES<kgg&n`yzW~!=|>AnRnK@iqwL#qO4Y}tOh4j#%mx$xkGU^
z4#|Dx@Kz82e^2EdOZ*xu#T>1NS^nsv-<N9IaaGN_q+PYB-C$xuB=_u@X?U}Inj}Ge
z|C?&Oa=hFL-*eQB;m#RR`2EvU+7|@aWuf-rT*j@ImK-3%FQ}=9fttYD)OrGwU>vN+
zG=KFTxOA22=xm!*!n1gl{>$WwL2auO7uD^ao6FsT&R1`qcXB@*&dT8Si)w$sdB3q)
zyLQPyZ(mtT@6qj|JNn9N+NZ$vJ<*RQuNf_Q?Pv1OPCHvs@U`b(-FxE}l9j|zOf)Gr
z{kCi#kO{yOj_(@?!frnzP_{=tQ0J{~ud**4bF&f;-3$hh?)$vV>4)#wU;h5SyFY=G
z&H4^(?$|jWPJhmD`&B&-^<o;=<zyk=%ZXWG^<p|XO%I~9z$+lGfx;}jSr%7_j73ld
zfh*-B+(ccNDB{H|9Nqfo___kZ6?)9>!97i_^}3-{KhD*DKwK9jA^$~EP5=iB>;K=O
z(u=`qfd$-@td8)YaAAI>%uet$ngc%;F&O58&2wK?`Pcw;IK-oUy(bAP<};_KZ8_nP
z`ypyCSIo(yh<ppjE#mpIhYsNUAcK>`PX~{M3>?{5zcPM*Io-XDq=d|L$AUA+8Nlt|
z-k%W^W;Ozz!1GGP_l_#;u1_@Dz_IsBmhWZ;drDqU{zcLf)ja&fshqo;rGKF`Z98ly
zGQ=%16hQa=fyAe0fbElV=22*J{F<!ry109iDcZk{w;omWzfda0j3M*asHA6=RS&P*
z=PhL*M=#mq$39j0_V~7EK%#A|!amh`Hlzg{a5X>@__xLmP7hyqa}oXMznOG;KeG`f
zBmp7e&VP{7AU_KNDMGMgtgSI{R%O4_h2O(Hw%cKL>rKL=>C`q~zEOlhS5+(mSVQ)j
z<P(Lf;Z0#8o&EV==4_>G<+xat_!k#2`A#I1>&*3)_o2#f2?nJtUjn6U7*8JdQ1Suk
z>DNm%8p<hED@Cjc8DDvM1`1!?qjY0b5nqCgQI;ixJd*c_G6XFsMM})Ro<uhl?^bH>
z@%@t8_{EJw^y_!V`+*d6Vl&$0P`}EO=a~57?@qAV3n{Z7Qa(ln4MeDp>j`0@Y1h<A
zvFgaeEvgc+s)!zis!<ch({jmTmizz+As{jjY+$nNc5Prue%rN4Lh&kib7~%taRf4U
z*u+uj<?V<-4Brr|-V61+d^4AjZ5#tw!um2u4+$z{5;A96Q)KJL$vr@8IfuqkfNspJ
zK)AngOmpoz$CJVJHp*vKCf5opY9tUm%Os(4Y>kLwvuAp)LsYTj{Z!+~jm&`8<Ysil
zk7>DA4N-}Tcr#Z*n-YZxQB2K?ahEx|l}X5}sMnAygdUyp$@vUJymeT@P!I`<BeqKU
zGWjZm4_ghqM|=(4dYFVHe#m%+N>;_9rxgMt(K3st7IOyK=sruS+?6d3n6TDqyuU3p
zH%@=dWE|08nh=?i(6#ZoE3*OjNNy<CgN1Vf*H(0>r{ORzIAzp$qfMw!OjiQQ!(`fQ
zNn(pk?sU!;VuOP(XiO45C>xZ<B?(o}RWsI=9p2R<5%I<3hb;PTRu92Ee~+UeCXaPq
z{5o@v>@2peIz;duP@^;WurrHwI<K^N(Y?a;y*#$0fV}2@*df_OSlR$!V+rCZ(XrjA
zeO!#2g!4H#`7xIWXL_@Q^EJsC1};fRTdS{HZW;S`)Tuze37yO9kp>UL1-34(o!)>6
zt(Uyb-XO)k>sEQHR#=Pu1=z14MCUWE+Jg7O6)g7*YvlJRZHhvA`@G#TS~`?y2`%hS
zz1NitttE3V%_ilW)CB;^SM~zv*GeW?)m5*BV0o5T<MO$xvishRy-&jSGs5K;%eYiv
zD>4{2^YYmiIr(`4@{>Xq#k_L$JYq~Bx$WEL{U(#>l=+7QXZjv?H-nyNI}O9&b7$S;
zvpP}WSPNbnh9~4IR?(ixhF<nXbSZ3~;CjkQ_+me7>kwYy)h=MjzS1kdpjiF!fcJNI
z7?%Q%fA}#3Cq~4Omj!tFV=}R_<|bdDT`uAj&G?wY=7W&IalwXzc@7O4RxK=venLn9
z*4oE@be^AxZ4`N<dZ00)hjgnaeBri;>+s9`-xDjmU)-b?X-KT%#N*{zn%CwL8ku7k
zG`9Ik+(CgUo+tnc`n)YWRY5{hHv)N6rUBKF&W~_!!!5q)k4S$X@kHN<EHv$?{p6kV
z*=zc~lEh}!%uh2th^hYb{`N6pHa0Vm=$%ai^r7}q3Cu9uZ^R=<HUcB^1KelCcu$Pw
zffE?S$Jc?-z;tb95TZL;*F8!g2C>F+54e73Tm@+|IUhji*-c1`Mnz4Z4t|lk6V=&M
z>z+xdO9Fkdsg~-lN;r>u5)+#i<?=2nCCeAq6%cq;fZC~A=F+by7WXQj4MZy1IlFhm
zCj`pDbwb5QeyM0qQW$}7ZuVJFuxYE1qj_Xpn+j5JL&xh#O|ZR3<sDCmU!GurOTd9k
z2*~W@K)rx+kll@6%nEUAz=YGUf)6*Z_(vO_@{_~Q7obBN($%|bR21dZ{Bzg-hN~bV
zPdM_*+cKQ8dp-h)f(%Q;_Y5G82+kM}n@^b`aL3vaz?RYeP{4w=91TXISR906=5Vvz
z%Jib*xr1@P{gH_a$K-;=K@KhnWoj?Pg_yCNDXRcm0`OWEcs>k557)p=LT;@1`kVh;
z=%52O*_i0ud&8uDBV>zVdz=Qp%_+w<qh^uLcKnj_A=i|r$6D{+fN1Of<eL;Ju^=co
z<pEG-USeHH2bwR;HxJ!)!R@LWXx*)hwQfP5=%uPIZ{UB!Q{1^1T!Ryi>4At!VfHP&
z?L-3(+WpL#HY8fXgxSd8b{d4&Fyo1MECi$qKg)*Uq$(@Gaw`nlPYAsRpn1nFLYF6=
z&)W~HGJ_x%4TdmtP%?Cvy->%BV%@3*5p<V5<n=p2p{)qYW#%IL3EMmA)XWxCvyM^?
zp*)%~gL^ZLw@&TA;rlna3-fpHj4<nW;C};t4`T!&q#`Cn`HoSlTrAbj%v8Gek{gET
zujWm|Bd|QNoM*I<SIR=W-v51LlK2u<QReg5E9a||jqDAZ_ia+1WwW3hm^PC5u4z-8
zr>Pe<i=S<N6zf3XJ#+I_&!Hy0v15H*bsNq-r~f?TJzW2Tg!9EN1Lv_lhA&jS7!wG9
zGa<I}lBcBlYh7u#n>%|*XQXAn?>1~hae=s<B$*KD#_vN74Vp+dNowz%Ku4V7?aEX_
zT6ASO`_0dtNbL68w|nxR4Wis@{3QvaCn(wYQ^%^1c3P%lfV|q`NeIeUoDhaGGX!N?
z2r4G2U$%HJg^^`t5n|KUG_n_*p5X^TgAA>fp8BJbp8B>*#u^aM*fg}2XJvuf%`*9%
zb~e?(GO>Ki8L&}p$r-Q{pI^jnOX5R&XOIF_?Pfi4lS6dH`<<*sg<n);ue9Ah?jh5a
z!MrdYT7jCHJY=@VoZNsH8@1QxKXShB9B>*OH#Do!mZR<xR5BTkzpQ&$QosWU43uuv
zRpO}8!!)__&YQ6Hm^vf4E0?P4udgqewUUg)me*hpsA@ZaQP#mr7x*1#3Q92p>!Z8w
zib`f0K+T;PGXTv|dPMD=r1hsVdHhJTygjF|NqOrpg_O*t>f7N<?y&%J<^tvj-AcZ3
zl#|_h9V5n@NNI=sBnr$_+2JEVT^vR;1IRt&h5AvlRfH)NrO_~GJPl0R60OcwFTf8-
z?d1U8ZSHr>4P8O6AAJG?iuS8FiWb5H33E_r&b91ZZH(Q12)FOgSBy|R;$dKJ>ac^b
zk_@9f`~Hxc5K-NPb?E38fj%Mw$D)#I*nLD$Y0x%Bu@zN6n2C6}!#XaYGmy>QpS^|I
zBM>vI(cMyM9kz|S#B!skZ%Do^Hz~0q$6>pnG9qHu=A3JttP0mWqtRAvBQmEl7p1qj
z`D`qie@T9$p9I#Wwe$OWD%>{IL$7bK+kedlY=OpNPWjDPf)-7qAmC6&YmYr%J=34;
z>7V6tq$2@l<Yp&ZuM-<UpFeb{tnwr>rF~qi%(<pIbc<mJ?b$Apg~iSxD68o<lw+*o
z+064fQ~ki48?@@j_Si;C_e-;=vl^}b`EGJFqF|_vq!DrCX1j`}K=s*DhhO05WvAvk
z_-=j79Kcf7BhuZ-^?i1IICwWvv#a%eJ5qBaJB;^(hwt(E6X6D!b>#r@?8XZU7~sCM
zuf?j{C4vrIjXBBDEx9{6h{$tK9LH?VKeBjW|MnGTdGB)d=Te8j#C-uw<qyCT{JY}$
z@4_h)7K>#IgXcuEbvM2Sb2@m|Wct)73U!a?{#_2~+nWc{XJ>srVuJG8&T|UNZyB@-
z)7n+)WR*$R`uQ6GO=Xrp>PlW|0w^AJgoO!rJ;pT{x0$8&6d3K-c=`z5LM5A<b@PSN
zwP?6PUoAaxs@CP@s@-m-83BrEV-_S2)qpjfniE`Zv+xd+F7OSA3#F;|`AjcWynk73
zXIv`CFHRUq<5RM5*BRbGxEOPqG+QpQkr?6)OQ!lR5<x`3)z-x|o6bL&))z~s%Z|<l
z2HH<dBC~3;a~swxnvtdAVfW<zrCZ=>(?oaXhS#X=C1EHh`71@swZUr2$6?_&i&6D(
zFquGW)|+7(4dS9{R!H~xJL*&6QIMUfpO831;|M^L%KKcMC!%Hv$NSD9P!Y9XE>xM#
zkh@0kOfC>0-nUqn-j3_5AQ*El-)cNQ=JINVNXnkCu}Y=ZJvC(#UYMGU8Y^W~oygm%
zHa!Jb%|^(QFu)FX&Ug+6`>Gw;e>@r0>9{g@^3Wl&!CcJXh{sGbX+H{EBuOV+mFlg=
zq*-1v>AR)4^p8v-beV}NboZ-$wDB^&kCg5)ecJ+fI^3MI1TcKCfLKzHHZ_|n>U5Z<
z<(N+0Lx>1Ue4}eO;9TfQTJ*{2G*sy=scZF|Yc{1gg%V4x*8(3ln%Wfm_)InXdG8k3
zUTs;HY}XN4i9id|K}FP0_^lk_x{HR?R2O}?Orc%bC{@%>fa~NRI6gmjchze*j&;z^
zbRPkV+c;Ovcm1r~jNI`(w7YmMGA<IXeLs*w^FEcfNH1&g98G8mZp2s!pDdrtePPed
z#JnYZZE&*KM9^<oS6XiyTEDx87nWGMW{$%Um~TMd+doY=Eof&-ps-7gCz2m0z&LQU
zr9*UOx=Nl}G(u@nqc~iXPi{hG%QTw|jF|xbXORb+hnmV-lDkxTSzHrm$#yid*;fHs
z_79$Vl5%)0a81)=uXJ}Sx=`4p$H{rQzsE9wrS-%pxzn2aBQIv^`@?G_9(0GkM2fcC
zZFs%VUw6?MxZ%8+KQ3$jrk~tMIsU!9Hw{dY0qfbU+D+-4#@;5|=r{XPP@r?=JzEAa
zE3YqQ!N0)0wnYn;Dc3zH!_B_f)R}Gnxla)D%95*BWce20P8$5jYqZunW!TBdaJdeb
z6Oo$UTK*gVSp<e==$U#{PY7g&eU0zBd?@&zs={T!(&B!(-4+^u9^X45%<?wO1v958
zQYfdY60wYX%x58gI{a!f5TZTlyoLm1GqVu7L>xe~e5(Xiq`)r@tESX~dRswW?bi#0
zQPJ)z`S3tdyHsPt%oJJjYJOAz3kh+#tx%=YR=PkdSB<2cg^-$YwK6olDCNBkDorem
z^u$^Oqz4}I{nAWV1rR&EWJTo|yEvfr;mXPu>w!Og%6~zKl24&1zx>l74J#0QX@IM)
zW}j$Tji)owN-dRZ>I5%O`iegd-F(9{d@{}a3+X5cz!PKumj4gxQ#cdRhs}4{HKzqm
z=4p0{qxx{a_W#|*Tgx~Yh;-#jVfT}J`--iksuz!o_guEZ2oQ}S;SGQCEwk&{K9m{c
z^LRKv-f9ngYW_m9`{eQc?)vz?DA{=7E6qTepi=etcx;s@`sZ(vNhhtoJ$sP*0}wR-
zIbVLYk^WqL^%#_M@1jn)mV7AJ`Hs$+sd1}PNk^`+_Tx|;j*0oPyZd0;F0e|<9%-r!
zZKxbBLF*A&hZF;EwZn}<yAh-iv#Mnwz0Tsj%U;z5d_Tr)?C>Tz{dj6UVqIPVS~{Mk
zW-n|QD%!prnGAFa8|~k6Hu&uL0K6<{cbLgb90_x67^HS?l<3$bc}jf(Tqq<6MRyS|
zVS)6@du>zUuMmDd7Y42H5pbSto1%pnA?BOK9U_63@NOvvVF7Dzr_(UFW=sf_z8YPl
z+^#E*kg`K|b)(^E(BR^ybHArs)`vXwrc<V4H3*Q|;Oh(#(+O#S-n3Lj0L5dM=`(g=
zK`;hGGRHt#n!}BEVJKIVFe!qoSlk2Z8%o;r2BXrNuJ5s{B+uqEBB@jt?7Zbrs#_Z5
zi^MnLyD^~*9qx!kJU)Z<*ho-j?RNb16(q!|D(Ap`_R}}~^nNEA{(F?FzH}aO`k3|3
zKhVflIs}rds4X8@Pc5|RfDc9m-0FZ<=IFle{;s^hbde1~nRz7*u{KF3Oz<Ep!E<Kx
zd2bi0Li&?OP?N(O!s*%trOh}ClqSo41e0{9J-W2@m}8nPI7NG2dTBWLC5T-QV()Zx
zbyN#+H%8s@BvEOk->?Oi`FsPR?u8nJQ=SoS+i5B#KUeN4!d4v&fSFzv`ef8o*^vU=
z%CpX472+{fMOYZ58~6M$8Rj*l5cJX8%wq;WQ-X-!JgBuNHH@*H)({K9_JlbktB2*f
zsbVOn(}a42;NvPx*8SXNacKD?c-%L2Ayzp0@PwPEl5!TRUv-fR7Ne+^tw0>c6-?QF
zZi8=Pi8F8ld++Ce0YoGtzma8CkLTL+9Ea5p-nU!4cE?~mr_!f~zO?5R&^&(mXts%>
z_gJcyJ#4k=$v@f7Uk%A3lvG6?Xva;9X5Zt+U%C|s&Ev$0R-T?&=?qiv+RCX$+h1FN
zp5`!a=b^-*fNHjwzb4%(tL|RQ;z`M)YTK5UxoI94%hgMh04iwm>Fq|_2y@ae7&!Jj
z8=8>xtf(D~kJCUWyux!2K_%S<aUu><7vz4(>4Mm;12JtyR<W=nTE@=_CQP*TpDA(<
za5VSfaYlFoYd35_yaH>PYzNmSg(TU9Wj?;(=WAd6skd)@-<hIktpmfqLxJC3ul4RG
z*@M9;=|ru40r;U)L8vWt*08t(1acprCbeO@-iIkVuf;R0dnHQ>AQ<b1Cw*jRwJf5O
z=Zo^}If!Q-i}Hi`iJ3=}Du!T49;r>l7HM0hs`_>)I%>jZm9lQJFhR*e#3Iw8xzkIC
zFVi=j+Qn0*Bvs%Co-b@GE!!_6k0tM{F%<Nk)pi5ofSqHW@a`vrRwGf%W~$Pr9nN^K
z7sdrc6P0-v>>aDpzAxDTIeGzI-?~k`Sga2fvGo;#%HoG52Bg_>r>(+p6GxQ+QfcEG
zN&A_|W5xI)^<Owi)`2c?Uqh8s$}t|BcE*Ig=&ZmZD%foG2<K2oK+~8<w<x$r_9pf8
z<1@6AfZh?FCf51sN*Q0p$|z?hD<w7e6Du^y{>ikYzdE6G0Zp4G)WkaKB<D*t^^Db2
z(N^ac`WBIzpdzbEQU!diac6AzGwRs(f3x%!+pkR;F$lz`zy89`F7YT3&&Zsob%Pyn
zFSM|%Qz&{RZ%9}HJ;tpYhv4Cm)jLZN&CSm#0^~4RV1JW;tpv6-rX53-fmR3O#^Iwb
zmsaq&hX<=tpDsr^1ZMrNj4G=wU00Qkt&8nSpt4w@U>&^r!L{#*qVj74@rTeQaIa+o
z^JmQKkO*AG1SRuixYz#?HdR@$!!8L}%!C`-JkM&gF$W_}Ry1s-CPlOIPMI)|PVxvY
z0<3^<?u_rnf<tSqrmNMDIuFtfzc8jViRe+*d9iZHR=P!(Rm)lgmm(#KcB)8BRsNc_
z7}cV11KRT=O+=1Zk)tO)|D6#b-~JNn(LK;~2flBYlo&IKLf78E_}cD1(&NCoDz5v>
zucE=4e%ipfp9`G)NCSIRht(_R(9?j#0e~&YanA>yriPJazix<aJT87WuOhHBM#uaL
zu`p?;21VkP&IIavv@PGQc&F_NR&EYIOJZ5!Hi~yFSI?f>2Lw^l(7g*2u|qu-pY_GJ
z&GSZW@&ao$g=kt+Pf{n%Qn_%E<;iw%ZIcNYR`?H9=hz-bpsnr3HX7Tu(b%?a+nFSd
zlg4(##<m*Uwrx8(-RFHjoc#;t)66w%t>?M#$_B)ab&s%z1PZ(mZP#L?LtJVgg><dF
zq*j|UOvmPJWZnFEuNgHU@JaP5==rbeN80sSl3~&Sa~00t;L<<y>0P1BupdHpV{~OD
zHuJU<h%jiULMSv9)$TVd(VV5#L_JJT!hx@R0=q|0vDs%<^nHIF<`ayY=*~_~j=Zv=
z7q_(@jc-^G^j*3HCA@hwAo0e4fz(xy3v1hY>+O|m&=qWlQKlL)rsnHCc{sMmS7kM%
z8f|vJKsHCg738q$@z3v9&Dvw*gkkZXMYle4OU%nlEQm@0aJAVlT}$p;X1?%>Upg!7
z7j%6Xy4fr2S$zfnI#N^(e&yUjcp~i-459oC+T`mt#vYCaV-GO=wf#Fln*qI-8WXFa
zOWv5LY)WTjGWUzvV{t3wg0}-DyFKQ^<KiP8EfKYze%@U~xC0^$+gTWEXd?6rlL^=L
z&+6MBORps5_OIR%W7ro3-hN<xi0#9I2Bg_b&JB+h#us*p@r_Wel;Z^)=?Y^u6U%ye
z9Nq~-kJ*l9<aH25kQekoJ-g>Y+JiGY=TJML^W(sGKeDk`Iq{Tj;;Xca#glJYmF8}>
z31a(vLzWJ@TU7(QQj0E%Y$3)R$$2&;(t93_YsBW<7H0!T;!RyQrPpIH>ZMfi8z$5z
ztjea5sO@y$E~7$zmERi%%xPK=Nu6*4Hnv~vUM;>&NKPLoC}TVT`WzVWD^{A1V;$|C
zC9zzntm05#dkWs80IloSDFHp7J)<5PoB=s3|8=~?V7r7hVbFfIq1<MI)Jljv!;)9!
zuy~o=Z@ntZ2fe1Ef?X%$%$SA>-Ui;vb%m*UQ#G%zl(CKB^tn`a4A3PpTrCB!RC7I~
z8Fqs<DeN^p8mnEP|CbEKtg52tkXmN?>eH7$gt@r3)~Z7=ijT2ny7DFt<TB;tkX2u0
zXcupj^-}XXm+tpOy;;0qMjFNMy66J+&#R6vZsnH=mv*Tm{MP43WPFp`{PIk>OW`}*
zR@^PpD;c^z@a{=6f!HP4uMKP1fy)_uO@X`#)%x2K8%&wN0*kauO0zd+MNy3P5EMit
z{6!V69Nd}=?O4pwu;enD)d0J=H{D7-dkvx})*Ct@^w>+DFxvB7FVqXo33%2JtDEsK
zhT{{g20T&VLzp|u{G`Tsr>M(O8le`8c}2B!Rf3ED)(~gSzwdgb>%bcV?^SknzXj##
zxH+K`;nEfGhoX~^N&ruWKNZ8d-*sXkxi;E=u708&1+n8ffzTuM6`!*BCOnb7K=bzl
z?;nMHvE4`4O7e=L4=4kP7Ie(T{7E{x4$F*-ZOcZfhrh)fA&e$(_qtxp+st+KKUefJ
z<#bpG!xZ=O7Xy$tJF<%5yU1;@QdEmEO;)G_8!4`VD4lX^>T1Uj>Q0NTxXxf66Gkkj
zetlsBBgPqz)V>Zh%9KY+4%FB1Uymj65CWIGAao+2*JvK5c^l2<%{WIBug;m{p9|h~
zJJn0IpEVKf+`KYpn3-MKH!H(OX``LTFO>NMrJj1deNY1<{CBs@7)#13Npbj;^kKgS
zG^C<{aydyIo!>sQyJ*h357<^t?-AdgF1C$(Hy`F#T5-4YQtVG(;P~dy-|Ol8N25FF
zCxm|Zs;bJBr@G!*JfenPWpY4GEL;t{8r7<^)AOMwSPe4Hu2Q-+Z=A4uq!c(9LqQTu
z+OZ4<mHld~unUFGuO*kE#GCraC6e*?lKUkH$U0t|)>X1UK(cYBj$w-PhB>LC5iHRl
z?qs{Z;cM6SM((BN*+pM=CckH!x3T*nyqdVEn%22XciqikLpeO!G^QPUtsrA!pAUGv
z)q0S2FI5|e`yu_>YX!0mSC80FY&#y|zTG{&^zA0KZ)As;B&TD!|Kd`7SVU~pC^_E(
zE<I%CX`Ry8P#Q0L-#&yH%NM3Px2pX!pWaTAXzGGhCa7-~(U~n&9vz;`2hxWt<j=&=
z`^RZ^Gu)=F#J`*is}RRpApO~d7zQ)y(H|Y}lKu$V?cVX5=zpV|%pa^;Z%6{Ck`T5N
zc|%0(R?sWW;7gmrZ6IA}Jt*P+7L-T<d@z%(B&+Ua=S`D(l?u=D3{L8Y+u<6mnj>Pr
z=aU?Hd<FswNqi(NIFyMAV$`p`KU1l0H4T2%u~ZDq?*}WJldLPsHcM~7b$NJ?hMrJg
zP4DOkKZPE3x--DHwHWCp?u^&h(c5k9ceigFXi~@3`4R@j<)|LN6MbKp7+l2wCL8cX
ziiFG0GHLgo#NjO<wEW5_h8E{t+xJ6k-r|;#d=xns7hPFu1R9OTUJ~&;vqp#8Xg>Z#
zIQre5^-j&Zs_oW3>YKGK{4wreU)Z!zLDYpLoT?EAJ5qbq%TSb7FNH(v7hf@3*g#sm
zR(3)#MzDdoUoWDX_<jHD!tVe;&~fEqeG&XT`SQ#(<Vw6*;Q^R9{>%4z@DG&!&-dE-
zMtcjDblCL`0v~=E(igYIJ`^dzdq3)kspRFuC;`RPaZFZCqY;V;CrDbBp=UcPIll9~
z?K&g`@U1nj9ju;Yj5QGM+v+<K+;}qBOcnf+qsywy@#^Xj?926T)Mn7FGzxuk`0_RZ
zWLL{?c63UwXLj!32|YTY8yjz@M@4AA+&d+yn?E66`Fe+b7)%&KPV_YoVA}oOsz3cM
zZdLmrqp+8zLqKXofv{zZ3+K{0Uxn~!?lA~H-aJt-lC@fdvc_}n^zrm2n9|*4arxd>
zG0WTe-lV&39jv8(uy8w;-+=UvdU6B+sQ`mu=PZWjrMg3OBpoL$ntQ8bm-SHm5y=Is
z3T|mEx-*3aVNAG?2FRK^!SW6&Z=>8srA`r=o`+q)6plJpHRkh--DU3v&TGPl(O599
z1Xuv2`$LKtmVUo=k^w_PWyf{DevyBHCyX7=pU#l%jX;#OyK9||xfpOm@;!1Oo6W-=
zBbfQ)9yfR%7d|G+mcDk%v=p58Ar!gqb1hvIS#Z@K<&fab?nm-YYcSZZ5oGE4<33D(
zre__OgIIcoa>_~7A7Ns87x75@V5q5ejb^+EqJ)|Zn%$Cf%OzYM(jpx2$8@A1`tRK|
z1v_{ofM_{vgT#(~vQ!!b2ADE1@I#9qddUX^^pv{l$k8>&&$*W`VgO>sWyc)>2Z_1x
zgc`$*OlUdoP+v@3R#cOwi>8u=t~Gi>x>~*kR6WU1!>&u`b+jPHTx=5!=1=Ebd;`2_
zlc}E{tu?vTCZBN!O1@8PVbe|s#=bbAkGgwt&e6R+=Y_wgYba=lWm*q_SX2?qp<G2>
zF{>oq>8%ul%I@0l&(l$vd00MwU<n~DXJ#K?={$T-_c1J>x{FBegIfYkvZu};zn=f-
z#Gr5wS77tBhA%afMKEszOKxr>HugZ|tlL0FyGlC2FyqyNCTZ~t=jBM8%|+ZTMmXE$
z4-!tL>RIGS1ogUAaD^w3S1gEwCY0-@JJSd6VG-rOiZ;MEhK^C)uF~m-bq(ffK0g@*
z{h<nImkCCAr@<IxEui~oPwU)U+H4w3+pV|2i0q6I!#G}#=bccPb4>i!&UH1e@x1T6
ziBsfj0t3<h8yH}KX`U>FWUlGe=I+E=BPK2vT0W3$`-*N<Se_4XD=<+BU~zo|Ly3aj
z69W0EILXF3z2UvzRTFwSALNSWggxsw>PYxa!E^ho^RL!s6^+PdzGau;@S7Cp&mjZ$
zL92dAutLh_7*Wpz{@!_q{gPtJ<C0>7Cigy>?$Ld?FYzEQR#;;0g*_ym#M?#(t&{!v
zpP`8%pVmh{P&#V>=)Iu9G^^;=?_~={O(V@0wQ1Zi-Yq!(-})gr)2zo48v&xKAQ5Sy
zQu(ln%H1gMyNNjd=g|IU9I%4FW42Q*ORj0}HQEJ{1RuJCx9Ci*<QQjfD-pHCiyxB}
zMKepkjJKfSx|F)7)o&`Y#aEgl>n@N5469V&H^o-@5%wN{H_ufBehM8g*+*4AyQzUW
z)36?$Y|CcG@Dd47slQqe?Hc|M^LGNERcWy9Jbf)Pjv<N*MID+TFDW>^WLU779DAyB
zGB;jwf6b%8Pm@5fF+`I4`{Mo*phun)K;OIZ%sTm|YRJ`FqkeOo{uSw|yOIQ#fh)<H
z&+1TXW_TI~ycPI(hZx_W4%F>Ki)%N+Zk2VCrA<;X`X7YfcH%u!k3O+Ae4zaJ+7wlV
zaxI+%)jK84J0cJ{94p-;exRL>j|}3UkOm>~8R|V3It;LWz*a>f(x)8mLchL~?eq94
zVDlsa>JNYI3S)dgq%#A)Y>?=^r_TWy?IVT<ChM65B*~!-`J4{*GS)GR!5iS2l&QI+
zs+LNe`J$iR7fiAo`w;966KHASW>X$RP-LAq|65Lt&S|)n)sCxPb>ZDy;}{Mxe*;PL
zYG^JWL;S@Eq6*2%*u`~Aak(Gk*G1z)t9u3}R<9L?&;{$kN03h!2>uGhS%>QDIGd{6
zfzEdV!wUKSArrK6mOjYK%i^>t$zgOPIor)rm|BK3)FD25owVqIxG<*Lgo(GNrt5k$
znmXnpk)ya_x{lUjlhQ(HMxchUq#)O&3X_JY^e`@gF(C#?W8XB<<Jc0Fy&&WY(4QCk
zpDeuGGWMFh_#$$Kqs_?kMQ_D;G#7fq8qg#Fdq~I+iTo2uKGh)*wae^>@3MLX-EDhw
zYJ86{Bn*Fq=U~RLG|QpX+^6NKs79}S<^!!=3Ih+syA3%DnbDh^Do&e{-w-&%6lA8u
zSx0nMTasFlg0{xjX^%PQAD28K>LKO^?S*N%TkD2Rcoj<;?f12R9=WL!EX=Wt<c{A0
zrz0UKjJi}2HzCSsm&I_n+}zk{MZD>JIy^e|H^H*40aEC9hv(v|+dM1Wqx0rTo5Spi
zt+H8t1Qz4O9p}QHPM!?hH%vWI{=De!9FqP5XI$oMDr@3%ywwA2BDnHm%rJ4>l8n+O
zAl7yn7=wr$Jz`s%w%~{O-=zYtx#Qgd2`fjkA(NOBq&=WZUscxjmL#|@{e1El1)e==
zvGd<#XPp<6Ds&y?{^mNVsYlS$W60*Vsr!3WnmMC6`N)ZiTYa~F)vdP0r;&Ca-VS#B
z4J^EI&n7DC{R<trx=F2+=0CkS`GLdpOcZZliyiocRMFVxRM-9s1udI0Txlu*3<E@e
zFK&QiMm%p}z+1=Yx5d(_ie8Apjqo>JE~b6CsX%(uEnBE3y4jHKjIm0kn(iK@QS~hu
zx1j3ja+imIk{RM8)v>X%eYnIm<=G$P4<`~6r$12<!Wtw3<=)ndIKON3YYB`P6UoJL
z9OO%>Gt(-_`L<NWnZ!L8e-@kpvxj9a39(T$p^X`lt<z*y7vvlhW$c1n{ob31D;WZO
zrX|u^t7?!2@A*lvDQj7bsvLH|Z(FsC6=<b%QnBDVan5>EKv{cjadj#pLb_T@_x4Yi
z^=4}I*!O;?9?*V&6rHKPJ}YM*x^=ORxudAmLn!Bjk#iZu`*lJa+iGA393S**IKo6>
zh~`Oxq6ad4+wvt47B(lS!UVHL&0HRBGIkn#F8y;W?0uOEQ%8ZC5umO(bf{}(a1jTM
zLgiBSu>8BpA1w&`YMQj!dtntXxjg}f*(9m%yP6~2`Po{F<xdI`w7W%fwcTo+#G+b!
z@;+O+uIAA5esj!1mi~HK;G^rCIa`6+t<E%{9Kcj%yv}<GvoSm0RzpvS71>YCH4WV=
z)>QtES|SO`&LT5T95h8WBYh76EgevZDqfOYM%7v2H#po<5Tu2{7+zPhH*b$^rQaP$
z7F`fhgrB|F`{!pg-{$gR5X;Ofe=T`&Y3|bTo;1>ePifYfJev0%fPIQKTG@xn>69c;
zeKpT)qVkJ3B*Wg#(&AxFT<HXS^<b(6mZ$?m*!_A^^+KizZ^bL*_w1vDE_JGRtou54
z)wq5>*S@T-m5jkRi1Pv(N#u%rpR}vd^3~;Qz6HBoP_~e@(E8pvLqz{<4A<&%VLe+b
z8MogL^6P$zLVEw6AJN&Yb4q_~ls<S4KCKfip@g%#xTq+GskW0l#kmUx$G0n*30`@b
z%on=WzZxT4E+F{Rzqsslr<`w;duT5#;KYeQR$dkJtZ0cY%eDtyhli=ie?N!YA{N1@
zw685^;!_lv`vnDAY9?rSgddrmLkBOA>cK&mBTr4i0rC?WAX+WO5`;)W;=SC!#p_o+
z2-c2_@&RMzZ2@6#htjYIIq8{TsWb4`e3aZhVqX+ItT|-N_yh=+f4d6p98$@uJTuf-
zA+{oktoCidajB~1A$C9Nit$o1^2kMUX;g|Vfa9OIheG08eKe66=ava=Tnr5G7{han
zR@58rC1Vr=)lk``iza;@NhUUsWMc#=IrA#@S^gZYUpY*NFH@?`Vm<qMIN2AkN)_G{
zfu*E9rru;}U;^;qch{9?-$PVwuTEIkQm(U~4Zd>?P01fldA6TkLyhbj&9U8iaG6uK
z+x9W|F8{)CZ^TRtxDjlPi$ho_|93!hC{sR|7B$PkKIf#&opasK6pF<8Vi=1LzEJ>P
z@yDfwQvSDV_~V2UVE*q3;Xjg5vSx(;NJeM4UA5+Q#7+MH(MTtu&$XH|^?6(6(_b1%
zI!U@r!UK1c9W!dswv;L||BnJ0`NI7fIGWC9kLj~%LuO^>Wj7rJpyU6g_3<%Qa`Hy_
z0&eR*-gAFq5_Ir2x&pJ`;rM(HyyR*O27ArfztA4ss*GKkysR|CrFNmGC{K@F-K~j1
z@0_Gknvqtbj%~f&-kDLP&?cYKy308{-!6$tLyT>C_~M?9sSbUab=mKeqcIl6XKY~Y
zMdTh8Ku;0H|GKDoTk975@OwQgsfaKr(c&sE{*r?$*TUtUm>oGumBQf%c*%G7fD%Af
zFgsrkr>TBU+Z!TNi#d(qTYX&s>|t$z);f_tGD=J4_ZT{*+j+Z_1Rh&FL^G1c+WHzB
z=c2?MHS4^s<@{K;Ee6A*kTh2$8S&NS@_1Kca|=zTHn^4*+3!8(!#q2LQVoT;mkGpv
z^FOD|PPFqDZa7(l?Gqz_e~{D(l7^f3%}%IfN5m*`vzg;O?;4@fYN@|;o(%Zm23o#_
z=kCMZ>`V8qruJg`!(c@mrW_j@3GJel&Jpyt!)x5wn4;feq4|iys};!mu(1#8h5f*j
z>rZygOVwsQ|3aqD^robDo{EXWr*J_<ICtW>y!&JcbOD5|O-EzEjTAC<sSwPn4Zim&
zd3Ro;?%#14h^)<@8SexVqBU$Z`NyoQqIJzWG+$J1V85guU1RNnJ+Ar%1l=ca;WNMY
zk01VOL0vx0V^Jthv8VQNM5R)_R<tct))Ce~6HyWgr<WW(SWdd0*FRY|WhE<%J%o)2
zZ3zBR`u3+sz|j~TNZ-dQQ950BX7FM}{zo@)R`x=l?T_P9r;lzSnRBp=JNXI>3)l8a
zHzJ;!Mqoo+8h18Q(rRA(KJ4IxIaE@WuCy90m;M<i1S5e!vsl!JBb|SHJ@PbNuA7wO
zNaN*6NrL~)jugxE@MicL<ZS1xM@VeHL!~0QZ-8y@gxY`!IIXi5YGSkgenO)~Y|_e*
zVFq!<-5Aht+LZ|70JVPV<ZWE%1U|KYjm=K0Mu8ZvNVj0iEwqi4|L$?#yS8fqA|zeY
z!F+xHxt-Vl>Z)k$rz+;lsHPP&YwW3oIk_M6cD=oktt8?&rSxddtZ<=mYxJg%w3C`g
z^nl^RSUQdmWM_Fu!VB)eLnLwpP#}yb%F)Wv!6+=3;2!*)lBMaR{*l~98a|=AvfMYf
zxg3JxfuV@-T6D}}c#@fE5SY3pr_OS`IU0tkRQXrELYoae-!d&CN-XcVEkS(FjLexO
zdpa?GVMaNo5gqKTw|OOBxV+3s@v4X}CQfUjP4`q1*#1ipFY(>Wy9pRv<t`Y*wWuWf
zUFdK!qOxl-O>-;K02^gNHPSQGnGmJqlV|6p4WH4QZ|sc!7lKsApmC#7rmC82%$b(X
z22WNyh!*&+>w#W(R5A*hT)C724x=S-RZdBS3E!{cw`!x>Y~L?iFVWTaC~dfEh*>H)
zT)FK9z;52+;?y5PBd)Q0G%=BIjI7nF6{h(TxLuj0l^ygqa9335N}1{(HDDn?ON&z+
zEy#PytG#m%Z#}c+Rn9S&T4wcl6;AHnx|Emmlpf#k;HFEDSTIG!I~QB@?0DAAPMeZX
zO*&D!CCb@yy17tjam(`u<<P76gVt${<oVkH7UnV|(uoq~6{zvw>d|s!ueDtKi7;B(
z8mB)9N{82_cFYgyE=*~#&&*1sDX~W|HP$?FLyEfJZ3Udu=)<j*d@20j;cn^6w9N_z
z>`m!-6wP(gHqzj@j>{Cm8E=m^eUGQII1lb{yef^17kfEuCY0==TEqv%29g(+=JxXd
zjxcM5=pWkM-^(}QefBbtsvg98TJS$8B7eThIp04-b!3Rad<f^hhNDYxYAD-~p({MF
z%MCAf_Lp${M)8W+sNuD&I|@`TUvQtYCLK^JU(nH(bKq>ip+@{S462ux`WL9Jj>*=~
z3jYyft)%rQR`}c2;Xt;aa9B!r*KqR#aLGE7{~cta^XgW@@xD&Ozpts_QzgCG!r_JH
z>)PDg*GoGVC!@hkmrOO}Ts<f2fQdJs5FXDqqfA#ynk*}kb)t-RH&c2jKTlcq9>_$G
z8krUH$5<D&=sQhHK1V>^?}i$l-x?%$#Z7Su^+p}!GQx^XPDwU}=bG^CL!XkAz=&_;
zeVEVpQm8vACa*zd5=Lw4f3J#wSe2LWinXsyCFHLJJ`=W6@{+e<^nZoW!$>TJb`me>
zH5&YM6`aOQoW>Hi$TNsTf<!v4Zg)n)uzFT!*v^878Z|R-KLM0q4KM6yW-IqqvMX+&
zAzWqEWVuP8M*GI@t<Q9u)}*VefK57gODCw{o4&U;uuf`9#&qeUX}{lZK-WFe(T*u!
z*CQ;Hucq)Qi6zIyKUYAd(#V2L{h<=_1gp&lef8pFs}?RR;;b?H$m(5dFaHNwVU4r|
zG1I7H>z2tQ>&WDW#fj0=O%mkDsL=|`%E#;6Jk|T}-5&{L4?v<zdEeg<fRIkA)R^bK
zR&rlpKZQ}sm$o8?z*iwr5aeB}_Z^qBX5~rvT|Tk?<GXK=IlsWE2Pyd*cB`5n*GSQ9
z4u{QI0Ui_qnl}i^He@$vn2u?*wL9xYExru<?EVLmCwnYj%h_8mW7H)QNnYU)6si4y
z<kmQ*ySp+HKKHkUNwaBw0HGHd*N}ZnoUb`wiz|dEuNfH}kyJ8XRYI@)*Fym-W(3%Y
z9}+?thJUiALj5;V2XA<~oVA$?=6V`1HR6__87gW`d@i4|t%JY4l`%!eG6#y<E8ht&
z7N)Z=$c`+L6naiudO1+{XP|5;75%<Qp%btmIBimIySF}UtnQ~G07+C5ep(w;1jj<f
z;9drVl9Q(mB*A;n;T5KZ+igEgw!}Y%>ZeK-*e{aZaGO-kqc=4S#_jRsXAg(V0Y~PK
z=em<icIH#dN*xit88@DWpI#SJ<GD>$0ma%)T1eh(S%CzV+Q&0YK?MB41bRXW*q2AD
z0oGSSaaBZ;tgu2jz$2056<$WGE1O^t867vch;bls9F(EtRd3u{2yrWvh&_S`r1=XI
zY<9GHx0irH^--eB2{UKhEw+S_MD3%YU)fe*_H!{O&k4fNd4YdjcZ3L(eS&LQ0{hXx
zJ>oi97g#Li!NO&d&eopN7GDm=qVJvW=XOr)xtD-4+A%dXkZaPj_$nXkMWk0;?wanE
zJfu>U(m)Vfh#aiJVJU4hx3|*P9K3${@=a#w%WHX03lDa(+b~ulDt*nu@K~qr2<h^+
zqKE2=P;^kDlVAo?2UL8TH0Z^(lOV68YHp5IA1N(<32Y&TP;ofo*3O&1#!a2qsa?hX
z*U}u=Z-<;I;IeDk#&F0lJ15q;L|(R*aq7+p*FLrm+-G;rs97RiEoKGLWxP*GxoMPn
zO{0~66y9Z`X_S49X35sWWx}0x>D;>6;;ccR&lgxf2&|qw;AXSocx)dYALdNBx7omT
zyg=mV+B_#HM(q$g_FTn|aYM>ga`QclF56qefs>2{ZtPZH<StexqZ5Xc7p=UDNBC*H
zQ?}*pGcrA!iZ5PnKF!xO8Czd!3d<N!$iJ!QjttUFW%AxT+D@kD@MGG=;71jE*adFp
z`StwvIG>u-z~08G{u+2zCYCJFS49}QDTk_zN(2$~^CcoQLIz(Qe_VWc-mFcnTE~Ut
zUd#{#g6lg$7}j;P!qryhCA^-0U%B_+6g&m|i8;=;=R03*{{y^pb(F{S#o|GOyl)p_
zgY0VC(y9zU3QO|HLmBU#QAKEAVC@&A>d{-oKy}9_{89QmSB>NSdSJ&)GUO6xpOPo!
zfwO-2_(r<MNE}StPNS`<l>yMgl~<HnI8l)T7F4O-0T|V1w*}2tBAxW~;*ri~UKlnK
zzwmgnlKSR8dsJMFH+_!Z2afrMv0QWF%Lhr9c2PbiC+h5fe75}b#?b8K&`u~n$&rTi
zFB@0f`)&+#tKF5FpwO~0cJc!W$@%+_eVA_%CCg&uwRru|l?}Tq#Qz8fKM6m1l5j&Y
zfouob?5zXx)aA%r@cb`1ia%Xj@i&@@e!hADGUbZE)7E#BwucoYUxvw8-FLfnxq17U
zN)YE6WSLM8w5Kv#U4M2N!mM<L(99LAC^Tt^DKdX9`3d<SeqRZmWBaxVwq5v1SA&r5
zLGNZKko2Dh2i&rk^`G}8Uts3ghpn(?iD;cDi9*j501GE8`~Pj39q5e3oHwCt9MRr`
zRbI=%VvYCyKqcZOt%s{SUUaiSW9+!S3L`0x6pKu18)EI+1OF+mpyE3pHK3w4e?LY>
ziSo6-zp%f-5@x0i#2^4sxxiHy;F<aPuE8$F%xD}xx8|2HJ2@CEmBBrE{dfW7GX5vM
zmh%77Ypp~7(rZ-pjibvne(%0MotBj*QQ9FjEKT9-OEk~NT!WEz#pM3#o~O+#yUi1J
zYmzPlIqFAlb8{CuKO8tldCuwWo!p?xrH&z7R^uenmMIpOfX;to$QZ8FZmQLyOwC;N
zoLCz-H1C8t^W0RTlMyCB{Pj9@AA2%n(H7*}*TH2`=XoR+#-%vPA(>P?>WkVK@hbW|
znwAQKdYm7_F?-)4poFY%eJxB2s`JdgKr-5d<dP9{p!Vp3gj8km`(up}S#%-@5vm}g
zK3P<|=o#Fo!gqReEmKgOwfjo@ALj4BQ#DfQEFm_0;(|sJ6fs``$QrV#a|<yiQ!6b&
zD5>5Ao<<zpQkeNN{AI&o5?L3z1zjgXGMNqaww=j1#(~p>3GD_A@3N+J#|9%lip?%|
z^{nTD+A&Gc<vu>Lu;Ipa_e#ljUx_c}{R|JJ8|j8I6TOv#9~#PJ5m6^~<AYjkt3zzz
zpFJQ8Ocn`09+@!#swPv$1aT*Q7r58deZMlwVVhTS_S`-i>sZ%tpH3W2c*&`t2eQ&o
zvX@_PQK;VTBb3kF8Mvz(Var}w5+dCfUpm?--+f2>p^QbIat6~E%T-NincdNAn8Fb2
zw=2X-!$K9TfpuS;`oGMy;{tg(s%>_*D(NJ6N>VvbqZ{u)PNaT!O+MkH>sJA+#_#7)
z*B?4D-?mMaS$TiLKlL$;IG>pvRM?$}-KkU2-xVhN3;jz;j>8RG(d*t1VTs!%!0c3M
zq)+Ek<<JWj#D}Zdn(zxQaK+9H8bweo&eS(wtk=2ki5SfE)|m&k7b@kOiRHi_mG1Bm
z_gQMJQi%h=R}#<ODfE$glP29<0Qhu*dSRq@zz0%X-8Rmy$+Lfn%AetzZ?7=CI*pE0
zQ1m9(PhG@Ow-a%d2OA=YySVk^%41xAMX4@xpq+#<cCRmLG(s4K6gC?aLRt5=Ma4*?
zdpji0NVMgh5se?EsHPhdSNlxdcOtX1oimsFDzf|mBHbDH7#06i&ybdTX4eJw)M>Vq
z@s%{c`TTp^iq)V@%S15_rCc86%FDlbxs{(kB=iv}55?v2UXYz2^78>#xT>0bm{nW|
zu7XIB7rE=^Amj!OVYuYEe^%$4vXygq6poa?!e1mG^!*mdIw9QPeBu1{O|Vv#BS@BG
zt+2U3;n09Hf3ZP{_qa(5feYNy-fj!QoePvpL)XxqR>KJKb|`1#Q8|W|BM%2Q`s;>d
zVn`5g-+jX=qUM1*e1AA1m{E>cP3qgfoIsxaKYHSy_#Ypgx05!3y~vOrbOW_|*%cy*
zYp{!n`SC_N@Pm<Dy8a{dzse|&yno8#XN0T)J26O``C3U5I!QHkfpQ-b-}zt{K^qQ^
z1R!XtLY)1WZ~bKX-FKEtEtl|+6D$Q+`^fk2nP=5Rz+{Q(!LgN1>v>WUW?Z6oMe%R>
zXr`XOdf6_!GkoRb@S9@5_%Hc{XOJGtEUKuD)hWb+W``tL_CZ^QR`MPPC4<%<&v46u
zm7D9l)&;}@V4FQJN@5dll+Uq{`?~6smG2BHvOd>z$3GcWfKOVJr%Ur6Qdm@!z)DU6
zErJXqJVxX>$(sv>c`ym&NxL(YCoVilgy)6T{f~BN4TiJ>aqt~=rU>qqrFiCbZ{g0V
zu#WWUKC|I$>(?}BnbU6$`84XEDb@!-M#}Fj%h1k-I0i8F9zFs-A-vZ67Sg21Sv{NU
ze)H}`ckPB%DN_C>uesAQdCJRdnV2xF)u9OnU&G{TyPoG(dn?5C^9r`b;^o^MrG!+G
zmdViw;T!P;g%Cr?Rb&5ecf>(Xrs9A8NEIWf`0mx0<?dG+$Ac}sd-41vts(pXhLJbw
zQhoHy`7<OV>Fl$Yp7--{8%GA<=Tma=N)f#Iesf^WfET3GR8$HPLRJNe7xP(SXQjTJ
z9B$f~^w-QTDtsK$FPMjE_#+?w626%fvjLk9U%+Sv4-W8u`dJf{{m#ej0^V!g=Z}Z|
z7X^$KA0z+#RjOtDt}Wy?cAnlDs2;`lx>Gz&R<}fAXLjW4s*{g7zC|0kJ>M-P37Q<a
z%QkoL)O6aUK`2R)Q^-u5Hc~DB>zJTC2U_WJwM|77g5QUHUW?$EYL!muG_{;{xQuyU
z5ZVJ19MI*I)=r8qi~@J|9-7w-U@Zo;uJ+;kBkqO${2}WQzI&)|H(9m=?7r16T?Q)?
z9~SAvu)Oox^$)0U;be&<ij*!m=d73FO*Brj;tbDV3;-X0tA7Tx>0azw!NrdxFJ+DI
z5UX0<A=2LD^9&yEvN<T3fpL6KAWbX;%$soPXsH7^#Wk+rDQ@U0v<T-dBz|vsbtME_
z%BZ=<nYtjLg8I%>Ttx-})0EnRW#CKZ>fo<Q-ap>0sbMviNLV2bV(-sKX&gP$EIwjR
zar<zJ^X=Vf>ixbsr9uCJHPiHMm9Z{QC?IiC8k4t7)>2J|ci$+uI#?zUK0to283=9_
zW(Pxr{VSxr9$_3?2jO{g!-~pJIpP2@vLbM1QgnHZ7LnhX+yGMu2y6NbWJj47{ynqF
zb8He88=yTYMod7Im8L7=Wm%FHsq*nXHG1?_JNEA1c(dkz;4cRydc{3Pr|A%Zvij-a
zmUsSDfEd~L_Tie>PX2Re6IqN=XsVark+WTR9&ANo^yAi<WDCA9H=!EeX{nV^cT2n}
zkWh-ui<fcJp*E8PD0B3WccN48AwsXLrlRaPEGudYSw{=1#^V)GnrvbHX1Z3A)+`}m
z-)o;URP~2FUB#-a-cY_;%~yihXrIvzMVTD-1})-PouYsL+W<WzD#Tl+04=HNJ+uI(
zmGtn4^-rb}(Iq0S*<S;RmE<ke<EDTL{{)@Yd@k!+C&dR8fY~Ev#R}D|H_BR1*=eJ(
z?j=0R>5qUdT*BK1A+OX%z5OkA3k%EBV;fCA3Q@>d`|upn|MEoZC1Owmi~E{HCPtxl
z>rp_zZAnEupAgoKI*IA;Di!B7IHVVYoC1yXKHOM!H9h-61Rmm6G%N;785QArAEbXT
zv0ymTIGoNDz&bD1+OdJbYqC84;>~~=V~18y*nX<{p~&{AHFBiHM{6@4L({?c&m5C0
zkCJW7-8|zosAi>}k?Ne@+!i+!Ra&ay!>uY4#e1r*NJBn@7nA5|VK8=cx=&`QKemZH
z{86JyKVeV6Tl4MMhsXizt+1nU9^P$R$8N&9YquyDcp@}wuff6v@7}c<U0^QTc!4B8
z!jEtgL*Cf1qXP<xTSZ}SfYE}G0QQi-op=j6;o`zmwjZyfPC^&S)eRM^%y~_{4w4V6
zPh#0Ki2Pa}oPTJTn|vg09IF?fZ;01+oTgWBV>OrdW^up0hkf+V^0OWjX{^z9^)^yZ
zLg_Cn%adQsoY8njZFw>4Ts_nK+v04#3*x(6(?rDT(lP7bjZSSs^{&HsQ2zLBEIPC!
z+)N_EnT0vX*lCqeJa?}1_l@egyXZQtllgWp_Y+Q0%Z2wpEB4e+2oMTz7FK4i)W20A
zSU`W{CMwhLKbCu5bG{3$w`51Aep?v-!<7b-a=z_|d|mp<xG@tni~IfVP?%&SP8XtW
z+B+dGJYlqZfm`4EK=<<k@Tu?jb<g+y3`e-k);3bR^TNV3DZyPDI5HD^{eCi4VugD6
zC;Ka97D)QieIFt~(hY4M?>1Wm1n`lB0qC#LGb`owX68@Ux3BasftN??+isdf|6la)
zlF~;8q8TF8&pH31_Y&{w4G*pitRdLw>2fRcq!or4u>k)U$NPI$=_gNguNM0|FJ22S
zxkn#WHeMHe*O(>W&CN~jPVCN8<|=50yQ}utw_+UjrM|#gC9P1yTTx4WdtHBBfCSCj
zRQip*xESv^1@XEjAWdrG7k&sv`QhkK6867b9u{{26%o8lysv}70={!UO{$>+jKwXA
zsf?f)#7mzYk>`eC>HGuzvlFiyVB<fhSWMA6)uUB}!bYCe%VwN)erQUHCZ#tPhA2%D
z4IKQEWBCrUCx&=H-W;Sxzuj+u4_wQjQERBS?S(g4LN?h(tIb@M%E_t_i1XsDQ*{`E
zAntk^&T=OOV3Xx3FESw`;`f*8Ym?NGsP^G%l8s`}nZU}#X=AAGlWR^tX{71z-k*wt
zEB?q=9RCQZ93U&(jV`7tBVpGME*d3iKdG2Kh^MPys<@AKc%jw`{{xD12)wFB1S}D9
zYvZ3sHqWF()i!F=pkl$YmKjq{XOSfjpB61sp(_<4l18D1U>8U!7l{=zN5614_fD9|
zwC;+Na3ssLkeXn(6onRn5d1cRn!K>A)L=0eS0D}XAdbf)7V3PO5)P!&t^3uqiAhqn
zLbek0wqIgI3kDgA^u2so9WWeo*^jHzz8ob^_+2A*Xt^rzCY`pH9r4b=dDIb-IotMI
zqb|b%IGFH?mFDM<^qcX|YXJPI;GBAF)U3RuEG=jKyFsrh6i$9tf;NE-5RT3=(WUkn
z15AhVgIO^gxDV5hN#<f5y%ic64`D3s9$Frk+^T%%Pc#I#wTH{704-J$eT8yIwAJLC
zsgPu%-`A^kjPQ&bbKVq&13h$k9`0h4cWM-}QD1d+UmHK{GWeBX;;|+h8pd34g=JlS
zYd<<;VEquB%D0T*FQmZ@i92u)>Z%_6S7fk1wn`_46mwjW`xNse^s0vlGbmO_@fu!t
z(3`!saGR*s?HvPM0GYgPe=l_oZA6&m?oa+&*f~7%G=9mEU3Za+AJZP?x#2)}q{&Ad
zv9+_(Ka7}7o&vOB&<y&^uh{_#(RZdzS(ouV!O}{inE}wXj*B9HHg$Q2HrF$V4YLbw
zy^@hd96Jr#@oL)x*+i%)t~VXBB6+oOHe&}1u-!k&4=EYrKvDQQT!NQnv3S9yb`ZYk
zbhuuwdD%;(2Cr&juRetY(XYEv%%~idM31uBoEf#kmWSbUl?Vg!L-~9(wLLuB!VW)1
z5)+g{jyoZr#SBg}9Ikx9ifi76-VrMUO(T>8JF}4LguIj4l-E(z?{>CYySqAz62v|!
zEvfPsGhH<lK&R{JD5T^Q6RzQAE<zkN+s@@?oXOZi@};~6XZy2r4`#FM!;Tg%jLB+i
zk<BiLPQPYNUG@!}k^{*u9_t%JBXQ<hRFD)%x+JEaJJ=l!XEn4{PsRv^*P5gHxb_KE
zeA%fi$=BvRxMF?1cnxZE7t!A8<NnXUO!#%SUY%$%AhdNz)=^|0I}IjCnOTnG*a!|>
z&k3q2t%J*hzj;zGgyOPD+y!x~#mK7BwV=_T#y*+ndkkfUGn{adDw$q_xaj6k)2;QW
zODsY4?s4X9yt>33dod0M8rKOz+qu;ONG)2$5OVskB{BPGgKpN}+8VXHfS)@GqN%!O
zn264(K$=T^jWDS*Iix^{$ok^jr+<>pdXVSoj0oS%j95oLB_Z@EDt8ezm$%N*z>af<
zu9{3wmOcePoQ1atUtAhw(*)_UB6#1nOBY4e_N$sN936NBmCavA5~0%uXj%G2c{aLi
zCq1MdSE)WS8lDtGm9%E+5LL_+H|fv;&pu^I06tsn@jOnDttw_paaZWwIDiaQom=cw
z^?hv>%0cvbKRTHJGf~%$@{}ZVh*T?}UOPXo#0IIRmLZ^95%R|0gJU<SI2SL{5FwFH
z4JstG9r2bsFF6);3m%fC+7=1SJ30xWqV#Us=jB|_3r6c`Y^E0dS0}p{N`D=xyxV{%
z!0WR`C%2xA9en^{+dh}sXQDTq!v87%F{Ar^1m&nfXDktk>w7$3rMM7xg^f?XUp)o~
zeGFS`*at_}*Bae7dl~qO{1?QQh(Ld}9|<ocGE%mi6NmaW!A`q%DZicHtHv8N2HI%X
zMVu}fn#&Tam-cc1iMyJcEOSmITpcwnU~axzptG-;ek<rua?Ua>Ud|6XcWl|mH#Gio
z+vT@q*wn9Y2e_V9e<yP`yUm@KJ6Bv?V3-gPr`T$d>$tfql^}cz0|r{;L1cu8oT*Iw
z=q<>=tE!zSCbG!0q!oO!f&_w9##=)%d;hUZG}VzkGsN4%N|+{tN|-hg6;!tPfgBc#
z%R?)kQlj`{pG`Ozk6XMl2D~c1gSLJk-oKws-U?+#^P(C1DSBUR*+5wot+mJptE)6I
zj91oBj0~c}Z#(-g@MAWs*lJzixz~o7+m`6^>ms^$_kFq@T8Y|2gY{4(lUsGBqrI-5
z`sNR}%0bWs`BR3y(Lf>|O3sf8K$a(tE-abZ=m0o4y0uYE^St??POsKZK6LTn%IbdX
zinTkhLp3R)v3EPsLLUSgq~-Fd_9DIqsRX9SMQ25Xo510MCiTY_{xIm~mJZyMZN!Xl
zuH}5My$8faUUpY6yi^)Ed3}_X<vY;vZeXf)a;CEKL|)5odT5RHn2d4&^nBCdQe^P7
zn}4A~`ntJT;xBgTWxNr4o_)>@Zcu(R!3RrdTWraD0YHB~vnpjDs>uac*%Sn5P96;J
zl8bmRoMh<aa$|S9ttgE-LMY9&M?IJMY&bPf4Q^;(smV>+H0+qO4Vq(yzI(8Ete^31
z^kibfJ{_Ht;EXPEWf5(mqAioX8<_D*U-o}~_5l(Lf1LmKFKG@Hgc9KT?*-rmZtK6S
zGW(N;Di>P#SSDTGMj%Kvhy;Nriw{_1@xebY<o*_C_0#h(NxAfCC<55v4^oV%p?1bD
zeSe+)-af%vu2!ygmTrb-gTBAHy+?$ZSAxC<{;ygLLG{Vi#xMQ`!AY_%_5Uy}h+Dw>
zMTiS<pnrkW)rd%lCh&B9Q~kYk?+<iAZ`f4qQj{`HwB%T8yip8XuFf-k?-TntCtn9U
zL$@4jul(RHZt@gUvG1LyyncKaLiWVgsniX)h&-!6bvW|%+8N{4SI7GeukpuP@BHb+
zZS?_(M)5%#Q|IZy5;>g_15qx)SL?gm%i}b#E-W{tZsSH)Y^1(=@E^<hH)b<&^d7lw
zO5_k0Su9+`aTT*3o$3&RF2(VKlS$Tt1@kr-(V3>W8xDSYWYeg1F;7eiw0A>O@t6XP
z5UQBU7)qFS$$^IWF)=5KI69VXjBQywwH;EoLw#`nSW|sweQF9-oP|)Y6I!ED{Rkk`
zHJ5#?mc<$jB$@&{*sU!2h))FVq+jm=QhV7UT*h2`o~YnORkH5>$S-&hKT%+(C93-#
zZicL%X;f)-WLq-$t<q53>DvTYXC!(D<?8JLDwc!X?@D4}i^12bx_ycZH3(3+azphX
zjw+WHdGwQ~3Co@)z8-<g4ursT+z0?{*a71oOeEdKPfx7SF@+Bed{si5ioWb#FIazx
z#CZ_SWJu@tG{UY=uavo1y$=K?>JL&dZuTf|Yp#55QFI=4@p#Z{2^NI+S?@f0WkM^N
zbf=<#KB`r_I1EmKBlJ{51sWxsBE5Tm_!?!EittUcOf=1E))QA^{JJAVeP%%F5I;@N
zO;l7SkHma5_90-D<9JiumLu+v-RFMl4GmXO{L&2k=ugd0WwkuiMZpg`_}blGo<sFS
zyYo~B;Kh4J+u!R&yV#nAT@+ooZ+r_ti0Si<uNyDS5o$s9=3-kDRc2)2LO9W*tT{~j
z3u^%djy8#hTrqwO&Jh~}?hd$4atG4;pa#;D@`7es*w)rDF6fahZWas6h#5&(Dk<8p
z#6K8|;D2MEvr0lMaF~vd<40ZOWSbmu16hKZ9(K|3+Ux~$pKok{eByN`WOhBkz|l0K
zq%fAafwcbDDq=O+<f^Q-B2ve0LC1gn3VAmo=2RgriMApQ0vqht8VByMro;B3vG2j@
zCnc&nYorvImUF(bGMzhq;L5qM=5oi5o*1gblMuy-MHV)X$i{KTSz!mucXlIY1t@mm
zJTc<E2a~86Hx-TrcSB)`caePt$$_U@?~BptsFB;M-o$}&1Pd7_UAJ_QBDN-gR_Y7;
zjmP0bjJc18W+^@;cmXU9RCQhxf%=OnR`5Pq>`Hg0Ru$O?5L-hoM6R~c?iRurZnHUF
zgh9L8!(d!!AK{KC4{Dy%lQ@03i%~5|`*cz&4&=+7YF4UvSUD${65@2@ce4x*<T5=0
z_>22|Wq-YC*(j2z>!o+)8X;W<;N^NY>>Q`!e@nel1-vX8Is+v2BaQ(vl)BLS$Khf<
ze@XV!OTeB)PADt!tOdJ9mP05ZKtLI%HI*k?G}_7NRox;<o7{`B^O8;qMS1t<&qd|V
z@%YtbdPi)2hgFE7>9#K-lZ#Ei*k)+(`BrTg%)|K-R$ZPb|19IIL6tkSwXD+=iP6@P
zyv6`PP*v(rIe-Qm&zuX{QRuo&n5>c@vM35(2+rRg8~xztq(oHGuhLt8o+OvAVG4Hn
z0f~0NFpZ8{7}HJZQY}4|{>2(A9-JX{3y-z&wV1j|s?sI>2a{R2$d-%{Yl<DZ7Yzme
zG^`)?1}F6qsahC9$fIaQ0Sf&brkY08)M==%SNWSF0RVz-Xk3nU<OOzzV5aO~tqqg+
zeJweyzwc(3`6|J#2bxU#u0AqOK#;sT0hsWWZz^tDeF2v%ZA;~sYh;`lp{?cR%tBxn
z_7%?6q)!9jK^2#7?-wzO{auq^tRPUt)>R{~`spMfK}Yp-o&`W|d{xLh7V4w7mK9HL
zd~nvw02CfI1U`wZQMQDb4z(NHG&_-_BSkv>K{oXOGT6#w;>A1@L2jV$Q>lvQ57DVg
z<eTWsElINZ=A)M8gV-k;{SX@FXY@_nXbuyBGWTfdeNsyzAQvsM=~LWhHkCM7FdiB}
zn5%ffLe_bo74S`s`$`JEDTPOBH+~5oet;_rSWPps`qLw=@C#-9ivG7b%mFy%4%?Nm
zWd~6N?>C7VF3)hMYthZ(O=_n&b7k65-r_siWOeHXNUVfu*U$rOQmv^RtP!RB>xP~r
zou93Y$X~pnw=Xi-9~DyB*wQ~!U&s*{Ih+}Lqf6^Lkmj8E=`=3Hnx&_YIr#C#o4w>r
z04Gtxjoq#l>B#k(xGGIVQq_T|fyFCFjTj%i!gsI5h6UoiW_zZt=EsoN`N*5WU1Uw|
zsIXOwwJ76SkD==R(T+ShcrLci1Hk&%zAWrQ1+~aj^@^1qj8O-R&}JVXYYlYym=$f%
zjw&Xfst{Wj*Ru#Lcd}fG)sCMoWA1PPa|}wWTurbVVH~Qw?WS|-sAvo*BNybX-uyF}
zy<opLfD%rKntR&4SvJj--_%AiDYoq@nuXJ1E<K_}QC5`|S#TnkdnmT-uQPvdgjx$&
z%45f1r=;C7AEUgh15#akSgDBH$#SgqG;_;4m&#BQ*qB^v%usoXI|XRKfB;j#v(a9f
z`%zk3>Q-z9z5j5rrZXg%;=7M1(To0?&MxeWxHGtjEDVCZB(y5bGfI$^Q=}ml`#^~+
z3QGs!bR9A7zl&{N2n8P(uJFMsFNp`(tnjtRF^-fvK5^LnSjUchao9Jj8)V$cJ-*U6
zMCy2ErQTwKu;_@CUD*};g{f_z<`i4*)*roHE%(r}3Iob^r>?6iY^}t%j^5do+}g68
zOJK?sL06=_Ss_FtzT=ZAJYyD04Yzcf!wi4qp+an1C^>fI4_oH$dCS?Pd-7!9WHdq&
z>63e@r4DK!I5{;k-#NMoRIFzq{F~63zK26bB1&a3T#*ps6^3+75<DEhQtNh5(=4E-
z&gZn)r9)p&<&spXUkLL9&Sbvn@>&W${uEwhpTaD$%_3NpbyrgEjW3L<w*uOLW_eu-
z-2SieuKrIJSue2F^xRcV%I)~c<EtHB-N}>D<<H?h%ZkoMK_3Z0)YYEK-HTfNcPUB`
z$|A;@6#rGzC#D~(Ck501ek38Z@2%Kf{PCfd&jrWgOy~$3;45VB^WBhhK{X3ZP5!)e
z%*CTOmn=^|g+_aW7e;8a`9w05+jBuaQB}S?EnE$(l(#U-&uV#I!xGA)kCL9SbmvE6
z%KE$lFUm{okqItQ>>B7=)tdZI9ZF~Qt0ycrp1T!YBuy|4!eTCfd;_K|=Y3_Yq{hOH
za=F0fmIWSfL&-c%fmyHA^PvI0BbJ4mJgknOp&lB+U8#_Br1B5ybEPAxDBS*Zagf})
zn}m=@FG=&7&Y6CO`BT@VCl&goB-QALMd~r@<iK>0!Ek2mA5)Pb?IsCJ0n!qQEF|q8
zfdnHdUJ0V%#W-2ONkO{4m7s2G`!Ig>Dl6l87%7{;*caJ_0ag2jd#=4C{S3h*N=Ud&
z{IYSK%2WeRdXab{K~q=+fqRmVa1@}hOg%_h-_^b%z5a8>{v4xbEXuS<4`96@L`w`U
zsQ1hDb{<irsaDrC&&o^Iz{<d|$<?iE^B*|P(W`N3-45c&5A*s?iSIJGmz!6J_)%Co
zTa#=mGy5wVgC`<cclmd`^cwZ;1YFThv(Vi?bzaxU<yQAhrd2Aj1qfQ|3_b`Iz`^!^
z59k-TBldL7|DnGSrXfB-AiF}xVGU1&+Y2GiQtiq3UXOG;FsPZv%eg;A7e1Z;^-SZm
z=15)Dn7ke9{f_y0GY~m|)6LVZ3m}3C22UwuUUhfU0Uu$STsr)BzFw{Lx}|ENUrRNg
z2OnDs(Nb@=zR!R<jj!wT`aeavL2zUNU-a$LwHMGON!=Ij7;Qyxn08Iy+x+XUZ;Pj5
z=Dakff5Y|Ne}Gf_(4`^N0n%oSV8<lq>+W{y;EE9<${<C}yCl^h6>h2A%vmd0V{9sl
z#r$FMXy}XnOWVK0hCy+tauX{#oKzhH+Iz=$A%@gXG!)?N@tokY$uZmyj9G2@W|~8T
z?1XgODl2by=X$1o(r@0z@k0)QGFkx+eZ|;g#~vXOCWworU}y$5FA||z6E!^wsn<9q
z%9NH-6$O_dj5&DAJZrW&)a$Pu!|<wnkbI>^1ZL2Unv{wpH3IZ^Tij+T-4>FFT*mb^
zN}_WeOef%SLnS*kgwY9Z3q8Qm6#jp>dZ!@G!lhfcx@^14wryKo?y_zBE8Dhh+qTUv
z+xDsTud^fezi;wtMn=Y*7jwLCW{yYI{r66&i8E(VwSqIh0+~@ud(u+50L{6@bf^d6
zCQh~{g)TKCis<&ZCX`Xn-rC_LwIUU-bNF`e8Kl^5nkiBjfiB%<wI5|yEl<DQC&NHc
z67GQhVB<d$5^JvtuHuzf;@MT&>6^e?qYw{`kry67dNvO!S@m{5H?l%%giE4nKADxe
zBls$MBXb}f2qVx-NbMmm3bT46)VSG!XezyN-7U&)1)iRxg~!0Q-X*-6N?O&NO+GLx
zK5@vgIAjAYM)3=!s9R5u>fz&shsI)<HVHX7d+rhy4t@S)#a|_tLyaBs11Y~IL@EBc
z0RaI3T0Kh~*OVkhcOTzqwoQ&0++BIt<pi~S9o;pvf%f`7V~OGu8bSG~`OJ}>*pT|K
zCizx8RGiubf^eKf{+<q`g1hw)u_{I&_(Nx3N0re0%^?C7Zu>#Zeu|_nhzmC8dA9QT
z-Cu5ozQJewE!Qsem<)`KKU<|WvpvX8?m%*YCmT(P=f%^8!Yi0;xsIB8;3N`WxFnLE
zv^XEPtKbLR%H%f$Ne~DQS(Niji%G3P@mq4`mipnvR<0TS#NZWVV^^x&k-95U2Ops!
zV!n774`c<F7}dDmHk>KHLTX~tc5f{#PJNTR?gy4&_4|4Rsuc52End>g>Jw~b4P$OV
zwbL-{4KNhp>s+sEvK58FC~6T<K^<u4xdBw_z94$vyL7SVdR+rqdM5O6PG#1hKzxVf
zB9J9SI;bsKdLkpoJc%zFOIeVk<zVogT$L27e+dyHmF_!ZUs&h?%pP#?Uy(0M6pY&8
zgSxUY!)kKWdsC>PHyUV{j92^RRIwvKsq56W$u{c%%U$*6!*)^|@AbHg%!h<uPgn^r
za?yz&A?!?kq1u3jzW=d)ksA4?x4}U;W>Jq+<u%W0>p$mKQEKH6xy(5?wiP$F5VVp5
zYZB$G(vwy(0!DPZjxY9Wk3qy0$h7-+)dB_I`TfKjQ?osrmAFgJX6TT%U|Vm1x)+_3
zJ8AdOGL^1ZPaStjV3BDMzvu;zwCMe$hvvV}Xu~=1ENS~Lb|?5qj;`WJv+-(gpnmmZ
zD}B6h#WbaVH`b}4>dnWfT5zjm><&tpUUN=epl}@AS?u);C4}>lRGB9DPId`_f1f+b
zzT@kQIw#`SupPo>Ut+;DUbt)l#I07w&EXWu+9<>_ge5;4riBs_arGF=z8Pn(&iIIi
zsT#9OQHWMlGMCi_*zSK5RugkVF^}SI;f(>P`Ic!te?sm|l&8}Ac()D{R}b!s(XUZ1
z(40tz-K7%bgc||!Ts)zx&If!u6+JMgYV<6$CHu3Dz~8gjL#mWU4dB55Jl%!`awZp*
z<PflBl1I)h8jpf0qEkm-n(CYt;Q9(?HlU-ma&5AF-L`mVGwIj{%Vyd<y^hqVDTF%g
z%bAD3{=Zt=D=6_fizvV>q%fmn;IcUB@ke%3&Ge{dC>_R%H!8~WFQx%t>yVW^L)Sbp
zWJ}|5!1nRgse|IUG1<rfSJRbvE=rTDM^NF7n31Fhf0UMr=B79c?s&B^c~BA3X=rb;
zx++EpS$O}|q>aU8ypgN}AR#~1X*EqQLT1u~aZG;E379m>Ir>iI_U&4k%Xc>)^<`z0
z%|uK`0YQ4gH7jPxmST<>3TwPV7J)cQELbjc^{9d~g!~SWb`}-D!NGaMpcyM#4f5$V
z(7hIMKLW_~i!zU;$bQ$G<z$=1ZhPR+wQTB|#R@|yZCC(FdMB~c026ntyDk-lIhX{)
zxOe}u5AnQ3JW?Wj{i|@ivePOH*lNhss`uAF=8F_Q0g<?Ea-sk{1CxSzYy=twZsVem
z%T2;p$)aNAbmJw!X}{GolB-u$loi$3kmUBhm<&YeMS~{mDMCDYL#17zQ`FHm1Sccc
zx52*$u>hV^b=A;nks9BvH;>H+K4fma9{9eDD9JSCPK}~i`a<L(O7O-bAy$i?rq3J^
zBkNFnKcMsr!G_~`naf;E<fo4+{{+x0DfT+!k9Tsq^TP{3N8B}$keq&imChdAkdT-k
z=C%a2+D-zEH$)6!6Ay!mdvH2I3D<AU)k1SSAeC|tm@<0C`TV?66_fNRiUsGPnnI%J
zy#VqyF(aD4x2p0IFRh!ubJZ@Se1&<GiqP6(n9r8nk>9wG;XMsdY_v~g)<uNr%Rg2F
z`Lh{iS}73#oSe~Ej}#_6*OYNvO}v|8CgI9?VPE@6P#TCGsz~^&l_+yY#G57(SGbJ)
zka`yli}LS#^myo>^!ii25{2c7LMEN3_Ld0){W8&}EJNRvP!yi{B!eNV-lKzIDoD?o
ziQJfMw}jzul09vyr;m%UdmGz`>nOp9azrNN7|Un?TJz&APm|Z~`{Eo6c`9KIvD2Xu
z;PYj<#Fj0v1Xy_*|4=94n%RI8d(V;ThkCpPn^MZBBVDIrU7N|T7D@5uyfiW&vZm3K
z$KJ;E0-G7z0-LT?^=~$r><e~d2PLxAVWu5=?-zqX7l+p3i1KD$d0~(FjMR=3ql6u2
z&*=sLuW-5?zBEN^9f*T#!7VxTFx+U?@gIkQPN+8h9bAV24<Q?MVWw7|l8;29f!XP7
z1|U^<Oa;bi&-Q!R6UBH3&j4j1<l=&N-`sr%oDVOW%NK<yg}4o9<^m>jKqBHhJaFM_
zLaZKQ@^uqmb%1o|;;hj5*LVEE8Oa?!xvM>(vr{&=f}fknIcl8&zNn6JNW?1d6~q#Z
z5YzhOQKTU34#|&ixIVw&S~~=a;59+Ei!lT7>|C9UOtRe<TZreegI%EY5aN)=W=L-6
zSJZrS3FraQXmJ~x8fHXk=u@{k;cXJh82YZ2e=>cD<((%H&lvLP8qQq}rC5|*GKv?V
ztTzcp9dw1k#5_;Ps_sRM*LXZJ!Iepl1PUZRmZUER<n7};iK~QELO(8)KgT3PS1zp@
zD_U%D&NK04t?kaRQzHuH;SC;Mw&nw;daVu51O%P$LO)2m%DHF|nGew<ES6Skd-<<L
zMlE><`AhPKp*go?H`XTOK#wyLor4<G#YoQwcuQRY|Nm%GU<UR$BoY8KBlG`a*<ET%
zN0783b-$|}*rO|Hbm7ll1@u|oSl@11;g>r!Px-D)ctCtSSBVFrDpKKZUHJ{A7Bv^E
z5E}FJKn5lL2tjqX4|y6ny8mF?>%TA|zA*U#J6_*k`*)YF4oLsOw%^?vBc(H!IDeSf
z2gLw#ejw#-4l`_nwpIHhgEP_}FUJ{+<}B0y_K^5<vTdcxMDX`U9O+gh4Bc=T%O}~u
zyWKSieYjtuL57J~V=5$niyM7F=4$NjbWhION7l>$-d{=%5%4Q`_~~W9Y?A@>?7OKg
zHu_vAha;lmDv(v<Ip6AEonGHm8nX$eeHwtQC6d%5x@pu&H$RVf(fM)PBmR4edE&ru
z8FWP`|8pSdThXdvG>7A~J52|arhM8H`z>#c#ZlGvj2jwclwbBn^7y9A0@Odm_J(^B
zXOWN&%4v}$sro`6-zd^mzVJ$``=ASadQq`g#gq8V6L)Z<sh)i<c)r?VSWyIQ<uZU^
z5?O7ol}eF<yZY~=qMCv*EH42MJDpIP)GX!>Pt|7-V1kYcGFVeTj{rSLl5mA%nIuJX
zSLFpElH26tG%h9;n4;?>6ju8KnsJe5jKv3r`g0oFbfm7L97Kq1F#wRc789Dax1&Fp
zd3C`0x*xWX8YrQ6$y3T069TXaFb$v;8S=bWHprB){x8)N9Gy}s1J?d5<!tF#oQ_Ud
z<vRx@=e-skyKNf7nwK2Yl@{(=>i%9NoXIf9;smW5Sy7j7sv;BR<T;{JH-bTap#KOB
z=C`28V4ikW=5$(aakP3NipTm3g0vm8qZ!Odc)(?Y5!wcgtvPTUg}h`=JOM!VKsb0s
zU)#Cu*Ev@)mG+FraqS~LOK{DoVLr5hdN5|zle)icPek@COEHa7stkW6|L5J|Z-V(i
zihS^A_)wqcDWkNLbm+yq-GyV_?vIBWTN@^?m%G;zz%;tDpZPD!{Q=u!7>fu{KvWpC
zIclCHS#nbFM3-}H-N-S04-i21nq{7W*h(>{*+kr%)?OLaErO~@k7t!w1sW@01HXX=
zb%A#O4pKkv`yi$aGxX~vR7PxDDY)A_gMl5QY^bLcV(1{6g#@KP6ueLOOhz0Cd9H1G
z!kwwkb0InnHB_<)Tg4(6_8UYbltG?^m;>k3fNUa!lc1)4J}pQ(w-vxXHqJ9iis{%c
z<l&u6cx3GsdcP8_gg~6s)2SGrfgo2%2*nwqbpxLH7x=iw9F3xdtI|>rPU)nbTvvC;
zSDUK0qFkD2Cr<QN9Fc07I&o>_Sha;w^6nh=DYrZQIxv#6#3@!at?B$J_)1=zp#24K
zgg@nd`@Av-Z)>()F$^G$3)t8!El(bFAvFgf==`)?gSRga4Tk)HSo#L|Zl~ebUNa$<
zQkd!}a`zuLZLQ2vayE{Z3WPM5<Twm>`foWe7(U1N#tDf;=*HNyumkY1MRQnF@^cCt
zwW9n#M{9SA2E$Tvd`-LvszjW$N4nuAH#Mg|A*g&rV{a0R{@?(&zfjI|XpOZ>a*z4T
zARLPD!Qn_N=E~~)Drr<WWyPn%vca&rFhN+8m^7^@U89P|wcRMb$j*uV7I^L<xr0sC
z6=~)*gzlDkX6dTr>C--ygD7s(hMDi{rq=P|SfrzI_PKw9Y+%KI06{#qPVuI<eZy^L
z(iz#srtQb2anS$?5u#fEGQ>%$G<G{i1%`S7a_oyrx_{E*AQ}rUl?TLIpKFfs7dKb|
z#XU@zA$9UV#1By2?_h$Q-$f8$U0{JTs72;Obrq#T>_Ha0WOVTJIISEKp>)%)%R}S}
zjLy$le4{Qi4i|f$R&hcvD4$>HdAXsYe_)WQ@ir<cXiovCf>N@EY6C)V%~6y4nNH;&
z03>(^+UN=n+SOX|jQZ&KJ97#y(W0IiF-x7i*H9F8qAO)8a0>@@5Kc99)<sh}|Jq6+
zZ79{WQeN&jYuSzqpp)L!5BsEs2ym)&WbYw1!SgD|j4+tIvI<(O1rr$Dc6SOvu*LRs
z`XAyMLOtNuX@IP2)iiC22!iCMbWzvtNCrWir%`80Zqtq2K}KMaWtE_D_B2NzJlmSf
z;`C$J!xd`q8i*On7CEv*u=}=<TxyGJ@nNw@zHy0rW9tn3ux4M{_=?mHGbb%23EU<c
z_gZ2IbCXJf%F+_~-#w|S3#*S;Jd7a(_2sKkIYL0e7#~a}6pb%Pbt7@|q=r<d!>n^v
zjOOom?T*~$xAR{D-Y19P_A4rE-hU=nEdN@7K(1<Q+gqWmp0AQxdGl>e0eNeW`rR|o
z_N-jyX19dzsE$Xy!<M-?q$)2dn)*?&d!m(vcymPlvyWZ8$1*+9DuYiHR<$LE_}4qH
zb=Lr(QE<^K6NjLSh=HeJWO7^8byGa}e9Lk_S1Xye4spPK8N6i)22wGu6Pdb6OqX0d
zFzQ4ry2gOj7|qg~71M<cZU%2}Mz??j$Mn;q02CR(9my@JnRZEqIjgD|dvA9O`NdR^
z&@3MEuurkPca1}`I7I$94L6>xw%bQ@XRZVI<_p1&Ps2&CS9qlYL0qBWnF6rj6Vn^G
z`USJ?!6D*g2tW^vT?lh|4lsdDxJPxta0;7={q0oZ{cu|2?RxA=saa7w(;NSFoA@Ye
zU0>b?Zd``Xxm(Ama>pG5i&(6;Y-?J}H&K#!JT9}!C23KTqK1B+s1iMRpB-dZBa;GB
zaV1`sai@!%IzaE{xre`{XKJvs8;3w8NsTvH=m-z)c8Z-3kZ#VW3gI5QO(D;^Dl4sA
zi`Bs-9Eal@E9=o<0cCz(<ZCOg@+qx0HkD2zzs!uRLP-Eh*7)Y5f}@xx>C3<jB~|iV
zt^#GFP4HHmusq`>dCs%!e&piFC?J60*nN4>N}QV{M|41}3hkO8eAbN6)(Q>Bx)C)h
zrI)YIgRf8wvavTm#tYnR71+y^d_2i2aNDP7W;34b)VihhzA!?VgLvNE-WW57wSQEb
z`og_2q{`vLEMEDRp;cj0fD{LrQbqu;N;Jx~5i@9rA`}g7O9CHj<vjkM-2?yw)pf5q
zyZG<7MLuL|IBOEQm!$+eezu`@Zolk@L$sSS4XFh0U4B&_h~5d^r-pveG_#UUOA!C$
z<q06^PRKX`B!(ds^96(!X}6KmeFL8PFoeVW{$sst*jk=?VwYd4ZrvcYM5zJT;%<zY
zh3L087>-m%-cMzvi8+o5%G&@OtgT}_d4{1P#oSt&^3=tQP>!nM)R)t5nJz|;D312O
zrBO!PoF3AMAuhJ)-PY0J&LOAAiFqwEr`7A>P8fWc#P?M!RjI68J`jDKH>>M)hiCq)
zS|V9AgfxyDqz7}xr5A)yBnO(?T)i0<2je%g8t8l9XiA$aO20I&SMmWC?HhB&q{9wv
z6<>Grdx(k$S3dqype$akY6Z7UOx1<cQjFb_e-8he>Z>QCr`zl>EbE6&!JWoeRBy#x
zHOFT(Jxa9zUY}>rl0CSr-*D7aH>jFB*u~q`n~2~tsw{0ydKvRl=k$3p79M=vOs*Fu
znn*$xd95>C@#*fWMoa;=r`<t&TgH!F9O?R-I_BpHa_@4T57rJc(N|-f<X3r)`?50n
z#Q;iz^=as)&B!^LP)mBSLLdKpda%*y_IownZT%9y9#4i}orXjBouIvm;S9F(5olDV
zm<fx-8?$VhTAB6ka027%g`!^UI<@L#@pA6;k;ra(D>tZgm1KZ@PTP(jeAof_t8qO1
zq(*%kUt?1mzxNl@jJXW1xQkkB&DMB{0DA>vFH_&qe1-;iuuGIXoALdX&}71J>Y+)S
zY5!A=y89H3H!+B10VaamPX2QL7H#XzqF$QK&21E2%61B(X>g`6P}}RY>}GyzoNI#c
zt(8NPCN`N+RwcmH|Ja7E?M45iaaAjX`TTtaso8XO(Gnu1a4BB0=<OYv+5A`EnPktF
z780ZI@=}IUcG^SRQ_XXLWg-uS89ckLTIVWm>aN9VtdJm=2h|pPr<H+j)3897ShZ`{
z{nlR>rK*K#$$+dpL)Me8?G!R6L#el4;B?u`GJ!6ZQ)cF!6jix<O0?o_rYYxQzdC$f
zn=L)0WrAdLcKas=(unI?WU1ZE0%A6>1aA>To(LYC#sww!@?i<9cMA=t-LVUP6|&OA
zJ_R{#@pj){&IuG&kxJ7V+++;ENq)4H0m%{UzVCcMh=UL||M$?r!Wf4{3Sj5>UuTXf
zjV_x5HpHuYR1ZJn7iMM>zkmoJNnfXsRv5*~L&tP2dleo2LJ>vb@H;8fi53R*j%1Oz
z9rkZw_#JT8(VG(R3J7T(4*p2pfuJALyPTzG`j~;4o>M`|-6FMt{fU1J@P7#UUq+65
z_$19QKwfVEaEN@EeDu5fcy!o%DrnUdD10*r7=|*f`TL)LqzZ59b~zJwsm|<{j=v)T
z3RGV}7&f~fH!Ku9!R4JecfK5)<u}?oX8jbn;{3Pfuv2P}>SW30=u!<Lm@8hi{G<b#
zEQhcAzZX3AY}xtYcGGe2zkEInUmoieUaS#^xpBS#zv(nE4IzHv1=oP&A{9P-T=xv*
z3>*{3ko9rwh7pX5S_&cuM<@bkjpzT(V>RzWv6%djvs4|2Jg1;}YwAOpLovQ5xbYvQ
z4bV{mznIxp@jKPYWT?YitI7!x!%N6Mai6A;d{xZGsbCj}<g2omv8-IlFlt2}6-@w=
zlp%Wsj0c0-!bvzZ_G@ykskKIg4h(Vlk;RoCfpH=pJP0`}t_P!L0LkqHt&5P6&69)C
zv$dwKRSq{8(L$D}q{)?xXt)a)_a_VzeK+6+a_i)>2+~(UVkiB2r6Z^`O*Klq1k|Y|
z9L+4R=w1aAu?@H7??|Ac9tKmyj(ZfK6l4Sd8ZN9Fhc57zR)?gRr}Gb^&(EBO$k7?r
zU>ItcJ^S#kPD;s$S2i#EP+a5EqQ;HEx)S^PUR0H9PjqvKnUvVayyD^Y=kkcCq?m<}
ze@{_MTE5pFzE>S$#Mo;u_6+(lTI%^FJT5R(a-s_=qs^KzHeHf4WKjFikgmKJ7N!mW
z+LYDhhE@xN-bvYVX_$=_2?h@9N-K%^=eX3a>>74wDYvPCP|#^yb)TBwq3IBaMa_hX
z^j`Efl`*>X6dnEqhP5~k`m~?6>}YRbtZdQo+iUeN#}`W+HNY-hoO5%YvPZCY%e%wR
zU1HRz^#?H|fp5@$<H-_KIE=rjLry~j;C0(Sj8cMSY*wmmIf8PqiIOpEL-1*}DeO^?
zOU`MVjLEE%S>lVRJQzQ~ZbQr^K|o<*wP^zJbubY2n)^#l><xz1%Y$f+16#*r<OQ|p
zxrlt)qcDYvG435^^U|4kSZL_&P!$Z5x|8Auy3#>ZMB!|XWI9(r`nHP*fu$n>n?nW?
zFI~^H5r!$EN)R#!*h(qEjhm-8B9#AH<qC3r;)Awh3>wG+4Y-Z?GuVci4y@?t%~mha
z&8TNGsryc&yD*|E^ye4X)~4bh2&*hO{i}x$gNiv4BgW$EyApAH<BbiatioM&Pmh?X
zm7LY~i`f=ACzt+}9awm#GD|@LNUbMuu9mCYKYIQmB-7YPCCl#?_=&uqJxzwV2>ojG
znpFiI)hS#M7|*0o6<m69gMPyXx|Dur_7KR^g4uTIYq2gIU%ShXO^Fpec;2<KC~Tzn
zoTiCG*Z3oya6Vs16;qo<pAB5ELvcCb$1HUoB(|0R@SAT*554@rS^1J0FfI6(KJn?W
z6|0CmZ%gX1Mmy2rR=Xm<yV~1k87wFzrSQm^=k}tyqT}*<N=Ft5cRWQ9OaEb9)8=U6
zb9#m<{D!Qys$zr^&y+2txPN4^EG2cM8{`<y+KHkAoH*z&XU=U@S@h&3`jxxV`oOcg
z`doukuPSh(mD-Rs$&D!mz;P;yH_;SC9VyZe#ghI0Vsl6?Yo61t=`EuLnfdW%eyOLW
zd16~e18x&<ywgv>caGL_Yf=-SKfXt`aroQ&Y3b~8q!0#9#*<<MyaY7XlCz(7%7c`S
z;9mN9Gs}u#Lzt7pja)%!0;5YKA<~&e(1??>3BG()E1FCNP3w#m&^)FqHXC9!0QTfB
z>f%Cmp~~0Il~%j0E_r1NZ6ja7ZL?+_l+ulz)i6=6KtQo=ylJap)+o?nP@2(gZk9!}
zk>0pfMXOl?mLUAx#SH1%c)g&o2cL#F+<-IQ=*4G!`&Z6Ba%+mu#Ki5gy^M#<7LRCQ
z@17kByY)(;E)w+x0JP)4>QmypEiE|P>kuMk=p+_fk)CA392U+&Q1r0>T=+T4UXhbA
zcMRSNUdmg@sUOyFu~ff^V5jCI6nK0EwSQ05TGwoxMYH+K7S732qJv^kIHLJ*%Eo3U
z^&o9UlWFuUD@HObeP}~?3X_STlAYF}rH7e)#bFfQ`;saiAg`YfZiv8Y1*xJQX`6P^
zQlx0kX6s@lN~(jFgKGN2We}D{CnCpD;ajpDHtN}ys+cx%LfOVwr(pTFSsjmCh~leX
zE4*8@9$uH#&?a>_^YkirCuLUj>OSRVeja!{MYs`Crn32b$Cix=`_<R}sM;0Iy<W^2
zlvbqVs^)u$d6SIaN+(`>-y)Nq2r!I!nc@FL=swy%`JaE}FP4;F)>vc!24;@`)i2hN
zwk2Uj?7pXdLx`-?K1@M9^aYjJR6PjhAZdWc;IP}fR`S`{a&euBt*kdgiy~9HtUv!u
zy43m78SFomrxBwQ<2KoH_>6$$UpS7LdPb0+c;+7ywL5A>nOHbCNHRql4gEg7w?)Vd
za9@n>M*8WupWI8~zq`eql=)KtpWMIR0t1P}eZ3|*7M&WJW$uZn#Fx^213yy)enZgm
zD%#uW<?Bl&jxjR73?=1WGZ7-DJZ#cmGUXDh=uGtUROK&F=|mmNOcZcT5jpGZ{Cud}
z?+p&@u;H4R9}B4Zj~8W`m*@W8zfB(vS|lJ0FaY6@30)W}J&n<q`<cU)!v$L51Vb7}
zje_ThpTSTqIw1yQQI{z(O^G}3DwSs2*uRi^!xqRMF`SrOsWeP^h8i2=jlW?nI^P&T
z`<Z+6>f2jv`0>=fAnl3v)3*~onj$-0m_5<7;&0Q9E)He+HaQN6ScR*9=NOF-28hFs
z#Q=gi2ZVhjjieSRYGnkOEXD|NK^xM|3%K}$5FgHj6(z|N3Ll{8Ajd;48peRKD=;OC
z?Zi?h%i{}bp`KHH`tHHglJ-XLE38&eV6+%7;g%?^gl+I|O*AP*cRZ|Vn3+}Kcl9b)
zra4m2fJpY8NXOL@w=wYtow~jnvpK4TFaT3&tlD~H<23QMrie1}r<%bMZ3+7DQgTcI
zE^QnGz8&|ifw**KiQ<90M}%C=1M+l_FIrMqmD%I)UN*jI_h9suVdk<{M=Z1oSFPC&
zzlug6fuTaH3+<4L<Jqb?C+dHZ=wo6;2TNX0_)9RAGmb;c!Ly<PjOL-0%HX@*;Q&xr
z38PH4wODwO6~9L!)y^wCmytR4mz^}o<`)^nX)+qS7;N(*1jY(iiJb96U9dw3nc@5N
za2Q}|(f1)CjS7!sRcn(u_u65@tP#xaV<XbO(LfoS95;4v3v>*O$h$WwPRZmvQwrnS
zz*482*u(|Tvv8sun>f>#H>|<N!T}^D&0LGgBx|ge*+tKm(0G+oWdw|iRDV6I>Kgml
z=qcNsi$SHw?!0oX{YWj>kA~Y<IV%)$th|6rEW~h1loN#5*i|pNRK~m1Z)Q5H5HID-
zGB$*{B^3__%T1HIns}q<VJrct90{<dG+^!XXGa7dR8v6Z`YQMvW;)?4O@Od+YU(&9
zT9IdlpG^~Z`SuKBh<w_8Ig~}mvC5!(%qoq@;DN7Zx1<_{cj{ha$yCYES#|b5CSM$S
zsRs3l(NGoL&@#ya+SOM{GKFP-qt#7PY363p)#1X2d2WOd13WN;w>I?ZU>8hjl5^$t
z?DxzOS#Gm>_u6%Olg4B^+5qbAVr`hO8(NY3^8e^1*n4+|g&5|=pCz~jLjBuGk5?|$
z1h*72-hNh#1h?wtMAK19x#dY{%`;X>MGIvXPVm4>F46}Qu1wYhQOC`MGx#KD_cq}|
z^SMR-M7bJYg8PS5TL&S$+F5_xqY*$u>M1ra%O<Ar!($eQ0xL3}-T*2DP=WenS`4KV
z%l<rJnV11XPPYGnX~%aeqj}hU5|dDb*T^tjBqk~IUXsQbGL1E|tL?}-l|IrFjCXg-
zHH>%7aw3xjIp9N|(x2LsbZwZlEc#^<_!v_8H9DJJlT^%2==j*Hb&Cu!(<CRl(+KeZ
z=6nyirB>&Gvgm~J764FF%PXURVk&W*Jp1Qrol0g#Qy7IJe{W@3X(U98f$Gm`M=n*V
zAj4|BC!M@nNeVro;G|(PzsMBAvmqo+7>)Xc0XnVRB-^n;UUcZ#*_p7=<;D^?Z{+ye
zLtXQdx6q8bZ^xqd5ytq4nj7O)mLaX1bzQF*HICsi!~TM%`V8Q!>yzJk^+j1mmqW$e
zRBl117DA8qnuWT&Y=Y?EGF-!K9X=ODX1uXVxBj>GaKP`zHa&}*-v38Xu0lt;P8~nY
zBuZv}wOSVn5_t)@`h)Gd+Rbl)jtfKB%@$U&Hsi9fi!m5kd@VP|bo0QwF#3*<@0H#i
z!KI<7Mchuiuo58t8%5TMSBK*7pZ7f#W#g5ybIn1x>yA(b!w<~+;iki?a@R0ioj4ym
zgssKHCXX?>aJ}W7GA4mPO&yR<bRE{-@H;L#D|x^sZo15N`G6*J`XJe)*e{PFI_-<u
zVfCHd*dAKu^*3tvw_)NC)6Sr`VR=ODWlXIWiF?CLS8xCcr9Cc791~J0YAgp8M(hnt
z-G^y&n9hgAcxj&f_-6al+Gn|2ch4k_by%udr(}WzZjof1kMf1f)s<Wm-&wEaBd(vy
zx{d3QZf=-`=bt$aKHY(;@_~0$zRgT}V!lf3!zjC;8k9PPj8+76ddooO?Hfz(Z*_EM
zW#tZ5HhTbOSpi2RGe5bMx+9$+<!psEZTg(K3#T)FjwefzHoO#f@u@7aMjHh#?F#Do
zvQQ9Xk6BWEQ9uFLX}Lm0!9Q8&k#q99EvxD9mEr`;^;BiiZICu3ZqO^x(_A}hxg$-8
z%QB{0n~shdPj6v}_l!T<wOidaFbRbi4`QDyben+cmjun79(nG-%{lJsmM0ew!-K&y
z`gXPLbV28DJldL&N`1BtJ~Oy$6(7i&J@%UJEVbJLHx=*uvki9@*=o)^`-<gED7y9i
zWtnumx$TL9Wt_9=+k0wweF~$jzjR{QCXv><5P&dy(z5GcbNEgvWYxm9RywiQ)dJ%i
zhp#9ZB_Cto705MHOMNBRUto+PQ_lZKALy%Lk^-2RS=j$?fv}}H7JbnAAM^MJ5XuP4
zSb;ov@Zta8Jw6}%@W(x#{QFA*RgIS^<*f25TTF1YQX(G7>lPE1F5M?*wef|Y4Jk)r
zV{O&^eG2AlH|M+mcxSt~=POIzD(%u>?cs@UjwzuYC85Fg-{nM)E+AQSwxan<N$Q*8
zyYqddQ>S&aXi_@$b|z&d0x_SerWK&By^H}@MPbk55J9S{D@045G&uZLUM_n3JZn=<
z_)u?GlVdB1Jnk7bKZ0_hQ-B+Sj?#2ez$*Et*x@(Pner`jQ=0UZb<fxFWzGV<E!Ol-
z$zSz?;%|8jgxvTA8bDR1Pe!3?gZ|meGhm^oSQnoXJIlzVqG{86aIiDBX2ir;-2pkK
zwwd4(oN3r}AgJYrV%!klB~o~2a#u-I+@7g{L7hjSjF@CYAtMCj%|+kj$++T*bPOm`
z6OD+3MN<RVn%+b;T^^%uvQjU;Y>v1n1@6>sky3=m_m9ER&&^T4NUW4CehXNYNR>$~
zXnmnzuVwyNU@qPw=Sgdd16)vncb*QBk*hDL|AxIZH&ZdU*3i`M+vvahP+ZtH220as
z_3t2)ok57srj$6R9<`@tVT8%P-7a#!uZ=bCx<fjb9q6(PLl~>L*A48ZRn%#Rj<>}t
zRT`gsi2NbSNWeIzNNdywTo)$~$=D3#8V2P>U@VG7uwwX>kjg#<AtooSGb>c%J|!d9
z$J>?{Yw!L#rd%WsSpqVI&{%O*dJNicB7WfQ>)Vw_vw~~$H{X&WR%+Re{p#ncoGJ=#
zmm2hRrlH3O_9%c}EgxhVmf+h$(1?;w1HhpiJofv*9DrS75iYOPejcp)oRo)FDOK9o
zY<%hr(_<Oh%{I!n$N0@nOHX<1WqedLFS0YBNthS89zdoPvQqOjb@#8mR}4mRSuTgQ
z?sDgMayP)F-EW=ArTBp<aIvdJcbXVNDUiDsCt7$7H-vMkFcx|xj;TIL&MJwAtX}gG
z5JMXB3{YX+YN}Is1>LD}x}YJU4%K~PJ(dQOb~0o+wjo&5_~{C!eROH;H#)mEByW-Q
zFiDb)St+JFKKYa$Y*Z0wzPeiJ6bX@`m6tL&FMp4_Vrf#juA@*b%A_2Net--ge4QCY
zQdG)G_S(n<H>X+h|8N|M7H<f0>y?w*Ul*d|0Ois&lpT{|Kv>r-*Zml*^kN~TG{%*9
zaJ*$I`np(#^eW|AcSYnQxpL?#AZ?;#5WbF3Fv+ZQ`8H*P=_JN`Ye?K)uIzgE=ZJNQ
zQE+4hq*MxAbV8H)IU)LuXAmRTQj=1NiIgz^9=&2wylf`k=&ZoU5$l0zFRfC&pbIH`
z0S99eSxVmt?lA&XJy?b36*8(|>J_M0utoI!R#?08f$>*=ZGyvy4t?!SY}kLNo;rM+
zxAi^SYuA0h(7pIsxoWEzi@P7Di9hcy>nTI6@~~zdrCZlxTAO;9T<4tH9`gmhN8t^&
z1_6vC+|==1g*34HzLXc1DeIiNyle0I0ODP`6Wurp5o=P8Mv<N4nAF7wUc`f+R-hXz
zj#wUI`d~?44YJgh3*nX;Yw4=<u=^S?y<}UB6a_vOB;Xp&v-J~od+|!gRL1dh0!awA
z7Lw-0mx19~1hK7RM0u(kb0p@L=1x$HM5V^L$w3-ytD6(LDu;s(p-uju@E%=$fbH%<
zwnpSAYwVjv-xBb8i(VyH%F0~atm8dL=ql=Ud=9hRZ14}(e>HyD*gW}uwb;S&;PfXl
zXAOY@^Ua-ocIfVQnXdv#;_x_-JVO7FfMXEd0(*%;GfQl42+fXlBr7I-s|S7no+^h;
z{sCaL=#7=R#zA;_gTFlBoj7Nk0DjfWE8t?8en_VE08cN5q-O*iShpR4LFQfv5HE)R
z6aLuK5XLsP!=7N@_W|L<-uzF{r!jv&$rb;fJc1Ln_%t_t!1&=m4uCLTwY~pO2<Z+K
z!0@A!vHYJD!2f-g#_bz`B)K6D;e8<uNm9l8`{Yd8Dh0uEs1zgw4U;vwRcyZA3=I8|
z6dFZwb}6NCoz-k5R~q59R<)9v1M!4(HUb&s=gtXq;pQj%o{fa+Y`4D)`y~EycnBB-
zL^8*0hu?o*??e<^I;Y;c`W|*zV33UNyoH)64imoCP&)_&1c1k>R~X_a40HzqK>%xm
zwksG2bo|mrcUmLF#~GA_n8cCR*s!ZxOKDu@s%@sv<Ni;bW;?;>Flu$rz4{<e(WIcr
zuEO*6t~7N~B7RT*se~&Y55GBl7YqU}IXAF3{=db+5*P|_OVOCMw0_3jm%?OJp^+<E
z2>|Z9jle+E7$8XDVFy3cx(k=Oe{u}!#1(Gk)ZZMi{H~ZT2~lA@Q@xVLl_0%1&`QZK
zYh@*6dXG_}>oc`f=Q)hWU(+)_Y?KRih@ed@@v3?nCroj-g7I>CFRv%Ib*ku-qgmzT
zb1rS#Zt{l1kep1Y`Fc?3_E11)pR2i20~~i$f)(8k`HSDY1G!)j8r3#z8^YsiY`}0s
z)Be6T9NCX+ZP2PFYCIS6uhQNuYpk`*<$66iMNKn#qErj(M*BS+BGC3RGX|}-anc{B
zCU|Mug<{*`c}B)4Jo!U(!NPCT?N#^i_$$>t*O3@dY4?W#7v)Z=vkJZ!_>0np8Gzq1
zwJ2l%S#cMmdpjgtJiO|~ZOtu%)@ko;_>v^O9M-xtRUv@kN@l<pd#25YwXJY}Wth#Z
zHLb-n6>&%1g-O)w@VN(iffgapnf{f~)||r__$;t_x@XTyem$~XL=WQe(s$?NL(*Xo
zD9iX~2(}a}vF;)XiLR#D)HUj64v=@PBE0KeXGMp{tOjox(`&o=ksOe>*e><0Q0+0y
zfG#gt1JL^Ro{s&*#@oDmxQxxYQa*mhS8uEH$qoa@;oQ<N_-x_4!h6?kVzGp6+pU^A
zaYLu#&&fCsvgM_tkWbl}U22JXCET2OW|vO6@62qfWs@kQYT$BjdiSX$lTL3^d3>*y
zWbqJwGD*7S-kwa+th|P?PY;vvrZwUAn)&P(t9`=#$79bvpq%WAC~SLg`R_GZ;Z3U?
zx2T9yyi_Oe>yaJ+<N!lq_21qED^p4w|1VMiGxPt_Rfn3~F+UeC)30c_S73%8J`xph
zu|Q!!P<2@149u?5{a_*=-s3S2DIJ$r*=qrs0wr@7trIonHQiKd@5TINjP@_&WaQ+g
zAou$1KK{YiyZ0Ms?-|FZ=hp`$956hgr?1BI>Gnlrd04PFAG;~y(|{z;`d{5m!7+X_
zFkT-El4q+_xuR|_UT$2JMWLN>H%Q9pA`28^hcVsgVayVkUlJNZr?wLGYS|_Bbs_bc
z(y6*Sb);j$5p}N#%ieV7qYW=i5mN=`YU?t%!bzO6ufvQLMmWEVUcru9?xWA8_ILQ6
zLmh9<7iwnsWp?<~KmZ?%jA)%{Uzu{b4h7`J0oi=A>)1y@WBh;|pKPCY(Z<xJ2ED3i
zRkUz>h|ixj*xbLyj3O1wtpbE3_lkYc4W%?4(W;W`H&|f9#`ZsRQ<k@dUYdz+xYOWg
z>X(-!JRpDTd9AQ03~Pk{gc<hTf<7b|-`o^(pfpHPC3{c=vjO~fC`{>$mFjb=2#Cj_
z{c;*5`Lcimit@q{X*>0*2#{~r%b`r*<ry%!b|+vf$}JfYFjH~}tQ*`T_2%Ehrs-uo
z3I$b|lm~`B_bu{w_n_maYRqQO#_V6D_m#4Olx^v_$MLkiX*_g#bv@rY#SM9!SX5yh
zkoy=3fq)g6p#V~?xWMC+Hg(oEqP%@G5h=#n)W&EIQq0*A<uwxgYvt>VLn@Xknyu=_
z=fIyZ-Z9Q&!z^`uos|{?SHo0flNTTDR>Zpk3c)tRR5;RDPFT3*Jk_NX!I6su(wg}{
zKrhSzr-3Kh?~x?J1$~^G3dsG^9sr%XiaY_H%F3ln9>8SOW`-Ej_@rnK#KH)+LOO5}
zQuR(M*^Ttf1wz6Q<2z9YHt8RSCaaX`zIH*Wr<QlGg*}M3r<pQ>iA=lIsiFKc4Am_2
zPTnB|QZ6Pf1J;GeF&Y7x5L+rpGKTAofFa)2OBtEW$NY<!I&Ix~k|jfGUNmJ+V|$^1
zMlM#486X}C9Zv|xvL#YyBGN9o*NauMm5ptvj^9wd?YHH~$48TT22{Sml-@-el+adi
z3oCBtug)~*6Ym1IhHtmd*S*w+^IWIjM~Mu$lZVSlN8=0dN8<_pZFdoR)sxL-=TuEd
z7m2l7dTQ@i|7^4M1AFRS{Q3JllXnD+za>m*Q2=%?`QnZ9EIf-_D?>Egsqcd$#>g-b
zlIMM=twv&L`$_Qv)TB%_)UXq8ASSR`TCGM!U5zD2C1vQhWK^X4?c#dD0fdFMlWSHM
z)0sJ%s>R%^hT33^lP?rxy!YdHr2%#Wg>brs@ctRf!IXrjWYQA~wA{SQNr*#{GQS2H
zc>xtcBC)J;yRVpeY4vCcUaGkBPBa`Ze}%IHwT1i7yiClbz}<#R^|YU`0^c+u8$c7c
z9QJhPZ(Oup;?Q4uePjM1K<w18Q%Mq6V`{tyH){*ybCO84D7QVdl+!*kRR1N54p<7H
zT9{s7wNBn*y3De)lF2Y#W1vlaEG(2|3<ex%Hmm(&@D>_i-U4$BWJ4&9M1UvAr>*@;
zaGd4pPih~fcJt>d;oaNg{4MLrCZJ1qrD@Jce2r>Iv%FCYeU{;{m_(O3>V!(U$wM%e
zhh{;PeW?^d{5WM(4N6XoV=+m9tR#ia1?G$@^9mPm?>(-srDWK-(lW=Jk%lIDsRejO
zn}ibq41N!UI|R68IwFwVv_rCEI9J#n;$>YPV}VxLbU#p!K)Ijjmq&+P#Eqy|)mtvp
zbR7P2ztCJIek8b<o0xn~E$l3@ObrC>rSmkxc$=vU$+XwZ%Iefu<r1-2ad!6ZUD~(W
zdQ4c*loGYm*rP5Kvm-mcnh<-tX965oIXdW{xWDj}X0fYaN+FzTR>$X9O09SpS!`!&
zEZ2~I5iZeSY5}4zU}K2Y9Q1^7bl+sEY~{yjWycn3wi0=s^Tt;wXEwALett+)u*SYT
zPxbSE`ptCP?^<<?Gfv$xGTpOj>BbFhZ`?G68KsNS6N#^--u;#yzcZG;g8{<wK1p9~
zD7e%qvlFx~`bHL|G=vg$^RbFD9vXSPm_0Do6;HWYBi*E;lDyc6$7r~}>h?22a6SQC
z2Ts&N8g@sG#E-aESSo>6r-Z4q#iwzaSC@=*MIIv}u>>`{2!PIb4;!j7kvvvKGmp)I
z4I|ddh~2s)>lJC*2Cni6Xh5+$Q@K6OAba#`WBuG5-FZ0WO(`V75$ZySO|(5jWrJ>^
zL3oFgAK1cGJqsLK!-}ysv+*Bca$J)At#d;|0rXGY0E3@#>0GbRbVaILUv_1w&wjoQ
zRGB83qQt{E23+*rI44@Mkj*R<q)}lRnQLZFbf-`e_1o8#oxTAq8GtW~rq@5e9%|rV
zNOcph+p>@mS8}Y$ftYK#beNYVEO{<fyW5*D!Ti9f5}n_qILtt}X*y|QjQW41SkLSE
zx-m)(t_4%Npm;$|GXHb})I>^qAVaqnXFBx25)N-_T4Liwn{yc@nlOBk^sd1SawRWk
zy-u4r3|x>=W#VCFK>@m>w~xeFMKAHgzh@jkj@#}=srU9(107=?;x&J$bpdhngCSYg
zI%e@oB)-}Z_2HS(HJI2d8I<DlbTz;2{ul$3np<JtzGZ1=-cHcfonF!HZ<3plWdgg0
z2GEu6kIfWG`b-zVq=vUVYRX=gedC5jLs5|uDt8r`o5gj}4FE(&90uHGzr#gFhR;7_
z=M^=?EY?mLq#P=hCxdO`&N{p2JK@@HEeC}qr*A8avMhG)iuC9uIS=Tatz<2OBm5&Q
z=!YwJF6ro)YnDAVsf3|7e6&_|=tg6?H9UtdwCUpf?|=`hkDSZAtZG!%pwxgnt#s!9
zP2fAA@k;Bf5CJfnpxzIh6BT|7SN=QbLCY*F#9{b5MgUr>M4x{$J?1lTMai6aD;2g*
z@lh`Qda04LGHa!KDjY(kTyvY}O#ip`#!pov{78tnEhyq^$+I)RdGPyV&+nhE@z$`i
zR+`_hu-#E_*{-*5Fu-{*oBB?KQ)w=ZPI_=BKsTlLu%2Jqs=Z@^1J3^eEuYTG*Ad-u
znq7^Dxsg;|HH^*Y?67L{t(zcLQA0LCaj$TcoxbJZ)>f&67-~#j_Y>>|88T(J2LlC|
zi8aBGm<+(k^uM&!md4c2qz7#GGvx<xfyOs7;(<ag?d(Q=8yYW3!+*Wj9;L$)Mb?rp
z)3(4fh#1I<CBpJw?j`RYjN=zz0S<Q-cXZ*1CFiCDAJ8+p6+1cE#rS|f37Mjq1)148
z<mW$#Kawb4_-wwfTZWl+en2~9&v38du6qzUk4~bbG8C$N(DDAhsAbm67LO(ZLgOk>
z=OHfv?Zi43N0onz`VLE{cFW7|3R?A`zHz+pE6;f3I%(Nv_DQ`2i8ty)UbS;!+e5f~
z_8RjFO^eh#srhM`3AZ(zxtV%S60_y!@q+EbjQr9+U9vpG+6DfFApn%=B8d#k!tt2z
zR>8x|+w;Tw!!Ek2#xOy?BUx4cgF&)=y9A|GtT8T{MOUrjJfaCzzH2T~Jyp60lS8&v
zuW<|Bnl~cX37Thf5pjlANP!=(YC^{-fp5xGjRN>G2Qop1KtfJ~sjdjqwCIcwTY~aR
z?{`92W4F7IqNl!p8Q>|FD<KL^Fvz56Pe~gm&vqaeVJK%JgA$}oJ8kgMzgyY?mGE!1
z+a3{9V=~Q`7;jeCK{4m~DM7sbgC<eisS;6|m_Z!PvDKq{yNG@!X~pxcY$mslS!C$4
zeGAd}D1t3Ut&rvd6v3gKUzSld0kKR90inizn^ksYL5G!3D&W{c%&E$lSeILhkhD_O
zz1`vMi1(VVLKt2O>lwMqj>%J$sy{Xf+PG<yoOGE}N2nR(b`1tYzR(SmycXv%nX+5v
z4{&8{b%r4!+>`@FgWQ866nn<Qd0==(+t(n|`E=GFo1HkUnQj<U5bjW^XI9n%{nDcz
zan=AM_2O$oTR@G8l|l0lY$%1^W(-JsyN4na3kxL}D6?=22o^Iu6qRtiNpzZ-QD(u{
zMNM>H0v<(@&(eM%|NPiMIlcOh)ICW+R=Ybn*-9X3Tj&gB{b;dx$-$4w)s!vKHSwi%
z&~zs1K@*4kS=)1hZ)(KWkfhrP`tc1@DQ$%@DotZk7$DuH8Em!x?<3jqVx-hJfAwJ9
ztoW>0Njbez_OvW;v8f#|04{hr*AJN@aGJl-U=A&24|pc10_2a45zOUgFl!wCKufem
zI`{FPiMLdA#o?8?oQ=*&>C?Iu^HUI#HYFZOdL@Sqi|VYewvb*$d5f;)e>?tWzdjMT
z#Lf9&!~up3($t1(j<h&UNk8k2R&Pd^Wk3q|VIOvmk&|en&&(l=NiBu`djJXA(|L}&
z@^sh{X6^)`IL9=hKP3`SJm%cC?ygev=|q~t5^F`#uj2;%QLHV4T08LhzuL-GKI>bi
zT@S*s!*xo{ah>VmYQ&HE7_Mz)&LBw}2)`XQi2+(Qb;Y*-o~wW`P*n*}^^}zUDBJam
zY~)c8Ma8XTF%g~>$q;SPGjIQMd%+N(GICix6#(Py8e;T{D2VpLy4+rh`aZQs%?0-r
zTfUnzA&hD+2_YKTr&LGGd+6ZER$PYWe@-BopQRHgDj=ph?1c0HNxI^uDslq1RzA+$
zIRTVPfe$s~GM%7oz#p7Bkd0@py2R2f&Ha%VXOz*PH)vhilYuP&jnSV!aXYu4V=_dD
zR%5Fx*@_N~hml&c+TfIY={bU~O@xKD)$5|hLcH~!62F}r4hhbCER*r~x>Tq+EcL-@
zuG_ecTWofvC;_%Pb*Dfw$Mk*<HT!jcCJKmkY8h>H;Utwg6Pkd`nEh>$av6OL4d_i8
z_bFIEJH$==yO$8i!NwqUTM}bcv~+Z<W#R3Pj|O)^l6a1j7b{lbLBUjM#+5aB_ChC>
z-mD0^wp1d7jeR6x<aWN-7&=AwQFu7(x6mB5ZpfV^S+Zzx8NX9J>|G*mSz@?V2@7~a
zuk-e5%m4K+AUNwA(fq{WIgA4(nJDb1ERGlmN`jjyt02qVOOA++0bB`A@!AmX6)?J7
z?=$YvDR2w?)w+&#qWK%93kjptjHuuw=p*d|lL8Q+ew%m+taM{ty~LD0PJI-c=_^*q
z^3$w$?WK-g_IA7$Ki!z)mVtBo4glA?2<OOjiniv|l%;70*K6bL1)Ap)r*0%d<64AQ
z{92gTye-nJgmGMt^OF-@gr;3;EJ;(G^&=fr0QzA_tdFI-c{#&@gf+f8JfWw_RP}|-
zf^jDIz8#Y>rRj@%q2|?StvCCOF;;gq$^B&iQp0+5RVUFgo|RR1;wOdOHb6^v%b+J6
z1bET{{TVKVlRYNyOl3aES@CBwwWXTfiLKiDO%`>cDr1BD{OC#h+yG&--DjoU$Jrnz
zk@oy;x?Otgd$Ik><$OHdUT5`ly`=efgX3QK=H6>ngIn>1hSqS=&>s^cd#giq@$uv#
zYFkbrjSW|j$8C$-DJC;C0s!w?Qj-uiT0ggFCW~~ONc#^01fu|bSxBx49<iWpw*jZ;
zW3;})NV?5~N!i=vUitlfIAmEI$*U(-1iN}NZWIxJ9r9(i8^+CySdV*2K3+n&11Bt!
zARlC>$>m|_U=`x_%KM-94kS9&Yi}ebIDs4`{NT+cfmf&{xmRpK2S8$G{Q{(dXvJH{
zH}NjY*efwx7j5IP^)Ao5`i~}>pjaa$L?uT8W9TNAFP&pn51aAB&emvdP_pLER$_o;
z^|5OcNZf5?#n`Ae+|DF?|A@{rBHv@3z>CDC4dEWvalv-#JyMaE(&D2n1Wd!S{izd4
zPZVFX3vssh?ZI-1snr&_p{>^AwiW-P3&(H5v0QJEb7DuPLJwcw5VT=1dgYVoztHB&
z`d6s-gfybar#5kncky`ha-hFzI&b)tEf1YX-G%yqE!S4g-ilO?gMzcFT}EkkX3U<r
z7oNcn0h;#+1AO>CFBpIN*BJlX9sAK84L`br^M9KyXii1rkRx^<Q@()(3*6HG^$blE
z8J`;8&c|^XNz>X3kazz?RrqigmY*@|+NPlHU}a`ORd~Er`LT&e5v9TT4jbw>h%%j~
zKb}#)Vdewa@B!Sky1${&`_hheXkt>pGSn?G@-U&@J{~q8ri;7*40!xW{o?zMeIvY?
z0zr!UH})@H9vqUC!k-Ed(u*j3rqitdh-<r#UQ~};x_wqCgn5s#>!Nb8V=Z>SS9_X?
z(~vhn#{C>mgVe_UwCCTp&PNpJ$ix@ZB%KloE9Rv0{TRwKkNUiP-liOmjO5SL!z65<
z9$p`k_(ENx7k6p^_~^$aiVLOqf9x2v`L>l)WDZl=#lWQV!g?XCC{taCHlXKQ)jXgL
zQ8$@qIfj){teS)~v!s)k*p~i3uHGp+lc?MNj%_;~+qP}n>e$8;bZpypM;+U?%_r{I
zNq>3Yb1uH~AEPezsJht~HLB)bYtG;L6DLE(wOq`KNOR18g@D<ZyCuUNmYV%~oRrC1
z*YcxO`-CC>MgW&m8JBAOkcy_X4?MrzX3qGI+dj3-P<=s^G~~7t6z~MqA>#pQuUhCL
z53i+8ZBDP5#Zyt5;Jj8_7g3YE^d@Eq{;GwWvTkp-_#14e^n2=L)D^3bR(0i5`G@|3
ze&{w%c@%w;XGY-BRv(159U?k}!Ts@3CTo_PfK}*&-er&$%}I-Op)`fs&Ca|iTcyS-
zY3kOdsp3PhnSfb(G6218?$f#MnQ%24=6R|Tk(12Va7+`(HM10k3mJhq9TNeyC`~hv
zmK6II&#~t6$D%^GnW%N@g)Ao)s_7&<fm1=HARo0X+l(>G`q(C!!M>^B2Skg>o>X(L
zlO!7+89lAAZdp!;X!{+Fnl5%mL=A#nILJai-i<L&FNUxn2cW<W@zM@{lb&hpO%{Go
z3n*;g*w2HDi&s^5$kbhrom8`NdL(I|Tlo*TK%3OO1|E+wRS>C1t~`&y|IBf_Q=k2-
zs5AQ#m1+csvtZenIylBRgD0Q&q#0S&f_QYZLtwW15hq;@<NQYeY#a=@s<rL>iYK9c
z)3MU@5B7&B89-(HO}R-_wIlk&0{yLkYf-iZW0uW{O*TV_DQ6&=5GWLsVHRpA>7E-j
zH@y+48CDGKLi~fg7xmk?O$=>}vqeoAOVM0_Vk_#g2msZfPJ$jFC_Dt*9DlK``@`rV
zZs$_w4np(x)`^JvNr>w0h0TFr-FzNTJvgF*E6X9;17NIw?Ut-qK*S^uQC?HB*>>A_
z&CrakTv9)P*~JIX<zw0`L7xr_tkTiEFT+QjsZ3M}Q8dxLNl77z7h>8~zFx!u4>VlU
z58)M&%&D#V!ts0T$$*hqoCooGB%@P7=9U(ty@m|q;;bK}O*<d;`L$v?;@Zi3FhGf`
zQ@O+m1h}QdFY|u3*;&19@!|#h#FEAG=v68eO0dzbKm1AUd{W777;OjMRK<`EhM%KI
zneV6oJ3NetQ0C{B#0Ut}Lh3kW4uv2hYN?0#;=$Ko5FDpKP}F@;P%1riEc_rMbjuIH
z95e%^DcFRSKM8E_aDQmJc!G!&8-Nx)p}&?)0ZuVN6Rmb1Hm(>fM9Xi2_0OOXI!$?Z
zbs;TC1#P}S#~r2sW0-D3{H*_eEaPPLrgvI>W$iVe5Vs|-0z(Mw!ph(N4ibF#r7=Vi
zmzWNjB^^k+b(+9ZiGE33vGoOS)ESGAWyH}9lBP}>iwGRs&+=Ad(tmHk_<IZe!5dTn
zZG=DYM!2L`BXyM|PMt$!P&4j9#6dIDrp}>lD(av!+XJKx9wv!P9@C_yild~J%@&E;
ztQLvtLQT@v-6n~K*F@1J^L08U59m52Q`E;a41srfeRLgIjnr#dRKxTdJ6N_cTksaJ
zNx<4qXXw(AEQ=Qf`a$<eR==_TTmZj8R=;!$FV8mCSOHC!XYDX#ov>btv@<k0p|uy5
z!y5B6-VH|gnBFCA`nrtlB9sfhFC0mdQpH)~Y-;kA>^rGUv4ePPjHGkIgLo5+g^P(>
z>=R^PCUSXzF1DGBF9)YdPBf>4wE$!@E`{*E!G<WKo_zZCl@o%5Zs%&sGayD)ubo%O
z&O^Yqwh<9jObMd+;}5Z3Gs&e7=_x<z8gA0wZ>r!RD!g1fOZ8HL+SO8w9VxVqbq;~7
z-7mfydFY$Fy#}$HHf+%NtG>f8?7bi$<-y!@h@{&N*bC#&yF|@hXKOA9cp->1he7l(
zLHMvtHakD8OUs!#iy7ue9e@+JYgpkdm>`1TQY);X2Y>1VvS<V{{vu*=rhsFzhq5G2
z20=&9-&j9^f6mDo&s%++8oMA3yQT^_xA&cxf13}s+eOax+G@5>GLRW#q5USLe8Z7j
zI^2HFiO5imZXdNimnN?uw-$%(oi6q`CMs$QOfAY>?2dUX-O#%^90LZOtdT223Hv2p
zpVi{t*G&CfCGZEEAFdcu^x3=HT^#Y5wmTH4J9?)-z|uLVyjyY*pigS~0{|E8oxQ{O
zH5{#_9gA%tt)`QNDRLM0Q4;?5E49uql7B-%@rJ=@aofd9qCK!O)atP8?R?w55wjU)
zTgDVO2sOM;3<%t8iU5Khtdl@%Gouq-?aY#;sdI<8O7pt3PpnNk6Hzw8pgMY24JL+s
zBgosG)XlJWCjZ}9VBL+_e+KNADm<ow+I<q`St>6#JEWh8^`DjpLlWeF9AA0803st6
zzIY%bERKL3u#0w?<jgpf29P1j`;A)f-)qa<E0-6SmlXdlfTMsuOwZEWgbpo_sd#xk
zZbSN`e(^8%Gt$Ejyv7<8%R}|fatw--!*&--J)o{4w%ZCh0!P+y7H^v1Px?`{KkYsx
z6Gh4R@u=)2=SJYA{*8#-_S+(4%AzlNwZglElqP>GvXIzA$7YFUeTEPt;y5dR&NQ!X
zTy7z?a>K{ZGe<y9*0|#?k_5~h`LT!5&;gr1FM{lFcBfh)h((i0?x`GOrd(e)1OOk`
z#QCeFuK&?47@#caCW_zAU)KMVj`>dH$K!t|@_||p#3<>1p^c|Vgwc#0qjNV&p=JKK
zjuSnl^yZW5kVh-1+KjV3(WBuYdauz7R`vKKb$>QQ#(tw#dD?mKGmtkQJ%7GH^Z&yO
z`1jWF`QX_OI|GJn>igM2GxN(mdkz80>+@riY9<xn+W;ES5;od*k4f~;C5iVB9Q-U~
z-YgSUsru!ts}Z<kOtk+#*Mh;mR^MOTpNR2fymqkym~jL&^(|6<WcS%GwhP+FwXjF_
zeuK^yXSHCuu(geGX}gDhSe|ZW>}Rz<?pGdHSupD6_Z)GPFPGL9vcav$<1j}#>TXHu
zxK)P$JTH&O`Sn7M0N>i8S2HtOucl8cKAC<5>5#L6)?KbE^7{>-(7*1_j?X(~BaHU%
z7(XG!HE!#s3`j1v!~yHyraI1A!CGbMnVR??lLizHdeG+KQqFB#+j5p5O7GW^?`eCc
zg7`OPTbnX{NwH*`bPRM3TgAe8+*kxkx=v_-FkItxnkq3fImji{ghR{n8%du_IvPLt
zZU<oqFG@q*>6C`lbkS1Ft4!?J!7BNa#FwancC4A+oL~3(PV4D00d_nE?E|5FS#l$^
zZmS=jJLYGFe;x6y*kI~J=QVTA&U5mnfD?v`Fe>Ta{7Peb5SK5Fhss0U#x$_o=FuU5
zYfmoN;>wR%_}=7HX-$^f(h9K#tbpHQbzMR2YzLr?QLyD8!Er&%yWl=i4?uH&L=spB
zS>`LSApD0=lV7`R41dyVmks?dQlM~=)QBJOqIU1`qTo|Ta|zQL=0e2BEjEJLK3n3#
zd{oIXk0X}g|1N2&tWt($qPDj?KA@@q{xrtfGrCDxlyzwigcPyG#W8i<Zrb%Z<(XeV
zHqCcQpxCB3a*XDIsIyCm8W)om>PM5lsw8HC*A(lX6IW!@M@u~Z2!qu_Fga|uZ!wNj
z#cP)|5F)PfW)b^IpWJXePXW*><v+};j}@e;A_oP3Q?Jd`oQ9+#fw;?2d35muaCRw#
zXwT-PP1_R830_STUQG&2{Z4(e+(PLod>QS*<~<>Mk%Ie$5l4w<-vDEM+^`Bn3x8~W
z)&Luwp=G&+=UOI{2{(#*oJB!ZF-w&c!_!mq%gqBb9Orx7l<VpDAQFItaedQ<(My|O
zM8^=6piLod<(F$v)D|YQk08kd1fNn9DCyK0OqimA0afN8@rKY$ex~lARh#pxgl936
zV=q#`zpIn#6f!MBz!I)5eYszJpvcVfh6ZtO;5u=G6=~3+rTt*rt7<_Q<CbM5XUF@(
z_SMNta26_6iG#IADrZLuJUiYjVRuhnDecO(L(^OFYZqgs<UmXE0T!VH;N>}Il$kuV
zkPBuN!Od};3s=TwbP7!r5h7zu4Btjp4K{L^HG^xhcyeF^1axF(UxN=BeOQRqFNo*&
zKRjdAepqr%>_(~W7!2sR_>-m&oYB8#C~M)`X05fzufi~YLcp#n+Cai<3tH=h<;}>=
zvqsWmwiuH)J9it9V-SV`Cj4s6HIk9z8;(-Rq0=U~?|AMsE7KE_Kn(bo%wS%$7npih
z_2E6^FFq0vhGmoD-zRc8aHMiBKl*cqljk(p%{4wYDqB?A4i`3+CLoB#Rz_QZvCRO{
zrj))432UP$az-`%76g}I*v%uAmM*bn#L0MSY1`hOHH?$pD7X@UEbk&eKPSCeFcl0v
zI=>r6`>}PBdqo{X6U$cu%7GY~FTJK`23(7F_k&b7qm0FVdtIfY58ZQvFnw@M3u~;C
z{Vl}2EJ0~qeKg6N&j@tvK))t8t}w_BYbvP}KF-`yn#d_MO&E^;&_-dXVZyMrJrcw|
zOZ?$e!w>y#1r$R7XC-$DlIom6S{a4e^@98i76f%tV8FZ^*N*a{Kv0`*pbim~3!c`x
z62{21!jC|7*H}x@Fz73{T4V2rXc44&-EW=;EwxW9y+sBZa8wjZNkZG7X@&`le>&r<
zgB`K*PtS~@wdM-ha~5k?m;YFRx}w_?*=%DgvB=|-na38ui5_1&kN^yN%#g;=brSDD
zNm-h*f8LY4{meV7#i)U|w42I8AX$>|nJ()sHKj!#@5?3AiFg__z;g`mg0paZ1Hq#U
zOX?qaDn4wOeo+0Y46h(mUabWd6~PZ2{xDD#vHXHemN)775!UHt<Xh}Ev1thez!*}4
z#c&cI#9}ZY_LoGy8-D;Zn-UAOJ^ZEPAP4jZnR4MLD-mB?pLoLVIi`#GpJ%wMn$rR;
zZspIjrWQTJLJj1Vw|^uL0Y+E*1@v61eU6f&q1;mZG-nQt1ut6Ex@lksS4CmuCS{L8
zRr9M~FfD~Y({l~p$$VXTaxQv9ACMa^I5m@`WPKn2mVFYv_02yyl6`cqWlo)ojf=KF
z^sA7X(Fn&QCVvAxw$hNt!V%8okv<up>By12`5O_pom~C!U)`EIy*V5HZCr9;>ghT&
zrCxb4`cbFP(%r_&gm$^GS~1%*PyxDr;UDGJ%_-3|CpK^*SDEY%E>z!;insg<8!CQE
zAm#f4^cIgD!}aAT{L|X|ThmuHa(h${4p*b^IX`k;n6^uWnfe+?IBMv1yUC^`DwR_x
z%()1J5F-1L1sS@Jxd$1z5Sf`~bw3S4AIS6gJ)~Oyi3?7C*op>hl$zIpdAB|yt)x?E
zj|G=jsZsr+VpW(PPqaYA&RTc4TPbm9(Qh{ya8y<<vjS^=BkzRxiD;!OkRY7J81x~!
z@b!ffRA#*xGLD?}Ap=738xqaVHt8eBY#?)meFw-b$x;GfG~D6FwaQeJS`fm`XceOT
z9AxkrcG<4KW^S#~cIo_AB9EgDvg^az&%Ep<Di)07<mJ=!OSeqs??S1RIl_+}0Uy#s
zKqMK<bmGJ6PPprattXPHB{Aq0k+Z%5*EwrM1qY|=jbR`2!n5j?K>(EmT!{m@m(mYm
z?9|_m9yrm1ikYw5wWc^AWt}dd?FTX-#-4`@heglmqXz?`aA7@Z+x{U%3)ERdzqjp8
zEU1s%85NFJx-ZoQ1=`3u<>f5GUAGbp0N2hJU{ZOV@VhDPo<U~M93o}fxKufXTTruf
zq((T)dON^#4o{QU4e4&Gs5s&QrUZ%%ctqXK4gFxu@X{!*_R`zhXZwH>`v9ZP9RAdS
z0LD@3LxVIMgf{h0#2b%R9EKp^2}vT2!xP>}Wf+B~A5E=P&yKagg$1=yPYv@RU={m*
z{jo30!C=vrwM9y%>t!jcg=4GH((kvWpX2mRb<`)z_D0L-MD3nKcmWwPTv>@yO`TV{
z^rCaFgH3{R6FY<HVkbsxozWmtpHEJX+Z2xxN~U8CP?_*VxswUX{hi%dD+AWNo};CT
zf~|?JJoR5ToL|z|$6fkAFzGg9(2xJB!Svfw(En(`|5pq;l5u@E(6pwAe^)(&!?;k-
zVV&B~Z$%N=S#8Tb|1SUfR86TEo%+e|k>j9D4>rijpo;MtNm@Dn;EskKF2usa^B*m^
z_zI5_5V~p<{hV+3-9bxC-lM<yQI<Y=1fe#gAj*bvbN4oi4xA7GY=ZpN9h~gD0Au>+
zm%ytU8iK7nd~q*A1BvmP=}LBx!9Q~|Mi_X0&xExTq?EsJAc+^NdK3Li<xU<0B{nHW
zfobVrO~#=#nEi@%8UvU17B_iU#u69TV)17{@GFD$%1_z_I41+)Lm*JdC?Go^fac_b
z_rLa|OkoUo^hJP(k`d(<0s2fyJwT~fDc=Dn)8I(ww`Os8perv-e+>2!N#+W7ll79K
zbYGxGfgv94eNr*s9EKpzQXBi0ciD#vx9*N5d|r4{5W@)_AIz-r&nE7o8oh&!7dzz9
z;KPWu5Ey!C9zqPOqO1}SYb5EH9@ycbkQq(yoXIe5D;xlrf#IEFS1|ZhrUe*(vH(TM
zmC7ZJafI@1sF1BwT*Zo}4mYh$va#DzW)}#KyYp({M0po{LU3=sPryK{2lK?CVI~9k
zvy1w>{!zxc#g<h$c{oDGlL;<i<2u6h@1pgA9E+NXdvgPYo#<5TXV(J9=&=J&39KV~
zQn_aSd?Y}SwQb|^s0yV&Hta4m4dnd-_$dK+A~Fd6^)^By&z@`-8pR2Pvh#>VC}NoL
zGU#Mr*47pjy)E#%>AG@1n(|ft@WK7V>dQ^PkBMZm9RruaYe9c<U29scc^gc5UkYUZ
z1u`%xY!&2J*Y<phIadK{S7<7wwm%NF0I5gr4gsKZX<&TfZ=`|slIEr8c&C|G(&_**
zjoftDjoLNd2b|CVaxcSPxko>;w~*Zj8m7FfVQC}e3`cU*2KA1WdPU((K@+AECFpd)
z1Q+NueO!^ab;_{%A0_m09hzEw1+(e%q*JX3um_pm@_8+`6v7d$eH|FZ_K(mz9rfg9
z`bvP2V#Xwi8_}Bel~?b4urUoS(a5Xy#j-a|(n%A>DBQ3co1W~uo{nVPttbf?u-*Kf
zIJ?4oXaHJCUs~FKE2YX#7FD*d#Pn=Q8BKA<KpC=zo4cLCRHEx|<xT7jD?;Ti%OW<+
zuS{+IcO<qt<uHl#P_Rlm8hC4UkL`ZY7E^$-fE4NWB+Ip&7jse|sglbydx3+e?SMxu
zte(G`llGxdE)2h!=rWn0_qA9v4QCb-9vY`tNbq{rk?deeYihIGlwz6$KG;@S9{{b&
zfod>M5`rMWzU_qxAJsc?f(2GXrE^RkZ{rwmQkHLEkfgo{BG9fy9=~5p1;(uIpdOI-
zfnh;zA=o|<#j0FpXQpXq4ZEYq*ji8Sq2(}HcSIVSo>$aty@ls4kb3I|x3{)j13HTM
zOnp}=;LARqsRQSU>^!YzCj%*BE5~m_z7mj4Cnq73C|WDFlS0!&_fr$ii{9XOV~q1T
z#;ZAP6of@)dj^j+o<-bI(4X^VB^>}4fts7#LtT%iw}tbntX@eSaE$V<Sc2e=f&9#S
za%q<Js6?c4bh%2f8#$s{e3(};eV0)|=QQewb=G*h`Z#4rMKSlXiABj<K?F$9&z=cu
zgD-$Gh5pEow}jO>7oiHcw~Q}5YI8(yjAma=8Ed48f_;}U9qDvXL<(SJodMwHc5yb%
zpLB?vQ5>Q^;+(Ln7f`kT+J8`3EJrs)E;wFEP|Ah2gMX?RqkD$0@sh|{7purM(1Dhf
zU<&od%f6{mvn<$buOJaItbETXVQ@NM=FgVLU<1;!)atq3x}>7J)KO<EDhPg(+Siyx
z5nd3|2ypv0Zzcaba^|5Lc?3+>PEpzxrK!l<<t~b_66$-NS}xq=^u!NC^I1ifbn0+k
zFLSfOx%g9%gsPeXzRo*7ICN8!N?lzk*D3GJl~hDiO|8cD?`6UQd~%%uH5YBpc^4VC
zw*yjilnWY(w^M`VqPkvAOp~Oum}$6(Ezzud&J>>H9r~gtHoY=Ma)9dQV4mwv4a<c&
z=2dM?Gy}`_JX67MPo8`>Fo{Xyi~dBKX+1$%C4y0N&i;2DgEd(Os{$emN>)-s0<v<l
zqbl|3p$PS$+T!Q1qdmY|qo_#Tr_z9`MJ}cjpLr9+FEQBT*`Ug<)VI|)snxS{l6m(!
z%F)m{qaPERLm-q(9stq4{9w0l0@OmW=Fr~J{~3mWiDD-KD)M&+0v$<h1+^5-sl{OT
z1cqk!T)&(~2;R|MtZf|8WIt@LUShlCurJWrp81s^O`;mlag)9y{vg%tckT-7&vnTU
zm9I4+w}zhD>(G>q?heqY>qu$Gj-0k(LfhD73%a}MvtaL5H^Bb2v`ELf?!nko-j={z
zZYSwz+O1M+rwS9+ntR!%&G=0nXIWH5Z|3^k@7guJ@{W#9xl)@y#A`V1ivoSQDHPdk
z_DPouYuxpWrM_oh9XAY&Lli4A&(|HfNSBV5j$4rFS?UKCGem4e`5gUVR#MY{S&nNh
z`57twf75h!mI4@tJS{J-y=K%aFPE>nJ!h8h?T<ym|1z&Zh8(kz5+lG>YY-xsEO=7j
zB}!^+=YCu8c;v{pr&%4MaVB$Em<{`(y~Xr~Jna+BT$|rEw5e<NSIclC1pDNmcG=tH
zCNBWX)QNdKw*6hosF1PTH_G_dDl(IXtA=?J)kD7ndjPFb&h6!DMeOP>cbodK3$zUC
z424D(l(7u1u~zGJiAg+bZqSF2O{%q_PiBUYyQ|F3X)=t&8_e_Bi0IoK@(+1ok?dOd
zl+l}+<lb6?LvF26Z<XFh_DVmb3G{+~O#ki-E!uUfSI@@^`EAph6v(6MaGJ}Vz%Ur%
zOC?*Cx&w&pSSLHLlDd=U6DT?%8c(U6%duR$ETd=6rg@)yPUYNi+Fgb??B7nwc79q3
zn=nAV2;oq7P-K5t7C#jF*)SCD2I0wO^!Jsx+{-@Q5Z|gIl%8?Bd)_&NW)S@WZj{?7
z1~g`{Ed>05S86tBU(N8<I3_-;1$3$fw0iR1{T@#VcAEoV(4{=fbB8};G*WQ3Q}FYK
zNd><6zou;rP_F;+Y_oFx-+tdWT>X&qVW)l$SsT+6?SEC$+<#P(#g-h9x%?|YMvyTc
zO-3dzHxo2i*hyZf$N#Ws|3Wxy{3}spUPOk?hHc8|vhVNHtJUM{<mAo0quY<gpOj)@
z=@)%v&PA3#{F-454gdLMQI_SEHURQ-Hl@~pHpHKPMO(3G7R2`Xt3Y(KskphOcmFI1
z*nH9{_j}9tPt1|_M(&{_OKH9;a1SoCVBBB{m=Tcpf~R!u-Dy=&D)$Gp=Fd=F7~WCT
z_<57G8?S&F5hUb9?zEt&s4Xf2dMC^y8E%a<wJ{h0gJ6A(8%jl)1P$<5Ye2x)`*HmK
zYPxw!{oq&()*xUo@?1rRCuZwrf6}--2A%5Wad&@qf01O(*iHbCroE{JCsuhdGC}1h
zTC9S|T&O8w^sn1QX&Y|{WxS&k%2TnB*ibO1QmL|axUFg<D2^Eg8%+}1eMRwjESzy{
zDc$q6EYy@D$zn=k5Gq-zQoy5AW1?`QZjuz_zcgdOC_j9_{>Tf^&H`w};vtT*^p?FE
zOId8Hlltq`gi%t#9nW3dL{(T2+G18Ed7LBni*YSiBAJGts>#9|q+73CS<{D&Rguk;
z%Cyw|UlzN7crmw`WEU|C!RD{>T~l*|eyy&ri2N%Ur8sKOJXmpWN&qb~I_79Zl(f2e
z(E+oHcX0_T`f+$<7CwcBBT1Dfii9_cKAZUzkGV<Mh(uy!_VN#l$x<kHEJ>ju5n`ID
zNLEfb%a9q3ZSz8h2@!36`xKW7*sWyU$SxX+Of#DCXUNo)C39Yy>Pepg^l0gMu@^VV
zhD?7*!1Rr%`$Fjy2Vnc&gCWKXF%Gp5i`KnK<xM?7aGcj)HPye&uKYLk&ZN_Yv5Rjb
zIb!VcpVs}3-`mm*;0iU#jjjr))jhe=lo<NJEkxl_H!k7|iC*f*>L$4ntfezerE^$z
zGRtQL$DuV%g5eXSQvr0$46CPix7dd`<sazcMUNzg=l+<3NB}bE4&FHidfY5I+8;BS
zpf>YAW`yIUOdoHlIoAGF%0U=n>!!80nvS$G??>`T5U55O(o&R|IjpNnEwFG@tiv(?
z_z5!@Jt|*`7fRkvc0y81bC;5iW$nF>#T0emHY|n~GA~fMX2!UXn?DI3ws@L#HI@zA
zfkl^x#|{5BX$WAq<P&cRX-!{5`?6GAWB^2;QHe&WchZgLOvtiwRgC{=>!DxjOq7OP
znc<9*-H@Zmg=%?$>k5I_aoR7h)|SmJLv~7jm%+mF2=MpksYu@%pSPVkHo%Dfirhu{
zjUdy@c=Ne;T!z_YQQsepbi^RnDcJNFP+=$Q4B2B@RSR&inI7a_vn5ov03DYO^3wa8
zYq5`z0WQU|Hp>%(jaK|LejnS}G5cFtdOCAQmq_>5(VgM<?CPkekR0NfKE&wcV!{x`
zST&)!Uq7L;Dxk8~2!EO$AA!|FW7jIE?&?1s2S#h9Q=@5h5OrHVGjeWPHQ2&Zh!yUY
z4an3g+AIOKjEX|`NRxR(w#P~P^X5C+8~uI%rPecQ^{7O(@6q0^ONR?SNW;YM)lwBn
zPQD2EtaCj-eKMOiVoJ&{55P!1|4JOy&rsjDPsD^Il<J5>cJ+xvMziM;+>4Cc-77h}
z{5JYc%5@#)|JI?ZT#5}w^0Xo!xb5?{GqiT<XdeJ@2}|_s>jf!2JTdY60sfJS>?_yJ
z?bj+ptyxgN&r5~6Xwx#KCtTFl@<F%xn18YnKmPTt0h|<nb=!V+9vaR_p>|cmWO>pC
zzZJuLMMyYlrHqmVdYOnG=hn52YQt(59Z8q_!KJGEGia6u$H*V4Rhss?8)kSNs>5;e
z&Z_|OX#WNm_@}G0e{`h=4jWFMXR!1S^SnyC7+!Cx$KAc-ry{e?Wyitonx@=2h;D;m
zs$H{>CtlI!D!uqr_Vx_Na8_$iUAGlXj}24nSrX%9&i_%E`a_?urp1QK&{#UUI28*L
zJt$B14uaeO2S#6|W-e;e?l5PQWA7YN7cmZ)MxU83UMp(NO3b(WwSISityTNQ07Zya
z_J@Y}f_rj5%Z0JuA2N;qtv(%x)`sna@K=Ct4rVo8sE<(cMMr?mmYJ~gMXlGc0h*vW
z(>cj_df&NKX59pHEw)EsVjepvsdi&nKRZ3HCF4x@0QKnFVj*WwV}-CoU+<D-pNk|Q
zpazRu*fAAjpQk-V3dr(?Q%o&*5Q(7QNM90`7?%$bk!PN#IfcuBr!mc{xkz8Uwn8D8
z_hGh9=3xFJCfLydqk602hJ@NW6OB}jes)K;;3>(wT<spFskeZU*b`bfwywLZ*cL5~
z%*<~RcM<1QUftFPrc-Ez-!~sur@IBXf3DTw(zjV#>>uqaQK`q)T6S$CccbY{$1pm`
zqXUV}f^@5-<;qku9&EzW&9NS-wb&Wh&$ZQ!o(!bBhO4n1bjN%ulYCOK4YXl{PFYvq
zv3}mV@in4KajBHWA$d)+++cI2Oc^E$53i+Fui7w0bm9tCM4_7}lLX{r7^eX`3sm=W
zRuZZ^k;#|$-x*E+`KQ0-`tCE%phwovjTWBNzUu*<2GU)(=B`{f96NA0ZA?_8Nu_3{
zztRm50@g#_9se~NXmRwMUC>^oE7_GMd}q<gvn4CL7)lY1w8RhQCKx+`HHMNTQ<My5
z{oI79Yqy+mg~bim4-7k!GOB=$B3Wx13mh9;OWT>ZSPTJKTKWt(j`}A_*=^X?t$G6v
zF)$K+9jN0v)fzyTDnGC`7X$gRTK%}H1poHn8Z};%WaJI@Fc%EaL?*2cX*S%k^3DdV
zQ9~+ONZ3Q+L}zpPNtSTBA+b7K(TQK7GYSD3FbEL{p8aF$g4`f*4-vo-1YtK!=Ra|U
zShD#g$hP-0RH_eq0NnU6%tW{G7~7CGI?f}5oT~V`rB#N}&u%t4=GRbpGD|8$-w<`q
z=YcYtnZu0rs#j4B2G(_nony`ARGY^$mqIt6TBpPCOjNGrr%!~)T^UhdehTvgPw0El
zEg<pDNZnfK^FgQs(;u|^f6Px@$=~NB01Mau%k-A1-{eI3E*hO8XB_u{1R+CifOSLq
zw-!MQQCyeu94+<kk_=l=M>d*I#_h@_oQ|Kc5(G54I6t?T5rzV4*t*y@P%k>Z;4was
zW`&ZUnV7a`dvD`Z4l2yHC)*dpn6G&$VNtwZA6B7dLwRff(2g|wDmOX%4Wr=cJt??e
z1pN7N&?LVc>uEH=HoD$CZghs9qTY00%DDM03vhP)>CM_P=l15(pDQ6c5SJcqARH7k
zTq-PXR=_!|7hW>MBFw5@6xkK_)z6l)!2an|&7hQjH4*x}u>1ske9NBe)pUf5)i@X{
zjb|fIkRKd?W5Ps54<p`6%!UypqkmUlmx2y9_`?>Fi@HA6EFu+7bIGU{I!V~Xmb{`X
z_hUFzan{BzKPL`{N}~hUM7kyrrei4vqGav^d*isDrsqKt&n}Us(0;~HX2|M#>7S#j
zunghixxE-io>cL{$ZCsF*s9BkF`ZE^!PihVD3W~wBEQ>{uGkC|r)MDL?0o?uLWM*q
z$lIc9!x74ytrJrl(p~Wa@8mJ&Q9-d<c4#&ngYDs51nIpBG>mwy8{2LD4G0r%#xtml
z<bKQr4?ao_Pf{=V0y$BQs=?B_=ELIDX$67b$W`OBO$F9dw(4vrWDa^#-vFEr(f}^h
z;#D93+H2x2H;~g8jPPPG0tkd|xAbHR1ct<YOL7pj9xm{ila-lu6<;G4`*;rzOA<di
zV$^oz4^#hOk1Dk03T04%65$(SKiNn$vXBH7KEZT$>AXBr6Weklf;;VeVpuURl*;*E
zHo0<?q`IpnN#E}!Nh<blGO(C;7t#?1P$j@`2GqlMa#QOlIJbBWH3HeJ40_LuGLwW-
z9m+k#XgDq9{yIfOJmBkz3_dNxlP-&J0mFWjqkNvO_yzs07?wJX<zw@xVogOc`xrMC
zjbeLsg<_70q1MlmwWd19BhB6hn)J4jOtLJ7P!4+ASU<0v#&8=(>oAEL)?rl}9Yg?Y
zIWsvOs}ft(i%hJj3`He<xU!yRg;eRs`%!ZGkz~D#Q>^ujlats)k4y+5Qb)s6v!XA4
z;|jL9|3%RmZKqM{!X;&pT;<Fao;$_U@>8fJ<1mJXj2=FXQhLV{a4DG-eZkqsf4rZF
zj*E7LS`Akv4aZ_)lseoa+5=zrS0x~7Y}}i_L;Q<Z>erANm?kOy1<P!d6&{xN!K!|T
zu6d@7np33ZpqST(wWpK#IYy4HW8$m9@06So0IjNA8tJr`1jpoI?uX)5+5G|5VF7mQ
zwQi=<6ip`TP(ky>+cA1GE(wktO0sI|gVxWm4_P}tzDWJeJlP@-QCr!xH+#T5*N~K0
znsbSSXQEVHt|aXh+lLC5#@&wqg2*ddL#50%5>*p-!-t6SV);v`VlE3SGp<_ejcsez
zo3PwiJ%%UH)4PhYLcuC~L%3~x10JE5O<}K<$!;Zqy!%k4Uzhl+`%*==aiadho&44$
zm#U&@#a>%LRevx_1gz1CNg)7k`Xv8VWawAqAEl9@%L65KAii9|{kUO;c8e!XRkvI+
z&HS1o37$<eJGMpvK6NQX)s!2hb*g2L=kUKiDY;8ip8hruXBXNAeiZ1iwgHf7Mta=?
zM*KlDXQrCRWd_cZ3!~P0<YV)lcFEW!@GC?E`&!><d$dt}aC-5ya#X;+7+Pg57&9NN
zF$su3JfZ;Y>f3%-0CzpZ3|%SSJ`8X?CvDu1#OBP4KK$QVY0M)2@9O25D}AJ?yqQXk
zuHiu(Jnz**m5ty@U=grUW{Drhhm*u%-NE-?<v@tR7S>H~Jo|nm<jo&bL=Q>T9X2q5
zrs=NeQ`cB($9NfJ3_1X@NCTzyE>W~N_hv5otuh-{gR)O)gw&_~H6MDk>86`0dvmo<
zmE@aXGhzAP&>iMcsO}Avxh*t6=@rEe-UN#)T66DbwX<D&cH>Q&5K7K8&7^XNq|VDx
zL}F7~<ITC(H|o=p5tu^JoJ%cNrgg$S7?~w`!`drr!rk3RtOqD%zS9k5NpG!DnKEoA
zbYht&O=;xHv$fwLj#xbfOK`~X+2Zig?<xuVbMHzd{+z_|xdTx<_u0ye{c&PFfTuJY
z#R{WWS6<@Z<7S!s#N@Q?dI^fe(F*S-k6x)AI=MmE=lAIT^u#rSM$9{-A2a+;*wJ&~
zF4VH-LH=sL;%FJ#nrq*w3d!Z^YiHG&*F9DTDV<E~$0C5)QrBp-E}_bDeGpxDz3^2C
z&DIyow%zX}7SnK66c|1*Y=lC6a8qmLcWOr!&7(C{@qzNI(o2uFo1}v!Qn1>O3-q(=
z;85uwxIcHZ$$$TNU|ekfTL9qxzqGt>7!ElX(l-p}09v&;bR$rN5Wx#7Bb&t?|0N+a
z_RiwJ1J)Q)#3g>2j!&E;#!CL+OC=X0&8I$>;rQf<j0^{uHo7#9umQ{8i3|64_h0>Q
zU+*s-;sN6_PABcyix-<m9EXC<An;IzLZ5&00XcN<rhYFFF!4yUdR|+T5~6mPocygf
zem?EgrA1vw{1MI!!CL}j)<k-r(TbYaDtsS4i1BbrDM$w!SkV(sj3K{jI_7m3SYBlW
z+D(~~#NRl2X3e9G8x*wgX)lI7OJ_}+WF<G5db_`@-i}*%PiG@({ysdcy1_EeE6OAA
z1LOhn#_X;eNA>^mzxY0VWU&bUW^h3j?S`7_LrWxL%-^CJm^W=ERg0e&p(OD@7sl(T
zA5ixlp6bV`-PoYD#?h2x9gJr}<+>2}FmRjmv_(4=PNv1wH^*!>lm{s`OzGwIc{xux
zaTt7eO1w)4%#d0jSO>X8(%h5%pn))%fJ@rnQ#3jT8vI#Z)@Ub18Cdexs|38vcqpMS
zhpiuPONi-!W5oR=Q%qTysk~u}zr5A+Gqu@N&s(#kdO4zCiaroM7rUm4w!Lim_ftYF
z`C>%l37s&1GjH}68;$pM8hTr~ZHH5=ov~;+#6Zf(ojHb?PN@n65e{z&*v#&70NADA
ze~wEIc5&$Z9p9W7@MI<mjo8QaUsus2gzHZ<;~1Xb3}X{#dONW!elMk^jrw$W0h(&(
zdMFt=bHzpCffrbF<=ojXZnyO0kPkjW_^Jsk5s2e>pX#guNeAW>zs)bH=5((N&uYdF
z-?i<sz)JY3`!E;<6u;PIn59CW0k%de8^F|@e6Q22pWHp@^;@@)!kWE-77bCH`^WUb
zMG^_-5Gk9t&MT$3ppTrIFZ7_`&ovKS=OrAybyp1KHk(=q_Ugs-u}>)JI-JvJk^SC-
zM)fUG!t&sf#yPdnZH-C;sl1oJKv#%#kj=`YpZl9@RQYU1Y?m@CYU?!Q0MWbS=N7tI
znmP31Yq+3Pntwbcel{D{N*p!;&lnYRqbHca1bJ0iRQv~4UHt?)RI&p4hb<T+7@tci
z?F%4v*1MJvry8fg&wp?y+=W{l_z)v2w!U!oPcj+7!4TscOVPS05y<i0kj?Fi6r}pA
zbc}T+%3jeS+c6yP@<x{i0y@y}fKnAKHLXtuXPHesf4uqhjd`)3$X-y-d8<F8QBt}1
zi5+o9@HGz+4}Nx;prTWMZW%gOUF&WYZYIa?u*CbW@S=NiV|a3-JiAY*xJ=UjocNJe
zMsoI&5oZQgusW^~e-R_&S(^zv5^NO+dl7$s{T%1X6}zsO>Yu)c4)Czz5L!Pz<teK&
z6se_BIRb~s+hOsS{Mum#XMNG;gW~TO(K`vXSBRb?($HyqCD9o!p<uAuLz;W#5A4rk
z5(TD<=nndUFc6Y+B7QcOH<CZ-xXnrM&bH}I9#^9f1$iR=aqY7N(4hK2DjhwD(Q~bl
zQt+EZH(nBz@6yL{13u|R?m2Y@`_76P>p)&Nsf~_|q+Y??weBF#31_kCrv8T5MXSlf
zwrh}Q@E5K9efdOKufj-H<j=HA#ae-btOm-tCgGPokqgOR>3A}<Saq{ic0Uz|Q9ZlU
zwNOPe9C)0BR<RX<KpGWmjt=crinX%jcKYr;5mEP~=lfH)0{jg=E?c$RyXf9?^k-B_
zS#TWiY2m!^+TpWjma}J4BjL{&+@;p)x;coS=C4c~wgWS*rRq4c)4=9>Y)3LJWekkY
zPpEW<r)QH5YO#P7m5?xp30t?;$IY*`=h>9Yc1!K0N9TMGKOK&VVg~AmY+gbVm-1yJ
zUrFCVy_miYm$S1=vMmW8dJ~5S)o|rdny5Qu1cFLIv0eMp*BQtTwcG$ayOgEq;Mo+!
zr<yssYCAVj+3CID+7<}*i$CEKg*$=p=SX`+fddqi0TB9)$H+mG=V`EDZo)nt|7aA7
z85Tom6*t;t?R>N?<R!F?SE_#0W4fN~VfLL;NmNE?1Inkk&J%T$Aoj<@J`Js*m>KPy
z--XQ<nQeS&#j;4;VqlAVVDmurU*gZDA{E3&FDqlbpl;&UPq33*RzNx+fL5gFC69W(
zn5$PBNtf4<BCWn6%<E?pke)BW1s73o=4VSWp5<0u2Kopd_qe-%5ic|vAB+4kvvjG;
zQj59i019M31uG6xbE}8S!Zk)-w?N?KJQJXaEyKC<W=#|ssN@eqdsUsuyE<MQ8cLus
z<La7r71Fe_BFEM)_Kfz`KEx!!$aEJ;Gs4}mybW358KrdwO9YZmL|86*rPJy|+}ao2
z64ux~z9kCltlTVleBEtdjz$P=0K_(hayrU3pp%iP($4F|-Fes~TK6PNb@FVJu_dR3
zv(lnx&DzO7MYm2sc3B`C{gw2h?il{#SiENpkKCw+C3MqGkshZAF-X&yv_wF@=%GI$
zde+Co`Hg`Xv{(ot>43p-xzpfs4D!C?Und$<f7)oeT9Ra!CHHE}i$`p?OC$t~dGpaJ
zp!F!$W!g6^<2J9F9DSJ>7uZp*$ypR|(Y7}|8TO}Ml-8;_x|2RV0wMdUc9k=VeMPT9
zN<ex?_<E(JrS?$`>%<^or-XXi;fFfol!yM>7_<e&J$D-2m0qol<xj^|Og|k=M?LY2
z30*xTU}yCYV?FVOMWafF*I|aX5#Q%4fGi4&ROh7QzN3NC#3d@9mj7}^R>q@o#s<Cu
zh9AyK<uu<q_!Oa`z5_Yd^9WQaWR&`{@yhC3Ge~4Py)YzgD6ed!G`nwU^kco2=9>Q+
zfvV>kE797ebQr-xTbURL4?Q=&_tyNxyPO)L;3e~~_%Or7W=?&^#Czo7*gr?20InL=
z@1d%&0p1X<+)8y#kIes?D$v|~PsYl>{q~)AoI+BknLKmRy#GM*JqMOqzbZ+%nlhNa
z;9|CD9bt?4@iiJ61h*eZFdeM%G>1ER52y2gn_viDV%0WJZMYnY4sEmM5y=w%Ni3@W
zv_&g(sw@@5b=)SP>`+fsirXB$Lk1YgI5lRzJ(l-^g8Xf*{oiuH|B!^a*g60Ipuj8r
zNr%fe)NSB5D6sbC6NIq~CIMp10p)Kn{gypn_LQmS>t{j@sSbvW%+*8gMJCQO+_u84
zj=Q!-Il0fP#XdazzZcVC(^#WiBL|`I;NGwcqitY*Ub@hi1bt3zo_7y_FVjNZMrUX>
zhuh7^TRgz=djPGu--|k}KCk}YeHSI{LQ@*geK^mTi$w`p+zb4X=8z8Euvxt})67tp
z+J<h+!avg8p{mIF=iOVdSM10X`*B!vj2}w(5&pvgYCN+H2V(=nY3=08@!j}s3wVa7
zFK3LSxM4df!>k5x3EX8Pvs+e`xbHJ9>l`tTci%}1c^=u}ew@pvhgo1R10aBL;>ALz
z)YIp6)+N#Bcz?61OE<tUg{}I#=<((I`hK@);I1<6@HkRYVb-8~oCXi9_TZ<}=@aD&
zj#WF7ty>AF5mgA9jI)tBZ~}p~FZ|<P?bcYGSK_D~)p}+uLiD-8xK&%os$<BQDRWo>
zIRO}|+iCpu9(_}7EJB+UiWH>|S8($C8gxrc%W}<dGhjh8>bMn3RwmA{miMxsUaC&D
zVWAqmE=5*cW1xg`jN=^tU_ISv6x>Xq&-S%NqA4U4A~b$9(*3(K8?zIUm>w{U2{isG
z$1u^huGm-4Z4;I)%GY3xIT~dny%yz#J_In;zkM#mC?K+u*|BSX2_%laQ|wOMCa{H`
zE?_WsT!$<8Bgz9m_W<hefoST*UW2r<u$;dBcED?}Ty@ie{0N5P7GM#D{XLyF-^14?
zugbbd)_{bjQG~D~dg&TUvTey{luqfnG-C&Wo_SeKtMJ+bvxU+f!kW`LY?U>{02MI!
z7J}M<N~wC=p~J-AEbP3s%}`6>Y@_2uBt-bgYaNu9Rx;epE*J3Y1<E&gvSY1i+7;fO
zQeRj{wt|GFTLb&!CKNIzOGDCP<b{fNa@0Y~5b?}G2s|01)e1@2g;~Q&sVhuBWRfBK
z7O$hH2>9E?dWZ>#Xf>BK_+-bmbqy%6;<7G2va2qvyH4R_L!`0Eax_#B$N%E`%@-$P
z6%crT1;xa2D;Gv7En0PH(nP{{Xlt6wAg+NlMCrlXVr}n^Bj6+0f5%0182cO6JZkfd
zGx*&HjbqPXiRy!PN6{2t@0z>Fer1N$hQODNo0kP~%@7+q7>mNOt+1YWFC0)OW`mZ7
z!~)X*?UaJ_xvbxerLHD9x6gcV^e5a;usI{2K;Zm2f@rf~bSE}%ZDJVbZ%cD8U4_(x
zHJf<8?VJ_zJP_|;y%N3oJDj%cF^U=y7x4?XT)SI$3p9_7Y^;t)M?XhNJW2Tue<}jF
zF@6YxfUAn1CpQt*q|i#fAp;QL2okX=uKbE<W^D@3a-pQc;rdIV_bI{WaOi2gWl4#q
zlE|Mh?1g+zIPA*|o@%8mSwjI{g6)_-%KB78ACs+JQ^K@ai+FB!nTd*sFh@zGdroj^
zTansG4#%(2;nnTpZD`Oa)yluX$g8^h*>!eJ1Z9)WZ8h-umO%G&+yl@?eW&cfM5G$W
zYHz{EuJdrjkafwDWqwff*8&Q$>dl!zM<lM5)%Pd$x`%~SmSRg(*|PXz)#Afg*<Ty~
zB=<J83$f3#JiJfQ-L9?dv(;0^<b_$5+MY{t|9A(JR+a6Qr(jFV1OK1<Y}2IP<D#p^
zJ<GFk2UuY{aa<+d$l!o-FS{j1VpZnPpKu<5k$**t6>*RLD&|SLg#qR>|KcQ^@ABlT
z7`dH<7XqVa`158en0W8SPGi1`*m_C-=fOPgr-YRtXs*gXF1HhOL5_{ElHQr*Vy3(M
zY*L}7a?eMG>eX49tZU!vweZG&__t_xQlwgAG5RlQk?9El103-CobFC?8khamLX$K$
zzX9!G!;~Ffc~RuR@8hHoRKBX$5S3qNdYb!{knp4%oLB2h*cWS0!!x0ung0;iicq8@
z4fG3<N-d~=qAKE3SjrnxR(Y<yHPIiTA`ju8lQnh@RBmPN`!jlZhlV&*@Oe?)VM*w2
zP(a?4SV17bL@F&K%)jTJG6wOKD2-@d;4fD{{-49aof+vs1*6N%n9`j%OTkgP^StOn
z`7m~tY0<7!-XTGS)0H`!OnDl1l6XB`k?Ug(EHoNqnUYItRa$SD+yp`cc?uOq?rWLX
z<Q>-Gj459+5-IL{ofYycD4t4lIoZModS{X7`A1$rX+d3OYOU>C>J7xP)U9?r0f!V4
zMTs87zLzV+v?{a?oi!Cdn1XvNW;P-dX3utKwv1y0rQPn;RoL%f3tSz8)9NN3LYEos
z$tZ%EQO!kpGZa|>!)9sk$tER|EJdRHZ!IrOmVmNco2g3ibRH#triELV;E<WJ{?*i;
z`aB;1z?v+nW9Fb9Qf5znWvz^2X4)r>=+wM4E;*P-=eVr0awfZk?>SD)sFJ9bu>tLv
z$l@Y<2(JWcw5jYRze~pX2$p}Ewy!S1j|g+C<*;`)k5CdZoJRV0u6VFNJ4^Fd%+-be
zuM;U_<GUyO5K#a6QljHva-nog+WCQ_(AyC}kFAGRqc^@)(!D7b`h~Am8pdk%Vh)kW
zgv6qn9I>t03iJ9OL=69~>5sqy_i9ttrBzc*#atn>iZfgh7GAZXZ2l?V>9a~(PvFqS
zSN?(e-bYNnQMaZ@+(=CpRVscD+`g?!c~6r<2RZ;$Y+)!(#CPKi-RdjDusi9Q@C_Xh
z&-0M3b@nhJ-ziI<1$R;*1GrQQtEW`I=e&%Wf29wqd~rjJ=S+PGn*3pKLF8gsr6h{=
zb0ceI-Fh)|AnAhxqJRp?4Z-J)G5a~sUN^sfh|R_@D;L~DJ?MepWD8<>NhkN;O@WIh
zZ#{mfp6pRm4<Xy**vXSK`04|Q90CoXEt8z4fst~i(9m1>$M86r*&KY^pDj6;iN-$)
z57EG-fUHb15#(mnX}F&-5YK1xllV|KG$k~)1bYxtg!9Y}BkIN}+9l0_o&E19ymG@1
zX#HD`idpmICL1PQ-Ye7nx5szC0=3?B-ljxm4Nd*sOj#cFJS-Nq3S~%Tu0po}&cEp4
zS`aP06t5{Sj+_8um6e6I^IeSh2}5~J=MaxCGSBwE2jvBRuMt>aC`eQBUXWGT%g{M{
ze_U;k+`+_os3n8<UvVoa^WnZSCt$`t$`?O%2MYMy-PS!AS8Mkh<YH1i^ziJo<5K7y
zRT+r>SYi()3lCR_>|W=uBHdR27`pnWtO!I@i7Z7*0oH@(i~S7Rc8Kx`wdwA-9n5Ma
zk)OgGr7EM;-VpvB3Q8^jU(d&B`3s2Vz2oCmY>sQf5KguK0N{<QA%L85kg{Pm&UsZ7
z%XBuk*Oxlx!2dAxq^evT%4q+yBs#@%`RZ#h-mQXb_`QL>F*>K*2Dr5~7aQapla^T#
z5=nrbfv{Ps2^F^j+m)Pwc>gG1>tCU0CH=llcr}zM?a)aOLBNfkFfx_7H&&h#`4+*(
za<>;s(GHZ~b5x9BHeJeNW7&>Q4eQuRNhV|CLyha3dfuT}`#_AlPE~!e#b;}6N=zo`
z%$4EH>gsO#8%%Ah|K-AGwKbD~Vao*Wy_B+lQiMzMWsF|E{6~iV%_-SiGIDcIv)h1C
zb8Q*wD@Ku#a%~Tk7@L>dc&7|IYN<mAX+M%)ZX^;2H19YGoMdB5n{0i}%Ky4CddHmD
z`mfMUH`c=Wwo0@9zri_~_>2F*hO}Og#Z$#=g_*;_?1OfqW@=AKZU-M0JiWfn(i3PD
zYJa*cSSQ6of)XR;ZAgR|i&C!jsCbFK#H}o>zBB)xpR02>wq9R({$CGUpD)pu5LS7<
z^8&qYx-50#R2cAt{D9Z{DV{X|)!|^d>i+z`H*CBwuM9^s95xYp9+MIk2n>TN1)e>0
z#|^Gmv-C$pEpk55``ky4E_9VNDz*Em((6=i<<gvw1Z@e?#wmA$BU>E$ZuS=VFGp78
ziJq9L#MQkDv3zXa))!4<C04(Uvo7`}S6cst$L#XnJitXj0Ata=6_y)-qUS#kDwB-)
zKV}ov*S6&`7DPY%Kg-{X-#<|ps+L$BWANB%$qz-L6#JXeb;?<%J5SAC7!L?S=catI
zDKn)h7|CeOweu#=zb*MJPRwNS3+&=_SM$N*C)IqgqhKsL#tu43qgc?g6kUz{2Ok*B
zjx~Q3`!aEcRYB0cpmVwa#m40JoLNw(_jq1nMy-RK6I!-qrSx~0K?eGVbQYP(rYU~$
z(iFKE*{(mKX?0kKuir?c2?<(ll-l$y)QDILDxo7pzdu|9<z3-Y5su0ZiKeG#vi3sW
ze5T7q!ug(5vnlh`{~E)n6G<=f;>tPQ#E%5VT8+|_Zl##0CpWYJ*R2BvNfBhP2T~zK
z1y9ADe#XMrS<7_8U7Sl{4Hom~j(c+m%~jm0leGksg-g<uey4qrdp|zEjBU#M+2PPJ
zrGH3I)AzQcL>QEj(5p#WNZTFO3JO^lAmFKxBzb=`1O7j@&MCN)sDJY@C$=ZHZQC{{
zww?T9+qP|UV%xUuOt5+P-HZKi?Zs2w)qScjy1V+E{^Ij!tq2nTO-V_Ie_@;yE`cLl
zKw$jKbl?^wgWqI36$%KF(J6q!%4Ar=c3MbKVbeSoOoRjBg0@I|tWKj`N{oZ&6|r{y
zlZ3g4|EZG%7G_XWAt5vuXGqim!GuR6kr-v1ue`r}G>P>L)@qZ}9(g5sI`(SKJu}YB
z=K21prlaFDn&~GfgBghCw^n>KbVM3LVLb^#q$}?T>5NroNeH;&+44V2RLIwq*yTt!
zaAtu2cY!3wtJoB$`~<~8vi@u4Z#%$cR5351XX>N@B6+Y8B02CP|02v@j@TIVf)Rn4
zWk->7r(A#ljZ_<k8fcoSL#)owFVN$-HI3ae;fAz4l^sM~<4B&^ENcu0_yc@{&caa`
zM+a##$0Fa70Rd2Q>@X8`4F?jp#YmEwUdXr~g_W7#c~sz~cXHl-Qnr)hC~6sQI4XA=
zl^=nSz<$niycz5??vmfQ<mhodAVw**W0FBpi*HiQlwB~_TpQ2Tam+I^eq2J#-temJ
z4QyX;*xpB~B><Ov4{=5BQ`jKsgW)azA&sqT>kf{4;0I7oo36+R#Ggx2FY1l@hcS-x
zIIP`MSj1^dx5O32&J$%76vX{6aor2`rmabx^xq;EWlj}P#a1=VRU6TlQf)-<<a2b$
ztD>;mmh{(DPdMO$`g@oIV{yo1bEu6`jU2;`D5=)b>2qLe>-czaV5&PXa{+<<W!bi-
z9X6#eZ~~C%ES;H|;@Z#NK#}Gcl!AkmA}z7ZSnBheJtWUk9BxdNl|-1Puf;XuVo2m_
zY$M=s#<y%AD>bkP&um!yQ)}99V3mdb?dm99J&MCAenHwadd+DZS*SE5meXWx;xR{3
zl^!KCMYM5ffx`kAJ!L6d01Bd{eTV66>}*tPNCJRkdejpUzoX6=q4sb_C6+sEIx?u_
zIMNo_JeWW=FC+cif^EK#<^W2vT#QL_+%JuV3NPwhBUl`h9f`a}zz1G28>YQOE)cgY
z@3A^d=t(#-H!CYyg}5?*(pWZ{bx0+eBNCjor1fW8iMA4XU>HZBUOx9@j@^EChF<-g
z1Sn#kQbZ8XwXwI><h)!S;p;2Y1_u2r!>nkC00Qw(pzk+esc_9tXkRk`<hczfc#%68
zWWH7a*i0nGP~D7|6IG87WXf{>vs*w31c&@hfWIaxXC9-Ld-^6vAUrcr8XXZ$?Z;hR
z8AW@T6fI*a_~>pNhy5U%9+Pt1)zpyh0w9p|V_8xuki?3pt#@dj#+am>Als(jR#Oj=
zViit1&<t}12F*DDW{)5@jY;C9gHJuxu|_Cti6zwtAEQRVv!m@paWIUR8hA`oaV}hx
zu1Y|(m46;s%ajoukG2(yGigjj+e?O+Bux$_u}yznuI&+fPhG;QS4_clC=pF<0Wj8h
z@^v@UHRws~b^_n6jxO3^L;f}uo9B-@WECsG7X#78N$C_tZnh<<sPWq|Ao*SL+aFm{
z0G~C%UD+WuUciKefmt<esh)UhQew9*zGx#!b1pjm$V0}<oCrk_ZAVOat_l8~Aps$Z
z1V;>nGh=g0;ypCJYghvRY?&Kt41g&4=-OeT|L5m2$Q1El@Ho)s?F$ma4v@tDSSre}
ztjOlrlIJI3@kN{|8IylUi;HI-X6#;@d(OVYeiNVzK0b$Rb%i@TA{?|0ap1@Q+2BBz
z&N<u<-0V`uwu<P7nqEl!&UR7Us*1$#3WqW+q>DgR4KX5jQ7qaMNsTvM0d%hqZghOb
zy`NU5*DT6IcWdOloX_E=u^tXI#qIRqspGART6x5Rc5)jcbT^yLr-}9C+8?K(v~(?b
z*{5_3U*<Il%~7O}6JH9=E!!=#(T#Y2fo|ybh!_7`+X=skuRHQ8%CMwvQ7Mz`w!hD8
zm1u-zE&oQhBvIH&JYDvd2VgT7Rx#SG3Td7jLYtVB5bSwvLwjBHh<7L6lmmp{Z+SD{
zM>a;4cr~-Z9o}rS;^wvGC=?Z%hf-kps4#No&!s2uUn#o5au>z*r<|vtqaTetwkz!`
zDUQo~HC=?>L9=H+1;e&SnJn^k-(>O@vf`t!eDIWl%f1_hE%p6bRBT_73|+Dr*=hCs
zyP`)J_C%)=Gi*;Zd)R5L`~KZ-I8oC!E}LA!p#^>{z)kUly$k(REUB=MEV;jEsrJfZ
zU>j!fbH2S1%v>#Scl3VW5<ChG(fl`##}SYCv%Fzt{J*1k-5O&tIP8esC)BT?Ms4(d
zdBQ*=0=9C_u#Ryo#QOVzK4Ukf6&j)q#mh``JeVw6Q+xO4cS}MQwc}Kv05y|R$BGUW
zmv<02g1tBIr!SLQ->)SqE0^fG@=r~hfE7vzlR`Pt%Fl^h?LXE5BYzX!0DvoiGQsl;
zS)Js`1oY-y8e&v9(l!=;8Uxpt?rrx*n?maq_4)-qqfo4Qp7`T}&MVty;Y$#CHHgbN
zwytb5)M7|QHXP8Z1qxQ#Os5Eg!M-1CmV*+onW3llp2wO^*NZvkfC%Da8^lhyVKXB}
z42b@(0X;^>%f1~CxOeqpfDf(WC#Zr;nWT-*JRSLyXz;0XNOnp}?-IfJ!UiM*r|3!&
zh~q(G&2&Zd%=-IuwACTXexin;d38M(WD@?(i!mRTI(BkB^e9L~TCFEBo{0P*_%a5l
zWeu&!nijYAC~Yf+2ZJBwScj>wBQzJP0T>tL3AnrY?%fq{1!NxxKmkGQmBY7Cs*GM?
zSE}&0AK<k=4eoc``2wj2xhrG=B<rC>_UnW#q)E}r!{Ybszk77BWo#s@fA0CZS#iTn
zzVqZVF`^IZ&*9tbxEQqikU!Khq|~wCM0d#O=mDI+f~KUXrKF%y)H<U@(|;x%v}z9u
zw+iqIvhA^ofVs6@01`w`Ymz27h;lS2gVGNaB0MPBlhA=6A#wIQ>LmM1_5JmkM(9PD
z^N3TCVm8*#>m1^9Q#eR8epbf>nH*dB?aePVQue_5p%m0Z-cabIcf-hkiEFLXkQU;}
zzGfz(687DFtfw0EcUAvRdSLweu9emolSLQY+>#5bvx$zg2LvJ_;9N^vmEMHm!^-Qv
ztZ#NdLpxSA+1qNCG?Pl2qW^^o<t1p=b4ZZG+DQ-~&tF87Br`0*dg`96OJZm#c1elh
z4=ZLc*+ER5V>)~>2*(V_>1p{TFv(*e*WiD`)xTpv`$e&Q+|^)@??C>JP+23s_TlR-
zb5N#F{<mdl3J{?t85{cT205;)?66xd+i;HPVoA;01M=wuyp5sV(#1c<CD-P#{(D^|
z!c|?U8-+hN)hD%s<eEcto8>RLP;ah$9Z-P)qAMB-!@aOJ<_<f9b3Ha4!lwP@kL{t}
zgR_fc8}ZEz-D^sFb1EEdYe>5vr)+u?hWxQD<BDp%HNZoIEWML7U6X$7nnXp(%it*2
zjUmKjw)}@E$|4%N856oswS|!_*Dw3TNFWI9(y#$Lnno@U8>mNWH9a&R2UWe|6odyp
zIPa&m6Gg!C@^{p-aPlCH1D;c{VDn=15)Q!|C%+ZxcBg@<K%|Lcbox>>K6G-q6;-mx
zmTgUb56~jc3o*am4v(Tv$nxe|9cP<+m-S@-3KRK<hJB0Yl@FT;1M@&nz*ZnHFLw5H
zcuHW{kynaTO-=p{>TACMxKY)gv~rRKk_nnyZraGMjXW(dTc^%hbi%<zr;`RA?wRXQ
zVVzQ4FhN*Chxd~naYCvvr^6v3+p-b#n>@C_7l8Y)A-jA-@HW!gY=s+^%Z0O9gW3d1
z>fkPmQjWZE`yL{#%EZxPH>Nf3dZ8r#&PV9q$u8fIlYKYZ9%OxmlB&jOrQEn~%+YeJ
z^Ueu|&o{uSP~F=WarU%9BqS9?Wm7s_og!-V@yLctcIb9FA#46q+ek0QAtnxEVr%T=
zoJwv63<u2dpNz&2qMwa{>Hq#1F5!;F(6nCV)RqyXMUYrh8!&_dh5K)2b!o>9IL|cE
z-|f96?8Krg6{skw%8rQPu15P-Cr~8p%PrCDV6=zb=IUf=Wo@bT(!S&l^dam$EL{JS
z-%0sNXwWIu=2dI;@TOqERkCuyhr^}V5q!G?(1bc#0lxn(?oaH*VUx8;oniZ74XY5}
z@q0{OeF0vIp0M&!u)Vf>2LoY9h9V>J4EmvOVoN*2lWeIMrZRy~(wGl_QJV(HFR7lu
zq2_CBAqBgM;S=nkceuRq!HxV7{fBFFJM?#`^~9=y%Yb{a5h4SYB-=mk+j&w5yby5#
zqTR19jcR5P8>$o-1{q77`*rWXbl^9YTBC|R4|n{-g@zgN`0ap!Q9N+P&}QjzPHa4C
z?(QVhkT}2lPjDoAp<LIgC*2J5KcRLC9EDS7c6`l!znFeYR@i`BcqV+@wq*n(7Rd;<
zGRza4MYD)<&6oR#aODooth+dMjM!ZO?r?Gq0=u=0-D%h)?W3Wcy?V83B{VlPqbuUU
zXkgYsmxw8&e*H=n#5Li-1qySYM1xSJioq5z={&d@CD~BE_0cqZFnx1FWUd!d0?Q}*
zJ24aK>e#Fx{?+`!8+L^v9fuOtZ<K7IRfnBPul6U*RY;Sn9UD(BYC6EZ&ZI{aP#@*Z
zyk;bMq7G&M?`(`rbMfS#b8BB7QZg{44K|g7@pM`u=_n>fk?g2-On`|Cn>Q#}Vm=Z8
ziRFfD%#o-Z*v&!ywW3cRvL+6;Pa-LO(EiytARI|?dmBet=Gar%6%2FldvZ@M#n^NS
z_Ue;pi>eQKz~ZG2hQ`PM(IYz_P(eFmam1TICAu60?J>2tlb+lHsTZOFJPM?qgQ^nw
z{tJoj!K>*3TN66cDrOC|M0L-&A7Ks2jJF^DN_7POst}G56pUjnBnQb_T@5*-NGZbg
z3@h;AB?@{O*jR)|Zrj`lgseg?<6q`dJZS80D9as(9pu0jYIY;76Pa%pAc0kgf=QEx
zexrhx(qKUFHhOgu9Ky^IpL?;>tA5l_4Oz3lT7y+Sxa-%2|Lo1u@c~M-aR*5JYI08N
zo(4kdEzE7vL6j4QD_Kga5ArsJ;91yd8P5oPgez`xgCf>p7nb`-Shii=M89ODIwp#y
zg>lrMYt0}7X%HkKqPk;A0Ng0GSO0+GA&3yb41HCVg0ZYZp&^=<n1VChs+Gf%+<WBh
za?nAYteC^BC&SpEp)>k0r%XvtA!uJ?6koO^H7K%JKRkAfD4!+XqywpF5Jj|iddg5u
zxtfL<rws$#y9bNWgj~@_GrJHkhAYPH7*sKuj*!3oq_J`p<0T;%@G{K(XMU}RB6R#8
zW6-B0Toa-8_NjB*<X-LE8K!j0c&jgOCtagcO7tWW0+aV}qe!?ztuvb@`2m)oV<<bf
z{3T0?S^WHAL@P({<@`i|!8EU-8w?Ko9&`6a8J?rwOV*4cCn7?PLZ%x=>0)@~;t(e}
za7e}W0Z(0Cx;z*rAnzX#C`%l2LHIGFx^G5S*0>8W?pbujHY5TIwju_B`zZJ)W6>p0
zfq_<e+Ff6JU>YdHu|Q&k+#}S4(fgCS5&U2&>pN(2uA>s!2M{CC%2B0fU=wfc56bn(
zgWOOmXK0Gn$iV)wTVTJ2HukZGwl+)2v{o@h3@hIOE9qGY5EeoXS0RK04nW~arb@8Q
zVA&jOW5pU^Ddhg6HS$`L)MF3Q7L#cO9<_7ELjcxX*>i-~6SqtHP{QMO4IR?JSsZvZ
zHMI4|P>3?vf;=1ZvMoU!*~ZXCLH}MWwrNY^6-#1jbUubrh>_^ljSzLs$U8gnc!LUr
zb$t3@O**q5a83HzQ<$-X7`X!$Nbz@WO5}n1z>s^K3<m#hCwDFe!NbgA#r#3^=HDY-
z!W<*KzgPN{w+gb?P*jGogMcG2TnY3%)B?G~{Wo)#oMZo`v?2A^Cy4JDgP&acRE-Ry
zij3aMg0}JzPI~dL@bu5ZzoOBELqnI*7%Hc!?_oNlfD$@mYwbgqCc-%qi9klI!}&+a
z!+=tuH@hgk2v{_q{8ACd77_aSa~02`Q&A!8Wz(neZ*|rpXTPFhQx#{EQ06DStSwrU
zP(y;&y{FZwx=U$ERZgktQIr<u2UR889q5MgV=Xx3iE9a5?gWiVl_v=ii)r&#sXugh
zk(<_T02)W9+U%q56)CAjv#h<Cuzbxzo%Wj8s3}bI0XP0>M+(&ZI_6r+=5X`!Agi)*
z5dS(>&L_^8EcSM>d+^H`u!8c=Cf!iODe!K`dHsqhTy^&oEXb_1e3^#r@IX!)6JBAk
zs|6hSO)G`X$vKM4+YABs+7KRI2a_)r>_e+3K=p7NG-!Vm$556FdjYJepfD2QR!UEj
zW34z(A(m;SQKmVOS1Qq%5pnW{Xv3F4SLfRys+F@8INZ<@S}yyH+!AYYnjZ+4UXNA5
z8ROUBQ}#eb3s)*%;XWv}TJ+y23j|(t#<}5}Hr{73bNf)ekzavvf_V&9+-i2ild5n+
zfaepBa`$>z>-7?)vr|RLn-*sJYZ{U;Uciw{C6EK>C>`l~SyJ3``fg*9R>sd97g(J4
zq7O4#vU2Hne0P{Ux`vdsoLU%?t#FK&Tjp%0VLzkJnJ2IlF19YXDdr3p%*+e@LGIoK
zBb$!S%nRCcHh*;Wkgcm@8*<WS_km{*a7QKnXDN{$_gV25H}PnqpfVR(*M}4t-N!{9
z+Q34k+%WF6<SiAG+As3jIJZ=Uz28zqJ<8I}!<oDTD>44(oTPJb2UQ2iSFY&GM0Kk!
zJdnDhUth#jo4#-geY#=$#B~yfg+G-?^HHWD9H;X0RDHO)5sCvP8<v!H2zLTNW9ikG
zv_{HiA|Kgi%HEoIti;9L@g<gMRjC_S>h;bi3I(gBodT&)#idW5V{~Pyx@DkFte1Jh
zQ^WXHHU4dit{wP7`B<NHt##oI$BM$fzoig_Zimz?r_XcvSdQ3U!E}U`_N}Rgq2-dq
z61=fnUnQU?4!5{t#VhxU&Ga6yP2zq+_*5jHVc<TsfUhn_Q7GSAmN`-Zp49P{@bNZ&
z6e7NT`J9<cO6Kl?ezCI>pKxQwgW$0)u)c?Kf;Gn7(?vxneqtZ3o#86U&QZdCH@+1q
z&ALd8AFGp&f3BvSZ~T#6!d2=<S@}pnE>jAZ*77Z_z+TcQQU8It9e4y-0ZV3~ezozK
zldJtby6WN9qttH+{GMD)n^B=^zwLQp4N~)m4LH-C{62E_v8_3@C0Yl&H++E==t>f_
zZj#dm^g91m4i3k~ec*R6PGgJV^u(jzpC42f+#(PSTVF$g!cSZ9mYbY`b0E}->=ynM
zhh;O-uNrBOseU-}EWvyL{H1NWaaxyfzgm-^X}!EKw|-MpfL<v~%h8JB=)i|bj!m1a
z^-C#MRzlan;bsQ2)50JT|DKJ;a<SAr<C@zqIQMX~h6Iaq2}gt`Hn-Z6m)V!A2)7hh
zURNKcHT0ErqLgQv^Y~4KIx%S{G03k1^eM2;J=Wchq?N1Mc*|r!u$_K=@0C=sVs864
zuv0N5*pw_oT_BzD87;RfLiOg>B-^;_oMDJIcbRUkb62b>TR+oOfD+Kk)e-I$wzbp~
zwIrO7bkZ~hzU0mB^FKRetlN!%ns7wVN|v?2E=80FREqLc&xsza+Z6xx?JO}5Ny;hE
z30%|nuSpGC!G;w;a}P=D)Og8Me53Jr?;rf`?q#k%mN5m&t>bRbpg}w^;9RW|mLGc}
zHm&B7d#TZ7*=jIZo01x6YB2}GaitD5-rdF}$~S+;_6fZH#~YmWg4Y}FuWd^NUNP3<
zQaKxfEcN$Gx0aL$LY!%bwy*3e;1q2Y-)b7ME3Kr_PjE?qxt+;(%o#%x)}_VS^yQ0;
zXxFX;K`?d>9~I!?Bz=7E>P@~WzZJNc>`yYo^6NN>uk&R#b?Xywd^!B!xp|l^gXueM
zkC(Z0+%z6i<xu+bI+t3;Jy(ZE`icF6-^@;B4l(WqSr2PA9lU``>3%EP20F~v1sK4w
zka!0JEs6l3lTJjR*TPNK1#}Cl=UkX07PE<R9b8gh#C64&9f^H)&@-t#V4E0MMye?}
z8_uqec10t7uadH;kYX&3A;h&ykm+EzB{L%(w0-B;dNQh;^?)|uCuSpki|64{v{}uR
z`0H;EF~cvZo`^LL7J6t509?>cU<Jm$BRIwf)nE!>+ntT^lEXF+Pt{3t2}5o?;WLtK
zEBj&ZDXGR5B7^DI?0vH87D<cQ^U9>d@t06LuAUdh6swcRSqXkR>FfN^4oI#@w&=dk
zwLeQ;6|guw6}-pr!<(6{LLWt=Okr^`QLLVDU#Uud+@~s0kjp&H9C!kLS2b8f@1cfU
zl~)vi4t=jn4g`}g`0EipY;@<Xp#^u7MA$vaf@3-{Kp3>u23fB1q6$s>T<&`OYI;7V
zo)zrmN!}BuYLr~%MB0wNLM|s)aUZr@=+^Nt(dS0_J`5jO<v2G%lsS{hQqL>yS-|5c
zhRfoE4$H_Co9FF1_Sw;{n6~?gDc`w3tq=sTb?su<kykAq-mpz+gr8nsAJV8)WGfX<
z>y7Nit7^D=^Q-(`4mpsOs{c%^oW;9ehuS6tcbCbZn_x6(|Aur*&lIO6^c=5IH(Z3R
zH4>r7UB@?bOotH*W{@iQ>N}y&u(+;AmV&f)6YdK=5XBMAu<WOs6FdFuEu@hY5^%;d
z0FK>a@R{XU>6G(rf*lQ*`&)%G`h4tkM=Q%vVui+{sQra3F~)s{bAy%&$aFLeTXOaN
z7ytmli!dSmH)FWh`~z2FW@P&xT?0eflC=kI|3Ph@B4{9`?t@_ZK*jxv+aU3Qb*y_@
zZ#RZdl>YK<Q;8oEP1znG5gfQOi;%8=ewU!_r88Rl%U`e2u5qA#lKPoCd#n8V@#pnx
z;N|EAkPx}5*6UI44WRvTDW0blsx=I`ApmsR0WuqQq7ZhpLJ@*ysJ%B^GZ*Vs+ipFA
zW=2{wm8hB|aB@Rq*Vy9rZ~&k|jCEU1)MdBf@~$7We@7Hzudt38FQK2J0Nh#pO*a2p
zdja1M_aiqZ^1XDG_wXqIdiM5en8yao+EjgXn;}b;ucw)#+KHLmvxuL&#x6!KW>X0T
z(6tq++68m4?5GvVkIOGy_8;7AW*9RYE|KltpWWQ*P~~KGh79xu*D>tT+8t?Y&$PEX
z)p-$z6W`>(^5dzmY}HoE(VoRNnQ~P2=cHBEA!Ck@1SGmI)RfDwrZBbZE3qfGZj}X)
zyHIT=2x6<P{jFvKw=_JIGkTQMA-R$Tba@r<kxwlsH$)u64?Z10Aj=ZtWsoxor_^I>
z7TRz5Y|CrBC!I7=&&Sq9AkHDX90nRWTT6rv>5{`*9?!LP{L!g+6tsnN#n*%vJa=t>
zQ$5=!|Eo;eP-onvAKe@17N;0y$hw!^eq!44`3*gx9LZ_KSspTt-8@u%W`6Dgu;M=d
zeRy*UF-AMAdfE<gj?q%lO|I)b8=zBDz3p$&ZMvzFERVg_l!WD)6pgpqu!nBJrtV{5
z0JcFEml~cBp$$6U_2FhKPaLJWWLi-yxYQ{#w0kj<Z3JtvD3W)Qv{R*HVjrgn8cqJ5
zm<_qi-F5(l1xPOsSwK<xb?LSb;8t4n5S4u%z!s0#oSH;!$8#$gW%i6k!{YUiqYP1}
z+-<{{O4_8DYuk(RIy=FXB>`3U2>-GykPY5|i01XsiP#SZC4rr2_OsYrgq@CxK0;%7
z^ilwN%Q_hC6^$ulk6>gkUa3A7qpD5x&Yj7}36RoKml64wf@WAa<{yCw_~XM`1PM(M
zsdd)iP)5f|mBVyDy;vDu!6Fy*Bw~(+Q)0~x7|({jKoI|2gRp>zY%IDl)l)upcHvv4
zJe{;atnc+$0sMh4WS>g_%BN_QN;#}ko)`uL)Cru5w61K<U$f#Qr=aV4IT*+p?HmH_
z>rr5BDsshhr9b&^nlQEkjH@Ivr{sRAzsOWm^VZBK{`yi)Vx2u6MdKS4WHhtdne1vb
z#*rmT=a?A0f7JsWVvEe+*}$2USY>61BekX!U8Q92OL8-t_eEP#nVQsRVs<k(Wre+*
z`o$}H-~q#IbKpQ`8dk{5q*z$CQ8oU84~x%QLLS0DLLpV)ow%F?NGfe;Zpva#RohIf
z$2z<Mb?R&Vn-n67;i3ZshQizgn$yb`j;6vauWIUS$=#9&>w#(kTlj}kdyrPeayc$y
zy;>TDWc2XgX>G_@c=)*<sOmO+Gd`@I+`>Im4Mh@e0<p^to6f$#mghpP3D6WJ=MxE6
z0mTcw4?!ayfts}fKsrn*P6_y(=3_l}e&QEyoD>|XMq!8JekAgh`TmUsC6%WFly)yn
zv4>$K?MU(MN{C;=R^00S5h0vCF*>0d!f)lP>Lts4RHo(A6l+BT1Ekpll0?cN%`1*z
zM;b<=tDh$-pPyUM*fDHD<?|b5O;Cy5LXF@{J^!}Or{Km0ATCb9Ab&dgM+!OnpIb2G
zkV=Gm+jQZ%&f*J?t4?+S7cgtNfCO{VBHR4kpaT=20780@6ZKzqRTh6JO>7!|scT<a
zxRYoo!DeaneEfSRB8b!X;@D#Ef=~%VV4$K`b^G};W%C416diM`-6;>1Hb)`e62i<M
z;o<jwkuIVkz}D2V41RW)0<}5Sy`%4F=}HPxUlYp<#h!7kCb9TVfrm&#Yc`a<{w(Fl
zBe7kil*p&S+rcP)3K2_t)uA<2x2Em3g{?Nx!g>dU{kSwra0j@**89w3<|`hJf`(K#
z?!*juDMR&Cw};NZwb9u9zssrbBuMgWBr4mW)U(>*fY68_O1ZIrS5Stq^a^VY?C}G>
zL)`(>0!xbVdDdc)VnQU49<`pS;^D12@#H#VxQe=P!52KkEJ$ZY48RWYU)QWewRtx*
z5A1k@3%5FTT@YuXFad{LkvH7YU%$@}>rn3CrN%z#fkXqAeV5-N|9B<;%6Fs3rHtny
z`hCBY1K<^5JR%>O`!@eH<0Y&|X^k7f55>hUm6S=+J7UFozx0qOe&Ps7J7bc00;6_@
zmR$sA=LS)`_{zwzEMjiq$$xs6S2m5ynkRQILxBX#(Rs_@gn2qm!dD?1!SACk-rQlF
zY`$dc|5b=Ig=&)U*;Rqp4;A!msc@eUK{8RT@<U1g)>2aP2oq@ugZs)kKE{C^CXH!N
z*B6=Te4y!&$9bw~vS5}kwx;S~cyPuDkxExOwJpnXN0{VjAHPRlUM@&S8}K<Ngh0zV
z&NPC9c97%Pnxxin+1)Q%$|Yoa>JcERK26JJ|9h@Z2Mw;A#KIq%gP+}eg2hvqTG(~i
z@I#H+mRNN7c1%Y|+Wt)+!-J(+qe`>8kC_v5hfKQQ=cfZtY67wH2iv42`?-j7q%)}&
z9~my)BKlJXwMIw)tvFDxnhC;96mQeD1YYhDpQ;rIRz-JMZF*T}OdhJbDZ8W1KSZ<p
zM5GoS&ewyd#DFB`gN$LC37d34mug8}1~7vJG(z1y-d+IF7J84tpY^cRcY4_|L0@Wk
zpcvPp^boZE4fHv2(k2q4WM50p(4Ii$BNMDp2QHc{j;3FX!)vQnRyD$yk%IxKn?bSQ
zu{(wYPhW=6t_m1d#R7@A7-hS5(m^&8xfuD98L9^#c2cp8>O+8oK`_YEYh>1(1zf7=
zs4(zMz+Zb~+{&RV2cM$EJG-wHJltx!Wt?z0l{TyEsy{rr;}uNlJXW=qyNLP-A^P_v
z(R%P7l@K=NWT0A^jOUofn;B7Zdo)`Ze?)W2YVZ@27$5aH5l<!Do5qIQO(oWIWkQU)
zA-fE%nz3G}|Gk^5_p_Ucgy3Y;1XyOW%fa7~R$7WqbN4r~d#rC@Pj>mi2P~XMkmGZ}
zb|9;vjJpq9(ev*Sd}rtyCyrM+G81y6)maLPD<wgrnRAC6#8#=58+bQqs2OqP-8V$g
zKFe}oZ+j?e*e}bn;bfWog=-&ASAES{f1!K@`&i0TgRLprh59;|_v^hv1z1id(Fry2
zG%IFy#wnG7JtR49B{`rb-aG9&<p8&O$kZ-c`n}fe0Bt&QNi5IVknBDsZy?`VB5f|Y
ze_NDx$_Lx}?q;9-^AF|1c6iVB@1O?@kiC8(wa3tWgxDOy58leT2GQvgJ3p$r08c-Q
z^<a6N4lVU$g|>w`$i{GI1{|g*1NML38y$`=3C12KQv4MO-aip-Sp$(upW1`WvRE@(
zI69pJK~6U%yUcKScC)n|T4OCk3d}_*<lB;%E6_8}niJ~3-Z4i^3$`XARHpH&zPD|5
zDa%m<NnVk>IL*VLNZp`RXd<p!cMlIxSu91QTbuY|Hklvl4)+9q*k927wcz^pSX`Y^
zk3N@-_H@xTS1$N1Le83k<^D8Nb8_yWZp3VF&xm<~3}gC-nh2lZ0jpSNg%c%krrdtc
zCd2!Zp0)FP8D)czO?RN#V?LZM51>K*%ZXWhQ?<vp)bh`|B@7G1pp^=@JBx+aG|KC+
z?<7|h-8W;f(kJT(fS7ChMs6<VwmeTS#?3mu`AKZU>6lWv>uc1JJ)F8%#MdR;Fwame
zrJH>yYBk_<UHgD`>8v*4RlXm~0~DK`o~JpDIda(4pv_7yaW8Rd{g*Yl0Zm$@hfbO)
zwBA4^bB?ES_7O5Gb6=IGD)sNQo~W0<Y`)>OGwSekAUQah0LJ|Jpd(WuJcF*Dua21q
zcCW3I*CV_}Y}$d;pruk+Mgw(vYYVLFSsfgPp3y%mv}$@}_=4_jw`4Qu8s<~qN3!_q
zf5KYUBTN%lokvp|2@f`StPW?V1ZI)>p9Vj`vzH;}hjl3+gR5|IGoU#WE_F`GxCIGf
zu0h(q(839G0fAWe+F2CyKRHg`)usTdt3X+OPn5I2TQj~EZ1Bp;AbK4KLYUi(b2iI$
z-7!0iZ<BDU#g^-{o_XO+5Sh0fs$$k$i#xTy!tKbLiIpZWAiM60*vcYX?}|}7wJu(d
zxcgSV0}zx7o<KZD70B+(W7u?O)i1rQ=-*GCw~N0%AUnT-YD=iO|C{9J{I6jm=l|^0
z`RQZcWcyE+|EE{SUf-`D7lZ`DQJSIkcc|@ClRW3@Hvr0tP*h2Y-gShR8S0lNZ3NA-
zkXkpDWe9yBuE;w%WG%$aKIT5dXCgLV@r6_S_dV0cM<#X=W?`74J0~1>p}5)9@2k@Q
z0=*ajFLXX23sJ3D8pd$9RrV$B8vlBR+hho(6?cBCs8b?Uu2+8Z+L1o*j}g{E8UHi)
z(x=QJr;WuLGwqn$gcC3ZO6!fZowBcHNws^=%HPO?IaW0GZ!t}rn7XG$2^&+N(SwH_
z`d)<Io?nvr=+3`dXSNnn3l4P=3!6RbxT4rj3CrdHLwgq&_Sj#il8flf!kC3l5O5`%
z6iM<;VwKKpm}U5byfAwSi07(M**Q!8i$!veS$fdWHX(GW+wCMJS*N!4lMmBWumv!A
zS-DvSd;*{+3Oq4ORd2kvAXj<6+x##vL7NhD%6F(UA-73=y|GW=n)~gl&tg8Go0@bw
zxKB|4VemTPD@H)I3ji`*B?N%)Id)G2S#hmOxi?d&Yc`cEVY>wg|2Sqyc2psB#E5^x
zuA~1FPyD-}&ebXpaE@7uY<t|^+ug-@)$neHh1n9Ut)^|cm+WDR>bir<7(r9hl>?in
z-tX5BfdgUf-m<+M3~;)AP`fbDhfbnEUfWZ^RS9@eF+p}%_O`8tAlDqbI?eA)5$6$Z
z+C0yB?%Lc878(MUZ)#eM14@}P-ga|y@o$t-^8T&Sb~s;QeQ)359S(f&%%aYW)l|vl
zB_xr8qehmy7W!t(MYfL{nVUTsZC$-yj4b>G-}kxgru3)j&iwpOwQdX9Z$Ukkpe7K2
zb!jb*S`2&P{k3@Koar)mZC1#0Hy-69Ft+{HvA_zU<sSl0iF7?}RdNjO@<~kZm|w`4
zvM5rWmis9|&V~933RajqgI<Oo36XIn%+)OLnAgf>sG`Ua3KmZhmoH7F*?}zC-uri1
z{l7<!rUD>KbIfZ~mX*)6O-wbV#)Izx9Fu`%H~wxdhF*}<HDx;%<(UbJbFZ5X`EcH~
z_nQsVPicwZFAPl6ItSX!X4Z|5m7KU!4#_@-{=7F$uytzZlL@a-$$0S6<1?Ms^`uW?
z+&w%l>w{>^YoI^Y7Ky^uq>J}5k>24FR(i3^gO?CGseGYVi&)9H8dyC{`iUt3^-r6j
z(J!8>E*cv8@`MuhM@7wg$qW}&qBJVaOC7d2>C^>xh<de-)v+Y;(laL@4zxHIBgi(h
zk#ISNUR6svdcO<Mh5I(N->Cz+hQCi2E8;80NJp|jhj6FD5{wk1K^Ze3htre|=@l-A
zHQ*e!4%s^*&Z+ba4!nwJc!ALY95AS~iBM#NSt0%*IAJ<K^Z_jbjc1@e9wY~S=EJug
z!^yOf>Wp>-ecUuQw`XCO&fU9CB_ODVzLN~jy!>5LWwpgs2LsUw;Em_R&}0^szl}C}
z_iXmC<Uj_}zJ{?x>~5|)*lmjjy4sKRc4ucz@L&l-Ha7yZF*U%MvO}Q(+k0b0kfdVO
zQqjZwougs1C8PO59I=YZv8yT-%F?JS`}Ek_p+2})Rw6jILhCrF7!*<Ov~l{#@QB7y
zSh91cphuOWu9~k6c-L2?Q5%@ObGl+C`Po=<;s!hCtGCve1;M6^A<015*p=@x{=-!V
z&#E$M2&N+0Ff1IkWcu&`!Tb0r%`CI_p+=7k&@37%VH?vL%~say<tBZu1g&;h>U1w>
z>R>IKk{0?;w#LE?t!iX^H{p_n2c5FxhXw`djT45=mxydo>OmvEJd6)h{EI4EU(h-)
z<#|uFh0z;C-y50HzM4zJ8SW{)5#f5F(G(5c&V2y}^lV1=$#8anr({{gz8Z>Lvjm59
zNnvIaO<lXUWV?=u=^FX4bcPL4?^#~fRHs!zfo$?5MuwxHvTg}wC!QDDlok3K&j=G7
zt$#qQ`m(9o4$nhY&c%^Cqn+FOp_M(3l)w>G*u-Oqp*KvrpaPPjRDa@OM?KTh&3LMn
z_PysVnwmZqV>>xO-SE`H#cdWxUNK9YGsZZAUVXv(nO-b%|F+#VwsD>FoMDMsaU`AZ
z{5CDweOyN;tn}pA`jAHD;vA7KN|WI5kJ_F=84*I}Uoyl}XIBl*-)U5Atc04K6?JO+
z8Fbf^GyNE!{?ptUYCJf0JHB9kUJ~@b;bXSGM2Kc8fnOm3I(}@&9g=-{A^#G}2Kegp
z@9EkV#BtZ#kpm<5lQ<_Ejrkf<u&-oPXD7LpX<f<YE%Fc)^#b`w{&D(Aan)LzIw38p
z6U3d;g;fjXeFTrPq;{8~Ca<ij?ZKcSbw*t3z;icFQ2DX2?xdU^+1A$xIr|UH4i#wN
zTu=X{=@xJYRL-^`S)*WYG|sxK6<YDNoL%v&V;-@=^YTk;UR95$CQp<0=x&U$tlK5+
z*}Zavy@W1jbsbpmKhG3QOE6WxXg3eNk4UgD%0<WgS(BdN@k%#r9pdK-rJ{}dx1R7K
zg>2^=dV`PzEqzhHk0`mGMV0zD%vLG~JMoC>j2*WRP_2os*mTA?;FVZMPs71@fJ39%
z1Awlj=<}7KgiB4>jmwGA;?D^3DYv2gvH24cg2vYMFzM0phXgjn26No&&TN$6x?4dG
zjio3*T147g2$9|SUIx=P+AS+msv+E%D)<nOYfp9if|yB{vQ|VSPVitZ0A**VKZP}`
zw;P8A04n`P;Q{#}40T-GwP2eZieo$O00eux?;OK)Ulz*yVAQi-h!?pb#drI_^z7;5
zD)~A~Vj-($!OB9JZtsq$C5yjy+iq?rFUa?L_f`bs*Qz^=U5se@Ktpl>^}|oXk7vXe
z+Iw&K`u$~V2c2&$(*wccm%=dLRgWWaeVquVpaLczRLW$$!jN8}KlK+%<M+3WfV|_g
z#c&uZrf_-}mrxXU<<H^goDF{8cMN6LkevU<Q|;z~f3?10gRH@UFfgQ6GNF-z{-Enq
zfg6y>Qn7JBU_)ssL4E}KBd{NV{|MqokUxU@5%iB>e)OMlzkUSwBlsU7{0Om?mJ$it
z7ntEcRgmnA|07~Mr8yRZ%l_+UeRK|~wJc-_jO_%4j59XXzZrmA(pl=m1oH12fsj;+
zR8@6mu?cR3VZ6CX#KFV6h-D#lOeW(iopP1(wa6%AI`?b<vV*VrUv2C{=SxV4MY1!~
z!hs8ypEAB7Q<?X#g@dD;!sTU40Gy%~%cFOJS#5KvS#A^CiQ`L*Z>a<R+uNQWdhC((
zmnW4z9K;u{68~uX6AtaY$P2aXiJ9J^keeRQ;+tqyq&M%!!z=lkGlLxASFR;-`K5UU
zF{?jD$qP{7I^ol~&^y+qb*>klI??*YOsPk$3zp#ZGCtQ4tEJ{dJHekmK+5<}6j&Fd
zjX`GhH|pqZD*<$J_q*wy7J44IzesS~{L9M-_?XOaS&+F`3@1so05{`U9I7yK^bTRa
zJDM7@j;H;e#wv)UBuRK*xm&Vb>V1sh_8J;l?eldvp2n<a@+qJ+D@N55@hcnwGGp|@
zAb!e`1L#%<Fjg5lWa;Y*IG#K8XyP2#8SQvX*x*VtMu+?;-y~dIdz;WS&OOI<LpPN{
zNQ?RWfSh4mQpZm}|5&I}k2lO9$doGrFQ~#Fx_82XEg%mos^p1`<+1{6$!gIguIgPa
z4PYJSpI|DAZl5&Y^?Y7|^mwIe!`wgaqp~8}3v3|8B+mcyu*&-ea3n<y=`*lyH?YqK
zf`r9&D#N7ch-zk;ZuleX4+hB0=H>8&9S-b>lhCzEJ<kXj1Laad`XqXS#C^w2w+e02
zh*tyHFm{gPjfXKcjQL@seI+<FYlZ46nEfH()o09HsYswoY4`!p8yTmxwUD|%-A(A|
z9y%d{q5BNUfkE#A+8cR)-P_c@P<2i>%rDr;TbuUm<i2qZL#8s{1<UZR-WR{?aL|tA
zi`Z4NvA75tAb!k;Ar7L^s{X-C1<&mO!ttMwNn_&w`5|edO-)LEN!XLt%KpbluI`v9
zoGO?H?%Uy{(n{2uo5z6{#hsFoUX8>>TQ^x}Uq1h*i50gIkUYzxb%v$pX}YsU2!j^)
zm#X=&^<Jf4>sUQ^#`jcORC5m2Oj4J=e9J3wh340CQJ-4p=6uDxxK&2O=jtwAu&AzV
zF&6FYarH;wpLZ8$WG$&MH8pB8ZPgvv+y;T0-?)|*%x3Ve>ZQ}&_mvqDks0gle|EEC
z+Nn@ZWZY`B07h0{Y@Z~14a-{3+<^-X&3}EGy_@4g`#sYLm({10{CZ?|n<DtcCPf#y
z<UirucQcGxo0SFd<Y7E&U$0|lOy93|&JJLoCPWnUATz}A@HF%@7qH*SfhQ1w12tRE
z6E`kfXMMdMI@Z*MevOOvTGI^RU{5FpCBxwciTe080djX;pVOZ=3tP!1W@!zpv(5jF
zV!(x}MCy9xq#(0V;_N65G0CE92C@m)V<Gbs|67l@dpJfnvhrI#L0QDb63wq>tu0Yw
zoE<#K3M#R!ot|I1^Gc0)Yj{|$B!FzTN*XR1KeU-y_pzh=PS?=8LX>?R&(qAXQlHC_
z9`cJ<2Q00LEpYj|4rsJ$ds>kcd7Tl-mX9nyTrKQhNy~|2jCt1zTG*o~)o?L;R14KD
ztel*UgRzdA^W>vF=&Ugwj&ztY7)DTe5b?RzHwf^u5h><Y(sJ0D?I|H-FRL`kH-V!S
z=#IA}gn3X;ZJ2fv0<0>TN6F&XLy|A?PCyJy0J<J68yrE~;)4p?)#{n8=i^3qV7gWA
z-`kI|-4fM2om-#;a_Am8%}-aWdn_Y_1oWpypo1$<XnX!_3QqbT;|`JCO*LWpi}GG)
ziwDCjeDVjm?X0^N*XtoQh5+X86R_QGgNyJ>8(T=-4Rwi3m%WYj{k=FhQTjSjtE<f`
zfL3EHjjaB^E<}oPjn-{~o@`Ae10a}s0j0UN8z~z6LYNx-;+4UR#JO!*2KXdN!*;Rl
zO-#bNuI)<bgC8baYf|&dTKQ~E*73u|3S50Z^`mVu0YQG2{t_k8Q-K3#y8rOBaGNr@
zW0cm9F)(B)qVidD<BiegFnFj4VbJeG08(%2fz{C+A7$>XO^jU`HksLVC#q23q>tNq
zi2o*}^xZ8)T#Tm=d))RxCB(dJcAKdHts&{D(&lw=bSY<lDuu)oQus~`mL+52vm4i6
z5TvrLlQ1tdlDSid_K-j6solK5oD6oq2RT}iAUcVEm0r)VJY}wGQ1dMkPfT>nm>f|k
zm*s1mUhcYR7eA5|b~)f|t-I=Ww!=aTT9^hINERw+jt8}rv!OfbmtAQ2XcE9P9SiR&
zt)3M6c{A*GaKCuX@}AsCZ}5NJ6Ob;4&;GZ#)zQSz=0AIOMwT$l3~a6RbZDMnAPnsP
znMlb%7}!F8=FuM^{|KcOxB->M8-#)5zoSxnZh?QLHZ!5&{v7(xd|Mjo$&B_R^j1%1
zj3{bg#{bO({eJ-I#Yz*F0}O~=FVxSFRhKnIy3i2_#R%)#eXaAtV}+#(_ur{8Cfp=8
zguzA-)h~=0@gm~LM&3d-hiby*O`N~)z`Q>+VvA1aDynQ`M1>R=gp!4;rLxIjQywH5
zJozZL0Q2uGzU;F<4D#6tRrA$E00(3(mXoPqAD6YhU3xQ9DctRJ7Hk|+YR|%CSp@J#
zPbA|$J<~bNE6akBrsu;bSctK*cx3>s_BUJC?7%HTEg1|kpI5YccM7V=-cmtG+QLrP
zd$4+&MCY2Bj_3Sn9pwC|<J5{>>aKsK^2vFB_vGL8<>EO(*D?ohsz%dXHdiY%-}wxi
zX*x6CeBE8?{j~_ML}&EY54Wd_O#1!TXp;ZWgJAqWY&j0L{{fd@(w?fhXoK5+q5J?*
zeEJ5(-4ykA^}8-<>nw;&Jakvno$UH9C=i)TpdoKbY|ri&m9rL2l8D$BSL#@(O-ytD
zASWXyHv@ez?D%A7`#|OIrP-mubPuZix>`9SqEXh9NzK#Pbz~A^ASEOG#k?#F==G6(
zcy!{2i1}!}S<wH^C!Yyu_I&4)4`8+;raj>4+4=tLZ*SV66T@~-s9$oj74hyFHk)XV
zo?)}6vwhPZ;ZviVxqrXn-}&bJ{PfDwS~$_?XRYmp<G2d}KjBuhz0C)14T1_O&(l&W
zB$Cf^0_T~k|3o=TtG~(#>28w%P<yLTnN$6CK$4gy4_3?w-z6Jv<|K<yn}pFs0U>zC
zPhat1OyU_!bdfn#K&T#2_RTWbUJc1rcL{{`(P3|!1l2Rh?|*e(OzbEbiYBX)&$RcB
zVVO3qE^OZ|sk`40_3kPIEkDRf-VZ`9+MA?&(1A7Mbh=w(H7&TFY2W`zaVNUPm*GO+
z?W%kb-^v>mT3}s-ang4(PJO;Dv%PeiZry2X%IY1g(4HJpL0J{jEAs~alMxZgEs2yT
zHZp1C>EphRPgM&Qmp2KWXdKW9ig<3A?;SwsFdZ{V8gT7-`-YXrz@jCmI*B^4wCK0&
z*GeSSe|Q+iZvK6=^GgW>K$;#4JcyNLX|V&RdUg75uHxWa*3U&s-sCJ4_tV1gB8dvd
z@oH`;a(7A20jRe?v-4K(wIUSkrOj;TMvwug&}YfP8!*M%1KXve5__t#0j<k-uIvhX
z=X!WAvsR~<uG@FCUvVzif@UlFLi$7i+bY8%jyKI&8-jkhBD9DGAa&h?Bvrz&N;~+%
z6=Q9(8!0n=1jSr(e4>luDlBc76ps1o!gLWs3sU5EzM~RjRmSZrJAJEmxdAUXoeWTV
zqTAWSk&QYlzIgL$Y|jcN!E>uz;C12_922Q}>LG3^j&q*+2+%S3O<#}*l_7ZrA#J4S
zkXLotj{MT*w)j(RU9dGrRUpm)ZX!6x>14K#swjkm#lXzaB*8_+#wG(r!3u#7W)FO8
z0r$IzWztc*D99uP41aRa8|8~QQxfDm;WF?MVn-SfL(q;2a_(y|2*G!!dtox!l$vid
z-BkVw`)1#6_uivw)4GYU9o%OIo|}JdLhCBRG;BlPyqFFO-~~iFREnm<-B<HAbp+8;
z<WtffqnLE4dV|R4niLJPwj_wCW6vE-@?F$g&lFKhciT>FU_67S<2hs<|L!p;xrkuO
zd;ZCS7c^n&6wT=_ODB-=!N!D8qAp<nQf4f?0AjqOQ6z8x<J3@Z_R=Nhhp&=%NszD_
zm&&Vg7R|i^#CkTfpxfB#IoIgEHEY<mOq$~BI9T5$gX>FEUxMzc4C%kg_^`(8DwLM&
zMIFoCpM|I|8n%Rb+U_dGnLMXNSS2@MSYB0=P-#ib`?RD)V(&#3)s>W+L2&1!=2ol*
zfBP|G@g)$pqVox}nrVhF5^o?qAtd)iUTt$x7jO~)uEZ}1m7_EsR#z#WHmu5D;4r#e
zOi6-G+1U2;<KZVk5%IX0BY?p5Xv99mCiaJVm{dR+pu$iHr@$pXgihT&Wb^S3L!N`o
zbK3z8Sym;Gc<34~*anonl~{8(F^rfYs7EiTT;6*Ry!^teKr^$YLFlBL5<EeC*wHuM
zf@|Y|<MaIu?jczgf$!k`hfAo18-R{#kh%)v3E!+Kl8>I&8-{4m&barZ?G6>wBPfv6
z(y#bdhk`pO8FCST>Sk7ND^cybv#SF2(y!sh6&HSU=4XeZHuz-p(BcE(Th%HR4=0U)
z{ZEe=NthP=m#A%~E0MdXc}9ZHtox{W2(o0rTQ(1|@t%nTt*v}`u*mwov51QEyC)y9
zJte~t2nwxD$E8YrnxoJ>sR@)!r0URxR#jp`lG49lCl7+F>=yiaqZT_KqY)WUcUTD+
z&_m<)xArj=v9wPM%(5FaWR`5;`R|;?s`O@-Qm<)(iL$+z?TdG4qHQ)orVZ|t#OB0+
z!BP)3sHlMyTMyd;MZ1{Wa~rgN^6x}#hMXA>>gEh4@$o+Iuk3=!&2!5L)y+1ARO?lw
znTGLNDV5xlYSOth=pYed7`&%$`YhUN?KPr#o=J44O#-LJgt-o}ZSBOhQXP0YnltAB
zofF5A%hJeYzzolKM0&K+>1Ya?`F#u^L3_^D&sX%hh=1jnVzIRqH6gC5WsMoZsciE>
z%OuKnuVo!DuvxxvuGN!JK24#T{fRfEdj#gxkKeC5t>ZYu*K<^X-Hjef`+=R3JU6Mq
zC6|+GR3jov+LV#WMJ!7x`;o|RF@5gCLCGO^^-mLSx(<As^sn?BY6{kG5S>)O^E6fe
zaFy(rIo@I-pR)hY+m*@<Gjw0y@eGt}3ZtV0=gk!WrMr%J@Q|INBt@noUp{_a<5mto
zfT!n;xG12j`ox%J?tbLOx8l|69yVx0pd}3)=@1`Le)N%VN+c^K%BswaxM5*w3@`0U
z$ubi>%Mqa47;u0dDjh5$-Fpidl1$)MlkP|KVwI`_@r{|`8i4cvQ?S1Re8g1JmtNaO
zpmt#JkCvO$7gS0=>!4b%K}|c-S;YvY#<5WHk1u7rnh*G2pfl6zC#?lAac@>}hZ7Fh
zJ)a^wnx=dB<j{zx{c@1J)Iq&tF*}zi#YJv)=ll)w@QO9^a#B@9mX1n*k(5V>f-2nG
zGt`AiUXL&{aYsJiAzfgfgd_xyJ7Z78SB``=8{3cJ?8kU!5t^3Gz+|ZyzO)I-LWopo
zhUpMh`5W$%emS!5#FzwA`C)8~UA55CF}SVD8=I}w=RLhDPj@pqWe#(R1E9EPS3PIV
z$9kokn(vBYojPWsESL`<iEFQ)=9r@_hr`7w{%ra|$7$glajt{1#G6pLkMAPbS#fB(
zl0SeMRJ~=WdvM?w+fFyWLi*snx`@|Mq+d(r^%ca`{w=8QyEKN#W}rLh-rof5AO1R)
z>i4@8Qs@SgFr>?t6$Bh2qwBo~DC3op@S7j;DE-bdqU}0}L!%wgA(1J66CFMv)uBa~
z!U4D6sN{~NYb4D|rO-rY0&|zlU%rXO&_L}*dFXDep(h#~)2*Ul{J+?G2jE_!W_vWY
zZJgNliEZ0CvF+p++qP{xIk9cqw(-urf4uwZeN|IkyQXUInd#co)6>;!t*ROYJlfOO
zHasTKGvid>5f`?B-z&UFwl(~bRUNN$k6d1jgD~W~)_)TZ-m;6JgeNI^5=eBd+RVNa
zQ<EmHKwbECmdOg?12p*nv{UvkliK$D_Za0amvl(WuQ_3|x)xR92${7&zhbxX9slsx
zN69lW++`wwwGQI~<2krdA{>7UxEF{}9zCla^uXZjOu11Tjh%Sk03Y88GT<-sao4d`
zidfbKyf5RcpA<}UBX2;p&R-^lRsT7q>pk`YG3Ayb=gA<HSkd(Yl+8B9eshdVN{83C
zZi}~ZN+eag%6urzV&p<HAEi9nSLlonRZwrVAK@q>5boq~cg8<BHWW>RmbeyA%h{5R
z$z4e%DA#6ZRy{6HZKzpxJkrIaapFiOTO3mI+MG~9WQZpwOV2E-!s~cD(+`bxGuadP
zsI*RPKE4fw{7dQpwuz<-stsOp1y3B<(+xPUk@WJ~TxIjNsb>r1JsNML^x81{g^q?#
zIB4{kJfojc&cQxzT7TFY%E^43tspJN=^FeYUL-Hi<NDb*YqO1t<*zQPTHA-%CL>kI
z4DgZL2q?xCdmYp2rqc+*Ri4~U_!bU`i$iH>tIrZ(tb=8hZEeQ6?#Of&1`cA$H*k%U
zg-NzVYM!}EoS3ddD_iE7PNb+*I4d6dMW^z1e=Zqbj3HNgtbM|SMu@Ofq1u8fD(onK
zpPq9yzifVgrv3oyZWh3&UW0;g0hqYh*#0MsuUd=8?vNen`hn&Va?(D;uGb!!h>J)U
z#Z53`;r%&7$6@90#!Lc%Dj}gu%foOqfs(Js!_l;D;RTvp62Qonl?C4)dUhX;!#DTT
zybbWk_Wg#Zi2F4Pv~c0#IWMJANWs|e$<f{O^+j9ksC1qVp#QlqLQ{&2zl**;2FL5Z
zm^q>utX<qO=y`08l4LQrY_1pOeZXD3;eMVjeAv9Bd5N&W><C2`)f#B7=Ds~IscH;=
z?r#Lpm!UUPo)-)8C|_bK7T>8!5p@kuq|l@aEwGn}l<O*5aZ9;Bw?(+RsEA9RV`6NR
z8rP4Q6hUwR$|YGmQevoQs%ht~lRp@Ky1wPK?!lz61~T&AtcpsN)~ce#5I&z(d6-Sg
zg!8}qHE4I>U*<g^_E|{;sL-fG{KBm>M#=MoX`#rZrM0ji!mwq|`amY^NG{st2j1O|
zZ6x)NLvs2)kATMNb@dLQbdMc*%48YBShbil0v4kID%dM&hBl&}!b%Qs4D>J*Bw+zX
zKX2<-`8#R2!PnrmQ&wawra@Y*`YSrt<*^sYs0;7ow$z36&SK5;GT{lI!OP?>q*r13
zvS%}<BXs|8b~B`fR(o3PuI#0Ks}G)%<Fw(H84AWaYE(M%I(1j?-G$a8DpbLO6XzYt
zI9pf%oeS>NCw_*E(vx`ChT=;!?Uj98i(_=*gFGLHP?s8MSDW^mY!>aDIYwQ~WrPt7
z<KZO~-iP@_bIT@SNVVA2>ent(74@$~%}<Xv%kvef$x!dL31tTyO#zo@qc*Er=&00d
zBHV?LWqfpDEwt#b!`j-f76ep3s9}T7YJLwu$DchU@0h}~c}P<rnoUcHBiw^ACV}*D
zvEi}(tBc!bpFYsCAU8|qaoB?;ky-?U_dAmgIY3lm)9&M;Xq_5`wRy0Jc%wfmxdwz;
zIIHwGbYZfX-=IJii-PFP+*$<}|3KD9S}?lM%EgTQ)<rBloEF6=DA;3W))fSVKbjW+
z9<+JVw?EGmwxLZpdS>Q~=O*Niw?%w>aYHh~Ph@`?EjYfwt8_`vkDY=O93q&)X462m
zNj<Q{dXx4wv;ouvNs2!UA8OFVDFk1lrJ#C!G3$*sKBDBFhLwI(tT6u3oeYoFEZ&?(
z2<pHaf`8l&v|sYYol6VJ&t5EM87dZFC>=9xD(ZSqi^)q>%}X|u7re>%vv3brbn?Bo
zuaXee%deLO6X$63n^;a1^s<D1#Oh+EkZ|R)QMoE|t(KzH<;$;7X&RPc>Ogb9yH^<x
zdT`?D8BbHF?``Z#ja$$f?<DFh4>lA{hXlJSFqEoIjQLM%_~`Tqk_8ndiU%IxSA=BN
zqgU9aH*P$!s%I8r-j)>BQ47$~MIcTEetHhHI4gjrhW6zqQNf?R?}xln)X!X!o2%B&
z7&PURYB2>+`j=AXh<P1kkQkadhDA_AHPGZRs@^!8s!e`X$s9B##cb4eOhJi2!7=J;
zPh=g!+zNbFI5Hy>XO-?J3ylvT;=n_;uOll!yhi0fI%Mc5&sNSb8>4HkP|>$VHngVz
zqy12z8l&ixLkw>KBwwFnAw(#-6BMaiUrX*Li;|LeM*gn~WN&d<T;!h&bQqzUsE2@F
zuz92Qoat4ZA(;Cw_E*-(tKAr;`h(7Im6J1Xh?y?Kxy3*EpkyIR%rXF^X_K=m>=Qir
zIiS4*iVe!`sdnztWo?P~G|+E!J!rL@5J5u}ZcC1q0;JWsC@0M;2SW4iIk`AstTC-*
zX?K)gGiiB3{Q2~*jj)HbTU|<k)oF$*s*{83ak5;F^&qxEu2&T2K6+oqD?xWl^qN%K
z_+$_;Ef=(qtP~dURj>h>O-1Gqm<Xxd+DRm_^4$yW$+h`x)0SG*T1cfgXX`t_iZl@#
zo%nUENBFnTT&t*BD1y~)d!61_Pur}erkjpsi*Mhi4Og0#&X&j>HCz|~<qPZfVfW}6
zmy|ume409j%$0e4H#<WrV+u)<6@vpUJGW)<<bD+l8W%x)N<M&+*+l?W5|FBlb!`F$
z@CL)7QT#>?8Lk&Gt}N>|j@BR2!+E2O{agFeShwcT&X#o3a+H#FvnnsWh6M6k-SVpC
zMeWv()}(Ct#u_-@v5t-gzU?J~>vw@=GEn&y-K=N~w}eKMQ_1P&<fpruXZsaId)F&b
z+fD})cpIRawcmh=c5TOwE2<*fgt)`a`Mo!t9M96U9^La+*9Dq~xAoc$q+1V%#HSNr
zA4~P&B^&S!7UAZ$+lG?zv<e!Isr0(F-1-q0@527;UTd?Kuc{!=-snk++`bT$Wdg3J
z$;$g-OcN!>qg$cm2UWh11@D|Rp~Q=2$;R|fy4nqt#z(-Bdyn@YZ2|;rpG3tD`oL3R
z3qGIfK0SCE%j<kKe)Y9?WKql;V1n=;!_RsV5NMkCKpdhYwao}!fve#PT3V=?DXP=t
zwd@gmPSfS1HhhDd%jVL&K_`n~w$x>`UG7@CS9<)|)gmRw{FKug9FX0I=uK*;7D}+)
zxy=g4Hw=OMt;WOY(f}tRh=>Y2?meCG3MIyz2Rs3ifPkJ1)va?W8{vn*$kuzWqAW$$
zm)A(5t=}h6e*`{8{z)(pi*kD<B6p*v@>ye&1GA>)vjF1)Sh?8$KO`krIySMm90}jP
ze+&3M?HMzT@1E)ycT-)MSFPFW@NWpB42WkQC(Yf&m`UHrUM_AtR+Xe#k`jYuDSC#0
z2_lu;)X^iKrj2m7&ZbwVPiL{uXuqQ_20Nx-r^9b#PP+!0SHWYg$|HeS98(K!s;&W!
zFz!&XC##x%^*93dxj-=foRJ$qLy=dsy<nji$h$z3<h`(MIlzp=a;!w;JK?~ic-(xy
za2Ao!PLc8)dr1V)ov%rO(ahuE6x!DI-v0HA!3n(0a=|JP8{q(fzqXMkD4qEATWxU#
z3~u5J256)Lp-A8fn0eo|i9&99fW`rkbK9247yO+mG<z}qKzs<YU<@!7#blO2RYBqj
z%9#B;J{S6&!BvtFgzcDS41i%Cpn;B<2pN|l8Cj6Pj!}Ex!3vnbbNxw4{d!}8TQkCv
zXMy5fFz><^N+R6{{{V;o@{1W27Zg7%%p<v1B!Z+V7?uSy6c8UIgY~8GbL0lNrWrkI
zoEhK!<M-HGhB74&6=yuVhdPz;2J7veH&(h7kZMS?W_Je@G2sItGElu=b9qfIc-DP(
z2fL6=!WN2qD=VbkLxz%vfSMjLh;A4W!tx#?!UolmjpGYs;4;}Bn7}D8h&qneU{yX`
zgBgt5uL5tv87-X4DF{jKKR^PYfZ`Cf<v|%uoDfTd2t{b$;tefm&=z15`)@&129y%T
zA=z&#UKb{4DAz#52=q9pP)~H?Ckx>%MX2LrY`K3Q*E0`4wD$h+I*7{$AE+{-kqALl
zGVU+QSnpQ)EA4vGT82Ea#&=lpF2VebT<`<x31prRIRY^$;&PymZzKksfJKHOpCr_g
zDhNg~A6xagO#&rI*s#ZJ)*mLYAc0Fu?@=<Obh#lUSdDo>?hTLHm+WRAQFGpVuu>=C
zO{m&)-SXjp!^b!3fZH)gBXa%9zyOcyW(kVIely~26XO%`po5QzElMIEp|}ll1SJp>
zp_}?wf5}_zm!0}B_Y4BC6x{hE@B0J~#JIw83iZPDZW^FL$6nx~>^Yzdm-r<1116Ue
zGUGYvxZqMiaMk&_#VLn+!82+Hm-5SttcSwT>yo0=i04xp;+yuuDnauH!)U~88uH*O
zp^EF0EU?Ho)n)1i;OI=q9em0iu<rPz<Y2mD6B5lAtn=cdgT()dlR(#5leWk>5r&fp
z`_iiQ8|%uH7kdkYSQivi*kH{335L5Vtj8E_D~1!~wQ!~qZz?Lna13HA++xQz?gLYf
zX)0lYAeA-2kcuF%`As%1WD8yi<N^BBuW2FvAagcHU`4!(PKu~R5`%)n2$?T(CV`jV
zhJf=b&_0>+S8*J`S{5+sgvM1MBIs&x%1f3+{|gg3I0y<3gB0!Ydk^s|GIs~=YhcKz
z{VeydPxoHy&2c2)IX0#8!SE@<R{3WUu#x*5tDk;1A^iKf>&NuXXpO(URG#4XX)e53
zrh4y1m$K-1g1UbWIT+b-DJ0@|AuzcUY~obKXzdua)%$NiVM1%P!Wy)yloW`rje?30
zFn0#tt2mh!PJSXxb_=yVn<&~<4U3%U4Nkt3+gu+#wJ@2Z8d(@gRziRQyU+>Z3jC=`
z-m+LBvvvMpUIA>hLa?RjHf0AtWyyT{I7rCxDwJ;3tfWfLJCt)8wlintt`doJxsX}*
zJUKd<y#OrWVN#P_D3!)p3>2P@XHe99q3XT{y<;suZ8a!8O;XChj;UTP<nU=LoVa6n
z@N~A&$PXdZFT9zV+zg#NSEU3Kd9_OBF{9Bs==u|baENLIO@!wZIF+7~p_<jJ%+!<#
z)l;NYwde-5au*Lbzq4%itZeY3IvsCGKx+-9@TLGD{5ub&P^d<I&aqa>(nKbz{Fba*
zstMM_{!dgv+-h^b86r4%eQAUTD;e1Ylw$F!RIBXK9+D=_#XTuiSO8P2+UaI>d3snm
z(;_^zy(JVr5=%?}QDwQ{iqvRlCXNwg5J1~oJ~a}aKMogkz44nWVaCBPDHc@V!?5|c
z7oRmi?}`7n$NFC^KI`{|%(bIi_fL0L->jAlfg{#<2O>+F`to@w$X|!Ljx603UE~SS
z=-4wjr>Ks$gh;`x%9Z0*VrjZ11`^Ck!uy!nl>drzjL928a72fOMj)=gRHET@Gr_@4
z)%G^lJV$wq@n7%OXsH>KU*I%JP7P=I#fakpeO5G?cGNfFO{z>5!e9s+SXdqBrc}co
z!SKL^G#<=#o<uL>9MUW@M*^TimDbV)a89H1X~C1M1L_{LK-lqZN96sEV3kprTE&XV
zu<%gWsLF;DK<Q+HBYyelJ>$U;+2|8MJi3U>j7H|cwd1HhA-E<~SnOmt`>}A?T6>j%
z%`$nlbR}0qa)HlV-X828YUM{_;(A1ruiZYRJdv$&$Mx|<PcSmtE-fvE<?KS{p5(oz
z<ei6U%9#iPcxNiL$N-?`e)TtAyL8)Gdm+yJM*?7B9?kO49F9?N4MygERZ!1EkZRh}
z>dhQ+gh^%t`ucW`Q7|DE>*NI|=yD*yh1n=4%8L+lR=kB8VntR?q=8Wb8Ki0TI@ut7
ze)?WjR}Snbc#-vO5>Y>~3HrjMy_)X~u_9df6ZRpuf_rEhV~FW1^~i}7%!w3l*puwZ
z?|>%LkoN-mQ<I~1NJ!9gPJXap;wB}&ITuj|qFN(SiM$8sSJZ$ewGw6O5sFa&dOqqb
z<SH6iCxRexlpBqA@<C#n3dTM%rv^r*X1Zl?&Ak^&7qxa4BTdYZ4OlRJ6Z6u3%o1|q
z;jf&{abtX@)&~0h3vMH&rp5F=vtxStf?~B{<^Fo^UmSIV$`aP)B;*^`o-XN&SVPrZ
zhUCM#7LjmOnqu_HC&I3!Lh%WJA{35)Y%Dg7`#wi+8hndYHYBgGn^$8Jy+$+}RE-_p
z;b2i-LQPDQ8-@!3|G3DD=~I6R&aB0<2lttcLM>#hO?T+QWI_Xg2(6^MjFB;ZxmyI^
zbk!J{CNqCfBl$Y2qdOSJOj*0=vYGgYS^9}+rM{v{rrDVOj!lxaDSt`^tOg$`gN0mK
z`qb29{t`E<mIw13F~zW1UwYTkWfzShXj=izH9&2RB@t>?JEfj618LVtBCg*f{sn5)
za&i`fCKvDTV1*sS>u$S!z|!21U32d(mIs!W>h7+^9?nT>c%@cblk-dXCBvT{q-g$_
z7-})Y#wVmhE0Q!STaG&kP)!~<sm8HE?2vpT9B{pQfqojXdN#1`OQU^7y%Gw?>!I)J
zPBPCZ66~=~{H8(m-dZEj*<l<Jl}4rojRZm1kroesXv(dVDzn$8QQ!ihsRrV?P$zVu
zw*vmGK;0B|<7hCTWvP+xV&>w%l>$>et5%m6%UP=#ysY}22!5>u$PeBi<=ErfNH*V6
zSXuF*nrk=<iWWwua_q#Z?ku~wC|NY8@E-OtidJ*;YZ!PrXjJ~*>Rh+puKKCGsXe)v
z(yHFJtGS*rHB%oD%0~RkJo0SRncArtnfT)0{zn(^I2~>|mt?Wy!TU_^E)AQ+W5?Ib
zvByE2$;;<qZMUlj$j8l;=CAMG!=$1g)X|+<8nS$Lb!hIwQY$iU%*cMa+0Nb~hkh$D
zwW_s`oFo!)zRa?ao$qX%cw@?tu>83{Iyjk#ocdU^eEpcf1oSNF{^=uDD~8Kr&88e>
zovKiR<O${?4lsVnRKJv`)y`1>-xtmB9{DT7lcg>GK=w5OU}$){G<}{Cq*G5lDEo_3
zv-7ypI90cecOH52%m~u1BK1noIYcfAc499)rCo=0ayqXW!wE^CWk3hY@nyK=?fSRF
z>QYMj<7P;e@#*X1#d2oVLN7#?J_mnm)5T1=OD#;dGjB}IqPwYRe`+SP@~9xrp~w4g
zo8I*F%9mvufWXu$Ezj|;N5n~hWJ5VF&+Bzyup)+2^?l=RX?U5mCe=>eYyf-|cM-(%
z)3o^$vP|P8b>P_X?)l4`xaDt}K4L4te?qO`!!BfsBeE56B>yrYZ~4k7^H5bf$W7u%
zhw;_eY{Ebiyy$+VK9E`5q50F*Lb75wr~a_w^LF$N2u1rQ*!)ubD{&=4%JDwY2a*Qc
z63Kmxky1ki(CR#`jTp`u<}F1!gx2OF&P(rJrJ{Uh@`5tY>F}h+Wk1{SXZCzfixPHS
zDxEn$c}-io%oTfHj}>;UALTS2>H6U9cl|5>xb~8U=Qc_E;$7sdQdA(}#_q$}Nipzl
z%?1brgyngE`MR<^^7}qqoy7v)XKqe7YIkaK>Fj#+k8iH|ap`xS<!jASFQ${V33;`A
z-CcHq7Pn4-(F;8sL9SZ?ZG5;Gne>B;{5joku4(#uHtrHd6!d!ScCx4P9E}%mYXd_^
zPqSy=Z>DV?Yh*h=HeP=pIso2m+Wvtr@8Vy8gKy~L@6_+m?<)SA(4I{&a379GOob!g
zH3m%Kzvn9horZI@Cxq`)OO^t=x4vsXGj&=yXbHJO`5tP9I{Dh(X{*!vGCxqJ6`!B5
zU1_z;xCyK6ivW&|m}rMD{gac-$|o9vmpAoqYnh{&RNk$-87||}lo6{{H>3%DY?5gJ
zl_b{iC#tP*@o!z}4F_6Na+w*Y$%{^_-wjQ;4{rU$@So1am>uJ*$x{Q`xu4wyK0GlS
zcYB1_Kjl9M`_>+O`a0L{Js;cr>H0)@I2dLF@90=#L)2Dd$+#<ZwDy{o|N0*Kwew*L
z&7BqBl}Ss`;^<El#oUWZ^i#k!1<!8)5?)*eEa831%5sgDfHd8|?HP(iOunCWEMIF?
zEQkbAn1D1JcUMud%w9Wh?ydL=b{oz8yq2o@0r-%sYtT5Bwk(jmSV&UHlJHU!5j&fO
zo$vdM>lnnX+ZVCnc-_uxCxImv&bqxL>lxe01zr!H<95L<Q;6S0ht~nTA}{FxO5dH4
zjki9!EFPVG|I(de%Vzly>z3j<W#$Ra&6mA1_#n2?w&pi?c4w6woMHG->-RJ~`O8ka
zXGmr)aE`zJMLRIXG4snQG@)5(VIS{`-h9D?$lbNU{Q&;L^}2)b4=sOjhImD*sr4Rp
z|Im>3Vj}&#BMYHZYbtelsBT37Q|OH1%TC^}N189y&M{HYLS9)qt$~)j=POkn=RUC^
zr@uTw)`QJc(|!1l>Q_kbv<Ku52>GT58BKO|8AuJPA%@==`6CqjE6@09s6sP(JKcPB
z>djj{1A>uDL2+gp#(zTy-t#iAD)AmQWTC3ne^>Ak8?V$(U3FHG2W30~4!UREQE_rq
zc+4BuiJjLddmIfy<7~3lMxLYptw%6!(9kG6N`U$Su2oGQlmiJpPhhx9%)HaHVktCQ
zV^ng*6NF$}uvR`5Xj%!Kf0X~Xo6f|_#Bw>pYu1*Hcv0`DdpmVt{%Sqma)c)QgyV&o
zgsZ~!O1F6@846;!dsG5o(dl;e@o(v>(9Z7Bx(%i#D}w57!*as&?$I!sOo%I<8uB0v
z+RY8Ndd)Xeip?U|kOEOrE+p&${I_R(bsle8)6lNmyeaE+rz>1`@}QnaylZ3#Foi4j
zJu9-N0PN!Khof++l`6x{B`tGVrR|&ST2U~HJ6Kj58K`DO?<K%w(5$(Ly?&mZZNv?#
zM%wdq>PdF-+8u#etTAIftE(IoGV}T?xaSFZkY4I`s1L+HeOvF3<96tLzhDOjR+)Sp
z*Z0Lc87^yDuY4vb><t&7HtsF~KUYTH;YfC0e5%GuVN_Rga4v}lQYuXAkK=v-S>@-t
z6uJ0?K<kA44>^GC><94qGk%b}1;)s(yPLoA1^fBp?%~v^gH|UW0_);ZccN-!Y24*4
zh{Qo+<6#lRA<?dU5V8g{EvVdgGgPMAI(X#m^z_`!t-bwN3i$jM{n_E~$wItA>?lmw
z&%9ejn8u{J(;=GB=)><)FIPQSVPMy1EOT+=CbhNU^aUh;{&5^{{RV$N@N=+^ugkza
z9yPp)7-7x))0q?s$9X8d|E=77;^{fyB%eE&AxxAKngLU=fNSe~<t<1;<51OZ%D*>|
z&SqKuc6i->bIkED^}fXG(~o)fx!4$9?49h8d!Exr8B6kM{=_+0yBsAPX_!8RA0{T(
zhRyFk=mx;X^?udEt@p)yN9`G}g#!(7z!QU8V9GlSs-0g2m8JNlopBG1D3`i-DKZ=b
z)^jX8Yzxju@#kk;H}8bPduV{*^bJ}cNizpqPNaoZ*MRdLOqrnd>kW(c8ad4q_Fn$s
z;fV$t7kZoqb)xk3ZXul{R?Dg14NB&4muE*@YZd_fuu9hJMj3|dVcsXlF&}xNfyWQR
znq_}uf`~Thy20hQ_NRAn;CWx1K&x&c_V=LE{t?#f3Pn}gjeo$JuQY1fRV%B1w(ns+
zIL}u~s6pwBxSx=<$TK6;6r&R9t_v0wN*!qwE%JYx?F;_?IS?nEXa~^tu9yaIi0&@{
z+{mZ{1ueq$8F1qOC-^@zDh$kX@ZToIsE&nT0e*~vmhkG|#T<B`8F^xUqt&teZ!_qG
z5_=W`M==@lBG7l)R17^SM<PqaA1&j&Ylf2^HbRQ83{ToA14*9tN^e05ZBbqnPb!{A
zA|E$iUs?gzmsrK$KTiYVtP|6w`d>$rYRqq{kspwHtt<2Ye`^~nCu1tpASO$yY&Iqe
z09HZS45Nn_3y^Ho$wt@mwB3ep#iLd1vQlwTfxcm@s&EUuTG7>CC?G^YdN@XN=rWop
zKy)Yy0tFU7OtAzL(eiA<V_P}fT+O+VTBy5~eMR`<YWf1QRn5b5btz{$Et8O$b>n@K
zb;CpZi!aBZUgO2Y)|-#VWFaAGaWPdLAm@AgfwBIs@%g&dfn7fmwhE#a6&0y?xjJxn
zIC%UDARVM5f?B?ZBqzz35ZV9upg1rhCoS_8oiwONX?F=p(W%#<WWa!to_GzOKRiUA
zNJz|;MOLF6BoiG{+D?3vzsu3=es3@CGD}QUf5>4tiIl!~0`FSXv0(c9TYbC>Ky`41
zbewuy46~hR6<ItV!8VaPaddCeew1J$<S^G!nsR?gHgBW{q2G@=@e1CB84N<jK-Zcz
zlUZTBrXqu!qOKzKW~5h9=f{8{W27f#{i_9~-N9RpsWOV}5Q!GFKFmF1RicP-r%R$s
zq)Wz{Tq&H@h$mjo7>Oq=dywAfAEtpJ#sK+l5W*-adAb8xo$!UuOZ{{5wbk@8_m1gg
zeNxq&fSZZNX8HB<%gLSTkC8Qf3c>+qh~^GlqXU|DJ5mb!GJA=3BjhgYW2ij9#?HpM
zRRGr!3$$N$Y;9~z-$ehs9t_WTe<v9!dMmu)TF!f9_;aS+MU;FCq6`cbfEDE#C<qI$
z77YvHX9SH$JD`*mO>+x_<0D^N;Oibovf`(41x$DpC<k?(hk*k}?L07T6XAD+MKpP^
ztLf%COA20VakfLNnU<cDB{>5k!ar7Sl%S%mxW9F=fMmolZ0nHuPFKU@*Kd2;l(A_k
z1@fy9Od+^ehd5aZ)t3$&5U&bTCOC9x1O5XzEGGQ!OJ&ssO0X;?xK*sTmBVCZ=l+_?
zK6q8N&pY-Mhc5>&l+*8y&57?$`UVX&y_PpuTNX1y6xT?tt^afNidw_F_{q(w7}_8z
z2qQ?vT)~!~(5Lb*l9?y?2I<M5sw>qhV(x7!n3V!9hTai4!E}KE0R5A_mIniIj7Dw2
zioPP2G8K!4Di8s(VPOIotxQCo&e;g58a-h0XiqaswP-8_U%?kLm>4iS(dnlgE?#$(
zS(6_ve3QjVi75PBkdT*L)2}n;XT3iMfo`dexHcG&tNFUNHS7y_E|OA>%Wx=zN!xPI
zehaIXj5K{ksW-)dR`R7(%-I<nR!``%Je;|^R2II0SVjgE{_oVJ$eB2cxUpKLUqi5)
zJ%3K*vmu>3DEPAjjJT$#H}x7=wBsPlXcssH1#_FbT?UaIbDQ22jI5j313)>1k(ZM%
zRy`u|X~L!sEThS!C`F9^vSaa`^1gk)$Iv}GdLj#BH9r;tRMR3`f9_`JYBEwhl@LuE
zwYq6s(!EjhRFBN2l?|E=9_QF%-P~VclsBLrrP63oWm2-B^iT|SvwMYwt!ev{HxYLu
zd{(`>M_hq_pDxmbs?R%}xzL<G!ScV;`2v;td}e>-;BDw>6|F&=NAG@mp|P?(bBM=R
z=5EBA?L<TYKs*oXs?4#!cy<-T>oc9@2ER;b86wIVwvd;fv|sIHbgAma+ub<**-szM
z1qFGB&W0*`jULu`Xz61&t{m5X&mvrvuxEGaDULY{9;=3QzH=9tDf@hk`P?Q{c{_Bk
zQm&w%fs@+=0#)a1=Z-PqpP<buO>qYnL~ZBQRx4WqNTu4baPsC093e8i@sY#?i`9Qo
zSJJND)!Z|BU=&bz<B#mX>~mpYvNV(Z5X7W8W<^u@+Oif&EWr>oU}lx5@u~!dYvOJr
z7D_^(pY{a}`g0?$!SQKV?wmV6Z3MakCgKVg)=Xa3gxO=a+;$~?#`YTj_-zNvfP-&1
zVX9pLY!uE_@<cR+Ma}H~h9`2Di0Ofv`Uodev)FlI<W+de#|8K;T)=o1P~5^{iRPNZ
z)ex`rUuS*#$T%&O?#;mFK-byNYrLSd_xNz+;HouA(}4Z*UoE{3bAEPB*f{0U(Qc%%
zcGA>sF}*FAyX?6X^*Sw*>aMPdwg#;nIOnzpIFUL7DfE^nD-qc#WICrmb`@Cyr!|qS
zJ9a;x)R`XH{Hdcp-!z1%99UQ%0n%2%ZO3)XV0)&*js29rcqS<g=ci1JVk_aE&1;(5
zSG=bT>f8|88qu2ZztWRcuueEe2c-@gm_lpP&ZwfJyt_GAKyiK<=HyZ1>sy*Qj}Qz6
zP<ONO%|q(BC64Ud!>@wk>yvYJTJwpIy4V{S+cWO+FMC1Edc~;@v66?DuD-xVD;Awx
zZo^6xIy}m;51+ua;Bf}u1U{TLE(TtVW#2Y<Ka7XSx4hT{S+5qXH>d%Q!1)PZi4v%#
zMBCXq`@$@BATZYuqUF52b{FgcV6%b%>G}u|Rhu5UvdXfl1@-em_+Qx?6jjq9AwRW1
zk~Y3RR11Eqte8>%5aQD@-LV_(tt-)Uji+Q$_tT{wT@37o7;?k02P3y23BHNT4hxNt
z!<3w-Z|A2Q;tX92J`r>EP64WDVOE$o5>zuYl;c3Ah6Dv};&%n*KQYZZe|CxhHwWh;
zrn(4>DUcx$3q>#3xY5yUHuga8HoUu_f75{xfeSI?K(h>-w5r%SR-<g1^T0@v{WC#$
zl;cj2e1B2tuu>W-9gu#W7WIC+96-{PvDLXW_6XjoRcHfw3EpS4C?#lTLx*^!!}$_i
zpMg3<-CI&AWJH&6JGTc|y#x#aFvIY;u{}U%$9no%VWbXOJBg}EA5;bD^Wg9A$jRG>
z=FI<acD^dxB(l4*w&YkbbySX7j#5=ouY^Rz%6o1LKZ3j~zC&lQr96YXz=R0Zicf|x
zzxxIXWr811nHHH2mQSzk7WCh?&`l!kvV5dtvA$!0te2`Nu<15~)4CD@68>x?Wl~kb
zJex&gmu@JtyZZ+m<ZpDBLhj(6#em>ER9EM^HqtZ;dSBuq4)|`<u@ejq=v4AL|5`t>
zJ%@(#hy68MjImT+tPn2M>1@NxyLT$#d4iz?W>L~4dmgXr|9ccTT!5~eR>h2Q!38n&
zyZ%;yKaa0dVA%dudI1Xv0LUaUu)!IW#v=}CuWXJ#ZFS#Uk_ZZ3=?-L}ulwWm2U^EJ
zhRKXgsXaMgKz^e>@**(vtQ0nPl-O`;rGkFI<mwG)6_nXTF}_P6<qwJgQ_(uu7bt?=
zOOd@*7kYuxS|!iS@xG?}hGA5Q#OX><k^eksaEyA!bDN$;0HtLRpz>9)0d<=-C<rbI
z#`Km;u`3=~1fh@*KkCh3S^l~)jKxoK*dA||lV4}4$|!?oekmDab|TR{faDL{%?PO6
z&jGMoW@C1ZMci_#z|-fW;Wzm22jQ+>E4F6JbgR*#74=l>(b2U5iFl8?<N)@PLSIu^
z>e3a&TGJv4|F2DEz&mjEY~J|EOl>(G`Vo*P!S)LiuWK%6%z+j+w##GwTvZQm6!}c*
zR^=E+2#?oy@ffp>q^#&&#Cf+uP>LQk0R?{$iFijx*BZ&VAeJBf-@mOFrvP1fZ4<AO
z+ER9ioaXj3BBwM>oj}D;=Y%C2L`M0}ivaW@lq5FpXu(n%(SJ&9BASdT^PBSlGy!<r
zr5@y5Jm2jC{j_HNm%~9^ppCUt*mY#2yWt)`VB)_qYX4I{%am#;hfSW!R)&cP=(7xB
zMC&@C*>;eo%Ft**6QQIJ2);_0y6z`n`^SMQD-;F!(?dQ^;3<*D;lUz9PIVz%og8|&
zf!#MJT-xN!nK1?(gyB^TZ9<fMyMboM#F|2SR9~+@<rkNA-TFWQppX6R0krE;cR+@3
zbvUHcfovSV_nyohC|pbn<e>Ti4!f{owx{Yo;!1`}d$Y4dN}Ulqt;R?OD69Yu0$0Rj
zqR3aLIFeZ5g*IRvVlNW+taL=R6#;oEKihihq8s74!#0^wifXi++IJfP*zjpRkbIFm
z7Q+QQC2-UE0pg%Wj<#bMUJ-v0fRl&Clb2WXB2Ezdot;Vkk6YmXUn~(TC(D25`TtT(
zmjBskCmSa#vtW-k{9y)49R)4YzqsZ?i5%D4o7eY>jq*og77Qh5FmS?rbyo2d#)Z(E
zOT+M|e|Q|rc>n>NRSeFOb&u$whyae9pgVqaPDK8yEG#%N^d+@R{=UZ}2a-sO4g_el
zb7^~hbJejVzr6Ts6VPKH{^d20rkSWWmc%5&4vak$H-*!#5oyC_`QnUCfdqy}w`%si
z=VN+QDI!-n>aHGUTuB%iO))S>RvAf78G4bkAhl7ACd!;txFGkUfIwkbpH<zUVTn6R
z@Zukqx;B27@&5jh>|Q;j6szx4k;-nxv0b!{at`X!9@`qn4uBNwylaSb&A4t?(4AtG
zNnSdu_*FhVag@w?kay+IviGaZw*d67oa@4?Y-M6EVuC7uoxk(*V|mLhc|%}chw6(K
z*c_4RV1bwhFfA4&s)Q*72ojx=|0ft75ozp&n-&>2cu~M3zO1KgLFB%)y+?Y0-h!=M
zN@_rNw=|>eJfIX-J@K9ic{IqFUdvU!A4&w(L6B8&j^hfknQSAWmGH~=gSDd<HvWwf
zO>vIKosl2!&lhlU(QxlnsGeiJWc&{ps(C-h$+J5oFIHAs`JRR?r-*%^)L2U&Apz_g
z@%i057OHU&Q_j}u&Z#^vWpe_F?O!`*A|ULf@DCI$L;z|dlW&f`ZdRs8eAL~ThP_`i
zWT+T5T+XY3kzks%L7Z0`J{+XkntC6Xiru2`XGT&?DQO{;>ve@>au>H2Q!mhY^Z;cG
z6c_!y_1?z&$L(Y46k@+8?WAldF=An%a$(|ldGoOTW2_%m)_LG*o%|If1OW{MRV~8S
z*SEeRv#on}lJ2ipT4)>#<!kB)sKiEl93MG)H$!$#V>3v!&l%N$!PPdxhO(3B+yPSq
zbMnDL&y~c-<YL+(yoq5)*2ZG54q;?ngwhGwqasIT$!xjo-xe36{H=FXvj1n>|Bqdt
z2s}ZaD&K~Q2Oz0O<PGkXfHsb6o}4o5<Z4O4!PwxOCI<XnXXCvj^3T~$d{klGDreyq
zaJW-*gk!WQ{9WVvfMPhPi7SLnNhe&RloDxQWbV1gHx!`o*>n=?>u%%uEj!V=w?0oo
znMIIvagC%=(}}vX;wNoJ4y!5(6jA#z$o7hla5EnBYKv0esD9d<zQ@S=o7mgw8WWQh
zSW0Qd0?%iYw7P!@I$SReTT(TJO~pnVmGxYofo528J7`8`m{NK(N=)_frHO*$=EiFQ
zHKDLg2iN<1OcPU;>KkY{+eY<2JT)i#|N5t&s>Z~EjC6c>xrbkBy{!J%or4M5Z`%1E
zW+cu*QUd-zd_%eleU`!haDgW@&#zKcVl=$r3QYmKRud0zz)YGpdE~^yfdKu)QJ%-R
zsY_F{G#RC4m&&5R!wt*r!azxCLx-izBPfz-rFd3Q;&z@+g|~h<$qE{lTx&rIzK$B~
zj+1jw>9YxYyLk>I&Y|cJTcn0YfZc_!K0bYQ1}hpku!L>s?)fD`s$0Ie_kAM+&8!sL
zfJxaq;~B>vUkAY>zk~)jM~kMx=H4a7n3QsCNkI!}(S;<i<ky!J@nOz8LQ~1R41&xg
zf))RNU(MKuFsImyu!}r5=I(~r-FTp#D&DT(tp3_=!SY+=;<@3*{x?t)EH|gq|KJ)<
zuK(rC%sNaO!a6abQ%?ohaY)UF)s&AB4=1gN5{y<~RwN<CNki(s)T25~YCtU;2gkNG
z-;Hzg>g(oyfw=6aR}wb+t};+AxxFTVsq<@44;;|#hkMLU%<=1yMvNKT;T9E$X8@zv
z&4@?O@c6^hw0)8Mqn8hg`gQrPwX2sdnfla&>ohW&$lnqCeI45|3b3sNcCfbPx)BBm
zA03ZC`Gj9js;c!GljjJo+JJ$A7b#IP%m-<{8qrgXL4y25E4Wb7>kuAFd&sF}Q0{>~
z2^AEPY4mHfK_sA{X|ctC2`wY!Iv^az-Z)68JV@DHd_}3IKWkAYWxHfYvIzq5Gu%xX
zR3#_7%Ha-dOTF~wa0-&I$TbXDjmk;t1Wio3z>ZAyu*&7SZRXsC&HzPr5AX1)>@~5o
zM}}f^x@hj_K@V856r1-O!a)*KC(!HEU-K=68LEMW6&)_{<RzFCDVXmV-jh&K!f#`d
z^0?B3c@8%&-PysZwj53Ei|kK&W3zFlozW?*C8MdQ6@sLMkm5W9&#^H&p^E0e%fu<r
zFPHDtTbsR&ORcEvyaA(qk6@!mgWNir9<Zs+vjpSFgn*&zYnl`L&gaEdP*bdNdt-&I
z$#-cGv<!7~Rr2_#2l(SjCzTALWwbj!C&5&Q0(?(P2=c^kd%vk~Qb<ojT6WM<jZfij
zQF($4U-pmeOMceGDlYEG>;+0zK6dE}HwwyPgMZRJEQuC07XQREVIEy1mHFPaJ_(hv
zL3;kfrb_+CI!u|W*7(13l>egjI&LdY5`pCnuRGOJve&No0A|Aezpq&`?;|7V!*O@I
zhcJzvQz7UqgPlnzu$WEK$WV>mFE~yM;Rd{<l)W;glt%j?wQ75HCX(6juLG@>8P$#Z
zsP4^oaxc)}gY0=b1Y&+mJ+}=M`(x841vD@}-x~mG>MjRob~64gl~Jx<{)%b9LiIVy
zeD(C#eiS(niAnmf$xCLDY8xl<94rel6&6jtc}7B>;*V#j5!O-cZIL_gjm+@9^ge;P
ziYNfl%kjx~Co?AwZ|G=!_dtHSqfF`!GNar^_&@l7i<yX#$S##_5R)M_p$QWk!r|rK
z$ziUwz6p~U81uUN&*6WVlqmT6PXLXD@qgwpx(d8jgN$%nUo@<GRAk|yLd0M-(Ee~Q
zf<7G1&emjXtSyRJ#6Lat44bopAiUiaXH=D)C5_|)u4JWP5Li)5L5<oH#E+af6EFzt
zWp(OQm6Dz*OB81_j{UN9F;gc`&3xfEv8^A~blZXlw+5SPfY{!b4y!?K$SiIiPD*Kr
zI3F9(69F2$nDwVulzLbT(m&#yn^y5i_3l5BsOvynl@+Wt?pZ}y!)wyP|C;2hCLdtN
zTdJ|NzG_=(-UYuT*3+{ve>=FbRupuX@-!pacr76Q3-g;A-aTVHg#Q)h4dHFz{)aFA
zYxv*z@PD)_{MMKxpd9}K{(pB}vaqvq{ZG$iYiY;gwxava)b47lQ;r{fDS<)Y@kj<9
z8<EOox;7%-TV6uVNre>2W_`c=nvJgIa~Ay8T%EN)f&1&k|NAg1#vj@=$fS>%ge;MM
z7blI`Ia<bQBnm}Fe4>eY^3;#!+9TsQ4IO4i#I)IXUD6bQp93GU=J(dmLcx0)z!k{#
zi}8esaK<zIq{(QTax-?)EATHHY%gmb_<kWgtllHD2(b5+=Hehj-RW%?GHrs67z-5|
z7IvV2@Zzu$5)-&}u?h}otbcJR2?Q{rc3;sibh<^g*Euyqq}w|1ycBmVR8rX`49@k1
zfnH)^3tUD3<0B&weE1FHmXPli<5mI)l9E<K(jY!0delF|+YH(;5F6509BBYtDP7wO
zk|BY}w+_5Ez=WeTE|3D20;ezywF@TiM&wOeLa<p#UOU&j7XxAt6v!5&Y)lB6tYSwf
z584o`B=huqhwyIzA_)QVC}S7|+%KqkU)c*Z4OkLnF3yh#sYhGWfUL`dWHY69%nJ!m
zW_n~4MO~v1De?Re*?oKtPm_C|LtelSM%gU?UuXO+(AGwvCVzckttxs9X7qs_`5S`S
z2NXaJR~bkuPr~>cp*Q{luj{XZLd^69@_;X=V_Y&Q!I&K*s@sEDjSG+z1TCbb<puC=
zLc-{T8!Y=czaZaO<c(?s$-EDALHJjCVPxo-SfrE?_3CE`WS^pr6-D)fq4W`DMT?qa
zkGJQ5lZA#xM)m1RAqPTn#19G_rk{pUCCGyHLrqGdBx;JTSyR$b$<j6wbl?ou!`ES_
z83183PKZf4r-3hv#}QX$^*TXd?*d4{kq!kB5{)H{mP%o+6-01EA_IHc0)JBwN<baK
zo!R*Rq3ZKH!V6{q=Jv$eb|Bz{pgN)~i_Qn$hrsT~BV%U{@&Fbl5oQeQ=2Bpm(ESZ+
zLKIT!pYLy&v#;^XfLAorANF@R5pvzOkV`n{6T1QiFj4|AB-^MkI(FGB(Jz3B2pde&
zNthtv*!k|sAH-9|G|Go~S^v#4q(FaPI3ZTbQ1ieuAv-rpBvvqvHe8t>d*i+*Qkj<+
zX0YUG<>}scg=`6gYd<~XeM-vZd?1t!#gIBmwlP#DKPWW*dNUYdQR++ybU35S3rAL7
zA_+BRJwps{$+19SGL{B@&j<i%2P)|iI<@63E4~Z~Oq39JUdz0nRC!+9qlzgRI8p?-
z7$xs06OJOU-<tplW*?%G!job>p<<Dj&>1G$Tr4G9xdQY*Ez3ozy}06G)EwAB_#WgO
zoh8f%0WBp(@o~R@C7$R~t?g3u3KWPWb<$c=-$Bqqfp8%f+AbRfb8`UNT4}Bxpu0z(
z5RpTDn4xAebLi@+b>f5mOEy`u?xt2oL&4@e)Io5moRA(<CHH+V6I_)N&MuetqX?{9
zTW1aA!B!BwDz`yP0s10zD<DFH-@7vptsq}l!6R2ltG+FQg!H=zJ<YTYyt<k79#+f5
z0u7_7W}cG1j7a`2B@$5CO0wxFNCV0HV=8!o9!=CFvo36!o)kLD><~P7Uv<t0{NvQk
zy?NR*@Y-|3^j?|th7(bKrnvA>T9HwscqD#sdm1grtoQSn`}6CS(<Jo)kE+LK)!H`P
zmZk$Uq*I)Gsls25Y=b(65j$+`5_C>{1UdU8d|r~C&_c4@{}>Q;Y=7bLi*(nL6i0u;
z3PgOk_3R&ZD&sn8?;Hdlx?howSr=W)#A~=WUVXs3l!m*bU5Kj!74yic=9tj%Uc3Rb
z`Blh%hrE#FpbR?pQOlFmgUiPVuUZ-qs>S6jz8Nzfs^t!UGN{;&WcA$V#1esdVc?>6
z&ln;*9zD;w?gXe@ceXIV=jX0v?@8We*q9!Q7zym&^~QI{3LIE`?z^9y0`G_p2wg2H
z{B|UypB3FzYCW67te2HGnbOlMDpaN0<SC}HaEG($X#E{EA1ql8yoFw_=!Iyb5s%Z<
ztNu{D&)sxpp6ubCr4L59lx5Jid}48m(6(ZuQ}qu1<qV)t;kTuq6df26wO-^FevY~t
zTa~phr^gb}Wqh{CrV;{gtaAH}q4Y74lH(5ZPxWc)%-gwtGt*(N{6R;#==IrK(qld+
zCYtQ!Pe!|Bd{aFdK&X_Ov&KW2y9HM?J$*jjT_@I`TN89vO24QOk{-lGDparyYhu<o
zT43+EBMwkY--r;tE1OB5Ou2Pp^`V72!OfU&h3}DM!@Xw4`nNTanWR13h8tt4Ve-|U
zi<`nZ5<_SLR=N)Hh?-Frzsm8?v|OP+#L!Ui<?Q<HoY#Wrbn;mKKB>p7VcTlSA7wuJ
zU*-t<uAv9{{K5TB<@(;;e6}5x44pQu`nId;8?AuOudn;IZ5zy$8Nu(p_ld2Gt)~f^
zdiUqc_a(<2o7gY8bS$3@AI@jo516aQ&?nQO<&6P{AA4~PNC=H*-$os~wMe^^zpj@j
zl>-BvZb+rtUtMJy<)~^U#z&?N9gwjws=0zb%{RUmh;%R*J*Ib_tt10@F%wfIt#AWB
zfLcIn<<?DTM5x6>nuKpa+h)z`*7f(7r_=Ovg27*n8^jTD!@qh21i{_D^<F>&f6vzW
z)0^p+U{O~9FA-!Hyq7$#Iz4NPDNYnx!635oAZHI(TeeGmD-*oz!Xvi&nWMSD6OO|u
znk{jF*Uw6JPxAr_MM!7W!k<6w`pDlAE`)#uq81OCpzpi7?Vdj)`W?V6{SC!tfA-c$
z_jWZGZmrXCwKx(wjNVGn^i%8eZL~jCQ>z*_={W#+<er<^z*Fo@gy7Y6DZ#Symwn_d
zP2rZShopR4NpJVM_&ZzSw>4S(V<|K2ot^se3=#_i4nColjoZ$&=u_MZ+c|wxVs`+t
zL=Bd=mG|4a&8i=_7K|`<%kqx&qT`392sr+6J(3A_$ImkS-lh$LlKUDdyZ8P~$=+Cz
zS4nRiu93|9qS;JXs_=>xx|=nhRzPTfD78LGxzMw70rRMDLUseO7q+C>Ou|;qXbr>Y
z_wDf)ck*S+XGzlE$)e8@lQ-!Fcrt)gDp3c}opVvr^st6yzb5ya(b;Nb@d9ZILYD^j
zmC@N@M6ohe$~uZQ{sLJ(X$oyJcZwQ+ikfmt3V(`HPVxJgQodO^Mx%=O$MMO>b)DDh
zjtgW;<@g2vwwuD2E{B%4hI}j3@xdN>@XpoK!<DOebRzb7pR6PO!kahU;U7SYw?Hc5
z#ylBeHyLljQ9X@RYEZ%|bK=YkN`x$>#YvPHn=Xpf`ZiOhg0+yOHpwOBJXwAbJhT(^
z5Lr@Fqyc??TTns^0&Ol<M^M5uC@nrgex_V%&_1dZH>XiKn;Bnz(ZR2jcN=TQ4`~U?
z@-b85{Gvb-3=}ELI!$i6iY`D(=1Hs<-RroO$rFw#q2q4MgoNWiu!8J&Q*3E5(-=YG
z<r^m(zD=WZ)zo}EyY$E!?bAMO?%J?1FqLCS(LsrnV7grOjJf$xc?dJUODy#|vAW=R
zc``z+6$X{4S$!Bf?9-@`#4YhaC>o)oPL5NqN~7jPMsv@ufX}kOAtT_GD1&x-R61Wr
zno=3Mc-SDWeSb9RthvC$CCxuwN+jQW&Oh0&F_^VQ!KtL&n7-{zAomC~ue{n?nL$0=
z5O=x7mOa3RXmAZ`54vPDS>u>HbLLZ<$WezYaSt^D``m+mZ%sBZO1W5Pp)Ox(oDDA1
z@|6~BK_ILV*%XJJa0x&*aO^_)7tHX@L~NWK(1P`D$`q9>&_f*}mo@e4#uSu2U}j_u
zO1@rE&*Y&JD`lr$W(ca<UUE(`3>jw+<<dGxtc~>_p>6;mfXcBlPM@a!^WB_UOe=OK
zJfE7Wz?>*;4Jx`JO@8Z`sI4^ZSFLgTN!*=Lc<Q;g<hZV3%p#!g-`$}WCz;bN*XTJK
zSreV6LrMJ}_j9nl9csrA3TMP^JO|FsUJ^Qdcrt$5>^yP{l!?wo*`(yURAr`X6`}sW
z$BmcD_G?+!gW|xl+3Lq{TVLkwx-aZ!{s9Q{RbY7SJVV4J4ngXh0F`YBD&ETy=A3DF
z?t>%1SJXHzPO=*-wVlP{nw&Tr559W!aK*Lrru`(05(e1|JsT{4W^koOkkf=;gAuzy
zR%(sOEF}|`^=fO#!<k{`nPN5BIJ;8Qnv5*6H7N147?eDt=yu0(YP`(a!$rDf3xCf#
zR+-pGVaC-AS|2M?zcttonDXH>#oxbw#@kB)Xm?$PGx6MQ7I6+0Np{sSJzD81sC|=S
zv+!X2xQ55)Y0cvyQ)ekNq$-6j%K6DpdMidzxf12}*N+n5ESNMZC*s>#bdr5D5Z)2d
z_f#^zon!aflU0VlOAQ;V?^{qPTU84~uB$@krXXm8B2Qu%n;2Q@o64qc%-Db_hG7Q)
zdqxO#?mb}^Ypj~hfO#cWq)BVAErHuc<Qyb%?ibTH64(@eq|ZiCS~JU-t3Ip1C_2`I
z&~BF+pSLEK)HT8RjSIVuCC|6D>j8MpHL-~~Y;Y2fFzolC9&G}*kILHA+Roh7n~MX6
zOHBKXo6gqA3-yn!^Szo4eIJdl7T>=BPp=>UFYjOoRVZ_5hKi51i>>FQ`&HfUPoDUq
zJbkO;x5`-n@;*c4;A!W}*0aZt95+6N9-y9Y`&r7TQQKvOpP=K0ASUw(gZr5<=6Ppf
z!D-;??spE{o%!%KJ44FIk?Bhff5dZqqT=`DUo6m-rEY`GL%omOhY)eo=#w0PCN5XF
z+)i+5Ey7u(<HT8{bEXN4kmLI@*Llum(f(sF+1LDt29Q4v5Zt36*f<p8q}9yR6$QuK
z|HIZd0C&<Z@5af-w(V?e+qP|+zu2~ICmY)~cH?AY+q^mF+`9jJ?)|E!YTl};shaBP
znSQ&Ur=KQk$cE?nloXu=AnUTKV-U>W_k(MAU3vB`8xfeibt}B`ez5bD+%AufO<z!a
zLDu%-T>fAA=>JYfSvY}N|5GZ9YX7b~!a=#YI6}|0R<>i10b{7%n_&IJEvdFx6ad!$
z64la;7nBeFi5PPAf#$4Z3=2NpK^_dI89`c$Z5VT-wg#Lfv7YR-vn>s?8WhI1EpyZ@
zqpzYeDkTXy-?`i+2AQKWuv<<siKKO2LhJ}4<kYJA_Yjnslv-}8s}Y#!_0#4y?dWXx
z{@%5XlijonGGLPnFh2!Bw0e4~F<UfPpp+BJLIyNHYQ(|CJxGtyF-)`V{R^Z<h4*|$
z6p!n{WQqa499JRHw4Yv2eOGJ80#kfaC62U&C8&v(IZ*1|yHgv@b`+3KW_eCQB@4eg
za5I6B`vgPL%JSsXdux2Xp1idx?jY$e|C_$^Uj@jIK&8LmqNGJJ>LGWKWnC_0|6rr<
zEdSpOExj%ba=1-4BTW)5CDi>uY$Wfrgf0v;z#1la_siTH=_wHusl_*Qq$n+XCPjH^
zId>!g;ppwH?`jeOBnCnN3hwUDkr}-{&!J0BuVW*3dSpGnu}yES@<kGzfS3Zl+IZOV
zt>82fP`;~vnuUFuFer3?KFIRBUms;>sF=JAKj4OI7yZQ{UO#>Y+^4%2^ZKRJkcbir
zV5GhQ{rnl0dqN(Y)#SVptQ=12#msWpP`C#_nhYoFkPSK=?7_I>7?v<e_wo|2tt5n~
zi^2n}Czan|*-I)a7ZW$S=h(@O+6+^86}=p~3p^fId#k9|HRwGLPDERv=^ifLZGFMZ
z6{0{&enaf^Lr)Ku#=Qb!hY;*1jPp+f08G9-IN==751#-l50M!xZm|~T+vtmJKj`s|
z7A?Dm9BFcFk^#$G^rYGJt~KIqiBQtX67dwLc9nq%<H{(H`RpOjY|YZvilo>%_UBf(
z#XA0D@x;O{3IytmlmV-jaO-qU{ZUmI`dy=fvGda+sqOQ;mLEwuinkG^5m%pkfO{=N
z)AsC9$*JNb4%2?k?7D5TCyRSfTf<lU#WeL}_t$vxU+pC&Hns7yM-Hiy%MQaj%2L18
zBI2^i#K+N7DX@y((>@+*$F1O`bh|6aUCA;fIwjdPFY2oRY4(&o{m9)BcHhD)%Udcw
z!hhBlSLV*NRlEDE7fHdoQ_pdqu^{0DfCc}5zhV9PFS)<8ogNHgih9bxkj>N%rAN%9
zc?c_HBcA6cR>j9T;ZSx4dwhFxs?)~b6T-JAX;i%!_@XIsP?B$3TXoyB!zJy#-A%33
z-rx}*rEPTR0hhkIY?J$r)vor0vp)oGo3Z7#=o~nt7yl~n@O`73_dsDS7Q~BFzdv`=
zqI)q&fd8h|_hQgvy+Au&{L=$6{l~GX`!Fy7+jij4u<uYqas{@9V(8<P`HIm5jHDy+
zKoL+7bvpU=q8$k}8tD1e#?`}VDKRx?hY))-RxIfr?L#mqdvp<h^b*paG1A>Ckhtk*
z7&wo3j<Sykfkc4=31y2wi}r+PYo8Eeqql3(FB`r>*XK5+Dn=|o#kh?S*@BvIFcfwH
z9zeW~D{H_4Hb=A|cQPq}88y%8K-*iM@&>k+aK~ko-Sm8h`@{zaz06D3MHhL10UPeU
ztT$(+@qno7)5GRzv6n?hoY$Dv!jHH-?53e;Rzou8B?*IpQ3u1yz1p-rvnv<Z8=kAj
zdLnm14&Uu%$s4{IX<kDinQJs=NnU8cGpE(qAk)$b$))lm<jN}NBqS?lx=G+?rQ;+S
zNT2pKegcpcD3n0Jq|^v(d%IKdo$0>%L1H&k^<7PfZd)rmB*s`TzZJ$I;poKxh-HKk
zH-xs3%bLPP%H&9tnyfVGU-Hrj&46$r$w(2I5fcYzsXVRUyAhZ!^x`4`!SiqcNwfzl
zXY9I1a6>wHV>u!kD-j54DYhzY(6&qV4@pikiUQ^`Ggjo%JsbyJsSNh}t+MTUv%Sr~
zv5xax1TS{%9j;xhzbgAkhoE0J(0{ZJ#|%%85(upxk#&F4<f^qWTZ+n3QBN7How7-%
ztLu1nlPKzNUkjUK($i5(uQ=%fwp=o1w&#;!_vYH`NrNRh>ZI(A#F^g`7`in1L+i%w
z=Fv2DQbaL_2RsV|iVZ>VZBAVIZ$$6R;Pj&porYy1{44Kon#u7d@($!RoGp594a$C#
zHgOg9=XQJTmT$YTRC8lb!X1p<rVbj4Ci!jL62!DZg8YwD!u)Ibuc9jJ&;MvWf^hy!
zyBzoi4p(Xk1FO)2?X=Y}yp~Oxgkp$J4ZnO*MlTD(Nae}z%*gGttEZ$nX?J{1Bh=dj
z*d+=abJeE5;}7IG55Z7hns4j0j}5AGqjS+#7E*tO{$1<&86&rTto)yj>s&zt@gEPe
zM9*(MQ&sC-I~o&qfgEN)Gs7F~46hJjDl&9@fR&Xn^m546!M~ZR+QnKaul+~|AoS9S
z7hG{%yGebTthlZu-X;xa<cJue0}7D<b0n&@SO9zG@aMcqN3ABT_)x+D%FVcgz)jys
zP%=kzHp)>djFB=kyd;j6tpul8L-)CAcQ5{<n=cK#Ub#_&`9g-TKkMryvwkxhx=n8b
zMTWI6Cg~QxjO;{Z%MA?vX7oSchpa#U9r@XSnbItVFbDuOYY9fzhgQuh>kGs!%bZmY
zVQiE}go1>q=paH+<&dNdV5ky=$7H~yfr<@AWW*L9e=AL^-9HVQy{vMI?yJ@0KhXKl
zHby!#W;Uj0c$lyFn6I9AW_z|fS<ny#=2`H%c0Zo@BK3G_yv9fEpU?P7QO*`ogtI_P
zB$H9aq>}()k~}0aFzGUi_vs2)6>q(Fdk>0!KB5rAgYzmtvLuYHDkZPJ!BVUgT6qa+
z71F;W2d0M9L&iMs4ntv_RVqCPxGghfbd7{M>PZEctQL?(+9l9Z&rn>k8RgTlO3;R*
zUw)b6z=nngH&sLVn%xGf4}u5DEkP4lH?m}KX2Jo4qWN@DQ^|`h!Fu<h_(jeZnHoi9
zOY22?1(P!9X+)V%G?#2x;{2ktBz&bROe+Q}2&vPtMMIQ|D$>dsQN?3QMilodB9=%a
z%fP53wFJ6Zq6;g4sAIWg5Q;DsHU~jM513ef1-`K6lM6u8Lf?ZUv!yjR;3;W_qe@oS
zmQ4b3?g#lGwu#kh*WlgARJ0~w&c;lpPOg>uegV7hAbBXo)%DbN;Z`cBo;(`y5&W*+
zYRr%!4a^+^`2j%;pQwS$2J`V7Ep6O()_?|*|G?Po2Ye)sf^QyVd7F)O1hQ1W4ZC50
z%!)7{7&7oaA(r5PS``co9Xh2T+3%WWA5a&-lggi+2#xC<jlO<Llj98)48F6$Z4OJz
z!ng#ZhJZow6)$!cHnSi_$=DtG7W|Dus8z9CmjwC{MjVlOxCbd(^=hO>9GrgL*)WOR
zuha7smFQ%arqHTJVKSBcj@>n(RfCF(A(62=_R+NTcOykZTgRO0@&!H9G+8ev9$`TM
ze#aiXUDu$5m`^|ug{UvpcJ+s0k2iSye7@gwxxC*W9u&2HqqF;3cHb+V30`<zhsk+g
zgl7HvtpGj|k%iF{!cw9m#d#{sU}FdTPb==fUe~&|%;zC@S=rQY&>lGG{RBh{O}GbL
zxW+QTUne^$j~)n<SXs49&l?Jqe~jn>vpat%YNwzflM5{Z>ULaUyws{BsF_3V)=*mp
zy<oVw?S;j!S?bh~^vvwlU)Oa;p9ntAOXBzkcI9EW!u~kI#R_kQzA~42$@lRi;xq0+
z{~+sEtmJgmx2bV&=7h)91||1<8g`x*2mV+=V^#m5ysaw{I3~fA8I5O84Z>^!AeJ1z
z9Ek!^US%3gWi8#{x7CDt@t1%-L#TZqHoFc8D|4Su!{2%MGP-8-$?9C|J~u^v)mxA%
zv016$jeTTi_j(GC!C}77LLMZb?WfJX-s|%v+tAqfihQdqd(v(TtrgA9q@L1m`B}jU
zP|sTI&I)^sd00INlhbLq1Z%1S047<;y7F=jrsSp3rlqBw>9lDT!lPO1g8&Ic_(v(b
z2Z#(hW~6==$Vb7axIKupsYWF2*R+m4&|6QT*#`3<dNPLgS~NRL70_)|6qMBH$*XHA
z?D*bglv}AF?dAa{ox35e;!h6Ikk0HEa<35>S&*2t65TqwC;hv^{tgy^F9i5?HS354
z+R>(V6XAfh`-pejJ=}`NU20|xAT%Mx+{9;8PXnu+s(vj^Ra<x5<MtmE1){o1oh0o-
za5#kHw-J7}c3MWKQqMqq=ZJ6d%Z+doz@8i2>uZZ=u%0+ke?<Mt2B2|YpXu>K<~PDf
zCE6kQCjT7k$=Fx1^xu5|`ucV6|8}-H#rN}kaznDW=x=<vTD!}SYB~hgRV(7y(=Q7m
zNm*|!H95Cl^y%-$i6N6^2#qAEECh>>ZXI;)Xy_iLLH4eAL)nq=*c}2HK3iy%q3<Cc
zj+xq#6*pmc49VTKIsk3Hoi3pD;AruG{ra5(c2lqA_ZvHrU)}l+@Vf`|3^#4bTQ?S-
z0mp>2>OQ@yK@hwRX?4a-$jZ}fxKc`5Rufdp)RmO8KBmTDW#*6idL@03u$=m&90`x1
zqz8His3J<Fpzl7E%i0S)_>QG4$FapWpt^Ol`!Zp`<SeM|G%p%8w39<gOkseD4^mB&
zc@17&t6L#TYZy-x;CUjNDN6ANVQ1Wf7JiVbEtc}NEFquj*Eq+(rY{`iEg*=2JIf0(
zqb*!nxPzus*Cwsb6XAZKAT{>zTb5XS2lrghhR$&~r579mwVB=ro*=MOpa&d#Y7R8r
z@LJ0ftd)JR=8viQu`AtbZuccRf;>IM`!=^H=xzcZ&$jpz0KUd3^!^$B$YElV0R}p`
z7v3DEao_X^EX>J*blxeJJcIE$L!qUQkXe=qg*fA&sIL7wqrZ;V<!YzB1=1Z;Cn6vy
zPd=}AWz&Fr1KNCke8_s=HIOe{7q_=}==aLf+(=N3i@i^Xwf<A>FQ>HtG=duSfe9U9
zK|v1>OE6kdfMukUF{=&azQ3*9f#B^cj5L)|C|@(@ubSreis`E?4PSY1f*A1^%ni~n
z7oWvE=-%hC=p*pRFGCDi+ru%~2Zq^@6Dyt|xP&s2wSb4_W%^Xo71XW#Po&(+ot@9n
zodh3+J{|LGhj){yUSMa){ipxg$oy*s@t=)M8n7)E8GxDjzvg7<Cd%3e{e%s@dO_o~
z%Ovl?wjc{$3RN>gK4a0kkO?}87ZV7;f4#yOtq#Kz%H^nw;olu6W^iG5z8ZwB49sZF
zv4fQvoTl8tXmiU1C$i^aWuSOc_2p%fPkngSd+O_M-Rnu#XK192dN_M=fil_x2uMdR
z`hwxp9}(AGF2ed2tOt})?QOg@0hg_Ayezh0(O*Zm6j}DUyiVlJG&-f8vc>Yx1?9HS
zHco}WP=15=KVzCfl+S4Dm!6n&zXg&&H{Uydd2*&nSM^vAE(mB;5L~!nNf*&I5?m&@
z4<T!E#o}H?DE@-RTc36k!6h063^6(hWfR(mv!{ZefS-a}f>{k^df0N3$KoZ~NB8_#
zy$A)TPZ0sQ((!5>sF8xa8pk5V8%s?$vKnYc5C-WOC9prjLB6Ngbzm8DU+D#8QML3g
zUVBjP{VYt=?#&A;rv7i+|Ht$k|Dra0?<RS8(zu4cDM2h8|2?gwM#Ixb<)EE!u+PCC
zQ4=>ugO{R_Dm;A`qOb)7L`>LZdmvE&9cq<g+$75vFnj(+$}CAfX_7%|qv>A{MJZUJ
zVx+i~x=uU{ZP&ZCel?V|^@szqM9|!QarGFNtuH~o?YVvQuY=EH=y)D14ltUPp8jsN
zkO(JFD=Fn=D|ipdfbMvB)r+eXYe+!8BJM%U8d>sk9#mAZO&<FxJyk9a71(O$bkF(8
z_fFcAi|Wf4N>F%9HH3+8Z(|d((a6q9VXJN>G_ZJwjC{y2KFL6{k&{6d3-CEQf6k-V
zd4At`e);hOW>0@yl3}Bp8NkZUN2QvblAA<5^0k7~OKyL3>EfvQzQ<q|G5o^7^PpmB
zdD69%UFhi<lEE;Wi=*G6osHJZ)lJ!5PwK1w-q@w%_&%|eegCYDH`V!|lbDvIPb<d|
zEkCiIqL&^Ol|xCYhxx$Nklq^ogq^_R1=kRe#zh|0>Yfeur6j%~4v-<mC$cc&Vhr+#
z_Q*~bo+8O5Mh?$IzKbvq2OknLVr&T3km{16B}ql8Ly8bVZb+0M-y&5*s)}G8(lWwp
z$XyYc!WO*_pZ_MT4y|`VdSrBc;hFx$h>^qo=uemH7wf-iSRXqf#eO=wVJBZPIvmoV
z=;3Sl9>wRoczKq~0x-W_pxP@dmh<&EU43)k_<}S%1x><#MyrZ5{UWZy@oG#R9mx+G
z@cjY0ad+96IiO_$)cCD?g<TEtYlimDQumZleM%3pA}Fzl*<VFP2n~)YZQiPS84|8Q
zHE08RK0tE=n4VCb(nJAGU5liqz-PyqTi1k^3p#wZGxpi13Gk6zPg2Ln-&s!R?%vkc
z-d#`;GSGYU`%i)TwYh>*dR*d%kVLgsPIB=g4s1S|Dtyf5U6%Y@+f$@ht9i=d!4de~
zBkQv-EE@Oy=b7tyiq_VVF#lhK3xjT<xM@pJh7;Ac;$(bSLRAF)zg(hBF-o9H@m#F<
za5x_U>b4-v@c_NFN$DVU%cRxNH$?@P*?{ur$ADITCvexuVmHv^fMjY^rPs%R4;=-T
zXaW-Zh@=iwy$M+I>$UNf0=w}1fS;$~*P*+1xAW3@P$?%6%QON~CWIBYLU7ZuX!#+>
zd@Psba0ER!GsbozzX5khI%EuVe6z9zZC7BXO7DsYO8^nA{6L7D`SP^H2V5w~_^s9c
zbOb@%Orqz?&xfWXWaPFt%i7>KopP2F;PaiIoH8v43RO_H7(VllBblr6qz;TO=kW!k
zO!peW?zhsPb3FwiLL)|v0Vz$^)mBn)UfohJr<24b?jPUt&<We6<R(m=4>pWQy-;~&
ziy#^E@&G-qoC{aH&}<784U|+^m`z@u)Z&i(o}p2|PG;|#_oQ$ac1=(>^ZU~3J?mdT
z;w>g3G@UKW7bFG5q`D0Xx(pgMKrqY9f68?uEiDcU_lgj}d{I6(mk_5xuu?98i{&VS
zdo4gI@gD&Hnmp%?cnrr(T7`kNoHwq$IZN@<JON1WHogeVAazAm&(M#cf*&#hXU-`;
z)54LhfyBo%b^Z>3OmfV$0y#ECG9Jd%l+1&jC^u9`J#LhOWwC`MSi(GoH3Ov-uwFVj
z(AjW^I)+?2nSy4}g@ilw+CV3R!tR6>B)s5*+8vZSMpg(|Nw)u;)ej20LhHA&7m^57
z84jpt8To(!SbXsh_?~%3#7r`tE7eA>Po_9V&5_!{dS!@#`FI)V$5C_=&4Q!XXUd>!
z%MQ9f*5Bpx+BkFY3YMZtR1tvCH>-+P36|!8hScLwXGob*DE}xfMMg-($#nSpRv<Wz
zi3xWsP(}4ynic$3C5PC1ID5cUfNv&&Vh(V}@?Hu$-R8A7LV%>`4AP3_{TiXE_&9NC
z8n+3I^f-%zPh-@J!o@9HD=iSp^F6_C3%UdO5t}-iRQyL}x{NYfd`G1Ap3WP+g$awE
zQcW#L(K@Y?*(n<4CNZZ(6M9M5qu|iKxr7Le52h|bd<*xnS|G%P>;X9%s9imi!6P7{
zVOv|=>e-L`t$EJ1Z~xt(7=qw1`7k)pr>kXQ;cvtshREG2ux`<OGN|K*yjbca%rd_Q
zz1?ZOEa|$6Lf3$RmB|QGjOsxl9nswmg`fEpOB6vMe!HZsITI(_F<2GWEQ(h;FQpL}
zdssqyV8R>W45VA@^f(_YDI%lT<vif8ySN#}<>k3Y!ScTG*b|t(K+u+7Cnr_%q8H`h
zbV@p`nS)WHZ8TckOiIFGDDk;yL0NB);handE?b@KnZle^#Ak}A(zjASbhi%K19r~6
zKk#h<bW>|S9&0w`E{lx<+D`!_yO#iNFC}sAd^92K%YwhLfYwdORYE(AW;nohz4}iG
z_a^-jql*3%{Qe21&KUQ1>y|s1PX*pijc{}a5SB=9h&X2?^?=?(qClK5JrN_7*v5ox
zY(3uhY=^@@gn1Y2N?@814HjGd?Ph6@opJkG`aKKm->D8inA=uVCv!KSad%pIq7DkX
z(claukQ=J?1dc)|75&ZfIky4%H($-iAQZ*z*8CH;O`4{mg6*gh4ex9if)+o)i*z>p
zOTVIE?h)51a1(TqW02opHw)G4kt~ktG_^I`$$Z(i*4qPD3gX%xw&7a}7!BFN8=i&l
zvo!UuS2x{=q&Q-b=VpOyNxzVOsxZ5xBXkIwNkF1yK*)dL%W{OILYxDzJ0q3+^$eHN
zx>~3i&>Hi{v>&(=rK`|;R$8nP?FK>+y>^&cPT#NWayy{+0s5XH-pQd4CD{Se2NJ6p
z3&s%wwOehDBydtm3)RH)Fl>eqOv(xH#k45!E|=VM(oaINe7`_~-VsZk<Y*Ac^h7SB
z-V4gU<mzD|+GXhJ#!>;3ZaJQVtw>LD&M0k;+5Vxbww*Pn5^7Oa^<B!Af#|MLuielZ
z0(^JpU6v6W!CEX41MoWL)&@GnaoO{VN<UAVc3Cbx6Ka)W(o$4bo7^VgVfP;KdFh}J
zvR7Z|#C*sz{qaQ@S#WF5ClHQA9yyeF+8=f08t6uQO40cU8T0||x0}t*RJekI3AJD@
z#Z#8`#_N51nlY+ET1xC9hA9%}v(Rt!t{fz06nlpGp<Up1p3R@bf1H|I)yK_Q77dMy
zK%&Z36l+x-YX-3jQPqrDur3T@?;xw*J~Rw*v9mxH6AcwG$4&Zu;<Hp+MQ33AI&h|_
ztGyuBsc8kg<|+XP+3p_Td}8owMWEG=@Zul-I0)Iow#uIu>199^41`6lDldJq1mBEW
zY9H@sdE%sC#U+1G9W!^J9K)Q#qCs+HtfKPJHthO#TMkFKkCzsF$W^L=q7Mt~%w@!L
zJ9}7IEt}}UNR&in%Vj0#n9q{DqdmK#;ROS*jBN{cHXMKetW}Oq$%3`0S9T$)lpWGj
zq6PWHEo)OIuT1vx=n{uxa}&q{9P}I}b3WK%z*KeDx;v{cY&LWm*svoKQf~MC{(f?G
zNe4%UB7}mN7+Gjz=QIIai>6Vj;Ux5e0aFJJ)(>UVFd!B0E<b?m^-x6ZjKcB#dVv>9
zs&Yg%v<{#MDVglR8@5=>ik6va!D<csO{VtvRu3|7>xYR-{q?Qd!kNIHqVcvVB&uO5
z{GAv5-D=qCxR9x=-K-Q(6-pcAO&1^E$H#u$$<xl#jexDeDtHhiys$-YQEAKM6Pt!a
z)(m~r2uw_Ay;Y6LAbmCVgh6^Jws~01{O@Ca>mPt6Khj3Fw$2-^U{ZK0)gK|y7kW;d
ze@Hi)Y=kA*;<bl2DJ(b^-pgLMQUg9O2L*Bw=tq8+(PY<9#g`fcyYEo5Z&xChJl(u9
z5DuF1Eg(#zZNYP@<tU4t7}V+6XcVEK?IHCO?zUg!g2yC+#2A%{y~94$NQ6w|PmE(-
z^}GNW<&vL_cg_7iUSC9)uvZc^X^DIXi$XFo{vudfw6J)^u4$heibt^mk;nBGb=KA3
zj2ZV&uUm{!#?E^FGT2PLph9GI7sX`Nvxm9!;uk*9zg?wRtr%dbabZYKY?r03duTH?
z*l8XyvBQ=FpknYpy-Rc4PJd0e>Xi-D7O(&~ep|3I%<PF7(~<qT2=@^Yw!iqo<^1FQ
zs<8tkCmt3f+x|?)>%Ja$yYy1`RJ&G0w>f2t_#tiqm$_-i@Nx(FNq4x9nIHZ0)iV9h
z*AFY6F>&n#5e<a2^rZgn=FHi^Jf7|z-UOUMUhX_^*TZ&j3skAL+n6gokBI;s9iK}8
z3tY_%pG`?@eLddrXU`o+Jmgc_W%eMQzY14svorU=XO)c`m~7`M!kyfvK;G8QFXdIs
z0S2(<-1Qz-eFfiX*O8Do#?BA?x^+XRAcD#Vy_Dbi^VSasQkqz$^0?)d_Lg?%JdGuW
zFwHny<zs$QR1m^^81kPw3SLKnPKxya6AjV~)t3#g@WnmZG!OXB0vu)(>N~WfqsT>N
z@7q{K(7BJ?)`l|-B9_%)vT)O@+lbF+=`%uthmXl*qv`on$Hh=UKn)NDFNx-56|~aw
zjx%SMSys`e7S5}V$z$hZ*2iaSzsmO3JfQf=m$36xO36V*;s7jhdV%+up=2L$O5(|@
zk0*4amo`xyi(LDgCKA2$a==f$z$wH6it|)A=JTW5f;O9+!S+}y(B0H`{`bT4+UrpQ
zeDEJnbpY0je_Sj=4Ek?%l_(geD5uCO8X;LaxEfS;>vRU4QN=Z>8rX?FwyRkl&%4~G
z2#k`Fi=j{IUu=tW1_&POI@7fPGk528b7J$c#nA4fm6@3sXQg(JiiKL|9hK>osoLwb
zuq?;yr}idK7RqSVNL-x-$jEC28G<^5!INId8O=)AZs<KscZS%c&}HK4i4@Gy;=R?;
za(pP)wlh$qFK&$n8?R24ia*#?L3-MyY3j9!#b&!uweYMPt05~_05)Pko-o74x1cN?
zVyuC^+bXsUeG;ov5BtJAs$+1#hPrlFN+@xRMvttnLXS|Aeg^GAYL)Xfs~)b3X9dtR
zuN%T){h*e6n((%EUodfkHwP}wY9ZxZ)lJTYIHyj0=BGS|4n!4mD_I4fFK_)f>1-mh
zS$fI5HCWlffSQ(STQ?a{xB?4t3%`Qyom9qu4X@Tqu5HK&XQ~xp6(^|rQd&zLloe#I
zpd4;Iw7nc>tHu%t%l&|F;@4I5^+%-#2#4*cv`XIAej6%7fwFcbs&nN&?>Nvk#wB36
z`-+*bO4N0rPOqEgBQ|>$SLYQkGZtU)CcLoCZH9Kri`gM3^t&J|g3J5o>ypZyIX+Ad
zefMm4rm_8G9INWj<rZpl44a)V7%wBp+{ENN%7#b*^?Lq5mO@C1=*g0nW!mt2RX^9;
z7}=mYcq5&G^MV0_j*aME*KW&HtHbVFK-~OzJsBN)+5RrH4;_J^V3%wUQrIv-{thob
zN6;_NB3+$e3~_aUi9$jUnvgYI`g_2KFK<CDfphx-TG|CiVERThR$A^`>q3!P@+|qz
z&ZJ0Co$OKgr@8oAZ6uGUubln@ub(q4d~*{U)`NFDRmbgws)5g-#Kbk({_m6t7^0*!
zB6(=O5dSSl?(z-WOyH_vd8q`+a8Y@E`qg@;?|~qrxW^xW%(SJI09dOc^fayFa^cZh
zZ^n@>9G@n5MIraN&e7$`^mDrC<#QXJrKOdvg#g*DZ<S2>7U7C<ATmuIWzFpkEkM1s
z{gIUwr_H8XqCQvKdtUx)-HaN=j?8=jOcK>V_n-ObxTi4B<G;Z7_ndrhm^dV;XHpaS
z@w9gmXCJnJ%O2;57|9Lc3TJkudH1VHn3UyXc}lKjbJTiZXj1Q6QY_J|7_{fzjtwP`
z>$Y(}C>|5*9$mEra_w(XrhA6DUEkv#JLuYJc(avO4)@i9EZC*@UGioE_^}W0w)hH<
zE(+1PU9BzAu43>N%3fr!D@@bCd>GNPS!fv@-H<8(Zf8E1evd5!291{xVZxSMpLL*#
zTn&|qnV_nU)7NDZ09zo=YeOn2G;vQms-w|mvb2Q5D|yT(p|f$^iNrc&1mSk|M>xfj
zlu~Lnkdw2gIsx33i(VD~g%t}okwEU+R>#8)%cbHf!cy<a-IfGJykD7+Oppdus#ytN
z<pwYyWB*(qtxH%paL}CY_i1uZBRvO5L6F-QZ-ZFW;&^G}vL%16n(cHhi2(_Yv@KI5
zbY#jYvCd^$Wc?SmR7WVYDEAC1#}U@b$-srvAia#Oi_R&xmDfy{Vvb;mz$^Yu?QRlI
z;ImI`>$kuTMospk|G3p-FdvWiJy<+spl1evC3&KyvT?b6_^vsz(lw)ET>uhXVYicl
z-{yjWLoO%S7ZUX1AqycYZnxwpM>J_r(Y087sljFV)V0cgLs?~8R=9?4pWD{Hrq>GY
zRqneV*6=Yizcw<OuEIF2ZNn~EpJK<YZA58LoL?V@c?O?3HzH$>@AEdeo{Svg<M9)_
z7X<H;4DX*RWod@$m}CGZw*Tr%){W=>E>a?nx&tC{lvUB<q?!^Cm4rkl<6EE&Pt4AP
zw5VH5r}|p!2oyu%A3rXA7`~D^c$<|pBzmHa@U$>P_8~Buu|t3Ekdlr&?F6o7Vc4-L
z%O<|cJV53kCANOPb#wFlK9as!($A^}iZzyL1K42`^}bwGtfNOc(};tcN&+QDowaKG
z>c8w;_DA4*wB*1hqF8xw#US3Sd|;TNq$@726zZh48$ulwRSpfE_#v55ik2*^jFkMo
zy)IpiDfTD~M|G#3mQgyxu_eCc%_qjk<u?Puy~h!k?for<oNG*A{ywGc&c9jZf)P<O
zLeusUlq`t#^@Hf9wnc62Ut}P~Bd?Kvuoolae>f8adl*OnTN!Or+~K@+c6tp#2X-90
z&Tcu4K0`|^8c+(X!I%Vag>Z-*F0NyXO{tTTu8?Mw0o?%pAR=Is22@BqH*j>C4q8W&
zh2erWi6L-@godAm0nf;+-t^u&MmW9C2Wi<1NAFIQq)9}Pg~^<C-JWff*6MD01@y_T
z&Bex9Q=RhwQjAt&M;tP{wD4+`4chfs#I<mEM>^`Ek}{!a1R*Y*AQM#4_0w$ZX}e~z
zq(s|_>Lb|$F`P7o%rVQw#l^%n)EM%dNhTZ*<%*ub$;I_(h+kXiuw`w;(iP(dRY%B=
zShg(_(fj*rYg)})IwdXF2N@BPIyK{F`_OQz5IrLRg%P|)m6bN1?$y4K>}4Vo?WvSy
zHqhAv%?Vf^aG_+LfVGgOWcUj>sn8;*ViCq;%O<R0Vy!?*QsI|!gc^leWjo1AQo<II
z$mL?=YsG}D0Y+yfN5~4p@cmr$G9Wh~JB|JdjTYDoyc~zzODDIy3JQ?<MAyd9EXfH0
zeRFpJ2F#H*S3%CF{^D~sD*q53tRBfUN6Dp(^r9wu@FSc0pw%G*DX;_zqA~ia?7pO%
zxHb;d{c3C}9|n3odfl&tI6cxz!7jFlKby(v>{Mtt4Ke+9k)MXw9v<~oV?25a_k;Dz
z&|NuXFeZFcGeOH-upiVs^602;-@yg*(wqb!3hOt2(Tm-5yOCzph&1exV_@bSHzdqC
zXKIMw2G=Tf444V&hKc29DVAYeZifo!BbK4sdnYq=yzVcjR{0eP7&#8e%N&GydM82~
zbp&=6nzyo_;{DM36%Xu|FBt%0|7v}{5R@^wrBUa;3*jTbXF>cGz$1)Va~ZNb8?puX
z8>g$z=ky%gfMG8KV1l{d4oG8CxxUqggvTd}8R{x&VDuQH(wb5P6SuAnSL_*Xo>x50
z;=ftBQpyg!V!Ze>OBVz1b^UC4Le~klo*|n2Ay_X2YU`@%-3<zwR<_-PFP|uhyecI#
z6mcNw0dp31)lu4e`|_SQ03FR~erpfF_8lE@bwG@ql&zcNh@E2E*X(=yc(VU&s>}ql
zpPm~}VDf;}3lpv(SGG)fF&R|M|4Q=0Ma}G=1g;p{8J)_R@5A^h{?%c8%SkLh^_}i)
z4b9I!;~S36lkDG~60b-mIpBU!mpam>ZVW4-n?0bEF)X!jVN$s-l0LDQHg^L&z-s5W
zKaV?qwJ9{_g-msi(z$uf8kVYiXgG}X9j7x16LmAZw8?cJO`4*oUO|*@xR^}mr~3kH
zdv!pfiEQH>#%XvBJoPBG-xu6UvI(Ugs)a^XWPO4sXDx{Q!?(}G{C`jd1~E$;mjnWI
z05cQ&|K0GXt7K^X{p0+&tQ#ARQDjlugdo<i4GVHBStBq=`h{YJTxfc~Eq|3wfd2D#
ztGm;CV|Y5UOW~q#qiDG>IDoY#5#7tT6=Vgxw#KP#)`TV$>n~l$8i!p=-E_gFfBVUi
z-It?Z#Txu8=zF${dX;fIVC^_-L%qtmc@HURPC@G7XWu&(hUd#M<T3QJ1^Otw@ulVY
z9KvINu2KcVHIJjdTA=N63UAIY<cwRpDL5_#(7SBXey406Xu1OSW+3e<8jc3`+~DEP
z8&Y`67Y2OA-z7-f&7u!xD&DzYse}_y-6XsCg)9^z4G*}JKT5(utOyh(c#lq{>xQw9
zDEFvbSB+{36v$q|amQUnNZVolESaXpCxj>WKgtL0LyZ3<O_b?*{YA&bBx|~M(x~Lv
z>XuDMkKf7$*QQ$E1y?kk9J0+|q+fjcPsUHXDFOaQ(^&r>G|l#3_V(|6qq%J`hLvry
zCk$MJR$4=A=I<N%g<_WcEoSw^?A{Ut&cgHLm-cJVC9TrT<WbX|DJ)?*rjiAAQ&-wR
zy^VEZH&8VO*L<MYW^$`>&v-R&0zKV#tnt~&gCP?=6y@DSSG&^LkCqQWFFK%J9hg}i
zC5|97m3?_T`co*YvctH?p3%%)`Py&^p#`ey653wuv4UnUrlVn)Y(_D0`|T4)OM%3>
zny}9ydm>2}Tv%UfuB0R2fP3*rdY%kLy@2Z1{RT;^HC?Y%%;Ea@hT{<R&mp{G2k|EM
z{n{r9{FBt;J21sS7Tr+5Z^ngC5;Eo*3glQs38DiSlH%~9*iI38q!&?qq=Tqb5u8G_
zdGxI8PE9`Vw=B`%aokF|c!sjm(l*NC!)F^It~6>ye5Ba^8xGb>-cf^Ev^<*pY_nZ6
zRlO|YD=qn}(6?Y5L;O0$YpwR4vltA&UU=B%*8h1OKmN7+H^i3YPePu?k?|b`*CW5*
zK<Jfkq>h_r<Pp9=@bB6k(N5cDg!qvLoN`8y$%R&Z=Do*4;1K(4z@a<2o!U7x8RQ|p
zEQJ)N28pU|{uRC$Q0IUw^(cY{-SAJO9?{9>Ju~lGgf8&I+{ZHKT!30*$R|+mQSHI0
z#!OVecFBtRopj0@jGC};;b{dR02~FQ^L7<s4!!b3BatJz{is2lKb<1W_Vf~(fbG%N
z>Zj7?%6Vc6CKZ9!b^$o+&sj-j+M^`t`Q<rl`aTC&P>P$8q()K#`BVSO?Vh)!^R;jS
zJDZNHxRYEApAre~Vuv8qV2K3rCgR8hp#{-m7%Jw{DF;DRWV#6AVvi`pCLJVG5$j@G
z79|5&jkBcD>+PE}grab*B)7jsZY)d>Lp!Mxqo_K{X$F<jDd#TdZu*mG2*x8=duV+Z
ztAf(tb=rm8wyMwXz>@@J=>KEt|6^&U|KP~1tpBYKk-TZQCV(h*<r&#6qblnE6ej^i
z6`-KVDyy0Z>2MyR1>Iu0Lu{|Vaz}+BC{-NPoqH7>hQ+{MCA*$I^*lSLy6(c%Sy~h3
zay}!RGNrx7eqo`N-ccb}_}<Hv{9)1ML;bdWK$LNFcQ$(wH+t0z$j$9&>FoT-dOUh^
zYV-Bgln<&{jP=&%do_W+F>C(d$Xzg8yyRlei;Kq6k7XTQyf(DEJiDax?eu%%S+cZP
z>u&edwYy_qci!$T6Sk5!W749%-75{Q>fpkAYm^dRy<D{5YxhAn>*?`9FIxJoUptC5
zy5+Xq>(sWz=i9ac;LB(`AzoxsM&vcSjmwA(<c1k@DjPG8l%^CwPzY9=i#9)9!z;Fa
zQmIEA4-7YX#Md&VR*B1=5wxBWbemvB_=_mQv4XWv*r<W4<L>}Pj9Z->7^KR}DIx(+
ztfc*FnWD9vg6)LzKDN8>068uwaw?#Yd(}U$8zzkScjq_*Fh~@>PnZ}~IVm{g?ZCki
z9SB7t%@h};EzALi1fR-z*A+GyAcHB2BnIw#gNat@FD&RPZ&hb*C6q2N@6L-Vfi6n=
zJ(Pk_6ZKoA*kCUBnhkWEmKiA-wl|;3oE&5`hS*6<HNR6$^SIW$5d>bbSigvREc{ea
zj2J6{c|xLCNpEqsTrcY9tqc39I_&@@leyv@)3~(Q`hJI9t@f?6q}q{T8*NRO)E!rs
zU2Ums-g?W`>siJ76M?^#DDXeI6?*~_Dd3wq_+Rns+pBheetXp&YR|cqYQj*%rW90!
zP{N9Cs+A=HA!%rgO5#{B%$6TYo+1MqvcxDqb6zi&cgtFBt1WZ+s`hbZ5W!M~<=IZ%
zCY_2N-bcG-60N$cGMvy&Z%48(llH~Lr@QBk)uVH-_xjiKr!}DUY>i%;;OqJB;umZj
z!By5&<yxM`yWds!L`dt|;0M?9WDBpW6`y=^X3To#8RF%sp{Bd|mo4^s*jiXAZ&g^_
zGEpq9o$uEPLl2%xCM`OnPH0DE)kiY}4Z+0Yd6FlW9}Meu^fvL0?Z<XkitVWKLo4j!
ztqm)^ymA&D`2^sXgedfZ0=%Uf^s2-qxYHcASEPx_C01fP86)exkPK1NF<DbA3%r<@
zsXnmn3Z$ir7HEMozaY4XTg>TzP<e|``EO+KWi6&~IgAPkMX@O%9`8_*D8v_9In;d`
z4n;ve8qyvKnQ@9>hGCju1~n)OCtMav97vLaDd++jWlKPibf^@Lj+0PmI)?>^@Js}3
zrE?>W3s*!0x^S3A69-Wfri<41sREN;vjS63yUD`Jq~uq5WQmv@6lC*|NJi?p$6<L*
zNg8aAhN3J4g`9(%xZB`r&V3i67VbAGT7SXgV&6{|!@-NAXDj9ueZV7T?+lqB{Dhvp
z=F7|f6~8vmZFrl%&<EZBpIjs<;1?Mv^LNf8c!WU&IGqS?!TGg0xMkzyCL}8)L-2Z4
z#(6Rb0@1VYbmQcwn38f%`<y3sgH6|zg9-uZ%8dIrI!(@t7Hr;;dvdzVzUc_#O^hHD
zzyHf~7GZnzXw$E*cuf<X*4Y(pa?x=T8F5AF{H7LZU{zIf8#2n5OdH(t6!=-+__RNh
zn^rFbz_qv7^k@i{DW_-PNNv@swB6KW6t^I>W11m7dVJJ|%yArAWVsLC&4MWoapH!X
z5vKIMZqA6u-TL0jsLVk#a!n|q!A1p}Qy7oRISfu!HkPs&Nu0DomDx;0R-An=R7g9Y
zT|$~t%wCqB&?5JPs`L%H!;sfnI8q|n6t6Rp=xD8Uw=9=eYs7veTK*XOER(t0nBr#M
zyXM|y!WX~`_gxG|LIGiA`cF#D%)<0vUsmF_RnSk=k$=a@=)zJ}ZbZXoXO2U*N?#zH
zxEzHf#0$}Fzf5_r2LAzuBW{4xjN{^a{G^@9Wt?JRaYA#B4J_QL8CV0eF4xI(Hfs(h
zMk8SU&zj?6;ctCc`Kb>MwPo*{cTH3&>TT^KW8VwF(5s56-x#)4LCs|*ralLM@{?gP
zUs{ck<N41+{Ia=0i%Xk_wQ^?OY4`0?qQ!9-?VN>$tz`C^x}_xCj3d$rxT7MD0&Hv-
zy0N8OA-Qu|3PVS>oFSss_g~KNt<E%l*36S1E{WcH#}v#raN$9Z`EZn=wsf`}lt6S7
zP)(Eo_tciCTX59C$9z0Wa6AEfLXp2?_|NsGgwKwYpwEsfcwVW6A@RII$%w0*g)(HC
zIC`kWQo$IqqEn~>oRZbH=2;ys_I6iYXmKTo?8c=;tIG|0c@)c%UN&iJUXP921Xxa0
z+yCIS%>R}(F-kxuOw%~UpaNxOW^N5W#aOoiVP*bzBu$gO#zaZWP{+jlzQ*3#q>ky7
z4#LXv?{1CnOEjRYER3z**O-*T-z(;{UO6l-02}*%3wy+9{m?=A(~$?2AyR-Ev6t9j
z?zCC^X1A%;+M$HVzTp5qAcrh5fK3RduoKLC{?=33W?x=XTT|g0rKN3c-Aw;yz0&sr
zYx{4{c2>N_!un$m<O?|Y(G=&=`seo78#&Lwe8SF+M^IPS<{x@(rWwHCqB4EbY;L_6
zb~*eymL<N{47}-f(2PGg*yOcF2Lg?w!PjBA`{Cb)8F=+<Ja4w0vpSM5?O8w^p~tCv
z`xD>p=h(0(=F@h)^$f`rK^tcrDHu;K&BIoG+WFV}Iz7zCLC*r(r&0#B1{$~P?*8~9
ze<F<$Nf2m|N@7J4g**Vq-Y<_%lSOg2XOTe#zXldA^*s4SdV@lWheAqiqNrUyh^**<
zDWZ<W!d$~&1fNioVv|ylrX)d1(x6zUMj<wXQWFEUI$30rM3`)2Tf#EkrA+CRL2>fE
zBmr49UZru$`+{p+sa=Nb2I?_sB3WrX_y=-?5_Jk#g-Rr65;>q^DFEdlAs`8)jdMcM
zFjaCw^6-tE_Cc%NE^st5F11>x)1;7EjO<6exYT<|Wlq20M1-2B`UJ_KdnnQdf-Ec<
z5Mwl^Tr{Z|5`aPs#W=iSh{K47F(6$+hPV__Il^+tW!Kk;oG~h0c8cf_nE?4N{ACEl
zh^Qf4Lxz?p6&WxYelP?*kn@~=O~@0GGDK~}+7PNCT}{#z@h~K2#N3dwB6m*chTIcO
z@K;_U0*E*qid-mMfjAn9!X!9b0TD@rw18A4I5V8sC|m<F@Vk*1<L`3V+iZda@n;x&
zqWXH+wz*Fpc~~!}jVq-iDPAilI;Y-V+-_Qu5mTlQQ96Lg0`(E46y~d{u4B8)PgBlL
z?nLe_JN{SeU9<b|p1bBr%ru3xq$@kei@nU_SL?62&%E{@n{4fPXtGErBJ3h{5c_a#
z;w6gmkm&H4EE3$umj-eDoe=z(jV@z<jO=fayg0g(?Fdd;nl8Fuu5!R>`mn?%Fv(E0
zjzMDNW6l9%7JAG$`+cP?%6LdW@rM%I2(-uTWo6mG7ROB-oTN0UgWeugZjB{lKte-V
z2Am*n#u~|2whBT8Wu}$+G9`Y??0lDXBrH&9y_qL=z%B4X-jZS@<^sqMaS>0)X;lm2
z_*9P@Cyz}<_G02<>?mX<Y>{mZC%Mbrz@z_&^uGfz{XxL>J$*ySw8i_u8`oA|Z(F*O
z2s_)6v5z}Ph1Hlm>>%*FOrtf5a{$YCo;S80`8eU|V1L{P;XB&#-O^jhDbb>DqaX@n
z+xl!B*t;iM_YD3-@s6p^w$;<D1fk}7va@PKDldlZWDtN2FWavuvw_7h7dl>gvp$#y
zQilQ@poO4G)+}7SErh5Sy^@YGaYFd=>A`ez7J%&7Tl9{Rv(&Z*;eo^xusO@J$mQ5$
zcu%3$(I!YmsYUdjZ{V5n@$x~?CPxB$i(<w?P&eDvyP2XZ`g4-y`!X|tI*GvxB@_0#
z4~N&W<b;nKkscUtb2H<&_WQ^Se?oIkdjtURTF;}Cz=4}&<`RscAnwM&CiP6G=J6%O
zgjLNcs;eOW+CqMZ!m+<E%=;s>xE#yAFNMRO+u6W>z%b}tbUVBZS6y~?u^u{@GQ*Zy
zapx%dm(JP)iQD)Epg|M+dJmzS6xP}a+|WVOG)N+udfPHefwvp_v&z}p`M?bv(Ki5p
zNW~VxRqL&7X*ky5zb9)k;OzLZP{N>Q@sfg!h|$l6uMAbghh-TLd2|T;Xx$^iBGgR4
zLSIX^G>GTGyNqUu6EU&<;K41A^G#5cS7&oldmo%R<~btu!fSP9<JmCSs$$%06Q?QP
zY$2AG92M(}uRojuu^WfQEdR-X1<H<?2M1{_Tp)k7m7ov_Y3fg!X2FR?3Si7CcjJ@+
z@;JA~j$wUs3wz1zzcdM_Crf|%11%^KV22=Z*==lpwVaMS2d;nm03B7*c499ZGV&QU
zVti4%ISwz}k3S-6ZBj6Qk^dv7t$U8tYhWZFp@J7Wy^97{%mnCNZlWHRj@R_j-U1B!
zZnNsj`s%FS8Vx055eUX&25_kgYXoLmPlXz;SH74SxR*h_+)}E_f*+1|t<Z(bAntqZ
zZSixL|NT<4E=ia1wl+&)1qG4~=%ySyMldHGXqhWtGG@I!*bi{B3|Y4BCk&b%xiE#>
z!6lqm@#ja-udKw$lhV`EQf-pI=v@wErDcX`fLO7s!oRlsDU9@p5r8>l(p@3~QYQg-
zO~^{-YAO~1By{Y#Qj04aD{IK->^%ZL=l+jEMB{e*CeYXR1TF#xlPG|RhlD^<Av3>z
z-7HAwQo}-wqmZtbO{P{gRaA`?;Ngc8m`-)070Hz~3iUoMdQ=A$i!TIrR2a~?dDKWI
zezR^dF+VcgEAR)Ltkw|-7>v5H`H%FWN&qR6Cqz^OsBu6A%;8U$bz^wpgiyM_4obkR
z2HaH?Ux@x5JennsRoe2#VUBwa0I}rAZC@62q|sQF^Yu|870hUESi7W>X)~AXSTm)<
zG-GZoVnEVy@9Nax5(@pyDF{eDH3V%xnMCXcm=dOO>?8H{6c;)P_zIjYv1nNQOjdM*
zzaUzh@l9WD58GdDuO+5+w8{8FK6HeApTLgjEyi2E7ihFCH-nEFyM%ZPw<y+$xPnwY
zUgz0g77%zORo3kq7#&}r$}6Vt66e9X0IV1YLcmRf_`{SBOW;7res|?8LUvId-dYFY
z_W71YE0XQc4m?)R422(0<k+*7bK*;_cb&Y{{V$O;qqUJ&(_K+H4R=!rW(?hp4?aAI
zy6$nBZFaF9Q+t+UaP7Q)&$u$eZxyb3+^G)7Jws<>Wn~@m8$FxdrYOo21t-vP&CdQ7
z(*WGKU-~*+?l=7i=G|&c^cLT999lhc&b=VnaxdgBp4dn4oSFIwq(C40i6I(H=J{5}
zcN}AL0u*3=N?U;%`riZ5n$9^l-UDsSrqk`&``!4l6$E6Pa!5#-G%w*?bR^zD(}S})
z=gw^v!8hv`P?=c5K!!S%8-C-}Eb;Hkg8;bwP`6dh=`Q_NBu;0A-5JgY=tq`^Rh#k*
zcJoovdduv5ch6tzyrY{%V_;b36I;_-Hd!%3o8|U(of*EV{l0NY><lN`0mPl;J)yN$
zw6<5Q<8maei>O8G?&Qfv$kRrHbJ(W`kh6~4h}*iSctD<nHGM4-tXS332~2Gwgy38l
za3qgup}bgBfca%4##_>pZ0{%}f`_jcB&VNI&l6+t2Z;(dqGKQMm=mS>bg59<;d+VQ
zO0a?gVq&GHVq{DjF`7N}NM<4trkp?CfEVJf8-wN!*aW-vGO7hz+JXiONTEgLU(6&&
zapr+Z>K22kIYLScQJL$lf!taYvx4>^sRW}^7w?X~0D+&eBO9Ksoo{WkUBqHZDQN3A
z+~KMvmirO;QfLaju_H4iKV#GlX7#TP_FX;=v_-*D6w7T-n@KXs%1>m?IS!dJoh=Uz
zlG5g1C+)<Nj?8mQfkEbd+2Zg7SS!|lSGAOlg9w!Hv{8oV);r8M`6tdvkrhSB$A%+b
zRVSF668W2QFK)8#TK0N5LY+OX4-?EeoCBL0Fj8?PB|`mDPJd3D;lsiO=#VID>!hky
zVu<Z87bh>cs-`^X5D)T9c#p=$;JD+ST=F^X-=C0hclFn$m%OK*W3rmf7m(y!gvlNG
zN9~gg1^vQI%TlzFW4WT`UJZZ~!YDrl6PBXyLr|p5Ggk4UjE(tSUMTGnQUSXbmG*bf
z0}bHrC8ZV3(a6?7%g#;%pg|zKJKqf~e7CyM&K>Tw7y8ULY^>2y8LvE}6G`ecs)xZM
zFm!$K>Oy)eis>crwH|!MZ(fM4?pQIS;*33rLz7yU`aQq3({ml_P_qkvgMO^Y^0Ihn
z{HxU_1||XI{w8mZ{=to#-DmqSbbVgvHm~)`%{7Hu9k?16Z6(kJP(94At1w-|?!_a2
zf#5F*q)*h03z_6LU<9E{6vY8QqVWr7G!S>?VWZtEC)Hp%yndLA&nOI7Bn}(J?T@(E
z5hJ<?W4DX2Aj46XNZJbC@8Qq_?o^vl@wEeSzRSZUE0mh`#z+e${NdjU)0JH9Iwgsd
zXDZXvuCCKMud!^6hH!@m@_ehW`&*OX<nyj-JJJnN)nLcI+(oeGSh6F+mLh~uvGIav
zIq?t=*yMaP%KC)pKM+hpF%vBks<@c=l95bj-mvgRNS=!P^g-sKc;D{jA6qPr`$Zwy
zLXsrG2Z7VZ1h9xva<N|2S^ko}xXGbn_k{ovzztibeF$Kw0-UxAIc0bcm1KC+jFK4*
zsN_tR^VUp8e%Ye0{wacQ(ruVg6S6w;EKp0h?qlCL`d@6FQ*a<*x3wp>?M$3ZY)vw;
zZQFJx>WOXJww+9D+qUiGpL5Q|U#HG@)m>fhRabYvyZ74bSzEMagJ2g`MCwyUNSM(j
zr@}&xe1AP>m>Zzzj<61sG3P_@=E-rtp&9TdyW1H7K8j)NY?}BwWj~e&Kp+qgj*9V^
zb6e`#DlR8NyE>lN{sHVWvhG@isJX1_Ed{K+8JLzB%SUqd6RwR-F?6$zlaJFe*~#Li
ztt4#cTw6%9d+0{Eg@`*>4gYv7kKUI+>_}Rbb(t}-H<R>1o<g)r`i~R8p}rx>j#7u1
z7iz)bhC8K9#c~iWZj4t#y=MKo-MVb#_Di0*xEB#l(*p|%YXdxX0)8ZeNMg<l?sKxO
zK-u0xaN#fwby}#1O9n)sc+b`G;114y$0S(n?S#L??5HdwT9LGEP$xcZ1CF12PUFDk
z{_KHsr?LrGfBj=cr`(E0^6Lu6W?;J2H&--~pBu1p#@`E|N`Fu4=Kl^`b}|6K)CCX>
z*Y$YZk|hy`jR8xuv$*PV94e<sOch<a`dBo&o$zjnt!1B16&N};lNHw=KYK1ek>r0^
zzVQE5wQ?3iv-9%RjIb@1E;;3Eu7}qtiorx{7B%=BPQ}02=g;uNkM>q{Y=P5P*o9Im
zo(*O8)?kf~PmkC7j%jhadukkZoN`@xQH~sHUbT;sivZ{!>R3LcMcy6SGH$j24|8~G
zj}=;aAh7ePW#F}i1$&u|_J}Ow`F#o#%V?gW)Ym9pEuy}>v0^r8-0+yVB_{S3vmV>=
z70OdNW+j%<R;dLn*Jt6oQ#+BnM%&I3Qa5V%nN4I@s72;Kw9m<#lI*h`ckRoe($m4K
z(0qEm#(```+;+nyGox5iN3TcxR=>cPdGu<LaLnHuUia6xW@^>mmt2il>=LAoJJ9Mh
zZeNyG0dgkc5-bCuQZwX5zBS}Nu-(qN6iS&W^ilMZW&G|rMQw=p(rGj`g)`cCu=MPC
z^P8+?dr8W*cO^sN+4_`!7629RoF4X&#M}XGNkCL~DVz7OtPY`TY|uZJ>Vf>_e7X(+
z-#_g9z#gk&vQNd>|7#it<>yv%%8xhipsG))<`uzDmttYoZKTe)7gLh1EE>7VIR`5C
zXI}=;?hv~rY^!Kr|K@hYOmnouqeGmq{y>Wb*oE<hxh21c`rRUWOa=ymuL1XKg(aP8
zNT7|nx-Eu@;n*!JcvS}RSZ$KJii}t527Z0{eP;k#vr8%yRWHR-e2<mo0~xY!;4XiC
zVeQY>`$U&kZveGLdz_1*j;^xO#>XAfq@P?@rMtV1HGSI_`g*n!psR(%sEV_a+BwNN
z>AcObQJV*OD)q}}w{(WfLeNG4hPIFk07?Sbe&ei!u}BXW8ZBVF!Pz2>oCT>xg=3vk
z^U_SPkfB<8{$-Gy2vBeaO+^OFckPSVQ%Vtc)ZWc<;-+{A_<hUezG07=@uRBR;}?HL
zxTaD+w%2xVq#@QlGi>HI`uS_L-RI69^m7->>IyRY@A60S2$I*BKE_GkOQWjj>4B;x
z7IOsHXQV#6Gggi$IeKOrrbLItv|}8thlo|u;5Oq)GZq0&(HsiYtm8KLJLd=DS|QbD
z9xbZZY8HaZVtx#O|4M5eYun_DU-AS9uc)4iFgFmEvuxd+Q0qVqQVs&0vCCDVyYW1k
zO5@}2-A+9=vuy8P60Sji(IY1!0<;?^ApOlNBv@0+r2>^zW@|O9coR1Ha%70xEJtdi
zntr|Dx=l60rAzWW9{tG>kKG?gyg~s1txH#uI&Mn~JLEtpWLc8mY$R9`hOKH!mufsi
z3?lgUN!f%Bfhl}IUnV||V*3Mj-A#GjWw$?BT%MhY87kmN**Hn-EYr910f^E}#?FF8
z^r#+<DqynvgktH?0)>rF5n9tyvKxSzgR34io6AcYn^D2@AHZ|1&^bOcqf+}*Inj<}
zq6#y{!cy*k{H-L+l#zV;mxyO&ZUGxn03nB^+?=@kUa;8VVqdaoKemc!GoGlj`M#ki
zk7IsY?`nd{-|FwoZi1=yX251xo~(nB=Up_vDOCBxudD@dIP=(oryNn=<Mho@Yc)kn
z?vgm$AP3e@aTblP&zw5Wz!kKGjx&{x8i%KiewkfHjp>#|A2zH!0hiNDlGX$BcuzT1
z)wC_`Z+^0w!3(TuN?*_4?uwWmib~m@8PYUcpP5`FY5}txLBaysL?CPQTbq6%uQsW)
z%u>PNeN(w*wi_v*J#~a(dt^s`QI&2;hlvF6jHr=?3*~ay*Uz{Ho+SHA2JIKuei;TI
zoZlfdhki2px?MRZ3Z(1h+!Zwxmw2SR`3VC<fJ)+uhRLC`zh+m9FGZV^#3kSC<`aA9
zqJza`y5M_hbj@B{Bqoz@*Ea-e&*ux$)#-10W2p`E&XuyX$(rIgxB#+ulsi8VzPWSl
z@Hk|}hl};TR_JsjyY=!K@g`=MbHmHC>5Jh0)2}R?I$Y({FwPC+eW4rkMrqf;v`k&4
zu(X0h8S?=2e&I~y-OsUP3QLPiJRjzPqZ@ME&~2qr2{QE!USQm-XDvva<8&*3(>!?@
zYwba$#j>Q^`_5R+4*2<G+kgk<GVQ!Z<}v9(8n%iD(s(n2lbiaNvQLgcnjv800X|G%
z?wlKcuIu}R4i0hK${B`}*@_3<Q*98w59#silNv+XA03{vks-NlwE3xq2{PCd8}p4j
z-u6Psb>8?dk@)AycZQaT_sg(}v0f`9JY35%JcJXG_FDm^U;yQCW+@8d`CnM}2We_Z
z%kntgiQrd+IsHtU69#fBVtjQJ{mOBz=|V)v3m2t-O2s)Z*!U<-!@V+Yo)t*~jm&jJ
zv6Vc)dfgK}<)PG;6#h)9<(XZvZqSFQM7Kz<l+c?I$j=ppPsBbC!}GM!avP7$75NF<
z4jK#ol*#kt4T$caE@h3|yce|9<~34~18Ve64ZG%h7Oz%wi#Sppo$rF!8RH<fl9rZb
zgI>dqe|&1#svAW&5#n3#CKlB@(()7hZ8B>x-$U?sY7IU-qFJiHdCVKCg}vJ@Dxp3B
zoG%06!Tfoj-+nfZ*FPGyPn3S8os>wRn~LFIy-RSg1Aow6CNh%Id6AkLK$PExMhT8$
z(5i&jS3DV;AE1%xpr=ZM5*r%%&-{iqcWVVwzKBL|cc~sDV%0`0@t3V1*%#>jVf0fV
za?Z91O<^vj*K@Ku#*)kVnJtxgW^pNN{2{MO>yxPaXd88Ya-bm`Q}4WCsrH$+)nZ<<
zFoqb8!Mu2mN7reO=Bp<^N#aN-RY|SIcCFA3nyt;e&Knw-II>C?wKgvsQ^>R<c$#@-
z_z+*Huig+G2lu$Jb8{@sT37@@ipuGpQSXYGnTff~25GA64I3Y2i<V^wadj2f&`^pb
z$4lWbU`-V@!1B+W(<9}8xml?Wv8?{-r)wt-OkR<~VFn>ghL^?>g+nb%y^0x%UiK#{
zPuBT&fk5!(t#<1Hs&0JK=#oOC&}tt%`L~C`5<0&DWU6EGUuhgFz@~z=t~|1Xl)_0F
zp5w`3?;FJkr|n*UM?l?%v?zVCjt2|jkL+B8O^k^bTT7|?)DWw(@KTe}vEDk!l*FNg
z{X?w8P%iKOG`pyyNi?MjmI5b^W_$5Jn|<Ba4>(+*^6)B7Y|J^2@fM^kx8;ym6Ctz_
zg$K1vu-#1rW>qc#@aPTaKUh=#f-%APBbj=bW}+HHi*|p}L{L+y<i#NCozZ3F5m_t@
z0n}Jn=Y1A+SOq?l1{>j8NNV=3mb_Cm3Yvs2G_oZ;I|kZC)8Q9E1>`XsHR|e5mi<iD
zTtrzMSeAS}E>wixs1$zK@LC?-7gVI(vR|KYWTKb)1}K4IfX8kZk<W4HYc7iUe)3m~
z!`@h}JGea)U^I|em?_pNhTN}x$01MHY7xF19X1_YxZ;6&@1#xXb_ti68Sx=4`!)vm
z@LExU?=7P0TkmA1qv~oatJ=Cb9T_osRnrLOlmCe|7&GDYA0!P{wts_1@qwfy$w9I>
z?Eh2=j{j06eggkXx{cI;QAb-^&H9#_qliAJF5O|KxU>jSs)eBir>uZn18OM(A<&EH
zi|pFlg;Y*5OlS-xvd*FH0JE?rTHds{DpS$a<odGqCga)ibvK2~cyiJC^b*et<8(Ow
z(&aSy)VcLW2p*7%^Bo!5deP1vaPvO{csbnML=tvg+99%Tw_BhAa=?y&C-MW&$X8vs
zrr}RwS`D+(BSyU;9Eh%kL0LT`-lm^R_m591%+E+-a2&K&J2a&qH4Q0~ALN~uO!0Pu
znDx-HFyDzQLa4z>Op&{h0q78b?FhRBI;I_bG+#NltU#p6)m3U!L70+S$X^Iht`l)}
z4L`cu`e7{F#H{wEvlAAud@Y{}DCdkXs2<w>xRWQdugtAe!%(RE_B#X+j*&(oyG!b(
z3=dEIVPw)HDWdIsZq>wm6*H}_;U|bgzvq*93*8D-@XBLiVNj`!Dt~ueS(VY<WHu8?
zkUYd}lOn|UkxZvf96vC6P=^d8(yaRI2&!n;R0`sBFov9=wKEECQM-QsS_eHsAl!so
z*WT3F+i4tBO)QCnpiZd!)jG=0O0wu`-Af2-QUHMWbQYmhBhR%y{Fm&YORh_L_&>r!
zZ<4w=EeR%?RESAGUcaLuL~WcsF+L1sZ|Z+(4%(p)0eCyI*2KUjIXh}r0M?F-H3>V~
z70Mbkzaiz095`}&$S*<J0OVX@Y!q2xRD}RPc@zg>-dJ(6RLAt5&VRP*XB#HcTL?jc
zBK={q@qM1Tm7>ogqLdj^t#QeTpn$I4`h8U9C@)$^j7+v{mPym~QHPbiE?lCYpS|Ec
z0dtr>m_(iXud~3HrfqXY{ku=zS$}!_IAyC0Y_{_h&BSS_3yO)zMNX8oE+ZFkyJQ&n
zJd#kUq*(m^?D#qMRa08~;$4Qusd;GG*=Vn2<t+<E%}o<qd4}mmovQpbemiRoj*_>Q
z-u0KoZPGA<gpHc6ks#4~z+BG3K?#PYYGp`SlD`YNHVqiGg1zpqydzT%x_hhQe?qvt
z<nyNr4mqqB2`(g<kmiWodKIZK+y#qAZe-wEP98~WgTm*X{Zb(sr^)BSnzYIde?!f{
ze>VNL2%l0{2DOU_5ud94*Vr`g8u_<q2|AjS@1K+FRXP5zSqGXqBYqvl9CPUSDrcRr
zK=)p{w|3xTD$0LP22%0bk{3a)mtoJvolbqXl-ToqAW?P|ZnyujD~qT3O|ScF;ACt_
zE_2;Hnihwy->OH=>LU_S(Phnfo|>IdHOytrc9kO!Z-SBmUh>kNx4#H_DE<_if;lg-
zG=D94Va7NtE;Pj2$kLpOgc<|78fl|gFW6}Jk3EpwYEJR&haus8Yf|rtUD+en&*ytZ
zFOcHr{)^1y(Ih#Zf#0d693ofsx)YJcxyYJEIK*H#k4SgrFdZEw?61mvW;+Ku7mjo$
zZWS?F%JZhbw9=1TepixmF<8H=Zm=-dEM~jNv$SSG!b}l2;iW2Fudhp$V)9|fR?Nv8
zA`pP=lmZxmv_o;D39m=aQXR!VP5P^-VAaEPMep3v`1s4AoNGBmGc~`^b9yI8jJ$I;
ztSBt$Qk}vA0keQkwkX^&wGwvZEKi?;jT52}(vD71!U@gMh*T@=an?qJn2Kt}IO;+q
zHsUIfs({;v>!_k3H*oE%+Z{x0K&N&fmFgd0Ha!6yF{MvZ0m{iziqdlJP!*Fz=CBBF
zE@i5cmd4nxkIcQ)T+QYg2ICf%VLgkXXEKk90(*)^xWmO(=(PK@>ZD$?t;LUP>HBY5
z?*4hgGNH!cNzCR5Y2W6rH~7hxIIX>a2}4^+YUrsiZ^&^<E3H)e&$K~$V|7_o&JSSf
zAul9s+#gz7^s>`kwUQ-p>~nW(>Fg=sEURokFE=n8GUaOu$GvN&5$?CXn+cLlYOcwX
zIfR&teI!c;v|SidKQoR74MiDpXOa;S9&w}AE8ckEQrD-=@#_J>Bb&3Mg@j~sL-Gvk
z%&+j%l*QqKj`0j$<&-J(BI*gAURQv%lXAe&I*5E3qZ;ZGtLV>*nozWu-w9gfb`+vv
zu=ENsatKde%6h_hZ@|BJlJu4hg|_odt*wlUZz$qyVkxxT1uY62BsMeiZkwq+&xXMW
z?yH8@Hy5-ukgwZF4-MpCs@tHdpv#D=MfTZjXip+dfn$j%C;~c6KZCW}+fjfn)5m1?
zPp;3@m7?nol?nvj-DW8a9QrF|!jfej?K-@|Haj_qDUK;x@lmOmf<=m@r*|(H>1Sc%
z1<f8I0#^I*MDXPP8e{750VNbf?C>wmw%_UmW-Wf-P<4I4nbk)F`3aj*<o0i!3Cn#%
z{p`QV4IDNQZt?BMkK?ZXUDN=M;G5#<N?DuYz}m1yBfVB&Zy7X#uwpX}KwNkV)fw&h
zip<N<<ve(wntk^!G6_O%p-tz-W(ex45{KBe+=ZkcJYMMa8a?_ha?P4;H``{e4k9_n
z#vh`q`;05uFeV_QF2xjG1q=~A7;Kf21W&i^FU!$!C*#vZi;#vN__qOS_udXJcM_Qg
zgRyK=e{AbXUR#lJgEnlAI5*2Goi6fD#*z$;5i!gJbA#Z;*MdncsJB)IOTKbY%A21{
zR#CY3IUmYj7$bcqPdDJ!H-qVqS;fshxc((;h&N|jE-~ZYZ7FM-XOz)hVq-fc%X1r3
zFbYr^>v9O%*qm=CA3uP#rfD{OL#}prI<bT!$7GPq$J4hh-qzhi0j=I7EhIabW#dK7
zb-aE$A|Kf@|CE>*FljafAZ7t7MHhF9;|#%Q7Uk1l8fowH;RgF9qvB-m^2Qx+5CG>t
z(@(oZM}o4ju6mB*s|>1yZ}-$!CopYTY6{Zc05xEYgx6Q(#0RWxh2=ydrJeqL6;c20
z;JTGNv!o996YS5KgKt4K>JOOIq+h;O%V=Od#y!7EQkWc+5lBrRa^<0bRc82RUvFD8
zCyG6zIMEr~;F-|}Nfes(5v${V4?MuR{e+Un`WIV%ZnLVl<okSayx6N)xgCob)^Z*B
zP3}gn+~@C}&^zF`3ySP67&UzDRZnPPpHCI4@W7goc(vj0u^P>$oyf;~u;1qR5X6Cg
z_N1*keQ@CE$|1q6;&M|OtKmD=tqx|Y|M1R~5;Yz+T?a@Z|K0EvsM0s>WB*yv3DF$~
z<@gvt0)dmRmJlPlC;T4F_#={9IwnBn(3zBKD1avwl?ULqQa4LU;X!_S$O+DD8&H?<
zL-oPb+$}iUc0agvaewpJcR8CZ59O94sF)kjo>;Q!kdz@=hFuix;IH*m3X)SeMih>u
zEK?N3brZ*`a8+-r=c{0kEdm!7l~mO(AS)2nNR2AVkcjFUUxgo;)%&T>EdA+nEhWq~
z`WiRcxdcSH7Qb+G)9VPC7Bi8rI9t*y#mg$qu`pYPrQt|uNXV?{Dyw^_FEDsJ9_4>e
z)7+m<Tu5E_WnG{%c?+A!|M7Tqp162beOb_YYDe>Uf45dQ@-;3Zyg}RTc)K4cHPmb;
z`b(eo(P^2>EUGUw9wG7PPnnXc#<*5e0?_aE3E{vECVj8ac3KNZK=kgKu?IBPK&My0
z7Dc(|gTlB!hT4R*#uPmh5jiwk1unGE{C1z{j4*sTlYz6hdjU~p^kh4~rqFS;EVtyC
zEgpe2H}8BtYL@MN0y5G+da2@Wg%A2DqMTX!0D;2<tcZ4o;0*rK%*^^a6XqKlr`Ux-
z`V#O5%Q~Gml8%TCMPPSHpG6uxwq|MAN=wN4KGq#4iy=Voq4mVF#Qvktk|^K9EFq0A
zI~M7(7ra9rJA)C^a8FO#)p!P+d-z~vlIbR<By`3;G#xoQ!-2k>5P6{?`lWV!INHD^
zW+$u>yRu5u6M3CYbG|qtmn(Q1(uX}z%NwYjdFY#&ovfUKrJJ{?{P(!xyEA^9Yaz1a
z*BXq(oC+XSr8}LmN0y^Ipk}%y0lQsb(zxe7PbbX4NW^1n3>oLG$1a2WF|Ng&7@>K}
zR!70QfRk(BF<qmHPB<kzt;}`Bfy*Z8okPS^q^{h!2l+@ZwU)n1$uPw<RaG)sngm>y
zuPD_A(^o#D(v&fzVId90yknE16*EV^6Yig;Jq&=P`~@iF@?TfHNp+z}hxb%5hDBmQ
zEPP>|851c-c4ALk)YD!o${Bqn;)2eEB>V95ZgQwnh`KYilEhxAwg+<zDnm|*xLpsI
zKhuoW0v7Uw56p`_fzx}vwup<VIRGT&=o?M&hj6z@HMVP=i@JiaAxG0McjBLoteS0$
z$cmMHmW4Z~970~y8X`<EwtW!2G2SjBHnUZyvwf^uGc>PvqxJ!->BYB+>v>dM<vuZz
zpZA-g97``j6ci+qOMUZ~uTBF*_bjk61I7saQkN2|NQ*JbN6~Ib+1={-%fKId!JIDR
zYnDI=(hqYf8Qu;DIMXdZ6BtlL2(SC$9YOZL*0Mb}F+Cj9j&(s}O<lLkou#uO?<Myn
z+!)<t883EPYB=&oV9YR6n6KElQ8Co+B=JMyah7px8-<w*<Ryr-f!*(KhtUryffqd@
z<4CMd{gn!i+&TWP^uB_eq5$I19#0LAYjpG=<+XzhYm2{@6A!-FWTK&)smmb6ej*B5
zw|JX+DOa*=akg1k7cGu4Uj=t$)x}wr4^`(<`hkv=nw=RwFIm3zeHfzV%l*DfWa5QW
zRCC%&S6C(E!-f|lNc>fnFPq~gU6YHOy|Z)o(|vk6haKSDw_qCp4`^EU#Fg9qUcV#E
zKd~8FjOV469hZ@t61p|fVn&6VPzu|H!$36=(zV&E4eO(vsp-rdmfswOr`{_H^g}6C
z8Ad2IB<PnTATmPfr2*@8MJOkYyjHRPJ0NbqcaNX4_4_?xFD>1TdrGMKSC8F(J=$ct
zg;d3SuV9v0RKTVL0Wj>GFws5Ab^6=PAo6|6vTBcCROj1E_5p#34YK?8@Wh}=d<%Oq
zZ7J@Kgx>j|Qhkb-8^&qk7sv&b3;OcJ^AW4C&|aQegsOft+3wAD3@)9HqXiP1A9kyK
z3++M~O)rV%Zj1&)dofPOlcvGG>ZQya-+3BoiaY)U9jMEPCj)Jghu{XdQWx@;rmnhW
zWbGumjcBfZ2+Cc=AOGI*_i|Zmt(<mJOLP9C8-er6EhVBy)Y4+R5yyEPg6Tu*0n>WU
z*+@!n9xQ1--i>BGp*?$|*xdCBd~)jWWokpYY>XfHI(9#O9HpMNH%nFMk0E**J~g4}
zxd9zCF{aY1Wni#)mr&N*q%38aBtZu|p+a9)&ntT+zLBWVt&H`Q#_4pa`-#mmTB6J2
z?K@%gHLg+4?({IS5?aJIbnj(+q)tR$aM7oEl-ce(d6l%W5ocJ%l{gobclW_nFc<$0
zR&Df^D9=4&fVZ%skeqB+`@}bunqN>w+=o)5Q8EUUAwc?UGy`Dg9hc6*O_j$tv&4)B
zhVBytbrDHp7pZW-et?8;>f?EV)6oxe_8OpS;iRPVRs!4DWk09lCJNOc>k}Wg4PDmx
zEP8!&?@hIBet+4FdyZ%QUVhMNMt1ZzwHb8N2uDIAuWg}XJ6D3;h=Y<}`+FpIrG!IY
zsj(V89pLV0wcfBuo-(pP7J(~Wjar{VOA>E7_j-~El+$>l-`~mtI!byvx=KpEYvcCz
zQ%*07CiGIZr~R<>pi$UYuo*?5P66)C&86FY3IZW3sn4KPcfWcJW!$+mwdf*fw6wg1
zXBX!_Hjdb0nF^^|TgY0qt`cRhl)Jc#kuBceffQkC-BL}Ij_aj;O3OC>H-S}C33>UH
z4cF?jH_7>!WIc@hC!@;{yhN7)?**!sFGGW1bj$}YpU1C4_pzJi-EOhRVSgj^+_2Xe
zpM)lftdumHEUlbL37pvai79$toVs<qDcuEF+0&|sKNIFRecACYtrF5rtO=n~1s@_F
zK<ezWZ%$T!)G{5qm=RiN8q8T`b@i$6!88=yUkT5Nj?&zM0@2<x_;>+EynXZVhk><n
z{=j#+=Hn6;YffuauvT~IbnBHk{O$1V#56l1zBs~)vEd)Zcel5W@np3KFgBGk4>}(`
z$%lq8Pd+ejyV8tK9#JJj#Lqi$HQT>Tfzt3Jo+{suRq%ur#aTsCoDQGMy(#)CC;a#$
zqT?+4tC6u4UeXB)^1izIK6A<$xCIxKBE<4$?81utSob~Hg2-CIu>)VFzr{Tyww3I@
zjV-=20Rb2Tl%!82Q__jf7*4r~LA2_&1-VK5_#%<d;0=bM0s}vLA@)0v{IAwOfb;(8
z5c(gjAbc6pgsY4VcF==ot|uiWD7jvqZ*0l*to9{)qvRtx#Yi>KS`{mY_={z>v**=U
zB_kVJ@?mZ5b}WgrNK+7RqD4W%Lo+)}qrKaLPE+s76q3Di@R<~)ol{fQYsWhWrp;C=
z3#r($4Hs4BaSdeb)G7|8JK<ehz%bK!a<|v5voQo*3okxsA-$v+Mh(hPzfJxqn}V-B
zri4tJ>*q=*n%G2X@fA`=*Uc|b%=#+>Dc;Wsj4?lM=F{IpWp|Gz7ox>hQ_gxxeDB6X
zyKH=TIvp1H{yzgWR$6~s!T@}sC64ZbiiaLqypG_^=3bvnk&<i~Km>Ipz+amyA9o6D
z@cn$3IsAp>_W}G2?oZt3)j7{J8hUiS|8D8&UK?Z)6Ga%RzMI(br<eUp<d+G*exl|X
zq<tUD-wP%Cd_DuImA4M5Qu9S@{)<Aj9V?4;w5`dN5r>P8&G*-euGVv9JWDf%p|O`P
z)`v^lIFDDqDZdH(PWi58AnGKciG$fYQ5$THn76;){pYr3vp>=!WOn#^G~Tnlsgvl#
zG(D<ZP~orM^4|Ocf#8U_d>fWIS)NIsH%bF77BdYl4@%PnXhL!WULOp(Ua7!#@v;XI
zo`|`jpA2AKexX9{dGaV6s-lCD>M!w8)Hq;aI7X^k$0wXZ-kXF;fSF}cQ^ZP^0Tl@D
zq=A=A$kLC<*$X)g%bze#+iCJFqXG7Li(nNWoRy`Gw*Hmw8$$L$l?efK`espi^PGLx
z1p7RktaMZy)RcZ(euK0!viWrT%MG}h!4WL;gSP)r=Uag$snQ^%1_^cr)Le~32L#$F
zn#Pj}YM1fyh?Noufc9SK@qPjJmw)>!zze~yV!}#m+zitm@erA#2Q}2frht#8htWCg
z!exuuBXf*pnHDB>Mh>-?A{>x?3Su4%@@F+iIKXb#$G}TaL7<MTA=N_oT)3{)&!Q|b
zLUGH9o3l5PXh2CXTH~6Tz31QEL{$ChGsxidK7TG2^XG>nP=&gurgQV$yy+Ntb4@e8
z__N#dXwk|Yv2OoMf+I9hbNmxe0QvEqf8$ciOu6<-xkpRIM1>63?y#~3dq`b+I%-LV
zQ(H}8yn8f#l!lhpgN@vzJsdCmNte53X_vg|_bq?_7t}hblF@(a33CxA8>wNFCSM!l
zaDcI~G5z<Tda|(z4k}=yjJAT46=UodCz8a}7CghFv{cw8n4>ybw$OM=vkkQhaZ**d
z7!yE-Oz}NFMYy5v50wOX!5_`IU;A1y#7(yfuLkWdHVgSR+~RaI8*{6+(PlbY7X+Rs
zT$$i*OLK2Vrkkl|S#Moa-kUt6y=17;WT<rO>9y29ILrp3GI;=*2#eqct<sTnX;GPH
z1<39Yz4Ih6LVaHH-4UuR%)2{s!dB=`axA$qau&~-g`=de1_>;qloDgzXZKeXY;rvk
zZ4rie286AW_-@}F5`_%In>fnjFN&2CrUNS$HqAlH8g4ZjB_%Z*_S8&Fe_6XiwW1;)
z9%?UbAv?v{HD%zGBtDald74I4$WCdNC($`+gnpfEdQ2KVvwERC0-~Yx&*V&(*qVA}
zV4(|U{KPoD+ANm`nADm~5{V|KR)c6|*n*`wUjB@xdAY7s@zuy=ZgU#;kIufFMdpem
zS=k~B)$+mz)$-pql3@!)N@=uh37{Z-Mc8Hn){@Vi`;|a@onxGvvF&DDVyB3Oi~0#@
zeBh#aC5?ZqijNKhMTE#Qsx@^Js8*;=Z<8U;va2=a<4@_p10%=^^@z~k6i!-t$(A_%
z;M$`+bcIB7ZcCl{s{v*Q`Md;lDWgJ=6L{MIJfmnwEiTT{fiJ@}#=9=KFycK2=3pyJ
zns3S@e4D@>jO6;$>kUE>yIFB_^-Ua9i>FnZU4*9V(zk{i?646TN#fDX)}+sdFG=qu
zXyPs_TcRpL;<r^<aO#GO+TI;kbV5*Jol=2=Dq<(twzuHVc`&Sbg<4z0GR~Bd0l<R@
zQ`$@ht*-;jR$g04Z(|mb-t9j6gWh+nE!zIi_%qOBm|T^!c2MlaLPL3}uMN>gn4IjF
z$Y~H*SB`Y0AZ3u9_h+ROwcxLG$X@@(NK%Gj8O8&RPr;ZDlsv1l04ODy8xPBE>9P(~
zR(5T;yT9m+{DN}_Va~{r#jKJF(X*8JqD6D!QsRQLqWx{R#Vn~yWE5iE#1d)_c<HuX
z%QJ9;tc^nBA?VeEM_k2O{iMttrCfioEuN^;n5muZ@bPIs#PUodBK$Q<uHp$A%so=Y
z4iJfWF}*~l@is8Q(dmZjz6>df|6Q8;nuF_YaJu}3Lb>b00Bv(HWPPw5{Md<s$xOO8
zOF#)RwRZvXgq&dF6NO3gax07;eE9P>7(MVOT$KMTXI4KClwja%`TZ=GKZZ2fraX=0
z715DM(1Le7__++(A#sZ%2b=1VQ-Ha{7wU&xDF|pweT$~v^xmz4+%$36tD+_m1jFt>
z6MhVdBFZ)%#u4p>hzMqQZOO*$+S=wOoaqUXQ=Zx0G!OmZnVx;R1Gqk90&jd)I5Gep
zF2_lIPjSfz*RKOwi-iT7LK&#U{2c;eIf@6zz@|N*v6C}j5g_Q{aL{X}<kY|Aq<WBf
zUu>j2W-Fah@t9A^IdgsamM}p<Mb`UIiKm4LeG&W)1A-(E4;+gGjwY|8vg8Xo>4jYh
zo4V)DW72;%qeTx9$&Kp?N8EgZhydC7vQRlfi<$^WR5Gh|f{@NctY7ou%!f!Bs$tJg
zIkP(saf2ZNfuA%zSN_bI`DOBMvc$ljH}0Q3U9;Q-5Z$DtgO`~^ZQFKK6OhAXJll@S
z8065F?mZV8%RL&)ou9eBN!jCm=X!o=eK}dlckiB53<Yo><ihZ`kqk78LIC8K+U0bb
zb>l)0C`tYXd5Bb(KacbRckZ%jSPO=*zsL6|bcX&R16WyS4~Sh5(HM24rEMg;$LI)l
z4Mz}W^f40Vz#qP2H;2RbC~x8P!T)T%mcvxUvG-hYBo?#G!Z|O|s=t`f`8~j4YT9&T
zA1{;c@7;#@Tfb(+mh7}w9stY`x;<{rl!+d5+5555H6^p6)#83$uq{>XC7stBix^-=
zyL+>F^C_)K0=PVaA?-`9;(w?zJpCncaWcw&YnIhikFGrYUS&(5<<L?9>Ri5Mrx+{V
zW^hq<AA1i)3qfvbA-14%)D}Qg;>4l#xCH5}4=mNfRUIB<CYP%S0f+4xKLXL2gM(op
zab;cD{=|h75q1gowl;sgGAeFKO!g0K?QSzgEl(WvL4=u^@2vE4#~jBeWw3H&$`Bvd
zAFUEXudQFOR5S+Fd0L)>)wgaWpfq&1N!gWCRdYgi&@`?|pt{XKYNgS?lz!Cr&C8R!
z8SD88*y+}Pbq>P(0HE<JxlPFKbZDi>#S|^?+umfs_KwwEC}HM2_zA)bSZUqg(!Yz#
zguh(%1%|1*rAzJ^Ug$@kecXZ>2YD7G`mv{wy_IRm&kni&U8urLsnq}1nhJsF&EyC~
z+#MTijE|q|1HkIvK8dlAs^M%$;b5xx`#E6OfZAg8<6b;rAaFX<&o?E+w?i5EV5fh1
zHPS@7t-KuWuc<~sk8YhhvdYdFg(L+OJuCPm7)f-cox{rr%=*>=PL5$8Kd1vQwH!L%
z;qvNru(ytv23mI;OqFe!O>d93M3e;I5MA`nVUVHd)S^dk{-mC#B0UlR&dofWf|P%;
zz$YwG%9q^$-q*L$oxX?vuxbBupvCfokS9~x;IRDLv)TT~T*l1K{J&D8E7h!=(M)i&
zSTp5`Rc#`7;k{UD6t!b}^Qxd7(PPRR*27$5H`5y|B$XWH(xui|WmYAeY|;xPEX<_@
zEi|b_sKf<o;4oD2<Q3eWj`Pk(+lJ~Lqs}-u&mAZa3?FFUtSFD9DXu!UysqweuS|LY
z0aP>;#NfN-ph^u5E0#mM@!=R%aiHG3$3sM*wT0@R)9+_|mdFhV0&?2+v^%Jb<H<@W
zJ0Fzx#$USk*zCWwdrn60{aT_Fu6LtI?9P~e_V7r9Q$k36rSDwl7y!msXiIK1KUQk*
z4lh{>+tJ_z5m37pW@wRX?_FCX_+1q+$0}yfyg#S0C{(4Or&fsx$D;E%Jb8YBa5Uj=
z&CL-fQ5hpQtjqbQWW>mt7R0A2vRPro%Srwi7BsLBXbnjS8>Tg2FHL|majX-jP*EKP
zGG$E@!ww2GY2stfo2Aw1X=C8RB}_zW<wa>E1NT=i*6N1YW?>;(6|~7JV&H%g2sm*?
zdi1zLSdoL-Ksb!iIOoy|<J^#kSO(he3o<=yy=MK1qVWm{yrpW*%vKwhHo<&i5k(vg
zT4nT*v4a!08&gS>cGyvr$CS`_*wkoRVNBAonB<tmVO(Q^IA3eQCgK%w#JFg55)$Ev
zb3qzp2&|ocHQpfJq`$i4B&NW=mMrE`H4GQbQcIAq?k>!|!ab+l2+!o3@#rjdaGb8R
zBDqesWvYk1CcSp7HK9LIq=Wt}XELFm95lYnhGFSK%NRH-<_0@kmF=nH@3a-98>nM3
zf(zw(g0qT8mD0!s7gc+C#lz`sc;@uqVc!q4S8qR$Z}KZE17=oK+#vy?6YkwRWY4_M
zdcp_|&?D#+>M0h9^xM-RA><EyS$<$RI~~pz>YD<4Q0ksM%HFK$@{ecFMbEJTlFknJ
z4w&RzcC-4iK#_t3kb*mS4CPc-!Iuz)P1HlDd9vJjNbAexq%lUAylWWoKWr1ALCq-=
z>hYCtAH>4dJ^fO_PcQ(7f4jQbfc}b_w#Sy3UyiAqi%jQ=C5Wa=YJ$Yy1*wv&??>rZ
zRj%N49t;Xw@>X$1iJ3w2b|pvKYjz#2VJM8$@RP_|f+F4rImg2mWmrU<CU-=npp#NN
zRO~Rauu><(Uj^v0xlWY+TBCC+n;>oxl*X7jUz9$zOewvP;D$gApDWQigFNy{?aCvv
z!e*hHmY;t=(c1==;BxEvPU3hU?Xj}yWzuBtwQURwuQb9Z{4Lz{4|kKO8?Ku0r<1=>
zc9FXuIx6j<#-c2c$&vq9<O%->08$@GKDMpj98YZG<HXD7tmyQ`6_1nl#?c{7#39Fd
zx?lQ^zw5d2e>VZ-=gng~hV8FUam!l6YF2Dqk=kpNR7>TPx?dq&;EOWf4jYi%caZ#6
zrkIXtVqT52ET7T$wF6<2#X#4>LOeYR{xTTJ)G8nSl%S!5lmT;>QKMGa9TbhOj<kII
z*YR4?@{s-2!?PUB1I65gHF~dN4cX;R6dUwgdXx^f@wgNag)2hD_Crxqi-!A42_@Gn
zJ=_PSE%`F3eJEgr6MM?4#&OKH9A$nI3Ut5_U3A1p66r|!2B~u<y~5bEV5MxDgQS;-
zk+s`rPHvn$65R)cbn&}ni-8GER1v#!e{DauYNeK%Pz1L%53Q_Tf~&PfL-5=n+S#aN
z7FLZ&(i#A;Gm!p`x{;l(755i-`SzMb;^cS7X5eqE7o(De(z!Q3NOSGQ?06AZ`)8fV
zA1%-Kmr8Rbz)u<xewocwVD7j`LXAyO3YaNjx2F*N-azW8#M*M>oXiMig|d-Qk&#jT
z!8pHg+L+=c_ppgF)S6|W0?1w>uDrs>#8*yJMG^sh^(>ca!`(TxeMcK-phDLgtgFv~
z7L-Z2Wwz#VMmVIq@mu#o+ns1EP?v^t8a|ZT8vY7)AT;$JE_}9|23Ky1?7`W8cs+)U
zA5z48R-f#6Zx><b6=hP#mrutMi|z3J)VFPubFw2H0D%F-&NAW9^vWt#J*(vn3HP?B
zo&=z|HoP}?yo01t96aho*v7HLxw%YQN;&zgdBMOT@NumZg~PlVYS6D`N!5gzT?1F9
z-?GTgahH=v)}tpYy1n{QN1PiUmy^xU&Ess;5iZ4|4YaqyX1cT{vvYUntXT-Ybo(w@
zf0g`Mi|vS^Azq3ofCn6`FagE*X0n&{9v+zD`Grsugey48^G<MTS!_*TA%vwocDCSx
zdCha^;Jo=^%R9vqRysQiGAh;4H)c3HO`BEg+&e9LezZU>d?G51!|LqZ&eMTt56c(z
zdDpGUzxVsC6vR&==nUd!XgnSI!WK<7Qh;TRINd<~y80oXfn_e$V%$1NoJi+`YYiAC
z`hzVEX0;+ZsnJi?l~Cz^#wz^|>sXbsQO`z1_K&KAnDAGb{{6KsM{DiJzn`ExDU#Le
zo#P&m7<jvqZ5TGF)9nZYPJcKY59R6eCeL;CzssHF!^+my;DQubHmnMfsu6hwP><Xl
z))+mI>SXrrHm*kjMzy8Fb|wUO6kLGo%3jpS1x?yTi8C9IC|}SL_+GWJ+CRX6R+B$i
zP@O$JpWa}BhOO1r+8N0|5F~=wb&_oO{5WhC=_0eid|o*JE#*a@_16cZBaMZ--qtqs
zCC_@vIoUXZXuNe^4tL&Wtmoa?0#l1^gp}2ec2BYe0nbl;t@7bcA}fchXh=XH$1TQk
z;KMt?mO(+!uCjEX{|!%*r|&{c_6pxUEmf<o<kw6cPX(xf%e2QzjPqZwD%B8`6LLek
z=>&AmANE3+7-eMts4~Qy0{&GEmk%%Yrb?{0RdgPh_y|}04(L*o@*C&!PEm8&4tBS8
zlW5=%1T;3@k*y%>jvqW|l`MdIC0j~UXBo@%?CLIL!``9j{Klzsqm1<M4O7a<sghTy
z)Y1kuQ){8B6)2C&Z;0P5vIk);C8lCL4k%5zOTRA+XmG1_4Y?R#ndWz*kz#&wcQ@sA
z)m5Q{q!dp}T<j}tau*Rz@Wr{s5`Z#tIYu{|8OB4^=^8+uLT*qXR5b&T9nH<2M6PlX
zlu(QLkJtqdv#+8tQx(534pB`n$6A)rFE1Y82?CX1*c*THomWsPCg=`BD?3z@BI^AG
znS^R5{l0#|h!>fp>4fn;L#Oj6l$K+gaYOgklIORQH4k+EXL-4nA-Mp=-&1Wh#-=Oe
zh@DZX4()!aNS8_J$$y9dY4qDn>cN*g7tZGeIc!%g_*cjpk-MM*@MQD0S8qBfoel7G
z@hsi;B_elTWavh4`|ha<C*&Y*C6@<bnnr{bhKwn$1QjynAI8L*8jG4iQ@UgJ|9G*z
zh}ByH+R%~0dF~BD6igfo>}jE1rWmhj-}R~oTp**j1f5^gpSURi$Xad9M$%$_Pp_?+
zMROu#5vcJu`{Cb66o{xJH($_5Go1X9-rZtJgIf=Ja-|meOFTP{)f<CgbEx$N@1^L#
z>vF^L{f?{FyZ!PiuPomeL3-cH_-DhKpY12u{iawK);m<;)zrv;sz*8g4HhOR@Pm*f
zle^=vg0XUOCi7ckVZ*br{Ue+?Iyn=waxf+5vVh<N?Ck$5CAKqFOKwdPE9mN}`r4$K
zhWRL7S!Gw73PdueA=1m>@2`0>+4$+CkF)N^L04v1d~wa^U!fOVRlkoktW5Dwq=iXE
zG|0%bxAS)lN$9N$u=hD}nM_G4iNkM(&7r2)9T7*FK%UlxBkn?Aa*0Jmr7Zyj>X<_E
zBn1?fK|xq!u9C`>D9(I&q0tbh@Q+^rDz3?_sJ5>NEMd#ebfPngTbMvtICvwiVVJ0&
z79lkv2dd1sxq#ehtY8Iokj92kGB7Q4Y>HO!KJf5@dDghtc}#9(dn-Eicr665h=hb`
zn$a8x)4xNS1S{f7K~wg92I_!3?JQ~;bJ@RX8TJx0s^Fl%K79(`88@i>HMp4}UF78l
zxghgVVha&P5x{C0#an!3J1!XERPm1CM2#!`x=4noSTVRVkg&LN1vs$F;-}&L1vn=J
zXedd|SckvWai3|=F9<d{CjfK1dMrzIFK+L0OO6|HD64<ekW0vkF~9*EU(?U_@iD76
zR4X9)K_69XyjiIUX1sBHyy@X{Z1EkVVp2?0@0j22=T}u(!jV>u_U`-Zjc-*@AIrGO
zSPz;!J06z4ER$3i=42bBLL&+zxhj<&w01vSCRR}w0o699wW6kAmU3O87ZU!AA4S0)
z-97bb<y?f2m|*fKtSO)mFZ=vExh^n^T=N(aRk7g41~=G-JA?e1kSafwCPH!2!@JN#
zeGmY15}b&bY&D#g`XneqUwY1VyBdDkqaycQv6tjVQd9E!i!Ms<$uai^g9|b+HLPpL
zn`*m7X>_gXn1KF-{AXB|S;G5cta74yjmNHe?E>sVYh8kJX%E;mPmA;p@H5@)u6E{P
z_|+6Y6WrkD#t$)tVeI6XiMX>!?PqfB<Ig35SR~Qy*2&dzRvbgDr5rcOO5g>_LGJmn
zZwq>PskON}>f?qJ&d$lnBFqV?JiTmo@$g#uZKQ+<3o$=lb}Po1chYCWY~{(vgNK}F
zKZI;QOglbdJr3}kCG}<|#=(gtGM1(=mL&Xqs3f5DZ(zP%MYbx-GQ;ZIba9Q}&G-!_
znMqfDB7MXx#iRDJe|A*ghj_p6vYJ!(43>BzZPcc%KY$0m88Z{)KRpT_q*7iE8eaC-
zfAiWvP+$C{h2w=!yy&U*(5N9eVz5&HR~#47$wk6MMG<J!R^(Q@U)vlpc<Xf=IL<4$
zZ6r%<kWiF&?6c5b!>N)lD=W2~W|gmGPFOHuQCYFx*xS(Nm^kdcASAfZ!56SIlW8mE
zcXV%E-?7L|cMY`VCX2=Fl6BCidTT2mO+rv&{z!~nJ2#M?B|?(mpJv2g7)9mQjGeAc
z3mBawR|b4Jvag5;ul8f}C4@d^aaF&uM)J|Qmy+40SxR#2syKpAW^90;sz5fhdF9b$
zYmYd{@uc%;6=%6Nmt_8C>;6{`s|wH>`<Pjj)s+^1u;Y)M=AD$87g6BOIW4q6?`|C3
zP2?j@uUulaQ>E*uu)k)Q7k1;$ZCBfKf{Y~e3IU*}17#iy_^t^NbKmL5wL071d#Z7t
zo!6%7m`rsZF2g9ZgQE?M;UPQAdc#yZaHkBVYT@rYIXj*`yiO?V1@xXQ)lWt3ib4u|
z^K(H{b*Sp|{zWYi^4=GBDty(}sX{3R?P=*qDkRoj?l4c!LKtRUUE<pSJ?0%H<i*vE
z{Q&mHpNeS{ebxp-Yz!5t5CnVje7<3x6UuncTRrYc)3fP&pNygxOXsz>)HsPNj?@DF
zx$iiSIm0fCQ$a7>B0jtY@fJvg)q^7sPtK?9RF~eA2DDjL&9A&Cr@RaPux34%*-$;t
z*T&7A-X~x{pLFe#&akzSaMFMm(;}l@6Tq$aVQlXbkA8+j#fME+kS$BGZ<|4}4QU*1
z9sjdV4pBTEKOW6dk}npql}s<psaNKpfUzPAWB5v6Q?O7q8%r$}OEmkMsPJg64!F4x
zGDE{r=cTj%)ciCOQ5t4wHiu7od-Y;$D*H;1^_PuX3_%iw>+=KCSA*u{g+pPv0PJc3
zTkCNGzCl4Zgp!=b&}+@jz7x(~HKS*g#R1f?9y(Jl>btz>46N|P^WE~i8jR&2#g5R%
zyWgl~iE8J|RM`<l*jk%@)}T@Ys?HxGF5bVFyTV9@6j(W3L7jHVp`I`N3A_g3`6vzU
z?5jJ0n@9XfjrhI$B@K4*pyJF(pt1s(<I~d@LLb`m&zvNs1@rgcv4PCYEOhG}aejX`
zy`yONyIUQ3hU7JMe>&WT{BtZr^ab%lG~b8&x_sg7$@mC$Nx|`C>mEZU%j^w`=fYTc
zRC5f6w$xvyKY|;PCq09uNJX3)ef9nKkvCb~I`}#Da%zvJIY|^+A60NYV2QDwp;pDE
zBz|MW4-qaKZ@@0Gr66ih830J-BD4%q3LJQ1Z$)$#KZtyvqYjbBzk|EI=`{Uqdc|Ep
zi<k>h({Mk%xGkc2?Y}ZW8PF<>0wdBQN$cJBM=8}T-19x*pynU%?u7o<bRO$rnv<>*
z&f-jgm9_i&65c^a6DNHg(8niW)WP-TQpw6Z?S1c;{`EZs3I5c;N+i5%p)uym-L=X4
zrk0OfreQ3(Smy)cq6W+|XCn>Sm5L=evkuu+ConV3booJXl5HBnvq5w+IgDFKn}Jw2
zYoKl1*>_jtSw&~ag4O~nC#>)c)U(#`Q{n|$V{f!?zqPkUqu`kn2-h~qplzw6hYCyl
zHZZQZwXONh+Y;bjThqEe(H^IWIv;b|{|q8+1r=l74+*|f*6u+Oy7JGV-d!b>ZVuR<
zbinBF(HTrgV>-Z0@sK@2rIR=_A8|B;k$1-UobOYiHDA)(=QT-c9feY;prmfC2vn~>
z&~UBvp}XKqz0m3da!wdXx=W7QLU0n#Qfk$+r_MEd06(FgkpTlU;ORo4JrjYY8N}y$
zT5gbGo5*D-{-qAqwy)9+?`7O-tyf520+u)6?)KMrFr*%479@dccwS+qYh=jp(5lFy
zD{(r38unqgNSWWC%Q**7Z~SEH(d+H^I)x^@zC($G*smG^wagK<Wq+2x0TmtL+w{cJ
zYzrQywOI~RyPAfRs@v_MHsa;ZpjtE=-Y8l8Sq*Y>h~d-*_iVn4E;$!l-zqmWfAz^C
zyPh#1+%rE2=E)?Qt5IqmV)19!j+5#mT2<Wj;|r`aJ%^7n@O=(7{j%&*{(Cx)5Tk(<
zY)8}-#h;A@fN`hw#@IK1!Lm|m<_p{`nAapm7NinQf#FuD%lh{t{KDA`@Z6p5Pa-kM
z{$&{I2Z9o&5+a``8vv^iLqV1op|A_XcMJPlndXHGOuqK-;X?-9ubmA@`(Dm^Lg8Su
zqocQrR<(WDZb;!e#Msa70Ccqg^tBezSFGQHER=`cz)n3sEQ3@4yoRDmQkoA*S%+VK
zc^BUbfvy<`BVK*y%V4lzeL8qsFeHTz1AyN(zh{U5mXy`5dZNYfNVjzS*81^6L$NG^
zHjhiedKJX(hp5KncW`x5ZhGuun)@3;YYp)d^FkeJ=<siA6%Oy$PNQXzPG5v+w$>7S
z>{p#Cz?QH5`UT}R(meT}>e&CE_s5|8+unphUD3ppLDA06nV9Kcg{#OQVQXqf{9j<O
zf2YD)ysR9o%$%Ht%%)66?1m;>CZ@(lhQ|MnOdM=1Ova{6eE(+!-v3#m!=Pm0VFJs>
z#+7^>^WQm-|BD37wx}Vm;)4J8<_ifOT(~1F%M(SwI93K3OIaFWgic@}a9sf%xpJM^
zX-G$@Uq`!_?YkR_TE%*1X|1luaM}n~v2&WPR|z3a`_bFi&28$I*Hr6JJN~4cQN-^%
ziofEGt-)>%xm!yVxSsm7rUq)~0FJ(N3ezrp7;BIQ<2SHch^BsG_(4@{zg+B~N+$d@
zeefm`q^7<{>`;RK6liZGg5O`^sRZ|VNclBrqDE#BJ?iIv4$ByOOdx1XFzp7+Mfx;F
z2HdVg@Z<f2DS?kX=YgHINTx=5=fNLLP*B@ioXAi+`d)ZW4$y}?Je=skz>Yn>FX;d{
zP`$O&?iDPRDrUfkxowW`Z&ZsswBw%f2d!2-;wV@5<!4n##2Y2bg;{n${D83AG)uAl
zq2pmGCqnTaJnbPY9h17WS8A6lMYWCuQV%0MRy>pBRO$d%d8!m=TEwFo)c_Z#mh_~t
zw+c>DcxvkaaFnibP(|JcJREB?nH+Gd*?+KUvj~p+?X4co{5T=Bj{fv?zft;W#&=Ya
z&tpg<)YvVj$53>tMMosh9$NZ4|3GNel&O(T6H~s)o-I3trF9i+mfu8|>`=1dap3;K
zFpZ}1{{^1|VEinh>=5(K8Z94Dc8YnHpk*ngTFlGmT0W-i67yH{`(H-cBNBf&RLdun
zy&@4Wv@ECW6N&ms%L>Xtk%UYwD=9T1ncK9iq8w(nzv&v0oPK(AEk{3NuEce?9yj1d
z+=QEP3vR`2XuqrNxC5(jCsyMw+>Lv1FYd$rcmNM#4IV=K{*T~MwC}lAWY~TEEXVjP
z$C!`f36ar3dh{emkBb!LX*qvIIVn<nP0MM@DUpiKT0W<o7Fl#v%NfcUkrg|%)KTh0
zHa2Rhr__s7{i)>($~lpPv0Bbj&WqG$X*ox^AW}D1%X!Krk%kH_7bsVlFN!pkYQIEp
z5V>2e<uc_O^A(ZrUTSZkU+11r!#*NEH^1sCM{hDWioBTT|0|Z)W88nE{xdT$TRaP!
zzm030e_K4uF8j~)tV;JA`S*I)fBthfV9HcI^EziXiIdv=+8dNR;$)|4xk<^yo;VSU
z&_2~~F$duw48|U4H^Ob^aE!pV*bePxY+~+!b~8E{f_5|B!7nL3jKWSBjdn|Z#T<jN
z*ahRz?#i#3<1qmfF$sU|#<c&(2*qSf!Bn&x^B&%(WMCHd!aiuX<OAmZH~<IYV6@xt
zA#*Mc!7$82yBQxb55-|P97o_t&UuVaD0WMZ!h9^i(dfS`=KsJQRqgIdzhkiw$6;?2
zY=y0{4SKLW24G)I!*tBS@i+kku?4n7yL0Vcn1s`CGTJ>m743gcoQ^ZF80|itgC#f{
z?T#zOGAzfrXt$W%cXm(N{blcvjc7NE-B63rKJD#(u^Yth2>T4T&-o2_0JmZlZo}QU
zAMNw!2p+-{cob{VKK<;o%iiG^(LN>Y6UP2MHlqEDwtp}8#VP#J{jH}x)!+JoI5WcC
zGAm8XLvczbxn+O$D=m-2DNS@s`5#&yi&GKpmU;DBo`|zzxm#9+=yS=4ZwTkCE^uA@
zi*^xbozE>BUTFysXH%hDs$#VSinH^ETTVRJ(n6e5={g5tD-6Zf*aq8TJB-AR=*1{;
z>ZZ6?uK&&T>|WRN$*va<yIy|g+EAqbR%h%a&Q<plIgNUG+Ph$kc;n*y-5a+=dpyR8
z_ts0d-_FsVB;J2ZbxshUxA~K%_~+F+cN1SmmCot@`FEXD#h3j+=S=bSjnTQg_;T;M
z-*f)2#{3U69J;FtWo~41baG{3Z3<;>WN%_>3UhQ}a&&ldWo8O7HZ?dfI5r9;B}Gq0
E3P=FPZ2$lO

diff --git a/doc/software-manual.tex b/doc/software-manual.tex
index 6031fb5c0..43d41e89f 100644
--- a/doc/software-manual.tex
+++ b/doc/software-manual.tex
@@ -1,4 +1,4 @@
-\documentclass[a4paper,11pt]{jvetdoc}
+\documentclass[a4paper,11pt]{jvetdoc}
 
 \usepackage{geometry}[2010/02/12]
 
@@ -205,7 +205,7 @@ fontsize=\footnotesize}
 \maketitle
 \begin{abstract}
 This document is a user manual describing usage of the VTM reference software
-for the VVC project. It applies to version 10.1 of the software.
+for the VVC project. It applies to version 14.0 of the software.
 \end{abstract}
 
 \tableofcontents
@@ -216,7 +216,7 @@ for the VVC project. It applies to version 10.1 of the software.
 Reference software is being made available to provide a reference
 implementation of the HEVC standard being developed by the Joint 
 Video Experts Team (JVET) regrouping experts from
-ITU-T SG 16 and ISO/IEC SC29 WG11. One of the main goals of the
+ITU-T SG 16 and ISO/IEC SC29 WG5. One of the main goals of the
 reference software is to provide a basis upon which to conduct
 experiments in order to determine which coding tools provide desired
 coding performance. It is not meant to be a particularly efficient
@@ -258,7 +258,7 @@ be available in older compilers.
  \thead{Versions} \\
 \hline
 MS Visual Studio  & 2017 and 2019 \\
-GCC               & 5.4, 7.3 and 8.3\\
+GCC               & 7.3, 8.3 and 9.3\\
 Xcode/clang       & latest \\
 \hline
 \end{tabular}
@@ -453,32 +453,32 @@ range is between
 0.3 and 1.
 
 \item[]\textbf{tcOffsetDiv2}: An in-loop deblocking filter parameter for luma component, tcOffsetDiv2 
-is added to the base parameter LoopFilterTcOffset_div2 to set the final tc_offset_div2 
+is added to the base parameter DeblockingFilterTcOffset_div2 to set the final tc_offset_div2 
 parameter for this picture signalled in the slice segment header. The final 
 value of tc_offset_div2 shall be an integer number in the range $-12..12$.
 
 \item[]\textbf{betaOffsetDiv2}: An in-loop deblocking filter parameter for luma component, betaOffsetDiv2 
-is added to the base parameter LoopFilterBetaOffset_div2 to set the final beta_offset_div2 
+is added to the base parameter DeblockingFilterBetaOffset_div2 to set the final beta_offset_div2 
 parameter for this picture signalled in the slice segment header. The final 
 value of beta_offset_div2 shall be an integer number in the range $-12..12$.
 
 \item[]\textbf{CbTcOffsetDiv2}: An in-loop deblocking filter parameter for Cb component, CbTcOffsetDiv2 
-is added to the base parameter LoopFilterCbTcOffset_div2 to set the final tc_offset_div2 
+is added to the base parameter DeblockingFilterCbTcOffset_div2 to set the final tc_offset_div2 
 parameter for this picture signalled in the slice segment header. The final 
 value of tc_offset_div2 shall be an integer number in the range $-12..12$.
 
 \item[]\textbf{CbBetaOffsetDiv2}: An in-loop deblocking filter parameter for Cb component, CbBetaOffsetDiv2 
-is added to the base parameter LoopFilterCbBetaOffset_div2 to set the final beta_offset_div2 
+is added to the base parameter DeblockingFilterCbBetaOffset_div2 to set the final beta_offset_div2 
 parameter for this picture signalled in the slice segment header. The final 
 value of beta_offset_div2 shall be an integer number in the range $-12..12$.
 
 \item[]\textbf{CrTcOffsetDiv2}: An in-loop deblocking filter parameter for Cr component, CrTcOffsetDiv2 
-is added to the base parameter LoopFilterCrTcOffset_div2 to set the final tc_offset_div2 
+is added to the base parameter DeblockingFilterCrTcOffset_div2 to set the final tc_offset_div2 
 parameter for this picture signalled in the slice segment header. The final 
 value of tc_offset_div2 shall be an integer number in the range $-12..12$.
 
 \item[]\textbf{CrBetaOffsetDiv2}: An in-loop deblocking filter parameter for Cr component, CrBetaOffsetDiv2 
-is added to the base parameter LoopFilterCrBetaOffset_div2 to set the final beta_offset_div2 
+is added to the base parameter DeblockingFilterCrBetaOffset_div2 to set the final beta_offset_div2 
 parameter for this picture signalled in the slice segment header. The final 
 value of beta_offset_div2 shall be an integer number in the range $-12..12$.
 
@@ -752,6 +752,12 @@ When 1, the Mean Square Error (MSE) values of each frame will also be output alo
 When 1, the Mean Square Error (MSE) values of the entire sequence will also be output alongside the default PSNR values.
 \\
 
+\Option{PrintWPSNR} &
+%\ShortOption{\None} &
+\Default{false} &
+When 1, weighted PSNR (wPSNR) values of the entire sequence will also be output.
+\\
+
 \Option{SummaryOutFilename} &
 %\ShortOption{\None} &
 \Default{false} &
@@ -778,7 +784,7 @@ When 1, CABAC zero word padding will be enabled. This is currently not the defau
 
 \Option{ConformanceWindowMode} &
 %\ShortOption{\None} &
-\Default{0} &
+\Default{1} &
 Specifies how the parameters related to the conformance window are interpreted (cropping/padding).
 The following modes are available:
 \par
@@ -949,6 +955,16 @@ Strength for every * frame in GOP based temporal filter, where * is an integer.
 enable GOP based temporal filter at every 8th frame with strength 0.95. Longer intervals overrides shorter when there are
 multiple matches.
 \\
+\Option{AlfTrueOrg} &
+%\ShortOption{\None} &
+\Default{true} &
+When GOP based temporal filter is enabled, enable or disable using true original samples for ALF optimization .
+\\
+\Option{SaoTrueOrg} &
+%\ShortOption{\None} &
+\Default{false} &
+When GOP based temporal filter is enabled, enable or disable using true original samples for SAO optimization .
+\\
 \end{OptionTableNoShorthand}
 
 %%
@@ -1737,6 +1753,13 @@ Specifies the DRAP period in frames.
 Dependent RAP indication SEI messages are disabled if DRAPPeriod is 0.
 \\
 
+\Option{EDRAPPeriod} &
+%\ShortOption{\None} &
+\Default{0} &
+Specifies the EDRAP period in frames.
+Extended DRAP indication SEI messages are disabled if EDRAPPeriod is 0.
+\\
+
 \Option{GOPSize (-g)} &
 %\ShortOption{-g} &
 \Default{1} &
@@ -2189,6 +2212,60 @@ For Cb component with BT.2020 container use 1.14; for BT.709 material and 1.04 f
 For Cr component with BT.2020 container use 1.79; for BT.709 material and 1.39 for P3 material.
 \\
 
+\Option{SmoothQPReductionEnable} &
+\Default{0} &
+Enable QP reduction for smooth blocks according to a QP reduction model:
+$Clip3(SmoothQPReductionLimit, 0, SmoothQPReductionModelScale*QP+SmoothQPReductionModelOffset)$.
+The QP reduction model is used when SAD is less than SmoothQPReductionThreshold * number of samples in block. Separate parameters for intra and inter pictures.
+Where SAD is defined as the sum of absolute differences between original luma samples and luma samples predicted by a 2nd order polynomial model.
+The model parameters are determined by a least square fit to original luma samples on a granularity of 64x64 samples.
+\\
+
+\Option{SmoothQPReductionThresholdIntra} &
+\Default{3.0} &
+Threshold parameter for smoothness for intra pictures.
+\\
+
+\Option{SmoothQPReductionModelScaleIntra} &
+\Default{-1.0} &
+Scale parameter of the QP reduction model for intra pictures.
+\\
+
+\Option{SmoothQPReductionModelOffsetIntra} &
+\Default{27.0} &
+Offset parameter of the QP reduction model for intra pictures.
+\\
+
+\Option{SmoothQPReductionLimitIntra} &
+\Default{-16.0} &
+Threshold parameter for controlling amount of QP reduction by the QP reduction model for intra pictures.
+\\
+
+\Option{SmoothQPReductionThresholdInter} &
+\Default{3.0} &
+Threshold parameter for smoothness for inter pictures.
+\\
+
+\Option{SmoothQPReductionModelScaleInter} &
+\Default{-1.0} &
+Scale parameter of the QP reduction model for inter pictures.
+\\
+
+\Option{SmoothQPReductionModelOffsetInter} &
+\Default{27.0} &
+Offset parameter of the QP reduction model for inter pictures.
+\\
+
+\Option{SmoothQPReductionLimitInter} &
+\Default{-16.0} &
+Threshold parameter for controlling amount of QP reduction by the QP reduction model for inter pictures.
+\\
+
+\Option{SmoothQPReductionPeriodicity} &
+\Default{1} &
+Periodicity parameter for application of the QP reduction model. 1: all frames, 0: only intra pictures, 2: every second frame, etc.
+\\
+
 \Option{SliceChromaQPOffsetPeriodicity} &
 \Default{0} &
 Defines the periodicity for inter slices that use the slice-level chroma QP offsets, as defined by SliceCbQpOffsetIntraOrPeriodic and SliceCrQpOffsetIntraOrPeriodic. A value of 0 disables the periodicity. It is intended to be used in low-delay configurations where an regular intra period is not defined.
@@ -2200,11 +2277,11 @@ Defines the periodicity for inter slices that use the slice-level chroma QP offs
 Defines the slice-level QP offset to be used for intra slices, or once every 'SliceChromaQPOffsetPeriodicity' pictures.
 \\
 
-\Option{MaxCuDQPDepth (-dqd)} &
+\Option{MaxCuDQPSubdiv (-dqd)} &
 %\ShortOption{\None} &
 \Default{0} &
-Defines maximum depth of a minimum CuDQP for sub-LCU-level delta QP.
-MaxCuDQPDepth shall be greater than or equal to SliceGranularity.
+Defines maximum CTU subdivision level defining luma Quantization Groups. A quantization group contains at most one luma QP delta (carried by the first coded TU), and all CUs inside a QG share the same luma QP predictor.
+"Sbudivision level" means how many times the number of samples of the CTU is divided by two, e.g. a binary split increases subdiv by 1 and a quad split increases subdiv by 2.
 \\
 
 \Option{RDOQ} &
@@ -2324,10 +2401,26 @@ Specifies whether scaling matrices are disabled to blocks when the colour space
 Indicates if the designated colour space of scaling matrices is equal to the original colour space.
 \\
 
-\Option{MaxCUChromaQpAdjustmentDepth} &
+\Option{MaxCuChromaQpOffsetSubdiv} &
 %\ShortOption{\None} &
-\Default{-1} &
-Specifies the maximum depth for CU chroma QP adjustment; if negative, CU chroma QP adjustment is disabled.
+\Default{0} &
+Specifies the maximum subdiv for CU chroma QP adjustment. Has no effect if CbQpOffsetList, etc. are left empty.
+\\
+
+\Option{SliceCuChromaQpOffsetEnabled} &
+%\ShortOption{\None} &
+\Default{true} &
+Specifies whether CU chroma QP adjustment is enabled at slice level. Has no effect if CbQpOffsetList, etc. are left empty.
+\\
+
+\Option{CbQpOffsetList}%
+\Option{CrQpOffsetList}%
+\Option{CbCrQpOffsetList} &
+%\ShortOption{\None} &
+\Default{\NotSet} &
+Comma-separated value lists specifying the Cb/Cr/CbCr QP offsets for each chroma QP adjustment index. Each list shall be the same length.
+CbCrQpOffsetList may be omitted whereas CbQpOffsetList and CrQpOffsetList are specified, in which case it is filled with zeros.
+Note that when CbCrQpOffset and CbCrQpOffsetList values are all zero, pps_joint_cbcr_qp_offset_present_flag will be automatically set to zero.
 \\
 
 \end{OptionTableNoShorthand}
@@ -2530,13 +2623,13 @@ Target subpic index for target output layers that containing multiple subpicture
 %% In-loop filtering parameters
 %%
 \begin{OptionTableNoShorthand}{In-loop filtering parameters}{tab:inloop-filter}
-\Option{LoopFilterDisable} &
+\Option{DeblockingFilterDisable} &
 %\ShortOption{\None} &
 \Default{false} &
 Enables or disables the in-loop deblocking filter.
 \\
 
-\Option{LoopFilterOffsetInPPS}&
+\Option{DeblockingFilterOffsetInPPS}&
 %\ShortOption{\None}&
 \Default{false}&
 If enabled, the in-loop deblocking filter control parameters are sent in PPS. 
@@ -2549,42 +2642,42 @@ In this case, the final value of the deblocking filter parameter sent for a cert
 (base parameter + GOP parameter for this picture). Intra-pictures use the base parameters values.
 \\
 
-\Option{LoopFilterTcOffset_div2}&
+\Option{DeblockingFilterTcOffset_div2}&
 %\ShortOption{\None}&
 \Default{0}&
 Specifies the base value for the in-loop deblocking filter parameter tc_offset_div2 for luma component. The final value of tc_offset_div2 
 shall be an integer number in the range $-12..12$.
 \\
 
-\Option{LoopFilterBetaOffset_div2}&
+\Option{DeblockingFilterBetaOffset_div2}&
 %\ShortOption{\None}&
 \Default{0}&
 Specifies the base value for the in-loop deblocking filter parameter beta_offset_div2 for luma component. The final value of beta_offset_div2 
 shall be an integer number in the range $-12..12$.
 \\
 
-\Option{LoopFilterCbTcOffset_div2}&
+\Option{DeblockingFilterCbTcOffset_div2}&
 %\ShortOption{\None}&
 \Default{0}&
 Specifies the base value for the in-loop deblocking filter parameter tc_offset_div2 for Cb component. The final value of tc_offset_div2 
 shall be an integer number in the range $-12..12$.
 \\
 
-\Option{LoopFilterCbBetaOffset_div2}&
+\Option{DeblockingFilterCbBetaOffset_div2}&
 %\ShortOption{\None}&
 \Default{0}&
 Specifies the base value for the in-loop deblocking filter parameter beta_offset_div2 for Cb component. The final value of beta_offset_div2 
 shall be an integer number in the range $-12..12$.
 \\
 
-\Option{LoopFilterCrTcOffset_div2}&
+\Option{DeblockingFilterCrTcOffset_div2}&
 %\ShortOption{\None}&
 \Default{0}&
 Specifies the base value for the in-loop deblocking filter parameter tc_offset_div2 for Cr component. The final value of tc_offset_div2 
 shall be an integer number in the range $-12..12$.
 \\
 
-\Option{LoopFilterCrBetaOffset_div2}&
+\Option{DeblockingFilterCrBetaOffset_div2}&
 %\ShortOption{\None}&
 \Default{0}&
 Specifies the base value for the in-loop deblocking filter parameter beta_offset_div2 for Cr component. The final value of beta_offset_div2 
@@ -2888,10 +2981,28 @@ switched at CTB level. Set to 1 to disable alternative chroma filters.
 Value shall be in the range 1..8.
 \\
 
-\Option{ALFStrength} &
+\Option{ALFStrengthLuma} &
 %\ShortOption{\None} &
 \Default{1.0} &
-Enables control of ALF filter strength. The parameter scales the magnitudes of the ALF filter coefficients for both luma and chroma. Valid values are in the range 0.0 to 1.0. NOTE: Refinement of quantized filter coefficents is not used when ALFStrength is different from 1.0. To ensure reduced filter strength the parameter ALFAllowPredefinedFilters should also be set to false.  
+Enables control of ALF filter strength for luma. The parameter scales the magnitudes of the ALF filter coefficients for luma. Valid values are in the range 0.0 to 1.0. NOTE: Refinement of quantized filter coefficents is not used when ALFStrengthLuma is different from 1.0. To ensure reduced filter strength the parameter ALFAllowPredefinedFilters should also be set to false.  
+\\
+
+\Option{ALFStrengthChroma} &
+%\ShortOption{\None} &
+\Default{1.0} &
+Enables control of ALF filter strength for chroma. The parameter scales the magnitudes of the ALF filter coefficients for chroma. Valid values are in the range 0.0 to 1.0.
+\\
+
+\Option{ALFStrengthTargetLuma} &
+%\ShortOption{\None} &
+\Default{1.0} &
+Enables control of ALF filter strength target for luma filter optimization. The parameter scales the auto-correlation matrix E and the cross-correlation vector y for luma. Valid values are in the range 0.0 to 1.0.
+\\
+
+\Option{ALFStrengthTargetChroma} &
+%\ShortOption{\None} &
+\Default{1.0} &
+Enables control of ALF filter strength target for chroma filter optimization. The parameter scales the auto-correlation matrix E and the cross-correlation vector y for chroma. Valid values are in the range 0.0 to 1.0.
 \\
 
 \Option{ALFAllowPredefinedFilters} &
@@ -2918,6 +3029,12 @@ QP threshold above which the encoder reduces cross-component ALF usage.
 Enables control of CCALF filter strength. The parameter scales the magnitudes of the CCALF filter coefficients. Valid values are in the range 0.0 to 1.0. NOTE: Refinement of quantized filter coefficents is not used when CCALFStrength is different from 1.0.
 \\
 
+\Option{CCALFStrengthTarget} &
+%\ShortOption{\None} &
+\Default{1.0} &
+Enables control of CCALF filter strength target in filter optimization. The parameter scales the auto-correlation matrix E and the cross-correlation vector y for CCALF. Valid values are in the range 0.0 to 1.0.
+\\
+
 \Option{SMVD} &
 %\ShortOption{\None} &
 \Default{false} &
@@ -3130,6 +3247,43 @@ RCInitialCpbFullness should be smaller than or equal to 1.
 \\
 \end{OptionTableNoShorthand}
 
+%%
+%% GDR parameters
+%%
+\begin{OptionTableNoShorthand}{GDR parameters}{tab:gdr}
+
+
+\Option{GdrEnabled} &
+%\ShortOption{\None} &
+\Default{false} &
+Enables or disables the use of GDR (Gradual Decoding Refresh)
+\\
+
+\Option{GdrPocStart} &
+%\ShortOption{\None} &
+\Default{-1} &
+Specifies poc number of first GDR
+\\
+
+\Option{GdrPeriod} &
+%\ShortOption{\None} &
+\Default{-1} &
+Specifies number of frames between GDR picture to the next GDR picture
+\\
+
+\Option{GdrInterval} &
+%\ShortOption{\None} &
+\Default{-1} &
+Specifies number of of frames from GDR picture to the recovery point picture (note: ph_recovery_poc_cnt will be (GDR Inteval - 1)) 
+\\
+
+\Option{GdrNoHash} &
+%\ShortOption{\None} &
+\Default{true} &
+Specifies not to generate picture hash SEI for GDR/recovering pictures 
+\\
+
+\end{OptionTableNoShorthand}
 
 
 %%
@@ -3302,6 +3456,11 @@ Specifies the use of extended_precision_processing flag. Note that unless the HI
 This setting is only valid for the 16-bit RExt profiles.
 \\
 
+\Option{TSRCRicePresent} &
+\Default{false} &
+When true, specifies the that extension of the Golomb-Rice parameter derivation for TSRC is used. Version 1  profiles require this to be false and some Version 2 (RExt) profiles may require this to be true.
+\\
+
 \Option{HighPrecisionPredictionWeighting} &
 \Default{false} &
 Specifies the value of high_precision_prediction_weighting_flag. This setting is only valid for the 16-bit or 4:4:4 RExt profiles.
@@ -3328,11 +3487,21 @@ When true, specifies the use of the residual rotation tool. Version 1 and some V
 When true, specifies the use of a single significance map context for transform-skipped and transquant-bypassed TUs. Version 1 and some Version 2 (RExt) profiles require this to be false.
 \\
 
+\Option{ExtendedRiceRRC} &
+\Default{false} &
+When true, specifies the that extension of the Golomb-Rice parameter derivation for RRC is used. Version 1  profiles require this to be false and some Version 2 (RExt) profiles may require this to be true.
+\\
+
 \Option{GolombRiceParameterAdaptation} &
 \Default{false} &
 When true, enable the adaptation of the Golomb-Rice parameter over the course of each slice. Version 1 and some Version 2 (RExt) profiles require this to be false.
 \\
 
+\Option{ReverseLastSigCoeff} &
+\Default{false} &
+When true, enable reverse last significant coefficient postion in RRC. Version 1 and some Version 2 (RExt) profiles require this to be false.
+\\
+
 \Option{AlignCABACBeforeBypass} &
 \Default{false} &
 When true, align the CABAC engine to a defined fraction of a bit prior to coding bypass data (including sign bits) when coeff_abs_level_remaining syntax elements are present in the group.
@@ -3381,7 +3550,7 @@ The table below lists the SEI messages defined for Version 1 and Range-Extension
   139 & Temporal motion-constrained tile sets    & Table \ref{tab:sei-tmcts} \\
   140 & Chroma resampling filter hint            & Table \ref{tab:chroma-resampling-filter-hint} \\
   141 & Knee function information                & Table \ref{tab:sei-knee-function} \\
-  142 & Colour remapping information             & Table \ref{tab:sei-colour-remapping}\\
+  142 & Colour transform information             & Table \ref{tab:sei-colour-transform}\\
   143 & Deinterlaced field identification        & (Not handled)\\
   144 & Content light level info                 & Table \ref{tab:sei-content-light-level}\\
   147 & Alternative transfer characteristics     & Table \ref{tab:sei-alternative-transfer-characteristics}\\
@@ -3392,9 +3561,16 @@ 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} \\  
+  165 & Alpha Channel Information                & Table \ref{tab:sei-aci} \\
   168 & Frame-field information                  & Table \ref{tab:sei-frame-field} \\  
+  177 & Depth Representation Information         & Table \ref{tab:sei-dri} \\
+  179 & Multiview Acquisition Information        & Table \ref{tab:sei-mai} \\
+  180 & Multiview View Position                  & Table \ref{tab:sei-mvp} \\
+  202 & Annotated regions information            & Table \ref{tab:sei-annotated-regions} \\  
   203 & Subpicture Level Information             & Table \ref{tab:sei-subpic-level} \\  
   204 & Sample Aspect Ratio Information          & Table \ref{tab:sei-sari} \\  
+  205 & Scalability Dimension Information        & Table \ref{tab:sei-sdi} \\
+  207 & Constrained RASL encoding                & Table \ref{tab:sei-constrained-rasl-encoding} \\
 \end{SEIListTable}
 %%
 %% SEI messages
@@ -3705,17 +3881,21 @@ disabled.
 
 
 \begin{OptionTableNoShorthand}{Display orientation SEI message encoder parameters}{tab:sei-display-orientation}
-\Option{SEIDisplayOrientation} &
+\Option{SEIDisplayOrientationEnabled} &
+\Default{false} &
+Enables (true) or disables (false) the insertion of the Display orientation SEI messages.
+\\
+\Option{SEIDisplayOrientationCancelFlag} &
+\Default{true} &
+Indicates that display orientation SEI message cancels the persistence (true) or follows (false).
+\\
+\Option{SEIDisplayOrientationPersistenceFlag} &
+\Default{false} &
+Specifies the persistence of the display orientation SEI message.
+\\
+\Option{SEIDisplayOrientationTransformType} &
 \Default{0} &
-Enables or disables the insertion of the Display orientation
-SEI messages.
-\par
-\begin{tabular}{cp{0.20\textwidth}}
-  0 & Disabled \\
-  N: $0 < N < (2^{16} - 1)$ & Enable display orientation SEI message with 
-  \mbox{anticlockwise_rotation = N} 
-  and \mbox{display_orientation_repetition_period = 1} \\
-\end{tabular}
+Specifies the rotation and mirroring to be applied to the picture.
 \\
 \end{OptionTableNoShorthand}
 
@@ -4057,12 +4237,63 @@ Array of output knee point. Default table can be set to the following:
 \end{OptionTableNoShorthand}
 
 
-\begin{OptionTableNoShorthand}{Colour remapping SEI message encoder parameters}{tab:sei-colour-remapping}
-\Option{SEIColourRemappingInfoFileRoot (-cri)} &
-\Default{\NotSet} &
-Specifies the prefix of input Colour Remapping Information file. Prefix is completed by ``_x.txt'' where x is the  POC number.
-The contents of the file are a list of the SEI message's syntax element names (in decoding order) immediately followed by a `:' and then the associated value.
-An example file can be found in cfg/misc/example_colour_remapping_sei_encoder_0.txt.
+\begin{OptionTableNoShorthand}{Colour transform information SEI message encoder parameters}{tab:sei-colour-transform}
+\Option{SEICTIEnabled} &
+\Default{false} &
+Enables (true) or disables (false) the insertion of colour transform information (CTI) SEI message.
+Examples configuration files for CTI can be found in folder cfg/examples_SEI_CTI.
+\\
+\Option{SEICTIId} &
+\Default{0} &
+Specifies the ID of the CTI SEI message.
+\\
+\Option{SEICTISignalInfoFlag} &
+\Default{false} &
+Enables (true) or disables (false) the insertion of output signal information after applying the colour transform.
+\\
+\Option{SEICTIFullRangeFlag} &
+\Default{false} &
+Specifies the range (true:full, false:limited) of the output signal after applying the colour transform.
+\\
+\Option{SEICTIPrimaries} &
+\Default{0} &
+Specifies the colour primaries of the output signal after applying the colour transform.
+\\
+\Option{SEICTITransferFunction} &
+\Default{0} &
+Specifies the transfer function (characteristics) of the output signal after applying the colour transform.
+\\
+\Option{SEICTIMatrixCoefs} &
+\Default{0} &
+Specifies the matrix coefficients type of the output signal after applying the colour transform.
+\\
+\Option{SEICTICrossCompFlag} &
+\Default{true} &
+Enables (true) or disables (false) the cross-component scaling for applying the colour transform.
+\\
+\Option{SEICTICrossCompInferred} &
+\Default{true} &
+Infers (true) or signals (false) the cross-component scaling tables for the colour transform.
+\\
+\Option{SEICTINbChromaLut} &
+\Default{0} &
+Specifies the number of chroma tables (1 or 2) for the colour transform (only used when SEICTICrossCompInferred = false).
+\\
+\Option{SEICTILut0} &
+\Default{0} &
+Specifies the transform table for colour component 0.
+\\
+\Option{SEICTILut1} &
+\Default{0} &
+Specifies the transform table for colour component 1 (only used when SEICTICrossCompFlag = false).
+\\
+\Option{SEICTILut2} &
+\Default{0} &
+Specifies the transform table for colour component 2 (only used when SEICTINbChromaLut = 2).
+\\
+\Option{SEICTIChromaOffset} &
+\Default{0} &
+Specifies the offset to be added to the values of the cross-component scaling tables (only used when SEICTICrossCompInferred = false).
 \\
 \end{OptionTableNoShorthand}
 
@@ -4402,6 +4633,257 @@ Specifies the vertical size of the sample aspect ratio, if SEISARIAspectRatioIdc
 \\
 \end{OptionTableNoShorthand}
 
+\begin{OptionTableNoShorthand}{Scalability Dimension Information SEI message encoder parameters}{tab:sei-sdi}
+\Option{SEISDIEnabled} &
+\Default{false} &
+Enables (true) or disables (false) the insertion of Scalability Dimension Information SEI message.
+\\
+\Option{SEISDIMaxLayersMinus1} &
+\Default{0} &
+Specifies the maximum number of layers minus 1 in the current CVS.
+\\
+\Option{SEISDIMultiviewInfoFlag} &
+\Default{false} &
+Specifies the current CVS may have multiple views and the sdi_view_id_val[ ] syntax elements are present in the scalaibility dimension information SEI message.
+\\
+\Option{SEISDIAuxiliaryInfoFlag} &
+\Default{false} &
+Specifies that one or more layers in the current CVS may be auxiliary layers, which carry auxiliary information, and the sdi_aux_id[ ] syntax elements are present in the scalaibility dimension information SEI message.
+\\
+\Option{SEISDIViewIdLenMinus1} &
+\Default{0} &
+Specifies the length, in bits, of the sdi_view_id_val[ i ] syntax element minus 1 in the scalaibility dimension information SEI message.
+\\
+\Option{SEISDILayerId} &
+\Default{""} &
+List of the layer identifiers that may be present in the scalaibility dimension information SEI message in the current CVS.
+\\
+\Option{SEISDIViewIdVal} &
+\Default{""} &
+List of the view identifiers in the scalaibility dimension information SEI message.
+\\
+\Option{SEISDIAuxId} &
+\Default{""} &
+List of the auxiliary identifiers in the scalaibility dimension information SEI message.
+\\
+\Option{SEISDINumAssociatedPrimaryLayersMinus1} &
+\Default{""} &
+List of the numbers of associated primary layers of i-th layer, which is an auxiliary layer.
+\\
+\end{OptionTableNoShorthand}
+
+\begin{OptionTableNoShorthand}{Alpha Channel Information SEI message encoder parameters}{tab:sei-aci}
+\Option{SEIACIEnabled} &
+\Default{false} &
+Enables (true) or disables (false) the insertion of Alpha Channel Information SEI message.
+\\
+\Option{SEIACICancelFlag} &
+\Default{false} &
+Specifies the persistence of any previous alpha channel information SEI message in output order.
+\\
+\Option{SEIACIUseIdc} &
+\Default{0} &
+Specifies the usage of the auxiliary picture in the alpha channel information SEI message.
+\\
+\Option{SEIACIBitDepthMinus8} &
+\Default{0} &
+Specifies the bit depth of the samples of the auxiliary picture in the alpha channel information SEI message.
+\\
+\Option{SEIACITransparentValue} &
+\Default{0} &
+Specifies the interpretation sample value of an auxiliary coded picture luma sample for which the associated luma and chroma samples of the primary coded picture are considered transparent for purposes of alpha blending in the alpha channel information SEI message.
+\\
+\Option{SEIACIOpaqueValue} &
+\Default{0} &
+Specifies the interpretation sample value of an auxiliary coded picture luma sample for which the associated luma and chroma samples of the primary coded picture are considered opaque for purposes of alpha blending in the alpha channel information SEI message.
+\\
+\Option{SEIACIIncrFlag} &
+\Default{false} &
+Specifies the interpretation sample value for each decoded auxiliary picture luma sample value is equal to the decoded auxiliary picture sample value for purposes of alpha blending in the alpha channel information SEI message.
+\\
+\Option{SEIACIClipFlag} &
+\Default{false} &
+Specifies whether clipping operation is applied in the alpha channel information SEI message.
+\\
+\Option{SEIACIClipTypeFlag} &
+\Default{false} &
+Specifies the type of clipping operation in the alpha channel information SEI message.
+\\
+\end{OptionTableNoShorthand}
+
+\begin{OptionTableNoShorthand}{Depth Representation Information SEI message encoder parameters}{tab:sei-dri}
+\Option{SEIDRIEnabled} &
+\Default{false} &
+Enables (true) or disables (false) the insertion of Depth Representation Information SEI message.
+\\
+\Option{SEIDRIZNearFlag} &
+\Default{false} &
+Specifies the presence of the nearest depth value in the depth representation information SEI message.
+\\
+\Option{SEIDRIZFarFlag} &
+\Default{false} &
+Specifies the presence of the farthest depth value in the depth representation information SEI message.
+\\
+\Option{SEIDRIDMinFlag} &
+\Default{false} &
+Specifies the presence of the minimum disparity value in the depth representation information SEI message.
+\\
+\Option{SEIDRIDMaxFlag} &
+\Default{false} &
+Specifies the presence of the maximum disparity value in the depth representation information SEI message.
+\\
+\Option{SEIDRIZNear} &
+\Default{0.0} &
+Specifies the nearest depth value in the depth representation information SEI message.
+\\
+\Option{SEIDRIZFar} &
+\Default{0.0} &
+Specifies the farest depth value in the depth representation information SEI message.
+\\
+\Option{SEIDRIDMin} &
+\Default{0.0} &
+Specifies the minimum disparity value in the depth representation information SEI message.
+\\
+\Option{SEIDRIDMax} &
+\Default{0.0} &
+Specifies the maximum disparity value in the depth representation information SEI message.
+\\
+\Option{SEIDRIDepthRepresentationType} &
+\Default{0} &
+Specifies the the representation definition of decoded luma samples of auxiliary pictures in the depth representation information SEI message.
+\\
+\Option{SEIDRIDisparityRefViewId} &
+\Default{0} &
+Specifies the ViewId value against which the disparity values are derived in the depth representation information SEI message.
+\\
+\Option{SEIDRINonlinearNumMinus1} &
+\Default{0} &
+Specifies the number of piece-wise linear segments minus 2 for mapping of depth values to a scale that is uniformly quantized in terms of disparity  in the depth representation information SEI message.
+\\
+\Option{SEIDRINonlinearModel} &
+\Default{""} &
+List of the piece-wise linear segments for mapping of decoded luma sample values of an auxiliary picture to a scale that is uniformly quantized in terms of disparity in the depth representation information SEI message.
+\\
+\end{OptionTableNoShorthand}
+
+\begin{OptionTableNoShorthand}{Multiview Acquisition Information SEI message encoder parameters}{tab:sei-mai}
+\Option{SEIMAIEnabled} &
+\Default{false} &
+Enables (true) or disables (false) the insertion of Multiview Acquisition Information SEI message.
+\\
+\Option{SEIMAIIntrinsicParamFlag} &
+\Default{false} &
+Specifies the presence of intrinsic camera parameters in the multiview acquisition information SEI message.
+\\
+\Option{SEIMAIExtrinsicParamFlag} &
+\Default{false} &
+Specifies the presence of extrinsic camera parameters in the multiview acquisition information SEI message.
+\\
+\Option{SEIMAINumViewsMinus1} &
+\Default{0} &
+Specifies the number of views minus 1 in the multiview acquisition information SEI message.
+\\
+\Option{SEIMAIIntrinsicParamsEqualFlag} &
+\Default{false} &
+Specifies the intrinsic camera parameters are equal for all cameras in the multiview acquisition information SEI message.
+\\
+\Option{SEIMAIPrecFocalLength} &
+\Default{0} &
+Specifies the exponent of the maximum allowable truncation error for focal_length_x[i] and focal_length_y[i] in the multiview acquisition information SEI message.
+\\
+\Option{SEIMAIPrecPrincipalPoint} &
+\Default{0} &
+Specifies the exponent of the maximum allowable truncation error for principal_point_x[i] and principal_point_y[i] in the multiview acquisition information SEI message.
+\\
+\Option{SEIMAIPrecSkewFactor} &
+\Default{0} &
+Specifies the exponent of the maximum allowable truncation error for skew factor in the multiview acquisition information SEI message.
+\\
+\Option{SEIMAISignFocalLengthX} &
+\Default{""} &
+List of the signs of the focal length of the camera in the horizontal direction in the multiview acquisition information SEI message.
+\\
+\Option{SEIMAIExponentFocalLengthX} &
+\Default{""} &
+List of the exponent parts of the focal length of the camera in the horizontal direction. in the multiview acquisition information SEI message.
+\\
+\Option{SEIMAIMantissaFocalLengthX} &
+\Default{""} &
+List of the mantissa parts of the focal length of the camera in the horizontal direction in the multiview acquisition information SEI message.
+\\
+\Option{SEIMAISignFocalLengthY} &
+\Default{""} &
+List of the signs of the focal length of the camera in the vertical direction in the multiview acquisition information SEI message.
+\\
+\Option{SEIMAIExponentFocalLengthY} &
+\Default{""} &
+List of the exponent parts of the focal length of the camera in the vertical direction in the multiview acquisition information SEI message.
+\\
+\Option{SEIMAIMantissaFocalLengthY} &
+\Default{""} &
+List of the mantissa parts of the focal length of the camera in the vertical direction in the multiview acquisition information SEI message.
+\\
+\Option{SEIMAISignPrincipalPointX} &
+\Default{""} &
+List of the signs of the principal point of the camera in the horizontal direction in the multiview acquisition information SEI message.
+\\
+\Option{SEIMAIExponentPrincipalPointX} &
+\Default{""} &
+List of the exponent parts of the principal point of the camera in the horizontal direction in the multiview acquisition information SEI message.
+\\
+\Option{SEIMAIMantissaPrincipalPointX} &
+\Default{""} &
+List of the mantissa parts of the principal point of the camera in the horizontal direction in the multiview acquisition information SEI message.
+\\
+\Option{SEIMAISignPrincipalPointY} &
+\Default{""} &
+List of the signs of the principal point of the camera in the vertical direction in the multiview acquisition information SEI message.
+\\
+\Option{SEIMAIExponentPrincipalPointY} &
+\Default{""} &
+List of the exponent parts of the principal point of the camera in the vertical direction in the multiview acquisition information SEI message.
+\\
+\Option{SEIMAIMantissaPrincipalPointY} &
+\Default{""} &
+List of the mantissa parts of the principal point of the camera in the vertical direction in the multiview acquisition information SEI message.
+\\
+\Option{SEIMAISignSkewFactor} &
+\Default{""} &
+List of the signs of the skew factor of the camera in the multiview acquisition information SEI message.
+\\
+\Option{SEIMAIExponentSkewFactor} &
+\Default{""} &
+List of the exponent parts of the skew factor of the camera in the multiview acquisition information SEI message.
+\\
+\Option{SEIMAIMantissaSkewFactor} &
+\Default{""} &
+List of the mantissa parts of the skew factor of the camera in the multiview acquisition information SEI message.
+\\
+\Option{SEIMAIPrecRotationParam} &
+\Default{0} &
+Specifies the exponent of the maximum allowable truncation error for rotation in the multiview acquisition information SEI message.
+\\
+\Option{SEIMAIPrecTranslationParam} &
+\Default{0} &
+Specifies the exponent of the maximum allowable truncation error for translation in the multiview acquisition information SEI message.
+\\
+\end{OptionTableNoShorthand}
+
+\begin{OptionTableNoShorthand}{Multiview View Position SEI message encoder parameters}{tab:sei-mvp}
+\Option{SEIMVPEnabled} &
+\Default{false} &
+Enables (true) or disables (false) the insertion of Multiview View Position SEI message.
+\\
+\Option{SEIMVPNumViewsMinus1} &
+\Default{0} &
+Specifies the number of views minus 1 in the multiview view position SEI message.
+\\
+\Option{SEIMVPViewPosition} &
+\Default{""} &
+List of the view position in the multiview view position SEI message.
+\\
+\end{OptionTableNoShorthand}
+
 \begin{OptionTableNoShorthand}{Frame-Field Information SEI message encoder parameters}{tab:sei-frame-field}
 \Option{SEIFrameFieldInfo} &
 \Default{false} &
@@ -4409,6 +4891,15 @@ Enables (true) or disables (false) the insertion of Frame-Field Information SEI
 \\
 \end{OptionTableNoShorthand}
 
+\begin{OptionTableNoShorthand}{Annotated Regions SEI message encoder parameters}{tab:sei-annotated-regions}
+\Option{SEIAnnotatedRegionsFileRoot (-cri)} &
+\Default{\NotSet} &
+Specifies the prefix of input Annotated Regions file. Prefix is completed by ``_x.txt'' where x is the  POC number.
+The contents of the file are a list of the SEI message's syntax element names (in decoding order) immediately followed by a `:' and then the associated value.
+An example file can be found in cfg/sei_vui/annotated_regions/anno_reg_0.txt.
+\\
+\end{OptionTableNoShorthand}
+
 \begin{OptionTableNoShorthand}{Subpicture Level Information SEI message encoder parameters}{tab:sei-subpic-level}
 \Option{SEISubpictLevelInfoEnabled} &
 \Default{false} &
@@ -4439,7 +4930,7 @@ Enable signalling of level information for each sublayer
 \\
 \Option{SEISubpicLevelInfoNonSubpicLayersFractions} &
 \Default{""} &
-List of fraction of levels to be signalled for non-subpicture layers.
+List of fractions of levels to be signalled for non-subpicture layers. Each value in the list shall be in the range 0 to 255.
 \par
 \begin{tabular}{p{0.49\columnwidth}}
 When sli_sublayer_info_present_flag = 0, the number of input elements shall be equal to numReflevels. List is ordered by level.\\
@@ -4457,7 +4948,7 @@ When sli_sublayer_info_present_flag = 1, the number of input elements shall be e
 \\
 \Option{SEISubpicLevelInfoRefLevelFractions} &
 \Default{""} &
-List of fractions of levels to be signalled.
+List of fractions of levels to be signalled. Each value in the list shall be in the range 0 to 255.
 \par
 \begin{tabular}{p{0.49\columnwidth}}
 When sli_sublayer_info_present_flag = 0, the number of input elements shall be equal to numSubpics * numReflevels. List is ordered by subpicture then level.\\
@@ -4582,6 +5073,13 @@ specifies the CCV avg luminance value in the content colour volume SEI message.
 \end{OptionTableNoShorthand}
 
 
+\begin{OptionTableNoShorthand}{Constrained RASL encoding for bitstream switching}{tab:sei-constrained-rasl-encoding}
+\Option{SEIConstrainedRASL} &
+\Default{false} &
+When true (non-zero), the SEI enables several restrictions for encoding RASL frames: CCLM estimation is skipped in intra search, TMVP is disabled and PH syntax ph_dmvr_disabled_flag is set to 1.
+\\
+\end{OptionTableNoShorthand}
+
 
 
 %\Option{SEITimeCode} &
@@ -4774,13 +5272,20 @@ has the following behaviour:
 When a non-empty file name is specified, information regarding any decoded SEI messages will be output to the indicated file. If the file name is '-', then stdout is used instead.
 \\
 
-\Option{SEIColourRemappingInfoFilename} &
+\Option{SEICTIFilename} &
 %\ShortOption{\None} &
 \Default{\NotSet} &
-Specifies that the colour remapping SEI message should be applied to the output video, with the output written to this file.
+Specifies that the colour transform information (CTI) SEI message should be applied to the output video, with the output written to this file.
 If no value is specified, the SEI message is ignored and no mapping is applied.
 \\
 
+\Option{SEIAnnotatedRegionsInfoFilename} &
+%\ShortOption{\None} &
+\Default{\NotSet} &
+When a non-empty file name is specified, object information using the decoded SEI messages will be output to the indicated file.
+If no value is specified, the SEI message will not be output.
+\\
+
 \Option{OutputColourSpaceConvert} &
 \Default{\NotSet} &
 Specifies the colour space conversion to apply to 444 video. Permitted values are:
@@ -5047,10 +5552,19 @@ DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_ALL,
 \label{sec:stream-merge-tool}
 
 The StreamMergeApp tool takes multiple single-layer (singe nuh_layer_id) bistreams 
-as inputs and merge them into a multi-layer bistream by interleaving the NALUs 
+as inputs and merge them into a multi-layer bistream by interleaving the Picture Units
 from the input single layer bistreams. During the merge, the tool assigns a new unique
-nuh_layer_id for each input bitstream. Then the decoder could specify which layer 
-bitstream to be decoded through the command line option "-p nuh_layer_id". 
+nuh_layer_id for each input bitstream as well as unique parameter sets identifiers for each layer.
+Then the decoder can specify which layer bitstream to be decoded through the command line option "-p nuh_layer_id".
+
+Some current limitations of the tool:
+\begin{itemize}
+\item All input bitstreams are single layer and thus all layers in the output bitstream are independent layers.
+\item Each layer in the output bitstream is abitrarily put in an individual OLS and is also an output layer.
+\item All parameter sets from the input bitstreams are treated as different parameter sets. There is thus no parameters sets sharing in the output bitstream.
+\item The slice header in the input bitstreams shall contain no picture header structure and no alf information.
+\end{itemize}
+
 
 \subsection{Usage}
 \label{sec:stream-merge-usage}
diff --git a/source/App/BitstreamExtractorApp/BitstreamExtractorApp.cpp b/source/App/BitstreamExtractorApp/BitstreamExtractorApp.cpp
index 15009db24..b4bd86f8a 100644
--- a/source/App/BitstreamExtractorApp/BitstreamExtractorApp.cpp
+++ b/source/App/BitstreamExtractorApp/BitstreamExtractorApp.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -116,7 +116,7 @@ Slice BitstreamExtractorApp::xParseSliceHeader(InputNALUnit &nalu)
   slice.setTLayer(nalu.m_temporalId);
 
   m_hlSynaxReader.parseSliceHeader(&slice, &m_picHeader, &m_parameterSetManager, m_prevTid0Poc, m_prevPicPOC);
-  
+
   return slice;
 }
 
@@ -172,6 +172,30 @@ bool BitstreamExtractorApp::xCheckSliceSubpicture(InputNALUnit &nalu, int target
 }
 #endif
 
+#if JVET_S0154_ASPECT9_AND_S0158_ASPECT4
+bool BitstreamExtractorApp::xCheckSEIFiller(SEIMessages SEIs, int targetSubPicId, bool &rmAllFillerInSubpicExt, bool lastSliceWritten)
+{
+  for (auto sei : SEIs)
+  {
+    if (sei->payloadType() == SEI::SUBPICTURE_LEVEL_INFO)
+    {
+      SEISubpicureLevelInfo *seiSLI = (SEISubpicureLevelInfo *)sei;
+      if (!seiSLI->m_cbrConstraintFlag)
+      {
+        rmAllFillerInSubpicExt = true;
+      }
+    }
+  }
+  for (auto sei : SEIs)
+  {
+    if (sei->payloadType() == SEI::FILLER_PAYLOAD)
+    {
+      return (rmAllFillerInSubpicExt ? false : lastSliceWritten);
+    }
+  }
+  return true;
+}
+#else
 bool BitstreamExtractorApp::xCheckSeiSubpicture(SEIMessages SEIs, int targetSubPicId, bool &rmAllFillerInSubpicExt, bool lastSliceWritten, bool isVclNalUnitRemoved)
 {
   bool isWriteSeiNalUnitToStream = true;
@@ -242,6 +266,7 @@ bool BitstreamExtractorApp::xCheckSeiSubpicture(SEIMessages SEIs, int targetSubP
 
   return isWriteSeiNalUnitToStream;
 }
+#endif
 
 void BitstreamExtractorApp::xRewriteSPS (SPS &targetSPS, const SPS &sourceSPS, SubPic &subPic)
 {
@@ -267,6 +292,47 @@ void BitstreamExtractorApp::xRewriteSPS (SPS &targetSPS, const SPS &sourceSPS, S
   conf.setWindowRightOffset(subpicConfWinRightOffset);
   conf.setWindowTopOffset(subpicConfWinTopOffset);
   conf.setWindowBottomOffset(subpicConfWinBottomOffset);
+
+#if JVET_S0117_VB  // Virtual boundaries rewriting
+  if (sourceSPS.getVirtualBoundariesEnabledFlag() && sourceSPS.getVirtualBoundariesPresentFlag())
+  { 
+    targetSPS.setNumVerVirtualBoundaries(0);
+    for (int i = 0; i < sourceSPS.getNumVerVirtualBoundaries() ; i ++)
+    {
+      int subPicLeftX = subPic.getSubPicCtuTopLeftX() * sourceSPS.getCTUSize();
+      int subPicRightX = (subPic.getSubPicCtuTopLeftX() + subPic.getSubPicWidthInCTUs()) * sourceSPS.getCTUSize();
+      if (subPicRightX > sourceSPS.getMaxPicWidthInLumaSamples())
+      {
+        subPicRightX = sourceSPS.getMaxPicWidthInLumaSamples();
+      }
+      if ( sourceSPS.getVirtualBoundariesPosX(i) > subPicLeftX && sourceSPS.getVirtualBoundariesPosX(i) < subPicRightX)
+      {
+        targetSPS.setVirtualBoundariesPosX(targetSPS.getNumVerVirtualBoundaries(), sourceSPS.getVirtualBoundariesPosX(i) - subPicLeftX);
+        targetSPS.setNumVerVirtualBoundaries(targetSPS.getNumVerVirtualBoundaries() + 1);
+      }
+    }
+
+    targetSPS.setNumHorVirtualBoundaries(0);
+    for (int i = 0; i < sourceSPS.getNumHorVirtualBoundaries(); i++)
+    {
+      int subPicTopY = subPic.getSubPicCtuTopLeftY() * sourceSPS.getCTUSize();
+      int subPicBottomY = (subPic.getSubPicCtuTopLeftY() + subPic.getSubPicHeightInCTUs()) * sourceSPS.getCTUSize();
+      if (subPicBottomY > sourceSPS.getMaxPicHeightInLumaSamples())
+      {
+        subPicBottomY = sourceSPS.getMaxPicHeightInLumaSamples();
+      }
+      if (sourceSPS.getVirtualBoundariesPosY(i) > subPicTopY && sourceSPS.getVirtualBoundariesPosY(i) < subPicBottomY)
+      {
+        targetSPS.setVirtualBoundariesPosY(targetSPS.getNumHorVirtualBoundaries(), sourceSPS.getVirtualBoundariesPosY(i) - subPicTopY);
+        targetSPS.setNumHorVirtualBoundaries(targetSPS.getNumHorVirtualBoundaries() + 1);
+      }
+    }
+    if (targetSPS.getNumVerVirtualBoundaries() == 0 && targetSPS.getNumHorVirtualBoundaries() == 0)
+    {
+      targetSPS.setVirtualBoundariesEnabledFlag(0);
+    }
+  }
+#endif
 }
 
 void BitstreamExtractorApp::xRewritePPS(PPS &targetPPS, const PPS &sourcePPS, const SPS &sourceSPS, SubPic &subPic)
@@ -282,7 +348,7 @@ void BitstreamExtractorApp::xRewritePPS(PPS &targetPPS, const PPS &sourcePPS, co
   // picture size
   targetPPS.setPicWidthInLumaSamples(subPic.getSubPicWidthInLumaSample());
   targetPPS.setPicHeightInLumaSamples(subPic.getSubPicHeightInLumaSample());
-  // todo: Conformance window
+  // todo: Conformance window (conf window rewriting is not needed per JVET-S0117)
 
   int subWidthC = SPS::getWinUnitX(sourceSPS.getChromaFormatIdc());
   int subHeightC = SPS::getWinUnitY(sourceSPS.getChromaFormatIdc());
@@ -479,7 +545,11 @@ bool BitstreamExtractorApp::xCheckNumSubLayers(InputNALUnit &nalu, VPS *vps)
   return retval;
 }
 
+#if JVET_S0154_ASPECT9_AND_S0158_ASPECT4
+bool BitstreamExtractorApp::xCheckSEIsSubPicture(SEIMessages& SEIs, InputNALUnit& nalu, std::ostream& out, int subpicId, VPS *vps)
+#else
 bool BitstreamExtractorApp::xCheckSEIsSubPicture(SEIMessages& SEIs, InputNALUnit& nalu, std::ostream& out, int subpicId)
+#endif
 {
   SEIMessages scalableNestingSEIs = getSeisByType(SEIs, SEI::SCALABLE_NESTING);
   if (scalableNestingSEIs.size())
@@ -496,12 +566,20 @@ bool BitstreamExtractorApp::xCheckSEIsSubPicture(SEIMessages& SEIs, InputNALUnit
     }
     if (std::find(sei->m_snSubpicId.begin(), sei->m_snSubpicId.end(), subpicId) != sei->m_snSubpicId.end())
     {
-      // applies to target subpicture -> extract
-      OutputNALUnit outNalu( nalu.m_nalUnitType, nalu.m_nuhLayerId, nalu.m_temporalId );
-      m_seiWriter.writeSEImessages(outNalu.m_Bitstream, sei->m_nestedSEIs, m_hrd, false, nalu.m_temporalId);
-      NALUnitEBSP naluWithHeader(outNalu);
-      writeAnnexBNalUnit(out, naluWithHeader, true);
-      return false;
+#if JVET_S0154_ASPECT9_AND_S0158_ASPECT4
+      // C.7 step 7.c
+      if (sei->m_snOlsFlag || vps->getNumLayersInOls(m_targetOlsIdx) == 1)
+      {
+#endif
+        // applies to target subpicture -> extract
+        OutputNALUnit outNalu( nalu.m_nalUnitType, nalu.m_nuhLayerId, nalu.m_temporalId );
+        m_seiWriter.writeSEImessages(outNalu.m_Bitstream, sei->m_nestedSEIs, m_hrd, false, nalu.m_temporalId);
+        NALUnitEBSP naluWithHeader(outNalu);
+        writeAnnexBNalUnit(out, naluWithHeader, true);
+        return false;
+#if JVET_S0154_ASPECT9_AND_S0158_ASPECT4
+      }
+#endif
     }
     else
     {
@@ -554,6 +632,86 @@ bool BitstreamExtractorApp::xCheckScalableNestingSEI(SEIScalableNesting *seiNest
   return nestingAppliedInTargetOlsLayerId;
 }
 
+#if JVET_S0154_ASPECT9_AND_S0158_ASPECT4
+bool BitstreamExtractorApp::xIsTargetOlsIncludeAllVclLayers()
+{
+  std::ifstream bitstreamFileIn(m_bitstreamFileNameIn.c_str(), std::ifstream::in | std::ifstream::binary);
+  if (!bitstreamFileIn)
+  {
+    EXIT("failed to open bitstream file " << m_bitstreamFileNameIn.c_str() << " for reading");
+  }
+
+  InputByteStream bytestream(bitstreamFileIn);
+
+  bitstreamFileIn.clear();
+  bitstreamFileIn.seekg(0, std::ios::beg);
+
+  if (m_targetOlsIdx >= 0)
+  {
+    std::vector<int> layerIdInTargetOls;
+    std::vector<int> layerIdInVclNalu;
+    while (!!bitstreamFileIn)
+    {
+      AnnexBStats stats = AnnexBStats();
+      InputNALUnit nalu;
+      byteStreamNALUnit(bytestream, nalu.getBitstream().getFifo(), stats);
+
+      // call actual decoding function
+      if (nalu.getBitstream().getFifo().empty())
+      {
+        msg(WARNING, "Warning: Attempt to decode an empty NAL unit");
+      }
+      else
+      {
+        read(nalu);
+
+        if (nalu.m_nalUnitType == NAL_UNIT_VPS)
+        {
+          VPS* vps = new VPS();
+          m_hlSynaxReader.setBitstream(&nalu.getBitstream());
+          m_hlSynaxReader.parseVPS(vps);
+          int vpsId = vps->getVPSId();
+          // note: storeVPS may invalidate the vps pointer!
+          m_parameterSetManager.storeVPS(vps, nalu.getBitstream().getFifo());
+          // get VPS back
+          vps = m_parameterSetManager.getVPS(vpsId);
+          m_vpsId = vps->getVPSId();
+        }
+
+        VPS *vps = nullptr;
+        if (m_vpsId > 0)
+        {
+          vps = m_parameterSetManager.getVPS(m_vpsId);
+          layerIdInTargetOls = vps->getLayerIdsInOls(m_targetOlsIdx);
+          if (NALUnit::isVclNalUnitType(nalu.m_nalUnitType))
+          {
+            if (layerIdInVclNalu.size() == 0 || nalu.m_nuhLayerId >= layerIdInVclNalu[layerIdInVclNalu.size() - 1])
+            {
+              layerIdInVclNalu.push_back(nalu.m_nuhLayerId);
+            }
+            else
+            {
+              break;
+            }
+          }
+        }
+      }
+    }
+
+    //When LayerIdInOls[ targetOlsIdx ] does not include all values of nuh_layer_id in all VCL NAL units in the bitstream inBitstream
+    for (int i = 0; i < layerIdInVclNalu.size(); i++)
+    {
+      bool vclLayerIncludedInTargetOls = std::find(layerIdInTargetOls.begin(), layerIdInTargetOls.end(), layerIdInVclNalu[i]) != layerIdInTargetOls.end();
+      if (!vclLayerIncludedInTargetOls)
+      {
+        return false;
+      }
+    }
+  }
+  return true;
+}
+#endif
+
 uint32_t BitstreamExtractorApp::decode()
 {
   std::ifstream bitstreamFileIn(m_bitstreamFileNameIn.c_str(), std::ifstream::in | std::ifstream::binary);
@@ -585,6 +743,10 @@ uint32_t BitstreamExtractorApp::decode()
   bool isMultiSubpicLayer[MAX_VPS_LAYERS] = { false };
   bool rmAllFillerInSubpicExt[MAX_VPS_LAYERS] = { false };
 
+#if JVET_S0154_ASPECT9_AND_S0158_ASPECT4
+  bool targetOlsIncludeAllVclLayers = xIsTargetOlsIncludeAllVclLayers();
+#endif
+
   while (!!bitstreamFileIn)
   {
     AnnexBStats stats = AnnexBStats();
@@ -643,11 +805,7 @@ uint32_t BitstreamExtractorApp::decode()
         }
         // Remove NAL units with nal_unit_type not equal to any of VPS_NUT, DPS_NUT, and EOB_NUT and with nuh_layer_id not included in the list LayerIdInOls[targetOlsIdx].
         NalUnitType t = nalu.m_nalUnitType;
-#if JVET_S0163_ON_TARGETOLS_SUBLAYERS
         bool isSpecialNalTypes = t == NAL_UNIT_OPI || t == NAL_UNIT_VPS || t == NAL_UNIT_DCI || t == NAL_UNIT_EOB;
-#else
-        bool isSpecialNalTypes = t == NAL_UNIT_VPS || t == NAL_UNIT_DCI || t == NAL_UNIT_EOB;
-#endif
         vps = m_parameterSetManager.getVPS(m_vpsId);
         if (m_vpsId == 0)
         {
@@ -816,27 +974,55 @@ uint32_t BitstreamExtractorApp::decode()
               {
                 writeInpuNalUnitToStream &= xCheckScalableNestingSEI(seiNesting, nalu, vps);
               }
+#if JVET_S0154_ASPECT9_AND_S0158_ASPECT4
+              // C.6 step 9.c
+              if (writeInpuNalUnitToStream && !targetOlsIncludeAllVclLayers && !seiNesting->m_snSubpicFlag)
+              {
+                if (seiNesting->m_snOlsFlag || vps->getNumLayersInOls(m_targetOlsIdx) == 1)
+                {
+                  OutputNALUnit outNalu(nalu.m_nalUnitType, nalu.m_nuhLayerId, nalu.m_temporalId);
+                  m_seiWriter.writeSEImessages(outNalu.m_Bitstream, seiNesting->m_nestedSEIs, m_hrd, false, nalu.m_temporalId);
+                  NALUnitEBSP naluWithHeader(outNalu);
+                  writeAnnexBNalUnit(bitstreamFileOut, naluWithHeader, true);
+                  writeInpuNalUnitToStream = false;
+                }
+              }
+#endif
             }
             // remove unqualified timing related SEI
             if (sei->payloadType() == SEI::BUFFERING_PERIOD || (m_removeTimingSEI && sei->payloadType() == SEI::PICTURE_TIMING) || sei->payloadType() == SEI::DECODING_UNIT_INFO || sei->payloadType() == SEI::SUBPICTURE_LEVEL_INFO)
             {
+#if JVET_S0154_ASPECT9_AND_S0158_ASPECT4
+              writeInpuNalUnitToStream &= targetOlsIncludeAllVclLayers;
+#else
               bool targetOlsIdxGreaterThanZero = m_targetOlsIdx > 0;
               writeInpuNalUnitToStream &= !targetOlsIdxGreaterThanZero;
+#endif
             }
           }
+#if !JVET_S0154_ASPECT9_AND_S0158_ASPECT4
           if (m_subPicIdx >= 0 && writeInpuNalUnitToStream)
           {
             writeInpuNalUnitToStream = xCheckSeiSubpicture(SEIs, subpicIdTarget[nalu.m_nuhLayerId], rmAllFillerInSubpicExt[nalu.m_nuhLayerId], lastSliceWritten, isVclNalUnitRemoved[nalu.m_nuhLayerId]);
           }
+#endif
           if (m_vpsId == -1)
           {
             delete vps;
           }
         }
+#if JVET_S0154_ASPECT9_AND_S0158_ASPECT4
+        writeInpuNalUnitToStream &= xCheckSEIFiller(SEIs, subpicIdTarget[nalu.m_nuhLayerId], rmAllFillerInSubpicExt[nalu.m_nuhLayerId], lastSliceWritten);
+        if (writeInpuNalUnitToStream && isVclNalUnitRemoved[nalu.m_nuhLayerId] && m_subPicIdx >= 0)
+        {
+          writeInpuNalUnitToStream &= xCheckSEIsSubPicture(SEIs, nalu, bitstreamFileOut, subpicIdTarget[nalu.m_nuhLayerId], vps);
+        }
+#else
         if (m_subPicIdx >= 0)
         {
           writeInpuNalUnitToStream &= xCheckSEIsSubPicture(SEIs, nalu, bitstreamFileOut, subpicIdTarget[nalu.m_nuhLayerId]);
         }
+#endif
       }
 
 #if JVET_R0107_BITSTREAM_EXTACTION
@@ -846,9 +1032,15 @@ uint32_t BitstreamExtractorApp::decode()
          slice = xParseSliceHeader(nalu);
       }
 #endif
+#if JVET_S0154_ASPECT9_AND_S0158_ASPECT4
+      if (isMultiSubpicLayer[nalu.m_nuhLayerId] && writeInpuNalUnitToStream)
+      {
+        if (m_subPicIdx >= 0 && nalu.isSlice())
+#else
       if (m_subPicIdx >= 0 && isMultiSubpicLayer[nalu.m_nuhLayerId] && writeInpuNalUnitToStream)
       {
         if (nalu.isSlice())
+#endif
         {
           writeInpuNalUnitToStream = xCheckSliceSubpicture(slice, subpicIdTarget[nalu.m_nuhLayerId]);
           if (!writeInpuNalUnitToStream)
diff --git a/source/App/BitstreamExtractorApp/BitstreamExtractorApp.h b/source/App/BitstreamExtractorApp/BitstreamExtractorApp.h
index 345aac94a..1ff853487 100644
--- a/source/App/BitstreamExtractorApp/BitstreamExtractorApp.h
+++ b/source/App/BitstreamExtractorApp/BitstreamExtractorApp.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -65,7 +65,11 @@ protected:
   void xPrintSubPicInfo (PPS *pps);
   void xRewriteSPS (SPS &targetSPS, const SPS &sourceSPS, SubPic &subPic);
   void xRewritePPS (PPS &targetPPS, const PPS &sourcePPS, const SPS &sourceSPS, SubPic &subPic);
+#if JVET_S0154_ASPECT9_AND_S0158_ASPECT4
+  bool xCheckSEIFiller(SEIMessages SEIs, int targetSubPicId, bool &rmAllFillerInSubpicExt, bool lastSliceWritten);
+#else
   bool xCheckSeiSubpicture(SEIMessages SEIs, int targetSubPicId, bool &rmAllFillerInSubpicExt, bool lastSliceWritten, bool isVclNalUnitRemoved);
+#endif
 
 #if JVET_R0107_BITSTREAM_EXTACTION
   Slice xParseSliceHeader(InputNALUnit &nalu);
@@ -74,7 +78,12 @@ protected:
   bool xCheckSliceSubpicture(InputNALUnit &nalu, int subPicId);
 #endif
   void xReadPicHeader(InputNALUnit &nalu);
+#if JVET_S0154_ASPECT9_AND_S0158_ASPECT4
+  bool xIsTargetOlsIncludeAllVclLayers();
+  bool xCheckSEIsSubPicture(SEIMessages& SEIs, InputNALUnit& nalu, std::ostream& out, int subpicId, VPS *vps);
+#else
   bool xCheckSEIsSubPicture(SEIMessages& SEIs, InputNALUnit& nalu, std::ostream& out, int subpicId);
+#endif
   bool xCheckScalableNestingSEI(SEIScalableNesting *seiNesting, InputNALUnit& nalu, VPS *vps);
 
   void xSetSPSUpdated(int spsId)   { return m_updatedSPSList.push_back(spsId); }
diff --git a/source/App/BitstreamExtractorApp/BitstreamExtractorAppCfg.cpp b/source/App/BitstreamExtractorApp/BitstreamExtractorAppCfg.cpp
index 318049b44..8da48167a 100644
--- a/source/App/BitstreamExtractorApp/BitstreamExtractorAppCfg.cpp
+++ b/source/App/BitstreamExtractorApp/BitstreamExtractorAppCfg.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/App/BitstreamExtractorApp/BitstreamExtractorAppCfg.h b/source/App/BitstreamExtractorApp/BitstreamExtractorAppCfg.h
index b76c0905a..a8a55d0e8 100644
--- a/source/App/BitstreamExtractorApp/BitstreamExtractorAppCfg.h
+++ b/source/App/BitstreamExtractorApp/BitstreamExtractorAppCfg.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/App/BitstreamExtractorApp/CMakeLists.txt b/source/App/BitstreamExtractorApp/CMakeLists.txt
index a299cf5cc..c6145774e 100644
--- a/source/App/BitstreamExtractorApp/CMakeLists.txt
+++ b/source/App/BitstreamExtractorApp/CMakeLists.txt
@@ -33,32 +33,12 @@ if( SET_ENABLE_TRACING )
   endif()
 endif()
 
-if( OpenMP_FOUND )
-  if( SET_ENABLE_SPLIT_PARALLELISM )
-    if( ENABLE_SPLIT_PARALLELISM )
-      target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_SPLIT_PARALLELISM=1 )
-    else()
-      target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_SPLIT_PARALLELISM=0 )
-    endif()
-  endif()
-  if( SET_ENABLE_WPP_PARALLELISM )
-    if( ENABLE_WPP_PARALLELISM )
-      target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_WPP_PARALLELISM=1 )
-    else()
-      target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_WPP_PARALLELISM=0 )
-    endif()
-  endif()
-else()
-  target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_SPLIT_PARALLELISM=0 )
-  target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_WPP_PARALLELISM=0 )
-endif()
-
 if( CMAKE_COMPILER_IS_GNUCC AND BUILD_STATIC )
   set( ADDITIONAL_LIBS ${ADDITIONAL_LIBS} -static -static-libgcc -static-libstdc++ )
   target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_WPP_STATIC_LINK=1 )
 endif()
 
-target_link_libraries( ${EXE_NAME} CommonLib EncoderLib DecoderLib Utilities Threads::Threads ${ADDITIONAL_LIBS} )
+target_link_libraries( ${EXE_NAME} CommonLib EncoderLib DecoderLib Utilities ${ADDITIONAL_LIBS} )
 
 # lldb custom data formatters
 if( XCODE )
diff --git a/source/App/BitstreamExtractorApp/bitstreamextractormain.cpp b/source/App/BitstreamExtractorApp/bitstreamextractormain.cpp
index e57f05d41..3e7b381a6 100644
--- a/source/App/BitstreamExtractorApp/bitstreamextractormain.cpp
+++ b/source/App/BitstreamExtractorApp/bitstreamextractormain.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/App/DecoderAnalyserApp/CMakeLists.txt b/source/App/DecoderAnalyserApp/CMakeLists.txt
index ad272ca1f..7b23371f7 100644
--- a/source/App/DecoderAnalyserApp/CMakeLists.txt
+++ b/source/App/DecoderAnalyserApp/CMakeLists.txt
@@ -35,32 +35,12 @@ if( SET_ENABLE_TRACING )
   endif()
 endif()
 
-if( OpenMP_FOUND )
-  if( SET_ENABLE_SPLIT_PARALLELISM )
-    if( ENABLE_SPLIT_PARALLELISM )
-      target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_SPLIT_PARALLELISM=1 )
-    else()
-      target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_SPLIT_PARALLELISM=0 )
-    endif()
-  endif()
-  if( SET_ENABLE_WPP_PARALLELISM )
-    if( ENABLE_WPP_PARALLELISM )
-      target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_WPP_PARALLELISM=1 )
-    else()
-      target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_WPP_PARALLELISM=0 )
-    endif()
-  endif()
-else()
-  target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_SPLIT_PARALLELISM=0 )
-  target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_WPP_PARALLELISM=0 )
-endif()
-
 if( CMAKE_COMPILER_IS_GNUCC AND BUILD_STATIC )
   set( ADDITIONAL_LIBS ${ADDITIONAL_LIBS} -static -static-libgcc -static-libstdc++ )
   target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_WPP_STATIC_LINK=1 )
 endif()
 
-target_link_libraries( ${EXE_NAME} CommonAnalyserLib DecoderAnalyserLib Utilities Threads::Threads ${ADDITIONAL_LIBS} )
+target_link_libraries( ${EXE_NAME} CommonAnalyserLib DecoderAnalyserLib Utilities ${ADDITIONAL_LIBS} )
 
 # lldb custom data formatters
 if( XCODE )
diff --git a/source/App/DecoderApp/CMakeLists.txt b/source/App/DecoderApp/CMakeLists.txt
index 4e71c5c1e..958d2db0d 100644
--- a/source/App/DecoderApp/CMakeLists.txt
+++ b/source/App/DecoderApp/CMakeLists.txt
@@ -33,32 +33,12 @@ if( SET_ENABLE_TRACING )
   endif()
 endif()
 
-if( OpenMP_FOUND )
-  if( SET_ENABLE_SPLIT_PARALLELISM )
-    if( ENABLE_SPLIT_PARALLELISM )
-      target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_SPLIT_PARALLELISM=1 )
-    else()
-      target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_SPLIT_PARALLELISM=0 )
-    endif()
-  endif()
-  if( SET_ENABLE_WPP_PARALLELISM )
-    if( ENABLE_WPP_PARALLELISM )
-      target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_WPP_PARALLELISM=1 )
-    else()
-      target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_WPP_PARALLELISM=0 )
-    endif()
-  endif()
-else()
-  target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_SPLIT_PARALLELISM=0 )
-  target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_WPP_PARALLELISM=0 )
-endif()
-
 if( CMAKE_COMPILER_IS_GNUCC AND BUILD_STATIC )
   set( ADDITIONAL_LIBS ${ADDITIONAL_LIBS} -static -static-libgcc -static-libstdc++ )
   target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_WPP_STATIC_LINK=1 )
 endif()
 
-target_link_libraries( ${EXE_NAME} CommonLib DecoderLib Utilities Threads::Threads ${ADDITIONAL_LIBS} )
+target_link_libraries( ${EXE_NAME} CommonLib DecoderLib Utilities ${ADDITIONAL_LIBS} )
 
 # lldb custom data formatters
 if( XCODE )
diff --git a/source/App/DecoderApp/DecApp.cpp b/source/App/DecoderApp/DecApp.cpp
index c2f20c7e8..100720131 100644
--- a/source/App/DecoderApp/DecApp.cpp
+++ b/source/App/DecoderApp/DecApp.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -123,15 +123,24 @@ uint32_t DecApp::decode()
     }
   }
 
+  // clear contents of annotated-Regions-SEI output file
+  if (!m_annotatedRegionsSEIFileName.empty())
+  {
+    std::ofstream ofile(m_annotatedRegionsSEIFileName.c_str());
+    if (!ofile.good() || !ofile.is_open())
+    {
+      fprintf(stderr, "\nUnable to open file '%s' for writing annotated-Regions-SEI\n", m_annotatedRegionsSEIFileName.c_str());
+      exit(EXIT_FAILURE);
+    }
+  }
+
   // main decoder loop
   bool loopFiltered[MAX_VPS_LAYERS] = { false };
 
   bool bPicSkipped = false;
 
   bool isEosPresentInPu = false;
-#if JVET_S0078_NOOUTPUTPRIORPICFLAG
-  bool firstSliceInAU = true;
-#endif
+  bool isEosPresentInLastPu = false;
 
   bool outputPicturePresentInBitstream = false;
   auto setOutputPicturePresentInStream = [&]()
@@ -150,10 +159,11 @@ uint32_t DecApp::decode()
     }
   };
 
-#if JVET_S0163_ON_TARGETOLS_SUBLAYERS
     m_cDecLib.setHTidExternalSetFlag(m_mTidExternalSet);
     m_cDecLib.setTOlsIdxExternalFlag(m_tOlsIdxTidExternalSet);
-#endif
+
+  bool gdrRecoveryPeriod[MAX_NUM_LAYER_IDS] = { false };
+  bool prevPicSkipped = true;
 
   while (!!bitstreamFile)
   {
@@ -188,21 +198,31 @@ uint32_t DecApp::decode()
             (nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_W_RADL ||
              nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_N_LP))
         {
-          m_newCLVS[nalu.m_nuhLayerId] = true;   // An IDR picture starts a new CLVS
-#if !JVET_S0078_NOOUTPUTPRIORPICFLAG
-          xFlushOutput(pcListPic, nalu.m_nuhLayerId);
-#endif
+          if (!m_cDecLib.getMixedNaluTypesInPicFlag())
+          {
+            m_newCLVS[nalu.m_nuhLayerId] = true;   // An IDR picture starts a new CLVS
+            xFlushOutput(pcListPic, nalu.m_nuhLayerId);
+          }
+          else
+          {
+            m_newCLVS[nalu.m_nuhLayerId] = false;
+          }
         }
-        if (m_cDecLib.getFirstSliceInPicture() && nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_CRA && isEosPresentInPu)
+        else if (m_cDecLib.getFirstSliceInPicture() && nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_CRA && isEosPresentInLastPu)
         {
           // A CRA that is immediately preceded by an EOS is a CLVSS
           m_newCLVS[nalu.m_nuhLayerId] = true;
+          xFlushOutput(pcListPic, nalu.m_nuhLayerId);
         }
-        else if (m_cDecLib.getFirstSliceInPicture() && nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_CRA && !isEosPresentInPu)
+        else if (m_cDecLib.getFirstSliceInPicture() && nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_CRA && !isEosPresentInLastPu)
         {
           // A CRA that is not immediately precede by an EOS is not a CLVSS
           m_newCLVS[nalu.m_nuhLayerId] = false;
         }
+        else if(m_cDecLib.getFirstSliceInPicture() && !isEosPresentInLastPu)
+        {
+          m_newCLVS[nalu.m_nuhLayerId] = false;
+        }
 
         // parse NAL unit syntax if within target decoding layer
         if( ( m_iMaxTemporalLayer < 0 || nalu.m_temporalId <= m_iMaxTemporalLayer ) && xIsNaluWithinTargetDecLayerIdSet( &nalu ) )
@@ -225,8 +245,40 @@ uint32_t DecApp::decode()
               bPicSkipped = false;
             }
           }
+
+          int skipFrameCounter = m_iSkipFrame;
           m_cDecLib.decode(nalu, m_iSkipFrame, m_iPOCLastDisplay, m_targetOlsIdx);
-#if JVET_S0163_ON_TARGETOLS_SUBLAYERS
+
+          if ( prevPicSkipped && nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_GDR )
+          {
+            gdrRecoveryPeriod[nalu.m_nuhLayerId] = true;
+          }
+
+          if ( skipFrameCounter == 1 && ( nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_GDR  || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_CRA ))
+          {
+            skipFrameCounter--;
+          }
+
+          if ( m_iSkipFrame < skipFrameCounter  &&
+              ((nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_TRAIL) || (nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_STSA) || (nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_RASL) || (nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_RADL) || (nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_W_RADL) || (nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_N_LP) || (nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_CRA) || (nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_GDR)))
+          {
+            if (m_cDecLib.isSliceNaluFirstInAU(true, nalu))
+            {
+              m_cDecLib.checkSeiInPictureUnit();
+              m_cDecLib.resetPictureSeiNalus();
+              m_cDecLib.checkAPSInPictureUnit();
+              m_cDecLib.resetPictureUnitNals();
+              m_cDecLib.resetAccessUnitSeiTids();
+              m_cDecLib.checkSEIInAccessUnit();
+              m_cDecLib.resetAccessUnitSeiPayLoadTypes();
+              m_cDecLib.resetAccessUnitNals();
+              m_cDecLib.resetAccessUnitApsNals();
+              m_cDecLib.resetAccessUnitPicInfo();
+            }
+            bPicSkipped = true;
+            m_iSkipFrame++;   // skipFrame count restore, the real decrement occur at the begin of next frame
+          }
+
           if (nalu.m_nalUnitType == NAL_UNIT_OPI)
           {
             if (!m_cDecLib.getHTidExternalSetFlag() && m_cDecLib.getOPI()->getHtidInfoPresentFlag())
@@ -235,14 +287,9 @@ uint32_t DecApp::decode()
             }
             m_cDecLib.setHTidOpiSetFlag(m_cDecLib.getOPI()->getHtidInfoPresentFlag());
           }
-#endif
           if (nalu.m_nalUnitType == NAL_UNIT_VPS)
           {
-#if JVET_S0163_ON_TARGETOLS_SUBLAYERS
             m_cDecLib.deriveTargetOutputLayerSet( m_cDecLib.getVPS()->m_targetOlsIdx );
-#else
-            m_cDecLib.deriveTargetOutputLayerSet( m_targetOlsIdx );
-#endif
             m_targetDecLayerIdSet = m_cDecLib.getVPS()->m_targetLayerIdSet;
             m_targetOutputLayerIdSet = m_cDecLib.getVPS()->m_targetOutputLayerIdSet;
           }
@@ -252,6 +299,12 @@ uint32_t DecApp::decode()
           bPicSkipped = true;
         }
       }
+
+      if( nalu.isSlice() && nalu.m_nalUnitType != NAL_UNIT_CODED_SLICE_RASL)
+      {
+        prevPicSkipped = bPicSkipped;
+      }
+
       // once an EOS NAL unit appears in the current PU, mark the variable isEosPresentInPu as true
       if (nalu.m_nalUnitType == NAL_UNIT_EOS)
       {
@@ -281,6 +334,14 @@ uint32_t DecApp::decode()
       m_cDecLib.updateAssociatedIRAP();
       m_cDecLib.updatePrevGDRInSameLayer();
       m_cDecLib.updatePrevIRAPAndGDRSubpic();
+
+      if ( gdrRecoveryPeriod[nalu.m_nuhLayerId] )
+      {
+        if ( m_cDecLib.getGDRRecoveryPocReached() )
+        {
+          gdrRecoveryPeriod[nalu.m_nuhLayerId] = false;
+        }
+      }
     }
     else if ( (bNewPicture || !bitstreamFile || nalu.m_nalUnitType == NAL_UNIT_EOS ) &&
       m_cDecLib.getFirstSliceInSequence(nalu.m_nuhLayerId))
@@ -290,6 +351,19 @@ uint32_t DecApp::decode()
 
     if( pcListPic )
     {
+      if ( gdrRecoveryPeriod[nalu.m_nuhLayerId] ) // Suppress YUV and OPL output during GDR recovery
+      {
+        PicList::iterator iterPic = pcListPic->begin();
+        while (iterPic != pcListPic->end())
+        {
+          Picture *pcPic = *(iterPic++);
+          if (pcPic->layerId == nalu.m_nuhLayerId)
+          {
+            pcPic->neededForOutput = false;
+          }
+        }
+      }
+
       if( !m_reconFileName.empty() && !m_cVideoIOYuvReconFile[nalu.m_nuhLayerId].isOpen() )
       {
         const BitDepths &bitDepths=pcListPic->front()->cs->sps->getBitDepths(); // use bit depths of first reconstructed picture.
@@ -336,6 +410,44 @@ uint32_t DecApp::decode()
           m_cVideoIOYuvReconFile[nalu.m_nuhLayerId].setBitdepthShift(channelType, reconBitdepth - fileBitdepth);
         }
       }
+      if (!m_SEICTIFileName.empty() && !m_cVideoIOYuvSEICTIFile[nalu.m_nuhLayerId].isOpen())
+      {
+        const BitDepths& bitDepths = pcListPic->front()->cs->sps->getBitDepths(); // use bit depths of first reconstructed picture.
+        for (uint32_t channelType = 0; channelType < MAX_NUM_CHANNEL_TYPE; channelType++)
+        {
+          if (m_outputBitDepth[channelType] == 0)
+          {
+            m_outputBitDepth[channelType] = bitDepths.recon[channelType];
+          }
+        }
+
+        if (m_packedYUVMode && (m_outputBitDepth[CH_L] != 10 && m_outputBitDepth[CH_L] != 12))
+        {
+          EXIT("Invalid output bit-depth for packed YUV output, aborting\n");
+        }
+
+        std::string SEICTIFileName = m_SEICTIFileName;
+        if (m_SEICTIFileName.compare("/dev/null") && m_cDecLib.getVPS() != nullptr && m_cDecLib.getVPS()->getMaxLayers() > 1 && xIsNaluWithinTargetOutputLayerIdSet(&nalu))
+        {
+          size_t pos = SEICTIFileName.find_last_of('.');
+          if (pos != string::npos)
+          {
+            SEICTIFileName.insert(pos, std::to_string(nalu.m_nuhLayerId));
+          }
+          else
+          {
+            SEICTIFileName.append(std::to_string(nalu.m_nuhLayerId));
+          }
+        }
+        if ((m_cDecLib.getVPS() != nullptr && (m_cDecLib.getVPS()->getMaxLayers() == 1 || xIsNaluWithinTargetOutputLayerIdSet(&nalu))) || m_cDecLib.getVPS() == nullptr)
+        {
+          m_cVideoIOYuvSEICTIFile[nalu.m_nuhLayerId].open(SEICTIFileName, true, m_outputBitDepth, m_outputBitDepth, bitDepths.recon); // write mode
+        }
+      }
+      if (!m_annotatedRegionsSEIFileName.empty())
+      {
+        xOutputAnnotatedRegions(pcListPic);
+      }
       // write reconstruction to file
       if( bNewPicture )
       {
@@ -344,74 +456,28 @@ uint32_t DecApp::decode()
       }
       if (nalu.m_nalUnitType == NAL_UNIT_EOS)
       {
+        if (!m_annotatedRegionsSEIFileName.empty() && bNewPicture)
+        {
+          xOutputAnnotatedRegions(pcListPic);
+        }
         setOutputPicturePresentInStream();
         xWriteOutput( pcListPic, nalu.m_temporalId );
         m_cDecLib.setFirstSliceInPicture (false);
       }
       // write reconstruction to file -- for additional bumping as defined in C.5.2.3
-#if JVET_S0163_ON_TARGETOLS_SUBLAYERS
       if (!bNewPicture && ((nalu.m_nalUnitType >= NAL_UNIT_CODED_SLICE_TRAIL && nalu.m_nalUnitType <= NAL_UNIT_RESERVED_IRAP_VCL_11)
         || (nalu.m_nalUnitType >= NAL_UNIT_CODED_SLICE_IDR_W_RADL && nalu.m_nalUnitType <= NAL_UNIT_CODED_SLICE_GDR)))
-#else
-      if (!bNewPicture && ((nalu.m_nalUnitType >= NAL_UNIT_CODED_SLICE_TRAIL && nalu.m_nalUnitType <= NAL_UNIT_RESERVED_IRAP_VCL_12)
-        || (nalu.m_nalUnitType >= NAL_UNIT_CODED_SLICE_IDR_W_RADL && nalu.m_nalUnitType <= NAL_UNIT_CODED_SLICE_GDR)))
-#endif
       {
         setOutputPicturePresentInStream();
-#if JVET_S0078_NOOUTPUTPRIORPICFLAG
-        bool firstPicInCVSAUThatIsNotAU0 = false;
-        if (firstSliceInAU)
-        {
-          if (m_targetDecLayerIdSet.size() > 0)
-          {
-            if (m_cDecLib.getAudIrapOrGdrAuFlag())
-            {
-              firstPicInCVSAUThatIsNotAU0 = true;
-            }
-          }
-          else
-          {
-            if (nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_W_RADL
-                || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_N_LP
-                || (nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_CRA && isEosPresentInPu))
-            {
-              firstPicInCVSAUThatIsNotAU0 = true;
-            }
-          }
-        }
-        if (firstPicInCVSAUThatIsNotAU0)
-        {
-          xFlushOutput(pcListPic, NOT_VALID, m_cDecLib.getNoOutputPriorPicsFlag());
-        }
-        else
-        {
-          xWriteOutput(pcListPic, nalu.m_temporalId);
-        }
-#else
         xWriteOutput( pcListPic, nalu.m_temporalId );
-#endif
       }
     }
-#if JVET_S0078_NOOUTPUTPRIORPICFLAG
-#if JVET_S0163_ON_TARGETOLS_SUBLAYERS
-    if ((nalu.m_nalUnitType >= NAL_UNIT_CODED_SLICE_TRAIL && nalu.m_nalUnitType <= NAL_UNIT_OPI)
-        || (nalu.m_nalUnitType >= NAL_UNIT_CODED_SLICE_IDR_W_RADL && nalu.m_nalUnitType <= NAL_UNIT_CODED_SLICE_GDR))
-    {
-      firstSliceInAU = false;
-    }
-#else
-    if ((nalu.m_nalUnitType >= NAL_UNIT_CODED_SLICE_TRAIL && nalu.m_nalUnitType <= NAL_UNIT_RESERVED_IRAP_VCL_12)
-        || (nalu.m_nalUnitType >= NAL_UNIT_CODED_SLICE_IDR_W_RADL && nalu.m_nalUnitType <= NAL_UNIT_CODED_SLICE_GDR))
-    {
-      firstSliceInAU = false;
-    }
-#endif
-#endif
     if( bNewPicture )
     {
       m_cDecLib.checkSeiInPictureUnit();
       m_cDecLib.resetPictureSeiNalus();
       // reset the EOS present status for the next PU check
+      isEosPresentInLastPu = isEosPresentInPu;
       isEosPresentInPu = false;
     }
     if (bNewPicture || !bitstreamFile || nalu.m_nalUnitType == NAL_UNIT_EOS)
@@ -443,11 +509,12 @@ uint32_t DecApp::decode()
       m_cDecLib.resetAccessUnitNals();
       m_cDecLib.resetAccessUnitApsNals();
       m_cDecLib.resetAccessUnitPicInfo();
-#if JVET_S0078_NOOUTPUTPRIORPICFLAG
-      firstSliceInAU = true;
-#endif
     }
   }
+  if (!m_annotatedRegionsSEIFileName.empty())
+  {
+    xOutputAnnotatedRegions(pcListPic);
+  }
   // May need to check again one more time as in case one the bitstream has only one picture, the first check may miss it
   setOutputPicturePresentInStream();
   CHECK(!outputPicturePresentInBitstream, "It is required that there shall be at least one picture with PictureOutputFlag equal to 1 in the bitstream")
@@ -530,6 +597,9 @@ void DecApp::xCreateDecLib()
 #endif
   m_cDecLib.m_targetSubPicIdx = this->m_targetSubPicIdx;
   m_cDecLib.initScalingList();
+#if GDR_LEAK_TEST
+  m_cDecLib.m_gdrPocRandomAccess = this->m_gdrPocRandomAccess;
+#endif // GDR_LEAK_TEST
 }
 
 void DecApp::xDestroyDecLib()
@@ -541,6 +611,13 @@ void DecApp::xDestroyDecLib()
       recFile.second.close();
     }
   }
+  if (!m_SEICTIFileName.empty())
+  {
+    for (auto& recFile : m_cVideoIOYuvSEICTIFile)
+    {
+      recFile.second.close();
+    }
+  }
 
   // destroy decoder class
   m_cDecLib.destroy();
@@ -582,7 +659,7 @@ void DecApp::xWriteOutput( PicList* pcListPic, uint32_t tId )
   while (iterPic != pcListPic->end())
   {
     Picture* pcPic = *(iterPic);
-    if(pcPic->neededForOutput && pcPic->getPOC() > m_iPOCLastDisplay)
+    if(pcPic->neededForOutput && pcPic->getPOC() >= m_iPOCLastDisplay)
     {
        numPicsNotYetDisplayed++;
       dpbFullness++;
@@ -667,7 +744,7 @@ void DecApp::xWriteOutput( PicList* pcListPic, uint32_t tId )
     {
       pcPic = *(iterPic);
 
-      if(pcPic->neededForOutput && pcPic->getPOC() > m_iPOCLastDisplay &&
+      if(pcPic->neededForOutput && pcPic->getPOC() >= m_iPOCLastDisplay &&
         (numPicsNotYetDisplayed >  maxNumReorderPicsHighestTid || dpbFullness > maxDecPicBufferingHighestTid))
       {
         // write to file
@@ -699,6 +776,27 @@ void DecApp::xWriteOutput( PicList* pcListPic, uint32_t tId )
                                         NUM_CHROMA_FORMAT, m_bClipOutputVideoToRec709Range );
             }
         }
+        // Perform CTI on decoded frame and write to output CTI file
+        if (!m_SEICTIFileName.empty())
+        {
+          const Window& conf = pcPic->getConformanceWindow();
+          const SPS* sps = pcPic->cs->sps;
+          ChromaFormat chromaFormatIDC = sps->getChromaFormatIdc();
+          if (m_upscaledOutput)
+          {
+            m_cVideoIOYuvSEICTIFile[pcPic->layerId].writeUpscaledPicture(*sps, *pcPic->cs->pps, pcPic->getDisplayBuf(), m_outputColourSpaceConvert, m_packedYUVMode, m_upscaledOutput, NUM_CHROMA_FORMAT, m_bClipOutputVideoToRec709Range);
+          }
+          else
+          {
+            m_cVideoIOYuvSEICTIFile[pcPic->layerId].write(pcPic->getRecoBuf().get(COMPONENT_Y).width, pcPic->getRecoBuf().get(COMPONENT_Y).height, pcPic->getDisplayBuf(),
+              m_outputColourSpaceConvert, m_packedYUVMode,
+              conf.getWindowLeftOffset() * SPS::getWinUnitX(chromaFormatIDC),
+              conf.getWindowRightOffset() * SPS::getWinUnitX(chromaFormatIDC),
+              conf.getWindowTopOffset() * SPS::getWinUnitY(chromaFormatIDC),
+              conf.getWindowBottomOffset() * SPS::getWinUnitY(chromaFormatIDC),
+              NUM_CHROMA_FORMAT, m_bClipOutputVideoToRec709Range);
+          }
+        }
         writeLineToOutputLog(pcPic);
 
         // update POC of display order
@@ -719,11 +817,7 @@ void DecApp::xWriteOutput( PicList* pcListPic, uint32_t tId )
 
 /** \param pcListPic list of pictures to be written to file
  */
-#if JVET_S0078_NOOUTPUTPRIORPICFLAG
-void DecApp::xFlushOutput( PicList *pcListPic, const int layerId, bool noOutputOfPriorPicsFlag)
-#else
 void DecApp::xFlushOutput( PicList* pcListPic, const int layerId )
-#endif
 {
   if(!pcListPic || pcListPic->empty())
   {
@@ -752,10 +846,6 @@ void DecApp::xFlushOutput( PicList* pcListPic, const int layerId )
 
       if ( pcPicTop->neededForOutput && pcPicBottom->neededForOutput && !(pcPicTop->getPOC()%2) && (pcPicBottom->getPOC() == pcPicTop->getPOC()+1) )
       {
-#if JVET_S0078_NOOUTPUTPRIORPICFLAG
-        if (!noOutputOfPriorPicsFlag)
-        {
-#endif
           // write to file
           if ( !m_reconFileName.empty() )
           {
@@ -773,9 +863,6 @@ void DecApp::xFlushOutput( PicList* pcListPic, const int layerId )
           }
           writeLineToOutputLog(pcPicTop);
           writeLineToOutputLog(pcPicBottom);
-#if JVET_S0078_NOOUTPUTPRIORPICFLAG
-        }
-#endif
         // update POC of display order
         m_iPOCLastDisplay = pcPicBottom->getPOC();
 
@@ -820,10 +907,6 @@ void DecApp::xFlushOutput( PicList* pcListPic, const int layerId )
 
       if (pcPic->neededForOutput)
       {
-#if JVET_S0078_NOOUTPUTPRIORPICFLAG
-        if (!noOutputOfPriorPicsFlag)
-        {
-#endif
           // write to file
           if (!m_reconFileName.empty())
           {
@@ -846,10 +929,28 @@ void DecApp::xFlushOutput( PicList* pcListPic, const int layerId )
                                         NUM_CHROMA_FORMAT, m_bClipOutputVideoToRec709Range );
               }
           }
+          // Perform CTI on decoded frame and write to output CTI file
+          if (!m_SEICTIFileName.empty())
+          {
+            const Window& conf = pcPic->getConformanceWindow();
+            const SPS* sps = pcPic->cs->sps;
+            ChromaFormat chromaFormatIDC = sps->getChromaFormatIdc();
+            if (m_upscaledOutput)
+            {
+              m_cVideoIOYuvSEICTIFile[pcPic->layerId].writeUpscaledPicture(*sps, *pcPic->cs->pps, pcPic->getDisplayBuf(), m_outputColourSpaceConvert, m_packedYUVMode, m_upscaledOutput, NUM_CHROMA_FORMAT, m_bClipOutputVideoToRec709Range);
+            }
+            else
+            {
+              m_cVideoIOYuvSEICTIFile[pcPic->layerId].write(pcPic->getRecoBuf().get(COMPONENT_Y).width, pcPic->getRecoBuf().get(COMPONENT_Y).height, pcPic->getDisplayBuf(),
+                m_outputColourSpaceConvert, m_packedYUVMode,
+                conf.getWindowLeftOffset() * SPS::getWinUnitX(chromaFormatIDC),
+                conf.getWindowRightOffset() * SPS::getWinUnitX(chromaFormatIDC),
+                conf.getWindowTopOffset() * SPS::getWinUnitY(chromaFormatIDC),
+                conf.getWindowBottomOffset() * SPS::getWinUnitY(chromaFormatIDC),
+                NUM_CHROMA_FORMAT, m_bClipOutputVideoToRec709Range);
+            }
+          }
           writeLineToOutputLog(pcPic);
-#if JVET_S0078_NOOUTPUTPRIORPICFLAG
-        }
-#endif
         // update POC of display order
         m_iPOCLastDisplay = pcPic->getPOC();
 
@@ -880,6 +981,153 @@ void DecApp::xFlushOutput( PicList* pcListPic, const int layerId )
   m_iPOCLastDisplay = -MAX_INT;
 }
 
+/** \param pcListPic list of pictures to be written to file
+ */
+void DecApp::xOutputAnnotatedRegions(PicList* pcListPic)
+{
+  if(!pcListPic || pcListPic->empty())
+  {
+    return;
+  }
+  PicList::iterator iterPic   = pcListPic->begin();
+
+  while (iterPic != pcListPic->end())
+  {
+    Picture* pcPic = *(iterPic);
+    if (pcPic->neededForOutput)
+    {
+      // Check if any annotated region SEI has arrived
+      SEIMessages annotatedRegionSEIs = getSeisByType(pcPic->SEIs, SEI::ANNOTATED_REGIONS);
+      for(auto it=annotatedRegionSEIs.begin(); it!=annotatedRegionSEIs.end(); it++)
+      {
+        const SEIAnnotatedRegions &seiAnnotatedRegions = *(SEIAnnotatedRegions*)(*it);
+
+        if (seiAnnotatedRegions.m_hdr.m_cancelFlag)
+        {
+          m_arObjects.clear();
+          m_arLabels.clear();
+        }
+        else
+        {
+          if (m_arHeader.m_receivedSettingsOnce)
+          {
+            // validate those settings that must stay constant are constant.
+            assert(m_arHeader.m_occludedObjectFlag              == seiAnnotatedRegions.m_hdr.m_occludedObjectFlag);
+            assert(m_arHeader.m_partialObjectFlagPresentFlag    == seiAnnotatedRegions.m_hdr.m_partialObjectFlagPresentFlag);
+            assert(m_arHeader.m_objectConfidenceInfoPresentFlag == seiAnnotatedRegions.m_hdr.m_objectConfidenceInfoPresentFlag);
+            assert((!m_arHeader.m_objectConfidenceInfoPresentFlag) || m_arHeader.m_objectConfidenceLength == seiAnnotatedRegions.m_hdr.m_objectConfidenceLength);
+          }
+          else
+          {
+            m_arHeader.m_receivedSettingsOnce=true;
+            m_arHeader=seiAnnotatedRegions.m_hdr; // copy the settings.
+          }
+          // Process label updates
+          if (seiAnnotatedRegions.m_hdr.m_objectLabelPresentFlag)
+          {
+            for(auto srcIt=seiAnnotatedRegions.m_annotatedLabels.begin(); srcIt!=seiAnnotatedRegions.m_annotatedLabels.end(); srcIt++)
+            {
+              const uint32_t labIdx = srcIt->first;
+              if (srcIt->second.labelValid)
+              {
+                m_arLabels[labIdx] = srcIt->second.label;
+              }
+              else
+              {
+                m_arLabels.erase(labIdx);
+              }
+            }
+          }
+
+          // Process object updates
+          for(auto srcIt=seiAnnotatedRegions.m_annotatedRegions.begin(); srcIt!=seiAnnotatedRegions.m_annotatedRegions.end(); srcIt++)
+          {
+            uint32_t objIdx = srcIt->first;
+            const SEIAnnotatedRegions::AnnotatedRegionObject &src =srcIt->second;
+
+            if (src.objectCancelFlag)
+            {
+              m_arObjects.erase(objIdx);
+            }
+            else
+            {
+              auto destIt = m_arObjects.find(objIdx);
+
+              if (destIt == m_arObjects.end())
+              {
+                //New object arrived, needs to be appended to the map of tracked objects
+                m_arObjects[objIdx] = src;
+              }
+              else //Existing object, modifications to be done
+              {
+                SEIAnnotatedRegions::AnnotatedRegionObject &dst=destIt->second;
+
+                if (seiAnnotatedRegions.m_hdr.m_objectLabelPresentFlag && src.objectLabelValid)
+                {
+                  dst.objectLabelValid=true;
+                  dst.objLabelIdx = src.objLabelIdx;
+                }
+                if (src.boundingBoxValid)
+                {
+                  dst.boundingBoxTop    = src.boundingBoxTop   ;
+                  dst.boundingBoxLeft   = src.boundingBoxLeft  ;
+                  dst.boundingBoxWidth  = src.boundingBoxWidth ;
+                  dst.boundingBoxHeight = src.boundingBoxHeight;
+                  if (seiAnnotatedRegions.m_hdr.m_partialObjectFlagPresentFlag)
+                  {
+                    dst.partialObjectFlag = src.partialObjectFlag;
+                  }
+                  if (seiAnnotatedRegions.m_hdr.m_objectConfidenceInfoPresentFlag)
+                  {
+                    dst.objectConfidence = src.objectConfidence;
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+
+      if (!m_arObjects.empty())
+      {
+        FILE *fpPersist = fopen(m_annotatedRegionsSEIFileName.c_str(), "ab");
+        if (fpPersist == NULL)
+        {
+          std::cout << "Not able to open file for writing persist SEI messages" << std::endl;
+        }
+        else
+        {
+          fprintf(fpPersist, "\n");
+          fprintf(fpPersist, "Number of objects = %d\n", (int)m_arObjects.size());
+          for (auto it = m_arObjects.begin(); it != m_arObjects.end(); ++it)
+          {
+            fprintf(fpPersist, "Object Idx = %d\n",    it->first);
+            fprintf(fpPersist, "Object Top = %d\n",    it->second.boundingBoxTop);
+            fprintf(fpPersist, "Object Left = %d\n",   it->second.boundingBoxLeft);
+            fprintf(fpPersist, "Object Width = %d\n",  it->second.boundingBoxWidth);
+            fprintf(fpPersist, "Object Height = %d\n", it->second.boundingBoxHeight);
+            if (it->second.objectLabelValid)
+            {
+              auto labelIt=m_arLabels.find(it->second.objLabelIdx);
+              fprintf(fpPersist, "Object Label = %s\n", labelIt!=m_arLabels.end() ? (labelIt->second.c_str()) : "<UNKNOWN>");
+            }
+            if (m_arHeader.m_partialObjectFlagPresentFlag)
+            {
+              fprintf(fpPersist, "Object Partial = %d\n", it->second.partialObjectFlag?1:0);
+            }
+            if (m_arHeader.m_objectConfidenceInfoPresentFlag)
+            {
+              fprintf(fpPersist, "Object Conf = %d\n", it->second.objectConfidence);
+            }
+          }
+          fclose(fpPersist);
+        }
+      }
+    }
+   iterPic++;
+  }
+}
+
 /** \param nalu Input nalu to check whether its LayerId is within targetDecLayerIdSet
  */
 bool DecApp::xIsNaluWithinTargetDecLayerIdSet( const InputNALUnit* nalu ) const
diff --git a/source/App/DecoderApp/DecApp.h b/source/App/DecoderApp/DecApp.h
index 11f88ed5e..33ffaa519 100644
--- a/source/App/DecoderApp/DecApp.h
+++ b/source/App/DecoderApp/DecApp.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -61,6 +61,7 @@ private:
   // class interface
   DecLib          m_cDecLib;                     ///< decoder class
   std::unordered_map<int, VideoIOYuv>      m_cVideoIOYuvReconFile;        ///< reconstruction YUV class
+  std::unordered_map<int, VideoIOYuv>      m_cVideoIOYuvSEICTIFile;       ///< reconstruction YUV with CTI class
 
   // for output control
   int             m_iPOCLastDisplay;              ///< last POC in display order
@@ -70,6 +71,9 @@ private:
 
   bool            m_newCLVS[MAX_NUM_LAYER_IDS];   ///< used to record a new CLVSS
 
+  SEIAnnotatedRegions::AnnotatedRegionHeader                 m_arHeader; ///< AR header
+  std::map<uint32_t, SEIAnnotatedRegions::AnnotatedRegionObject> m_arObjects; ///< AR object pool
+  std::map<uint32_t, std::string>                                m_arLabels; ///< AR label pool
 
 private:
   bool  xIsNaluWithinTargetDecLayerIdSet( const InputNALUnit* nalu ) const; ///< check whether given Nalu is within targetDecLayerIdSet
@@ -85,15 +89,12 @@ private:
   void  xCreateDecLib     (); ///< create internal classes
   void  xDestroyDecLib    (); ///< destroy internal classes
   void  xWriteOutput      ( PicList* pcListPic , uint32_t tId); ///< write YUV to file
-#if JVET_S0078_NOOUTPUTPRIORPICFLAG
-  void  xFlushOutput( PicList *pcListPic, const int layerId = NOT_VALID, bool noOutputOfPriorPicsFlag = false );   ///< flush all remaining decoded pictures to file
-#else
   void  xFlushOutput( PicList* pcListPic, const int layerId = NOT_VALID ); ///< flush all remaining decoded pictures to file
-#endif
   bool  isNewPicture(ifstream *bitstreamFile, class InputByteStream *bytestream);  ///< check if next NAL unit will be the first NAL unit from a new picture
   bool  isNewAccessUnit(bool newPicture, ifstream *bitstreamFile, class InputByteStream *bytestream);  ///< check if next NAL unit will be the first NAL unit from a new access unit
 
   void  writeLineToOutputLog(Picture * pcPic);
+  void xOutputAnnotatedRegions(PicList* pcListPic);
 
 };
 
diff --git a/source/App/DecoderApp/DecAppCfg.cpp b/source/App/DecoderApp/DecAppCfg.cpp
index d96c20493..616d65fd1 100644
--- a/source/App/DecoderApp/DecAppCfg.cpp
+++ b/source/App/DecoderApp/DecAppCfg.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -88,19 +88,16 @@ bool DecAppCfg::parseCfg( int argc, char* argv[] )
   ("OutputBitDepth,d",          m_outputBitDepth[CHANNEL_TYPE_LUMA],   0,          "bit depth of YUV output luma component (default: use 0 for native depth)")
   ("OutputBitDepthC,d",         m_outputBitDepth[CHANNEL_TYPE_CHROMA], 0,          "bit depth of YUV output chroma component (default: use luma output bit-depth)")
   ("OutputColourSpaceConvert",  outputColourSpaceConvert,              string(""), "Colour space conversion to apply to input 444 video. Permitted values are (empty string=UNCHANGED) " + getListOfColourSpaceConverts(false))
-#if JVET_S0163_ON_TARGETOLS_SUBLAYERS
   ("MaxTemporalLayer,t",        m_iMaxTemporalLayer,                   500,    "Maximum Temporal Layer to be decoded. -1 to decode all layers")
   ("TargetOutputLayerSet,p",    m_targetOlsIdx,                        500,    "Target output layer set index")
-#else
-  ("MaxTemporalLayer,t",        m_iMaxTemporalLayer,                   -1,         "Maximum Temporal Layer to be decoded. -1 to decode all layers")
-  ("TargetOutputLayerSet,p",    m_targetOlsIdx,                          -1,       "Target output layer set index")
-#endif
   ("SEIDecodedPictureHash,-dph",m_decodedPictureHashSEIEnabled,        1,          "Control handling of decoded picture hash SEI messages\n"
                                                                                    "\t1: check hash in SEI messages if available in the bitstream\n"
                                                                                    "\t0: ignore SEI message")
   ("SEINoDisplay",              m_decodedNoDisplaySEIEnabled,          true,       "Control handling of decoded no display SEI messages")
   ("TarDecLayerIdSetFile,l",    cfg_TargetDecLayerIdSetFile,           string(""), "targetDecLayerIdSet file name. The file should include white space separated LayerId values to be decoded. Omitting the option or a value of -1 in the file decodes all layers.")
   ("SEIColourRemappingInfoFilename",  m_colourRemapSEIFileName,        string(""), "Colour Remapping YUV output file name. If empty, no remapping is applied (ignore SEI message)\n")
+  ("SEICTIFilename",            m_SEICTIFileName,                      string(""), "CTI YUV output file name. If empty, no Colour Transform is applied (ignore SEI message)\n")
+  ("SEIAnnotatedRegionsInfoFilename",  m_annotatedRegionsSEIFileName,   string(""), "Annotated regions output file name. If empty, no object information will be saved (ignore SEI message)\n")
   ("OutputDecodedSEIMessagesFilename",  m_outputDecodedSEIMessagesFilename,    string(""), "When non empty, output decoded SEI messages to the indicated file. If file is '-', then output to stdout\n")
 #if JVET_S0257_DUMP_360SEI_MESSAGE
   ("360DumpFile",  m_outputDecoded360SEIMessagesFilename, string(""), "When non empty, output decoded 360 SEI messages to the indicated file.\n")
@@ -125,6 +122,9 @@ bool DecAppCfg::parseCfg( int argc, char* argv[] )
   ("MCTSCheck",                m_mctsCheck,                           false,       "If enabled, the decoder checks for violations of mc_exact_sample_value_match_flag in Temporal MCTS ")
   ("targetSubPicIdx",          m_targetSubPicIdx,                     0,           "Specify which subpicture shall be written to output, using subpic index, 0: disabled, subpicIdx=m_targetSubPicIdx-1 \n" )
   ( "UpscaledOutput",          m_upscaledOutput,                          0,       "Upscaled output for RPR" )
+#if GDR_LEAK_TEST
+  ("RandomAccessPos",          m_gdrPocRandomAccess,                    0,         "POC of GDR Random access picture\n" )
+#endif // GDR_LEAK_TEST
   ;
 
   po::setDefaults(opts);
@@ -225,7 +225,6 @@ bool DecAppCfg::parseCfg( int argc, char* argv[] )
       msg( ERROR, "File %s could not be opened. Using all LayerIds as default.\n", cfg_TargetDecLayerIdSetFile.c_str() );
     }
   }
-#if JVET_S0163_ON_TARGETOLS_SUBLAYERS
   if (m_iMaxTemporalLayer != 500)
   {
     m_mTidExternalSet = true;
@@ -242,7 +241,6 @@ bool DecAppCfg::parseCfg( int argc, char* argv[] )
   {
     m_targetOlsIdx = -1;
   }
-#endif
   return true;
 }
 
@@ -256,13 +254,13 @@ DecAppCfg::DecAppCfg()
 , m_outputColourSpaceConvert(IPCOLOURSPACE_UNCHANGED)
 , m_targetOlsIdx(0)
 , m_iMaxTemporalLayer(-1)
-#if JVET_S0163_ON_TARGETOLS_SUBLAYERS
 , m_mTidExternalSet(false)
 , m_tOlsIdxTidExternalSet(false)
-#endif
 , m_decodedPictureHashSEIEnabled(0)
 , m_decodedNoDisplaySEIEnabled(false)
 , m_colourRemapSEIFileName()
+, m_SEICTIFileName()
+, m_annotatedRegionsSEIFileName()
 , m_targetDecLayerIdSet()
 , m_outputDecodedSEIMessagesFilename()
 #if JVET_S0257_DUMP_360SEI_MESSAGE
diff --git a/source/App/DecoderApp/DecAppCfg.h b/source/App/DecoderApp/DecAppCfg.h
index ba7c0338e..c8a735ca5 100644
--- a/source/App/DecoderApp/DecAppCfg.h
+++ b/source/App/DecoderApp/DecAppCfg.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -67,13 +67,13 @@ protected:
   int           m_targetOlsIdx;                       ///< target output layer set
   std::vector<int> m_targetOutputLayerIdSet;          ///< set of LayerIds to be outputted
   int           m_iMaxTemporalLayer;                  ///< maximum temporal layer to be decoded
-#if JVET_S0163_ON_TARGETOLS_SUBLAYERS
   bool          m_mTidExternalSet;                    ///< maximum temporal layer set externally
   bool          m_tOlsIdxTidExternalSet;              ///< target output layer set index externally set
-#endif
   int           m_decodedPictureHashSEIEnabled;       ///< Checksum(3)/CRC(2)/MD5(1)/disable(0) acting on decoded picture hash SEI message
   bool          m_decodedNoDisplaySEIEnabled;         ///< Enable(true)/disable(false) writing only pictures that get displayed based on the no display SEI message
   std::string   m_colourRemapSEIFileName;             ///< output Colour Remapping file name
+  std::string   m_SEICTIFileName;                     ///< output Recon with CTI file name
+  std::string   m_annotatedRegionsSEIFileName;        ///< annotated regions file name
   std::vector<int> m_targetDecLayerIdSet;             ///< set of LayerIds to be included in the sub-bitstream extraction process.
   std::string   m_outputDecodedSEIMessagesFilename;   ///< filename to output decoded SEI messages to. If '-', then use stdout. If empty, do not output details.
 #if JVET_S0257_DUMP_360SEI_MESSAGE
@@ -89,6 +89,9 @@ protected:
 
   int          m_upscaledOutput;                     ////< Output upscaled (2), decoded but in full resolution buffer (1) or decoded cropped (0, default) picture for RPR.
   int           m_targetSubPicIdx;                    ///< Specify which subpicture shall be write to output, using subpicture index
+#if GDR_LEAK_TEST
+  int           m_gdrPocRandomAccess;                   ///<
+#endif // GDR_LEAK_TEST
 public:
   DecAppCfg();
   virtual ~DecAppCfg();
diff --git a/source/App/DecoderApp/decmain.cpp b/source/App/DecoderApp/decmain.cpp
index c8a6e3bd7..94264a0ae 100644
--- a/source/App/DecoderApp/decmain.cpp
+++ b/source/App/DecoderApp/decmain.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/App/EncoderApp/CMakeLists.txt b/source/App/EncoderApp/CMakeLists.txt
index dd87e52d1..960790142 100644
--- a/source/App/EncoderApp/CMakeLists.txt
+++ b/source/App/EncoderApp/CMakeLists.txt
@@ -35,32 +35,12 @@ if( SET_ENABLE_TRACING )
   endif()
 endif()
 
-if( OpenMP_FOUND )
-  if( SET_ENABLE_SPLIT_PARALLELISM )
-    if( ENABLE_SPLIT_PARALLELISM )
-      target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_SPLIT_PARALLELISM=1 )
-    else()
-      target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_SPLIT_PARALLELISM=0 )
-    endif()
-  endif()
-  if( SET_ENABLE_WPP_PARALLELISM )
-    if( ENABLE_WPP_PARALLELISM )
-      target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_WPP_PARALLELISM=1 )
-    else()
-      target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_WPP_PARALLELISM=0 )
-    endif()
-  endif()
-else()
-  target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_SPLIT_PARALLELISM=0 )
-  target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_WPP_PARALLELISM=0 )
-endif()
-
 if( CMAKE_COMPILER_IS_GNUCC AND BUILD_STATIC )
   set( ADDITIONAL_LIBS ${ADDITIONAL_LIBS} -static -static-libgcc -static-libstdc++ )
   target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_WPP_STATIC_LINK=1 )
 endif()
 
-target_link_libraries( ${EXE_NAME} CommonLib EncoderLib DecoderLib Utilities Threads::Threads ${ADDITIONAL_LIBS} )
+target_link_libraries( ${EXE_NAME} CommonLib EncoderLib DecoderLib Utilities ${ADDITIONAL_LIBS} )
 
 if( EXTENSION_360_VIDEO )
   target_link_libraries( ${EXE_NAME} Lib360 AppEncHelper360 )
diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp
index 67be5dd88..70e980d75 100644
--- a/source/App/EncoderApp/EncApp.cpp
+++ b/source/App/EncoderApp/EncApp.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -76,7 +76,6 @@ EncApp::~EncApp()
 void EncApp::xInitLibCfg()
 {
   VPS& vps = *m_cEncLib.getVPS();
-#if JVET_S0163_ON_TARGETOLS_SUBLAYERS
   if (m_targetOlsIdx != 500)
   {
     vps.m_targetOlsIdx = m_targetOlsIdx;
@@ -85,9 +84,6 @@ void EncApp::xInitLibCfg()
   {
     vps.m_targetOlsIdx = -1;
   }
-#else
-  vps.m_targetOlsIdx = m_targetOlsIdx;
-#endif
 
   vps.setMaxLayers( m_maxLayers );
 
@@ -128,9 +124,7 @@ void EncApp::xInitLibCfg()
     }
   }
 
-#if JVET_R0193
   m_cfgVPSParameters.m_maxTidILRefPicsPlus1.resize(vps.getMaxLayers(), std::vector<uint32_t>(vps.getMaxLayers(), MAX_TLAYER));
-#endif
   for (int i = 0; i < vps.getMaxLayers(); i++)
   {
     vps.setGeneralLayerIdx( m_layerId[i], i );
@@ -155,7 +149,6 @@ void EncApp::xInitLibCfg()
             vps.setDirectRefLayerFlag(i, j, false);
           }
         }
-#if JVET_R0193
         string::size_type beginStr = m_maxTidILRefPicsPlus1Str[i].find_first_not_of(" ", 0);
         string::size_type endStr = m_maxTidILRefPicsPlus1Str[i].find_first_of(" ", beginStr);
         int t = 0;
@@ -165,7 +158,6 @@ void EncApp::xInitLibCfg()
           beginStr = m_maxTidILRefPicsPlus1Str[i].find_first_not_of(" ", endStr);
           endStr = m_maxTidILRefPicsPlus1Str[i].find_first_of(" ", beginStr);
         }
-#endif
       }
     }
   }
@@ -228,10 +220,19 @@ void EncApp::xInitLibCfg()
   ptls[0].setTierFlag                                            ( m_levelTier );
   ptls[0].setFrameOnlyConstraintFlag                             ( m_frameOnlyConstraintFlag);
   ptls[0].setMultiLayerEnabledFlag                               ( m_multiLayerEnabledFlag);
+#if JVET_W2005_RANGE_EXTENSION_PROFILES
+  CHECK((m_profile == Profile::MAIN_10 || m_profile == Profile::MAIN_10_444 || \
+         m_profile == Profile::MAIN_10_STILL_PICTURE || m_profile == Profile::MAIN_10_444_STILL_PICTURE || \
+         m_profile == Profile::MAIN_12 || m_profile == Profile::MAIN_12_INTRA || m_profile == Profile::MAIN_12_STILL_PICTURE || \
+         m_profile == Profile::MAIN_12_444 || m_profile == Profile::MAIN_12_444_INTRA || m_profile == Profile::MAIN_12_444_STILL_PICTURE || \
+         m_profile == Profile::MAIN_16_444 || m_profile == Profile::MAIN_16_444_INTRA || m_profile == Profile::MAIN_16_444_STILL_PICTURE) \
+          && m_multiLayerEnabledFlag, "ptl_multilayer_enabled_flag shall be equal to 0 for non-multilayer profiles");
+#else
   CHECK((m_profile == Profile::MAIN_10 || m_profile == Profile::MAIN_10_444
          || m_profile == Profile::MAIN_10_STILL_PICTURE || m_profile == Profile::MAIN_10_444_STILL_PICTURE)
           && m_multiLayerEnabledFlag,
         "ptl_multilayer_enabled_flag shall be equal to 0 for non-multilayer profiles");
+#endif
   ptls[0].setNumSubProfile                                       ( m_numSubProfile );
   for (int i = 0; i < m_numSubProfile; i++)
   {
@@ -258,13 +259,14 @@ void EncApp::xInitLibCfg()
   m_cEncLib.setPrintHexPsnr(m_printHexPsnr);
   m_cEncLib.setPrintSequenceMSE                                  ( m_printSequenceMSE);
   m_cEncLib.setPrintMSSSIM                                       ( m_printMSSSIM );
+  m_cEncLib.setPrintWPSNR                                        ( m_printWPSNR );
   m_cEncLib.setCabacZeroWordPaddingEnabled                       ( m_cabacZeroWordPaddingEnabled );
 
   m_cEncLib.setFrameRate                                         ( m_iFrameRate );
   m_cEncLib.setFrameSkip                                         ( m_FrameSkip );
   m_cEncLib.setTemporalSubsampleRatio                            ( m_temporalSubsampleRatio );
-  m_cEncLib.setSourceWidth                                       ( m_iSourceWidth );
-  m_cEncLib.setSourceHeight                                      ( m_iSourceHeight );
+  m_cEncLib.setSourceWidth                                       ( m_sourceWidth );
+  m_cEncLib.setSourceHeight                                      ( m_sourceHeight );
   m_cEncLib.setConformanceWindow                                 ( m_confWinLeft / SPS::getWinUnitX( m_InputChromaFormatIDC ), m_confWinRight / SPS::getWinUnitX( m_InputChromaFormatIDC ), m_confWinTop / SPS::getWinUnitY( m_InputChromaFormatIDC ), m_confWinBottom / SPS::getWinUnitY( m_InputChromaFormatIDC ) );
   m_cEncLib.setScalingRatio                                      ( m_scalingRatioHor, m_scalingRatioVer );
   m_cEncLib.setRprEnabled                                        (m_rprEnabledFlag);
@@ -457,6 +459,13 @@ void EncApp::xInitLibCfg()
     CHECK(m_noVirtualBoundaryConstraintFlag && m_virtualBoundariesEnabledFlag, "Virtuall boundaries shall be deactivated when m_noVirtualBoundaryConstraintFlag is equal to 1");
     m_cEncLib.setNoChromaQpOffsetConstraintFlag(m_noChromaQpOffsetConstraintFlag);
     CHECK(m_noChromaQpOffsetConstraintFlag && m_cuChromaQpOffsetSubdiv, "Chroma Qp offset shall be 0 when m_noChromaQpOffsetConstraintFlag is equal to 1");
+#if JVET_W2005_RANGE_EXTENSION_PROFILES
+    m_cEncLib.setGeneralLowerBitRateConstraintFlag(m_generalLowerBitRateConstraintFlag);
+    if (m_profile == Profile::MAIN_12 || m_profile == Profile::MAIN_12_444 || m_profile == Profile::MAIN_16_444)
+    {
+      CHECK(m_generalLowerBitRateConstraintFlag==0, "generalLowerBitRateConstraintFlag shall be 1 when non-Intra/Still Picture operation range extension profiles are used");
+    }
+#endif
   }
   else
   {
@@ -522,13 +531,24 @@ void EncApp::xInitLibCfg()
     m_cEncLib.setNoActConstraintFlag(false);
     m_cEncLib.setNoLmcsConstraintFlag(false);
     m_cEncLib.setNoChromaQpOffsetConstraintFlag(false);
+#if JVET_W2005_RANGE_EXTENSION_PROFILES
+    m_cEncLib.setGeneralLowerBitRateConstraintFlag(false);
+#endif
   }
 
   //====== Coding Structure ========
   m_cEncLib.setIntraPeriod                                       ( m_iIntraPeriod );
+#if GDR_ENABLED
+  m_cEncLib.setGdrEnabled                                        ( m_gdrEnabled );
+  m_cEncLib.setGdrPeriod                                         ( m_gdrPeriod );
+  m_cEncLib.setGdrPocStart                                       ( m_gdrPocStart );
+  m_cEncLib.setGdrInterval                                       ( m_gdrInterval);
+  m_cEncLib.setGdrNoHash                                         ( m_gdrNoHash );
+#endif
   m_cEncLib.setDecodingRefreshType                               ( m_iDecodingRefreshType );
   m_cEncLib.setGOPSize                                           ( m_iGOPSize );
   m_cEncLib.setDrapPeriod                                        ( m_drapPeriod );
+  m_cEncLib.setEdrapPeriod                                       ( m_edrapPeriod );
   m_cEncLib.setReWriteParamSets                                  ( m_rewriteParamSets );
   m_cEncLib.setRPLList0                                          ( m_RPLList0);
   m_cEncLib.setRPLList1                                          ( m_RPLList1);
@@ -553,9 +573,9 @@ void EncApp::xInitLibCfg()
   m_cEncLib.setIntraQPOffset                                     ( m_intraQPOffset );
   m_cEncLib.setLambdaFromQPEnable                                ( m_lambdaFromQPEnable );
 #endif
-  m_cEncLib.setChromaQpMappingTableParams                         (m_chromaQpMappingTableParams);
+  m_cEncLib.setChromaQpMappingTableParams                        (m_chromaQpMappingTableParams);
 
-  m_cEncLib.setPad                                               ( m_aiPad );
+  m_cEncLib.setSourcePadding                                     ( m_sourcePadding );
 
   m_cEncLib.setAccessUnitDelimiter                               ( m_AccessUnitDelimiter );
   m_cEncLib.setEnablePictureHeaderInSliceHeader                  ( m_enablePictureHeaderInSliceHeader );
@@ -565,14 +585,14 @@ void EncApp::xInitLibCfg()
   //===== Slice ========
 
   //====== Loop/Deblock Filter ========
-  m_cEncLib.setLoopFilterDisable                                 ( m_bLoopFilterDisable       );
-  m_cEncLib.setLoopFilterOffsetInPPS                             ( m_loopFilterOffsetInPPS );
-  m_cEncLib.setLoopFilterBetaOffset                              ( m_loopFilterBetaOffsetDiv2  );
-  m_cEncLib.setLoopFilterTcOffset                                ( m_loopFilterTcOffsetDiv2    );
-  m_cEncLib.setLoopFilterCbBetaOffset                            ( m_loopFilterCbBetaOffsetDiv2  );
-  m_cEncLib.setLoopFilterCbTcOffset                              ( m_loopFilterCbTcOffsetDiv2    );
-  m_cEncLib.setLoopFilterCrBetaOffset                            ( m_loopFilterCrBetaOffsetDiv2  );
-  m_cEncLib.setLoopFilterCrTcOffset                              ( m_loopFilterCrTcOffsetDiv2    );
+  m_cEncLib.setDeblockingFilterDisable                           ( m_deblockingFilterDisable           );
+  m_cEncLib.setDeblockingFilterOffsetInPPS                       ( m_deblockingFilterOffsetInPPS       );
+  m_cEncLib.setDeblockingFilterBetaOffset                        ( m_deblockingFilterBetaOffsetDiv2    );
+  m_cEncLib.setDeblockingFilterTcOffset                          ( m_deblockingFilterTcOffsetDiv2      );
+  m_cEncLib.setDeblockingFilterCbBetaOffset                      ( m_deblockingFilterCbBetaOffsetDiv2  );
+  m_cEncLib.setDeblockingFilterCbTcOffset                        ( m_deblockingFilterCbTcOffsetDiv2    );
+  m_cEncLib.setDeblockingFilterCrBetaOffset                      ( m_deblockingFilterCrBetaOffsetDiv2  );
+  m_cEncLib.setDeblockingFilterCrTcOffset                        ( m_deblockingFilterCrTcOffsetDiv2    );
 #if W0038_DB_OPT
   m_cEncLib.setDeblockingFilterMetric                            ( m_deblockingFilterMetric );
 #else
@@ -593,6 +613,8 @@ void EncApp::xInitLibCfg()
   m_cEncLib.setMaxDeltaQP                                        ( m_iMaxDeltaQP  );
   m_cEncLib.setCuQpDeltaSubdiv                                   ( m_cuQpDeltaSubdiv );
   m_cEncLib.setCuChromaQpOffsetSubdiv                            ( m_cuChromaQpOffsetSubdiv );
+  m_cEncLib.setCuChromaQpOffsetList                              ( m_cuChromaQpOffsetList );
+  m_cEncLib.setCuChromaQpOffsetEnabled                           ( m_cuChromaQpOffsetEnabled );
   m_cEncLib.setChromaCbQpOffset                                  ( m_cbQpOffset     );
   m_cEncLib.setChromaCrQpOffset                                  ( m_crQpOffset  );
   m_cEncLib.setChromaCbQpOffsetDualTree                          ( m_cbQpOffsetDualTree );
@@ -613,6 +635,11 @@ void EncApp::xInitLibCfg()
   m_cEncLib.setUseWPSNR                                          ( m_bUseWPSNR );
 #endif
   m_cEncLib.setExtendedPrecisionProcessingFlag                   ( m_extendedPrecisionProcessingFlag );
+  m_cEncLib.setRrcRiceExtensionEnableFlag                        ( m_rrcRiceExtensionEnableFlag );
+  m_cEncLib.setTSRCRicePresentFlag                               ( m_tsrcRicePresentFlag);
+#if JVET_W0046_RLSCP
+  m_cEncLib.setReverseLastSigCoeffEnabledFlag                    ( m_reverseLastSigCoeffEnabledFlag );
+#endif
   m_cEncLib.setHighPrecisionOffsetsEnabledFlag                   ( m_highPrecisionOffsetsEnabledFlag );
 
   m_cEncLib.setWeightedPredictionMethod( m_weightedPredictionMethod );
@@ -620,6 +647,24 @@ void EncApp::xInitLibCfg()
   //====== Tool list ========
 #if SHARP_LUMA_DELTA_QP
   m_cEncLib.setLumaLevelToDeltaQPControls                        ( m_lumaLevelToDeltaQPMapping );
+#endif
+  m_cEncLib.setSmoothQPReductionEnable                           (m_smoothQPReductionEnable);
+#if JVET_W0043
+  m_cEncLib.setSmoothQPReductionPeriodicity                      (m_smoothQPReductionPeriodicity);
+  m_cEncLib.setSmoothQPReductionThresholdIntra                   (m_smoothQPReductionThresholdIntra);
+  m_cEncLib.setSmoothQPReductionModelScaleIntra                  (m_smoothQPReductionModelScaleIntra);
+  m_cEncLib.setSmoothQPReductionModelOffsetIntra                 (m_smoothQPReductionModelOffsetIntra);
+  m_cEncLib.setSmoothQPReductionLimitIntra                       (m_smoothQPReductionLimitIntra);
+  m_cEncLib.setSmoothQPReductionThresholdInter                   (m_smoothQPReductionThresholdInter);
+  m_cEncLib.setSmoothQPReductionModelScaleInter                  (m_smoothQPReductionModelScaleInter);
+  m_cEncLib.setSmoothQPReductionModelOffsetInter                 (m_smoothQPReductionModelOffsetInter);
+  m_cEncLib.setSmoothQPReductionLimitInter                       (m_smoothQPReductionLimitInter);
+#else
+  m_cEncLib.setSmoothQPReductionThreshold                        (m_smoothQPReductionThreshold);
+  m_cEncLib.setSmoothQPReductionModelScale                       (m_smoothQPReductionModelScale);
+  m_cEncLib.setSmoothQPReductionModelOffset                      (m_smoothQPReductionModelOffset);
+  m_cEncLib.setSmoothQPReductionPeriodicity                      (m_smoothQPReductionPeriodicity);
+  m_cEncLib.setSmoothQPReductionLimit                            (m_smoothQPReductionLimit);
 #endif
 #if X0038_LAMBDA_FROM_QP_CAPABILITY
   m_cEncLib.setDeltaQpRD( (m_costMode==COST_LOSSLESS_CODING) ? 0 : m_uiDeltaQpRD );
@@ -774,6 +819,7 @@ void EncApp::xInitLibCfg()
   m_cEncLib.setUseBDPCM                                          ( m_useBDPCM );
   m_cEncLib.setTransformSkipRotationEnabledFlag                  ( m_transformSkipRotationEnabledFlag );
   m_cEncLib.setTransformSkipContextEnabledFlag                   ( m_transformSkipContextEnabledFlag   );
+  m_cEncLib.setRrcRiceExtensionEnableFlag(m_rrcRiceExtensionEnableFlag);
   m_cEncLib.setPersistentRiceAdaptationEnabledFlag               ( m_persistentRiceAdaptationEnabledFlag );
   m_cEncLib.setCabacBypassAlignmentEnabledFlag                   ( m_cabacBypassAlignmentEnabledFlag );
   m_cEncLib.setLog2MaxTransformSkipBlockSize                     ( m_log2MaxTransformSkipBlockSize  );
@@ -830,6 +876,9 @@ void EncApp::xInitLibCfg()
   //====== Sub-picture and Slices ========
   m_cEncLib.setSingleSlicePerSubPicFlagFlag                      ( m_singleSlicePerSubPicFlag );
   m_cEncLib.setUseSAO                                            ( m_bUseSAO );
+#if JVET_W0129_ENABLE_ALF_TRUEORG
+  m_cEncLib.setSaoTrueOrg                                        ( m_saoTrueOrg );
+#endif
   m_cEncLib.setTestSAODisableAtPictureLevel                      ( m_bTestSAODisableAtPictureLevel );
   m_cEncLib.setSaoEncodingRate                                   ( m_saoEncodingRate );
   m_cEncLib.setSaoEncodingRateChroma                             ( m_saoEncodingRateChroma );
@@ -842,6 +891,7 @@ void EncApp::xInitLibCfg()
   m_cEncLib.setDecodedPictureHashSEIType                         ( m_decodedPictureHashSEIType );
   m_cEncLib.setSubpicDecodedPictureHashType                      ( m_subpicDecodedPictureHashType );
   m_cEncLib.setDependentRAPIndicationSEIEnabled                  ( m_drapPeriod > 0 );
+  m_cEncLib.setEdrapIndicationSEIEnabled                         ( m_edrapPeriod > 0 );
   m_cEncLib.setBufferingPeriodSEIEnabled                         ( m_bufferingPeriodSEIEnabled );
   m_cEncLib.setPictureTimingSEIEnabled                           ( m_pictureTimingSEIEnabled );
   m_cEncLib.setFrameFieldInfoSEIEnabled                          ( m_frameFieldInfoSEIEnabled );
@@ -854,6 +904,10 @@ void EncApp::xInitLibCfg()
   m_cEncLib.setFramePackingArrangementSEIId                      ( m_framePackingSEIId );
   m_cEncLib.setFramePackingArrangementSEIQuincunx                ( m_framePackingSEIQuincunx );
   m_cEncLib.setFramePackingArrangementSEIInterpretation          ( m_framePackingSEIInterpretation );
+  m_cEncLib.setDoSEIEnabled                                      ( m_doSEIEnabled );
+  m_cEncLib.setDoSEICancelFlag                                   ( m_doSEICancelFlag );
+  m_cEncLib.setDoSEIPersistenceFlag                              ( m_doSEIPersistenceFlag);
+  m_cEncLib.setDoSEITransformType                                ( m_doSEITransformType);
   m_cEncLib.setParameterSetsInclusionIndicationSEIEnabled        (m_parameterSetsInclusionIndicationSEIEnabled);
   m_cEncLib.setSelfContainedClvsFlag                             (m_selfContainedClvsFlag);
   m_cEncLib.setErpSEIEnabled                                     ( m_erpSEIEnabled );
@@ -879,6 +933,7 @@ void EncApp::xInitLibCfg()
   m_cEncLib.setOmniViewportSEITiltCentre                         ( m_omniViewportSEITiltCentre );
   m_cEncLib.setOmniViewportSEIHorRange                           ( m_omniViewportSEIHorRange );
   m_cEncLib.setOmniViewportSEIVerRange                           ( m_omniViewportSEIVerRange );
+  m_cEncLib.setAnnotatedRegionSEIFileRoot                        (m_arSEIFileRoot);
   m_cEncLib.setRwpSEIEnabled                                     (m_rwpSEIEnabled);
   m_cEncLib.setRwpSEIRwpCancelFlag                               (m_rwpSEIRwpCancelFlag);
   m_cEncLib.setRwpSEIRwpPersistenceFlag                          (m_rwpSEIRwpPersistenceFlag);
@@ -952,6 +1007,22 @@ void EncApp::xInitLibCfg()
   m_cEncLib.setAmbientViewingEnvironmentSEIIlluminance           (m_aveSEIAmbientIlluminance);
   m_cEncLib.setAmbientViewingEnvironmentSEIAmbientLightX         ((uint16_t)m_aveSEIAmbientLightX);
   m_cEncLib.setAmbientViewingEnvironmentSEIAmbientLightY         ((uint16_t)m_aveSEIAmbientLightY);
+  // colour tranform information sei
+  m_cEncLib.setCtiSEIEnabled(m_ctiSEIEnabled);
+  m_cEncLib.setCtiSEIId(m_ctiSEIId);
+  m_cEncLib.setCtiSEISignalInfoFlag(m_ctiSEISignalInfoFlag);
+  m_cEncLib.setCtiSEIFullRangeFlag(m_ctiSEIFullRangeFlag);
+  m_cEncLib.setCtiSEIPrimaries(m_ctiSEIPrimaries);
+  m_cEncLib.setCtiSEITransferFunction(m_ctiSEITransferFunction);
+  m_cEncLib.setCtiSEIMatrixCoefs(m_ctiSEIMatrixCoefs);
+  m_cEncLib.setCtiSEICrossComponentFlag(m_ctiSEICrossComponentFlag);
+  m_cEncLib.setCtiSEICrossComponentInferred(m_ctiSEICrossComponentInferred);
+  m_cEncLib.setCtiSEINbChromaLut(m_ctiSEINumberChromaLut);
+  m_cEncLib.setCtiSEIChromaOffset(m_ctiSEIChromaOffset);
+  for (int i = 0; i < MAX_NUM_COMPONENT; i++) 
+  {
+    m_cEncLib.setCtiSEILut(m_ctiSEILut[i], i);
+  }
   // content colour volume SEI
   m_cEncLib.setCcvSEIEnabled                                     (m_ccvSEIEnabled);
   m_cEncLib.setCcvSEICancelFlag                                  (m_ccvSEICancelFlag);
@@ -970,6 +1041,71 @@ void EncApp::xInitLibCfg()
   m_cEncLib.setCcvSEIMinLuminanceValue                           (m_ccvSEIMinLuminanceValue);
   m_cEncLib.setCcvSEIMaxLuminanceValue                           (m_ccvSEIMaxLuminanceValue);
   m_cEncLib.setCcvSEIAvgLuminanceValue                           (m_ccvSEIAvgLuminanceValue);
+  // scalability dimension information sei
+  m_cEncLib.setSdiSEIEnabled                                     (m_sdiSEIEnabled);
+  m_cEncLib.setSdiSEIMaxLayersMinus1                             (m_sdiSEIMaxLayersMinus1);
+  m_cEncLib.setSdiSEIMultiviewInfoFlag                           (m_sdiSEIMultiviewInfoFlag);
+  m_cEncLib.setSdiSEIAuxiliaryInfoFlag                           (m_sdiSEIAuxiliaryInfoFlag);
+  m_cEncLib.setSdiSEIViewIdLenMinus1                             (m_sdiSEIViewIdLenMinus1);
+  m_cEncLib.setSdiSEILayerId                                     (m_sdiSEILayerId);
+  m_cEncLib.setSdiSEIViewIdVal                                   (m_sdiSEIViewIdVal);
+  m_cEncLib.setSdiSEIAuxId                                       (m_sdiSEIAuxId);
+  m_cEncLib.setSdiSEINumAssociatedPrimaryLayersMinus1            (m_sdiSEINumAssociatedPrimaryLayersMinus1);
+  // multiview acquisition information sei
+  m_cEncLib.setMaiSEIEnabled                                     (m_maiSEIEnabled);
+  m_cEncLib.setMaiSEIIntrinsicParamFlag                          (m_maiSEIIntrinsicParamFlag);
+  m_cEncLib.setMaiSEIExtrinsicParamFlag                          (m_maiSEIExtrinsicParamFlag);
+  m_cEncLib.setMaiSEINumViewsMinus1                              (m_maiSEINumViewsMinus1);
+  m_cEncLib.setMaiSEIIntrinsicParamsEqualFlag                    (m_maiSEIIntrinsicParamsEqualFlag);
+  m_cEncLib.setMaiSEIPrecFocalLength                             (m_maiSEIPrecFocalLength);
+  m_cEncLib.setMaiSEIPrecPrincipalPoint                          (m_maiSEIPrecPrincipalPoint);
+  m_cEncLib.setMaiSEIPrecSkewFactor                              (m_maiSEIPrecSkewFactor);
+  m_cEncLib.setMaiSEISignFocalLengthX                            (m_maiSEISignFocalLengthX);
+  m_cEncLib.setMaiSEIExponentFocalLengthX                        (m_maiSEIExponentFocalLengthX);
+  m_cEncLib.setMaiSEIMantissaFocalLengthX                        (m_maiSEIMantissaFocalLengthX);
+  m_cEncLib.setMaiSEISignFocalLengthY                            (m_maiSEISignFocalLengthY);
+  m_cEncLib.setMaiSEIExponentFocalLengthY                        (m_maiSEIExponentFocalLengthY);
+  m_cEncLib.setMaiSEIMantissaFocalLengthY                        (m_maiSEIMantissaFocalLengthY);
+  m_cEncLib.setMaiSEISignPrincipalPointX                         (m_maiSEISignPrincipalPointX);
+  m_cEncLib.setMaiSEIExponentPrincipalPointX                     (m_maiSEIExponentPrincipalPointX);
+  m_cEncLib.setMaiSEIMantissaPrincipalPointX                     (m_maiSEIMantissaPrincipalPointX);
+  m_cEncLib.setMaiSEISignPrincipalPointY                         (m_maiSEISignPrincipalPointY);
+  m_cEncLib.setMaiSEIExponentPrincipalPointY                     (m_maiSEIExponentPrincipalPointY);
+  m_cEncLib.setMaiSEIMantissaPrincipalPointY                     (m_maiSEIMantissaPrincipalPointY);
+  m_cEncLib.setMaiSEISignSkewFactor                              (m_maiSEISignSkewFactor);
+  m_cEncLib.setMaiSEIExponentSkewFactor                          (m_maiSEIExponentSkewFactor);
+  m_cEncLib.setMaiSEIMantissaSkewFactor                          (m_maiSEIMantissaSkewFactor);
+  m_cEncLib.setMaiSEIPrecRotationParam                           (m_maiSEIPrecRotationParam);
+  m_cEncLib.setMaiSEIPrecTranslationParam                        (m_maiSEIPrecTranslationParam);
+#if JVET_W0078_MVP_SEI 
+  m_cEncLib.setMvpSEIEnabled(m_mvpSEIEnabled);
+  m_cEncLib.setMvpSEINumViewsMinus1(m_mvpSEINumViewsMinus1);
+  m_cEncLib.setMvpSEIViewPosition(m_mvpSEIViewPosition);
+#endif
+  // alpha channel information sei
+  m_cEncLib.setAciSEIEnabled                                     (m_aciSEIEnabled);
+  m_cEncLib.setAciSEICancelFlag                                  (m_aciSEICancelFlag);
+  m_cEncLib.setAciSEIUseIdc                                      (m_aciSEIUseIdc);
+  m_cEncLib.setAciSEIBitDepthMinus8                              (m_aciSEIBitDepthMinus8);
+  m_cEncLib.setAciSEITransparentValue                            (m_aciSEITransparentValue);
+  m_cEncLib.setAciSEIOpaqueValue                                 (m_aciSEIOpaqueValue);
+  m_cEncLib.setAciSEIIncrFlag                                    (m_aciSEIIncrFlag);
+  m_cEncLib.setAciSEIClipFlag                                    (m_aciSEIClipFlag);
+  m_cEncLib.setAciSEIClipTypeFlag                                (m_aciSEIClipTypeFlag);
+  // depth representation information sei
+  m_cEncLib.setDriSEIEnabled                                     (m_driSEIEnabled);
+  m_cEncLib.setDriSEIZNearFlag                                   (m_driSEIZNearFlag);
+  m_cEncLib.setDriSEIZFarFlag                                    (m_driSEIZFarFlag);
+  m_cEncLib.setDriSEIDMinFlag                                    (m_driSEIDMinFlag);
+  m_cEncLib.setDriSEIDMaxFlag                                    (m_driSEIDMaxFlag);
+  m_cEncLib.setDriSEIZNear                                       (m_driSEIZNear);
+  m_cEncLib.setDriSEIZFar                                        (m_driSEIZFar);
+  m_cEncLib.setDriSEIDMin                                        (m_driSEIDMin);
+  m_cEncLib.setDriSEIDMax                                        (m_driSEIDMax);
+  m_cEncLib.setDriSEIDepthRepresentationType                     (m_driSEIDepthRepresentationType);
+  m_cEncLib.setDriSEIDisparityRefViewId                          (m_driSEIDisparityRefViewId);
+  m_cEncLib.setDriSEINonlinearNumMinus1                          (m_driSEINonlinearNumMinus1);
+  m_cEncLib.setDriSEINonlinearModel                              (m_driSEINonlinearModel);
   m_cEncLib.setEntropyCodingSyncEnabledFlag                      ( m_entropyCodingSyncEnabledFlag );
   m_cEncLib.setEntryPointPresentFlag                             ( m_entryPointPresentFlag );
   m_cEncLib.setTMVPModeId                                        ( m_TMVPModeId );
@@ -990,6 +1126,11 @@ void EncApp::xInitLibCfg()
   {
     m_cEncLib.setScalingMatrixDesignatedColourSpace(m_scalingMatrixDesignatedColourSpace);
   }
+#if JVET_W0133_CONSTRAINED_RASL_ENCODING
+  m_cEncLib.setConstrainedRaslencoding                           ( m_constrainedRaslEncoding );
+  m_cEncLib.setCraAPSreset                                       ( m_craAPSreset );
+  m_cEncLib.setRprRASLtoolSwitch                                 ( m_rprRASLtoolSwitch );
+#endif
   m_cEncLib.setDepQuantEnabledFlag                               ( m_depQuantEnabledFlag);
   m_cEncLib.setSignDataHidingEnabledFlag                         ( m_signDataHidingEnabledFlag);
   m_cEncLib.setUseRateCtrl                                       ( m_RCEnableRateControl );
@@ -1027,8 +1168,9 @@ void EncApp::xInitLibCfg()
   m_cEncLib.setOverscanInfoPresentFlag                           ( m_overscanInfoPresentFlag );
   m_cEncLib.setOverscanAppropriateFlag                           ( m_overscanAppropriateFlag );
   m_cEncLib.setVideoFullRangeFlag                                ( m_videoFullRangeFlag );
-  m_cEncLib.setEfficientFieldIRAPEnabled                         ( m_bEfficientFieldIRAPEnabled );
-  m_cEncLib.setHarmonizeGopFirstFieldCoupleEnabled               ( m_bHarmonizeGopFirstFieldCoupleEnabled );
+  m_cEncLib.setFieldSeqFlag                                      ( m_isField );
+  m_cEncLib.setEfficientFieldIRAPEnabled                         ( m_efficientFieldIRAPEnabled );
+  m_cEncLib.setHarmonizeGopFirstFieldCoupleEnabled               ( m_harmonizeGopFirstFieldCoupleEnabled );
   m_cEncLib.setSummaryOutFilename                                ( m_summaryOutFilename );
   m_cEncLib.setSummaryPicFilenameBase                            ( m_summaryPicFilenameBase );
   m_cEncLib.setSummaryVerboseness                                ( m_summaryVerboseness );
@@ -1043,16 +1185,19 @@ void EncApp::xInitLibCfg()
   m_cEncLib.setStopAfterFFtoPOC                                  ( m_stopAfterFFtoPOC );
   m_cEncLib.setBs2ModPOCAndType                                  ( m_bs2ModPOCAndType );
   m_cEncLib.setDebugCTU                                          ( m_debugCTU );
-#if ENABLE_SPLIT_PARALLELISM
-  m_cEncLib.setNumSplitThreads                                   ( m_numSplitThreads );
-  m_cEncLib.setForceSingleSplitThread                            ( m_forceSplitSequential );
-#endif
   m_cEncLib.setUseALF                                            ( m_alf );
-#if JVET_T0064
-  m_cEncLib.setALFStrength                                       (m_alfStrength);
+#if JVET_W0129_ENABLE_ALF_TRUEORG
+  m_cEncLib.setAlfTrueOrg                                        ( m_alfTrueOrg );
+#else
+  m_cEncLib.setAlfSaoTrueOrg                                     ( m_alfSaoTrueOrg );
+#endif
+  m_cEncLib.setALFStrengthLuma                                   (m_alfStrengthLuma);
   m_cEncLib.setCCALFStrength                                     (m_ccalfStrength);
   m_cEncLib.setALFAllowPredefinedFilters                         (m_alfAllowPredefinedFilters);
-#endif
+  m_cEncLib.setALFStrengthChroma                                 (m_alfStrengthChroma);
+  m_cEncLib.setALFStrengthTargetLuma                             (m_alfStrengthTargetLuma);
+  m_cEncLib.setALFStrengthTargetChroma                           (m_alfStrengthTargetChroma);
+  m_cEncLib.setCCALFStrengthTarget                               (m_ccalfStrengthTarget);
   m_cEncLib.setUseCCALF                                          ( m_ccalf );
   m_cEncLib.setCCALFQpThreshold                                  ( m_ccalfQpThreshold );
   m_cEncLib.setLmcs                                              ( m_lmcsEnabled );
@@ -1081,7 +1226,6 @@ void EncApp::xInitLibCfg()
   m_cEncLib.setCropOffsetBottom                                  (m_cropOffsetBottom);
   m_cEncLib.setCalculateHdrMetrics                               (m_calculateHdrMetrics);
 #endif
-#if JVET_S0163_ON_TARGETOLS_SUBLAYERS
   m_cEncLib.setOPIEnabled                                         ( m_OPIEnabled );
   if (m_OPIEnabled)
   {
@@ -1094,7 +1238,6 @@ void EncApp::xInitLibCfg()
       m_cEncLib.setTargetOlsIdx                                   (m_targetOlsIdx);
     }
   }
-#endif
   m_cEncLib.setGopBasedTemporalFilterEnabled(m_gopBasedTemporalFilterEnabled);
   m_cEncLib.setNumRefLayers                                       ( m_numRefLayers );
 
@@ -1108,18 +1251,18 @@ void EncApp::xCreateLib( std::list<PelUnitBuf*>& recBufList, const int layerId )
 #if EXTENSION_360_VIDEO
   m_cVideoIOYuvInputFile.skipFrames(m_FrameSkip, m_inputFileWidth, m_inputFileHeight, m_InputChromaFormatIDC);
 #else
-  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);
+  const int sourceHeight = m_isField ? m_iSourceHeightOrg : m_sourceHeight;
+  m_cVideoIOYuvInputFile.skipFrames(m_FrameSkip, m_sourceWidth - m_sourcePadding[0], sourceHeight - m_sourcePadding[1], m_InputChromaFormatIDC);
 #endif
   if (!m_reconFileName.empty())
   {
     if (m_packedYUVMode && ((m_outputBitDepth[CH_L] != 10 && m_outputBitDepth[CH_L] != 12)
-        || ((m_iSourceWidth & (1 + (m_outputBitDepth[CH_L] & 3))) != 0)))
+        || ((m_sourceWidth & (1 + (m_outputBitDepth[CH_L] & 3))) != 0)))
     {
       EXIT ("Invalid output bit-depth or image width for packed YUV output, aborting\n");
     }
     if (m_packedYUVMode && (m_chromaFormatIDC != CHROMA_400) && ((m_outputBitDepth[CH_C] != 10 && m_outputBitDepth[CH_C] != 12)
-        || (((m_iSourceWidth / SPS::getWinUnitX (m_chromaFormatIDC)) & (1 + (m_outputBitDepth[CH_C] & 3))) != 0)))
+        || (((m_sourceWidth / SPS::getWinUnitX (m_chromaFormatIDC)) & (1 + (m_outputBitDepth[CH_C] & 3))) != 0)))
     {
       EXIT ("Invalid chroma output bit-depth or image width for packed YUV output, aborting\n");
     }
@@ -1160,9 +1303,9 @@ void EncApp::xDestroyLib()
   m_cEncLib.destroy();
 }
 
-void EncApp::xInitLib(bool isFieldCoding)
+void EncApp::xInitLib()
 {
-  m_cEncLib.init(isFieldCoding, this );
+  m_cEncLib.init(this);
 }
 
 // ====================================================================================================================
@@ -1171,8 +1314,8 @@ void EncApp::xInitLib(bool isFieldCoding)
 
 void EncApp::createLib( const int layerIdx )
 {
-  const int sourceHeight = m_isField ? m_iSourceHeightOrg : m_iSourceHeight;
-  UnitArea unitArea( m_chromaFormatIDC, Area( 0, 0, m_iSourceWidth, sourceHeight ) );
+  const int sourceHeight = m_isField ? m_iSourceHeightOrg : m_sourceHeight;
+  UnitArea unitArea( m_chromaFormatIDC, Area( 0, 0, m_sourceWidth, sourceHeight ) );
 
   m_orgPic = new PelStorage;
   m_trueOrgPic = new PelStorage;
@@ -1197,7 +1340,7 @@ void EncApp::createLib( const int layerIdx )
   xInitLibCfg();
   const int layerId = m_cEncLib.getVPS() == nullptr ? 0 : m_cEncLib.getVPS()->getLayerId( layerIdx );
   xCreateLib( m_recBufList, layerId );
-  xInitLib( m_isField );
+  xInitLib();
 
   printChromaFormat();
 
@@ -1207,8 +1350,8 @@ void EncApp::createLib( const int layerIdx )
 
   if( m_gopBasedTemporalFilterEnabled )
   {
-    m_temporalFilter.init( m_FrameSkip, m_inputBitDepth, m_MSBExtendedBitDepth, m_internalBitDepth, m_iSourceWidth, m_iSourceHeight,
-      m_aiPad, m_bClipInputVideoToRec709Range, m_inputFileName, m_chromaFormatIDC,
+    m_temporalFilter.init( m_FrameSkip, m_inputBitDepth, m_MSBExtendedBitDepth, m_internalBitDepth, m_sourceWidth, sourceHeight,
+      m_sourcePadding, m_bClipInputVideoToRec709Range, m_inputFileName, m_chromaFormatIDC,
       m_inputColourSpaceConvert, m_iQP, m_gopBasedTemporalFilterStrengths,
       m_gopBasedTemporalFilterFutureReference );
   }
@@ -1266,10 +1409,10 @@ bool EncApp::encodePrep( bool& eos )
   }
   else
   {
-    m_cVideoIOYuvInputFile.read( *m_orgPic, *m_trueOrgPic, ipCSC, m_aiPad, m_InputChromaFormatIDC, m_bClipInputVideoToRec709Range );
+    m_cVideoIOYuvInputFile.read( *m_orgPic, *m_trueOrgPic, ipCSC, m_sourcePadding, m_InputChromaFormatIDC, m_bClipInputVideoToRec709Range );
   }
 #else
-  m_cVideoIOYuvInputFile.read( *m_orgPic, *m_trueOrgPic, ipCSC, m_aiPad, m_InputChromaFormatIDC, m_bClipInputVideoToRec709Range );
+  m_cVideoIOYuvInputFile.read( *m_orgPic, *m_trueOrgPic, ipCSC, m_sourcePadding, m_InputChromaFormatIDC, m_bClipInputVideoToRec709Range );
 #endif
 
   if( m_gopBasedTemporalFilterEnabled )
@@ -1340,8 +1483,8 @@ bool EncApp::encode()
 #if EXTENSION_360_VIDEO
       m_cVideoIOYuvInputFile.skipFrames( m_temporalSubsampleRatio - 1, m_inputFileWidth, m_inputFileHeight, m_InputChromaFormatIDC );
 #else
-    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 );
+    const int sourceHeight = m_isField ? m_iSourceHeightOrg : m_sourceHeight;
+    m_cVideoIOYuvInputFile.skipFrames( m_temporalSubsampleRatio - 1, m_sourceWidth - m_sourcePadding[0], sourceHeight - m_sourcePadding[1], m_InputChromaFormatIDC );
 #endif
     }
   }
@@ -1440,9 +1583,7 @@ void EncApp::rateStatsAccum(const AccessUnit& au, const std::vector<uint32_t>& a
     case NAL_UNIT_CODED_SLICE_GDR:
     case NAL_UNIT_CODED_SLICE_RADL:
     case NAL_UNIT_CODED_SLICE_RASL:
-#if JVET_S0163_ON_TARGETOLS_SUBLAYERS
     case NAL_UNIT_OPI:
-#endif
     case NAL_UNIT_DCI:
     case NAL_UNIT_VPS:
     case NAL_UNIT_SPS:
diff --git a/source/App/EncoderApp/EncApp.h b/source/App/EncoderApp/EncApp.h
index 0efa6935e..93323155c 100644
--- a/source/App/EncoderApp/EncApp.h
+++ b/source/App/EncoderApp/EncApp.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -83,7 +83,7 @@ private:
   // initialization
   void xCreateLib( std::list<PelUnitBuf*>& recBufList, const int layerId );         ///< create files & encoder class
   void xInitLibCfg ();                           ///< initialize internal variables
-  void xInitLib    (bool isFieldCoding);         ///< initialize encoder class
+  void xInitLib();                               ///< initialize encoder class
   void xDestroyLib ();                           ///< destroy encoder class
 
   // file I/O
diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp
index b38001ebc..b7d50a7e5 100644
--- a/source/App/EncoderApp/EncAppCfg.cpp
+++ b/source/App/EncoderApp/EncAppCfg.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -69,6 +69,17 @@ enum ExtendedProfileName   // this is used for determining profile strings, wher
   MULTILAYER_MAIN_10_STILL_PICTURE,
   MULTILAYER_MAIN_10_444,
   MULTILAYER_MAIN_10_444_STILL_PICTURE,
+#if JVET_W2005_RANGE_EXTENSION_PROFILES
+  MAIN_12,
+  MAIN_12_444,
+  MAIN_16_444,
+  MAIN_12_INTRA,
+  MAIN_12_444_INTRA,
+  MAIN_16_444_INTRA,
+  MAIN_12_STILL_PICTURE,
+  MAIN_12_444_STILL_PICTURE,
+  MAIN_16_444_STILL_PICTURE,
+#endif
   AUTO = -1
 };
 
@@ -100,6 +111,7 @@ EncAppCfg::~EncAppCfg()
 
 #if ENABLE_TRACING
   tracing_uninit(g_trace_ctx);
+  g_trace_ctx = nullptr;
 #endif
 }
 
@@ -178,6 +190,17 @@ static const struct MapStrToProfile
   { "multilayer_main_10_444", Profile::MULTILAYER_MAIN_10_444 },
   { "multilayer_main_10_still_picture", Profile::MULTILAYER_MAIN_10_STILL_PICTURE },
   { "multilayer_main_10_444_still_picture", Profile::MULTILAYER_MAIN_10_444_STILL_PICTURE },
+#if JVET_W2005_RANGE_EXTENSION_PROFILES
+  { "main_12", Profile::MAIN_12 },
+  { "main_12_444", Profile::MAIN_12_444 },
+  { "main_16_444", Profile::MAIN_16_444 },
+  { "main_12_intra", Profile::MAIN_12_INTRA },
+  { "main_12_444_intra", Profile::MAIN_12_444_INTRA },
+  { "main_16_444_intra", Profile::MAIN_16_444_INTRA },
+  { "main_12_still_picture", Profile::MAIN_12_STILL_PICTURE },
+  { "main_12_444_still_picture", Profile::MAIN_12_444_STILL_PICTURE },
+  { "main_16_444_still_picture", Profile::MAIN_16_444_STILL_PICTURE },
+#endif
 };
 
 static const struct MapStrToExtendedProfile
@@ -194,6 +217,17 @@ static const struct MapStrToExtendedProfile
   { "multilayer_main_10_444", MULTILAYER_MAIN_10_444 },
   { "multilayer_main_10_still_picture", MULTILAYER_MAIN_10_STILL_PICTURE },
   { "multilayer_main_10_444_still_picture", MULTILAYER_MAIN_10_444_STILL_PICTURE },
+#if JVET_W2005_RANGE_EXTENSION_PROFILES
+  { "main_12", MAIN_12 },
+  { "main_12_444", MAIN_12_444 },
+  { "main_16_444", MAIN_16_444 },
+  { "main_12_intra", MAIN_12_INTRA },
+  { "main_12_444_intra", MAIN_12_444_INTRA },
+  { "main_16_444_intra", MAIN_16_444_INTRA },
+  { "main_12_still_picture", MAIN_12_STILL_PICTURE },
+  { "main_12_444_still_picture", MAIN_12_444_STILL_PICTURE },
+  { "main_16_444_still_picture", MAIN_16_444_STILL_PICTURE },
+#endif
   { "auto", AUTO },
 };
 
@@ -229,9 +263,7 @@ strToLevel[] =
   {"6",   Level::LEVEL6},
   {"6.1", Level::LEVEL6_1},
   {"6.2", Level::LEVEL6_2},
-#if JVET_T0065_LEVEL_6_3
   {"6.3", Level::LEVEL6_3},
-#endif
   {"15.5", Level::LEVEL15_5},
 };
 
@@ -338,6 +370,8 @@ static inline istream& operator >> (istream &in, ScalingListMode &mode)
 template <class T>
 struct SMultiValueInput
 {
+  static_assert(!std::is_same<T, uint8_t>::value, "SMultiValueInput<uint8_t> is not supported");
+  static_assert(!std::is_same<T, int8_t>::value, "SMultiValueInput<int8_t> is not supported");
   const T              minValIncl;
   const T              maxValIncl;
   const std::size_t    minNumValuesIncl;
@@ -487,16 +521,11 @@ static uint32_t getMaxTileColsByLevel( Level::Name level )
     case Level::LEVEL6:
     case Level::LEVEL6_1:
     case Level::LEVEL6_2:
-#if !JVET_T0065_LEVEL_6_3
-    default:
-#endif
       return 20;
-#if JVET_T0065_LEVEL_6_3
     case Level::LEVEL6_3:
       return 30;
     default:
       return MAX_TILE_COLS;
-#endif
   }
 }
 
@@ -522,16 +551,11 @@ static uint32_t getMaxTileRowsByLevel( Level::Name level )
     case Level::LEVEL6:
     case Level::LEVEL6_1:
     case Level::LEVEL6_2:
-#if !JVET_T0065_LEVEL_6_3
-    default:
-#endif
       return 22;
-#if JVET_T0065_LEVEL_6_3
     case Level::LEVEL6_3:
       return 33;
     default:
       return MAX_TILES / MAX_TILE_COLS;
-#endif
   }
 }
 
@@ -558,16 +582,11 @@ static uint32_t getMaxSlicesByLevel( Level::Name level )
     case Level::LEVEL6:
     case Level::LEVEL6_1:
     case Level::LEVEL6_2:
-#if !JVET_T0065_LEVEL_6_3
-    default:
-#endif
       return 600;
-#if JVET_T0065_LEVEL_6_3
     case Level::LEVEL6_3:
       return 1000;
     default:
       return MAX_SLICES;
-#endif
   }
 }
 
@@ -623,15 +642,30 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
   SMultiValueInput<int> cfg_qpOutValCr                  (MIN_QP_VALUE_FOR_16_BIT, MAX_QP, 0, MAX_NUM_QP_VALUES, zeroVector, 1);
   SMultiValueInput<int> cfg_qpInValCbCr                 (MIN_QP_VALUE_FOR_16_BIT, MAX_QP, 0, MAX_NUM_QP_VALUES, zeroVector, 1);
   SMultiValueInput<int> cfg_qpOutValCbCr                (MIN_QP_VALUE_FOR_16_BIT, MAX_QP, 0, MAX_NUM_QP_VALUES, zeroVector, 1);
+  const int cQpOffsets[] = { 6 };
+  SMultiValueInput<int> cfg_cbQpOffsetList              (-12, 12, 0, 6, cQpOffsets, 0);
+  SMultiValueInput<int> cfg_crQpOffsetList              (-12, 12, 0, 6, cQpOffsets, 0);
+  SMultiValueInput<int> cfg_cbCrQpOffsetList            (-12, 12, 0, 6, cQpOffsets, 0);
+
   const uint32_t defaultInputKneeCodes[3]  = { 600, 800, 900 };
   const uint32_t defaultOutputKneeCodes[3] = { 100, 250, 450 };
   SMultiValueInput<uint32_t> cfg_kneeSEIInputKneePointValue      (1,  999, 0, 999, defaultInputKneeCodes,  sizeof(defaultInputKneeCodes )/sizeof(uint32_t));
   SMultiValueInput<uint32_t> cfg_kneeSEIOutputKneePointValue     (0, 1000, 0, 999, defaultOutputKneeCodes, sizeof(defaultOutputKneeCodes)/sizeof(uint32_t));
   const int defaultPrimaryCodes[6]     = { 0,50000, 0,0, 50000,0 };
   const int defaultWhitePointCode[2]   = { 16667, 16667 };
+
   SMultiValueInput<int>  cfg_DisplayPrimariesCode            (0, 50000, 6, 6, defaultPrimaryCodes,   sizeof(defaultPrimaryCodes  )/sizeof(int));
   SMultiValueInput<int>  cfg_DisplayWhitePointCode           (0, 50000, 2, 2, defaultWhitePointCode, sizeof(defaultWhitePointCode)/sizeof(int));
 
+#if RExt__HIGH_BIT_DEPTH_SUPPORT
+  SMultiValueInput<Pel>  cfg_SEICTILut0(0, ((1 << (2 + 16 - 1)) - 1), 0, MAX_CTI_LUT_SIZE + 1);
+  SMultiValueInput<Pel>  cfg_SEICTILut1(0, ((1 << (2 + 16 - 1)) - 1), 0, MAX_CTI_LUT_SIZE + 1);
+  SMultiValueInput<Pel>  cfg_SEICTILut2(0, ((1 << (2 + 16 - 1)) - 1), 0, MAX_CTI_LUT_SIZE + 1);
+#else
+  SMultiValueInput<Pel>  cfg_SEICTILut0(0, ((1 << (2 + 12 - 1)) - 1), 0, MAX_CTI_LUT_SIZE + 1);
+  SMultiValueInput<Pel>  cfg_SEICTILut1(0, ((1 << (2 + 12 - 1)) - 1), 0, MAX_CTI_LUT_SIZE + 1);
+  SMultiValueInput<Pel>  cfg_SEICTILut2(0, ((1 << (2 + 12 - 1)) - 1), 0, MAX_CTI_LUT_SIZE + 1);
+#endif
   SMultiValueInput<bool> cfg_timeCodeSeiTimeStampFlag        (0,  1, 0, MAX_TIMECODE_SEI_SETS);
   SMultiValueInput<bool> cfg_timeCodeSeiNumUnitFieldBasedFlag(0,  1, 0, MAX_TIMECODE_SEI_SETS);
   SMultiValueInput<int>  cfg_timeCodeSeiCountingType         (0,  6, 0, MAX_TIMECODE_SEI_SETS);
@@ -674,6 +708,30 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
   SMultiValueInput<uint32_t>   cfg_gcmpSEIFunctionUAffectedByVFlag   (0, 1, 5, 6);
   SMultiValueInput<double>     cfg_gcmpSEIFunctionCoeffV             (0.0, 1.0, 5, 6);
   SMultiValueInput<uint32_t>   cfg_gcmpSEIFunctionVAffectedByUFlag   (0, 1, 5, 6);
+  SMultiValueInput<uint32_t>        cfg_sdiSEILayerId                  (0, 63, 0, 63);
+  SMultiValueInput<uint32_t>        cfg_sdiSEIViewIdVal                (0, 63, 0, std::numeric_limits<uint32_t>::max());
+  SMultiValueInput<uint32_t>        cfg_sdiSEIAuxId                    (0, 255, 0, 63);
+  SMultiValueInput<uint32_t>        cfg_sdiSEINumAssociatedPrimaryLayersMinus1 (0, 63, 0, 63);
+  SMultiValueInput<bool>            cfg_maiSEISignFocalLengthX         (0, 1,   0, std::numeric_limits<uint32_t>::max());
+  SMultiValueInput<uint32_t>        cfg_maiSEIExponentFocalLengthX     (0, 63, 0, std::numeric_limits<uint32_t>::max());
+  SMultiValueInput<uint32_t>        cfg_maiSEIMantissaFocalLengthX     (0, std::numeric_limits<uint32_t>::max(), 0, std::numeric_limits<uint32_t>::max());
+  SMultiValueInput<bool>            cfg_maiSEISignFocalLengthY         (0, 1,   0, std::numeric_limits<uint32_t>::max());
+  SMultiValueInput<uint32_t>        cfg_maiSEIExponentFocalLengthY     (0, 63, 0, std::numeric_limits<uint32_t>::max());
+  SMultiValueInput<uint32_t>        cfg_maiSEIMantissaFocalLengthY     (0, std::numeric_limits<uint32_t>::max(), 0, std::numeric_limits<uint32_t>::max());
+  SMultiValueInput<bool>            cfg_maiSEISignPrincipalPointX      (0, 1,   0, std::numeric_limits<uint32_t>::max());
+  SMultiValueInput<uint32_t>        cfg_maiSEIExponentPrincipalPointX  (0, 63, 0, std::numeric_limits<uint32_t>::max());
+  SMultiValueInput<uint32_t>        cfg_maiSEIMantissaPrincipalPointX  (0, std::numeric_limits<uint32_t>::max(), 0, std::numeric_limits<uint32_t>::max());
+  SMultiValueInput<bool>            cfg_maiSEISignPrincipalPointY      (0, 1,   0, std::numeric_limits<uint32_t>::max());
+  SMultiValueInput<uint32_t>        cfg_maiSEIExponentPrincipalPointY  (0, 63, 0, std::numeric_limits<uint32_t>::max());
+  SMultiValueInput<uint32_t>        cfg_maiSEIMantissaPrincipalPointY  (0, std::numeric_limits<uint32_t>::max(), 0, std::numeric_limits<uint32_t>::max());
+  SMultiValueInput<bool>            cfg_maiSEISignSkewFactor           (0, 1,   0, std::numeric_limits<uint32_t>::max());
+  SMultiValueInput<uint32_t>        cfg_maiSEIExponentSkewFactor       (0, 63, 0, std::numeric_limits<uint32_t>::max());
+  SMultiValueInput<uint32_t>        cfg_maiSEIMantissaSkewFactor       (0, std::numeric_limits<uint32_t>::max(), 0, std::numeric_limits<uint32_t>::max());
+#if JVET_W0078_MVP_SEI 
+  SMultiValueInput<uint32_t>        cfg_mvpSEIViewPosition             (0, 63, 0, std::numeric_limits<uint32_t>::max());
+#endif
+
+  SMultiValueInput<uint32_t>        cfg_driSEINonlinearModel           (0, 31, 0, std::numeric_limits<uint32_t>::max());
 #if LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET
   const int defaultLadfQpOffset[3] = { 1, 0, 1 };
   const int defaultLadfIntervalLowerBound[2] = { 350, 833 };
@@ -683,7 +741,8 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
   SMultiValueInput<unsigned> cfg_virtualBoundariesPosX       (0, std::numeric_limits<uint32_t>::max(), 0, 3);
   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());
+  SMultiValueInput<uint32_t>  cfg_SubProfile(0, std::numeric_limits<uint8_t>::max(), 0,
+                                            std::numeric_limits<uint8_t>::max());
   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);
@@ -692,8 +751,8 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
   SMultiValueInput<bool>      cfg_loopFilterAcrossSubpicEnabledFlag(0, 1, 0, MAX_NUM_SUB_PICS);
   SMultiValueInput<uint32_t>  cfg_subPicId(0, std::numeric_limits<uint16_t>::max(), 0, MAX_NUM_SUB_PICS);
 
-  SMultiValueInput<int>       cfg_sliFractions(0, 100, 0, std::numeric_limits<int>::max());
-  SMultiValueInput<int>       cfg_sliNonSubpicLayersFractions(0, 100, 0, std::numeric_limits<int>::max());
+  SMultiValueInput<int>       cfg_sliFractions(0, 255, 0, std::numeric_limits<int>::max());
+  SMultiValueInput<int>       cfg_sliNonSubpicLayersFractions(0, 255, 0, std::numeric_limits<int>::max());
 
   SMultiValueInput<Level::Name>  cfg_sliRefLevels(Level::NONE, Level::LEVEL15_5, 0, 8 * MAX_VPS_SUBLAYERS);
 
@@ -725,8 +784,8 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
   ("InputPathPrefix,-ipp",                            inputPathPrefix,                             string(""), "pathname to prepend to input filename")
   ("BitstreamFile,b",                                 m_bitstreamFileName,                         string(""), "Bitstream output file name")
   ("ReconFile,o",                                     m_reconFileName,                             string(""), "Reconstructed YUV output file name")
-  ("SourceWidth,-wdt",                                m_iSourceWidth,                                       0, "Source picture width")
-  ("SourceHeight,-hgt",                               m_iSourceHeight,                                      0, "Source picture height")
+  ("SourceWidth,-wdt",                                m_sourceWidth,                                       0, "Source picture width")
+  ("SourceHeight,-hgt",                               m_sourceHeight,                                      0, "Source picture height")
   ("InputBitDepth",                                   m_inputBitDepth[CHANNEL_TYPE_LUMA],                   8, "Bit-depth of input file")
   ("OutputBitDepth",                                  m_outputBitDepth[CHANNEL_TYPE_LUMA],                  0, "Bit-depth of output file (default:InternalBitDepth)")
   ("MSBExtendedBitDepth",                             m_MSBExtendedBitDepth[CHANNEL_TYPE_LUMA],             0, "bit depth of luma component after addition of MSBs of value 0 (used for synthesising High Dynamic Range source material). (default:InputBitDepth)")
@@ -735,6 +794,10 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
   ("OutputBitDepthC",                                 m_outputBitDepth[CHANNEL_TYPE_CHROMA],                0, "As per OutputBitDepth but for chroma component. (default: use luma output bit-depth)")
   ("MSBExtendedBitDepthC",                            m_MSBExtendedBitDepth[CHANNEL_TYPE_CHROMA],           0, "As per MSBExtendedBitDepth but for chroma component. (default:MSBExtendedBitDepth)")
   ("ExtendedPrecision",                               m_extendedPrecisionProcessingFlag,                false, "Increased internal accuracies to support high bit depths (not valid in V1 profiles)")
+  ("TSRCRicePresent",                                 m_tsrcRicePresentFlag,                            false, "Indicate that TSRC Rice information is present in slice header (not valid in V1 profiles)")
+#if JVET_W0046_RLSCP
+  ("ReverseLastSigCoeff",                             m_reverseLastSigCoeffEnabledFlag,                 false, "enable reverse last significant coefficient postion in RRC (not valid in V1 profiles)")  
+#endif
   ("HighPrecisionPredictionWeighting",                m_highPrecisionOffsetsEnabledFlag,                false, "Use high precision option for weighted prediction (not valid in V1 profiles)")
   ("InputColourSpaceConvert",                         inputColourSpaceConvert,                     string(""), "Colour space conversion to apply to input video. Permitted values are (empty string=UNCHANGED) " + getListOfColourSpaceConverts(true))
   ("SNRInternalColourSpace",                          m_snrInternalColourSpace,                         false, "If true, then no colour space conversion is applied prior to SNR, otherwise inverse of input is applied.")
@@ -745,16 +808,12 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
   ("PrintFrameMSE",                                   m_printFrameMSE,                                  false, "0 (default) emit only bit count and PSNRs for each frame, 1 = also emit MSE values")
   ("PrintSequenceMSE",                                m_printSequenceMSE,                               false, "0 (default) emit only bit rate and PSNRs for the whole sequence, 1 = also emit MSE values")
   ("PrintMSSSIM",                                     m_printMSSSIM,                                    false, "0 (default) do not print MS-SSIM scores, 1 = print MS-SSIM scores for each frame and for the whole sequence")
+  ("PrintWPSNR",                                      m_printWPSNR,                                     false, "0 (default) do not print HDR-PQ based wPSNR, 1 = print HDR-PQ based wPSNR")
   ("CabacZeroWordPaddingEnabled",                     m_cabacZeroWordPaddingEnabled,                     true, "0 do not add conforming cabac-zero-words to bit streams, 1 (default) = add cabac-zero-words as required")
   ("ChromaFormatIDC,-cf",                             tmpChromaFormat,                                      0, "ChromaFormatIDC (400|420|422|444 or set 0 (default) for same as InputChromaFormat)")
-  ("ConformanceMode",                                 m_conformanceWindowMode,                              0, "Deprecated alias of ConformanceWindowMode")
-  ("ConformanceWindowMode",                           m_conformanceWindowMode,                              0, "Window conformance mode (0: no window, 1:automatic padding, 2:padding, 3:conformance")
-  ("HorizontalPadding,-pdx",                          m_aiPad[0],                                           0, "Horizontal source padding for conformance window mode 2")
-  ("VerticalPadding,-pdy",                            m_aiPad[1],                                           0, "Vertical source padding for conformance window mode 2")
-  ("ConfLeft",                                        m_confWinLeft,                                        0, "Deprecated alias of ConfWinLeft")
-  ("ConfRight",                                       m_confWinRight,                                       0, "Deprecated alias of ConfWinRight")
-  ("ConfTop",                                         m_confWinTop,                                         0, "Deprecated alias of ConfWinTop")
-  ("ConfBottom",                                      m_confWinBottom,                                      0, "Deprecated alias of ConfWinBottom")
+  ("ConformanceWindowMode",                           m_conformanceWindowMode,                              1, "Window conformance mode (0: no window, 1:automatic padding (default), 2:padding parameters specified, 3:conformance window parameters specified")
+  ("HorizontalPadding,-pdx",                          m_sourcePadding[0],                                   0, "Horizontal source padding for conformance window mode 2")
+  ("VerticalPadding,-pdy",                            m_sourcePadding[1],                                   0, "Vertical source padding for conformance window mode 2")
   ("ConfWinLeft",                                     m_confWinLeft,                                        0, "Left offset for window conformance mode 3")
   ("ConfWinRight",                                    m_confWinRight,                                       0, "Right offset for window conformance mode 3")
   ("ConfWinTop",                                      m_confWinTop,                                         0, "Top offset for window conformance mode 3")
@@ -793,8 +852,8 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
   //Field coding parameters
   ("FieldCoding",                                     m_isField,                                        false, "Signals if it's a field based coding")
   ("TopFieldFirst, Tff",                              m_isTopFieldFirst,                                false, "In case of field based coding, signals whether if it's a top field first or not")
-  ("EfficientFieldIRAPEnabled",                       m_bEfficientFieldIRAPEnabled,                      true, "Enable to code fields in a specific, potentially more efficient, order.")
-  ("HarmonizeGopFirstFieldCoupleEnabled",             m_bHarmonizeGopFirstFieldCoupleEnabled,            true, "Enables harmonization of Gop first field couple")
+  ("EfficientFieldIRAPEnabled",                       m_efficientFieldIRAPEnabled,                      true, "Enable to code fields in a specific, potentially more efficient, order.")
+  ("HarmonizeGopFirstFieldCoupleEnabled",             m_harmonizeGopFirstFieldCoupleEnabled,            true, "Enables harmonization of Gop first field couple")
 
   // Profile and level
   ("Profile",                                         extendedProfile,              ExtendedProfileName::NONE, "Profile name to use for encoding. Use [multilayer_]main_10[_444][_still_picture], auto, or none")
@@ -873,6 +932,9 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
   ("NoLmcsConstraintFlag",                            m_noLmcsConstraintFlag,                           false, "Indicate that LMCS is deactivated")
   ("NoLadfConstraintFlag",                            m_noLadfConstraintFlag,                          false, "Indicate that LADF is deactivated")
   ("NoVirtualBoundaryConstraintFlag",                 m_noVirtualBoundaryConstraintFlag,                false, "Indicate that virtual boundary is deactivated")
+#if JVET_W2005_RANGE_EXTENSION_PROFILES
+  ("GeneralLowerBitRateConstraintFlag",               m_generalLowerBitRateConstraintFlag,              false, "Indicate whether lower bitrate constraint is used")
+#endif
 
   ("CTUSize",                                         m_uiCTUSize,                                       128u, "CTUSize (specifies the CTU size if QTBT is on) [default: 128]")
   ("Log2MinCuSize",                                   m_log2MinCuSize,                                     2u, "Log2 min CU size")
@@ -1012,9 +1074,17 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
 
   // Coding structure paramters
   ("IntraPeriod,-ip",                                 m_iIntraPeriod,                                      -1, "Intra period in frames, (-1: only first frame)")
+#if GDR_ENABLED
+  ("GdrEnabled",                                      m_gdrEnabled,                                     false, "GDR enabled")
+  ("GdrPocStart",                                     m_gdrPocStart,                                       -1, "GDR poc start")
+  ("GdrPeriod",                                       m_gdrPeriod,                                         -1, "Number of frames between GDR picture to the next GDR picture")
+  ("GdrInterval",                                     m_gdrInterval,                                       -1, "Number of frames from GDR picture to the recovery point picture")
+  ("GdrNoHash",                                       m_gdrNoHash,                                       true, "Do not generate decode picture hash SEI messages for GDR and recovering pictures")
+#endif
   ("DecodingRefreshType,-dr",                         m_iDecodingRefreshType,                               0, "Intra refresh type (0:none 1:CRA 2:IDR 3:RecPointSEI)")
   ("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)")
+  ("EDRAPPeriod",                                     m_edrapPeriod,                                        0, "EDRAP period in frames (0: disable Extended Dependent RAP indication SEI messages)")
   ("ReWriteParamSets",                                m_rewriteParamSets,                           false, "Enable rewriting of Parameter sets before every (intra) random access point")
   ("IDRRefParamList",                                 m_idrRefParamList,                            false, "Enable indication of reference picture list syntax elements in slice headers of IDR pictures")
   // motion search options
@@ -1056,7 +1126,8 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
   ("DeltaQpRD,-dqr",                                  m_uiDeltaQpRD,                                       0u, "max dQp offset for slice")
   ("MaxDeltaQP,d",                                    m_iMaxDeltaQP,                                        0, "max dQp offset for block")
   ("MaxCuDQPSubdiv,-dqd",                             m_cuQpDeltaSubdiv,                                    0, "Maximum subdiv for CU luma Qp adjustment")
-  ("MaxCuChromaQpOffsetSubdiv",                       m_cuChromaQpOffsetSubdiv,                            -1, "Maximum subdiv for CU chroma Qp adjustment - set less than 0 to disable")
+  ("MaxCuChromaQpOffsetSubdiv",                       m_cuChromaQpOffsetSubdiv,                             0, "Maximum subdiv for CU chroma Qp adjustment")
+  ("SliceCuChromaQpOffsetEnabled",                    m_cuChromaQpOffsetEnabled,                         true, "Enable local chroma QP offsets (slice level flag)")
   ("FastDeltaQP",                                     m_bFastDeltaQP,                                   false, "Fast Delta QP Algorithm")
 #if SHARP_LUMA_DELTA_QP
   ("LumaLevelToDeltaQPMode",                          lumaLevelToDeltaQPMode,                              0u, "Luma based Delta QP 0(default): not used. 1: Based on CTU average, 2: Based on Max luma in CTU")
@@ -1066,7 +1137,25 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
   ("LumaLevelToDeltaQPMappingLuma",                   cfg_lumaLeveltoDQPMappingLuma,  cfg_lumaLeveltoDQPMappingLuma, "Luma to Delta QP Mapping - luma thresholds")
   ("LumaLevelToDeltaQPMappingDQP",                    cfg_lumaLeveltoDQPMappingQP,  cfg_lumaLeveltoDQPMappingQP, "Luma to Delta QP Mapping - DQP values")
 #endif
-  ("UseIdentityTableForNon420Chroma",                 m_useIdentityTableForNon420Chroma,                 true, "True: Indicates that 422/444 chroma uses identity chroma QP mapping tables; False: explicit Qp table may be specified in config")
+  ("SmoothQPReductionEnable",                         m_smoothQPReductionEnable,                         false, "Enable QP reduction for smooth blocks according to: Clip3(SmoothQPReductionLimit, 0, SmoothQPReductionModelScale*baseQP+SmoothQPReductionModelOffset)")
+#if JVET_W0043
+  ("SmoothQPReductionPeriodicity",                    m_smoothQPReductionPeriodicity,                        0, "Periodicity parameter of the QP reduction model, 1: all frames, 0: only intra pictures, 2: every second frame, etc")
+  ("SmoothQPReductionThresholdIntra",                 m_smoothQPReductionThresholdIntra,                   3.0, "Threshold parameter for smoothness for intra pictures (SmoothQPReductionThresholdIntra * number of samples in block)")
+  ("SmoothQPReductionModelScaleIntra",                m_smoothQPReductionModelScaleIntra,                 -1.0, "Scale parameter of the QP reduction model for intra pictures ")
+  ("SmoothQPReductionModelOffsetIntra",               m_smoothQPReductionModelOffsetIntra,                27.0, "Offset parameter of the QP reduction model for intra pictures ")
+  ("SmoothQPReductionLimitIntra",                     m_smoothQPReductionLimitIntra,                       -16, "Threshold parameter for controlling maximum amount of QP reduction by the QP reduction model for intra pictures ")
+  ("SmoothQPReductionThresholdInter",                 m_smoothQPReductionThresholdInter,                   3.0, "Threshold parameter for smoothness for inter pictures (SmoothQPReductionThresholdInter * number of samples in block)")
+  ("SmoothQPReductionModelScaleInter",                m_smoothQPReductionModelScaleInter,                 -1.0, "Scale parameter of the QP reduction model for inter pictures")
+  ("SmoothQPReductionModelOffsetInter",               m_smoothQPReductionModelOffsetInter,                27.0, "Offset parameter of the QP reduction model for inter pictures")
+  ("SmoothQPReductionLimitInter",                     m_smoothQPReductionLimitInter,                        -4, "Threshold parameter for controlling maximum amount of QP reduction by the QP reduction model for inter pictures")
+#else
+  ("SmoothQPReductionThreshold",                      m_smoothQPReductionThreshold,                        3.0, "Threshold parameter for smoothness (SmoothQPReductionThreshold * number of samples in block)")
+  ("SmoothQPReductionModelScale",                     m_smoothQPReductionModelScale,                      -1.0, "Scale parameter of the QP reduction model")
+  ("SmoothQPReductionModelOffset",                    m_smoothQPReductionModelOffset,                     27.0, "Offset parameter of the QP reduction model")
+  ("SmoothQPReductionLimit",                          m_smoothQPReductionLimit,                            -16, "Threshold parameter for controlling maximum amount of QP reduction by the QP reduction model")
+  ("SmoothQPReductionPeriodicity",                    m_smoothQPReductionPeriodicity,                        1, "Periodicity parameter of the QP reduction model, 1: all frames, 0: only intra pictures, 2: every second frame, etc")
+#endif
+  ("UseIdentityTableForNon420Chroma",                 m_useIdentityTableForNon420Chroma,                  true, "True: Indicates that 422/444 chroma uses identity chroma QP mapping tables; False: explicit Qp table may be specified in config")
   ("SameCQPTablesForAllChroma",                       m_chromaQpMappingTableParams.m_sameCQPTableForAllChromaFlag,                        true, "0: Different tables for Cb, Cr and joint Cb-Cr components, 1 (default): Same tables for all three chroma components")
   ("QpInValCb",                                       cfg_qpInValCb,                            cfg_qpInValCb, "Input coordinates for the QP table for Cb component")
   ("QpOutValCb",                                      cfg_qpOutValCb,                          cfg_qpOutValCb, "Output coordinates for the QP table for Cb component")
@@ -1092,6 +1181,9 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
   ("SliceCbQpOffsetIntraOrPeriodic",                  m_sliceChromaQpOffsetIntraOrPeriodic[0],              0, "Chroma Cb QP Offset at slice level for I slice or for periodic inter slices as defined by SliceChromaQPOffsetPeriodicity. Replaces offset in the GOP table.")
   ("SliceCrQpOffsetIntraOrPeriodic",                  m_sliceChromaQpOffsetIntraOrPeriodic[1],              0, "Chroma Cr QP Offset at slice level for I slice or for periodic inter slices as defined by SliceChromaQPOffsetPeriodicity. Replaces offset in the GOP table.")
 #endif
+  ("CbQpOffsetList",                                  cfg_cbQpOffsetList,                  cfg_cbQpOffsetList, "Chroma Cb QP offset list for local adjustment")
+  ("CrQpOffsetList",                                  cfg_crQpOffsetList,                  cfg_crQpOffsetList, "Chroma Cb QP offset list for local adjustment")
+  ("CbCrQpOffsetList",                                cfg_cbCrQpOffsetList,              cfg_cbCrQpOffsetList, "Chroma joint Cb-Cr QP offset list for local adjustment")
 
   ("AdaptiveQP,-aq",                                  m_bUseAdaptiveQP,                                 false, "QP adaptation based on a psycho-visual model")
   ("MaxQPAdaptationRange,-aqr",                       m_iQPAdaptationRange,                                 6, "QP adaptation range")
@@ -1108,14 +1200,14 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
   ("RDpenalty",                                       m_rdPenalty,                                          0, "RD-penalty for 32x32 TU for intra in non-intra slices. 0:disabled  1:RD-penalty  2:maximum RD-penalty")
 
   // Deblocking filter parameters
-  ("LoopFilterDisable",                               m_bLoopFilterDisable,                             false)
-  ("LoopFilterOffsetInPPS",                           m_loopFilterOffsetInPPS,                           true)
-  ("LoopFilterBetaOffset_div2",                       m_loopFilterBetaOffsetDiv2,                           0)
-  ("LoopFilterTcOffset_div2",                         m_loopFilterTcOffsetDiv2,                             0)
-  ("LoopFilterCbBetaOffset_div2",                     m_loopFilterCbBetaOffsetDiv2,                         0)
-  ("LoopFilterCbTcOffset_div2",                       m_loopFilterCbTcOffsetDiv2,                           0)
-  ("LoopFilterCrBetaOffset_div2",                     m_loopFilterCrBetaOffsetDiv2,                         0)
-  ("LoopFilterCrTcOffset_div2",                       m_loopFilterCrTcOffsetDiv2,                           0)
+  ("DeblockingFilterDisable",                         m_deblockingFilterDisable,                        false)
+  ("DeblockingFilterOffsetInPPS",                     m_deblockingFilterOffsetInPPS,                     true)
+  ("DeblockingFilterBetaOffset_div2",                 m_deblockingFilterBetaOffsetDiv2,                     0)
+  ("DeblockingFilterTcOffset_div2",                   m_deblockingFilterTcOffsetDiv2,                       0)
+  ("DeblockingFilterCbBetaOffset_div2",               m_deblockingFilterCbBetaOffsetDiv2,                   0)
+  ("DeblockingFilterCbTcOffset_div2",                 m_deblockingFilterCbTcOffsetDiv2,                     0)
+  ("DeblockingFilterCrBetaOffset_div2",               m_deblockingFilterCrBetaOffsetDiv2,                   0)
+  ("DeblockingFilterCrTcOffset_div2",                 m_deblockingFilterCrTcOffsetDiv2,                     0)
 #if W0038_DB_OPT
   ("DeblockingFilterMetric",                          m_deblockingFilterMetric,                             0)
 #else
@@ -1131,9 +1223,13 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
   ("ISPFast",                                         m_useFastISP,                                     false, "Fast encoder search for ISP")
   ("ResidualRotation",                                m_transformSkipRotationEnabledFlag,               false, "Enable rotation of transform-skipped and transquant-bypassed TUs through 180 degrees prior to entropy coding (not valid in V1 profiles)")
   ("SingleSignificanceMapContext",                    m_transformSkipContextEnabledFlag,                false, "Enable, for transform-skipped and transquant-bypassed TUs, the selection of a single significance map context variable for all coefficients (not valid in V1 profiles)")
+  ("ExtendedRiceRRC",                                 m_rrcRiceExtensionEnableFlag,                     false, "Enable the extention of the Golomb-Rice parameter derivation for RRC")
   ("GolombRiceParameterAdaptation",                   m_persistentRiceAdaptationEnabledFlag,            false, "Enable the adaptation of the Golomb-Rice parameter over the course of each slice")
   ("AlignCABACBeforeBypass",                          m_cabacBypassAlignmentEnabledFlag,                false, "Align the CABAC engine to a defined fraction of a bit prior to coding bypass data. Must be 1 in high bit rate profile, 0 otherwise")
   ("SAO",                                             m_bUseSAO,                                         true, "Enable Sample Adaptive Offset")
+#if JVET_W0129_ENABLE_ALF_TRUEORG
+  ("SaoTrueOrg",                                      m_saoTrueOrg,                                     false, "Using true original samples for SAO optimization when MCTF is enabled\n")
+#endif
   ("TestSAODisableAtPictureLevel",                    m_bTestSAODisableAtPictureLevel,                  false, "Enables the testing of disabling SAO at the picture level after having analysed all blocks")
   ("SaoEncodingRate",                                 m_saoEncodingRate,                                 0.75, "When >0 SAO early picture termination is enabled for luma and chroma")
   ("SaoEncodingRateChroma",                           m_saoEncodingRateChroma,                            0.5, "The SAO early picture termination rate to use for chroma (when m_SaoEncodingRate is >0). If <=0, use results for luma")
@@ -1249,6 +1345,10 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
                                                                                                                "\t0: unspecified\n"
                                                                                                                "\t1: stereo pair, frame0 represents left view\n"
                                                                                                                "\t2: stereo pair, frame0 represents right view")
+  ("SEIDisplayOrientationEnabled",                    m_doSEIEnabled,                                   false, "Controls if display orientation packing SEI message enabled")
+  ("SEIDisplayOrientationCancelFlag",                 m_doSEICancelFlag,                                 true, "Specifies the persistence of any previous display orientation SEI message in output order.")
+  ("SEIDisplayOrientationPersistenceFlag",            m_doSEIPersistenceFlag,                           false, "Specifies the persistence of the display orientation packing SEI message for the current layer.")
+  ("SEIDisplayOrientationTransformType",              m_doSEITransformType,                                 0, "specifies the rotation and mirroring to be applied to the picture.")
   ("SEIParameterSetsInclusionIndication",             m_parameterSetsInclusionIndicationSEIEnabled,      false, "Control generation of Parameter sets inclusion indication SEI messages")
   ("SEISelfContainedClvsFlag",                        m_selfContainedClvsFlag,                               0, "Self contained CLVS indication flag value")
   ("SEIMasteringDisplayColourVolume",                 m_masteringDisplay.colourVolumeSEIEnabled,         false, "Control generation of mastering display colour volume SEI messages")
@@ -1327,6 +1427,7 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
   ("SEISubpicLevelInfoRefLevels",                     cfg_sliRefLevels,                                  cfg_sliRefLevels, "List of reference levels for Subpicture Level Information SEI messages")
   ("SEISubpicLevelInfoExplicitFraction",              m_cfgSubpictureLevelInfoSEI.m_explicitFraction,    false,            "Enable sending of explicit fractions in Subpicture Level Information SEI messages")
   ("SEISubpicLevelInfoNumSubpics",                    m_cfgSubpictureLevelInfoSEI.m_numSubpictures,      1,                "Number of subpictures for Subpicture Level Information SEI messages")
+  ("SEIAnnotatedRegionsFileRoot,-ar",                 m_arSEIFileRoot,                                 string(""), "Annotated region SEI parameters root file name (wo num ext); only the file name base is to be added. Underscore and POC would be automatically addded to . E.g. \"-ar ar\" will search for files ar_0.txt, ar_1.txt, ...")
   ("SEISubpicLevelInfoMaxSublayers",                  m_cfgSubpictureLevelInfoSEI.m_sliMaxSublayers,               1,                    "Number of sublayers for Subpicture Level Information SEI messages")
   ("SEISubpicLevelInfoSublayerInfoPresentFlag",       m_cfgSubpictureLevelInfoSEI.m_sliSublayerInfoPresentFlag,    false,                "Enable sending of level information for all sublayers in Subpicture Level Information SEI messages")
   ("SEISubpicLevelInfoRefLevelFractions",             cfg_sliFractions,                                  cfg_sliFractions, "List of subpicture level fractions for Subpicture Level Information SEI messages")
@@ -1368,6 +1469,21 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
   ("SEIAVEAmbientIlluminance",                        m_aveSEIAmbientIlluminance,                      100000u, "Specifies the environmental illluminance of the ambient viewing environment in units of 1/10000 lux for the ambient viewing environment SEI message")
   ("SEIAVEAmbientLightX",                             m_aveSEIAmbientLightX,                            15635u, "Specifies the normalized x chromaticity coordinate of the environmental ambient light in the nominal viewing enviornment according to the CIE 1931 definition in units of 1/50000 lux for the ambient viewing enviornment SEI message")
   ("SEIAVEAmbientLightY",                             m_aveSEIAmbientLightY,                            16450u, "Specifies the normalized y chromaticity coordinate of the environmental ambient light in the nominal viewing enviornment according to the CIE 1931 definition in units of 1/50000 lux for the ambient viewing enviornment SEI message")
+// colour tranform information SEI
+  ("SEICTIEnabled",                                   m_ctiSEIEnabled,                                   false, "Control generation of the Colour transform information SEI message")
+  ("SEICTIId",                                        m_ctiSEIId,                                           0u, "Id of the Colour transform information SEI message")
+  ("SEICTISignalInfoFlag",                            m_ctiSEISignalInfoFlag,                            false, "indicates if signal information are present in the Colour transform information SEI message")
+  ("SEICTIFullRangeFlag",                             m_ctiSEIFullRangeFlag,                             false, "specifies signal range after applying the Colour transform information SEI message")
+  ("SEICTIPrimaries",                                 m_ctiSEIPrimaries,                                    0u, "indicates the signal primaries after applying the Colour transform information SEI message")
+  ("SEICTITransferFunction",                          m_ctiSEITransferFunction,                             0u, "indicates the signal transfer function after applying the Colour transform information SEI message")
+  ("SEICTIMatrixCoefs",                               m_ctiSEIMatrixCoefs,                                  0u, "indicates the signal matrix coefficients after applying the Colour transform information SEI message")
+  ("SEICTICrossCompFlag",                             m_ctiSEICrossComponentFlag,                         true, "Specifies if cross-component transform mode is enabled in SEI CTI")
+  ("SEICTICrossCompInferred",                         m_ctiSEICrossComponentInferred,                     true, "Specifies if cross-component transform LUT is inferred in SEI CTI")
+  ("SEICTINbChromaLut",                               m_ctiSEINumberChromaLut,                              0u, "Specifies the number of chroma LUTs in SEI CTI")
+  ("SEICTIChromaOffset",                              m_ctiSEIChromaOffset,                                  0, "Specifies the chroma offset of SEI CTI")
+  ("SEICTILut0",                                      cfg_SEICTILut0,                           cfg_SEICTILut0, "slope values for component 0 of SEI CTI")
+  ("SEICTILut1",                                      cfg_SEICTILut1,                           cfg_SEICTILut1, "slope values for component 1 of SEI CTI")
+  ("SEICTILut2",                                      cfg_SEICTILut2,                           cfg_SEICTILut2, "slope values for component 2 of SEI CTI")
 // content colour volume SEI
   ("SEICCVEnabled",                                   m_ccvSEIEnabled,                                   false, "Control generation of the Content Colour Volume SEI message")
   ("SEICCVCancelFlag",                                m_ccvSEICancelFlag,                                 true, "Specifies the persistence of any previous content colour volume SEI message in output order.")
@@ -1385,7 +1501,76 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
   ("SEICCVMaxLuminanceValue",                         m_ccvSEIMaxLuminanceValue,                           0.1, "specifies the CCV max luminance value  in the content colour volume SEI message")
   ("SEICCVAvgLuminanceValuePresent",                  m_ccvSEIAvgLuminanceValuePresentFlag,               true, "Specifies whether the CCV avg luminance value is present in the content colour volume SEI message")
   ("SEICCVAvgLuminanceValue",                         m_ccvSEIAvgLuminanceValue,                          0.01, "specifies the CCV avg luminance value  in the content colour volume SEI message")
-
+  // scalability dimension information SEI
+  ("SEISDIEnabled",                                   m_sdiSEIEnabled,                          false, "Control generation of scalaibility dimension information SEI message")
+  ("SEISDIMaxLayersMinus1",                           m_sdiSEIMaxLayersMinus1,                      0, "Specifies the maximum number of layers minus 1 in the current CVS")
+  ("SEISDIMultiviewInfoFlag",                         m_sdiSEIMultiviewInfoFlag,                false, "Specifies the current CVS may have multiple views and the sdi_view_id_val[ ] syntax elements are present in the scalaibility dimension information SEI message")
+  ("SEISDIAuxiliaryInfoFlag",                         m_sdiSEIAuxiliaryInfoFlag,                false, "Specifies that one or more layers in the current CVS may be auxiliary layers, which carry auxiliary information, and the sdi_aux_id[ ] syntax elements are present in the scalaibility dimension information SEI message")
+  ("SEISDIViewIdLenMinus1",                           m_sdiSEIViewIdLenMinus1,                      0, "Specifies the length, in bits, of the sdi_view_id_val[ i ] syntax element minus 1 in the scalaibility dimension information SEI message")
+  ("SEISDILayerId",                                   cfg_sdiSEILayerId,            cfg_sdiSEILayerId, "List of the layer identifiers that may be present in the scalaibility dimension information SEI message in the current CVS")
+  ("SEISDIViewIdVal",                                 cfg_sdiSEIViewIdVal,        cfg_sdiSEIViewIdVal, "List of the view identifiers in the scalaibility dimension information SEI message")
+  ("SEISDIAuxId",                                     cfg_sdiSEIAuxId,                cfg_sdiSEIAuxId, "List of the auxiliary identifiers in the scalaibility dimension information SEI message")
+  ("SEISDINumAssociatedPrimaryLayersMinus1",          cfg_sdiSEINumAssociatedPrimaryLayersMinus1, cfg_sdiSEINumAssociatedPrimaryLayersMinus1, "List of the numbers of associated primary layers of i-th layer, which is an auxiliary layer.")
+  // multiview acquisition information SEI
+  ("SEIMAIEnabled",                                   m_maiSEIEnabled,                                    false, "Control generation of multiview acquisition information SEI message")
+  ("SEIMAIIntrinsicParamFlag",                        m_maiSEIIntrinsicParamFlag,                         false, "Specifies the presence of intrinsic camera parameters in the multiview acquisition information SEI message")
+  ("SEIMAIExtrinsicParamFlag",                        m_maiSEIExtrinsicParamFlag,                         false, "Specifies the presence of extrinsic camera parameters in the multiview acquisition information SEI message")
+  ("SEIMAINumViewsMinus1",                            m_maiSEINumViewsMinus1,                                 0, "Specifies the number of views minus 1 in the multiview acquisition information SEI message")
+  ("SEIMAIIntrinsicParamsEqualFlag",                  m_maiSEIIntrinsicParamsEqualFlag,                   false, "Specifies the intrinsic camera parameters are equal for all cameras in the multiview acquisition information SEI message")
+  ("SEIMAIPrecFocalLength",                           m_maiSEIPrecFocalLength,                                0, "Specifies the exponent of the maximum allowable truncation error for focal_length_x[i] and focal_length_y[i] in the multiview acquisition information SEI message")
+  ("SEIMAIPrecPrincipalPoint",                        m_maiSEIPrecPrincipalPoint,                             0, "Specifies the exponent of the maximum allowable truncation error for principal_point_x[i] and principal_point_y[i] in the multiview acquisition information SEI message")
+  ("SEIMAIPrecSkewFactor",                            m_maiSEIPrecSkewFactor,                                 0, "Specifies the exponent of the maximum allowable truncation error for skew factor in the multiview acquisition information SEI message")
+  ("SEIMAISignFocalLengthX",                          cfg_maiSEISignFocalLengthX,    cfg_maiSEISignFocalLengthX, "List of the signs of the focal length of the camera in the horizontal direction in the multiview acquisition information SEI message")
+  ("SEIMAIExponentFocalLengthX",                      cfg_maiSEIExponentFocalLengthX, cfg_maiSEIExponentFocalLengthX, "List of the exponent parts of the focal length of the camera in the horizontal direction. in the multiview acquisition information SEI message")
+  ("SEIMAIMantissaFocalLengthX",                      cfg_maiSEIMantissaFocalLengthX, cfg_maiSEIMantissaFocalLengthX, "List of the mantissa parts of the focal length of the camera in the horizontal direction in the multiview acquisition information SEI message")
+  ("SEIMAISignFocalLengthY",                          cfg_maiSEISignFocalLengthY,    cfg_maiSEISignFocalLengthY, "List of the signs of the focal length of the camera in the vertical direction in the multiview acquisition information SEI message")
+  ("SEIMAIExponentFocalLengthY",                      cfg_maiSEIExponentFocalLengthY, cfg_maiSEIExponentFocalLengthY, "List of the exponent parts of the focal length of the camera in the vertical direction in the multiview acquisition information SEI message")
+  ("SEIMAIMantissaFocalLengthY",                      cfg_maiSEIMantissaFocalLengthY, cfg_maiSEIMantissaFocalLengthY, "List of the mantissa parts of the focal length of the camera in the vertical direction in the multiview acquisition information SEI message")
+  ("SEIMAISignPrincipalPointX",                       cfg_maiSEISignPrincipalPointX, cfg_maiSEISignPrincipalPointX, "List of the signs of the principal point of the camera in the horizontal direction in the multiview acquisition information SEI message")
+  ("SEIMAIExponentPrincipalPointX",                   cfg_maiSEIExponentPrincipalPointX, cfg_maiSEIExponentPrincipalPointX, "List of the exponent parts of the principal point of the camera in the horizontal direction in the multiview acquisition information SEI message")
+  ("SEIMAIMantissaPrincipalPointX",                   cfg_maiSEIMantissaPrincipalPointX, cfg_maiSEIMantissaPrincipalPointX, "List of the mantissa parts of the principal point of the camera in the horizontal direction in the multiview acquisition information SEI message")
+  ("SEIMAISignPrincipalPointY",                       cfg_maiSEISignPrincipalPointY, cfg_maiSEISignPrincipalPointY, "List of the signs of the principal point of the camera in the vertical direction in the multiview acquisition information SEI message")
+  ("SEIMAIExponentPrincipalPointY",                   cfg_maiSEIExponentPrincipalPointY, cfg_maiSEIExponentPrincipalPointY, "List of the exponent parts of the principal point of the camera in the vertical direction in the multiview acquisition information SEI message")
+  ("SEIMAIMantissaPrincipalPointY",                   cfg_maiSEIMantissaPrincipalPointY, cfg_maiSEIMantissaPrincipalPointY, "List of the mantissa parts of the principal point of the camera in the vertical direction in the multiview acquisition information SEI message")
+  ("SEIMAISignSkewFactor",                            cfg_maiSEISignSkewFactor,     cfg_maiSEISignSkewFactor, "List of the signs of the skew factor of the camera in the multiview acquisition information SEI message")
+  ("SEIMAIExponentSkewFactor",                        cfg_maiSEIExponentSkewFactor, cfg_maiSEIExponentSkewFactor, "List of the exponent parts of the skew factor of the camera in the multiview acquisition information SEI message")
+  ("SEIMAIMantissaSkewFactor",                        cfg_maiSEIMantissaSkewFactor, cfg_maiSEIMantissaSkewFactor, "List of the mantissa parts of the skew factor of the camera in the multiview acquisition information SEI message")
+  ("SEIMAIPrecRotationParam",                         m_maiSEIPrecRotationParam,                            0, "Specifies the exponent of the maximum allowable truncation error for rotation in the multiview acquisition information SEI message")
+  ("SEIMAIPrecTranslationParam",                      m_maiSEIPrecTranslationParam,                         0, "Specifies the exponent of the maximum allowable truncation error for translation in the multiview acquisition information SEI message")
+#if JVET_W0078_MVP_SEI 
+// multiview view position SEI
+  ("SEIMVPEnabled",                                   m_mvpSEIEnabled,                                  false, "Control generation of multiview view position SEI message")
+  ("SEIMVPNumViewsMinus1",                            m_mvpSEINumViewsMinus1,                               0, "Specifies the number of views minus 1 in the multiview view postion SEI message")
+  ("SEIMVPViewPosition",                              cfg_mvpSEIViewPosition,           cfg_mvpSEIViewPosition, "List of View Positions in the multiview view postion SEI message")
+#endif
+// alpha channel information SEI
+  ("SEIACIEnabled",                                   m_aciSEIEnabled,                                   false, "Control generation of alpha channel information SEI message")
+  ("SEIACICancelFlag",                                m_aciSEICancelFlag,                                false, "Specifies the persistence of any previous alpha channel information SEI message in output order")
+  ("SEIACIUseIdc",                                    m_aciSEIUseIdc,                                        0, "Specifies the usage of the auxiliary picture in the alpha channel information SEI message")
+  ("SEIACIBitDepthMinus8",                            m_aciSEIBitDepthMinus8,                                0, "Specifies the bit depth of the samples of the auxiliary picture in the alpha channel information SEI message")
+  ("SEIACITransparentValue",                          m_aciSEITransparentValue,                              0, "Specifies the interpretation sample value of an auxiliary coded picture luma sample for which the associated luma and chroma samples of the primary coded picture are considered transparent for purposes of alpha blending in the alpha channel information SEI message")
+  ("SEIACIOpaqueValue",                               m_aciSEIOpaqueValue,                                   0, "Specifies the interpretation sample value of an auxiliary coded picture luma sample for which the associated luma and chroma samples of the primary coded picture are considered opaque for purposes of alpha blending in the alpha channel information SEI message")
+  ("SEIACIIncrFlag",                                  m_aciSEIIncrFlag,                                  false, "Specifies the interpretation sample value for each decoded auxiliary picture luma sample value is equal to the decoded auxiliary picture sample value for purposes of alpha blending in the alpha channel information SEI message")
+  ("SEIACIClipFlag",                                  m_aciSEIClipFlag,                                  false, "Specifies whether clipping operation is applied in the alpha channel information SEI message")
+  ("SEIACIClipTypeFlag",                              m_aciSEIClipTypeFlag,                              false, "Specifies the type of clipping operation in the alpha channel information SEI message")
+  // depth representation information SEI
+  ("SEIDRIEnabled",                                   m_driSEIEnabled,                                   false, "Control generation of depth representation information SEI message")
+  ("SEIDRIZNearFlag",                                 m_driSEIZNearFlag,                                 false, "Specifies the presence of the nearest depth value in the depth representation information SEI message")
+  ("SEIDRIZFarFlag",                                  m_driSEIZFarFlag,                                  false, "Specifies the presence of the farthest depth value in the depth representation information SEI message")
+  ("SEIDRIDMinFlag",                                  m_driSEIDMinFlag,                                  false, "Specifies the presence of the minimum disparity value in the depth representation information SEI message")
+  ("SEIDRIDMaxFlag",                                  m_driSEIDMaxFlag,                                  false, "Specifies the presence of the maximum disparity value in the depth representation information SEI message")
+  ("SEIDRIZNear",                                     m_driSEIZNear,                                       0.0, "Specifies the nearest depth value in the depth representation information SEI message")
+  ("SEIDRIZFar",                                      m_driSEIZFar,                                        0.0, "Specifies the farest depth value in the depth representation information SEI message")
+  ("SEIDRIDMin",                                      m_driSEIDMin,                                        0.0, "Specifies the minimum disparity value in the depth representation information SEI message")
+  ("SEIDRIDMax",                                      m_driSEIDMax,                                        0.0, "Specifies the maximum disparity value in the depth representation information SEI message")
+  ("SEIDRIDepthRepresentationType",                   m_driSEIDepthRepresentationType,                       0, "Specifies the the representation definition of decoded luma samples of auxiliary pictures in the depth representation information SEI message")
+  ("SEIDRIDisparityRefViewId",                        m_driSEIDisparityRefViewId,                            0, "Specifies the ViewId value against which the disparity values are derived in the depth representation information SEI message")
+  ("SEIDRINonlinearNumMinus1",                        m_driSEINonlinearNumMinus1,                            0, "Specifies the number of piece-wise linear segments minus 2 for mapping of depth values to a scale that is uniformly quantized in terms of disparity  in the depth representation information SEI message")
+  ("SEIDRINonlinearModel",                            cfg_driSEINonlinearModel,       cfg_driSEINonlinearModel, "List of the piece-wise linear segments for mapping of decoded luma sample values of an auxiliary picture to a scale that is uniformly quantized in terms of disparity in the depth representation information SEI message")
+#if JVET_W0133_CONSTRAINED_RASL_ENCODING
+  ("SEIConstrainedRASL",                              m_constrainedRaslEncoding,                         false, "Control generation of constrained RASL encoding SEI message")
+#endif
+  
   ("DebugBitstream",                                  m_decodeBitstreams[0],             string( "" ), "Assume the frames up to POC DebugPOC will be the same as in this bitstream. Load those frames from the bitstream instead of encoding them." )
   ("DebugPOC",                                        m_switchPOC,                                 -1, "If DebugBitstream is present, load frames up to this POC from this bitstream. Starting with DebugPOC, return to normal encoding." )
   ("DecodeBitstream1",                                m_decodeBitstreams[0],             string( "" ), "Assume the frames up to POC DebugPOC will be the same as in this bitstream. Load those frames from the bitstream instead of encoding them." )
@@ -1396,18 +1581,21 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
   ("StopAfterFFtoPOC",                                m_stopAfterFFtoPOC,                       false, "If using fast forward to POC, after the POC of interest has been hit, stop further encoding.")
   ("ForceDecodeBitstream1",                           m_forceDecodeBitstream1,                  false, "force decoding of bitstream 1 - use this only if you are realy sure about what you are doing ")
   ("DecodeBitstream2ModPOCAndType",                   m_bs2ModPOCAndType,                       false, "Modify POC and NALU-type of second input bitstream, to use second BS as closing I-slice")
-  ("NumSplitThreads",                                 m_numSplitThreads,                            1, "Number of threads used to parallelize splitting")
-  ("ForceSingleSplitThread",                          m_forceSplitSequential,                   false, "Force single thread execution even if taking the parallelized path")
-  ("NumWppThreads",                                   m_numWppThreads,                              1, "Number of threads used to run WPP-style parallelization")
-  ("NumWppExtraLines",                                m_numWppExtraLines,                           0, "Number of additional wpp lines to switch when threads are blocked")
+
   ("DebugCTU",                                        m_debugCTU,                                  -1, "If DebugBitstream is present, load frames up to this POC from this bitstream. Starting with DebugPOC-frame at CTUline containin debug CTU.")
-  ("EnsureWppBitEqual",                               m_ensureWppBitEqual,                      false, "Ensure the results are equal to results with WPP-style parallelism, even if WPP is off")
+#if JVET_W0129_ENABLE_ALF_TRUEORG
+  ("AlfTrueOrg",                                      m_alfTrueOrg,                              true, "Using true original samples for ALF optimization when MCTF is enabled\n")
+#else
+  ("AlfSaoTrueOrg",                                    m_alfSaoTrueOrg,                         false, "Using true original samples for ALF and SAO optimization when MCTF is enabled\n")
+#endif
   ( "ALF",                                             m_alf,                                    true, "Adaptive Loop Filter\n" )
-#if JVET_T0064
-  ("ALFStrength",                                      m_alfStrength,                             1.0, "Adaptive Loop Filter strength. The parameter scales the magnitudes of the ALF filter coefficients for both luma and chroma. Valid range is 0.0 <= ALFStrength <= 1.0")
+  ("ALFStrengthLuma",                                  m_alfStrengthLuma,                         1.0, "Adaptive Loop Filter strength for luma. The parameter scales the magnitudes of the ALF filter coefficients for luma. Valid range is 0.0 <= ALFStrengthLuma <= 1.0")
   ("ALFAllowPredefinedFilters",                        m_alfAllowPredefinedFilters,              true, "Allow use of predefined filters for ALF")
   ("CCALFStrength",                                    m_ccalfStrength,                           1.0, "Cross-component Adaptive Loop Filter strength. The parameter scales the magnitudes of the CCALF filter coefficients. Valid range is 0.0 <= CCALFStrength <= 1.0")
-#endif
+  ("ALFStrengthChroma",                                m_alfStrengthChroma,                       1.0, "Adaptive Loop Filter strength for chroma. The parameter scales the magnitudes of the ALF filter coefficients for chroma. Valid range is 0.0 <= ALFStrengthChroma <= 1.0")
+  ("ALFStrengthTargetLuma",                            m_alfStrengthTargetLuma,                   1.0, "Adaptive Loop Filter strength target for ALF luma filter optimization. The parameter scales the auto-correlation matrix E and the cross-correlation vector y for luma. Valid range is 0.0 <= ALFStrengthTargetLuma <= 1.0")
+  ("ALFStrengthTargetChroma",                          m_alfStrengthTargetChroma,                 1.0, "Adaptive Loop Filter strength target for ALF chroma filter optimization. The parameter scales the auto-correlation matrix E and the cross-correlation vector y for chroma. Valid range is 0.0 <= ALFStrengthTargetChroma <= 1.0")
+  ("CCALFStrengthTarget",                              m_ccalfStrengthTarget,                     1.0, "Cross-component Adaptive Loop Filter strength target for filter optimization. The parameter scales the auto-correlation matrix E and the cross-correlation vector y. Valid range is 0.0 <= CCALFStrengthTarget <= 1.0")
   ( "CCALF",                                           m_ccalf,                                  true, "Cross-component Adaptive Loop Filter" )
   ( "CCALFQpTh",                                       m_ccalfQpThreshold,                         37, "QP threshold above which encoder reduces CCALF usage")
   ( "RPR",                                            m_rprEnabledFlag,                          true, "Reference Sample Resolution" )
@@ -1417,13 +1605,9 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
   ( "SwitchPocPeriod",                                m_switchPocPeriod,                            0, "Switch POC period for RPR" )
   ( "UpscaledOutput",                                 m_upscaledOutput,                             0, "Output upscaled (2), decoded but in full resolution buffer (1) or decoded cropped (0, default) picture for RPR" )
   ( "MaxLayers",                                      m_maxLayers,                                  1, "Max number of layers" )
-#if JVET_S0163_ON_TARGETOLS_SUBLAYERS
   ( "EnableOperatingPointInformation",                m_OPIEnabled,                             false, "Enables writing of Operating Point Information (OPI)" )
   ( "MaxTemporalLayer",                               m_maxTemporalLayer,                         500, "Maximum temporal layer to be signalled in OPI" )
   ( "TargetOutputLayerSet",                           m_targetOlsIdx,                             500, "Target output layer set index to be signalled in OPI" )
-#else
-  ( "TargetOutputLayerSet,p",                         m_targetOlsIdx,                              -1, "Target output layer set index" )
-#endif
   ;
   opts.addOptions()
   ( "MaxSublayers",                                   m_maxSublayers,                               7, "Max number of Sublayers")
@@ -1439,11 +1623,7 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
   ( "OlsOutputLayer%d",                               m_olsOutputLayerStr, string(""), MAX_VPS_LAYERS, "Output layer index of i-th OLS")
   ( "NumPTLsInVPS",                                   m_numPtlsInVps,                               1, "Number of profile_tier_level structures in VPS" )
   ( "AvoidIntraInDepLayers",                          m_avoidIntraInDepLayer,                    true, "Replaces I pictures in dependent layers with B pictures" )
-#if JVET_R0193
   ( "MaxTidILRefPicsPlusOneLayerId%d",                m_maxTidILRefPicsPlus1Str, string(""), MAX_VPS_LAYERS, "Maximum temporal ID for inter-layer reference pictures plus 1 of i-th layer, 0 for IRAP only")
-#else
-  ( "MaxTidILRefPicsPlus1",                           m_cfgVPSParameters.m_maxTidILRefPicsPlus1,   -1, "Maximum temporal ID for inter-layer reference pictures plus 1, 0 for IRAP only" )
-#endif
     ;
 
   opts.addOptions()
@@ -1482,6 +1662,20 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
 
   m_resChangeInClvsEnabled = m_scalingRatioHor != 1.0 || m_scalingRatioVer != 1.0;
   m_resChangeInClvsEnabled = m_resChangeInClvsEnabled && m_rprEnabledFlag;
+  
+#if JVET_W0133_CONSTRAINED_RASL_ENCODING
+  if( m_constrainedRaslEncoding )
+  {
+    m_craAPSreset            = true;
+    m_rprRASLtoolSwitch      = true;
+  }
+  else
+  {
+    m_craAPSreset            = false;
+    m_rprRASLtoolSwitch      = false;
+  }
+#endif
+  
   if( m_fractionOfFrames != 1.0 )
   {
     m_framesToBeEncoded = int( m_framesToBeEncoded * m_fractionOfFrames );
@@ -1502,6 +1696,77 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
     m_iIntraPeriod = -1;
   }
 
+#if GDR_ENABLED
+  if ( m_gdrEnabled )
+  {
+    m_iDecodingRefreshType = 3;
+    m_intraQPOffset = 0;
+    m_iGOPSize = 1;
+
+    int8_t sliceType = m_GOPList[0].m_sliceType;
+
+    m_GOPList[0].m_POC = 1;    
+    m_GOPList[0].m_QPOffset = 0;
+    m_GOPList[0].m_QPOffsetModelOffset = 0;
+    m_GOPList[0].m_QPOffsetModelScale = 0;
+    m_GOPList[0].m_CbQPoffset = 0;
+    m_GOPList[0].m_CrQPoffset = 0;
+    m_GOPList[0].m_QPFactor = 1.0;
+    m_GOPList[0].m_tcOffsetDiv2 = 0;
+    m_GOPList[0].m_betaOffsetDiv2 = 0;
+    m_GOPList[0].m_CbTcOffsetDiv2 = 0;
+    m_GOPList[0].m_CbBetaOffsetDiv2 = 0;
+    m_GOPList[0].m_CrTcOffsetDiv2 = 0;
+    m_GOPList[0].m_CrBetaOffsetDiv2 = 0;
+    m_GOPList[0].m_temporalId = 0;
+
+    m_GOPList[0].m_numRefPicsActive0 = 4;
+    m_GOPList[0].m_numRefPics0 = 4;
+    m_GOPList[0].m_deltaRefPics0[0] = 1;
+    m_GOPList[0].m_deltaRefPics0[1] = 2;
+    m_GOPList[0].m_deltaRefPics0[2] = 3;
+    m_GOPList[0].m_deltaRefPics0[3] = 4;
+
+    if (sliceType == 'B')
+    {
+      m_GOPList[0].m_numRefPicsActive1 = 4;
+      m_GOPList[0].m_numRefPics1 = 4;
+      m_GOPList[0].m_deltaRefPics1[0] = 1;
+      m_GOPList[0].m_deltaRefPics1[1] = 2;
+      m_GOPList[0].m_deltaRefPics1[2] = 3;
+      m_GOPList[0].m_deltaRefPics1[3] = 4;
+    }
+
+    m_BIO  = false;
+    m_DMVR = false;
+    m_SMVD = false;
+
+    if (m_gdrPeriod < 0)
+    {
+      m_gdrPeriod = m_iFrameRate * 2;
+    }
+
+    if (m_gdrInterval < 0)
+    {
+      m_gdrInterval = m_iFrameRate;
+    }
+
+    if (m_gdrPocStart < 0)
+    {
+      m_gdrPocStart = m_gdrPeriod;
+    }
+
+    if (m_iIntraPeriod == -1)
+    {
+      m_iFrameRate = (m_iFrameRate == 0) ? 30 : m_iFrameRate;
+      if (m_gdrPocStart % m_iFrameRate != 0)
+        m_iIntraPeriod = -1;
+      else
+        m_iIntraPeriod = m_gdrPeriod;
+    }
+  }
+#endif
+
   m_bpDeltasGOPStructure = false;
   if(m_iGOPSize == 16)
   {
@@ -1609,8 +1874,8 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
    * Set any derived parameters
    */
 #if EXTENSION_360_VIDEO
-  m_inputFileWidth = m_iSourceWidth;
-  m_inputFileHeight = m_iSourceHeight;
+  m_inputFileWidth = m_sourceWidth;
+  m_inputFileHeight = m_sourceHeight;
   m_ext360.setMaxCUInfo(m_uiCTUSize, 1 << MIN_CU_LOG2);
 #endif
 
@@ -1630,9 +1895,9 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
   if(m_isField)
   {
     //Frame height
-    m_iSourceHeightOrg = m_iSourceHeight;
+    m_iSourceHeightOrg = m_sourceHeight;
     //Field height
-    m_iSourceHeight = m_iSourceHeight >> 1;
+    m_sourceHeight = m_sourceHeight >> 1;
     //number of fields to encode
     m_framesToBeEncoded *= 2;
   }
@@ -1672,8 +1937,8 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
         m_subPicId[i]                   = cfg_subPicId.values[i];
       }
     }
-    uint32_t tmpWidthVal = (m_iSourceWidth + m_uiCTUSize - 1) / m_uiCTUSize;
-    uint32_t tmpHeightVal = (m_iSourceHeight + m_uiCTUSize - 1) / m_uiCTUSize;
+    uint32_t tmpWidthVal = (m_sourceWidth + m_uiCTUSize - 1) / m_uiCTUSize;
+    uint32_t tmpHeightVal = (m_sourceHeight + m_uiCTUSize - 1) / m_uiCTUSize;
     if (!m_subPicSameSizeFlag)
     {
       for (int i = 0; i < m_numSubPics; i++)
@@ -1711,10 +1976,10 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
 
   if (m_virtualBoundariesPresentFlag)
   {
-    if (m_iSourceWidth <= 8)
+    if (m_sourceWidth <= 8)
       CHECK(m_numVerVirtualBoundaries != 0, "The number of vertical virtual boundaries shall be 0 when the picture width is less than or equal to 8");
 
-    if (m_iSourceHeight <= 8)
+    if (m_sourceHeight <= 8)
       CHECK(m_numHorVirtualBoundaries != 0, "The number of horizontal virtual boundaries shall be 0 when the picture height is less than or equal to 8");
   }
 
@@ -1897,6 +2162,26 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
     case ExtendedProfileName::MULTILAYER_MAIN_10_444_STILL_PICTURE:
       m_profile = Profile::MULTILAYER_MAIN_10_444_STILL_PICTURE;
       break;
+#if JVET_W2005_RANGE_EXTENSION_PROFILES
+    case ExtendedProfileName::MAIN_12:
+      m_profile = Profile::MAIN_12; break;
+    case ExtendedProfileName::MAIN_12_444:
+      m_profile = Profile::MAIN_12_444; break;
+    case ExtendedProfileName::MAIN_16_444:
+      m_profile = Profile::MAIN_16_444; break;
+    case ExtendedProfileName::MAIN_12_INTRA:
+      m_profile = Profile::MAIN_12_INTRA; break;
+    case ExtendedProfileName::MAIN_12_444_INTRA:
+      m_profile = Profile::MAIN_12_444_INTRA; break;
+    case ExtendedProfileName::MAIN_16_444_INTRA:
+      m_profile = Profile::MAIN_16_444_INTRA; break;
+    case ExtendedProfileName::MAIN_12_STILL_PICTURE:
+      m_profile = Profile::MAIN_12_STILL_PICTURE; break;
+    case ExtendedProfileName::MAIN_12_444_STILL_PICTURE:
+      m_profile = Profile::MAIN_12_444_STILL_PICTURE; break;
+    case ExtendedProfileName::MAIN_16_444_STILL_PICTURE:
+      m_profile = Profile::MAIN_16_444_STILL_PICTURE; break;
+#endif
     default: EXIT("Unable to determine profile from configured settings"); break;
     }
   }
@@ -1923,57 +2208,85 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
     CHECK(m_bitDepthConstraint < 8 || m_bitDepthConstraint>16, "MaxBitDepthConstraint setting must be in the range 8 to 16 (inclusive)");
   }
 
-
   m_inputColourSpaceConvert = stringToInputColourSpaceConvert(inputColourSpaceConvert, true);
   m_rgbFormat = (m_inputColourSpaceConvert == IPCOLOURSPACE_RGBtoGBR && m_chromaFormatIDC == CHROMA_444) ? true : false;
+#if JVET_W2005_RANGE_EXTENSION_PROFILES
+  if (m_profile == Profile::MAIN_12 || m_profile == Profile::MAIN_12_INTRA || m_profile == Profile::MAIN_12_STILL_PICTURE ||
+      m_profile == Profile::MAIN_12_444 || m_profile == Profile::MAIN_12_444_INTRA || m_profile == Profile::MAIN_12_444_STILL_PICTURE ||
+      m_profile == Profile::MAIN_16_444 || m_profile == Profile::MAIN_16_444_INTRA || m_profile == Profile::MAIN_16_444_STILL_PICTURE)
+  {
+    m_gciPresentFlag = true;
+    if (m_profile == Profile::MAIN_12 || m_profile == Profile::MAIN_12_444 || m_profile == Profile::MAIN_16_444)
+    {
+      CHECK(m_generalLowerBitRateConstraintFlag == 0, "GeneralLowerBitRateConstraintFlag setting must be 1 for non-Intra/Still Picture operation range extension profiles.")
+    }
+  }
+  if (m_profile == Profile::MAIN_12_INTRA || m_profile == Profile::MAIN_12_444_INTRA || m_profile == Profile::MAIN_16_444_INTRA)
+  {
+    CHECK(m_iIntraPeriod != 1, "IntraPeriod setting must be 1 for Intra profiles")
+  }
+  if (m_profile == Profile::MULTILAYER_MAIN_10_STILL_PICTURE || m_profile == Profile::MAIN_10_STILL_PICTURE ||
+      m_profile == Profile::MAIN_12_STILL_PICTURE || m_profile == Profile::MAIN_12_444_STILL_PICTURE || m_profile == Profile::MAIN_16_444_STILL_PICTURE)
+  {
+    CHECK(m_framesToBeEncoded != 1, "FramesToBeEncoded setting must be 1 for Still Picture profiles")
+  }
+#endif
 
   // Picture width and height must be multiples of 8 and minCuSize
   const int minResolutionMultiple = std::max(8, 1 << m_log2MinCuSize);
-  CHECK(((m_iSourceWidth% minResolutionMultiple) || (m_iSourceHeight % minResolutionMultiple)) && m_conformanceWindowMode != 1, "Picture width or height is not a multiple of 8 or minCuSize, please use ConformanceMode 1!");
+
   switch (m_conformanceWindowMode)
   {
   case 0:
     {
       // no conformance or padding
       m_confWinLeft = m_confWinRight = m_confWinTop = m_confWinBottom = 0;
-      m_aiPad[1] = m_aiPad[0] = 0;
+      m_sourcePadding[1] = m_sourcePadding[0] = 0;
       break;
     }
   case 1:
     {
       // automatic padding to minimum CU size
-      if (m_iSourceWidth % minResolutionMultiple)
+      if (m_sourceWidth % minResolutionMultiple)
       {
-        m_aiPad[0] = m_confWinRight  = ((m_iSourceWidth / minResolutionMultiple) + 1) * minResolutionMultiple - m_iSourceWidth;
-        m_iSourceWidth  += m_confWinRight;
+        m_sourcePadding[0] = m_confWinRight  = ((m_sourceWidth / minResolutionMultiple) + 1) * minResolutionMultiple - m_sourceWidth;
+        m_sourceWidth  += m_confWinRight;
       }
-      if (m_iSourceHeight % minResolutionMultiple)
+      if (m_sourceHeight % minResolutionMultiple)
       {
-        m_aiPad[1] = m_confWinBottom = ((m_iSourceHeight / minResolutionMultiple) + 1) * minResolutionMultiple - m_iSourceHeight;
-        m_iSourceHeight += m_confWinBottom;
+        m_sourcePadding[1] = m_confWinBottom = ((m_sourceHeight / minResolutionMultiple) + 1) * minResolutionMultiple - m_sourceHeight;
+        m_sourceHeight += m_confWinBottom;
         if ( m_isField )
         {
           m_iSourceHeightOrg += m_confWinBottom << 1;
-          m_aiPad[1] = m_confWinBottom << 1;
+          m_sourcePadding[1] = m_confWinBottom << 1;
         }
       }
-      if (m_aiPad[0] % SPS::getWinUnitX(m_chromaFormatIDC) != 0)
+      if (m_sourcePadding[0] % SPS::getWinUnitX(m_chromaFormatIDC) != 0)
       {
         EXIT( "Error: picture width is not an integer multiple of the specified chroma subsampling");
       }
-      if (m_aiPad[1] % SPS::getWinUnitY(m_chromaFormatIDC) != 0)
+      if (m_sourcePadding[1] % SPS::getWinUnitY(m_chromaFormatIDC) != 0)
       {
         EXIT( "Error: picture height is not an integer multiple of the specified chroma subsampling");
       }
+      if (m_sourcePadding[0])
+      {
+        msg( INFO, "Info: Conformance window automatically enabled. Adding %i lumal pel horizontally\n", m_sourcePadding[0]);
+      }
+      if (m_sourcePadding[1])
+      {
+        msg( INFO, "Info: Conformance window automatically enabled. Adding %i lumal pel vertically\n", m_sourcePadding[1]);
+      }
       break;
     }
   case 2:
     {
       //padding
-      m_iSourceWidth  += m_aiPad[0];
-      m_iSourceHeight += m_aiPad[1];
-      m_confWinRight  = m_aiPad[0];
-      m_confWinBottom = m_aiPad[1];
+      m_sourceWidth  += m_sourcePadding[0];
+      m_sourceHeight += m_sourcePadding[1];
+      m_confWinRight  = m_sourcePadding[0];
+      m_confWinBottom = m_sourcePadding[1];
       break;
     }
   case 3:
@@ -1983,24 +2296,25 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
       {
         msg( ERROR, "Warning: Conformance window enabled, but all conformance window parameters set to zero\n");
       }
-      if ((m_aiPad[1] != 0) || (m_aiPad[0]!=0))
+      if ((m_sourcePadding[1] != 0) || (m_sourcePadding[0]!=0))
       {
         msg( ERROR, "Warning: Conformance window enabled, padding parameters will be ignored\n");
       }
-      m_aiPad[1] = m_aiPad[0] = 0;
+      m_sourcePadding[1] = m_sourcePadding[0] = 0;
       break;
     }
   }
+  CHECK(((m_sourceWidth% minResolutionMultiple) || (m_sourceHeight % minResolutionMultiple)), "Picture width or height (after padding) is not a multiple of 8 or minCuSize, please use ConformanceWindowMode=1 for automatic adjustment or ConformanceWindowMode=2 to specify padding manually!!");
 
   if( m_conformanceWindowMode > 0 && m_subPicInfoPresentFlag )
   {
     for(int i = 0; i < m_numSubPics; i++)
     {
-      CHECK( (m_subPicCtuTopLeftX[i] * m_uiCTUSize) >= (m_iSourceWidth - m_confWinRight * SPS::getWinUnitX(m_chromaFormatIDC)),
+      CHECK( (m_subPicCtuTopLeftX[i] * m_uiCTUSize) >= (m_sourceWidth - m_confWinRight * SPS::getWinUnitX(m_chromaFormatIDC)),
           "No subpicture can be located completely outside of the conformance cropping window");
       CHECK( ((m_subPicCtuTopLeftX[i] + m_subPicWidth[i]) * m_uiCTUSize) <= (m_confWinLeft * SPS::getWinUnitX(m_chromaFormatIDC)),
 	  "No subpicture can be located completely outside of the conformance cropping window" );
-      CHECK( (m_subPicCtuTopLeftY[i] * m_uiCTUSize) >= (m_iSourceHeight  - m_confWinBottom * SPS::getWinUnitY(m_chromaFormatIDC)),
+      CHECK( (m_subPicCtuTopLeftY[i] * m_uiCTUSize) >= (m_sourceHeight  - m_confWinBottom * SPS::getWinUnitY(m_chromaFormatIDC)),
           "No subpicture can be located completely outside of the conformance cropping window");
       CHECK( ((m_subPicCtuTopLeftY[i] + m_subPicHeight[i]) * m_uiCTUSize) <= (m_confWinTop * SPS::getWinUnitY(m_chromaFormatIDC)),
           "No subpicture can be located completely outside of the conformance cropping window");
@@ -2158,6 +2472,22 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
     }
   }
 
+  /* Local chroma QP offsets configuration */
+  CHECK(m_cuChromaQpOffsetSubdiv < 0, "MaxCuChromaQpOffsetSubdiv shall be >= 0");
+  CHECK(cfg_crQpOffsetList.values.size() != cfg_cbQpOffsetList.values.size(), "Chroma QP offset lists shall be the same size");
+  CHECK(cfg_cbCrQpOffsetList.values.size() != cfg_cbQpOffsetList.values.size() && cfg_cbCrQpOffsetList.values.size() > 0, "Chroma QP offset list for joint CbCr shall be either the same size as Cb and Cr or empty");
+  if (m_cuChromaQpOffsetSubdiv > 0 && !cfg_cbQpOffsetList.values.size())
+  {
+    msg(WARNING, "MaxCuChromaQpOffsetSubdiv has no effect when chroma QP offset lists are empty\n");
+  }
+  m_cuChromaQpOffsetList.resize(cfg_cbQpOffsetList.values.size());
+  for (int i=0; i < cfg_cbQpOffsetList.values.size(); i++)
+  {
+    m_cuChromaQpOffsetList[i].u.comp.CbOffset = cfg_cbQpOffsetList.values[i];
+    m_cuChromaQpOffsetList[i].u.comp.CrOffset = cfg_crQpOffsetList.values[i];
+    m_cuChromaQpOffsetList[i].u.comp.JointCbCrOffset = cfg_cbCrQpOffsetList.values.size() ? cfg_cbCrQpOffsetList.values[i] : 0;
+  }
+
 #if LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET
   if ( m_LadfEnabed )
   {
@@ -2193,7 +2523,20 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
   }
 #endif
 
+#if GDR_ENABLED
+  if (m_gdrEnabled)
+  {
+    m_virtualBoundariesEnabledFlag = 1;
+    m_virtualBoundariesPresentFlag = 0;
+  }
+  else
+  {
+    m_virtualBoundariesEnabledFlag = 0;
+  }
+#else
   m_virtualBoundariesEnabledFlag = 0;
+#endif
+
   if( m_numVerVirtualBoundaries > 0 || m_numHorVirtualBoundaries > 0 )
     m_virtualBoundariesEnabledFlag = 1;
 
@@ -2214,7 +2557,7 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
       }
       for (unsigned i = 0; i < m_numVerVirtualBoundaries; i++)
       {
-        CHECK( m_virtualBoundariesPosX[i] == 0 || m_virtualBoundariesPosX[i] >= m_iSourceWidth, "The vertical virtual boundary must be within the picture" );
+        CHECK( m_virtualBoundariesPosX[i] == 0 || m_virtualBoundariesPosX[i] >= m_sourceWidth, "The vertical virtual boundary must be within the picture" );
         CHECK( m_virtualBoundariesPosX[i] % 8, "The vertical virtual boundary must be a multiple of 8 luma samples" );
         if (i > 0)
         {
@@ -2228,7 +2571,7 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
       }
       for (unsigned i = 0; i < m_numHorVirtualBoundaries; i++)
       {
-        CHECK( m_virtualBoundariesPosY[i] == 0 || m_virtualBoundariesPosY[i] >= m_iSourceHeight, "The horizontal virtual boundary must be within the picture" );
+        CHECK( m_virtualBoundariesPosY[i] == 0 || m_virtualBoundariesPosY[i] >= m_sourceHeight, "The horizontal virtual boundary must be within the picture" );
         CHECK( m_virtualBoundariesPosY[i] % 8, "The horizontal virtual boundary must be a multiple of 8 luma samples" );
         if (i > 0)
         {
@@ -2275,6 +2618,50 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
       m_masteringDisplay.whitePoint[idx] = uint16_t((cfg_DisplayWhitePointCode.values.size() > idx) ? cfg_DisplayWhitePointCode.values[idx] : 0);
     }
   }
+  if (m_ctiSEIEnabled) 
+  {
+    CHECK(!m_ctiSEICrossComponentFlag && m_ctiSEICrossComponentInferred, "CTI CrossComponentFlag is 0, but CTI CrossComponentInferred is 1 (must be 0 for CrossComponentFlag 0)");
+    CHECK(!m_ctiSEICrossComponentFlag && !m_ctiSEICrossComponentInferred && !m_ctiSEINumberChromaLut, "For CTI CrossComponentFlag = 0, CTI NumberChromaLut needs to be specified (1 or 2) ");
+    CHECK(m_ctiSEICrossComponentFlag && !m_ctiSEICrossComponentInferred && !m_ctiSEINumberChromaLut, "For CTI CrossComponentFlag = 1 and CrossComponentInferred = 0, CTI NumberChromaLut needs to be specified (1 or 2) ");
+
+    CHECK(cfg_SEICTILut0.values.empty(), "SEI CTI (SEICTIEnabled) but no LUT0 specified");
+    m_ctiSEILut[0].presentFlag = true;
+    m_ctiSEILut[0].numLutValues = (int)cfg_SEICTILut0.values.size();
+    m_ctiSEILut[0].lutValues = cfg_SEICTILut0.values;
+
+    if (!m_ctiSEICrossComponentFlag || (m_ctiSEICrossComponentFlag && !m_ctiSEICrossComponentInferred)) 
+    {
+      CHECK(cfg_SEICTILut1.values.empty(), "SEI CTI LUT1 not specified");
+      m_ctiSEILut[1].presentFlag = true;
+      m_ctiSEILut[1].numLutValues = (int)cfg_SEICTILut1.values.size();
+      m_ctiSEILut[1].lutValues = cfg_SEICTILut1.values;
+
+      if (m_ctiSEINumberChromaLut == 1) 
+      { // Cb lut the same as Cr lut
+        m_ctiSEILut[2].presentFlag = true;
+        m_ctiSEILut[2].numLutValues = m_ctiSEILut[1].numLutValues;
+        m_ctiSEILut[2].lutValues = m_ctiSEILut[1].lutValues;
+      }
+      else if (m_ctiSEINumberChromaLut == 2) 
+      { // read from cfg
+        CHECK(cfg_SEICTILut2.values.empty(), "SEI CTI LUT2 not specified");
+        m_ctiSEILut[2].presentFlag = true;
+        m_ctiSEILut[2].numLutValues = (int)cfg_SEICTILut2.values.size();
+        m_ctiSEILut[2].lutValues = cfg_SEICTILut2.values;
+      }
+      else 
+      {
+        CHECK(m_ctiSEINumberChromaLut < 1 && m_ctiSEINumberChromaLut > 2, "Number of chroma LUTs is missing or out of range!");
+      }
+    }
+    //  check if lut size is power of 2
+    for (int idx = 0; idx < MAX_NUM_COMPONENT; idx++) 
+    {
+      int n = m_ctiSEILut[idx].numLutValues - 1;
+      CHECK(n > 0 && (n & (n - 1)) != 0, "Size of LUT minus 1 should be power of 2!");
+      CHECK(n > MAX_CTI_LUT_SIZE, "LUT size minus 1 is larger than MAX_CTI_LUT_SIZE (64)!");
+    }
+  }
   if ( m_omniViewportSEIEnabled && !m_omniViewportSEICancelFlag )
   {
     CHECK (!( m_omniViewportSEICntMinus1 >= 0 && m_omniViewportSEICntMinus1 < 16 ), "SEIOmniViewportCntMinus1 must be in the range of 0 to 16");
@@ -2383,9 +2770,94 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
       }
     }
   }
+  if ( m_sdiSEIEnabled )
+  {
+    if (m_sdiSEIMultiviewInfoFlag || m_sdiSEIAuxiliaryInfoFlag)
+    {
+      m_sdiSEILayerId.resize(m_sdiSEIMaxLayersMinus1 + 1);
+      m_sdiSEIViewIdVal.resize(m_sdiSEIMaxLayersMinus1 + 1);
+      m_sdiSEIAuxId.resize(m_sdiSEIMaxLayersMinus1 + 1);
+      m_sdiSEINumAssociatedPrimaryLayersMinus1.resize(m_sdiSEIMaxLayersMinus1 + 1);
+      for (int i = 0; i <= m_sdiSEIMaxLayersMinus1; i++)
+      {
+        m_sdiSEILayerId[i] = cfg_sdiSEILayerId.values[i];
+        if (m_sdiSEIMultiviewInfoFlag)
+        {
+          m_sdiSEIViewIdVal[i] = cfg_sdiSEIViewIdVal.values[i];
+        }
+        if (m_sdiSEIAuxiliaryInfoFlag)
+        {
+          m_sdiSEIAuxId[i] = cfg_sdiSEIAuxId.values[i];
+          if (m_sdiSEIAuxId[i] > 0)
+          {
+            m_sdiSEINumAssociatedPrimaryLayersMinus1[i] = cfg_sdiSEINumAssociatedPrimaryLayersMinus1.values[i];
+          }
+        }
+      }
+    }
+  }
+  if ( m_maiSEIEnabled )
+  {
+    if (m_maiSEIIntrinsicParamFlag)
+    {
+      int numViews = m_maiSEIIntrinsicParamsEqualFlag ? 1 : m_maiSEINumViewsMinus1 + 1;
+      m_maiSEISignFocalLengthX       .resize( numViews );
+      m_maiSEIExponentFocalLengthX   .resize( numViews );
+      m_maiSEIMantissaFocalLengthX   .resize( numViews );
+      m_maiSEISignFocalLengthY       .resize( numViews );
+      m_maiSEIExponentFocalLengthY   .resize( numViews );
+      m_maiSEIMantissaFocalLengthY   .resize( numViews );
+      m_maiSEISignPrincipalPointX    .resize( numViews );
+      m_maiSEIExponentPrincipalPointX.resize( numViews );
+      m_maiSEIMantissaPrincipalPointX.resize( numViews );
+      m_maiSEISignPrincipalPointY    .resize( numViews );
+      m_maiSEIExponentPrincipalPointY.resize( numViews );
+      m_maiSEIMantissaPrincipalPointY.resize( numViews );
+      m_maiSEISignSkewFactor         .resize( numViews );
+      m_maiSEIExponentSkewFactor     .resize( numViews );
+      m_maiSEIMantissaSkewFactor     .resize( numViews );
+      for( int i = 0; i  <=  ( m_maiSEIIntrinsicParamsEqualFlag ? 0 : m_maiSEINumViewsMinus1 ); i++ )
+      {
+        m_maiSEISignFocalLengthX       [i] = cfg_maiSEISignFocalLengthX.values[i];
+        m_maiSEIExponentFocalLengthX   [i] = cfg_maiSEIExponentFocalLengthX.values[i];
+        m_maiSEIMantissaFocalLengthX   [i] = cfg_maiSEIMantissaFocalLengthX.values[i];
+        m_maiSEISignFocalLengthY       [i] = cfg_maiSEISignFocalLengthY.values[i];
+        m_maiSEIExponentFocalLengthY   [i] = cfg_maiSEIExponentFocalLengthY.values[i];
+        m_maiSEIMantissaFocalLengthY   [i] = cfg_maiSEIMantissaFocalLengthY.values[i];
+        m_maiSEISignPrincipalPointX    [i] = cfg_maiSEISignPrincipalPointX.values[i];
+        m_maiSEIExponentPrincipalPointX[i] = cfg_maiSEIExponentPrincipalPointX.values[i];
+        m_maiSEIMantissaPrincipalPointX[i] = cfg_maiSEIMantissaPrincipalPointX.values[i];
+        m_maiSEISignPrincipalPointY    [i] = cfg_maiSEISignPrincipalPointY.values[i];
+        m_maiSEIExponentPrincipalPointY[i] = cfg_maiSEIExponentPrincipalPointY.values[i];
+        m_maiSEIMantissaPrincipalPointY[i] = cfg_maiSEIMantissaPrincipalPointY.values[i];
+        m_maiSEISignSkewFactor         [i] = cfg_maiSEISignSkewFactor.values[i];
+        m_maiSEIExponentSkewFactor     [i] = cfg_maiSEIExponentSkewFactor.values[i];
+        m_maiSEIMantissaSkewFactor     [i] = cfg_maiSEIMantissaSkewFactor.values[i];
+      }
+    }
+  }
+#if JVET_W0078_MVP_SEI 
+  if (m_mvpSEIEnabled)
+  {
+    int numViews = m_mvpSEINumViewsMinus1 + 1;
+    m_mvpSEIViewPosition.resize(numViews);
+    for (int i = 0; i <= m_mvpSEINumViewsMinus1; i++)
+    {
+      m_mvpSEIViewPosition[i] = cfg_mvpSEIViewPosition.values[i];
+    }
+  }
+#endif
+  if ( m_driSEIEnabled )
+  {
+    m_driSEINonlinearModel.resize(m_driSEINonlinearNumMinus1+1);
+    for(int i=0; i<(m_driSEINonlinearNumMinus1+1); i++)
+    {
+      m_driSEINonlinearModel[i]   = cfg_driSEINonlinearModel.values.size() > i ? cfg_driSEINonlinearModel.values[i] : 0;
+    }
+  }
   m_reshapeCW.binCW.resize(3);
   m_reshapeCW.rspFps = m_iFrameRate;
-  m_reshapeCW.rspPicSize = m_iSourceWidth*m_iSourceHeight;
+  m_reshapeCW.rspPicSize = m_sourceWidth*m_sourceHeight;
   m_reshapeCW.rspFpsToIp = std::max(16, 16 * (int)(round((double)m_iFrameRate /16.0)));
   m_reshapeCW.rspBaseQP = m_iQP;
   m_reshapeCW.updateCtrl = m_updateCtrl;
@@ -2411,22 +2883,22 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
 
 #if ENABLE_QPA_SUB_CTU
  #if QP_SWITCHING_FOR_PARALLEL
-  if ((m_iQP < 38) && m_bUsePerceptQPA && !m_bUseAdaptiveQP && (m_iSourceWidth <= 2048) && (m_iSourceHeight <= 1280)
+  if ((m_iQP < 38) && m_bUsePerceptQPA && !m_bUseAdaptiveQP && (m_sourceWidth <= 2048) && (m_sourceHeight <= 1280)
  #else
-  if (((int)m_fQP < 38) && m_bUsePerceptQPA && !m_bUseAdaptiveQP && (m_iSourceWidth <= 2048) && (m_iSourceHeight <= 1280)
+  if (((int)m_fQP < 38) && m_bUsePerceptQPA && !m_bUseAdaptiveQP && (m_sourceWidth <= 2048) && (m_sourceHeight <= 1280)
  #endif
  #if WCG_EXT && ER_CHROMA_QP_WCG_PPS
       && (!m_wcgChromaQpControl.enabled)
  #endif
-      && ((1 << (m_log2MaxTbSize + 1)) == m_uiCTUSize) && (m_iSourceWidth > 512 || m_iSourceHeight > 320))
+      && ((1 << (m_log2MaxTbSize + 1)) == m_uiCTUSize) && (m_sourceWidth > 512 || m_sourceHeight > 320))
   {
     m_cuQpDeltaSubdiv = 2;
   }
 #else
  #if QP_SWITCHING_FOR_PARALLEL
-  if( ( m_iQP < 38 ) && ( m_iGOPSize > 4 ) && m_bUsePerceptQPA && !m_bUseAdaptiveQP && ( m_iSourceHeight <= 1280 ) && ( m_iSourceWidth <= 2048 ) )
+  if( ( m_iQP < 38 ) && ( m_iGOPSize > 4 ) && m_bUsePerceptQPA && !m_bUseAdaptiveQP && ( m_sourceHeight <= 1280 ) && ( m_sourceWidth <= 2048 ) )
  #else
-  if( ( ( int ) m_fQP < 38 ) && ( m_iGOPSize > 4 ) && m_bUsePerceptQPA && !m_bUseAdaptiveQP && ( m_iSourceHeight <= 1280 ) && ( m_iSourceWidth <= 2048 ) )
+  if( ( ( int ) m_fQP < 38 ) && ( m_iGOPSize > 4 ) && m_bUsePerceptQPA && !m_bUseAdaptiveQP && ( m_sourceHeight <= 1280 ) && ( m_sourceWidth <= 2048 ) )
  #endif
   {
     msg( WARNING, "*************************************************************************\n" );
@@ -2463,7 +2935,7 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
     {
       firstSliceLossless = true;
     }
-    if (firstSliceLossless) // if first slice is lossless 
+    if (firstSliceLossless) // if first slice is lossless
     m_iQP = LOSSLESS_AND_MIXED_LOSSLESS_RD_COST_TEST_QP - ( ( m_internalBitDepth[CHANNEL_TYPE_LUMA] - 8 ) * 6 );
   }
 
@@ -2510,6 +2982,17 @@ int EncAppCfg::xAutoDetermineProfile()
         m_profile = m_maxLayers > 1 ? Profile::MULTILAYER_MAIN_10 : Profile::MAIN_10;
       }
     }
+#if JVET_W2005_RANGE_EXTENSION_PROFILES
+    else if (maxBitDepth <= 12)
+    {
+      m_profile = (m_level == Level::LEVEL15_5 && m_framesToBeEncoded == 1) ? Profile::MAIN_12_STILL_PICTURE : (m_iIntraPeriod == 1) ? Profile::MAIN_12_INTRA : Profile::MAIN_12;
+    }
+    else if (maxBitDepth <= 16)
+    {
+      // Since there's no 16bit 420 profiles in VVC, we use 444 profiles.
+      m_profile = (m_level == Level::LEVEL15_5 && m_framesToBeEncoded == 1) ? Profile::MAIN_16_444_STILL_PICTURE : (m_iIntraPeriod == 1) ? Profile::MAIN_16_444_INTRA : Profile::MAIN_16_444;
+    }
+#endif
     break;
 
   case ChromaFormat::CHROMA_422:
@@ -2526,11 +3009,26 @@ int EncAppCfg::xAutoDetermineProfile()
         m_profile = m_maxLayers > 1 ? Profile::MULTILAYER_MAIN_10_444 : Profile::MAIN_10_444;
       }
     }
+#if JVET_W2005_RANGE_EXTENSION_PROFILES
+    else if (maxBitDepth <= 12)
+    {
+      m_profile = (m_level == Level::LEVEL15_5 && m_framesToBeEncoded == 1) ? Profile::MAIN_12_444_STILL_PICTURE : (m_iIntraPeriod == 1) ? Profile::MAIN_12_444_INTRA : Profile::MAIN_12_444;
+    }
+    else if (maxBitDepth <= 16)
+    {
+      m_profile = (m_level == Level::LEVEL15_5 && m_framesToBeEncoded == 1) ? Profile::MAIN_16_444_STILL_PICTURE : (m_iIntraPeriod == 1) ? Profile::MAIN_16_444_INTRA : Profile::MAIN_16_444;
+    }
+#endif
     break;
 
   default: return 1;
   }
-
+#if JVET_W2005_RANGE_EXTENSION_PROFILES
+    if (m_profile == Profile::MAIN_12 || m_profile == Profile::MAIN_12_444 || m_profile == Profile::MAIN_16_444)
+    {
+      m_generalLowerBitRateConstraintFlag = 1; // GeneralLowerBitRateConstraintFlag setting must be 1 for non-Intra/Still Picture operation range extension profiles.")
+    }
+#endif
   return 0;
 }
 
@@ -2572,20 +3070,10 @@ bool EncAppCfg::xCheckParameter()
   {
     const int minCUSize = 1 << m_log2MinCuSize;
     xConfirmPara(m_wrapAroundOffset <= m_uiCTUSize + minCUSize, "Wrap-around offset must be greater than CtbSizeY + MinCbSize");
-    xConfirmPara(m_wrapAroundOffset > m_iSourceWidth, "Wrap-around offset must not be greater than the source picture width");
+    xConfirmPara(m_wrapAroundOffset > m_sourceWidth, "Wrap-around offset must not be greater than the source picture width");
     xConfirmPara( m_wrapAroundOffset % minCUSize != 0, "Wrap-around offset must be an integer multiple of the specified minimum CU size" );
   }
 
-#if ENABLE_SPLIT_PARALLELISM
-  xConfirmPara( m_numSplitThreads < 1, "Number of used threads cannot be smaller than 1" );
-  xConfirmPara( m_numSplitThreads > PARL_SPLIT_MAX_NUM_THREADS, "Number of used threads cannot be higher than the number of actual jobs" );
-#else
-  xConfirmPara( m_numSplitThreads != 1, "ENABLE_SPLIT_PARALLELISM is disabled, numSplitThreads has to be 1" );
-#endif
-
-  xConfirmPara( m_numWppThreads != 1, "ENABLE_WPP_PARALLELISM is disabled, numWppThreads has to be 1" );
-  xConfirmPara( m_ensureWppBitEqual, "ENABLE_WPP_PARALLELISM is disabled, cannot ensure being WPP bit-equal" );
-
 
 #if SHARP_LUMA_DELTA_QP && ENABLE_QPA
   xConfirmPara( m_bUsePerceptQPA && m_lumaLevelToDeltaQPMapping.mode >= 2, "QPA and SharpDeltaQP mode 2 cannot be used together" );
@@ -2610,12 +3098,31 @@ bool EncAppCfg::xCheckParameter()
     xConfirmPara(m_log2MaxTransformSkipBlockSize>=6, "Transform Skip Log2 Max Size must be less or equal to 5 for given profile.");
     xConfirmPara(m_transformSkipRotationEnabledFlag==true, "UseResidualRotation must not be enabled for given profile.");
     xConfirmPara(m_transformSkipContextEnabledFlag==true, "UseSingleSignificanceMapContext must not be enabled for given profile.");
+#if !JVET_W2005_RANGE_EXTENSION_PROFILES
+    xConfirmPara(m_rrcRiceExtensionEnableFlag == true, "Extention of the Golomb-Rice parameter derivation for RRC must not be enabled for given profile.");
     xConfirmPara(m_persistentRiceAdaptationEnabledFlag==true, "GolombRiceParameterAdaption must not be enabled for given profile.");
     xConfirmPara(m_extendedPrecisionProcessingFlag==true, "UseExtendedPrecision must not be enabled for given profile.");
+    xConfirmPara(m_tsrcRicePresentFlag == true, "TSRCRicePresent must not be enabled for given profile.");
+#if JVET_W0046_RLSCP
+    xConfirmPara(m_reverseLastSigCoeffEnabledFlag == true, "ReverseLastSigCoeff must not be enabled for given profile.");
+#endif
+#endif
     xConfirmPara(m_highPrecisionOffsetsEnabledFlag==true, "UseHighPrecisionPredictionWeighting must not be enabled for given profile.");
     xConfirmPara(m_enableIntraReferenceSmoothing==false, "EnableIntraReferenceSmoothing must be enabled for given profile.");
     xConfirmPara(m_cabacBypassAlignmentEnabledFlag, "AlignCABACBeforeBypass cannot be enabled for given profile.");
   }
+#if JVET_W2005_RANGE_EXTENSION_PROFILES
+  if (m_profile != Profile::NONE && m_profile != Profile::MAIN_12_444 && m_profile != Profile::MAIN_16_444 && m_profile != Profile::MAIN_12_444_INTRA && m_profile != Profile::MAIN_16_444_INTRA && m_profile != Profile::MAIN_12_444_STILL_PICTURE && m_profile != Profile::MAIN_12_444_STILL_PICTURE && m_profile != Profile::MAIN_16_444_STILL_PICTURE)
+  {
+    xConfirmPara(m_rrcRiceExtensionEnableFlag == true, "Extention of the Golomb-Rice parameter derivation for RRC must not be enabled for given profile.");
+    xConfirmPara(m_persistentRiceAdaptationEnabledFlag==true, "GolombRiceParameterAdaption must not be enabled for given profile.");
+    xConfirmPara(m_extendedPrecisionProcessingFlag==true, "UseExtendedPrecision must not be enabled for given profile.");
+    xConfirmPara(m_tsrcRicePresentFlag == true, "TSRCRicePresent must not be enabled for given profile.");
+#if JVET_W0046_RLSCP
+    xConfirmPara(m_reverseLastSigCoeffEnabledFlag == true, "ReverseLastSigCoeff must not be enabled for given profile.");
+#endif
+  }
+#endif
 
 
   // check range of parameters
@@ -2650,6 +3157,15 @@ bool EncAppCfg::xCheckParameter()
   xConfirmPara( (m_MSBExtendedBitDepth[CHANNEL_TYPE_LUMA  ] < m_inputBitDepth[CHANNEL_TYPE_LUMA  ]), "MSB-extended bit depth for luma channel (--MSBExtendedBitDepth) must be greater than or equal to input bit depth for luma channel (--InputBitDepth)" );
   xConfirmPara( (m_MSBExtendedBitDepth[CHANNEL_TYPE_CHROMA] < m_inputBitDepth[CHANNEL_TYPE_CHROMA]), "MSB-extended bit depth for chroma channel (--MSBExtendedBitDepthC) must be greater than or equal to input bit depth for chroma channel (--InputBitDepthC)" );
 
+#if JVET_W0178_CONSTRAINTS_ON_REXT_TOOLS
+  bool check_sps_range_extension_flag = m_extendedPrecisionProcessingFlag || 
+                                  m_rrcRiceExtensionEnableFlag ||
+                                  m_persistentRiceAdaptationEnabledFlag || 
+                                  m_tsrcRicePresentFlag;
+  if (m_internalBitDepth[CHANNEL_TYPE_LUMA] <= 10)
+    xConfirmPara( (check_sps_range_extension_flag == 1) ,
+                 "RExt tools (Extended Precision Processing, RRC Rice Extension, Persistent Rice Adaptation and TSRC Rice Extension) must be disabled for BitDepth is less than or equal to 10 (the value of sps_range_extension_flag shall be 0 when BitDepth is less than or equal to 10.)");
+#endif
 
   xConfirmPara( m_chromaFormatIDC >= NUM_CHROMA_FORMAT,                                     "ChromaFormatIDC must be either 400, 420, 422 or 444" );
   std::string sTempIPCSC="InputColourSpaceConvert must be empty, "+getListOfColourSpaceConverts(true);
@@ -2663,6 +3179,7 @@ bool EncAppCfg::xCheckParameter()
   xConfirmPara( m_iGOPSize > 1 &&  m_iGOPSize % 2,                                          "GOP Size must be a multiple of 2, if GOP Size is greater than 1" );
   xConfirmPara( (m_iIntraPeriod > 0 && m_iIntraPeriod < m_iGOPSize) || m_iIntraPeriod == 0, "Intra period must be more than GOP size, or -1 , not 0" );
   xConfirmPara( m_drapPeriod < 0,                                                           "DRAP period must be greater or equal to 0" );
+  xConfirmPara( m_edrapPeriod < 0,                                                          "EDRAP period must be greater or equal to 0" );
   xConfirmPara( m_iDecodingRefreshType < 0 || m_iDecodingRefreshType > 3,                   "Decoding Refresh Type must be comprised between 0 and 3 included" );
 
   if (m_isField)
@@ -2696,16 +3213,16 @@ bool EncAppCfg::xCheckParameter()
 
   xConfirmPara( m_iQP < -6 * (m_internalBitDepth[CHANNEL_TYPE_LUMA] - 8) || m_iQP > MAX_QP, "QP exceeds supported range (-QpBDOffsety to 63)" );
 #if W0038_DB_OPT
-  xConfirmPara( m_deblockingFilterMetric!=0 && (m_bLoopFilterDisable || m_loopFilterOffsetInPPS), "If DeblockingFilterMetric is non-zero then both LoopFilterDisable and LoopFilterOffsetInPPS must be 0");
+  xConfirmPara( m_deblockingFilterMetric!=0 && (m_deblockingFilterDisable || m_deblockingFilterOffsetInPPS), "If DeblockingFilterMetric is non-zero then both LoopFilterDisable and LoopFilterOffsetInPPS must be 0");
 #else
   xConfirmPara( m_DeblockingFilterMetric && (m_bLoopFilterDisable || m_loopFilterOffsetInPPS), "If DeblockingFilterMetric is true then both LoopFilterDisable and LoopFilterOffsetInPPS must be 0");
 #endif
-  xConfirmPara( m_loopFilterBetaOffsetDiv2 < -12 || m_loopFilterBetaOffsetDiv2 > 12,          "Loop Filter Beta Offset div. 2 exceeds supported range (-12 to 12" );
-  xConfirmPara( m_loopFilterTcOffsetDiv2 < -12 || m_loopFilterTcOffsetDiv2 > 12,              "Loop Filter Tc Offset div. 2 exceeds supported range (-12 to 12)" );
-  xConfirmPara( m_loopFilterCbBetaOffsetDiv2 < -12 || m_loopFilterCbBetaOffsetDiv2 > 12,      "Loop Filter Beta Offset div. 2 exceeds supported range (-12 to 12" );
-  xConfirmPara( m_loopFilterCbTcOffsetDiv2 < -12 || m_loopFilterCbTcOffsetDiv2 > 12,          "Loop Filter Tc Offset div. 2 exceeds supported range (-12 to 12)" );
-  xConfirmPara( m_loopFilterCrBetaOffsetDiv2 < -12 || m_loopFilterCrBetaOffsetDiv2 > 12,      "Loop Filter Beta Offset div. 2 exceeds supported range (-12 to 12" );
-  xConfirmPara( m_loopFilterCrTcOffsetDiv2 < -12 || m_loopFilterCrTcOffsetDiv2 > 12,          "Loop Filter Tc Offset div. 2 exceeds supported range (-12 to 12)" );
+  xConfirmPara( m_deblockingFilterBetaOffsetDiv2 < -12 || m_deblockingFilterBetaOffsetDiv2 > 12,          "Loop Filter Beta Offset div. 2 exceeds supported range (-12 to 12" );
+  xConfirmPara( m_deblockingFilterTcOffsetDiv2 < -12 || m_deblockingFilterTcOffsetDiv2 > 12,              "Loop Filter Tc Offset div. 2 exceeds supported range (-12 to 12)" );
+  xConfirmPara( m_deblockingFilterCbBetaOffsetDiv2 < -12 || m_deblockingFilterCbBetaOffsetDiv2 > 12,      "Loop Filter Beta Offset div. 2 exceeds supported range (-12 to 12" );
+  xConfirmPara( m_deblockingFilterCbTcOffsetDiv2 < -12 || m_deblockingFilterCbTcOffsetDiv2 > 12,          "Loop Filter Tc Offset div. 2 exceeds supported range (-12 to 12)" );
+  xConfirmPara( m_deblockingFilterCrBetaOffsetDiv2 < -12 || m_deblockingFilterCrBetaOffsetDiv2 > 12,      "Loop Filter Beta Offset div. 2 exceeds supported range (-12 to 12" );
+  xConfirmPara( m_deblockingFilterCrTcOffsetDiv2 < -12 || m_deblockingFilterCrTcOffsetDiv2 > 12,          "Loop Filter Tc Offset div. 2 exceeds supported range (-12 to 12)" );
   xConfirmPara( m_iSearchRange < 0 ,                                                        "Search Range must be more than 0" );
   xConfirmPara( m_bipredSearchRange < 0 ,                                                   "Bi-prediction refinement search range must be more than 0" );
   xConfirmPara( m_minSearchWindow < 0,                                                      "Minimum motion search window size for the adaptive window ME must be greater than or equal to 0" );
@@ -2752,6 +3269,10 @@ bool EncAppCfg::xCheckParameter()
     if (m_updateCtrl > 0 && m_adpOption > 2) { m_adpOption -= 2; }
   }
 
+  if (m_ctiSEIEnabled)
+  {
+    xConfirmPara(m_ctiSEINumberChromaLut < 0 || m_ctiSEINumberChromaLut > 2, "CTI number of chroma LUTs is out of range");
+  }
   xConfirmPara( m_cbQpOffset < -12,   "Min. Chroma Cb QP Offset is -12" );
   xConfirmPara( m_cbQpOffset >  12,   "Max. Chroma Cb QP Offset is  12" );
   xConfirmPara( m_crQpOffset < -12,   "Min. Chroma Cr QP Offset is -12" );
@@ -2767,18 +3288,30 @@ bool EncAppCfg::xCheckParameter()
     msg( WARNING, "****************************************************************************\n");
     m_dualTree = false;
   }
-#if JVET_T0064
   if (m_alf)
   {
-    xConfirmPara(m_alfStrength < 0.0, "ALFStrength is less than 0. Valid range is 0.0 <= ALFStrength <= 1.0" );
-    xConfirmPara(m_alfStrength > 1.0, "ALFStrength is greater than 1. Valid range is 0.0 <= ALFStrength <= 1.0" );
+    xConfirmPara(m_alfStrengthLuma < 0.0, "ALFStrengthLuma is less than 0. Valid range is 0.0 <= ALFStrengthLuma <= 1.0");
+    xConfirmPara(m_alfStrengthLuma > 1.0, "ALFStrengthLuma is greater than 1. Valid range is 0.0 <= ALFStrengthLuma <= 1.0");
   }
   if (m_ccalf)
   {
     xConfirmPara(m_ccalfStrength < 0.0, "CCALFStrength is less than 0. Valid range is 0.0 <= CCALFStrength <= 1.0");
     xConfirmPara(m_ccalfStrength > 1.0, "CCALFStrength is greater than 1. Valid range is 0.0 <= CCALFStrength <= 1.0");
-  }  
-#endif
+  }
+  if (m_alf)
+  {
+    xConfirmPara(m_alfStrengthChroma < 0.0, "ALFStrengthChroma is less than 0. Valid range is 0.0 <= ALFStrengthChroma <= 1.0");
+    xConfirmPara(m_alfStrengthChroma > 1.0, "ALFStrengthChroma is greater than 1. Valid range is 0.0 <= ALFStrengthChroma <= 1.0");
+    xConfirmPara(m_alfStrengthTargetLuma < 0.0, "ALFStrengthTargetLuma is less than 0. Valid range is 0.0 <= ALFStrengthTargetLuma <= 1.0");
+    xConfirmPara(m_alfStrengthTargetLuma > 1.0, "ALFStrengthTargetLuma is greater than 1. Valid range is 0.0 <= ALFStrengthTargetLuma <= 1.0");
+    xConfirmPara(m_alfStrengthTargetChroma < 0.0, "ALFStrengthTargetChroma is less than 0. Valid range is 0.0 <= ALFStrengthTargetChroma <= 1.0");
+    xConfirmPara(m_alfStrengthTargetChroma > 1.0, "ALFStrengthTargetChroma is greater than 1. Valid range is 0.0 <= ALFStrengthTargetChroma <= 1.0");
+  }
+  if (m_ccalf)
+  {
+    xConfirmPara(m_ccalfStrengthTarget < 0.0, "CCALFStrengthTarget is less than 0. Valid range is 0.0 <= CCALFStrengthTarget <= 1.0");
+    xConfirmPara(m_ccalfStrengthTarget > 1.0, "CCALFStrengthTarget is greater than 1. Valid range is 0.0 <= CCALFStrengthTarget <= 1.0");
+  }
   if (m_ccalf && (m_chromaFormatIDC == CHROMA_400))
   {
     msg( WARNING, "****************************************************************************\n");
@@ -2816,7 +3349,7 @@ bool EncAppCfg::xCheckParameter()
   xConfirmPara( m_uiMaxTT[2] > 64,                                                          "Maximum TT size for chroma block in I slice should be smaller than or equal to 64");
   xConfirmPara( m_uiMinQT[0] < minCuSize,                                                   "Min Luma QT size in I slices should be larger than or equal to minCuSize");
   xConfirmPara( m_uiMinQT[1] < minCuSize,                                                   "Min Luma QT size in non-I slices should be larger than or equal to minCuSize");
-  xConfirmPara((m_iSourceWidth % minCuSize ) || (m_iSourceHeight % minCuSize),              "Picture width or height is not a multiple of minCuSize");
+  xConfirmPara((m_sourceWidth % minCuSize ) || (m_sourceHeight % minCuSize),              "Picture width or height is not a multiple of minCuSize");
   const int minDiff = (int)floorLog2(m_uiMinQT[2]) - std::max(MIN_CU_LOG2, (int)m_log2MinCuSize - (int)getChannelTypeScaleX(CHANNEL_TYPE_CHROMA, m_chromaFormatIDC));
   xConfirmPara( minDiff < 0 ,                                                               "Min Chroma QT size in I slices is smaller than Min Luma CU size even considering color format");
   xConfirmPara( (m_uiMinQT[2] << (int)getChannelTypeScaleX(CHANNEL_TYPE_CHROMA, m_chromaFormatIDC)) > std::min(64, (int)m_uiCTUSize),
@@ -2840,8 +3373,8 @@ bool EncAppCfg::xCheckParameter()
   xConfirmPara( m_uiMaxTT[2] < (m_uiMinQT[2] << (int)getChannelTypeScaleX(CHANNEL_TYPE_CHROMA, m_chromaFormatIDC)),
                                                                                             "Maximum TT size for chroma block in I slice should be larger than minimum QT size");
   xConfirmPara( m_uiMaxTT[2] > m_uiCTUSize,                                                 "Maximum TT size for chroma block in I slice should be smaller than or equal to CTUSize");
-  xConfirmPara( (m_iSourceWidth  % (std::max(8u, m_log2MinCuSize))) != 0,                   "Resulting coded frame width must be a multiple of Max(8, the minimum CU size)");
-  xConfirmPara( (m_iSourceHeight % (std::max(8u, m_log2MinCuSize))) != 0,                   "Resulting coded frame height must be a multiple of Max(8, the minimum CU size)");
+  xConfirmPara( (m_sourceWidth  % (std::max(8u, m_log2MinCuSize))) != 0,                   "Resulting coded frame width must be a multiple of Max(8, the minimum CU size)");
+  xConfirmPara( (m_sourceHeight % (std::max(8u, m_log2MinCuSize))) != 0,                   "Resulting coded frame height must be a multiple of Max(8, the minimum CU size)");
   if (m_uiMaxMTTHierarchyDepthI == 0)
   {
     xConfirmPara(m_uiMaxBT[0] != m_uiMinQT[0], "MaxBTLumaISlice shall be equal to MinQTLumaISlice when MaxMTTHierarchyDepthISliceL is 0.");
@@ -2886,6 +3419,10 @@ bool EncAppCfg::xCheckParameter()
     xConfirmPara(!m_useTransformSkip, "BDPCM cannot be used when transform skip is disabled.");
   }
 
+  if (m_tsrcRicePresentFlag)
+  {
+    xConfirmPara(!m_useTransformSkip, "TSRCRicePresent cannot be enabled when transform skip is disabled.");
+  }
 
   if (!m_alf)
   {
@@ -2893,11 +3430,11 @@ bool EncAppCfg::xCheckParameter()
   }
 
 
-  xConfirmPara( m_iSourceWidth  % SPS::getWinUnitX(m_chromaFormatIDC) != 0, "Picture width must be an integer multiple of the specified chroma subsampling");
-  xConfirmPara( m_iSourceHeight % SPS::getWinUnitY(m_chromaFormatIDC) != 0, "Picture height must be an integer multiple of the specified chroma subsampling");
+  xConfirmPara( m_sourceWidth  % SPS::getWinUnitX(m_chromaFormatIDC) != 0, "Picture width must be an integer multiple of the specified chroma subsampling");
+  xConfirmPara( m_sourceHeight % SPS::getWinUnitY(m_chromaFormatIDC) != 0, "Picture height must be an integer multiple of the specified chroma subsampling");
 
-  xConfirmPara( m_aiPad[0] % SPS::getWinUnitX(m_chromaFormatIDC) != 0, "Horizontal padding must be an integer multiple of the specified chroma subsampling");
-  xConfirmPara( m_aiPad[1] % SPS::getWinUnitY(m_chromaFormatIDC) != 0, "Vertical padding must be an integer multiple of the specified chroma subsampling");
+  xConfirmPara( m_sourcePadding[0] % SPS::getWinUnitX(m_chromaFormatIDC) != 0, "Horizontal padding must be an integer multiple of the specified chroma subsampling");
+  xConfirmPara( m_sourcePadding[1] % SPS::getWinUnitY(m_chromaFormatIDC) != 0, "Vertical padding must be an integer multiple of the specified chroma subsampling");
 
   xConfirmPara( m_confWinLeft   % SPS::getWinUnitX(m_chromaFormatIDC) != 0, "Left conformance window offset must be an integer multiple of the specified chroma subsampling");
   xConfirmPara( m_confWinRight  % SPS::getWinUnitX(m_chromaFormatIDC) != 0, "Right conformance window offset must be an integer multiple of the specified chroma subsampling");
@@ -2975,16 +3512,16 @@ bool EncAppCfg::xCheckParameter()
     }
   }
 
-  if ( (m_iIntraPeriod != 1) && !m_loopFilterOffsetInPPS && (!m_bLoopFilterDisable) )
+  if ( (m_iIntraPeriod != 1) && !m_deblockingFilterOffsetInPPS && (!m_deblockingFilterDisable) )
   {
     for(int i=0; i<m_iGOPSize; i++)
     {
-      xConfirmPara( (m_GOPList[i].m_betaOffsetDiv2 + m_loopFilterBetaOffsetDiv2) < -12 || (m_GOPList[i].m_betaOffsetDiv2 + m_loopFilterBetaOffsetDiv2) > 12, "Loop Filter Beta Offset div. 2 for one of the GOP entries exceeds supported range (-12 to 12)" );
-      xConfirmPara( (m_GOPList[i].m_tcOffsetDiv2 + m_loopFilterTcOffsetDiv2) < -12 || (m_GOPList[i].m_tcOffsetDiv2 + m_loopFilterTcOffsetDiv2) > 12, "Loop Filter Tc Offset div. 2 for one of the GOP entries exceeds supported range (-12 to 12)" );
-      xConfirmPara( (m_GOPList[i].m_CbBetaOffsetDiv2 + m_loopFilterCbBetaOffsetDiv2) < -12 || (m_GOPList[i].m_CbBetaOffsetDiv2 + m_loopFilterCbBetaOffsetDiv2) > 12, "Loop Filter Beta Offset div. 2 for one of the GOP entries exceeds supported range (-12 to 12)" );
-      xConfirmPara( (m_GOPList[i].m_CbTcOffsetDiv2 + m_loopFilterCbTcOffsetDiv2) < -12 || (m_GOPList[i].m_CbTcOffsetDiv2 + m_loopFilterCbTcOffsetDiv2) > 12, "Loop Filter Tc Offset div. 2 for one of the GOP entries exceeds supported range (-12 to 12)" );
-      xConfirmPara( (m_GOPList[i].m_CrBetaOffsetDiv2 + m_loopFilterCrBetaOffsetDiv2) < -12 || (m_GOPList[i].m_CrBetaOffsetDiv2 + m_loopFilterCrBetaOffsetDiv2) > 12, "Loop Filter Beta Offset div. 2 for one of the GOP entries exceeds supported range (-12 to 12)" );
-      xConfirmPara( (m_GOPList[i].m_CrTcOffsetDiv2 + m_loopFilterCrTcOffsetDiv2) < -12 || (m_GOPList[i].m_CrTcOffsetDiv2 + m_loopFilterCrTcOffsetDiv2) > 12, "Loop Filter Tc Offset div. 2 for one of the GOP entries exceeds supported range (-12 to 12)" );
+      xConfirmPara( (m_GOPList[i].m_betaOffsetDiv2 + m_deblockingFilterBetaOffsetDiv2) < -12 || (m_GOPList[i].m_betaOffsetDiv2 + m_deblockingFilterBetaOffsetDiv2) > 12, "Loop Filter Beta Offset div. 2 for one of the GOP entries exceeds supported range (-12 to 12)" );
+      xConfirmPara( (m_GOPList[i].m_tcOffsetDiv2 + m_deblockingFilterTcOffsetDiv2) < -12 || (m_GOPList[i].m_tcOffsetDiv2 + m_deblockingFilterTcOffsetDiv2) > 12, "Loop Filter Tc Offset div. 2 for one of the GOP entries exceeds supported range (-12 to 12)" );
+      xConfirmPara( (m_GOPList[i].m_CbBetaOffsetDiv2 + m_deblockingFilterCbBetaOffsetDiv2) < -12 || (m_GOPList[i].m_CbBetaOffsetDiv2 + m_deblockingFilterCbBetaOffsetDiv2) > 12, "Loop Filter Beta Offset div. 2 for one of the GOP entries exceeds supported range (-12 to 12)" );
+      xConfirmPara( (m_GOPList[i].m_CbTcOffsetDiv2 + m_deblockingFilterCbTcOffsetDiv2) < -12 || (m_GOPList[i].m_CbTcOffsetDiv2 + m_deblockingFilterCbTcOffsetDiv2) > 12, "Loop Filter Tc Offset div. 2 for one of the GOP entries exceeds supported range (-12 to 12)" );
+      xConfirmPara( (m_GOPList[i].m_CrBetaOffsetDiv2 + m_deblockingFilterCrBetaOffsetDiv2) < -12 || (m_GOPList[i].m_CrBetaOffsetDiv2 + m_deblockingFilterCrBetaOffsetDiv2) > 12, "Loop Filter Beta Offset div. 2 for one of the GOP entries exceeds supported range (-12 to 12)" );
+      xConfirmPara( (m_GOPList[i].m_CrTcOffsetDiv2 + m_deblockingFilterCrTcOffsetDiv2) < -12 || (m_GOPList[i].m_CrTcOffsetDiv2 + m_deblockingFilterCrTcOffsetDiv2) > 12, "Loop Filter Tc Offset div. 2 for one of the GOP entries exceeds supported range (-12 to 12)" );
     }
   }
 
@@ -3335,8 +3872,8 @@ bool EncAppCfg::xCheckParameter()
     uint32_t colIdx, rowIdx;
     uint32_t remSize;
 
-    pps.setPicWidthInLumaSamples( m_iSourceWidth );
-    pps.setPicHeightInLumaSamples( m_iSourceHeight );
+    pps.setPicWidthInLumaSamples( m_sourceWidth );
+    pps.setPicHeightInLumaSamples( m_sourceHeight );
     pps.setLog2CtuSize( floorLog2(m_uiCTUSize) );
 
     // set default tile column if not provided
@@ -3645,6 +4182,11 @@ bool EncAppCfg::xCheckParameter()
     xConfirmPara(m_framePackingSEIType < 3 || m_framePackingSEIType > 5 , "SEIFramePackingType must be in rage 3 to 5");
   }
 
+  if (m_doSEIEnabled)
+  {
+    xConfirmPara(m_doSEITransformType < 0 || m_doSEITransformType > 7, "SEIDisplayOrientationTransformType must be in rage 0 to 7");
+  }
+
   if( m_erpSEIEnabled && !m_erpSEICancelFlag )
   {
     xConfirmPara( m_erpSEIGuardBandType < 0 || m_erpSEIGuardBandType > 8, "SEIEquirectangularprojectionGuardBandType must be in the range of 0 to 7");
@@ -3812,8 +4354,8 @@ void EncAppCfg::xPrintParameter()
   msg( DETAILS, "Input          File                    : %s\n", m_inputFileName.c_str() );
   msg( DETAILS, "Bitstream      File                    : %s\n", m_bitstreamFileName.c_str() );
   msg( DETAILS, "Reconstruction File                    : %s\n", m_reconFileName.c_str() );
-  msg( DETAILS, "Real     Format                        : %dx%d %gHz\n", m_iSourceWidth - m_confWinLeft - m_confWinRight, m_iSourceHeight - m_confWinTop - m_confWinBottom, (double)m_iFrameRate / m_temporalSubsampleRatio );
-  msg( DETAILS, "Internal Format                        : %dx%d %gHz\n", m_iSourceWidth, m_iSourceHeight, (double)m_iFrameRate / m_temporalSubsampleRatio );
+  msg( DETAILS, "Real     Format                        : %dx%d %gHz\n", m_sourceWidth - m_confWinLeft - m_confWinRight, m_sourceHeight - m_confWinTop - m_confWinBottom, (double)m_iFrameRate / m_temporalSubsampleRatio );
+  msg( DETAILS, "Internal Format                        : %dx%d %gHz\n", m_sourceWidth, m_sourceHeight, (double)m_iFrameRate / m_temporalSubsampleRatio );
   msg( DETAILS, "Sequence PSNR output                   : %s\n", ( m_printMSEBasedSequencePSNR ? "Linear average, MSE-based" : "Linear average only" ) );
   msg( DETAILS, "Hexadecimal PSNR output                : %s\n", ( m_printHexPsnr ? "Enabled" : "Disabled" ) );
   msg( DETAILS, "Sequence MSE output                    : %s\n", ( m_printSequenceMSE ? "Enabled" : "Disabled" ) );
@@ -3835,6 +4377,9 @@ void EncAppCfg::xPrintParameter()
   {
     msg( DETAILS, "Profile                                : %s\n", profileToString(m_profile) );
   }
+#if JVET_W2005_RANGE_EXTENSION_PROFILES
+  msg( DETAILS,"GeneralLowerBitRateConstraintFlag      : %d\n", m_generalLowerBitRateConstraintFlag );
+#endif
   msg(DETAILS, "CTU size / min CU size                 : %d / %d \n", m_uiMaxCUWidth, 1 << m_log2MinCuSize);
 
   msg(DETAILS, "subpicture info present flag           : %s\n", m_subPicInfoPresentFlag ? "Enabled" : "Disabled");
@@ -3877,6 +4422,7 @@ void EncAppCfg::xPrintParameter()
   msg( DETAILS, "Intra period                           : %d\n", m_iIntraPeriod );
   msg( DETAILS, "Decoding refresh type                  : %d\n", m_iDecodingRefreshType );
   msg( DETAILS, "DRAP period                            : %d\n", m_drapPeriod );
+  msg( DETAILS, "EDRAP period                           : %d\n", m_edrapPeriod );
 #if QP_SWITCHING_FOR_PARALLEL
   if (m_qpIncrementAtSourceFrame.bPresent)
   {
@@ -3899,11 +4445,30 @@ void EncAppCfg::xPrintParameter()
   msg( DETAILS, "MSB-extended bit depth                 : (Y:%d, C:%d)\n", m_MSBExtendedBitDepth[CHANNEL_TYPE_LUMA], m_MSBExtendedBitDepth[CHANNEL_TYPE_CHROMA] );
   msg( DETAILS, "Internal bit depth                     : (Y:%d, C:%d)\n", m_internalBitDepth[CHANNEL_TYPE_LUMA], m_internalBitDepth[CHANNEL_TYPE_CHROMA] );
   msg( DETAILS, "Intra reference smoothing              : %s\n", (m_enableIntraReferenceSmoothing           ? "Enabled" : "Disabled") );
-  msg( DETAILS, "cu_chroma_qp_offset_subdiv             : %d\n", m_cuChromaQpOffsetSubdiv);
+  if (m_cuChromaQpOffsetList.size() > 0)
+  {
+    msg( DETAILS, "Chroma QP offset list                  : (" );
+    for (int i=0; i < m_cuChromaQpOffsetList.size(); i++)
+    {
+      msg( DETAILS, "%d %d %d%s", m_cuChromaQpOffsetList[i].u.comp.CbOffset, m_cuChromaQpOffsetList[i].u.comp.CrOffset, m_cuChromaQpOffsetList[i].u.comp.JointCbCrOffset,
+        (i+1 < m_cuChromaQpOffsetList.size() ? ", " : ")\n") );
+    }
+    msg( DETAILS, "cu_chroma_qp_offset_subdiv             : %d\n", m_cuChromaQpOffsetSubdiv);
+    msg( DETAILS, "cu_chroma_qp_offset_enabled_flag       : %s\n", (m_cuChromaQpOffsetEnabled ? "Enabled" : "Disabled") );
+  }
+  else
+  {
+    msg( DETAILS, "Chroma QP offset list                  : Disabled\n" );
+  }
   msg( DETAILS, "extended_precision_processing_flag     : %s\n", (m_extendedPrecisionProcessingFlag         ? "Enabled" : "Disabled") );
+  msg( DETAILS, "TSRC_Rice_present_flag                 : %s\n", (m_tsrcRicePresentFlag                     ? "Enabled" : "Disabled") );
+#if JVET_W0046_RLSCP
+  msg( DETAILS, "reverse_last_sig_coeff_enabled_flag    : %s\n", (m_reverseLastSigCoeffEnabledFlag          ? "Enabled" : "Disabled") );
+#endif
   msg( DETAILS, "transform_skip_rotation_enabled_flag   : %s\n", (m_transformSkipRotationEnabledFlag        ? "Enabled" : "Disabled") );
   msg( DETAILS, "transform_skip_context_enabled_flag    : %s\n", (m_transformSkipContextEnabledFlag         ? "Enabled" : "Disabled") );
   msg( DETAILS, "high_precision_offsets_enabled_flag    : %s\n", (m_highPrecisionOffsetsEnabledFlag         ? "Enabled" : "Disabled") );
+  msg( DETAILS, "rrc_rice_extension_flag                : %s\n", (m_rrcRiceExtensionEnableFlag                 ? "Enabled" : "Disabled") );
   msg( DETAILS, "persistent_rice_adaptation_enabled_flag: %s\n", (m_persistentRiceAdaptationEnabledFlag     ? "Enabled" : "Disabled") );
   msg( DETAILS, "cabac_bypass_alignment_enabled_flag    : %s\n", (m_cabacBypassAlignmentEnabledFlag         ? "Enabled" : "Disabled") );
 
@@ -3937,6 +4502,17 @@ void EncAppCfg::xPrintParameter()
 #endif
   }
 
+#if GDR_ENABLED
+  msg(DETAILS, "GDREnabled                             : %d\n", m_gdrEnabled);
+
+  if (m_gdrEnabled)
+  {
+    msg(DETAILS, "GDR Start                              : %d\n", m_gdrPocStart);
+    msg(DETAILS, "GDR Interval                           : %d\n", m_gdrInterval);
+    msg(DETAILS, "GDR Period                             : %d\n", m_gdrPeriod);
+  }
+#endif
+
   msg( DETAILS, "Max Num Merge Candidates               : %d\n", m_maxNumMergeCand );
   msg( DETAILS, "Max Num Affine Merge Candidates        : %d\n", m_maxNumAffineMergeCand );
   msg( DETAILS, "Max Num Geo Merge Candidates           : %d\n", m_maxNumGeoCand );
@@ -3975,7 +4551,7 @@ void EncAppCfg::xPrintParameter()
   msg( VERBOSE, "WPP:%d ", (int)m_useWeightedPred);
   msg( VERBOSE, "WPB:%d ", (int)m_useWeightedBiPred);
   msg( VERBOSE, "PME:%d ", m_log2ParallelMergeLevel);
-  const int iWaveFrontSubstreams = m_entropyCodingSyncEnabledFlag ? (m_iSourceHeight + m_uiMaxCUHeight - 1) / m_uiMaxCUHeight : 1;
+  const int iWaveFrontSubstreams = m_entropyCodingSyncEnabledFlag ? (m_sourceHeight + m_uiMaxCUHeight - 1) / m_uiMaxCUHeight : 1;
   msg( VERBOSE, " WaveFrontSynchro:%d WaveFrontSubstreams:%d", m_entropyCodingSyncEnabledFlag?1:0, iWaveFrontSubstreams);
   msg( VERBOSE, " ScalingList:%d ", m_useScalingListId );
   msg( VERBOSE, "TMVPMode:%d ", m_TMVPModeId );
@@ -4078,14 +4654,6 @@ void EncAppCfg::xPrintParameter()
   if( m_MIP ) msg(VERBOSE, "FastMIP:%d ", m_useFastMIP);
   msg( VERBOSE, "FastLocalDualTree:%d ", m_fastLocalDualTreeMode );
 
-  msg( VERBOSE, "NumSplitThreads:%d ", m_numSplitThreads );
-  if( m_numSplitThreads > 1 )
-  {
-    msg( VERBOSE, "ForceSingleSplitThread:%d ", m_forceSplitSequential );
-  }
-  msg( VERBOSE, "NumWppThreads:%d+%d ", m_numWppThreads, m_numWppExtraLines );
-  msg( VERBOSE, "EnsureWppBitEqual:%d ", m_ensureWppBitEqual );
-
   if (m_resChangeInClvsEnabled)
   {
     msg( VERBOSE, "RPR:(%1.2lfx, %1.2lfx)|%d ", m_scalingRatioHor, m_scalingRatioVer, m_switchPocPeriod );
@@ -4095,10 +4663,18 @@ void EncAppCfg::xPrintParameter()
     msg( VERBOSE, "RPR:%d ", 0 );
   }
   msg(VERBOSE, "TemporalFilter:%d ", m_gopBasedTemporalFilterEnabled);
+  msg(VERBOSE, "SEI CTI:%d ", m_ctiSEIEnabled);
 #if EXTENSION_360_VIDEO
   m_ext360.outputConfigurationSummary();
 #endif
 
+#if JVET_W0133_CONSTRAINED_RASL_ENCODING
+  if( m_constrainedRaslEncoding )
+  {
+    msg(VERBOSE, "\n\nWarning: with SEIConstrainedRASL enabled, LMChroma estimation is skipped in RASL frames" );
+  }
+#endif
+
   msg( VERBOSE, "\n\n");
 
   msg( NOTICE, "\n");
diff --git a/source/App/EncoderApp/EncAppCfg.h b/source/App/EncoderApp/EncAppCfg.h
index 47b2ce682..eb145e69c 100644
--- a/source/App/EncoderApp/EncAppCfg.h
+++ b/source/App/EncoderApp/EncAppCfg.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -95,8 +95,8 @@ protected:
   int       m_iFrameRate;                                     ///< source frame-rates (Hz)
   uint32_t      m_FrameSkip;                                      ///< number of skipped frames from the beginning
   uint32_t      m_temporalSubsampleRatio;                         ///< temporal subsample ratio, 2 means code every two frames
-  int       m_iSourceWidth;                                   ///< source width in pixel
-  int       m_iSourceHeight;                                  ///< source height in pixel (when interlaced = field height)
+  int       m_sourceWidth;                                   ///< source width in pixel
+  int       m_sourceHeight;                                  ///< source height in pixel (when interlaced = field height)
 #if EXTENSION_360_VIDEO
   int       m_inputFileWidth;                                 ///< width of image in input file  (this is equivalent to sourceWidth,  if sourceWidth  is not subsequently altered due to padding)
   int       m_inputFileHeight;                                ///< height of image in input file (this is equivalent to sourceHeight, if sourceHeight is not subsequently altered due to padding)
@@ -105,16 +105,16 @@ protected:
 
   bool      m_isField;                                        ///< enable field coding
   bool      m_isTopFieldFirst;
-  bool      m_bEfficientFieldIRAPEnabled;                     ///< enable an efficient field IRAP structure.
-  bool      m_bHarmonizeGopFirstFieldCoupleEnabled;
+  bool      m_efficientFieldIRAPEnabled;   ///< enable an efficient field IRAP structure.
+  bool      m_harmonizeGopFirstFieldCoupleEnabled;
 
   int       m_conformanceWindowMode;
   int       m_confWinLeft;
   int       m_confWinRight;
   int       m_confWinTop;
   int       m_confWinBottom;
+  int       m_sourcePadding[2];                                       ///< number of padded pixels for width and height
   int       m_framesToBeEncoded;                              ///< number of encoded frames
-  int       m_aiPad[2];                                       ///< number of padded pixels for width and height
   bool      m_AccessUnitDelimiter;                            ///< add Access Unit Delimiter NAL units
   bool      m_enablePictureHeaderInSliceHeader;               ///< Enable Picture Header in Slice Header
   InputColourSpaceConversion m_inputColourSpaceConvert;       ///< colour space conversion to apply to input video
@@ -127,6 +127,7 @@ protected:
   bool      m_printFrameMSE;
   bool      m_printSequenceMSE;
   bool      m_printMSSSIM;
+  bool      m_printWPSNR;
   bool      m_cabacZeroWordPaddingEnabled;
   bool      m_bClipInputVideoToRec709Range;
   bool      m_bClipOutputVideoToRec709Range;
@@ -188,6 +189,9 @@ protected:
   bool      m_noCraConstraintFlag;
   bool      m_noGdrConstraintFlag;
   bool      m_noApsConstraintFlag;
+#if JVET_W2005_RANGE_EXTENSION_PROFILES
+  bool      m_generalLowerBitRateConstraintFlag;
+#endif
 
   // profile/level
   Profile::Name m_profile;
@@ -215,9 +219,17 @@ protected:
   bool          m_noSubpicInfoConstraintFlag;
   // coding structure
   int       m_iIntraPeriod;                                   ///< period of I-slice (random access period)
+#if GDR_ENABLED 
+  bool      m_gdrEnabled;
+  int       m_gdrPocStart;
+  int       m_gdrPeriod;
+  int       m_gdrInterval;  
+  bool      m_gdrNoHash;  
+#endif
   int       m_iDecodingRefreshType;                           ///< random access type
   int       m_iGOPSize;                                       ///< GOP size of hierarchical structure
   int       m_drapPeriod;                                     ///< period of dependent RAP pictures
+  int       m_edrapPeriod;                                    ///< period of extended dependent RAP pictures
   bool      m_rewriteParamSets;                              ///< Flag to enable rewriting of parameter sets at random access points
   RPLEntry  m_RPLList0[MAX_GOP];                               ///< the RPL entries from the config file
   RPLEntry  m_RPLList1[MAX_GOP];                               ///< the RPL entries from the config file
@@ -232,6 +244,7 @@ protected:
   uint32_t      m_log2MaxTransformSkipBlockSize;                  ///< transform-skip maximum size (minimum of 2)
   bool      m_transformSkipRotationEnabledFlag;               ///< control flag for transform-skip/transquant-bypass residual rotation
   bool      m_transformSkipContextEnabledFlag;                ///< control flag for transform-skip/transquant-bypass single significance map context
+  bool      m_rrcRiceExtensionEnableFlag;                        ///< control flag for enabling extension of the Golomb-Rice parameter derivation for RRC
   bool      m_persistentRiceAdaptationEnabledFlag;            ///< control flag for Golomb-Rice parameter adaptation over each slice
   bool      m_cabacBypassAlignmentEnabledFlag;
   bool      m_ISP;
@@ -253,9 +266,11 @@ protected:
   std::string m_dQPFileName;                                  ///< QP offset for each slice (initialized from external file)
   int*      m_aidQP;                                          ///< array of slice QP values
   int       m_iMaxDeltaQP;                                    ///< max. |delta QP|
-  uint32_t      m_uiDeltaQpRD;                                    ///< dQP range for multi-pass slice QP optimization
+  uint32_t  m_uiDeltaQpRD;                                    ///< dQP range for multi-pass slice QP optimization
   int       m_cuQpDeltaSubdiv;                                ///< Maximum subdiv for CU luma Qp adjustment (0:default)
   int       m_cuChromaQpOffsetSubdiv;                         ///< If negative, then do not apply chroma qp offsets.
+  std::vector<ChromaQpAdj> m_cuChromaQpOffsetList;            ///< Local chroma QP offsets list (to be signalled in PPS)
+  bool      m_cuChromaQpOffsetEnabled;                        ///< Enable local chroma QP offsets (slice level flag)
   bool      m_bFastDeltaQP;                                   ///< Fast Delta QP (false:default)
 
   int       m_cbQpOffset;                                     ///< Chroma Cb QP Offset (0:default)
@@ -275,6 +290,23 @@ protected:
   LumaLevelToDeltaQPMapping m_lumaLevelToDeltaQPMapping;      ///< mapping from luma level to Delta QP.
 #endif
   SEIMasteringDisplay m_masteringDisplay;
+  bool      m_smoothQPReductionEnable;
+#if JVET_W0043
+  double    m_smoothQPReductionThresholdIntra;
+  double    m_smoothQPReductionModelScaleIntra;
+  double    m_smoothQPReductionModelOffsetIntra;
+  int       m_smoothQPReductionLimitIntra;
+  double    m_smoothQPReductionThresholdInter;
+  double    m_smoothQPReductionModelScaleInter;
+  double    m_smoothQPReductionModelOffsetInter;
+  int       m_smoothQPReductionLimitInter;
+#else
+  double    m_smoothQPReductionThreshold;
+  double    m_smoothQPReductionModelScale;
+  double    m_smoothQPReductionModelOffset;
+  int       m_smoothQPReductionLimit;
+#endif
+  int       m_smoothQPReductionPeriodicity;
 
   bool      m_bUseAdaptiveQP;                                 ///< Flag for enabling QP adaptation based on a psycho-visual model
   int       m_iQPAdaptationRange;                             ///< dQP range by QP adaptation
@@ -393,13 +425,6 @@ protected:
   bool      m_useFastMIP;
   int       m_fastLocalDualTreeMode;
 
-
-  int       m_numSplitThreads;
-  bool      m_forceSplitSequential;
-  int       m_numWppThreads;
-  int       m_numWppExtraLines;
-  bool      m_ensureWppBitEqual;
-
   int       m_log2MaxTbSize;
   // coding tools (bit-depth)
   int       m_inputBitDepth   [MAX_NUM_CHANNEL_TYPE];         ///< bit-depth of input file
@@ -407,6 +432,10 @@ protected:
   int       m_MSBExtendedBitDepth[MAX_NUM_CHANNEL_TYPE];      ///< bit-depth of input samples after MSB extension
   int       m_internalBitDepth[MAX_NUM_CHANNEL_TYPE];         ///< bit-depth codec operates at (input/output files will be converted)
   bool      m_extendedPrecisionProcessingFlag;
+  bool      m_tsrcRicePresentFlag;
+#if JVET_W0046_RLSCP
+  bool      m_reverseLastSigCoeffEnabledFlag;
+#endif
   bool      m_highPrecisionOffsetsEnabledFlag;
 
   //coding tools (chroma format)
@@ -415,6 +444,9 @@ protected:
 
   // coding tool (SAO)
   bool      m_bUseSAO;
+#if JVET_W0129_ENABLE_ALF_TRUEORG
+  bool      m_saoTrueOrg;
+#endif
   bool      m_bTestSAODisableAtPictureLevel;
   double    m_saoEncodingRate;                                ///< When >0 SAO early picture termination is enabled for luma and chroma
   double    m_saoEncodingRateChroma;                          ///< The SAO early picture termination rate to use for chroma (when m_SaoEncodingRate is >0). If <=0, use results for luma.
@@ -422,14 +454,14 @@ protected:
   bool      m_saoCtuBoundary;                                 ///< SAO parameter estimation using non-deblocked pixels for CTU bottom and right boundary areas
   bool      m_saoGreedyMergeEnc;                              ///< SAO greedy merge encoding algorithm
   // coding tools (loop filter)
-  bool      m_bLoopFilterDisable;                             ///< flag for using deblocking filter
-  bool      m_loopFilterOffsetInPPS;                         ///< offset for deblocking filter in 0 = slice header, 1 = PPS
-  int       m_loopFilterBetaOffsetDiv2;                     ///< beta offset for deblocking filter
-  int       m_loopFilterTcOffsetDiv2;                       ///< tc offset for deblocking filter
-  int       m_loopFilterCbBetaOffsetDiv2;                     ///< beta offset for Cb deblocking filter
-  int       m_loopFilterCbTcOffsetDiv2;                       ///< tc offset for Cb deblocking filter
-  int       m_loopFilterCrBetaOffsetDiv2;                     ///< beta offset for Cr deblocking filter
-  int       m_loopFilterCrTcOffsetDiv2;                       ///< tc offset for Cr deblocking filter
+  bool      m_deblockingFilterDisable;                        ///< flag for using deblocking filter
+  bool      m_deblockingFilterOffsetInPPS;                    ///< offset for deblocking filter in 0 = slice header, 1 = PPS
+  int       m_deblockingFilterBetaOffsetDiv2;                 ///< beta offset for deblocking filter
+  int       m_deblockingFilterTcOffsetDiv2;                   ///< tc offset for deblocking filter
+  int       m_deblockingFilterCbBetaOffsetDiv2;               ///< beta offset for Cb deblocking filter
+  int       m_deblockingFilterCbTcOffsetDiv2;                 ///< tc offset for Cb deblocking filter
+  int       m_deblockingFilterCrBetaOffsetDiv2;               ///< beta offset for Cr deblocking filter
+  int       m_deblockingFilterCrTcOffsetDiv2;                 ///< tc offset for Cr deblocking filter
 #if W0038_DB_OPT
   int       m_deblockingFilterMetric;                         ///< blockiness metric in encoder
 #else
@@ -496,11 +528,16 @@ protected:
   int       m_framePackingSEIId;
   int       m_framePackingSEIQuincunx;
   int       m_framePackingSEIInterpretation;
+  bool      m_doSEIEnabled;
+  bool      m_doSEICancelFlag;
+  bool      m_doSEIPersistenceFlag;
+  int       m_doSEITransformType;
   bool      m_parameterSetsInclusionIndicationSEIEnabled;
   int       m_selfContainedClvsFlag;
 #if U0033_ALTERNATIVE_TRANSFER_CHARACTERISTICS_SEI
   int       m_preferredTransferCharacteristics;
 #endif
+
   // film grain characterstics sei
   bool      m_fgcSEIEnabled;
   bool      m_fgcSEICancelFlag;
@@ -519,6 +556,19 @@ protected:
   uint32_t  m_aveSEIAmbientIlluminance;
   uint32_t  m_aveSEIAmbientLightX;
   uint32_t  m_aveSEIAmbientLightY;
+  // colour tranform information sei
+  bool      m_ctiSEIEnabled;
+  uint32_t  m_ctiSEIId;
+  bool      m_ctiSEISignalInfoFlag;
+  bool      m_ctiSEIFullRangeFlag;
+  uint32_t  m_ctiSEIPrimaries;
+  uint32_t  m_ctiSEITransferFunction;
+  uint32_t  m_ctiSEIMatrixCoefs;
+  bool      m_ctiSEICrossComponentFlag;
+  bool      m_ctiSEICrossComponentInferred;
+  uint32_t  m_ctiSEINumberChromaLut;
+  int       m_ctiSEIChromaOffset;
+  LutModel  m_ctiSEILut[MAX_NUM_COMPONENT];
   // content colour volume sei
   bool      m_ccvSEIEnabled;
   bool      m_ccvSEICancelFlag;
@@ -532,6 +582,72 @@ protected:
   double    m_ccvSEIMinLuminanceValue;
   double    m_ccvSEIMaxLuminanceValue;
   double    m_ccvSEIAvgLuminanceValue;
+  // scalability dimension information sei
+  bool              m_sdiSEIEnabled;
+  int               m_sdiSEIMaxLayersMinus1;
+  bool              m_sdiSEIMultiviewInfoFlag;
+  bool              m_sdiSEIAuxiliaryInfoFlag;
+  int               m_sdiSEIViewIdLenMinus1;
+  std::vector<uint32_t>  m_sdiSEILayerId;
+  std::vector<uint32_t>  m_sdiSEIViewIdVal;
+  std::vector<uint32_t>  m_sdiSEIAuxId;
+  std::vector<uint32_t>  m_sdiSEINumAssociatedPrimaryLayersMinus1;
+  // multiview acquisition information sei
+  bool              m_maiSEIEnabled;
+  bool              m_maiSEIIntrinsicParamFlag;
+  bool              m_maiSEIExtrinsicParamFlag;
+  int               m_maiSEINumViewsMinus1;
+  bool              m_maiSEIIntrinsicParamsEqualFlag;
+  int               m_maiSEIPrecFocalLength;
+  int               m_maiSEIPrecPrincipalPoint;
+  int               m_maiSEIPrecSkewFactor;
+  std::vector<bool> m_maiSEISignFocalLengthX;
+  std::vector<uint32_t>  m_maiSEIExponentFocalLengthX;
+  std::vector<uint32_t>  m_maiSEIMantissaFocalLengthX;
+  std::vector<bool>      m_maiSEISignFocalLengthY;
+  std::vector<uint32_t>  m_maiSEIExponentFocalLengthY;
+  std::vector<uint32_t>  m_maiSEIMantissaFocalLengthY;
+  std::vector<bool>      m_maiSEISignPrincipalPointX;
+  std::vector<uint32_t>  m_maiSEIExponentPrincipalPointX;
+  std::vector<uint32_t>  m_maiSEIMantissaPrincipalPointX;
+  std::vector<bool>      m_maiSEISignPrincipalPointY;
+  std::vector<uint32_t>  m_maiSEIExponentPrincipalPointY;
+  std::vector<uint32_t>  m_maiSEIMantissaPrincipalPointY;
+  std::vector<bool>      m_maiSEISignSkewFactor;
+  std::vector<uint32_t>  m_maiSEIExponentSkewFactor;
+  std::vector<uint32_t>  m_maiSEIMantissaSkewFactor;
+  int               m_maiSEIPrecRotationParam;
+  int               m_maiSEIPrecTranslationParam;
+#if JVET_W0078_MVP_SEI 
+  // multiview acquisition information sei
+  bool              m_mvpSEIEnabled;
+  int               m_mvpSEINumViewsMinus1;
+  std::vector<uint32_t>  m_mvpSEIViewPosition;
+#endif
+  // alpha channel information sei
+  bool      m_aciSEIEnabled;
+  bool      m_aciSEICancelFlag;
+  int       m_aciSEIUseIdc;
+  int       m_aciSEIBitDepthMinus8;
+  int       m_aciSEITransparentValue;
+  int       m_aciSEIOpaqueValue;
+  bool      m_aciSEIIncrFlag;
+  bool      m_aciSEIClipFlag;
+  bool      m_aciSEIClipTypeFlag;
+  // depth representation information sei
+  bool      m_driSEIEnabled;
+  bool      m_driSEIZNearFlag;
+  bool      m_driSEIZFarFlag;
+  bool      m_driSEIDMinFlag;
+  bool      m_driSEIDMaxFlag;
+  double    m_driSEIZNear;
+  double    m_driSEIZFar;
+  double    m_driSEIDMin;
+  double    m_driSEIDMax;
+  int       m_driSEIDepthRepresentationType;
+  int       m_driSEIDisparityRefViewId;
+  int       m_driSEINonlinearNumMinus1;
+  std::vector<uint32_t> m_driSEINonlinearModel;
 
   bool      m_erpSEIEnabled;
   bool      m_erpSEICancelFlag;
@@ -558,6 +674,7 @@ protected:
   std::vector<int>      m_omniViewportSEITiltCentre;
   std::vector<uint32_t> m_omniViewportSEIHorRange;
   std::vector<uint32_t> m_omniViewportSEIVerRange;
+  std::string           m_arSEIFileRoot;  // Annotated region SEI - initialized from external file
   bool                  m_rwpSEIEnabled;
   bool                  m_rwpSEIRwpCancelFlag;
   bool                  m_rwpSEIRwpPersistenceFlag;
@@ -602,6 +719,10 @@ protected:
 
   CfgSEISubpictureLevel m_cfgSubpictureLevelInfoSEI;
 
+#if JVET_W0133_CONSTRAINED_RASL_ENCODING
+  bool                  m_constrainedRaslEncoding;
+#endif
+
   bool                  m_sampleAspectRatioInfoSEIEnabled;
   bool                  m_sariCancelFlag;
   bool                  m_sariPersistenceFlag;
@@ -694,11 +815,18 @@ protected:
   bool        m_forceDecodeBitstream1;
 
   bool        m_alf;                                          ///< Adaptive Loop Filter
-#if JVET_T0064
-  double      m_alfStrength;
+#if JVET_W0129_ENABLE_ALF_TRUEORG
+  bool        m_alfTrueOrg;
+#else
+  bool        m_alfSaoTrueOrg;
+#endif
+  double      m_alfStrengthLuma;
   bool        m_alfAllowPredefinedFilters;
   double      m_ccalfStrength;
-#endif
+  double      m_alfStrengthChroma;
+  double      m_alfStrengthTargetLuma;
+  double      m_alfStrengthTargetChroma;
+  double      m_ccalfStrengthTarget;
   bool        m_ccalf;
   int         m_ccalfQpThreshold;
 
@@ -709,6 +837,10 @@ protected:
   double      m_fractionOfFrames;                             ///< encode a fraction of the frames as specified in FramesToBeEncoded
   int         m_switchPocPeriod;
   int         m_upscaledOutput;                               ////< Output upscaled (2), decoded cropped but in full resolution buffer (1) or decoded cropped (0, default) picture for RPR.
+#if JVET_W0133_CONSTRAINED_RASL_ENCODING
+  bool        m_craAPSreset;
+  bool        m_rprRASLtoolSwitch;
+#endif
   bool        m_avoidIntraInDepLayer;
 
   bool                  m_gopBasedTemporalFilterEnabled;               ///< GOP-based Temporal Filter enable/disable
@@ -717,10 +849,8 @@ protected:
 
   int         m_maxLayers;
   int         m_targetOlsIdx;
-#if JVET_S0163_ON_TARGETOLS_SUBLAYERS
   bool        m_OPIEnabled;                                     ///< enable Operating Point Information (OPI)
   int         m_maxTemporalLayer;
-#endif
   int         m_layerId[MAX_VPS_LAYERS];
   int         m_layerIdx;
   int         m_maxSublayers;
@@ -734,9 +864,7 @@ protected:
   int         m_olsModeIdc;
   int         m_numOutputLayerSets;
   std::string m_olsOutputLayerStr[MAX_VPS_LAYERS];
-#if JVET_R0193
   std::string m_maxTidILRefPicsPlus1Str[MAX_VPS_LAYERS];
-#endif
 
   int         m_numPtlsInVps;
 
diff --git a/source/App/EncoderApp/encmain.cpp b/source/App/EncoderApp/encmain.cpp
index 0dfefebec..74ef03119 100644
--- a/source/App/EncoderApp/encmain.cpp
+++ b/source/App/EncoderApp/encmain.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -101,16 +101,6 @@ int main(int argc, char* argv[])
 #endif
 #if ENABLE_TRACING
   fprintf( stdout, "[ENABLE_TRACING] " );
-#endif
-#if ENABLE_SPLIT_PARALLELISM
-  fprintf( stdout, "[SPLIT_PARALLEL (%d jobs)]", PARL_SPLIT_MAX_NUM_JOBS );
-#endif
-#if ENABLE_SPLIT_PARALLELISM
-  const char* waitPolicy = getenv( "OMP_WAIT_POLICY" );
-  const char* maxThLim   = getenv( "OMP_THREAD_LIMIT" );
-  fprintf( stdout, waitPolicy ? "[OMP: WAIT_POLICY=%s," : "[OMP: WAIT_POLICY=,", waitPolicy );
-  fprintf( stdout, maxThLim   ? "THREAD_LIMIT=%s" : "THREAD_LIMIT=", maxThLim );
-  fprintf( stdout, "]" );
 #endif
   fprintf( stdout, "\n" );
 
diff --git a/source/App/Parcat/CMakeLists.txt b/source/App/Parcat/CMakeLists.txt
index 12edc317a..5b9605006 100644
--- a/source/App/Parcat/CMakeLists.txt
+++ b/source/App/Parcat/CMakeLists.txt
@@ -10,7 +10,7 @@ file( GLOB INC_FILES "*.h" )
 # add executable
 add_executable( ${EXE_NAME} ${SRC_FILES} ${INC_FILES} )
 
-target_link_libraries( ${EXE_NAME} CommonLib DecoderLib Utilities Threads::Threads ${ADDITIONAL_LIBS} )
+target_link_libraries( ${EXE_NAME} CommonLib DecoderLib Utilities ${ADDITIONAL_LIBS} )
 
 # include the output directory, where the svnrevision.h file is generated
 include_directories(${CMAKE_CURRENT_BINARY_DIR})
diff --git a/source/App/Parcat/parcat.cpp b/source/App/Parcat/parcat.cpp
index ad869476f..9f7db1dde 100644
--- a/source/App/Parcat/parcat.cpp
+++ b/source/App/Parcat/parcat.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -65,7 +65,7 @@ void ParcatHLSyntaxReader::parsePictureHeaderUpToPoc ( ParameterSetManager *para
   uint32_t  uiCode;
   PPS* pps = NULL;
   SPS* sps = NULL;
-  
+
   uint32_t uiTmp;
   READ_FLAG(uiTmp, "ph_gdr_or_irap_pic_flag");
   READ_FLAG(uiCode, "ph_non_ref_pic_flag");
@@ -212,8 +212,9 @@ std::vector<uint8_t> filter_segment(const std::vector<uint8_t> & v, int idx, int
   int sz = (int) v.size();
   int nal_start, nal_end;
   int off = 0;
-  int cnt = 0;
-  bool idr_found = false;
+  int cnt[MAX_VPS_LAYERS] = { 0 };
+  bool idr_found[MAX_VPS_LAYERS] = { false };
+  bool is_pre_sei_before_idr = true;
 
   std::vector<uint8_t> out;
   out.reserve(v.size());
@@ -268,22 +269,23 @@ std::vector<uint8_t> filter_segment(const std::vector<uint8_t> & v, int idx, int
       HLSReader.parsePPS( pps );
       parameterSetManager.storePPS( pps, inp_nalu.getBitstream().getFifo() );
     }
+    int nalu_layerId = nalu[0] & 0x3F;
 
+    if (nalu_type == NAL_UNIT_CODED_SLICE_IDR_W_RADL || nalu_type == NAL_UNIT_CODED_SLICE_IDR_N_LP)
+    {
+      is_pre_sei_before_idr = false;
+    }
     if(nalu_type == NAL_UNIT_CODED_SLICE_IDR_W_RADL || nalu_type == NAL_UNIT_CODED_SLICE_IDR_N_LP)
     {
       poc = 0;
       new_poc = *poc_base + poc;
       if (first_idr_slice_after_ph_nal)
       {
-        cnt--;
+        cnt[nalu_layerId]--;
       }
       first_idr_slice_after_ph_nal = false;
     }
-#if JVET_S0163_ON_TARGETOLS_SUBLAYERS
     if(inp_nalu.m_nalUnitType == NAL_UNIT_PH || (nalu_type < NAL_UNIT_CODED_SLICE_IDR_W_RADL) || (nalu_type > NAL_UNIT_CODED_SLICE_IDR_N_LP && nalu_type <= NAL_UNIT_RESERVED_IRAP_VCL_11) )
-#else
-    if(inp_nalu.m_nalUnitType == NAL_UNIT_PH || (nalu_type < NAL_UNIT_CODED_SLICE_IDR_W_RADL) || (nalu_type > NAL_UNIT_CODED_SLICE_IDR_N_LP && nalu_type <= NAL_UNIT_RESERVED_IRAP_VCL_12) )
-#endif
     {
       parcatHLSReader.setBitstream( &inp_nalu.getBitstream() );
       if (inp_nalu.m_nalUnitType == NAL_UNIT_PH)
@@ -323,7 +325,7 @@ std::vector<uint8_t> filter_segment(const std::vector<uint8_t> & v, int idx, int
 #if ENABLE_TRACING
         std::cout << "Changed poc " << poc << " to " << new_poc << std::endl;
 #endif
-        ++cnt;
+        ++cnt[nalu_layerId];
         change_poc = false;
       }
     }
@@ -331,16 +333,12 @@ std::vector<uint8_t> filter_segment(const std::vector<uint8_t> & v, int idx, int
     if(idx > 1 && (nalu_type == NAL_UNIT_CODED_SLICE_IDR_W_RADL || nalu_type == NAL_UNIT_CODED_SLICE_IDR_N_LP))
     {
       skip_next_sei = true;
-      idr_found = true;
+      idr_found[nalu_layerId] = true;
     }
-#if JVET_S0163_ON_TARGETOLS_SUBLAYERS
-    if ((idx > 1 && (nalu_type == NAL_UNIT_CODED_SLICE_IDR_W_RADL || nalu_type == NAL_UNIT_CODED_SLICE_IDR_N_LP)) 
-      || ((idx > 1 && !idr_found) && (nalu_type == NAL_UNIT_OPI || nalu_type == NAL_UNIT_DCI || nalu_type == NAL_UNIT_VPS || nalu_type == NAL_UNIT_SPS || nalu_type == NAL_UNIT_PPS || nalu_type == NAL_UNIT_PREFIX_APS || nalu_type == NAL_UNIT_SUFFIX_APS || nalu_type == NAL_UNIT_PH || nalu_type == NAL_UNIT_ACCESS_UNIT_DELIMITER)) 
-      || (nalu_type == NAL_UNIT_SUFFIX_SEI && skip_next_sei))
-#else
-    if ((idx > 1 && (nalu_type == NAL_UNIT_CODED_SLICE_IDR_W_RADL || nalu_type == NAL_UNIT_CODED_SLICE_IDR_N_LP)) || ((idx > 1 && !idr_found) && (nalu_type == NAL_UNIT_DCI || nalu_type == NAL_UNIT_VPS || nalu_type == NAL_UNIT_SPS || nalu_type == NAL_UNIT_PPS || nalu_type == NAL_UNIT_PREFIX_APS || nalu_type == NAL_UNIT_SUFFIX_APS || nalu_type == NAL_UNIT_PH || nalu_type == NAL_UNIT_ACCESS_UNIT_DELIMITER))
-      || (nalu_type == NAL_UNIT_SUFFIX_SEI && skip_next_sei))
-#endif
+    if ((idx > 1 && (nalu_type == NAL_UNIT_CODED_SLICE_IDR_W_RADL || nalu_type == NAL_UNIT_CODED_SLICE_IDR_N_LP))
+      || ((idx > 1 && !idr_found[nalu_layerId]) && (nalu_type == NAL_UNIT_OPI || nalu_type == NAL_UNIT_DCI || nalu_type == NAL_UNIT_VPS || nalu_type == NAL_UNIT_SPS || nalu_type == NAL_UNIT_PPS || nalu_type == NAL_UNIT_PREFIX_APS || nalu_type == NAL_UNIT_SUFFIX_APS || nalu_type == NAL_UNIT_PH || nalu_type == NAL_UNIT_ACCESS_UNIT_DELIMITER))
+      || (nalu_type == NAL_UNIT_SUFFIX_SEI && skip_next_sei)
+      || (idx > 1 && nalu_type == NAL_UNIT_PREFIX_SEI && is_pre_sei_before_idr))
     {
     }
     else
@@ -359,7 +357,7 @@ std::vector<uint8_t> filter_segment(const std::vector<uint8_t> & v, int idx, int
     sz -= nal_end;
   }
 
-  *poc_base += cnt;
+  *poc_base += *std::max_element(std::begin(cnt), std::end(cnt));
   return out;
 }
 
diff --git a/source/App/SEIRemovalApp/CMakeLists.txt b/source/App/SEIRemovalApp/CMakeLists.txt
index cb783adff..ef4fe3634 100644
--- a/source/App/SEIRemovalApp/CMakeLists.txt
+++ b/source/App/SEIRemovalApp/CMakeLists.txt
@@ -33,32 +33,12 @@ if( SET_ENABLE_TRACING )
   endif()
 endif()
 
-if( OpenMP_FOUND )
-  if( SET_ENABLE_SPLIT_PARALLELISM )
-    if( ENABLE_SPLIT_PARALLELISM )
-      target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_SPLIT_PARALLELISM=1 )
-    else()
-      target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_SPLIT_PARALLELISM=0 )
-    endif()
-  endif()
-  if( SET_ENABLE_WPP_PARALLELISM )
-    if( ENABLE_WPP_PARALLELISM )
-      target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_WPP_PARALLELISM=1 )
-    else()
-      target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_WPP_PARALLELISM=0 )
-    endif()
-  endif()
-else()
-  target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_SPLIT_PARALLELISM=0 )
-  target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_WPP_PARALLELISM=0 )
-endif()
-
 if( CMAKE_COMPILER_IS_GNUCC AND BUILD_STATIC )
   set( ADDITIONAL_LIBS ${ADDITIONAL_LIBS} -static -static-libgcc -static-libstdc++ )
   target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_WPP_STATIC_LINK=1 )
 endif()
 
-target_link_libraries( ${EXE_NAME} CommonLib DecoderLib Utilities Threads::Threads ${ADDITIONAL_LIBS} )
+target_link_libraries( ${EXE_NAME} CommonLib DecoderLib Utilities ${ADDITIONAL_LIBS} )
 
 # lldb custom data formatters
 if( XCODE )
diff --git a/source/App/SEIRemovalApp/SEIRemovalApp.cpp b/source/App/SEIRemovalApp/SEIRemovalApp.cpp
index e10c99da8..c12dee6a9 100644
--- a/source/App/SEIRemovalApp/SEIRemovalApp.cpp
+++ b/source/App/SEIRemovalApp/SEIRemovalApp.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/App/SEIRemovalApp/SEIRemovalApp.h b/source/App/SEIRemovalApp/SEIRemovalApp.h
index 32bb23ac2..ec03a9a36 100644
--- a/source/App/SEIRemovalApp/SEIRemovalApp.h
+++ b/source/App/SEIRemovalApp/SEIRemovalApp.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/App/SEIRemovalApp/SEIRemovalAppCfg.cpp b/source/App/SEIRemovalApp/SEIRemovalAppCfg.cpp
index f4ab6e1f0..20310d657 100644
--- a/source/App/SEIRemovalApp/SEIRemovalAppCfg.cpp
+++ b/source/App/SEIRemovalApp/SEIRemovalAppCfg.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/App/SEIRemovalApp/SEIRemovalAppCfg.h b/source/App/SEIRemovalApp/SEIRemovalAppCfg.h
index 593ba8383..5edd3561b 100644
--- a/source/App/SEIRemovalApp/SEIRemovalAppCfg.h
+++ b/source/App/SEIRemovalApp/SEIRemovalAppCfg.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/App/SEIRemovalApp/seiremovalmain.cpp b/source/App/SEIRemovalApp/seiremovalmain.cpp
index 5fba16f98..309bb72c3 100644
--- a/source/App/SEIRemovalApp/seiremovalmain.cpp
+++ b/source/App/SEIRemovalApp/seiremovalmain.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/App/StreamMergeApp/CMakeLists.txt b/source/App/StreamMergeApp/CMakeLists.txt
index 77c53ece6..117652574 100644
--- a/source/App/StreamMergeApp/CMakeLists.txt
+++ b/source/App/StreamMergeApp/CMakeLists.txt
@@ -33,32 +33,12 @@ if( SET_ENABLE_TRACING )
   endif()
 endif()
 
-if( OpenMP_FOUND )
-  if( SET_ENABLE_SPLIT_PARALLELISM )
-    if( ENABLE_SPLIT_PARALLELISM )
-      target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_SPLIT_PARALLELISM=1 )
-    else()
-      target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_SPLIT_PARALLELISM=0 )
-    endif()
-  endif()
-  if( SET_ENABLE_WPP_PARALLELISM )
-    if( ENABLE_WPP_PARALLELISM )
-      target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_WPP_PARALLELISM=1 )
-    else()
-      target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_WPP_PARALLELISM=0 )
-    endif()
-  endif()
-else()
-  target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_SPLIT_PARALLELISM=0 )
-  target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_WPP_PARALLELISM=0 )
-endif()
-
 if( CMAKE_COMPILER_IS_GNUCC AND BUILD_STATIC )
   set( ADDITIONAL_LIBS ${ADDITIONAL_LIBS} -static -static-libgcc -static-libstdc++ )
   target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_WPP_STATIC_LINK=1 )
 endif()
 
-target_link_libraries( ${EXE_NAME} CommonLib EncoderLib DecoderLib Utilities Threads::Threads ${ADDITIONAL_LIBS} )
+target_link_libraries( ${EXE_NAME} CommonLib EncoderLib DecoderLib Utilities ${ADDITIONAL_LIBS} )
 
 # lldb custom data formatters
 if( XCODE )
diff --git a/source/App/StreamMergeApp/StreamMergeApp.cpp b/source/App/StreamMergeApp/StreamMergeApp.cpp
index b9943e8ec..2f813eff7 100644
--- a/source/App/StreamMergeApp/StreamMergeApp.cpp
+++ b/source/App/StreamMergeApp/StreamMergeApp.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -41,8 +41,8 @@
 #include <fcntl.h>
 
 #include "StreamMergeApp.h"
-#include "DecoderLib/AnnexBread.h"
-#include "DecoderLib/NALread.h"
+#include "AnnexBwrite.h"
+#include "NALwrite.h"
 #if RExt__DECODER_DEBUG_BIT_STATISTICS
 #include "CommonLib/CodingStatistics.h"
 #endif
@@ -63,26 +63,6 @@ StreamMergeApp::StreamMergeApp()
 // Public member functions
 // ====================================================================================================================
 
-/**
- - create internal class
- - initialize internal class
- - until the end of the bitstream, call decoding function in StreamMergeApp class
- - delete allocated buffers
- - destroy internal class
- - returns the number of mismatching pictures
- */
-
-void read2(InputNALUnit& nalu)
-{
-  InputBitstream& bs = nalu.getBitstream();
-
-  nalu.m_forbiddenZeroBit   = bs.read(1);                 // forbidden zero bit
-  nalu.m_nuhReservedZeroBit = bs.read(1);                 // nuh_reserved_zero_bit
-  nalu.m_nuhLayerId         = bs.read(6);                 // nuh_layer_id
-  nalu.m_nalUnitType        = (NalUnitType) bs.read(5);   // nal_unit_type
-  nalu.m_temporalId         = bs.read(3) - 1;             // nuh_temporal_id_plus1
-}
-
 static void
 _byteStreamNALUnit(
   SingleLayerStream& bs,
@@ -224,121 +204,440 @@ byteStreamNALUnit(
   return eof;
 }
 
-void StreamMergeApp::writeNewVPS(ostream& out, int nLayerId, int nTemporalId)
+/**
+ - lookahead through next NAL units to determine if current NAL unit is the first NAL unit in a new picture
+ */
+bool StreamMergeApp::isNewPicture(std::ifstream *bitstreamFile, InputByteStream *bytestream, bool firstSliceInPicture)
 {
-  //write NALU header
-  OutputBitstream bsNALUHeader;
-  static const uint8_t start_code_prefix[] = { 0,0,0,1 };
+  bool ret      = false;
+  bool finished = false;
 
-  int forbiddenZero = 0;
-  bsNALUHeader.write(forbiddenZero, 1);   // forbidden_zero_bit
-  int nuhReservedZeroBit = 0;
-  bsNALUHeader.write(nuhReservedZeroBit, 1);   // nuh_reserved_zero_bit
-  bsNALUHeader.write(nLayerId, 6);             // nuh_layer_id
-  bsNALUHeader.write(NAL_UNIT_VPS, 5);         // nal_unit_type
-  bsNALUHeader.write(nTemporalId + 1, 3);      // nuh_temporal_id_plus1
-
-  out.write(reinterpret_cast<const char*>(start_code_prefix), 4);
-  out.write(reinterpret_cast<const char*>(bsNALUHeader.getByteStream()), bsNALUHeader.getByteStreamLength());
+  // cannot be a new picture if there haven't been any slices yet
+  if (firstSliceInPicture)
+  {
+    return false;
+  }
 
-  //write VPS
-  OutputBitstream bsVPS;
-  HLSWriter       m_HLSWriter;
+  // save stream position for backup
+  std::streampos location = bitstreamFile->tellg();
 
-  m_HLSWriter.setBitstream(&bsVPS);
-  m_HLSWriter.codeVPS(&vps);
+  // look ahead until picture start location is determined
+  while (!finished && !!(*bitstreamFile))
+  {
+    AnnexBStats  stats = AnnexBStats();
+    InputNALUnit nalu;
+    byteStreamNALUnit(*bytestream, nalu.getBitstream().getFifo(), stats);
+    if (nalu.getBitstream().getFifo().empty())
+    {
+      msg(ERROR, "Warning: Attempt to decode an empty NAL unit\n");
+    }
+    else
+    {
+      // get next NAL unit type
+      read(nalu);
+      switch (nalu.m_nalUnitType)
+      {
+      // NUT that indicate the start of a new picture
+      case NAL_UNIT_ACCESS_UNIT_DELIMITER:
+      case NAL_UNIT_OPI:
+      case NAL_UNIT_DCI:
+      case NAL_UNIT_VPS:
+      case NAL_UNIT_SPS:
+      case NAL_UNIT_PPS:
+      case NAL_UNIT_PH:
+        ret      = true;
+        finished = true;
+        break;
+
+      // NUT that are not the start of a new picture
+      case NAL_UNIT_CODED_SLICE_TRAIL:
+      case NAL_UNIT_CODED_SLICE_STSA:
+      case NAL_UNIT_CODED_SLICE_RASL:
+      case NAL_UNIT_CODED_SLICE_RADL:
+      case NAL_UNIT_RESERVED_VCL_4:
+      case NAL_UNIT_RESERVED_VCL_5:
+      case NAL_UNIT_RESERVED_VCL_6:
+      case NAL_UNIT_CODED_SLICE_IDR_W_RADL:
+      case NAL_UNIT_CODED_SLICE_IDR_N_LP:
+      case NAL_UNIT_CODED_SLICE_CRA:
+      case NAL_UNIT_CODED_SLICE_GDR:
+      case NAL_UNIT_RESERVED_IRAP_VCL_11:
+        ret      = checkPictureHeaderInSliceHeaderFlag(nalu);
+        finished = true;
+        break;
+
+        // NUT that are not the start of a new picture
+      case NAL_UNIT_EOS:
+      case NAL_UNIT_EOB:
+      case NAL_UNIT_SUFFIX_APS:
+      case NAL_UNIT_SUFFIX_SEI:
+      case NAL_UNIT_FD:
+        ret      = false;
+        finished = true;
+        break;
+
+      // NUT that might indicate the start of a new picture - keep looking
+      case NAL_UNIT_PREFIX_APS:
+      case NAL_UNIT_PREFIX_SEI:
+      case NAL_UNIT_RESERVED_NVCL_26:
+      case NAL_UNIT_RESERVED_NVCL_27:
+      case NAL_UNIT_UNSPECIFIED_28:
+      case NAL_UNIT_UNSPECIFIED_29:
+      case NAL_UNIT_UNSPECIFIED_30:
+      case NAL_UNIT_UNSPECIFIED_31:
+      default:
+        break;
+      }
+    }
+  }
 
-  out.write(reinterpret_cast<const char*>(bsVPS.getByteStream()), bsVPS.getByteStreamLength());
+  // restore previous stream location - minus 3 due to the need for the annexB parser to read three extra bytes
+  bitstreamFile->clear();
+  bitstreamFile->seekg(location - std::streamoff(3));
+  bytestream->reset();
 
-  return;
+  // return TRUE if next NAL unit is the start of a new picture
+  return ret;
 }
 
-uint32_t StreamMergeApp::mergeStreams()
+/**
+- lookahead through next NAL units to determine if current NAL unit is the first NAL unit in a new access unit
+*/
+bool StreamMergeApp::isNewAccessUnit(bool newPicture, std::ifstream *bitstreamFile, class InputByteStream *bytestream)
 {
-  ifstream bitstreamFileIn[MAX_VPS_LAYERS];
-  ofstream bitstreamFileOut(m_bitstreamFileNameOut.c_str(), ifstream::out | ifstream::binary);
-  int nNumValidStr = m_numInputStreams;
+  bool ret      = false;
+  bool finished = false;
 
-  for (int i = 0; i < m_numInputStreams; i++)
+  // can only be the start of an AU if this is the start of a new picture
+  if (newPicture == false)
   {
-    bitstreamFileIn[i].open(m_bitstreamFileNameIn[i].c_str(), ifstream::in | ifstream::binary);
+    return false;
+  }
 
-    if (!bitstreamFileIn[i])
+  // save stream position for backup
+  std::streampos location = bitstreamFile->tellg();
+
+  // look ahead until access unit start location is determined
+  while (!finished && !!(*bitstreamFile))
+  {
+    AnnexBStats  stats = AnnexBStats();
+    InputNALUnit nalu;
+    byteStreamNALUnit(*bytestream, nalu.getBitstream().getFifo(), stats);
+    if (nalu.getBitstream().getFifo().empty())
     {
-      EXIT("failed to open bitstream file " << m_bitstreamFileNameIn[i].c_str() << " for reading");
+      msg(ERROR, "Warning: Attempt to decode an empty NAL unit\n");
+    }
+    else
+    {
+      // get next NAL unit type
+      read(nalu);
+      switch (nalu.m_nalUnitType)
+      {
+      // AUD always indicates the start of a new access unit
+      case NAL_UNIT_ACCESS_UNIT_DELIMITER:
+        ret      = true;
+        finished = true;
+        break;
+
+      // slice types - check layer ID and POC
+      case NAL_UNIT_CODED_SLICE_TRAIL:
+      case NAL_UNIT_CODED_SLICE_STSA:
+      case NAL_UNIT_CODED_SLICE_RASL:
+      case NAL_UNIT_CODED_SLICE_RADL:
+      case NAL_UNIT_CODED_SLICE_IDR_W_RADL:
+      case NAL_UNIT_CODED_SLICE_IDR_N_LP:
+      case NAL_UNIT_CODED_SLICE_CRA:
+      case NAL_UNIT_CODED_SLICE_GDR:
+        ret      = true; // isSliceNaluFirstInAU(newPicture, nalu); // TODO: according to DecLib::isSliceNaluFirstInAU(), true if layerID==prevLayerID, otherwise true if POC!=prevPOC.
+        finished = true;
+        break;
+
+      // NUT that are not the start of a new access unit
+      case NAL_UNIT_EOS:
+      case NAL_UNIT_EOB:
+      case NAL_UNIT_SUFFIX_APS:
+      case NAL_UNIT_SUFFIX_SEI:
+      case NAL_UNIT_FD:
+        ret      = false;
+        finished = true;
+        break;
+
+      // all other NUT - keep looking to find first VCL
+      default: break;
+      }
     }
-
-    bitstreamFileIn[i].clear();
-    bitstreamFileIn[i].seekg(0, ios::beg);
   }
 
-  SingleLayerStream bytestream[MAX_VPS_LAYERS];
+  // restore previous stream location
+  bitstreamFile->clear();
+  bitstreamFile->seekg(location);
+  bytestream->reset();
 
-  for (int i = 0; i < m_numInputStreams; i++)
-    bytestream[i].init(bitstreamFileIn[i]);
+  // return TRUE if next NAL unit is the start of a new picture
+  return ret;
+}
 
-  //set VPS which will be replicated for all layers but with differnt nul_layer_id
-  vps.setMaxLayers(m_numInputStreams);
-  vps.setVPSExtensionFlag(false);
+void StreamMergeApp::inputNaluHeaderToOutputNalu(InputNALUnit& inNalu, OutputNALUnit& outNalu) {
+  outNalu.m_forbiddenZeroBit   = inNalu.m_forbiddenZeroBit;
+  outNalu.m_nalUnitType        = inNalu.m_nalUnitType;
+  outNalu.m_nuhLayerId         = inNalu.m_nuhLayerId;
+  outNalu.m_nuhReservedZeroBit = inNalu.m_nuhReservedZeroBit;
+  outNalu.m_temporalId         = inNalu.m_temporalId;
+}
+
+bool StreamMergeApp::preInjectNalu(MergeLayer &layer, InputNALUnit &inNalu, OutputNALUnit &outNalu)
+{
+  HLSyntaxReader hlsReader;
+  HLSWriter      hlsWriter;
+  hlsReader.setBitstream(&inNalu.getBitstream());
+  hlsWriter.setBitstream(&outNalu.m_Bitstream);
 
-  //Loop all input bitstreams to interleave their NALUs
-  while (nNumValidStr)
+  switch (inNalu.m_nalUnitType)
   {
-    //loop over all input streams
+  case NAL_UNIT_SPS:
+  {
+    VPS *vps = new VPS();
+    if (vpsId == -1)
+    {
+      vpsId = ++idIncrement;
+    }
+    vps->setVPSId(vpsId);
     for (int i = 0; i < m_numInputStreams; i++)
     {
-      uint8_t layerId = i < 63 ? i : i + 1;
+      vps->setLayerId(i, i);   // Because we use layer IDs that are layer indices.
+    }
+    vps->setMaxLayers(m_numInputStreams);
+    vector<ProfileTierLevel> ptls;
+    ptls.push_back(ProfileTierLevel());
+    vps->setProfileTierLevel(ptls);
+    layer.vpsIdMapping[0] = vps->getVPSId();
+    layer.psManager.storeVPS(vps, hlsReader.getBitstream()->getFifo());
+    hlsWriter.codeVPS(vps);
+    outNalu.m_nalUnitType = NAL_UNIT_VPS;
+    msg(INFO, " layer %i, nalu type VPS%i injected\n", layer.id, vps->getVPSId());
+    return true;
+  }
+  default:
+    break;
+  }
+  return false;
+}
+
+/**
+  - Decode NAL unit if it is parameter set or picture header, or decode slice header of VLC NAL unit
+ */
+void StreamMergeApp::decodeAndRewriteNalu(MergeLayer &layer, InputNALUnit &inNalu, OutputNALUnit &outNalu)
+{
+  HLSyntaxReader hlsReader;
+  HLSWriter      hlsWriter;
+  hlsReader.setBitstream(&inNalu.getBitstream());
+  hlsWriter.setBitstream(&outNalu.m_Bitstream);
+
+  msg(INFO, " layer %i, nalu type ", layer.id);
+  switch (inNalu.m_nalUnitType)
+  {
+  case NAL_UNIT_SPS:
+  {
+    SPS *oldSps = new SPS();
+    SPS *newSps = new SPS();
+    hlsReader.parseSPS(oldSps);
+    inNalu.getBitstream().resetToStart();
+    uint32_t uiCode;
+    inNalu.getBitstream().read(16, uiCode);
+    hlsReader.parseSPS(newSps);
+    // Set new values.
+    newSps->setSPSId(++idIncrement);
+    newSps->setVPSId(layer.vpsIdMapping.at(oldSps->getVPSId()));
+    newSps->setLayerId(layer.id);
+    // Store values for later reference.
+    layer.spsIdMapping.insert({ oldSps->getSPSId(), newSps->getSPSId() });
+    layer.oldIDsPsManager.storeSPS(oldSps, hlsReader.getBitstream()->getFifo());
+    layer.psManager.storeSPS(newSps, hlsReader.getBitstream()->getFifo());
+    hlsWriter.codeSPS(newSps);
+    msg(INFO, "SPS%i", newSps->getSPSId());
+    break;
+  }
+  case NAL_UNIT_PPS:
+  {
+    PPS *oldPps = new PPS();
+    PPS *newPps = new PPS();
+    hlsReader.parsePPS(oldPps);
+    inNalu.getBitstream().resetToStart();
+    uint32_t uiCode;
+    inNalu.getBitstream().read(16, uiCode);
+    hlsReader.parsePPS(newPps);
+    // Set new values.
+    newPps->setPPSId(++idIncrement);
+    newPps->setSPSId(layer.spsIdMapping.at(oldPps->getSPSId()));
+    newPps->setLayerId(layer.id);
+    // Store values for later reference.
+    layer.ppsIdMapping.insert({ oldPps->getPPSId(), newPps->getPPSId() });
+    layer.oldIDsPsManager.storePPS(oldPps, hlsReader.getBitstream()->getFifo());
+    layer.psManager.storePPS(newPps, hlsReader.getBitstream()->getFifo());
+    hlsWriter.codePPS(newPps);
+    msg(INFO, "PPS%i", newPps->getPPSId());
+    break;
+  }
+  case NAL_UNIT_PREFIX_APS:
+  case NAL_UNIT_SUFFIX_APS:
+  {
+    APS *aps = new APS();
+    hlsReader.parseAPS(aps);
+    layer.apsIdMapping.insert({ aps->getAPSId(), ++idIncrement });
+    aps->setLayerId(layer.id);
+    aps->setAPSId(idIncrement);
+    layer.psManager.storeAPS(aps, hlsReader.getBitstream()->getFifo());
+    hlsWriter.codeAPS(aps);
+    msg(INFO, "APS%s%i", inNalu.m_nalUnitType == NAL_UNIT_PREFIX_APS ? "p" : "s", aps->getAPSId());
+    break;
+  }
+  case NAL_UNIT_PH:
+  {
+    PicHeader ph = PicHeader();
+    hlsReader.parsePictureHeader(&ph, &layer.oldIDsPsManager, true);
+    Slice slice = Slice();
+    slice.setPPS(layer.psManager.getPPS(layer.ppsIdMapping.at(ph.getPPSId())));
+    slice.setSPS(layer.psManager.getSPS(layer.spsIdMapping.at(ph.getSPSId())));
+    slice.setPOC(ph.getPocLsb());
+    ph.setPPSId(layer.ppsIdMapping.at(ph.getPPSId()));
+    hlsWriter.codePictureHeader(&ph, true, &slice);
+    msg(INFO, "PH");
+    break;
+  }
+  default:
+  {
+    if (inNalu.isVcl())
+    {
+      msg(INFO, "VCL");
+    }
+    else if (inNalu.isSei())
+    {
+      msg(INFO, "SEI");
+    }
+    else
+    {
+      msg(INFO, "NNN");   // Any other NAL unit that is not handled above
+    }
+    msg(INFO, " with index %i", inNalu.m_nalUnitType);
+    // Copy payload from input nalu to output nalu. Code copied from SubpicMergeApp::copyInputNaluToOutputNalu().
+    vector<uint8_t> &inFifo  = inNalu.getBitstream().getFifo();
+    vector<uint8_t> &outFifo = outNalu.m_Bitstream.getFIFO();
+    outFifo                  = vector<uint8_t>(inFifo.begin() + 2, inFifo.end());
+    break;
+  }
+  }
+  msg(INFO, "\n");
+}
 
-      if (!bitstreamFileIn[i])
-        continue;
+uint32_t StreamMergeApp::mergeStreams()
+{
+  ofstream outputStream(m_bitstreamFileNameOut, ifstream::out | ifstream::binary);
 
-      AnnexBStats stats = AnnexBStats();
+  vector<MergeLayer> *layers = new vector<MergeLayer>;
+  layers->resize(m_numInputStreams);
 
-      InputNALUnit nalu;
+  // Prepare merge layers.
+  for (int i = 0; i < layers->size(); i++)
+  {
+    MergeLayer &layer = layers->at(i);
+    layer.id          = i;
 
-      byteStreamNALUnit(bytestream[i], bitstreamFileIn[i], nalu.getBitstream().getFifo(), stats);
+    // Open input file.
+    layer.fp = new ifstream();
+    layer.fp->open(m_bitstreamFileNameIn[i], ifstream::in | ifstream::binary);
+    if (!layer.fp->is_open())
+    {
+      EXIT("failed to open bitstream file " << m_bitstreamFileNameIn[i] << " for reading");
+    }
+    layer.fp->clear();
+    layer.fp->seekg(0, ios::beg);
+
+    // Prep other values.
+    layer.bs = new InputByteStream(*(layer.fp));
+
+    VPS vps;
+    vps.setMaxLayers((uint32_t) layers->size());
+    vps.setLayerId(layer.id, layer.id);   // Layer ID is rewritten here.
+    layer.vpsIdMapping.insert({ vps.getVPSId(), 0 });
+    vps.setVPSId(0);
+    layer.psManager.storeVPS(&vps, std::vector<uint8_t>()); // Create VPS with default values (VTM slice header parser needs this)
+  }
 
-      // call actual decoding function
-      if (nalu.getBitstream().getFifo().empty())
-      {
-        /* this can happen if the following occur:
-         *  - empty input file
-         *  - two back-to-back start_code_prefixes
-         *  - start_code_prefix immediately followed by EOF
-         */
-        std::cerr << "Warning: Attempt to decode an empty NAL unit" << std::endl;
-      }
-      else
-      {
-        read2(nalu);
+  // Loop over layers until every one is entirely read.
+  uint32_t layersStillToRead = (uint32_t) layers->size();
+  while (layersStillToRead > 0)
+  {
+    // Loop over every layer.
+    for (auto &layer: *layers)
+    {
+      if (layer.doneReading) continue;
+
+      //vector<OutputNALUnit> outNalus; // collection of nalus of this interleave part.
+      AccessUnit outAccessUnit;
+      // Read until eof or after first vcl nalu.
+      bool eoi = false; // end of interleave part.
+      while (!eoi) {
+        AnnexBStats  stats;
+        InputNALUnit inNalu;
+        inNalu.m_nalUnitType = NAL_UNIT_INVALID;
+
+        // Find next nalu in stream.
+        bool eof = byteStreamNALUnit(*layer.bs, inNalu.getBitstream().getFifo(), stats);
+
+        // End of file reached.
+        if (eof) {
+          eoi = true;
+          layersStillToRead--;
+          layer.doneReading = true;
+        }
 
-        if (nalu.m_nalUnitType == NAL_UNIT_VPS)
+        if (inNalu.getBitstream().getFifo().empty())
         {
-          writeNewVPS(bitstreamFileOut, layerId, nalu.m_temporalId);
-          printf("Write new VPS for stream %d\n", i);
-
+          msg(ERROR, "Warning: Attempt to decode an empty NAL unit\n");
           continue;
         }
 
-        int iNumZeros = stats.m_numLeadingZero8BitsBytes + stats.m_numZeroByteBytes + stats.m_numStartCodePrefixBytes - 1;
-        char ch = 0;
-        for (int i = 0; i < iNumZeros; i++) { bitstreamFileOut.write(&ch, 1); }
-        ch = 1; bitstreamFileOut.write(&ch, 1);
 
-        //update the nul_layer_id
-        uint8_t *p = (uint8_t*)nalu.getBitstream().getFifo().data();
-        p[1] = ((layerId + 1) << 1) & 0xff;
+        read(inNalu);   // Convert nalu payload to RBSP and parse nalu header
+
+        // NALU to optionally inject before the main output NALU.
+        OutputNALUnit injectedOutNalu((NalUnitType) inNalu.m_nalUnitType);
+        inputNaluHeaderToOutputNalu(inNalu, injectedOutNalu);
+        injectedOutNalu.m_nuhLayerId = layer.id;
+        if (preInjectNalu(layer, inNalu, injectedOutNalu))
+        {
+          outAccessUnit.push_back(new NALUnitEBSP(injectedOutNalu));
+        }
 
-        bitstreamFileOut.write((const char*)p, nalu.getBitstream().getFifo().size());
+        // Change input NALU to output NALU.
+        OutputNALUnit outNalu((NalUnitType) inNalu.m_nalUnitType);
+        inputNaluHeaderToOutputNalu(inNalu, outNalu);
+        outNalu.m_nuhLayerId = layer.id;
+        decodeAndRewriteNalu(layer, inNalu, outNalu);
+        outAccessUnit.push_back(new NALUnitEBSP(outNalu));
 
-        printf("Merge NALU type %d from stream %d\n", nalu.m_nalUnitType, i);
-      }
+        if (inNalu.isVcl())
+        {
+          layer.firstSliceInPicture = false;
+        }
 
-      if (!bitstreamFileIn[i])
-        nNumValidStr--;
+        try
+        {
+          bool bIsNewPicture = isNewPicture(layer.fp, layer.bs, layer.firstSliceInPicture);
+          if (isNewAccessUnit(bIsNewPicture, layer.fp, layer.bs))
+          {
+            layer.firstSliceInPicture = bIsNewPicture;
+            eoi                       = true;
+          }
+        }
+        catch (std::ios_base::failure&)
+        {
+          eoi = true;
+        }
+      }
+      writeAnnexBAccessUnit(outputStream, outAccessUnit);
     }
   }
-
   return 0;
 }
 
diff --git a/source/App/StreamMergeApp/StreamMergeApp.h b/source/App/StreamMergeApp/StreamMergeApp.h
index b4dc15ae8..1982ecc8e 100644
--- a/source/App/StreamMergeApp/StreamMergeApp.h
+++ b/source/App/StreamMergeApp/StreamMergeApp.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -45,30 +45,71 @@
 #include <stdio.h>
 #include <fstream>
 #include <iostream>
-#include "CommonLib/CommonDef.h"
-#include "VLCWriter.h"
+#include "CommonDef.h" 
+#include "NALread.h"
 #include "CABACWriter.h"
 #include "AnnexBread.h"
+#include "VLCReader.h"
+#include "VLCWriter.h"
 #include "StreamMergeAppCfg.h"
 
 using namespace std;
 
+
+
+struct MergeLayer;
+class SingleLayerStream;
+typedef map<uint32_t, uint32_t> OldToNewIdMapping;
+
 // ====================================================================================================================
 // Class definition
 // ====================================================================================================================
 
-/// decoder application class
+/// stream merger application class
 class StreamMergeApp : public StreamMergeAppCfg
 {
 
 public:
   StreamMergeApp();
-  virtual ~StreamMergeApp         ()  {}
+  virtual ~StreamMergeApp() {}
 
   VPS vps;
 
-  uint32_t  mergeStreams            (); ///< main stream merging function
-  void      writeNewVPS             (ostream& out, int nNumLayers, int nTemporalId);
+  uint32_t mergeStreams();   ///< main stream merging function
+
+private:
+  bool isNewPicture(std::ifstream *bitstreamFile, InputByteStream *bytestream, bool firstSliceInPicture);
+  bool isNewAccessUnit(bool newPicture, std::ifstream *bitstreamFile, InputByteStream *bytestream);
+  void inputNaluHeaderToOutputNalu(InputNALUnit &inNalu, OutputNALUnit &outNalu);
+  bool preInjectNalu(MergeLayer &layer, InputNALUnit &inNalu, OutputNALUnit &outNalu);
+  void decodeAndRewriteNalu(MergeLayer &layer, InputNALUnit &inNalu, OutputNALUnit &outNalu);
+
+  int vpsId = -1;
+  int idIncrement = 0;
+};
+
+
+
+
+struct MergeLayer
+{
+  int id;
+
+  ifstream *                 fp;
+  InputByteStream *          bs;
+  bool                       firstSliceInPicture = true;
+  bool                       doneReading = false;
+  vector<AnnexBStats>        stats;
+  ParameterSetManager        oldIDsPsManager;
+  ParameterSetManager        psManager;
+  vector<int>                vpsIds;
+  vector<int>                spsIds;
+  vector<int>                ppsIds;
+
+  OldToNewIdMapping vpsIdMapping;
+  OldToNewIdMapping spsIdMapping;
+  OldToNewIdMapping ppsIdMapping;
+  OldToNewIdMapping apsIdMapping;
 };
 
 
diff --git a/source/App/StreamMergeApp/StreamMergeAppCfg.cpp b/source/App/StreamMergeApp/StreamMergeAppCfg.cpp
index 88432c360..310fab49b 100644
--- a/source/App/StreamMergeApp/StreamMergeAppCfg.cpp
+++ b/source/App/StreamMergeApp/StreamMergeAppCfg.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/App/StreamMergeApp/StreamMergeAppCfg.h b/source/App/StreamMergeApp/StreamMergeAppCfg.h
index 6ef3e791c..e6248c0c5 100644
--- a/source/App/StreamMergeApp/StreamMergeAppCfg.h
+++ b/source/App/StreamMergeApp/StreamMergeAppCfg.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/App/StreamMergeApp/StreamMergeMain.cpp b/source/App/StreamMergeApp/StreamMergeMain.cpp
index 7404d8751..ad7c04735 100644
--- a/source/App/StreamMergeApp/StreamMergeMain.cpp
+++ b/source/App/StreamMergeApp/StreamMergeMain.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/App/SubpicMergeApp/CMakeLists.txt b/source/App/SubpicMergeApp/CMakeLists.txt
index dd8fac45f..64690566d 100644
--- a/source/App/SubpicMergeApp/CMakeLists.txt
+++ b/source/App/SubpicMergeApp/CMakeLists.txt
@@ -33,32 +33,12 @@ if( SET_ENABLE_TRACING )
   endif()
 endif()
 
-if( OpenMP_FOUND )
-  if( SET_ENABLE_SPLIT_PARALLELISM )
-    if( ENABLE_SPLIT_PARALLELISM )
-      target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_SPLIT_PARALLELISM=1 )
-    else()
-      target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_SPLIT_PARALLELISM=0 )
-    endif()
-  endif()
-  if( SET_ENABLE_WPP_PARALLELISM )
-    if( ENABLE_WPP_PARALLELISM )
-      target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_WPP_PARALLELISM=1 )
-    else()
-      target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_WPP_PARALLELISM=0 )
-    endif()
-  endif()
-else()
-  target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_SPLIT_PARALLELISM=0 )
-  target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_WPP_PARALLELISM=0 )
-endif()
-
 if( CMAKE_COMPILER_IS_GNUCC AND BUILD_STATIC )
   set( ADDITIONAL_LIBS ${ADDITIONAL_LIBS} -static -static-libgcc -static-libstdc++ )
   target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_WPP_STATIC_LINK=1 )
 endif()
 
-target_link_libraries( ${EXE_NAME} CommonLib EncoderLib DecoderLib Utilities Threads::Threads ${ADDITIONAL_LIBS} )
+target_link_libraries( ${EXE_NAME} CommonLib EncoderLib DecoderLib Utilities ${ADDITIONAL_LIBS} )
 
 # lldb custom data formatters
 if( XCODE )
diff --git a/source/App/SubpicMergeApp/SubpicMergeApp.cpp b/source/App/SubpicMergeApp/SubpicMergeApp.cpp
index 3dbda5f4a..c5903447a 100644
--- a/source/App/SubpicMergeApp/SubpicMergeApp.cpp
+++ b/source/App/SubpicMergeApp/SubpicMergeApp.cpp
@@ -3,7 +3,7 @@
 * and contributor rights, including patent rights, and no such rights are
 * granted under this license.
 *
-* Copyright (c) 2010-2020, ITU/ISO/IEC
+* Copyright (c) 2010-2021, ITU/ISO/IEC
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
@@ -52,6 +52,9 @@
 #include "NALwrite.h"
 #include "AnnexBwrite.h"
 #include "SubpicMergeApp.h"
+#include "SEIread.h"
+#include "SEIEncoder.h"
+#include "SEIwrite.h"
 
 
  //! \ingroup SubpicMergeApp
@@ -82,6 +85,7 @@ struct Subpicture {
   PicHeader                            picHeader;
   std::vector<Slice>                   slices;
   std::vector<OutputBitstream>         sliceData;
+  SEI                                  *decodedPictureHashSei;
 };
 
 
@@ -166,9 +170,7 @@ bool SubpicMergeApp::isNewPicture(std::ifstream *bitstreamFile, InputByteStream
 
         // NUT that indicate the start of a new picture
         case NAL_UNIT_ACCESS_UNIT_DELIMITER:
-#if JVET_S0163_ON_TARGETOLS_SUBLAYERS
         case NAL_UNIT_OPI:
-#endif
         case NAL_UNIT_DCI:
         case NAL_UNIT_VPS:
         case NAL_UNIT_SPS:
@@ -177,7 +179,7 @@ bool SubpicMergeApp::isNewPicture(std::ifstream *bitstreamFile, InputByteStream
           ret = true;
           finished = true;
           break;
-        
+
         // NUT that are not the start of a new picture
         case NAL_UNIT_CODED_SLICE_TRAIL:
         case NAL_UNIT_CODED_SLICE_STSA:
@@ -191,9 +193,6 @@ bool SubpicMergeApp::isNewPicture(std::ifstream *bitstreamFile, InputByteStream
         case NAL_UNIT_CODED_SLICE_CRA:
         case NAL_UNIT_CODED_SLICE_GDR:
         case NAL_UNIT_RESERVED_IRAP_VCL_11:
-#if !JVET_S0163_ON_TARGETOLS_SUBLAYERS
-        case NAL_UNIT_RESERVED_IRAP_VCL_12:
-#endif
           ret = checkPictureHeaderInSliceHeaderFlag(nalu);
           finished = true;
           break;
@@ -207,7 +206,7 @@ bool SubpicMergeApp::isNewPicture(std::ifstream *bitstreamFile, InputByteStream
           ret = false;
           finished = true;
           break;
-        
+
         // NUT that might indicate the start of a new picture - keep looking
         case NAL_UNIT_PREFIX_APS:
         case NAL_UNIT_PREFIX_SEI:
@@ -222,7 +221,7 @@ bool SubpicMergeApp::isNewPicture(std::ifstream *bitstreamFile, InputByteStream
       }
     }
   }
-  
+
   // restore previous stream location - minus 3 due to the need for the annexB parser to read three extra bytes
 #if RExt__DECODER_DEBUG_BIT_STATISTICS
   bitstreamFile->clear();
@@ -302,6 +301,27 @@ void SubpicMergeApp::parseAPS(HLSyntaxReader &hlsReader, ParameterSetManager &ps
   msg( INFO, "  APS%i", apsId);
 }
 
+/**
+  - Parse SEI message
+*/
+void SubpicMergeApp::parseSEI(SEIReader &seiReader, InputNALUnit &nalu, const VPS *vps, const SPS *sps, SEI *&decodePictureHashSei)
+{
+  SEIMessages seis;
+  HRD hrd;
+
+  seiReader.parseSEImessage(seiReader.getBitstream(), seis, nalu.m_nalUnitType, nalu.m_nuhLayerId, nalu.m_temporalId, vps, sps, hrd, 0);
+
+  decodePictureHashSei = nullptr;
+  for (auto& s : seis)
+  {
+    if (s->payloadType() == SEI::DECODED_PICTURE_HASH)
+    {
+      decodePictureHashSei = s;
+      break;
+    }
+  }
+}
+
 /**
   - Parse picture header
 */
@@ -339,10 +359,12 @@ void SubpicMergeApp::parseSliceHeader(HLSyntaxReader &hlsReader, InputNALUnit &n
 /**
   - Decode NAL unit if it is parameter set or picture header, or decode slice header of VLC NAL unit
  */
-void SubpicMergeApp::decodeNalu(Subpicture &subpic, InputNALUnit &nalu)
+void SubpicMergeApp::decodeNalu(Subpicture &subpic, InputNALUnit &nalu, SEI *&decodePictureHashSei)
 {
   HLSyntaxReader hlsReader;
+  SEIReader seiReader;
   hlsReader.setBitstream(&nalu.getBitstream());
+  seiReader.setBitstream(&nalu.getBitstream());
   int apsId;
   int apsType;
 
@@ -366,7 +388,18 @@ void SubpicMergeApp::decodeNalu(Subpicture &subpic, InputNALUnit &nalu)
     break;
   case NAL_UNIT_PH:
     parsePictureHeader(hlsReader, subpic.picHeader, subpic.psManager);
-  break;
+    break;
+  case NAL_UNIT_SUFFIX_SEI:
+    parseSEI(seiReader, nalu, subpic.slices.front().getVPS(), subpic.slices.front().getSPS(), decodePictureHashSei);
+    if (decodePictureHashSei != nullptr)
+    {
+      msg( INFO, "  hash SEI");
+    }
+    else
+    {
+      msg( INFO, "  suffix SEI");
+    }
+    break;
   default:
     if (nalu.isVcl())
     {
@@ -376,11 +409,11 @@ void SubpicMergeApp::decodeNalu(Subpicture &subpic, InputNALUnit &nalu)
     }
     else if (nalu.isSei())
     {
-      msg( INFO, "  SEI");
+      msg( INFO, "  prefix SEI");
     }
     else
     {
-      msg( INFO, "  NNN");  // Any other NAL unit that is not handled above
+      msg( INFO, "  ignored NALU");  // Any other NAL unit that is not handled above
     }
     break;
   }
@@ -403,6 +436,7 @@ void SubpicMergeApp::parseSubpic(Subpicture &subpic, bool &morePictures)
   subpic.slices.clear();
   subpic.sliceData.clear();
   subpic.firstSliceInPicture = true;
+  subpic.decodedPictureHashSei = nullptr;
 
   bool eof = false;
 
@@ -431,7 +465,7 @@ void SubpicMergeApp::parseSubpic(Subpicture &subpic, bool &morePictures)
     }
 
     read(nalu);  // Convert nalu payload to RBSP and parse nalu header
-    decodeNalu(subpic, nalu);
+    decodeNalu(subpic, nalu, subpic.decodedPictureHashSei);
 
     if (nalu.isVcl())
     {
@@ -448,7 +482,7 @@ void SubpicMergeApp::generateMergedStreamVPSes(std::vector<VPS*> &vpsList)
 {
   for (auto vpsId : m_subpics->at(0).vpsIds)
   {
-    // Create new SPS based on the SPS from the first subpicture 
+    // Create new SPS based on the SPS from the first subpicture
     vpsList.push_back(new VPS(*m_subpics->at(0).psManager.getVPS(vpsId)));
     VPS &vps = *vpsList.back();
 
@@ -493,7 +527,7 @@ void SubpicMergeApp::generateMergedStreamSPSes(std::vector<SPS*> &spsList)
 
   for (auto spsId : m_subpics->at(0).spsIds)
   {
-    // Create new SPS based on the SPS from the first subpicture 
+    // Create new SPS based on the SPS from the first subpicture
     spsList.push_back(new SPS(*m_subpics->at(0).psManager.getSPS(spsId)));
     SPS &sps = *spsList.back();
 
@@ -535,25 +569,59 @@ void SubpicMergeApp::getTileDimensions(std::vector<int> &tileWidths, std::vector
   std::vector<int> tileX;
   std::vector<int> tileY;
 
+  // Add subpicture boundaries as tile boundaries
+  for (auto &subpic : *m_subpics)
+  {
+    bool addTileXForCurrentSubpic = true;
+    bool addTileYForCurrentSubpic = true;
+
+    // Check if current subpic boundary need to be added as tile boundary
+    for (auto &subpicScan : *m_subpics)
+    {
+      if (subpic.topLeftCornerX >= subpicScan.topLeftCornerX && (subpic.topLeftCornerX + subpic.width) <= (subpicScan.topLeftCornerX + subpicScan.width) && subpic.width < subpicScan.width)
+      {
+        addTileXForCurrentSubpic = false;
+      }
+      if (subpic.topLeftCornerY >= subpicScan.topLeftCornerY && (subpic.topLeftCornerY + subpic.height) <= (subpicScan.topLeftCornerY + subpicScan.height) && subpic.height < subpicScan.height)
+      {
+        addTileYForCurrentSubpic = false;
+      }
+    }
+
+    if (addTileXForCurrentSubpic)
+    {
+      tileX.push_back(subpic.topLeftCornerX);
+    }
+    if (addTileYForCurrentSubpic)
+    {
+      tileY.push_back(subpic.topLeftCornerY);
+    }
+  }
+
+  // Add tile boundaries from tiles within subpictures
   for (auto &subpic : *m_subpics)
   {
-    tileX.push_back(subpic.topLeftCornerX);
-    tileY.push_back(subpic.topLeftCornerY);
     const PPS &pps = *subpic.slices[0].getPPS();
     if (!pps.getNoPicPartitionFlag())
     {
-      int x = subpic.topLeftCornerX;
-      for (int i = 0; i < pps.getNumTileColumns(); i++)
+      if (pps.getNumTileColumns() > 1)
       {
-        x += pps.getTileColumnWidth(i) * pps.getCtuSize();
-        tileX.push_back(x);
+        int x = subpic.topLeftCornerX;
+        for (int i = 0; i < pps.getNumTileColumns(); i++)
+        {
+          x += pps.getTileColumnWidth(i) * pps.getCtuSize();
+          tileX.push_back(x);
+        }
       }
 
-      int y = subpic.topLeftCornerY;
-      for (int i = 0; i < pps.getNumTileRows(); i++)
+      if (pps.getNumTileRows() > 1)
       {
-        y += pps.getTileRowHeight(i) * pps.getCtuSize();
-        tileY.push_back(y);
+        int y = subpic.topLeftCornerY;
+        for (int i = 0; i < pps.getNumTileRows(); i++)
+        {
+          y += pps.getTileRowHeight(i) * pps.getCtuSize();
+          tileY.push_back(y);
+        }
       }
     }
   }
@@ -601,7 +669,7 @@ void SubpicMergeApp::generateMergedStreamPPSes(ParameterSetManager &psManager, s
 
   for (auto ppsId : m_subpics->at(0).ppsIds)
   {
-    // Create new PPS based on the PPS from the first subpicture 
+    // Create new PPS based on the PPS from the first subpicture
     ppsList.push_back(new PPS(*m_subpics->at(0).psManager.getPPS(ppsId)));
     PPS &pps = *ppsList.back();
     SPS &sps = *psManager.getSPS(pps.getSPSId());
@@ -642,52 +710,82 @@ void SubpicMergeApp::generateMergedStreamPPSes(ParameterSetManager &psManager, s
     pps.setTileIdxDeltaPresentFlag(true);
     pps.initRectSlices( );
 
-    unsigned int numTileColsInPic = pps.getNumTileColumns();
-
-    unsigned int sliceIdx = 0;
+    pps.setSingleSlicePerSubPicFlag(true);
     for (auto &subpic : *m_subpics)
     {
-      unsigned int tileIdxY = 0;
-      for (unsigned int tileY = 0; tileY != subpic.topLeftCornerY && tileIdxY < tileHeights.size(); tileIdxY++)
+      const PPS &subpicPPS = *subpic.slices[0].getPPS();
+      if (subpicPPS.getNumSlicesInPic() > 1)
       {
-        tileY += tileHeights[tileIdxY];
+        pps.setSingleSlicePerSubPicFlag(false);
+        break;
       }
-      CHECK(tileIdxY == tileHeights.size(), "Could not find subpicture to tile border match");
+    }
+
+    if (!pps.getSingleSlicePerSubPicFlag())
+    {
+      unsigned int numTileColsInPic = pps.getNumTileColumns();
 
-      unsigned int tileIdxX = 0;
-      for (unsigned int tileX = 0; tileX != subpic.topLeftCornerX && tileIdxX < tileWidths.size(); tileIdxX++)
+      unsigned int sliceIdx = 0;
+      for (auto& subpic : *m_subpics)
       {
-        tileX += tileWidths[tileIdxX];
-      }
-      CHECK(tileIdxX == tileWidths.size(), "Could not find subpicture to tile border match")
+        unsigned int tileIdxY = 0;
+        for (unsigned int tileY = 0; tileIdxY < tileHeights.size(); tileIdxY++)
+        {
+          if (tileY == subpic.topLeftCornerY || (tileY + tileHeights[tileIdxY]) == (subpic.topLeftCornerY + subpic.height) ||
+              (tileY < subpic.topLeftCornerY && (tileY + tileHeights[tileIdxY]) >(subpic.topLeftCornerY + subpic.height)))
+          {
+            break;
+          }
+          tileY += tileHeights[tileIdxY];
+        }
+        CHECK(tileIdxY == tileHeights.size(), "Could not find subpicture to tile mapping");
 
-      const PPS &subpicPPS = *subpic.slices[0].getPPS();
+        unsigned int tileIdxX = 0;
+        for (unsigned int tileX = 0; tileIdxX < tileWidths.size(); tileIdxX++)
+        {
+          if (tileX == subpic.topLeftCornerX || (tileX + tileWidths[tileIdxX]) == (subpic.topLeftCornerX + subpic.width) ||
+              (tileX < subpic.topLeftCornerX && (tileX + tileWidths[tileIdxX]) >(subpic.topLeftCornerX + subpic.width)))
+          {
+            break;
+          }
+          tileX += tileWidths[tileIdxX];
+        }
+        CHECK(tileIdxX == tileWidths.size(), "Could not find subpicture to tile mapping")
 
-      if (subpicPPS.getNumSlicesInPic() == 1)
-      {
-        pps.setSliceWidthInTiles(sliceIdx, subpicPPS.getNumTileColumns());
-        pps.setSliceHeightInTiles(sliceIdx, subpicPPS.getNumTileRows());
-        pps.setNumSlicesInTile(sliceIdx, 1);
-        unsigned int sliceTileIdx = tileIdxY * numTileColsInPic + tileIdxX;
-        pps.setSliceTileIdx(sliceIdx, sliceTileIdx);
-        pps.setSliceHeightInCtu(sliceIdx, subpicPPS.getPicHeightInCtu());
-
-        sliceIdx++;
-      }
-      else
-      {
-        for (int subpicSliceIdx = 0; subpicSliceIdx < subpicPPS.getNumSlicesInPic(); subpicSliceIdx++, sliceIdx++)
+        const PPS& subpicPPS = *subpic.slices[0].getPPS();
+
+        if (subpicPPS.getNumSlicesInPic() == 1)
         {
-          pps.setSliceWidthInTiles(sliceIdx, subpicPPS.getSliceWidthInTiles(subpicSliceIdx));
-          pps.setSliceHeightInTiles(sliceIdx, subpicPPS.getSliceHeightInTiles(subpicSliceIdx));
-          pps.setNumSlicesInTile(sliceIdx, subpicPPS.getNumSlicesInTile(subpicSliceIdx));
-          unsigned int sliceTileIdxSubpic = subpicPPS.getSliceTileIdx(subpicSliceIdx);
-          unsigned int sliceTileIdx = (sliceTileIdxSubpic / subpicPPS.getNumTileColumns() + tileIdxY) * numTileColsInPic + tileIdxX + (sliceTileIdxSubpic % subpicPPS.getNumTileColumns());
+          pps.setSliceWidthInTiles(sliceIdx, subpicPPS.getNumTileColumns());
+          pps.setSliceHeightInTiles(sliceIdx, subpicPPS.getNumTileRows());
+          pps.setNumSlicesInTile(sliceIdx, 1);
+          unsigned int sliceTileIdx = tileIdxY * numTileColsInPic + tileIdxX;
           pps.setSliceTileIdx(sliceIdx, sliceTileIdx);
-          pps.setSliceHeightInCtu(sliceIdx, subpicPPS.getSliceHeightInCtu(subpicSliceIdx));
+          pps.setSliceHeightInCtu(sliceIdx, subpicPPS.getPicHeightInCtu());
+
+          sliceIdx++;
+        }
+        else
+        {
+          for (int subpicSliceIdx = 0; subpicSliceIdx < subpicPPS.getNumSlicesInPic(); subpicSliceIdx++, sliceIdx++)
+          {
+            pps.setSliceWidthInTiles(sliceIdx, subpicPPS.getSliceWidthInTiles(subpicSliceIdx));
+            pps.setSliceHeightInTiles(sliceIdx, subpicPPS.getSliceHeightInTiles(subpicSliceIdx));
+            pps.setNumSlicesInTile(sliceIdx, subpicPPS.getNumSlicesInTile(subpicSliceIdx));
+            unsigned int sliceTileIdxSubpic = subpicPPS.getSliceTileIdx(subpicSliceIdx);
+            unsigned int sliceTileIdx = (sliceTileIdxSubpic / subpicPPS.getNumTileColumns() + tileIdxY) * numTileColsInPic + tileIdxX + (sliceTileIdxSubpic % subpicPPS.getNumTileColumns());
+            pps.setSliceTileIdx(sliceIdx, sliceTileIdx);
+            pps.setSliceHeightInCtu(sliceIdx, subpicPPS.getSliceHeightInCtu(subpicSliceIdx));
+          }
         }
       }
     }
+    else
+    {
+      pps.setTileIdxDeltaPresentFlag(false);
+    }
+
+    pps.initRectSliceMap(&sps);
 
     pps.setLoopFilterAcrossTilesEnabledFlag(false);
     pps.setLoopFilterAcrossSlicesEnabledFlag(false);
@@ -708,8 +806,8 @@ void SubpicMergeApp::updateSliceHeadersForMergedStream(ParameterSetManager &psMa
       // Update slice headers to use new SPSes and PPSes
       int ppsId = slice.getPPS()->getPPSId();
       int spsId = slice.getSPS()->getSPSId();
-      CHECK(!psManager.getSPS(spsId), "Invaldi SPS");
-      CHECK(!psManager.getSPS(ppsId), "Invaldi PPS");
+      CHECK(!psManager.getSPS(spsId), "Invalid SPS");
+      CHECK(!psManager.getSPS(ppsId), "Invalid PPS");
       slice.setSPS(psManager.getSPS(spsId));
       slice.setPPS(psManager.getPPS(ppsId));
 
@@ -801,7 +899,7 @@ Subpicture &SubpicMergeApp::selectSubpicForPicHeader(bool isMixedNaluPic)
   Subpicture *subpicToReturn = NULL;
   bool IRAPFound = false;
 
-  // Find first non-IRAP subpicture 
+  // Find first non-IRAP subpicture
   for (auto &subpic : *m_subpics)
   {
     if (subpic.slices[0].isIRAP())
@@ -906,9 +1004,6 @@ void SubpicMergeApp::generateMergedPic(ParameterSetManager &psManager, bool mixe
     }
   }
 
-  // Don't copy SEI NAL units - many of them would be incorrect for merged stream
-  //copyNalUnitsToAccessUnit(accessUnit, subpic.nalus, (int)NAL_UNIT_PREFIX_SEI);
-
   updateSliceHeadersForMergedStream(psManager);
 
   // Code merged stream prefix APS NAL units
@@ -967,8 +1062,36 @@ void SubpicMergeApp::generateMergedPic(ParameterSetManager &psManager, bool mixe
     }
   }
 
-  // Don't copy SEIs - many of them would be incorrect for merged stream
-  // copyNalUnitsToAccessUnit(accessUnit, subpic.nalus, (int)NAL_UNIT_SUFFIX_SEI);
+  // Code Decoded picture hash SEI messages within Scalable nesting SEI messages
+  uint32_t layerId = m_subpics->at(0).slices[0].getNalUnitLayerId();
+  uint32_t temporalId = m_subpics->at(0).slices[0].getTLayer();
+  int subpicId = 0;
+  for (auto& subpic : *m_subpics)
+  {
+    if (subpic.decodedPictureHashSei != nullptr)
+    {
+      SEIEncoder seiEncoder;
+      SEIWriter seiWriter;
+      SEIMessages seiMessages;
+      SEIMessages nestedSEI;
+      HRD hrd;
+      nestedSEI.push_back(subpic.decodedPictureHashSei);
+      const std::vector<uint16_t> subPicIds = { (uint16_t)subpicId };
+      std::vector<int> targetOLS;
+      std::vector<int> targetLayers = { (int)subpic.nalus[0].m_nuhLayerId };
+      SEIScalableNesting *nestingSEI = new SEIScalableNesting();
+      seiEncoder.init(0, 0, 0);
+      const uint16_t maxSubpicIdInPic =
+        subPicIds.size() == 0 ? 0 : *std::max_element(subPicIds.begin(), subPicIds.end());
+      seiEncoder.initSEIScalableNesting(nestingSEI, nestedSEI, targetOLS, targetLayers, subPicIds, maxSubpicIdInPic);
+      OutputNALUnit nalu( NAL_UNIT_SUFFIX_SEI, layerId, temporalId );
+      seiMessages.push_back(nestingSEI);
+      seiWriter.writeSEImessages(nalu.m_Bitstream, seiMessages, hrd, false, temporalId);
+      accessUnit.push_back(new NALUnitEBSP(nalu));
+    }
+    subpicId++;
+  }
+
   copyNalUnitsToAccessUnit(accessUnit, subpic0.nalus, (int)NAL_UNIT_EOS);
   copyNalUnitsToAccessUnit(accessUnit, subpic0.nalus, (int)NAL_UNIT_EOB);
 
diff --git a/source/App/SubpicMergeApp/SubpicMergeApp.h b/source/App/SubpicMergeApp/SubpicMergeApp.h
index f293993d0..2a5285e3a 100644
--- a/source/App/SubpicMergeApp/SubpicMergeApp.h
+++ b/source/App/SubpicMergeApp/SubpicMergeApp.h
@@ -3,7 +3,7 @@
 * and contributor rights, including patent rights, and no such rights are
 * granted under this license.
 *
-* Copyright (c) 2010-2020, ITU/ISO/IEC
+* Copyright (c) 2010-2021, ITU/ISO/IEC
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
@@ -56,6 +56,8 @@ struct SubpicParams {
 struct Subpicture;
 class InputByteStream;
 class HLSyntaxReader;
+class SEIReader;
+class SEI;
 class DCI;
 class ParameterSetManager;
 class PicHeader;
@@ -92,9 +94,10 @@ private:
   int parseSPS(HLSyntaxReader &hlsReader, ParameterSetManager &psManager);
   int parsePPS(HLSyntaxReader &hlsReader, ParameterSetManager &psManager);
   void parseAPS(HLSyntaxReader &hlsReader, ParameterSetManager &psManager, int &apsId, int &apsType);
+  void parseSEI(SEIReader& seiReader, InputNALUnit &nalu, const VPS *vps, const SPS *sps, SEI *&decodePictureHashSei);
   void parsePictureHeader(HLSyntaxReader &hlsReader, PicHeader &picHeader, ParameterSetManager &psManager);
   void parseSliceHeader(HLSyntaxReader &hlsReader, InputNALUnit &nalu, Slice &slice, PicHeader &picHeader, OutputBitstream &sliceData, ParameterSetManager &psManager, int prevTid0Poc);
-  void decodeNalu(Subpicture &subpic, InputNALUnit &nalu);
+  void decodeNalu(Subpicture &subpic, InputNALUnit &nalu, SEI *&decodePictureHashSei);
   void parseSubpic(Subpicture &subpic, bool &morePictures);
   void generateMergedStreamVPSes(std::vector<VPS*> &vpsList);
   int computeSubPicIdLen(int numSubpics);
diff --git a/source/App/SubpicMergeApp/SubpicMergeMain.cpp b/source/App/SubpicMergeApp/SubpicMergeMain.cpp
index 6b37d09c8..51f4587b3 100644
--- a/source/App/SubpicMergeApp/SubpicMergeMain.cpp
+++ b/source/App/SubpicMergeApp/SubpicMergeMain.cpp
@@ -3,7 +3,7 @@
 * and contributor rights, including patent rights, and no such rights are
 * granted under this license.
 *
-* Copyright (c) 2010-2020, ITU/ISO/IEC
+* Copyright (c) 2010-2021, ITU/ISO/IEC
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/CommonAnalyserLib/CMakeLists.txt b/source/Lib/CommonAnalyserLib/CMakeLists.txt
index e915720f2..40471bb3e 100644
--- a/source/Lib/CommonAnalyserLib/CMakeLists.txt
+++ b/source/Lib/CommonAnalyserLib/CMakeLists.txt
@@ -64,31 +64,9 @@ if( SET_ENABLE_TRACING )
     target_compile_definitions( ${LIB_NAME} PUBLIC ENABLE_TRACING=0 )
   endif()
 endif()
-
-if( OpenMP_FOUND )
-  if( SET_ENABLE_SPLIT_PARALLELISM )
-    if( ENABLE_SPLIT_PARALLELISM )
-      target_compile_definitions( ${LIB_NAME} PUBLIC ENABLE_SPLIT_PARALLELISM=1 )
-    else()
-      target_compile_definitions( ${LIB_NAME} PUBLIC ENABLE_SPLIT_PARALLELISM=0 )
-    endif()
-  endif()
-  if( SET_ENABLE_WPP_PARALLELISM )
-    if( ENABLE_WPP_PARALLELISM )
-      target_compile_definitions( ${LIB_NAME} PUBLIC ENABLE_WPP_PARALLELISM=1 )
-    else()
-      target_compile_definitions( ${LIB_NAME} PUBLIC ENABLE_WPP_PARALLELISM=0 )
-    endif()
-  endif()
-  target_include_directories( ${LIB_NAME} PUBLIC ${OpenMP_CXX_INCLUDE_DIRS} )
-  target_link_libraries( ${LIB_NAME} ${OpenMP_CXX_LIBRARIES} )
-else()
-  target_compile_definitions( ${LIB_NAME} PUBLIC ENABLE_SPLIT_PARALLELISM=0 )
-  target_compile_definitions( ${LIB_NAME} PUBLIC ENABLE_WPP_PARALLELISM=0 )
-endif()
   
 target_include_directories( ${LIB_NAME} PUBLIC ../CommonLib/. ../CommonLib/.. ../CommonLib/x86 ../libmd5 )
-target_link_libraries( ${LIB_NAME} Threads::Threads )
+target_link_libraries( ${LIB_NAME} )
 
 # set needed compile definitions
 set_property( SOURCE ${SSE41_SRC_FILES} APPEND PROPERTY COMPILE_DEFINITIONS USE_SSE41 )
diff --git a/source/Lib/CommonLib/AdaptiveLoopFilter.cpp b/source/Lib/CommonLib/AdaptiveLoopFilter.cpp
index 91b0490bd..61105f0c0 100644
--- a/source/Lib/CommonLib/AdaptiveLoopFilter.cpp
+++ b/source/Lib/CommonLib/AdaptiveLoopFilter.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -435,7 +435,7 @@ void AdaptiveLoopFilter::ALFProcess(CodingStructure& cs)
       const CodingUnit *cu = cs.getCU( Position(xPos, yPos), CHANNEL_TYPE_LUMA );
 
       // skip this CTU if ALF is disabled
-      if (!cu->slice->getTileGroupAlfEnabledFlag(COMPONENT_Y) && !cu->slice->getTileGroupAlfEnabledFlag(COMPONENT_Cb) && !cu->slice->getTileGroupAlfEnabledFlag(COMPONENT_Cr))
+      if (!cu->slice->getAlfEnabledFlag(COMPONENT_Y) && !cu->slice->getAlfEnabledFlag(COMPONENT_Cb) && !cu->slice->getAlfEnabledFlag(COMPONENT_Cr))
       {
         ctuIdx++;
         continue;
@@ -445,7 +445,7 @@ void AdaptiveLoopFilter::ALFProcess(CodingStructure& cs)
       if(ctuIdx == 0 || lastSliceIdx != cu->slice->getSliceID() || alfCtuFilterIndex==nullptr)
       {
         cs.slice = cu->slice;
-        reconstructCoeffAPSs(cs, true, cu->slice->getTileGroupAlfEnabledFlag(COMPONENT_Cb) || cu->slice->getTileGroupAlfEnabledFlag(COMPONENT_Cr), false);
+        reconstructCoeffAPSs(cs, true, cu->slice->getAlfEnabledFlag(COMPONENT_Cb) || cu->slice->getAlfEnabledFlag(COMPONENT_Cr), false);
         alfCtuFilterIndex = cu->slice->getPic()->getAlfCtbFilterIndex();
         m_ccAlfFilterParam = cu->slice->m_ccAlfFilterParam;
       }
@@ -627,9 +627,9 @@ void AdaptiveLoopFilter::reconstructCoeffAPSs(CodingStructure& cs, bool luma, bo
   APS* curAPS;
   if (luma)
   {
-    for (int i = 0; i < cs.slice->getTileGroupNumAps(); i++)
+    for (int i = 0; i < cs.slice->getNumAlfApsIdsLuma(); i++)
     {
-      int apsIdx = cs.slice->getTileGroupApsIdLuma()[i];
+      int apsIdx = cs.slice->getAlfApsIdsLuma()[i];
       curAPS = aps[apsIdx];
       CHECK(curAPS == NULL, "invalid APS");
       alfParamTmp = curAPS->getAlfAPSParam();
@@ -642,7 +642,7 @@ void AdaptiveLoopFilter::reconstructCoeffAPSs(CodingStructure& cs, bool luma, bo
   //chroma
   if (chroma)
   {
-    int apsIdxChroma = cs.slice->getTileGroupApsIdChroma();
+    int apsIdxChroma = cs.slice->getAlfApsIdChroma();
     curAPS = aps[apsIdxChroma];
     m_alfParamChroma = &curAPS->getAlfAPSParam();
     alfParamTmp = *m_alfParamChroma;
diff --git a/source/Lib/CommonLib/AdaptiveLoopFilter.h b/source/Lib/CommonLib/AdaptiveLoopFilter.h
index 4df4485d9..aa8284b44 100644
--- a/source/Lib/CommonLib/AdaptiveLoopFilter.h
+++ b/source/Lib/CommonLib/AdaptiveLoopFilter.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/CommonLib/AffineGradientSearch.cpp b/source/Lib/CommonLib/AffineGradientSearch.cpp
index 90d939ac7..0764936eb 100644
--- a/source/Lib/CommonLib/AffineGradientSearch.cpp
+++ b/source/Lib/CommonLib/AffineGradientSearch.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/CommonLib/AffineGradientSearch.h b/source/Lib/CommonLib/AffineGradientSearch.h
index 380db3207..cc04bff90 100644
--- a/source/Lib/CommonLib/AffineGradientSearch.h
+++ b/source/Lib/CommonLib/AffineGradientSearch.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/CommonLib/AlfParameters.h b/source/Lib/CommonLib/AlfParameters.h
index 3bf050d84..5cec8edf5 100644
--- a/source/Lib/CommonLib/AlfParameters.h
+++ b/source/Lib/CommonLib/AlfParameters.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -112,7 +112,7 @@ struct AlfFilterShape
     else
     {
       filterType = ALF_NUM_OF_FILTER_TYPES;
-      CHECK( 0, "Wrong ALF filter shape" );
+      THROW("Wrong ALF filter shape");
     }
   }
 
diff --git a/source/Lib/CommonLib/BitStream.cpp b/source/Lib/CommonLib/BitStream.cpp
index 58a3360b3..f89692d5a 100644
--- a/source/Lib/CommonLib/BitStream.cpp
+++ b/source/Lib/CommonLib/BitStream.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/CommonLib/BitStream.h b/source/Lib/CommonLib/BitStream.h
index bce5feadc..5688c689c 100644
--- a/source/Lib/CommonLib/BitStream.h
+++ b/source/Lib/CommonLib/BitStream.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/CommonLib/Buffer.cpp b/source/Lib/CommonLib/Buffer.cpp
index b691f54e4..a72afc49e 100644
--- a/source/Lib/CommonLib/Buffer.cpp
+++ b/source/Lib/CommonLib/Buffer.cpp
@@ -3,7 +3,7 @@
 * and contributor rights, including patent rights, and no such rights are
 * granted under this license.
 *
-* Copyright (c) 2010-2020, ITU/ISO/IEC
+* Copyright (c) 2010-2021, ITU/ISO/IEC
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
@@ -249,6 +249,40 @@ void removeHighFreq(int16_t* dst, int dstStride, const int16_t* src, int srcStri
 #undef REM_HF_OP
 #undef REM_HF_OP_CLIP
 }
+#if RExt__HIGH_BIT_DEPTH_SUPPORT
+void removeWeightHighFreq_HBD(Pel* dst, int dstStride, const Pel* src, int srcStride, int width, int height, int shift, int bcwWeight)
+{
+  Intermediate_Int normalizer = ((1 << 16) + (bcwWeight > 0 ? (bcwWeight >> 1) : -(bcwWeight >> 1))) / bcwWeight;
+  Intermediate_Int weight0 = normalizer << g_BcwLog2WeightBase;
+  Intermediate_Int weight1 = (g_BcwWeightBase - bcwWeight)*normalizer;
+#define REM_HF_INC  \
+  src += srcStride; \
+  dst += dstStride; \
+
+#define REM_HF_OP( ADDR )      dst[ADDR] =             (Pel)((dst[ADDR]*weight0 - src[ADDR]*weight1 + (1<<15))>>16)
+
+  SIZE_AWARE_PER_EL_OP(REM_HF_OP, REM_HF_INC);
+
+#undef REM_HF_INC
+#undef REM_HF_OP
+#undef REM_HF_OP_CLIP
+}
+
+void removeHighFreq_HBD(Pel* dst, int dstStride, const Pel* src, int srcStride, int width, int height)
+{
+#define REM_HF_INC  \
+  src += srcStride; \
+  dst += dstStride; \
+
+#define REM_HF_OP( ADDR )      dst[ADDR] =             2 * dst[ADDR] - src[ADDR]
+
+  SIZE_AWARE_PER_EL_OP(REM_HF_OP, REM_HF_INC);
+
+#undef REM_HF_INC
+#undef REM_HF_OP
+#undef REM_HF_OP_CLIP
+}
+#endif
 #endif
 
 template<typename T>
@@ -299,10 +333,17 @@ PelBufferOps::PelBufferOps()
   copyBuffer = copyBufferCore;
   padding = paddingCore;
 #if ENABLE_SIMD_OPT_BCW
+#if RExt__HIGH_BIT_DEPTH_SUPPORT
+  removeWeightHighFreq8 = removeWeightHighFreq_HBD;
+  removeWeightHighFreq4 = removeWeightHighFreq_HBD;
+  removeHighFreq8 = removeHighFreq_HBD;
+  removeHighFreq4 = removeHighFreq_HBD;
+#else
   removeWeightHighFreq8 = removeWeightHighFreq;
   removeWeightHighFreq4 = removeWeightHighFreq;
   removeHighFreq8 = removeHighFreq;
   removeHighFreq4 = removeHighFreq;
+#endif
 #endif
 
   profGradFilter = gradFilterCore <false>;
@@ -381,15 +422,15 @@ void AreaBuf<Pel>::rspSignal(std::vector<Pel>& pLUT)
 {
   Pel* dst = buf;
   Pel* src = buf;
-    for (unsigned y = 0; y < height; y++)
+  for (unsigned y = 0; y < height; y++)
+  {
+    for (unsigned x = 0; x < width; x++)
     {
-      for (unsigned x = 0; x < width; x++)
-      {
-        dst[x] = pLUT[src[x]];
-      }
-      dst += stride;
-      src += stride;
+      dst[x] = pLUT[src[x]];
     }
+    dst += stride;
+    src += stride;
+  }
 }
 
 template<>
@@ -443,6 +484,61 @@ void AreaBuf<Pel>::scaleSignal(const int scale, const bool dir, const ClpRng& cl
   }
 }
 
+template<>
+void AreaBuf<Pel>::applyLumaCTI(std::vector<Pel>& pLUTY)
+{
+  Pel* dst = buf;
+  Pel* src = buf;
+  for (unsigned y = 0; y < height; y++)
+  {
+    for (unsigned x = 0; x < width; x++)
+    {
+      dst[x] = pLUTY[src[x]];
+    }
+    dst += stride;
+    src += stride;
+  }
+}
+
+template<>
+void AreaBuf<Pel>::applyChromaCTI(Pel* bufY, int strideY, std::vector<Pel>& pLUTC, int bitDepth, ChromaFormat chrFormat, bool fwdMap)
+{
+  int range = 1 << bitDepth;
+  int offset = range / 2;
+  int sx = 1 << getComponentScaleX(COMPONENT_Cb, chrFormat);
+  int sy = 1 << getComponentScaleY(COMPONENT_Cb, chrFormat);
+
+  Pel* dst = buf;
+  Pel* src = buf;
+  if (fwdMap)
+  {
+    for (unsigned y = 0; y < height; y++)
+    {
+      for (unsigned x = 0; x < width; x++)
+      {
+        int pelY = bufY[sy * y * strideY + sx * x];
+        double scale = (double)pLUTC[pelY] / (double)(1 << CSCALE_FP_PREC);
+        dst[x] = Clip3((Pel)0, (Pel)(range - 1), (Pel)(offset + (double)(src[x] - offset) / scale + .5));
+      }
+      dst += stride;
+      src += stride;
+    }
+  }
+  else
+  {
+    for (unsigned y = 0; y < height; y++)
+    {
+      for (unsigned x = 0; x < width; x++)
+      {
+        int pelY = bufY[sy * y * strideY + sx * x];
+        int scal = pLUTC[pelY];
+        dst[x] = Clip3(0, range - 1, ((offset << CSCALE_FP_PREC) + (src[x] - offset) * scal + (1 << (CSCALE_FP_PREC - 1))) >> CSCALE_FP_PREC);
+      }
+      dst += stride;
+      src += stride;
+    }
+  }
+}
 template<>
 void AreaBuf<Pel>::addAvg( const AreaBuf<const Pel> &other1, const AreaBuf<const Pel> &other2, const ClpRng& clpRng)
 {
@@ -831,57 +927,57 @@ void UnitBuf<Pel>::colorSpaceConvert(const UnitBuf<Pel> &other, const bool forwa
   CHECK(other.bufs[COMPONENT_Y].stride != other.bufs[COMPONENT_Cb].stride || other.bufs[COMPONENT_Y].stride != other.bufs[COMPONENT_Cr].stride, "unequal stride for 444 content");
   CHECK(bufs[COMPONENT_Y].width != other.bufs[COMPONENT_Y].width || bufs[COMPONENT_Y].height != other.bufs[COMPONENT_Y].height, "unequal block size")
 
-    if (forward)
+  if (forward)
+  {
+    for (int y = 0; y < height; y++)
     {
-      for (int y = 0; y < height; y++)
+      for (int x = 0; x < width; x++)
       {
-        for (int x = 0; x < width; x++)
-        {
-          r = pOrg2[x];
-          g = pOrg0[x];
-          b = pOrg1[x];
-
-          co = r - b;
-          int t = b + (co >> 1);
-          cg = g - t;
-          pDst0[x] = t + (cg >> 1);
-          pDst1[x] = cg;
-          pDst2[x] = co;
-        }
-        pOrg0 += strideOrg;
-        pOrg1 += strideOrg;
-        pOrg2 += strideOrg;
-        pDst0 += strideDst;
-        pDst1 += strideDst;
-        pDst2 += strideDst;
+        r = pOrg2[x];
+        g = pOrg0[x];
+        b = pOrg1[x];
+
+        co       = r - b;
+        int t    = b + (co >> 1);
+        cg       = g - t;
+        pDst0[x] = t + (cg >> 1);
+        pDst1[x] = cg;
+        pDst2[x] = co;
       }
+      pOrg0 += strideOrg;
+      pOrg1 += strideOrg;
+      pOrg2 += strideOrg;
+      pDst0 += strideDst;
+      pDst1 += strideDst;
+      pDst2 += strideDst;
     }
-    else
+  }
+  else
+  {
+    for (int y = 0; y < height; y++)
     {
-      for (int y = 0; y < height; y++)
+      for (int x = 0; x < width; x++)
       {
-        for (int x = 0; x < width; x++)
-        {
-          y0 = pOrg0[x];
-          cg = pOrg1[x];
-          co = pOrg2[x];
-
-          y0 = Clip3((-maxAbsclipBD - 1), maxAbsclipBD, y0);
-          cg = Clip3((-maxAbsclipBD - 1), maxAbsclipBD, cg);
-          co = Clip3((-maxAbsclipBD - 1), maxAbsclipBD, co);
-
-          int t = y0 - (cg >> 1);
-          pDst0[x] = cg + t;
-          pDst1[x] = t - (co >> 1);
-          pDst2[x] = co + pDst1[x];
-        }
-
-        pOrg0 += strideOrg;
-        pOrg1 += strideOrg;
-        pOrg2 += strideOrg;
-        pDst0 += strideDst;
-        pDst1 += strideDst;
-        pDst2 += strideDst;
+        y0 = pOrg0[x];
+        cg = pOrg1[x];
+        co = pOrg2[x];
+
+        y0 = Clip3((-maxAbsclipBD - 1), maxAbsclipBD, y0);
+        cg = Clip3((-maxAbsclipBD - 1), maxAbsclipBD, cg);
+        co = Clip3((-maxAbsclipBD - 1), maxAbsclipBD, co);
+
+        int t    = y0 - (cg >> 1);
+        pDst0[x] = cg + t;
+        pDst1[x] = t - (co >> 1);
+        pDst2[x] = co + pDst1[x];
       }
+
+      pOrg0 += strideOrg;
+      pOrg1 += strideOrg;
+      pOrg2 += strideOrg;
+      pDst0 += strideDst;
+      pDst1 += strideDst;
+      pDst2 += strideDst;
     }
+  }
 }
diff --git a/source/Lib/CommonLib/Buffer.h b/source/Lib/CommonLib/Buffer.h
index 4f7906076..de50d3175 100644
--- a/source/Lib/CommonLib/Buffer.h
+++ b/source/Lib/CommonLib/Buffer.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -137,6 +137,8 @@ struct AreaBuf : public Size
 
   void rspSignal            ( std::vector<Pel>& pLUT );
   void scaleSignal          ( const int scale, const bool dir , const ClpRng& clpRng);
+  void applyLumaCTI(std::vector<Pel>& pLUTY);
+  void applyChromaCTI(Pel* bufY, int strideY, std::vector<Pel>& pLUTUV, int bitDepth, ChromaFormat chrFormat, bool fwdMap);
   T    computeAvg           ( ) const;
 
         T& at( const int &x, const int &y )          { return buf[y * stride + x]; }
@@ -430,11 +432,17 @@ void AreaBuf<T>::removeWeightHighFreq(const AreaBuf<T>& other, const bool bClip,
   if(!bClip)
   {
     if(!(width & 7))
+    {
       g_pelBufOP.removeWeightHighFreq8(dst, dstStride, src, srcStride, width, height, 16, bcwWeight);
+    }
     else if(!(width & 3))
+    {
       g_pelBufOP.removeWeightHighFreq4(dst, dstStride, src, srcStride, width, height, 16, bcwWeight);
+    }
     else
-      CHECK(true, "Not supported");
+    {
+      THROW("Not supported");
+    }
   }
   else
   {
@@ -479,11 +487,17 @@ void AreaBuf<T>::removeHighFreq( const AreaBuf<T>& other, const bool bClip, cons
   if (!bClip)
   {
     if(!(width & 7))
+    {
       g_pelBufOP.removeHighFreq8(dst, dstStride, src, srcStride, width, height);
+    }
     else if (!(width & 3))
+    {
       g_pelBufOP.removeHighFreq4(dst, dstStride, src, srcStride, width, height);
+    }
     else
-      CHECK(true, "Not supported");
+    {
+      THROW("Not supported");
+    }
   }
   else
   {
diff --git a/source/Lib/CommonLib/CMakeLists.txt b/source/Lib/CommonLib/CMakeLists.txt
index 6ae75c82b..368545998 100644
--- a/source/Lib/CommonLib/CMakeLists.txt
+++ b/source/Lib/CommonLib/CMakeLists.txt
@@ -62,31 +62,9 @@ if( SET_ENABLE_TRACING )
     target_compile_definitions( ${LIB_NAME} PUBLIC ENABLE_TRACING=0 )
   endif()
 endif()
-
-if( OpenMP_FOUND )
-  if( SET_ENABLE_SPLIT_PARALLELISM )
-    if( ENABLE_SPLIT_PARALLELISM )
-      target_compile_definitions( ${LIB_NAME} PUBLIC ENABLE_SPLIT_PARALLELISM=1 )
-    else()
-      target_compile_definitions( ${LIB_NAME} PUBLIC ENABLE_SPLIT_PARALLELISM=0 )
-    endif()
-  endif()
-  if( SET_ENABLE_WPP_PARALLELISM )
-    if( ENABLE_WPP_PARALLELISM )
-      target_compile_definitions( ${LIB_NAME} PUBLIC ENABLE_WPP_PARALLELISM=1 )
-    else()
-      target_compile_definitions( ${LIB_NAME} PUBLIC ENABLE_WPP_PARALLELISM=0 )
-    endif()
-  endif()
-  target_include_directories( ${LIB_NAME} PUBLIC ${OpenMP_CXX_INCLUDE_DIRS} )
-  target_link_libraries( ${LIB_NAME} ${OpenMP_CXX_LIBRARIES} )
-else()
-  target_compile_definitions( ${LIB_NAME} PUBLIC ENABLE_SPLIT_PARALLELISM=0 )
-  target_compile_definitions( ${LIB_NAME} PUBLIC ENABLE_WPP_PARALLELISM=0 )
-endif()
   
 target_include_directories( ${LIB_NAME} PUBLIC . .. ./x86 ../libmd5 )
-target_link_libraries( ${LIB_NAME} Threads::Threads )
+target_link_libraries( ${LIB_NAME} )
 
 # set needed compile definitions
 set_property( SOURCE ${SSE41_SRC_FILES} APPEND PROPERTY COMPILE_DEFINITIONS USE_SSE41 )
diff --git a/source/Lib/CommonLib/CacheModel.cpp b/source/Lib/CommonLib/CacheModel.cpp
index 1f6d12224..2bd7b26bd 100644
--- a/source/Lib/CommonLib/CacheModel.cpp
+++ b/source/Lib/CommonLib/CacheModel.cpp
@@ -449,10 +449,11 @@ void CacheModel::cacheAccess( const Pel *addr, const std::string& fileName, cons
   // check cache hit in each way
   for ( way = 0 ; way < m_numWay ; way++ )
   {
-      if ( xIsCacheHit( pos + way, cacheAddr ) ) {
-        hit = true;
-        break;
-      }
+    if (xIsCacheHit(pos + way, cacheAddr))
+    {
+      hit = true;
+      break;
+    }
   }
 #if JVET_J0090_MEMORY_BANDWITH_MEASURE_PRINT_ACCESS_INFO
   if ( m_frameCount == JVET_J0090_MEMORY_BANDWITH_MEASURE_PRINT_FRAME )
diff --git a/source/Lib/CommonLib/CacheModel.h b/source/Lib/CommonLib/CacheModel.h
index 1150c24e0..ed71d9daa 100644
--- a/source/Lib/CommonLib/CacheModel.h
+++ b/source/Lib/CommonLib/CacheModel.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/CommonLib/ChromaFormat.cpp b/source/Lib/CommonLib/ChromaFormat.cpp
index 9a56d89e3..beec8c4dc 100644
--- a/source/Lib/CommonLib/ChromaFormat.cpp
+++ b/source/Lib/CommonLib/ChromaFormat.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/CommonLib/ChromaFormat.h b/source/Lib/CommonLib/ChromaFormat.h
index 14bc517bd..141351f5a 100644
--- a/source/Lib/CommonLib/ChromaFormat.h
+++ b/source/Lib/CommonLib/ChromaFormat.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/CommonLib/CodingStatistics.h b/source/Lib/CommonLib/CodingStatistics.h
index 2cbb789a9..42cd4d7ee 100644
--- a/source/Lib/CommonLib/CodingStatistics.h
+++ b/source/Lib/CommonLib/CodingStatistics.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/CommonLib/CodingStructure.cpp b/source/Lib/CommonLib/CodingStructure.cpp
index b655d445f..e9e084dba 100644
--- a/source/Lib/CommonLib/CodingStructure.cpp
+++ b/source/Lib/CommonLib/CodingStructure.cpp
@@ -3,7 +3,7 @@
 * and contributor rights, including patent rights, and no such rights are
 * granted under this license.
 *
-* Copyright (c) 2010-2020, ITU/ISO/IEC
+* Copyright (c) 2010-2021, ITU/ISO/IEC
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
@@ -93,6 +93,10 @@ CodingStructure::CodingStructure(CUCache& cuCache, PUCache& puCache, TUCache& tu
   }
 
   m_motionBuf     = nullptr;
+#if GDR_ENABLED
+  picHeader = nullptr;
+#endif
+
   features.resize( NUM_ENC_FEATURES );
   treeType = TREE_D;
   modeType = MODE_TYPE_ALL;
@@ -144,6 +148,676 @@ void CodingStructure::releaseIntermediateData()
   clearCUs();
 }
 
+#if GDR_ENABLED
+bool CodingStructure::containRefresh(int begX, int endX) const
+{
+  if (begX == endX)
+  {
+    return false;
+  }
+
+  const Area csArea      = area.Y();
+  const Area refreshArea = Area(begX, area.ly(), endX - begX, std::min(slice->getPPS()->getPicHeightInLumaSamples(), area.lheight()));
+
+  if (csArea.contains(refreshArea))
+  {
+    return true;
+  }
+
+  return false;
+}
+
+bool CodingStructure::overlapRefresh(int begX, int endX) const
+{
+  if (begX == endX)
+  {
+    return false;
+  }
+
+  const Area csArea = area.Y();
+  const Area refreshArea = Area(begX, area.ly(), endX - begX, area.lheight());
+
+  if (csArea.overlap(refreshArea))
+  {
+    return true;
+  }
+
+  return false;
+}
+
+bool CodingStructure::overlapRefresh() const
+{
+  const int  csX     = area.lx();
+  const int  csWidth = area.lwidth();
+
+  bool ret = overlapRefresh(csX, csX + csWidth);
+
+  return ret;
+}
+
+bool CodingStructure::withinRefresh(int begX, int endX) const
+{
+  if (begX == endX)
+  {
+    return false;
+  }
+
+  const Area csArea = area.Y();
+  const Area refreshArea = Area(begX, area.ly(), endX - begX, area.lheight());
+
+  if (refreshArea.contains(csArea))
+  {
+    return true;
+  }
+
+  return false;
+}
+
+bool CodingStructure::refreshCrossTTV(int begX, int endX) const
+{
+  const int  csX = area.lx();
+  const int  csY = area.ly();
+  const int  csWidth  = area.lwidth();
+  const int  csHeight = area.lheight();
+
+  const Area refreshArea = Area(begX, csY, endX - begX, csHeight);
+
+  const Area csArea0 = Area(csX,                                   csY, csWidth >> 2, csHeight);
+  const Area csArea1 = Area(csX + (csWidth >> 2),                  csY, csWidth >> 1, csHeight);
+  const Area csArea2 = Area(csX + (csWidth >> 2) + (csWidth >> 1), csY, csWidth >> 2, csHeight);
+
+  bool overlap0 = csArea0.overlap(refreshArea);
+  bool overlap1 = csArea1.overlap(refreshArea);
+  bool overlap2 = csArea2.overlap(refreshArea);
+
+  int sum = (overlap0 ? 1 : 0) + (overlap1 ? 1 : 0) + (overlap2 ? 1 : 0);
+
+  if (0 < sum)
+  {
+    return true;
+  }
+
+  return false;
+}
+
+bool CodingStructure::refreshCrossBTV(int begX, int endX) const
+{
+  const int  csX = area.lx();
+  const int  csY = area.ly();
+  const int  csWidth = area.lwidth();
+  const int  csHeight = area.lheight();
+
+  const Area refreshArea = Area(begX, csY, endX - begX, csHeight);
+
+  const Area csArea0 = Area(csX,                  csY, (csWidth >> 1), csHeight);
+  const Area csArea1 = Area(csX + (csWidth >> 1), csY, (csWidth >> 1), csHeight);
+
+  bool overlap0 = csArea0.overlap(refreshArea);
+  bool overlap1 = csArea1.overlap(refreshArea);
+
+  int sum = (overlap0 ? 1 : 0) + (overlap1 ? 1 : 0);
+
+  if (0 < sum)
+  {
+    return true;
+  }
+
+  return false;
+}
+
+bool CodingStructure::overlapDirty() const
+{
+  const Position topLeft  = area.Y().topLeft();
+  const Position topRight = area.Y().topRight();
+
+  bool insideLeft  = isClean(topLeft, CHANNEL_TYPE_LUMA);
+  bool insideRight = isClean(topRight, CHANNEL_TYPE_LUMA);
+
+  if (insideLeft != insideRight)
+  {
+    return true;
+  }
+
+  return false;
+}
+
+bool CodingStructure::dirtyCrossTTV() const
+{
+  const int  csX = area.lx();
+  const int  csY = area.ly();
+  const int  csWidth = area.lwidth();
+  const int  csHeight = area.lheight();
+
+  const Area csArea0 = Area(csX, csY, csWidth >> 2, csHeight);
+  const Area csArea1 = Area(csX + (csWidth >> 2), csY, csWidth >> 1, csHeight);
+  const Area csArea2 = Area(csX + (csWidth >> 2) + (csWidth >> 1), csY, csWidth >> 2, csHeight);
+
+  bool clean0 = isClean(csArea0, CHANNEL_TYPE_LUMA);
+  bool clean1 = isClean(csArea1, CHANNEL_TYPE_LUMA);
+  bool clean2 = isClean(csArea2, CHANNEL_TYPE_LUMA);
+
+  bool allclean = clean0 && clean1 && clean2;
+
+  if (allclean)
+  {
+    return false;
+  }
+
+  return true;
+}
+
+bool CodingStructure::dirtyCrossBTV() const
+{
+  const int  csX = area.lx();
+  const int  csY = area.ly();
+  const int  csWidth = area.lwidth();
+  const int  csHeight = area.lheight();
+
+  const Area csArea0 = Area(csX,                  csY, (csWidth >> 1), csHeight);
+  const Area csArea1 = Area(csX + (csWidth >> 1), csY, (csWidth >> 1), csHeight);
+
+  bool clean0 = isClean(csArea0, CHANNEL_TYPE_LUMA);
+  bool clean1 = isClean(csArea1, CHANNEL_TYPE_LUMA);
+
+  bool allclean = clean0 && clean1;
+
+  if (allclean)
+  {
+    return false;
+  }
+
+  return true;
+}
+#endif
+
+
+
+#if GDR_ENABLED
+bool CodingStructure::isClean(const Position &IntPos, Mv FracMv) const
+{
+  /*
+    1. non gdr picture --> false;
+    2. gdr picture
+         pos in clean area -> true
+         pos in dirty area -> false
+  */
+  const Picture* const curPic = slice->getPic();
+
+  if (!curPic)
+  {
+    return false;
+  }
+
+  PicHeader     *curPh = curPic->cs->picHeader;
+  bool isCurGdrPicture = curPh->getInGdrInterval();
+
+  if (isCurGdrPicture)
+  {
+    const int lumaPixelAway = 4;
+    const int chromaPixelAway = 5;
+
+    const int iMvShift = MV_FRACTIONAL_BITS_INTERNAL;
+    const int iMvLumaFrac = (1 << iMvShift);
+    const int iMvChromaFrac = (iMvLumaFrac << 1);
+
+    const bool isIntLumaMv = (FracMv.getHor() % iMvLumaFrac) == 0;
+    const bool isIntChromaMv = (FracMv.getHor() % iMvChromaFrac) == 0;
+
+    const int scaledEndX = curPh->getVirtualBoundariesPosX(0) << iMvShift;
+
+
+    const Position OrigFracPos = Position(IntPos.x << iMvShift, IntPos.y << iMvShift);
+    const int lastLumaPos = ((OrigFracPos.x / iMvLumaFrac)   * iMvLumaFrac) + FracMv.getHor() + (isIntLumaMv ? 0 : (lumaPixelAway << iMvShift));
+    const int lastChromaPos = ((OrigFracPos.x / iMvChromaFrac) * iMvChromaFrac) + FracMv.getHor() + (isIntChromaMv ? 0 : (chromaPixelAway << iMvShift));
+
+    const int lastPelPos = std::max(lastLumaPos, lastChromaPos);
+
+    if (lastPelPos < scaledEndX)
+    {
+      return true;
+    }
+    else
+    {
+      return false;
+    }
+  }
+
+  return true;
+}
+
+bool CodingStructure::isClean(const Position &IntPos, Mv FracMv, const Picture* const refPic) const
+{
+  /*
+    1. non gdr picture --> false;
+    2. gdr picture
+         pos in clean area -> true
+         pos in dirty area -> false
+  */
+  if (!refPic)
+  {
+    return false;
+  }
+
+  if (!refPic->cs)
+  {
+    return false;
+  }
+
+  PicHeader *refPh = refPic->cs->picHeader;
+  if (!refPh)
+  {
+    return false;
+  }
+
+  bool isRefGdrPicture = refPh->getInGdrInterval();
+
+  if (isRefGdrPicture)
+  {
+    const int lumaPixelAway = 4;
+    const int chromaPixelAway = 5;
+
+    const int iMvShift = MV_FRACTIONAL_BITS_INTERNAL;
+    const int iMvLumaFrac = (1 << iMvShift);
+    const int iMvChromaFrac = (iMvLumaFrac << 1);
+
+    const bool isIntLumaMv = (FracMv.getHor() % iMvLumaFrac) == 0;
+    const bool isIntChromaMv = (FracMv.getHor() % iMvChromaFrac) == 0;
+
+    const int  scaledEndX = refPh->getVirtualBoundariesPosX(0) << iMvShift;
+
+    const Position OrigFracPos = Position((IntPos.x) << iMvShift, IntPos.y << iMvShift);
+    const int lastLumaPos = ((OrigFracPos.x / iMvLumaFrac)   * iMvLumaFrac) + FracMv.getHor() + (isIntLumaMv ? 0 : (lumaPixelAway << iMvShift));
+    const int lastChromaPos = ((OrigFracPos.x / iMvChromaFrac) * iMvChromaFrac) + FracMv.getHor() + (isIntChromaMv ? 0 : (chromaPixelAway << iMvShift));
+
+    const int lastPelPos = std::max(lastLumaPos, lastChromaPos);
+
+    if (lastPelPos < scaledEndX)
+    {
+      return true;
+    }
+    else
+    {
+      return false;
+    }
+  }
+  else
+  {
+    // refPic is normal picture
+    bool isCurGdrPicture = (slice->getPicHeader()->getNumVerVirtualBoundaries() > 0);
+
+    if (isCurGdrPicture)
+    {
+      return false;
+    }
+    else
+    {
+      return true;
+    }
+  }
+}
+
+
+bool CodingStructure::isClean(const Position &IntPos, Mv FracMv, RefPicList e, int refIdx, int isProf) const
+{
+  /*
+    1. non gdr picture --> false;
+    2. gdr picture
+         pos in clean area -> true
+         pos in dirty area -> false
+  */
+  if (refIdx < 0)
+  {
+    return false;
+  }
+
+  const Picture* const refPic = slice->getRefPic(e, refIdx);
+  const bool isExceedNumRef = (refIdx < slice->getNumRefIdx(e)) ? false : true;
+
+  if (!refPic || isExceedNumRef)
+  {
+    return false;
+  }
+
+  if (!refPic->cs)
+  {
+    return false;
+  }
+
+  PicHeader *refPh = refPic->cs->picHeader;
+
+  if (!refPh)
+  {
+    return false;
+  }
+
+  bool isRefGdrPicture = refPh->getInGdrInterval();
+
+  if (isRefGdrPicture)
+  {
+    const int lumaPixelAway   = 4 + (isProf << 0);
+    const int chromaPixelAway = 4 + (isProf << 1);
+
+    const int iMvShift      = MV_FRACTIONAL_BITS_INTERNAL;
+    const int iMvLumaFrac   = (1 << iMvShift);
+    const int iMvChromaFrac = (iMvLumaFrac << 1);
+
+    const bool isIntLumaMv      = (FracMv.getHor() % iMvLumaFrac  ) == 0;
+    const bool isIntChromaMv    = isProf ? false : (FracMv.getHor() % iMvChromaFrac) == 0;
+
+    const int  scaledEndX      = refPh->getVirtualBoundariesPosX(0) << iMvShift;
+
+
+    const Position OrigFracPos  = Position((IntPos.x) << iMvShift, IntPos.y << iMvShift);
+    const int lastLumaPos     = ((OrigFracPos.x / iMvLumaFrac)   * iMvLumaFrac)   + FracMv.getHor() + (isIntLumaMv   ? 0 : (lumaPixelAway   << iMvShift));
+    const int lastChromaPos   = ((OrigFracPos.x / iMvChromaFrac) * iMvChromaFrac) + FracMv.getHor() + (isIntChromaMv ? 0 : (chromaPixelAway << iMvShift)) ;
+
+    const int lastPelPos    = std::max(lastLumaPos, lastChromaPos);
+
+    if (lastPelPos < scaledEndX)
+    {
+      return true;
+    }
+    else
+    {
+      return false;
+    }
+  }
+  else
+  {
+    // refPic is normal picture
+    bool isCurGdrPicture = (slice->getPicHeader()->getNumVerVirtualBoundaries() > 0);
+
+    if (isCurGdrPicture)
+    {
+      return false;
+    }
+    else
+    {
+      return true;
+    }
+  }
+}
+
+bool CodingStructure::isClean(const Position &IntPos, Mv FracMv, RefPicList e, int refIdx, bool ibc) const
+{
+  /*
+    1. non gdr picture --> false;
+    2. gdr picture
+         pos in clean area -> true
+         pos in dirty area -> false
+  */
+  if (refIdx < 0) return false;
+
+  Picture*   refPic;
+  PicHeader *refPh;
+
+  if (refIdx == MAX_NUM_REF)
+  {
+    refPic = slice->getPic();
+  }
+  else
+  {
+    refPic = slice->getRefPic(e, refIdx);
+  }
+
+  if (!refPic)
+  {
+    return false;
+  }
+
+  if (refIdx == MAX_NUM_REF)
+  {
+    refPh = picHeader;
+  }
+  else
+  {
+    if (refPic->cs)
+    {
+      return false;
+    }
+
+    refPh = refPic->cs->picHeader;
+  }
+
+  if (!refPh)
+  {
+    return false;
+  }
+
+  bool isRefGdrPicture = refPh->getInGdrInterval();
+
+  if (isRefGdrPicture)
+  {
+    const int lumaPixelAway = 4;
+    const int chromaPixelAway = 5;
+
+    const int iMvShift = MV_FRACTIONAL_BITS_INTERNAL;
+    const int iMvLumaFrac = (1 << iMvShift);
+    const int iMvChromaFrac = (iMvLumaFrac << 1);
+
+    const bool isIntLumaMv = (FracMv.getHor() % iMvLumaFrac) == 0;
+    const bool isIntChromaMv = (FracMv.getHor() % iMvChromaFrac) == 0;
+
+    const int  scaledEndX = refPh->getVirtualBoundariesPosX(0) << iMvShift;
+
+    const Position OrigFracPos = Position((IntPos.x) << iMvShift, IntPos.y << iMvShift);
+    const int lastLumaPos = ((OrigFracPos.x / iMvLumaFrac)   * iMvLumaFrac) + FracMv.getHor() + (isIntLumaMv ? 0 : (lumaPixelAway << iMvShift));
+    const int lastChromaPos = ((OrigFracPos.x / iMvChromaFrac) * iMvChromaFrac) + FracMv.getHor() + (isIntChromaMv ? 0 : (chromaPixelAway << iMvShift));
+
+    const int lastPelPos = std::max(lastLumaPos, lastChromaPos);
+
+    if (lastPelPos < scaledEndX)
+    {
+      return true;
+    }
+    else
+    {
+      return false;
+    }
+  }
+  else
+  {
+    // refPic is normal picture
+    bool isCurGdrPicture = (slice->getPicHeader()->getNumVerVirtualBoundaries() > 0);
+
+    if (isCurGdrPicture)
+    {
+      return false;
+    }
+    else
+    {
+      return true;
+    }
+  }
+}
+
+
+bool CodingStructure::isClean(const Position &IntPos, RefPicList e, int refIdx) const
+{
+  /*
+    1. non gdr picture --> false;
+    2. gdr picture
+         pos in clean area -> true
+         pos in dirty area -> false
+  */
+  const Picture* const refPic = slice->getRefPic(e, refIdx);
+
+  if (!refPic || refIdx < 0)
+  {
+    return false;
+  }
+
+  PicHeader     *refPh = refPic->cs->picHeader;
+  bool isRefGdrPicture = refPh->getInGdrInterval();
+
+  if (isRefGdrPicture)
+  {
+    if (IntPos.x < refPh->getVirtualBoundariesPosX(0))
+    {
+      return true;
+    }
+    else
+    {
+      return false;
+    }
+  }
+  else
+  {
+    // refPic is normal picture
+    bool isCurGdrPicture = (slice->getPicHeader()->getNumVerVirtualBoundaries() > 0);
+
+    if (isCurGdrPicture)
+    {
+      return false;
+    }
+    else
+    {
+      return true;
+    }
+  }
+}
+
+bool CodingStructure::isClean(const Position &IntPos, const Picture* const refPic) const
+{
+  if (!refPic)
+  {
+    return false;
+  }
+
+  PicHeader     *refPh = refPic->cs->picHeader;
+  bool isRefGdrPicture = refPh->getInGdrInterval();
+
+  if (isRefGdrPicture)
+  {
+    if (IntPos.x < refPh->getVirtualBoundariesPosX(0))
+    {
+      return true;
+    }
+    else
+    {
+      return false;
+    }
+  }
+  else
+  {
+    // refPic is normal picture
+    bool isCurGdrPicture = (slice->getPicHeader()->getNumVerVirtualBoundaries() > 0);
+
+    if (isCurGdrPicture)
+    {
+      return false;
+    }
+    else
+    {
+      return true;
+    }
+  }
+}
+
+bool CodingStructure::isClean(const int Intx, const int Inty, const ChannelType effChType) const
+{
+  /*
+    1. non gdr picture --> false;
+    2. gdr picture
+         pos in clean area -> true
+         pos in dirty area -> false
+  */
+  PicHeader     *curPh = picHeader;
+  bool isCurGdrPicture = curPh->getInGdrInterval();
+  if (isCurGdrPicture)
+  {
+    int virboundary_endx = curPh->getVirtualBoundariesPosX(0);
+
+    virboundary_endx = virboundary_endx >> effChType;
+    if (Intx < virboundary_endx)
+    {
+      return true;
+    }
+    else
+    {
+      return false;
+    }
+  }
+
+  return true;
+}
+
+bool CodingStructure::isClean(const Position &IntPos, const ChannelType effChType) const
+{
+  bool ret = isClean(IntPos.x, IntPos.y, effChType);
+
+  return ret;
+}
+
+bool CodingStructure::isClean(const Area &area, const ChannelType effChType) const
+{
+  Position pTopLeft  = area.topLeft();
+  Position pTopRight = area.topRight();
+  Position pBotLeft  = area.bottomLeft();
+  Position pBotRight = area.bottomRight();
+
+  bool bTopLeft  = isClean(pTopLeft,  effChType);
+  bool bTopRight = isClean(pTopRight, effChType);
+  bool bBotLeft  = isClean(pBotLeft,  effChType);
+  bool bBotRight = isClean(pBotRight, effChType);
+
+  return bTopLeft && bTopRight && bBotLeft && bBotRight;
+}
+
+bool CodingStructure::isClean(const ChannelType effChType) const
+{
+  bool ret = isClean(area.Y(), effChType);
+
+  return ret;
+}
+
+bool CodingStructure::isSubPuClean(PredictionUnit &pu, const Mv *mv) const
+{
+  MotionBuf mb = pu.getMotionBuf();
+
+  if (pu.cu->affine)
+  {
+    Position puPos = pu.Y().pos();
+    Size subPuSize = Size(4, 4);
+
+    int isProf = 1;
+
+    for (int y = 0; y < mb.height; y++)
+    {
+      for (int x = 0; x < mb.width; x++)
+      {
+
+        MotionInfo mi = mb.at(x, y);
+        Position subPuPos  = Position{puPos.x + (x << 2), puPos.y + (y << 2)};
+        Area     subPuArea = Area(subPuPos, subPuSize);
+        Position subPuTR   = subPuArea.topRight();
+
+        // check if SubPu with L0 is Out of boundary
+        if (mi.refIdx[0] >= 0)
+        {
+          if (!isClean(subPuTR, mi.mv[0], REF_PIC_LIST_0, mi.refIdx[0], isProf))
+          {
+            return false;
+          }
+        }
+
+        // check if SubPu wiht L1 is Out of boundary
+        if (mi.refIdx[1] >= 0)
+        {
+          if (!isClean(subPuTR, mi.mv[1], REF_PIC_LIST_1, mi.refIdx[1], isProf))
+          {
+            return false;
+          }
+        }
+      }
+    }
+  }
+
+  return true;
+}
+#endif
+
+
 bool CodingStructure::isDecomp( const Position &pos, const ChannelType effChType )
 {
   if( area.blocks[effChType].contains( pos ) )
@@ -549,10 +1223,6 @@ CodingUnit& CodingStructure::addCU( const UnitArea &unit, const ChannelType chTy
   if( prevCU )
   {
     prevCU->next = cu;
-#if ENABLE_SPLIT_PARALLELISM
-
-    CHECK( prevCU->cacheId != cu->cacheId, "Inconsintent cacheId between previous and current CU" );
-#endif
   }
 
   cus.push_back( cu );
@@ -593,21 +1263,12 @@ PredictionUnit& CodingStructure::addPU( const UnitArea &unit, const ChannelType
   pu->cs     = this;
   pu->cu     = m_isTuEnc ? cus[0] : getCU( unit.blocks[chType].pos(), chType );
   pu->chType = chType;
-#if ENABLE_SPLIT_PARALLELISM
-
-  CHECK( pu->cacheId != pu->cu->cacheId, "Inconsintent cacheId between the PU and assigned CU" );
-  CHECK( pu->cu->firstPU != nullptr, "Without an RQT the firstPU should be null" );
-#endif
 
   PredictionUnit *prevPU = m_numPUs > 0 ? pus.back() : nullptr;
 
   if( prevPU && prevPU->cu == pu->cu )
   {
     prevPU->next = pu;
-#if ENABLE_SPLIT_PARALLELISM
-
-    CHECK( prevPU->cacheId != pu->cacheId, "Inconsintent cacheId between previous and current PU" );
-#endif
   }
 
   pus.push_back( pu );
@@ -654,14 +1315,6 @@ TransformUnit& CodingStructure::addTU( const UnitArea &unit, const ChannelType c
   tu->cs     = this;
   tu->cu     = m_isTuEnc ? cus[0] : getCU( unit.blocks[chType].pos(), chType );
   tu->chType = chType;
-#if ENABLE_SPLIT_PARALLELISM
-
-  if( tu->cu )
-  {
-    CHECK(tu->cacheId != tu->cu->cacheId, "Inconsintent cacheId between the TU and assigned CU");
-  }
-#endif
-
 
   TransformUnit *prevTU = m_numTUs > 0 ? tus.back() : nullptr;
 
@@ -669,10 +1322,6 @@ TransformUnit& CodingStructure::addTU( const UnitArea &unit, const ChannelType c
   {
     prevTU->next = tu;
     tu->prev     = prevTU;
-#if ENABLE_SPLIT_PARALLELISM
-
-    CHECK( prevTU->cacheId != tu->cacheId, "Inconsintent cacheId between previous and current TU" );
-#endif
   }
 
   tus.push_back( tu );
@@ -893,6 +1542,7 @@ void CodingStructure::create(const ChromaFormat &_chromaFormat, const Area& _are
     return;
   }
 
+
   m_reco.create( area );
   m_pred.create( area );
   m_resi.create( area );
@@ -908,6 +1558,7 @@ void CodingStructure::create(const UnitArea& _unit, const bool isTopLayer, const
     return;
   }
 
+
   m_reco.create( area );
   m_pred.create( area );
   m_resi.create( area );
@@ -942,7 +1593,10 @@ void CodingStructure::createInternals(const UnitArea& _unit, const bool isTopLay
     m_offsets[i] = 0;
   }
 
-  if( !isTopLayer ) createCoeffs(isPLTused);
+  if (!isTopLayer)
+  {
+    createCoeffs(isPLTused);
+  }
 
   unsigned _lumaAreaScaled = g_miScaling.scale( area.lumaSize() ).area();
   m_motionBuf       = new MotionInfo[_lumaAreaScaled];
@@ -1050,6 +1704,7 @@ void CodingStructure::setPrevPLT(PLTBuf predictor)
     memcpy(prevPLT.curPLT[comp], predictor.curPLT[comp], MAXPLTPREDSIZE * sizeof(Pel));
   }
 }
+
 void CodingStructure::storePrevPLT(PLTBuf& predictor)
 {
   for (int comp = 0; comp < MAX_NUM_CHANNEL_TYPE; comp++)
@@ -1179,6 +1834,7 @@ void CodingStructure::initSubStructure( CodingStructure& subStruct, const Channe
   subStruct.vps       = vps;
   subStruct.pps       = pps;
   subStruct.picHeader = picHeader;
+
   memcpy(subStruct.alfApss, alfApss, sizeof(alfApss));
 
   subStruct.lmcsAps = lmcsAps;
@@ -1240,15 +1896,36 @@ void CodingStructure::useSubStructure( const CodingStructure& subStruct, const C
   if( parent )
   {
     // copy data to picture
-    if( cpyPred )    getPredBuf   ( clippedArea ).copyFrom( subPredBuf );
-    if( cpyResi )    getResiBuf   ( clippedArea ).copyFrom( subResiBuf );
-    if( cpyReco )    getRecoBuf   ( clippedArea ).copyFrom( subRecoBuf );
-    if( cpyOrgResi ) getOrgResiBuf( clippedArea ).copyFrom( subStruct.getOrgResiBuf( clippedArea ) );
+    if (cpyPred)
+    {
+      getPredBuf(clippedArea).copyFrom(subPredBuf);
+    }
+    if (cpyResi)
+    {
+      getResiBuf(clippedArea).copyFrom(subResiBuf);
+    }
+    if (cpyReco)
+    {
+      getRecoBuf(clippedArea).copyFrom(subRecoBuf);
+    }
+    if (cpyOrgResi)
+    {
+      getOrgResiBuf(clippedArea).copyFrom(subStruct.getOrgResiBuf(clippedArea));
+    }
   }
 
-  if( cpyPred ) picture->getPredBuf( clippedArea ).copyFrom( subPredBuf );
-  if( cpyResi ) picture->getResiBuf( clippedArea ).copyFrom( subResiBuf );
-  if( cpyReco ) picture->getRecoBuf( clippedArea ).copyFrom( subRecoBuf );
+  if (cpyPred)
+  {
+    picture->getPredBuf(clippedArea).copyFrom(subPredBuf);
+  }
+  if (cpyResi)
+  {
+    picture->getResiBuf(clippedArea).copyFrom(subResiBuf);
+  }
+  if (cpyReco)
+  {
+    picture->getRecoBuf(clippedArea).copyFrom(subRecoBuf);
+  }
 
   if (!subStruct.m_isTuEnc && ((!slice->isIntra() || slice->getSPS()->getIBCFlag()) && chType != CHANNEL_TYPE_CHROMA))
   {
@@ -1586,6 +2263,8 @@ const CPelUnitBuf CodingStructure::getOrgBuf(const UnitArea &unit)     const { r
 const CPelBuf     CodingStructure::getOrgBuf(const ComponentID &compID)const { return picture->getBuf(area.blocks[compID], PIC_ORIGINAL); }
        PelUnitBuf CodingStructure::getOrgBuf()                               { return picture->getBuf(area, PIC_ORIGINAL); }
 const CPelUnitBuf CodingStructure::getOrgBuf()                         const { return picture->getBuf(area, PIC_ORIGINAL); }
+       PelUnitBuf CodingStructure::getTrueOrgBuf()                           { return picture->getBuf(area, PIC_TRUE_ORIGINAL); }
+const CPelUnitBuf CodingStructure::getTrueOrgBuf()                     const { return picture->getBuf(area, PIC_TRUE_ORIGINAL); }
 
 PelBuf CodingStructure::getBuf( const CompArea &blk, const PictureType &type )
 {
diff --git a/source/Lib/CommonLib/CodingStructure.h b/source/Lib/CommonLib/CodingStructure.h
index b5ae7ac63..9fcfe29b2 100644
--- a/source/Lib/CommonLib/CodingStructure.h
+++ b/source/Lib/CommonLib/CodingStructure.h
@@ -3,7 +3,7 @@
 * and contributor rights, including patent rights, and no such rights are
 * granted under this license.
 *
-* Copyright (c) 2010-2020, ITU/ISO/IEC
+* Copyright (c) 2010-2021, ITU/ISO/IEC
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
@@ -104,6 +104,34 @@ public:
   void destroy();
   void releaseIntermediateData();
 
+#if GDR_ENABLED
+  bool containRefresh(int begX, int endX) const;
+  bool overlapRefresh() const;
+  bool overlapRefresh(int begX, int endX) const;
+  bool withinRefresh(int begX, int endX) const;
+
+  bool refreshCrossTTV(int begX, int endX) const;
+  bool refreshCrossBTV(int begX, int endX) const;
+
+  bool overlapDirty() const;
+  bool dirtyCrossTTV() const;  
+  bool dirtyCrossBTV() const;
+#endif
+
+#if GDR_ENABLED
+  bool isClean(const ChannelType effChType) const;
+  bool isClean(const Position &IntPos, RefPicList e, int refIdx) const;
+  bool isClean(const Position &IntPos, const Picture* const ref_pic) const;
+  bool isClean(const Position &IntPos, Mv FracMv) const;  
+  bool isClean(const Position &IntPos, Mv FracMv, const Picture* const refPic) const;
+  bool isClean(const Position &IntPos, Mv FracMv, RefPicList e, int refIdx, int isProf=0) const;
+  bool isClean(const Position &IntPos, Mv FracMv, RefPicList e, int refIdx, bool ibc) const;
+  bool isClean(const Position &IntPos, const ChannelType effChType) const;  
+  bool isClean(const int x, const int y, const ChannelType effChType) const;  
+  bool isClean(const Area &area, const ChannelType effChType) const;
+  
+  bool isSubPuClean(PredictionUnit &pu, const Mv *mv) const;
+#endif
   void rebindPicBufs();
 
   void createCoeffs(const bool isPLTused);
@@ -293,7 +321,8 @@ public:
   const CPelBuf       getOrgBuf(const ComponentID &compID) const;
          PelUnitBuf   getOrgBuf();
   const CPelUnitBuf   getOrgBuf() const;
-
+         PelUnitBuf   getTrueOrgBuf();
+  const CPelUnitBuf   getTrueOrgBuf() const;
 
   // pred buffer
          PelBuf       getPredBuf(const ComponentID &compID)       { return m_pred.get(compID); }
diff --git a/source/Lib/CommonLib/Common.h b/source/Lib/CommonLib/Common.h
index 9d30b8393..6313b984a 100644
--- a/source/Lib/CommonLib/Common.h
+++ b/source/Lib/CommonLib/Common.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -97,6 +97,33 @@ struct Area : public Position, public Size
   bool contains(const Position &_pos)       const { return (_pos.x >= x) && (_pos.x < (x + width)) && (_pos.y >= y) && (_pos.y < (y + height)); }
   bool contains(const Area &_area)          const { return contains(_area.pos()) && contains(_area.bottomRight()); }
 
+#if GDR_ENABLED  
+  bool overlap(const Area &_area) const 
+  { 
+    Area thisArea = Area(pos(), size());
+
+    if (contains(_area))
+      return false;
+
+    if (_area.contains(thisArea))
+      return false;
+
+    bool topLeft  = contains(_area.topLeft());
+    bool topRight = contains(_area.topRight());
+    bool botLeft  = contains(_area.bottomLeft());
+    bool botRight = contains(_area.bottomRight());
+
+    int sum = (topLeft ? 1 : 0) + (topRight ? 1 : 0) + (botLeft ? 1 : 0) + (botRight ? 1 : 0);
+
+    if (0 < sum && sum < 4)
+    {
+      return true;
+    }
+
+    return false;
+  }
+#endif
+
   bool operator!=(const Area &other)        const { return (Size::operator!=(other)) || (Position::operator!=(other)); }
   bool operator==(const Area &other)        const { return (Size::operator==(other)) && (Position::operator==(other)); }
 };
diff --git a/source/Lib/CommonLib/CommonDef.h b/source/Lib/CommonLib/CommonDef.h
index edcdceede..ffbca4861 100644
--- a/source/Lib/CommonLib/CommonDef.h
+++ b/source/Lib/CommonLib/CommonDef.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -163,19 +163,12 @@ static const int MAX_TB_LOG2_SIZEY = 6;
 static const int MIN_TB_SIZEY = 1 << MIN_TB_LOG2_SIZEY;
 static const int MAX_TB_SIZEY = 1 << MAX_TB_LOG2_SIZEY;
 
-static const int MAX_NUM_PICS_IN_SOP =                           1024;
-
-static const int MAX_NESTING_NUM_OPS =                           1024;
 static const int MAX_NESTING_NUM_LAYER =                           64;
 
-static const int MAX_VPS_NUM_HRD_PARAMETERS =                       1;
 static const int MAX_VPS_LAYERS =                                  64;
 static const int MAX_VPS_SUBLAYERS =                                7;
-static const int MAX_NUM_REF_LAYERS =                               7;
 static const int MAX_NUM_OLSS =                                   256;
 static const int MAX_VPS_OLS_MODE_IDC =                             2;
-static const int MAXIMUM_INTRA_FILTERED_WIDTH =                    16;
-static const int MAXIMUM_INTRA_FILTERED_HEIGHT =                   16;
 
 static const int MIP_MAX_WIDTH =                                   MAX_TB_SIZEY;
 static const int MIP_MAX_HEIGHT =                                  MAX_TB_SIZEY;
@@ -185,7 +178,6 @@ static const int MAX_NUM_ALF_CLASSES         =                     25;
 static const int MAX_NUM_ALF_LUMA_COEFF      =                     13;
 static const int MAX_NUM_ALF_CHROMA_COEFF    =                      7;
 static const int MAX_ALF_FILTER_LENGTH       =                      7;
-static const int MAX_NUM_ALF_COEFF           =                     MAX_ALF_FILTER_LENGTH * MAX_ALF_FILTER_LENGTH / 2 + 1;
 static const int MAX_ALF_PADDING_SIZE        =                      4;
 #define MAX_NUM_CC_ALF_FILTERS                                      4
 static constexpr int MAX_NUM_CC_ALF_CHROMA_COEFF    =               8;
@@ -195,8 +187,6 @@ static constexpr int CCALF_BITS_PER_COEFF_LEVEL     =               3;
 static const int ALF_FIXED_FILTER_NUM        =                     64;
 static const int ALF_CTB_MAX_NUM_APS         =                      8;
 static const int NUM_FIXED_FILTER_SETS       =                     16;
-static const int NUM_TOTAL_FILTER_SETS       =                     NUM_FIXED_FILTER_SETS + ALF_CTB_MAX_NUM_APS;
-
 
 static const int MAX_BDOF_APPLICATION_REGION =                     16;
 
@@ -209,23 +199,16 @@ static const int CU_DQP_EG_k =                                      0; ///< expg
 static const int SBH_THRESHOLD =                                    4; ///< value of the fixed SBH controlling threshold
 
 static const int MAX_NUM_VPS =                                     16;
-static const int MAX_NUM_DPS =                                     16;
 static const int MAX_NUM_SPS =                                     16;
 static const int MAX_NUM_PPS =                                     64;
 static const int MAX_NUM_APS =                                     32;  //Currently APS ID has 5 bits
 static const int NUM_APS_TYPE_LEN =                                 3;  //Currently APS Type has 3 bits
 static const int MAX_NUM_APS_TYPE =                                 8;  //Currently APS Type has 3 bits so the max type is 8
 
-#if JVET_T0065_LEVEL_6_3
 static constexpr int MAX_TILE_COLS = 30;   // Maximum number of tile columns
 static constexpr int MAX_TILES     = 990;  // Maximum number of tiles
 static constexpr int MAX_SLICES    = 1000; // Maximum number of slices per picture
 
-#else
-static const int MAX_TILE_COLS =                                   20;  ///< Maximum number of tile columns
-static const int MAX_TILES =                                      440;  ///< Maximum number of tiles
-static const int MAX_SLICES =                                     600;  ///< Maximum number of slices per picture
-#endif
 static const int MLS_GRP_NUM =                                   1024; ///< Max number of coefficient groups, max(16, 256)
 
 static const int MLS_CG_SIZE =                                      4; ///< Coefficient group size of 4x4; = MLS_CG_LOG2_WIDTH + MLS_CG_LOG2_HEIGHT
@@ -277,9 +260,6 @@ static const int LFNST_LAST_SIG_CHROMA =                            1;
 
 static const int NUM_LFNST_NUM_PER_SET =                            3;
 
-static const int LOG2_MAX_NUM_COLUMNS_MINUS1 =                      7;
-static const int LOG2_MAX_NUM_ROWS_MINUS1 =                         7;
-
 static const int CABAC_INIT_PRESENT_FLAG =                          1;
 
 static const int MV_FRACTIONAL_BITS_INTERNAL                      = 4;
@@ -302,8 +282,7 @@ static const int MAX_NUM_QP_VALUES =    MAX_QP + 1 - MIN_QP_VALUE_FOR_16_BIT; //
 // Cost mode support
 static const int LOSSLESS_AND_MIXED_LOSSLESS_RD_COST_TEST_QP =      0; ///< QP to use for lossless coding.
 static const int LOSSLESS_AND_MIXED_LOSSLESS_RD_COST_TEST_QP_PRIME =4; ///< QP' to use for mixed_lossy_lossless coding.
-
-static const int RExt__GOLOMB_RICE_ADAPTATION_STATISTICS_SETS =     4;
+static const int RExt__GOLOMB_RICE_ADAPTATION_STATISTICS_SETS = MAX_NUM_COMPONENT;
 
 static const int RExt__PREDICTION_WEIGHTING_ANALYSIS_DC_PRECISION = 0; ///< Additional fixed bit precision used during encoder-side weighting prediction analysis. Currently only used when high_precision_prediction_weighting_flag is set, for backwards compatibility reasons.
 
@@ -471,8 +450,6 @@ static const int PIC_CODE_CW_BINS =                              16;
 static const int LMCS_SEG_NUM =                                  32;
 static const int FP_PREC =                                       11;
 static const int CSCALE_FP_PREC =                                11;
-static const int  NEIG_NUM_LOG  =                                 6;
-static const int  NEIG_NUM =                      1 << NEIG_NUM_LOG;
 static const int LOG2_PALETTE_CG_SIZE =                           4;
 static const int RUN_IDX_THRE =                                   4;
 static const int MAX_CU_BLKSIZE_PLT =                            64;
@@ -493,17 +470,19 @@ static const int SCALE_RATIO_BITS =                              14;
 static const int MAX_SCALING_RATIO =                              2;  // max downsampling ratio for RPR
 static const std::pair<int, int> SCALE_1X = std::pair<int, int>( 1 << SCALE_RATIO_BITS, 1 << SCALE_RATIO_BITS );  // scale ratio 1x
 static const int DELTA_QP_ACT[4] =                  { -5, 1, 3, 1 };
-
+static const int MAX_TSRC_RICE =                                  8;  ///<Maximum supported TSRC Rice parameter
+static const int MIN_TSRC_RICE =                                  1;  ///<Minimum supported TSRC Rice parameter
+static const int MAX_CTI_LUT_SIZE =                              64;  ///<Maximum colour transform LUT size for CTI SEI
 // ====================================================================================================================
 // Macro functions
 // ====================================================================================================================
 
 struct ClpRng
 {
-  int min;
-  int max;
-  int bd;
-  int n;
+  int min {0};
+  int max {0};
+  int bd  {0};
+  int n   {0};
 };
 
 struct ClpRngs
@@ -702,16 +681,6 @@ static inline int ceilLog2(uint32_t x)
 #define _UNIT_AREA_AT(_a,_x,_y,_w,_h)
 #endif
 
-#if ENABLE_SPLIT_PARALLELISM
-#include <omp.h>
-
-#define PARL_PARAM(DEF) , DEF
-#define PARL_PARAM0(DEF) DEF
-#else
-#define PARL_PARAM(DEF)
-#define PARL_PARAM0(DEF)
-#endif
-
 static const uint32_t CCALF_CANDS_COEFF_NR = 8;
 static const int CCALF_SMALL_TAB[CCALF_CANDS_COEFF_NR] = { 0, 1, 2, 4, 8, 16, 32, 64 };
 
diff --git a/source/Lib/CommonLib/ContextModelling.cpp b/source/Lib/CommonLib/ContextModelling.cpp
index 3e1a44b0e..c7d90841c 100644
--- a/source/Lib/CommonLib/ContextModelling.cpp
+++ b/source/Lib/CommonLib/ContextModelling.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -40,58 +40,64 @@
 #include "CodingStructure.h"
 #include "Picture.h"
 
-
-CoeffCodingContext::CoeffCodingContext( const TransformUnit& tu, ComponentID component, bool signHide, bool bdpcm )
-  : m_compID                    (component)
-  , m_chType                    (toChannelType(m_compID))
-  , m_width                     (tu.block(m_compID).width)
-  , m_height                    (tu.block(m_compID).height)
-  , m_log2CGWidth               ( g_log2SbbSize[ floorLog2(m_width) ][ floorLog2(m_height) ][0] )
-  , m_log2CGHeight              ( g_log2SbbSize[ floorLog2(m_width) ][ floorLog2(m_height) ][1] )
-  , m_log2CGSize                (m_log2CGWidth + m_log2CGHeight)
+CoeffCodingContext::CoeffCodingContext(const TransformUnit &tu, ComponentID component, bool signHide, bool bdpcm)
+  : m_compID(component)
+  , m_chType(toChannelType(m_compID))
+  , m_width(tu.block(m_compID).width)
+  , m_height(tu.block(m_compID).height)
+  , m_log2CGWidth(g_log2SbbSize[floorLog2(m_width)][floorLog2(m_height)][0])
+  , m_log2CGHeight(g_log2SbbSize[floorLog2(m_width)][floorLog2(m_height)][1])
+  , m_log2CGSize(m_log2CGWidth + m_log2CGHeight)
   , m_widthInGroups(std::min<unsigned>(JVET_C0024_ZERO_OUT_TH, m_width) >> m_log2CGWidth)
   , m_heightInGroups(std::min<unsigned>(JVET_C0024_ZERO_OUT_TH, m_height) >> m_log2CGHeight)
-  , m_log2BlockWidth            ((unsigned)floorLog2(m_width))
-  , m_log2BlockHeight           ((unsigned)floorLog2(m_height))
-  , m_maxNumCoeff               (m_width * m_height)
-  , m_signHiding                (signHide)
-  , m_extendedPrecision         (tu.cs->sps->getSpsRangeExtension().getExtendedPrecisionProcessingFlag())
-  , m_maxLog2TrDynamicRange     (tu.cs->sps->getMaxLog2TrDynamicRange(m_chType))
-  , m_scanType                  (SCAN_DIAG)
-  , m_scan                      (g_scanOrder     [SCAN_GROUPED_4x4][m_scanType][gp_sizeIdxInfo->idxFrom(m_width        )][gp_sizeIdxInfo->idxFrom(m_height        )])
-  , m_scanCG                    (g_scanOrder     [SCAN_UNGROUPED  ][m_scanType][gp_sizeIdxInfo->idxFrom(m_widthInGroups)][gp_sizeIdxInfo->idxFrom(m_heightInGroups)])
-  , m_CtxSetLastX               (Ctx::LastX[m_chType])
-  , m_CtxSetLastY               (Ctx::LastY[m_chType])
-  , m_maxLastPosX(g_uiGroupIdx[std::min<unsigned>(JVET_C0024_ZERO_OUT_TH, m_width) - 1])
-  , m_maxLastPosY(g_uiGroupIdx[std::min<unsigned>(JVET_C0024_ZERO_OUT_TH, m_height) - 1])
-  , m_lastOffsetX               (0)
-  , m_lastOffsetY               (0)
-  , m_lastShiftX                (0)
-  , m_lastShiftY                (0)
-  , m_TrafoBypass               (tu.cs->sps->getSpsRangeExtension().getTransformSkipContextEnabledFlag() && (tu.mtsIdx[m_compID] == MTS_SKIP))
-  , m_minCoeff                  (-(1 << tu.cs->sps->getMaxLog2TrDynamicRange(m_chType)))
-  , m_maxCoeff                  ((1 << tu.cs->sps->getMaxLog2TrDynamicRange(m_chType)) - 1)
-  , m_scanPosLast               (-1)
-  , m_subSetId                  (-1)
-  , m_subSetPos                 (-1)
-  , m_subSetPosX                (-1)
-  , m_subSetPosY                (-1)
-  , m_minSubPos                 (-1)
-  , m_maxSubPos                 (-1)
-  , m_sigGroupCtxId             (-1)
-  , m_tmplCpSum1                (-1)
-  , m_tmplCpDiag                (-1)
-  , m_sigFlagCtxSet             { Ctx::SigFlag[m_chType], Ctx::SigFlag[m_chType+2], Ctx::SigFlag[m_chType+4] }
-  , m_parFlagCtxSet             ( Ctx::ParFlag[m_chType] )
-  , m_gtxFlagCtxSet             { Ctx::GtxFlag[m_chType], Ctx::GtxFlag[m_chType+2] }
-  , m_sigGroupCtxIdTS           (-1)
-  , m_tsSigFlagCtxSet           ( Ctx::TsSigFlag )
-  , m_tsParFlagCtxSet           ( Ctx::TsParFlag )
-  , m_tsGtxFlagCtxSet           ( Ctx::TsGtxFlag )
-  , m_tsLrg1FlagCtxSet          (Ctx::TsLrg1Flag)
-  , m_tsSignFlagCtxSet          (Ctx::TsResidualSign)
-  , m_sigCoeffGroupFlag         ()
-  , m_bdpcm                     (bdpcm)
+  , m_log2BlockWidth((unsigned) floorLog2(m_width))
+  , m_log2BlockHeight((unsigned) floorLog2(m_height))
+  , m_maxNumCoeff(m_width * m_height)
+  , m_signHiding(signHide)
+#if JVET_W0178_CONSTRAINTS_ON_REXT_TOOLS
+  , m_extendedPrecision(tu.cs->sps->getSpsRangeExtension().getExtendedPrecisionProcessingFlag())
+#else
+  , m_extendedPrecision(tu.cs->sps->getSpsRangeExtension().getExtendedPrecisionProcessingFlag() && tu.cs->sps->getBitDepth( m_chType ) > 10)
+#endif
+  , m_maxLog2TrDynamicRange(tu.cs->sps->getMaxLog2TrDynamicRange(m_chType))
+  , m_scanType(SCAN_DIAG)
+  , m_scan(
+      g_scanOrder[SCAN_GROUPED_4x4][m_scanType][gp_sizeIdxInfo->idxFrom(m_width)][gp_sizeIdxInfo->idxFrom(m_height)])
+  , m_scanCG(g_scanOrder[SCAN_UNGROUPED][m_scanType][gp_sizeIdxInfo->idxFrom(m_widthInGroups)]
+                        [gp_sizeIdxInfo->idxFrom(m_heightInGroups)])
+  , m_CtxSetLastX(Ctx::LastX[m_chType])
+  , m_CtxSetLastY(Ctx::LastY[m_chType])
+  , m_maxLastPosX(g_groupIdx[std::min<unsigned>(JVET_C0024_ZERO_OUT_TH, m_width) - 1])
+  , m_maxLastPosY(g_groupIdx[std::min<unsigned>(JVET_C0024_ZERO_OUT_TH, m_height) - 1])
+  , m_lastOffsetX(0)
+  , m_lastOffsetY(0)
+  , m_lastShiftX(0)
+  , m_lastShiftY(0)
+  , m_TrafoBypass(tu.cs->sps->getSpsRangeExtension().getTransformSkipContextEnabledFlag()
+                  && (tu.mtsIdx[m_compID] == MTS_SKIP))
+  , m_minCoeff(-(1 << tu.cs->sps->getMaxLog2TrDynamicRange(m_chType)))
+  , m_maxCoeff((1 << tu.cs->sps->getMaxLog2TrDynamicRange(m_chType)) - 1)
+  , m_scanPosLast(-1)
+  , m_subSetId(-1)
+  , m_subSetPos(-1)
+  , m_subSetPosX(-1)
+  , m_subSetPosY(-1)
+  , m_minSubPos(-1)
+  , m_maxSubPos(-1)
+  , m_sigGroupCtxId(-1)
+  , m_tmplCpSum1(-1)
+  , m_tmplCpDiag(-1)
+  , m_sigFlagCtxSet{ Ctx::SigFlag[m_chType], Ctx::SigFlag[m_chType + 2], Ctx::SigFlag[m_chType + 4] }
+  , m_parFlagCtxSet(Ctx::ParFlag[m_chType])
+  , m_gtxFlagCtxSet{ Ctx::GtxFlag[m_chType], Ctx::GtxFlag[m_chType + 2] }
+  , m_sigGroupCtxIdTS(-1)
+  , m_tsSigFlagCtxSet(Ctx::TsSigFlag)
+  , m_tsParFlagCtxSet(Ctx::TsParFlag)
+  , m_tsGtxFlagCtxSet(Ctx::TsGtxFlag)
+  , m_tsLrg1FlagCtxSet(Ctx::TsLrg1Flag)
+  , m_tsSignFlagCtxSet(Ctx::TsResidualSign)
+  , m_sigCoeffGroupFlag()
+  , m_bdpcm(bdpcm)
 {
   // LOGTODO
   unsigned log2sizeX = m_log2BlockWidth;
@@ -109,6 +115,19 @@ CoeffCodingContext::CoeffCodingContext( const TransformUnit& tu, ComponentID com
     const_cast<int&>(m_lastShiftX)  = (log2sizeX + 1) >> 2;
     const_cast<int&>(m_lastShiftY)  = (log2sizeY + 1) >> 2;
   }
+
+  m_cctxBaseLevel = 4; // default value for RRC rice derivation in VVCv1, is updated for extended RRC rice derivation
+  m_histValue = 0;  // default value for RRC rice derivation in VVCv1, is updated for history-based extention of RRC rice derivation
+  m_updateHist = 0;  // default value for RRC rice derivation (history update is disabled), is updated for history-based extention of RRC rice derivation
+
+  if (tu.cs->sps->getSpsRangeExtension().getRrcRiceExtensionEnableFlag())
+  {
+    deriveRiceRRC = &CoeffCodingContext::deriveRiceExt;
+  }
+  else
+  {
+    deriveRiceRRC = &CoeffCodingContext::deriveRice;
+  }
 }
 
 void CoeffCodingContext::initSubblock( int SubsetId, bool sigGroupFlag )
@@ -305,6 +324,7 @@ unsigned DeriveCtx::CtxAffineFlag( const CodingUnit& cu )
 
   return ctxId;
 }
+
 unsigned DeriveCtx::CtxSkipFlag( const CodingUnit& cu )
 {
   const CodingStructure *cs = cu.cs;
@@ -321,8 +341,6 @@ unsigned DeriveCtx::CtxSkipFlag( const CodingUnit& cu )
   return ctxId;
 }
 
-
-
 unsigned DeriveCtx::CtxPredModeFlag( const CodingUnit& cu )
 {
   const CodingUnit *cuLeft  = cu.cs->getCURestricted(cu.lumaPos().offset(-1, 0), cu, CH_L);
@@ -366,6 +384,25 @@ void MergeCtx::setMergeInfo( PredictionUnit& pu, int candIdx )
   pu.mvpIdx [REF_PIC_LIST_1] = NOT_VALID;
   pu.mvpNum [REF_PIC_LIST_0] = NOT_VALID;
   pu.mvpNum [REF_PIC_LIST_1] = NOT_VALID;
+#if GDR_ENABLED
+  CodingStructure &cs = *pu.cs;
+  const bool isEncodeGdrClean = cs.sps->getGDREnabledFlag() && cs.pcv->isEncoder && ((cs.picHeader->getInGdrInterval() && cs.isClean(pu.Y().topRight(), CHANNEL_TYPE_LUMA)) || (cs.picHeader->getNumVerVirtualBoundaries() == 0));
+
+  if (isEncodeGdrClean)
+  {
+    Mv mv0 = pu.mv[REF_PIC_LIST_0];
+    Mv mv1 = pu.mv[REF_PIC_LIST_1];
+
+    int refIdx0 = pu.refIdx[REF_PIC_LIST_0];
+    int refIdx1 = pu.refIdx[REF_PIC_LIST_1];
+
+    pu.mvSolid[REF_PIC_LIST_0] = mvSolid[(candIdx << 1) + 0];
+    pu.mvSolid[REF_PIC_LIST_1] = mvSolid[(candIdx << 1) + 1];
+    pu.mvValid[REF_PIC_LIST_0] = cs.isClean(pu.Y().topRight(), mv0, REF_PIC_LIST_0, refIdx0);
+    pu.mvValid[REF_PIC_LIST_1] = cs.isClean(pu.Y().topRight(), mv1, REF_PIC_LIST_1, refIdx1);
+  }
+#endif
+
   if (CU::isIBC(*pu.cu))
   {
     pu.bv = pu.mv[REF_PIC_LIST_0];
@@ -377,6 +414,7 @@ void MergeCtx::setMergeInfo( PredictionUnit& pu, int candIdx )
   PU::restrictBiPredMergeCandsOne(pu);
   pu.mmvdEncOptMode = 0;
 }
+
 void MergeCtx::setMmvdMergeCandiInfo(PredictionUnit& pu, int candIdx)
 {
   const Slice &slice = *pu.cs->slice;
@@ -389,6 +427,11 @@ void MergeCtx::setMmvdMergeCandiInfo(PredictionUnit& pu, int candIdx)
   int fPosPosition = 0;
   Mv tempMv[2];
 
+#if GDR_ENABLED
+  const CodingStructure &cs = *pu.cs;
+  const bool isEncodeGdrClean = cs.sps->getGDREnabledFlag() && cs.pcv->isEncoder && ((cs.picHeader->getInGdrInterval() && cs.isClean(pu.Y().topRight(), CHANNEL_TYPE_LUMA)) || (cs.picHeader->getNumVerVirtualBoundaries() == 0));
+#endif
+
   tempIdx = candIdx;
   fPosGroup = tempIdx / (MMVD_BASE_MV_NUM * MMVD_MAX_REFINE_NUM);
   tempIdx = tempIdx - fPosGroup * (MMVD_BASE_MV_NUM * MMVD_MAX_REFINE_NUM);
@@ -447,7 +490,9 @@ void MergeCtx::setMmvdMergeCandiInfo(PredictionUnit& pu, int candIdx)
         }
       }
       else
-      tempMv[0] = tempMv[1].scaleMv(scale);
+      {
+        tempMv[0] = tempMv[1].scaleMv(scale);
+      }
     }
     else
     {
@@ -466,7 +511,9 @@ void MergeCtx::setMmvdMergeCandiInfo(PredictionUnit& pu, int candIdx)
         }
       }
       else
-      tempMv[1] = tempMv[0].scaleMv(scale);
+      {
+        tempMv[1] = tempMv[0].scaleMv(scale);
+      }
     }
 
     pu.interDir = 3;
@@ -474,6 +521,25 @@ void MergeCtx::setMmvdMergeCandiInfo(PredictionUnit& pu, int candIdx)
     pu.refIdx[REF_PIC_LIST_0] = refList0;
     pu.mv[REF_PIC_LIST_1] = mmvdBaseMv[fPosBaseIdx][1].mv + tempMv[1];
     pu.refIdx[REF_PIC_LIST_1] = refList1;
+#if GDR_ENABLED
+    if (isEncodeGdrClean)
+    {
+      Mv mv0 = pu.mv[REF_PIC_LIST_0];
+      Mv mv1 = pu.mv[REF_PIC_LIST_1];
+
+      int refIdx0 = pu.refIdx[REF_PIC_LIST_0];
+      int refIdx1 = pu.refIdx[REF_PIC_LIST_1];
+
+      mmvdValid[fPosBaseIdx][0] = cs.isClean(pu.Y().topRight(), mv0, REF_PIC_LIST_0, refIdx0);
+      mmvdValid[fPosBaseIdx][1] = cs.isClean(pu.Y().topRight(), mv1, REF_PIC_LIST_1, refIdx1);
+
+      pu.mvSolid[REF_PIC_LIST_0] = mmvdSolid[fPosBaseIdx][0];
+      pu.mvSolid[REF_PIC_LIST_1] = mmvdSolid[fPosBaseIdx][1];
+
+      pu.mvValid[REF_PIC_LIST_0] = mmvdValid[fPosBaseIdx][0];
+      pu.mvValid[REF_PIC_LIST_1] = mmvdValid[fPosBaseIdx][1];
+    }
+#endif
   }
   else if (refList0 != -1)
   {
@@ -498,6 +564,26 @@ void MergeCtx::setMmvdMergeCandiInfo(PredictionUnit& pu, int candIdx)
     pu.refIdx[REF_PIC_LIST_0] = refList0;
     pu.mv[REF_PIC_LIST_1] = Mv(0, 0);
     pu.refIdx[REF_PIC_LIST_1] = -1;
+
+#if GDR_ENABLED
+    if (isEncodeGdrClean)
+    {
+      Mv mv0 = pu.mv[REF_PIC_LIST_0];
+      //Mv mv1 = pu.mv[REF_PIC_LIST_1];
+
+      int refIdx0 = pu.refIdx[REF_PIC_LIST_0];
+      //int refIdx1 = pu.refIdx[REF_PIC_LIST_1];
+
+      pu.mvSolid[REF_PIC_LIST_0] = mmvdSolid[fPosBaseIdx][0];
+      pu.mvSolid[REF_PIC_LIST_1] = true;
+
+      mmvdValid[fPosBaseIdx][0] = cs.isClean(pu.Y().topRight(), mv0, REF_PIC_LIST_0, refIdx0);
+      mmvdValid[fPosBaseIdx][1] = true;
+
+      pu.mvValid[REF_PIC_LIST_0] = mmvdValid[fPosBaseIdx][0];
+      pu.mvValid[REF_PIC_LIST_1] = true;
+    }
+#endif
   }
   else if (refList1 != -1)
   {
@@ -522,6 +608,25 @@ void MergeCtx::setMmvdMergeCandiInfo(PredictionUnit& pu, int candIdx)
     pu.refIdx[REF_PIC_LIST_0] = -1;
     pu.mv[REF_PIC_LIST_1] = mmvdBaseMv[fPosBaseIdx][1].mv + tempMv[1];
     pu.refIdx[REF_PIC_LIST_1] = refList1;
+#if GDR_ENABLED
+    if (isEncodeGdrClean)
+    {
+      // Mv mv0 = pu.mv[REF_PIC_LIST_0];
+      Mv mv1 = pu.mv[REF_PIC_LIST_1];
+
+      // int refIdx0 = pu.refIdx[REF_PIC_LIST_0];
+      int refIdx1 = pu.refIdx[REF_PIC_LIST_1];
+
+      mmvdValid[fPosBaseIdx][0] = true;
+      mmvdValid[fPosBaseIdx][1] = cs.isClean(pu.Y().topRight(), mv1, REF_PIC_LIST_1, refIdx1);
+
+      pu.mvSolid[REF_PIC_LIST_0] = true;
+      pu.mvSolid[REF_PIC_LIST_1] = mmvdSolid[fPosBaseIdx][1];
+
+      pu.mvValid[REF_PIC_LIST_0] = true;
+      pu.mvValid[REF_PIC_LIST_1] = mmvdValid[fPosBaseIdx][1];
+    }
+#endif
   }
 
   pu.mmvdMergeFlag = true;
@@ -548,7 +653,6 @@ void MergeCtx::setMmvdMergeCandiInfo(PredictionUnit& pu, int candIdx)
     }
   }
 
-
   PU::restrictBiPredMergeCandsOne(pu);
 }
 
@@ -573,7 +677,7 @@ unsigned DeriveCtx::CtxPltCopyFlag( const unsigned prevRunType, const unsigned d
   uint8_t *ucCtxLut = (prevRunType == PLT_RUN_INDEX) ? g_paletteRunLeftLut : g_paletteRunTopLut;
   if ( dist <= RUN_IDX_THRE )
   {
-     return ucCtxLut[dist];
+    return ucCtxLut[dist];
   }
   else
   {
diff --git a/source/Lib/CommonLib/ContextModelling.h b/source/Lib/CommonLib/ContextModelling.h
index e3006c3e5..494efd08c 100644
--- a/source/Lib/CommonLib/ContextModelling.h
+++ b/source/Lib/CommonLib/ContextModelling.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -38,7 +38,7 @@
 #ifndef __CONTEXTMODELLING__
 #define __CONTEXTMODELLING__
 
-
+#include "Rom.h"
 #include "CommonDef.h"
 #include "Contexts.h"
 #include "Slice.h"
@@ -192,6 +192,125 @@ public:
     return unsigned(std::max<TCoeff>(std::min<TCoeff>(sum - 5 * baseLevel, 31), 0));
   }
 
+  void updateRiceStat(unsigned &riceStat, TCoeff rem, int remainderFlag)
+  {
+    if (remainderFlag)
+    {
+      riceStat = (riceStat + floorLog2((uint32_t)rem) + 2) >> 1;
+    }
+    else 
+    {
+      riceStat = (riceStat + floorLog2((uint32_t)rem)) >> 1;
+    }
+  }
+  
+  unsigned templateAbsCompare(TCoeff sum)
+  {
+    int rangeIdx = 0;
+    if (sum < g_riceT[0])
+    {
+      rangeIdx = 0;
+    }
+    else if (sum < g_riceT[1])
+    {
+      rangeIdx = 1;
+    }
+    else if (sum < g_riceT[2])
+    {
+      rangeIdx = 2;
+    }
+    else if (sum < g_riceT[3])
+    {
+      rangeIdx = 3;
+    }
+    else
+    {
+      rangeIdx = 4;
+    }
+
+    return g_riceShift[rangeIdx];
+  }
+
+  unsigned templateAbsSumExt(int scanPos, const TCoeff* coeff, int baseLevel)
+  {
+    unsigned riceParam;
+    const uint32_t  posY = m_scan[scanPos].y;
+    const uint32_t  posX = m_scan[scanPos].x;
+    const TCoeff*   data = coeff + posX + posY * m_width;
+    TCoeff          sum = 0;
+    if (posX < m_width - 1)
+    {
+      sum += abs(data[1]);
+      if (posX < m_width - 2)
+      {
+        sum += abs(data[2]);
+      }
+      else
+      {
+        sum += m_histValue;
+      }
+
+      if (posY < m_height - 1)
+      {
+        sum += abs(data[m_width + 1]);
+      }
+      else
+      {
+        sum += m_histValue;
+      }
+    }
+    else
+    {
+      sum += 2 * m_histValue;
+    }
+    if (posY < m_height - 1)
+    {
+      sum += abs(data[m_width]);
+      if (posY < m_height - 2)
+      {
+        sum += abs(data[m_width << 1]);
+      }
+      else
+      {
+        sum += m_histValue;
+      }
+    }
+    else
+    {
+      sum += m_histValue;
+    }
+
+    int currentShift = templateAbsCompare(sum);
+    sum = sum >> currentShift;
+    if (baseLevel == 0)
+    {
+      riceParam = unsigned(std::min<TCoeff>(sum, 31));
+    }
+    else
+    {
+      riceParam = unsigned(std::max<TCoeff>(std::min<TCoeff>(sum - baseLevel, 31), 0));
+    }
+
+    riceParam = g_goRiceParsCoeff[riceParam] + currentShift;
+
+    return riceParam;
+  }
+
+  unsigned (CoeffCodingContext::*deriveRiceRRC)(int scanPos, const TCoeff* coeff, int baseLevel);
+
+  unsigned deriveRice(int scanPos, const TCoeff* coeff, int baseLevel)
+  {
+    unsigned sumAbs = templateAbsSum(scanPos, coeff, baseLevel);
+    unsigned riceParam = g_goRiceParsCoeff[sumAbs];
+    return riceParam;
+  }
+  
+  unsigned deriveRiceExt(int scanPos, const TCoeff* coeff, int baseLevel)
+  {
+    unsigned riceParam = templateAbsSumExt(scanPos, coeff, baseLevel);
+    return riceParam;
+  }
+
   unsigned sigCtxIdAbsTS( int scanPos, const TCoeff* coeff )
   {
     const uint32_t  posY   = m_scan[scanPos].y;
@@ -308,7 +427,9 @@ public:
   {
 
     if (absCoeff == 0)
+    {
       return 0;
+    }
     int pred1, absBelow = abs(belowPixel), absRight = abs(rightPixel);
 
     int absCoeffMod = int(absCoeff);
@@ -334,7 +455,9 @@ public:
   {
 
     if (absCoeff == 0)
+    {
       return 0;
+    }
 
     int pred1, absBelow = abs(belowPixel), absRight = abs(rightPixel);
     pred1 = std::max(absBelow, absRight);
@@ -359,6 +482,13 @@ public:
 
   int                       regBinLimit;
 
+  unsigned  getBaseLevel()                                   { return m_cctxBaseLevel; };
+  void setBaseLevel(int value)                               { m_cctxBaseLevel = value; };
+  TCoeff getHistValue()                                      { return m_histValue; };
+  void setHistValue(TCoeff value)                            { m_histValue = value; };
+  bool getUpdateHist() { return m_updateHist; };
+  void setUpdateHist(bool value) { m_updateHist = value; };
+
 private:
   // constant
   const ComponentID         m_compID;
@@ -413,6 +543,9 @@ private:
   int                       m_remainingContextBins;
   std::bitset<MLS_GRP_NUM>  m_sigCoeffGroupFlag;
   const bool                m_bdpcm;
+  int                       m_cctxBaseLevel; 
+  TCoeff                    m_histValue;    
+  bool                      m_updateHist;
 };
 
 
@@ -457,6 +590,13 @@ public:
   ~MergeCtx() {}
 public:
   MvField       mvFieldNeighbours [ MRG_MAX_NUM_CANDS << 1 ]; // double length for mv of both lists
+#if GDR_ENABLED 
+  // note : check if source of mv and mv itself is valid
+  bool          mvSolid           [MRG_MAX_NUM_CANDS << 1];  
+  bool          mvValid           [MRG_MAX_NUM_CANDS << 1];
+  Position      mvPos             [MRG_MAX_NUM_CANDS << 1];
+  MvpType       mvType            [MRG_MAX_NUM_CANDS << 1];
+#endif
   uint8_t       BcwIdx            [ MRG_MAX_NUM_CANDS      ];
   unsigned char interDirNeighbours[ MRG_MAX_NUM_CANDS      ];
   MergeType     mrgTypeNeighbours [ MRG_MAX_NUM_CANDS      ];
@@ -466,6 +606,10 @@ public:
   MotionBuf     subPuMvpMiBuf;
   MotionBuf     subPuMvpExtMiBuf;
   MvField mmvdBaseMv[MMVD_BASE_MV_NUM][2];
+#if GDR_ENABLED   
+  bool          mmvdSolid[MMVD_BASE_MV_NUM][2];
+  bool          mmvdValid[MMVD_BASE_MV_NUM][2];
+#endif
   void setMmvdMergeCandiInfo(PredictionUnit& pu, int candIdx);
   bool          mmvdUseAltHpelIf  [ MMVD_BASE_MV_NUM ];
   bool          useAltHpelIf      [ MRG_MAX_NUM_CANDS ];
@@ -479,6 +623,10 @@ public:
   ~AffineMergeCtx() {}
 public:
   MvField       mvFieldNeighbours[AFFINE_MRG_MAX_NUM_CANDS << 1][3]; // double length for mv of both lists
+#if GDR_ENABLED
+  bool          mvSolid[AFFINE_MRG_MAX_NUM_CANDS << 1][3];   
+  bool          mvValid[AFFINE_MRG_MAX_NUM_CANDS << 1][3];
+#endif
   unsigned char interDirNeighbours[AFFINE_MRG_MAX_NUM_CANDS];
   EAffineModel  affineType[AFFINE_MRG_MAX_NUM_CANDS];
   uint8_t       BcwIdx[AFFINE_MRG_MAX_NUM_CANDS];
diff --git a/source/Lib/CommonLib/Contexts.cpp b/source/Lib/CommonLib/Contexts.cpp
index f3acf16b6..d5d4d47a1 100644
--- a/source/Lib/CommonLib/Contexts.cpp
+++ b/source/Lib/CommonLib/Contexts.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -131,9 +131,6 @@ void BinProbModel_Std::init( int qp, int initId )
   m_state[1]   = p1 & MASK_1;
 }
 
-
-
-
 CtxSet::CtxSet( std::initializer_list<CtxSet> ctxSets )
 {
   uint16_t  minOffset = std::numeric_limits<uint16_t>::max();
@@ -147,10 +144,6 @@ CtxSet::CtxSet( std::initializer_list<CtxSet> ctxSets )
   Size    = maxOffset - minOffset;
 }
 
-
-
-
-
 const std::vector<uint8_t>& ContextSetCfg::getInitTable( unsigned initId )
 {
   CHECK( initId >= (unsigned)sm_InitTables.size(),
@@ -158,7 +151,6 @@ const std::vector<uint8_t>& ContextSetCfg::getInitTable( unsigned initId )
   return sm_InitTables[initId];
 }
 
-
 CtxSet ContextSetCfg::addCtxSet( std::initializer_list<std::initializer_list<uint8_t>> initSet2d )
 {
   const std::size_t startIdx  = sm_InitTables[0].size();
@@ -958,16 +950,8 @@ void CtxStore<BinProbModel>::savePStates( std::vector<uint16_t>& probStates ) co
   }
 }
 
-
-
-
-
 template class CtxStore<BinProbModel_Std>;
 
-
-
-
-
 Ctx::Ctx()                                  : m_BPMType( BPM_Undefined )                        {}
 Ctx::Ctx( const BinProbModel_Std*   dummy ) : m_BPMType( BPM_Std   ), m_CtxStore_Std  ( true )  {}
 
diff --git a/source/Lib/CommonLib/Contexts.h b/source/Lib/CommonLib/Contexts.h
index 5a94a2d95..d733b3106 100644
--- a/source/Lib/CommonLib/Contexts.h
+++ b/source/Lib/CommonLib/Contexts.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -382,6 +382,30 @@ public:
     }
   }
 
+#if JVET_W0178_CONSTRAINTS_ON_REXT_TOOLS
+  void riceStatReset(int bitDepth, bool persistentRiceAdaptationEnabledFlag)
+#else
+  void riceStatReset(int bitDepth)
+#endif
+  {
+    for (std::size_t k = 0; k < RExt__GOLOMB_RICE_ADAPTATION_STATISTICS_SETS; k++)
+    {
+#if JVET_W0178_CONSTRAINTS_ON_REXT_TOOLS
+      if (persistentRiceAdaptationEnabledFlag)
+      {
+          CHECK(bitDepth <= 10,"BitDepth shall be larger than 10.");
+          m_GRAdaptStats[k] = 2 * floorLog2(bitDepth - 10);
+      } 
+      else 
+      {
+          m_GRAdaptStats[k] = 0;
+      }
+#else
+      m_GRAdaptStats[k] = (bitDepth > 10) ? 2 * floorLog2(bitDepth - 10) : 0; 
+#endif
+    }
+  }
+
   void  loadPStates( const std::vector<uint16_t>& probStates )
   {
     switch( m_BPMType )
@@ -416,6 +440,9 @@ public:
   const unsigned&     getGRAdaptStats ( unsigned      id )      const { return m_GRAdaptStats[id]; }
   unsigned&           getGRAdaptStats ( unsigned      id )            { return m_GRAdaptStats[id]; }
 
+  const unsigned           getBaseLevel()                     const { return m_baseLevel; }
+  void                setBaseLevel(int value)                         { m_baseLevel = value; }
+
 public:
   unsigned            getBPMType      ()                        const { return m_BPMType; }
   const Ctx&          getCtx          ()                        const { return *this; }
@@ -438,12 +465,8 @@ private:
   CtxStore<BinProbModel_Std>    m_CtxStore_Std;
 protected:
   unsigned                      m_GRAdaptStats[RExt__GOLOMB_RICE_ADAPTATION_STATISTICS_SETS];
-#if ENABLE_SPLIT_PARALLELISM
+  int m_baseLevel;
 
-public:
-  int64_t cacheId;
-  bool    cacheUsed;
-#endif
 };
 
 
diff --git a/source/Lib/CommonLib/LoopFilter.cpp b/source/Lib/CommonLib/DeblockingFilter.cpp
similarity index 94%
rename from source/Lib/CommonLib/LoopFilter.cpp
rename to source/Lib/CommonLib/DeblockingFilter.cpp
index 46b268f23..1e8c9c555 100644
--- a/source/Lib/CommonLib/LoopFilter.cpp
+++ b/source/Lib/CommonLib/DeblockingFilter.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,11 +31,11 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/** \file     LoopFilter.cpp
+/** \file     DeblockingFilter.cpp
     \brief    deblocking filter
 */
 
-#include "LoopFilter.h"
+#include "DeblockingFilter.h"
 #include "Slice.h"
 #include "Mv.h"
 #include "Unit.h"
@@ -58,13 +58,13 @@
 // Tables
 // ====================================================================================================================
 
-const uint16_t LoopFilter::sm_tcTable[MAX_QP + 1 + DEFAULT_INTRA_TC_OFFSET] = {
+const uint16_t DeblockingFilter::sm_tcTable[MAX_QP + 1 + DEFAULT_INTRA_TC_OFFSET] = {
   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   3,   4,   4,   4,
   4,  5,  5,  5,  5,  7,  7,  8,  9,  10,  10,  11,  13,  14,  15,  17,  19,  21,  24,  25,  29,  33,
   36, 41, 45, 51, 57, 64, 71, 80, 89, 100, 112, 125, 141, 157, 177, 198, 222, 250, 280, 314, 352, 395
 };
 
-const uint8_t LoopFilter::sm_betaTable[MAX_QP + 1] = { 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+const uint8_t DeblockingFilter::sm_betaTable[MAX_QP + 1] = { 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
                                                        6,  7,  8,  9,  10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 22, 24,
                                                        26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56,
                                                        58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88 };
@@ -92,18 +92,18 @@ static bool isAvailableAbove( const CodingUnit& cu, const CodingUnit& cu2, const
 // Constructor / destructor / create / destroy
 // ====================================================================================================================
 
-LoopFilter::LoopFilter()
+DeblockingFilter::DeblockingFilter()
 {
 }
 
-LoopFilter::~LoopFilter()
+DeblockingFilter::~DeblockingFilter()
 {
 }
 
 // ====================================================================================================================
 // Public member functions
 // ====================================================================================================================
-void LoopFilter::create( const unsigned uiMaxCUDepth )
+void DeblockingFilter::create( const unsigned uiMaxCUDepth )
 {
   destroy();
   const unsigned numPartitions = 1 << ( uiMaxCUDepth << 1 );
@@ -115,14 +115,14 @@ void LoopFilter::create( const unsigned uiMaxCUDepth )
   m_enc = false;
 }
 
-void LoopFilter::initEncPicYuvBuffer(ChromaFormat chromaFormat, const Size &size, const unsigned maxCUSize)
+void DeblockingFilter::initEncPicYuvBuffer(ChromaFormat chromaFormat, const Size &size, const unsigned maxCUSize)
 {
   const Area a = Area(Position(), size);
   m_encPicYuvBuffer.destroy();
   m_encPicYuvBuffer.create(chromaFormat, a, maxCUSize, 7);
 }
 
-void LoopFilter::destroy()
+void DeblockingFilter::destroy()
 {
   for( int edgeDir = 0; edgeDir < NUM_EDGE_DIR; edgeDir++ )
   {
@@ -137,7 +137,7 @@ void LoopFilter::destroy()
  .
  \param  pcPic   picture class (Pic) pointer
  */
-void LoopFilter::loopFilterPic( CodingStructure& cs
+void DeblockingFilter::deblockingFilterPic( CodingStructure& cs
                                 )
 {
   const PreCalcValues& pcv = *cs.pcv;
@@ -238,11 +238,11 @@ void LoopFilter::loopFilterPic( CodingStructure& cs
   DTRACE_PIC_COMP(D_REC_CB_CHROMA_LF, cs, cs.getRecoBuf(), COMPONENT_Cb);
   DTRACE_PIC_COMP(D_REC_CB_CHROMA_LF, cs, cs.getRecoBuf(), COMPONENT_Cr);
 
-  DTRACE    ( g_trace_ctx, D_CRC, "LoopFilter" );
+  DTRACE    ( g_trace_ctx, D_CRC, "DeblockingFilter" );
   DTRACE_CRC( g_trace_ctx, D_CRC, cs, cs.getRecoBuf() );
 }
 
-void LoopFilter::resetFilterLengths()
+void DeblockingFilter::resetFilterLengths()
 {
   memset(m_aapucBS[EDGE_VER].data(), 0, m_aapucBS[EDGE_VER].byte_size());
   memset(m_aapbEdgeFilter[EDGE_VER].data(), false, m_aapbEdgeFilter[EDGE_VER].byte_size());
@@ -263,7 +263,7 @@ void LoopFilter::resetFilterLengths()
  \param cu               the CU to be deblocked
  \param edgeDir          the direction of the edge in block boundary (horizontal/vertical), which is added newly
 */
-void LoopFilter::xDeblockCU( CodingUnit& cu, const DeblockEdgeDir edgeDir )
+void DeblockingFilter::xDeblockCU( CodingUnit& cu, const DeblockEdgeDir edgeDir )
 {
   const PreCalcValues& pcv = *cu.cs->pcv;
   const Area area          = cu.Y().valid() ? cu.Y() : Area( recalcPosition( cu.chromaFormat, cu.chType, CHANNEL_TYPE_LUMA, cu.blocks[cu.chType].pos() ), recalcSize( cu.chromaFormat, cu.chType, CHANNEL_TYPE_LUMA, cu.blocks[cu.chType].size() ) );
@@ -275,7 +275,7 @@ void LoopFilter::xDeblockCU( CodingUnit& cu, const DeblockEdgeDir edgeDir )
 
   bool isCuCrossedByVirtualBoundaries = isCrossedByVirtualBoundaries( area.x, area.y, area.width, area.height, numHorVirBndry, numVerVirBndry, horVirBndryPos, verVirBndryPos, cu.cs->picHeader );
 
-  xSetLoopfilterParam( cu );
+  xSetDeblockingFilterParam( cu );
   static_vector<int, 2*MAX_CU_SIZE> edgeIdx;
   edgeIdx.clear();
 
@@ -445,7 +445,7 @@ void LoopFilter::xDeblockCU( CodingUnit& cu, const DeblockEdgeDir edgeDir )
   }
 }
 
-inline bool LoopFilter::isCrossedByVirtualBoundaries(const int xPos, const int yPos, const int width, const int height, int& numHorVirBndry, int& numVerVirBndry, int horVirBndryPos[], int verVirBndryPos[], const PicHeader* picHeader )
+inline bool DeblockingFilter::isCrossedByVirtualBoundaries(const int xPos, const int yPos, const int width, const int height, int& numHorVirBndry, int& numVerVirBndry, int horVirBndryPos[], int verVirBndryPos[], const PicHeader* picHeader )
 {
   numHorVirBndry = 0; numVerVirBndry = 0;
   if( picHeader->getVirtualBoundariesPresentFlag() )
@@ -468,7 +468,7 @@ inline bool LoopFilter::isCrossedByVirtualBoundaries(const int xPos, const int y
   return numHorVirBndry > 0 || numVerVirBndry > 0;
 }
 
-inline void LoopFilter::xDeriveEdgefilterParam( const int xPos, const int yPos, const int numVerVirBndry, const int numHorVirBndry, const int verVirBndryPos[], const int horVirBndryPos[], bool &verEdgeFilter, bool &horEdgeFilter )
+inline void DeblockingFilter::xDeriveEdgefilterParam( const int xPos, const int yPos, const int numVerVirBndry, const int numHorVirBndry, const int verVirBndryPos[], const int horVirBndryPos[], bool &verEdgeFilter, bool &horEdgeFilter )
 {
   for (int i = 0; i < numVerVirBndry; i++)
   {
@@ -489,7 +489,7 @@ inline void LoopFilter::xDeriveEdgefilterParam( const int xPos, const int yPos,
   }
 }
 
-void LoopFilter::xSetMaxFilterLengthPQFromTransformSizes(const DeblockEdgeDir edgeDir, const CodingUnit &cu,
+void DeblockingFilter::xSetMaxFilterLengthPQFromTransformSizes(const DeblockEdgeDir edgeDir, const CodingUnit &cu,
                                                          const TransformUnit &currTU, const int firstComponent)
 {
   const TransformUnit& tuQ = currTU;
@@ -541,7 +541,7 @@ void LoopFilter::xSetMaxFilterLengthPQFromTransformSizes(const DeblockEdgeDir ed
   }
   if ( edgeDir == EDGE_VER )
   {
-    for ( int cIdx = 0; cIdx < ::getNumberValidComponents(tuQ.chromaFormat); cIdx++ ) // per component
+    for ( int cIdx = firstComponent; cIdx < ::getNumberValidComponents(tuQ.chromaFormat); cIdx++ ) // per component
     {
       const ComponentID comp = ComponentID(cIdx);
       const ChannelType ch   = toChannelType(comp);
@@ -586,7 +586,7 @@ void LoopFilter::xSetMaxFilterLengthPQFromTransformSizes(const DeblockEdgeDir ed
   }
 }
 
-void LoopFilter::xSetMaxFilterLengthPQForCodingSubBlocks( const DeblockEdgeDir edgeDir, const CodingUnit& cu, const PredictionUnit& currPU, const bool& mvSubBlocks, const int& subBlockSize, const Area& areaPu )
+void DeblockingFilter::xSetMaxFilterLengthPQForCodingSubBlocks( const DeblockEdgeDir edgeDir, const CodingUnit& cu, const PredictionUnit& currPU, const bool& mvSubBlocks, const int& subBlockSize, const Area& areaPu )
 {
   if ( mvSubBlocks && currPU.Y().valid() )
   {
@@ -663,7 +663,7 @@ void LoopFilter::xSetMaxFilterLengthPQForCodingSubBlocks( const DeblockEdgeDir e
   }
 }
 
-void LoopFilter::xSetEdgefilterMultiple( const CodingUnit&    cu,
+void DeblockingFilter::xSetEdgefilterMultiple( const CodingUnit&    cu,
                                          const DeblockEdgeDir edgeDir,
                                          const Area&          area,
                                          const bool           bValue,
@@ -693,7 +693,7 @@ void LoopFilter::xSetEdgefilterMultiple( const CodingUnit&    cu,
   }
 }
 
-void LoopFilter::xSetLoopfilterParam( const CodingUnit& cu )
+void DeblockingFilter::xSetDeblockingFilterParam( const CodingUnit& cu )
 {
   const Slice& slice = *cu.slice;
   const PPS&   pps   = *cu.cs->pps;
@@ -714,7 +714,7 @@ void LoopFilter::xSetLoopfilterParam( const CodingUnit& cu )
     !( pps.getSubPicFromCU(cu).getloopFilterAcrossEnabledFlag() && pps.getSubPicFromCU(*cu.cs->getCU(pos.offset(0, -1), cu.chType)).getloopFilterAcrossEnabledFlag()));
 }
 
-unsigned LoopFilter::xGetBoundaryStrengthSingle ( const CodingUnit& cu, const DeblockEdgeDir edgeDir, const Position& localPos, const ChannelType chType ) const
+unsigned DeblockingFilter::xGetBoundaryStrengthSingle ( const CodingUnit& cu, const DeblockEdgeDir edgeDir, const Position& localPos, const ChannelType chType ) const
 {
   // The boundary strength that is output by the function xGetBoundaryStrengthSingle is a multi component boundary strength that contains boundary strength for luma (bits 0 to 1), cb (bits 2 to 3) and cr (bits 4 to 5).
 
@@ -903,7 +903,7 @@ unsigned LoopFilter::xGetBoundaryStrengthSingle ( const CodingUnit& cu, const De
 }
 
 #if LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET
-void LoopFilter::deriveLADFShift( const Pel* src, const int stride, int& shift, const DeblockEdgeDir edgeDir, const SPS sps )
+void DeblockingFilter::deriveLADFShift( const Pel* src, const int stride, int& shift, const DeblockEdgeDir edgeDir, const SPS sps )
 {
   uint32_t lumaLevel = 0;
   shift = sps.getLadfQpOffset(0);
@@ -932,7 +932,7 @@ void LoopFilter::deriveLADFShift( const Pel* src, const int stride, int& shift,
 }
 #endif
 
-void LoopFilter::xEdgeFilterLuma( const CodingUnit& cu, const DeblockEdgeDir edgeDir, const int iEdge )
+void DeblockingFilter::xEdgeFilterLuma( const CodingUnit& cu, const DeblockEdgeDir edgeDir, const int iEdge )
 {
   const CompArea&  lumaArea = cu.block(COMPONENT_Y);
   const PreCalcValues& pcv = *cu.cs->pcv;
@@ -1180,7 +1180,7 @@ void LoopFilter::xEdgeFilterLuma( const CodingUnit& cu, const DeblockEdgeDir edg
 }
 
 
-void LoopFilter::xEdgeFilterChroma(const CodingUnit& cu, const DeblockEdgeDir edgeDir, const int iEdge)
+void DeblockingFilter::xEdgeFilterChroma(const CodingUnit& cu, const DeblockEdgeDir edgeDir, const int iEdge)
 {
   const Position lumaPos   = cu.Y().valid() ? cu.Y().pos() : recalcPosition( cu.chromaFormat, cu.chType, CHANNEL_TYPE_LUMA, cu.blocks[cu.chType].pos() );
   const Size     lumaSize  = cu.Y().valid() ? cu.Y().size() : recalcSize( cu.chromaFormat, cu.chType, CHANNEL_TYPE_LUMA, cu.blocks[cu.chType].size() );
@@ -1406,7 +1406,7 @@ void LoopFilter::xEdgeFilterChroma(const CodingUnit& cu, const DeblockEdgeDir ed
  \param bFilterSecondQ  decision weak filter/no filter for partQ
  \param bitDepthLuma    luma bit depth
 */
-inline void LoopFilter::xBilinearFilter(Pel* srcP, Pel* srcQ, int offset, int refMiddle, int refP, int refQ, int numberPSide, int numberQSide, const int* dbCoeffsP, const int* dbCoeffsQ, int tc) const
+inline void DeblockingFilter::xBilinearFilter(Pel* srcP, Pel* srcQ, int offset, int refMiddle, int refP, int refQ, int numberPSide, int numberQSide, const int* dbCoeffsP, const int* dbCoeffsQ, int tc) const
 {
   const char tc7[7] = { 6, 5, 4, 3, 2, 1, 1 };
   const char tc3[3] = { 6, 4, 2 };
@@ -1430,7 +1430,7 @@ inline void LoopFilter::xBilinearFilter(Pel* srcP, Pel* srcQ, int offset, int re
   }
 }
 
-inline void LoopFilter::xFilteringPandQ(Pel* src, int offset, int numberPSide, int numberQSide, int tc) const
+inline void DeblockingFilter::xFilteringPandQ(Pel* src, int offset, int numberPSide, int numberQSide, int tc) const
 {
   CHECK(numberPSide <= 3 && numberQSide <= 3, "Short filtering in long filtering function");
   Pel* srcP = src-offset;
@@ -1504,7 +1504,7 @@ inline void LoopFilter::xFilteringPandQ(Pel* src, int offset, int numberPSide, i
   xBilinearFilter(srcP,srcQ,offset,refMiddle,refP,refQ,numberPSide,numberQSide,dbCoeffsP,dbCoeffsQ,tc);
 }
 
-inline void LoopFilter::xPelFilterLuma(Pel* piSrc, const int iOffset, const int tc, const bool sw, const bool bPartPNoFilter, const bool bPartQNoFilter, const int iThrCut, const bool bFilterSecondP, const bool bFilterSecondQ, const ClpRng& clpRng, bool sidePisLarge, bool sideQisLarge, int maxFilterLengthP, int maxFilterLengthQ) const
+inline void DeblockingFilter::xPelFilterLuma(Pel* piSrc, const int iOffset, const int tc, const bool sw, const bool bPartPNoFilter, const bool bPartQNoFilter, const int iThrCut, const bool bFilterSecondP, const bool bFilterSecondQ, const ClpRng& clpRng, bool sidePisLarge, bool sideQisLarge, int maxFilterLengthP, int maxFilterLengthQ) const
 {
   int delta;
 
@@ -1604,7 +1604,7 @@ inline void LoopFilter::xPelFilterLuma(Pel* piSrc, const int iOffset, const int
  \param bPartQNoFilter  indicator to disable filtering on partQ
  \param bitDepthChroma  chroma bit depth
  */
-inline void LoopFilter::xPelFilterChroma(Pel* piSrc, const int iOffset, const int tc, const bool sw, const bool bPartPNoFilter, const bool bPartQNoFilter, const ClpRng& clpRng, const bool largeBoundary, const bool isChromaHorCTBBoundary) const
+inline void DeblockingFilter::xPelFilterChroma(Pel* piSrc, const int iOffset, const int tc, const bool sw, const bool bPartPNoFilter, const bool bPartQNoFilter, const ClpRng& clpRng, const bool largeBoundary, const bool isChromaHorCTBBoundary) const
 {
   int delta;
 
@@ -1673,7 +1673,7 @@ inline void LoopFilter::xPelFilterChroma(Pel* piSrc, const int iOffset, const in
  \param tc              tc value
  \param piSrc           pointer to picture data
  */
-inline bool LoopFilter::xUseStrongFiltering(Pel* piSrc, const int iOffset, const int d, const int beta, const int tc, bool sidePisLarge, bool sideQisLarge, int maxFilterLengthP, int maxFilterLengthQ, bool isChromaHorCTBBoundary) const
+inline bool DeblockingFilter::xUseStrongFiltering(Pel* piSrc, const int iOffset, const int d, const int beta, const int tc, bool sidePisLarge, bool sideQisLarge, int maxFilterLengthP, int maxFilterLengthQ, bool isChromaHorCTBBoundary) const
 {
   const Pel m4 = piSrc[ 0          ];
   const Pel m3 = piSrc[-iOffset    ];
@@ -1732,7 +1732,7 @@ inline bool LoopFilter::xUseStrongFiltering(Pel* piSrc, const int iOffset, const
   }
 }
 
-inline int LoopFilter::xCalcDP(Pel* piSrc, const int iOffset, const bool isChromaHorCTBBoundary) const
+inline int DeblockingFilter::xCalcDP(Pel* piSrc, const int iOffset, const bool isChromaHorCTBBoundary) const
 {
   if (isChromaHorCTBBoundary)
   {
@@ -1744,12 +1744,12 @@ inline int LoopFilter::xCalcDP(Pel* piSrc, const int iOffset, const bool isChrom
   }
 }
 
-inline int LoopFilter::xCalcDQ( Pel* piSrc, const int iOffset ) const
+inline int DeblockingFilter::xCalcDQ( Pel* piSrc, const int iOffset ) const
 {
   return abs( piSrc[0] - 2 * piSrc[iOffset] + piSrc[iOffset * 2] );
 }
 
-inline unsigned LoopFilter::BsSet(unsigned val, const ComponentID compIdx) const { return (val << (compIdx << 1)); }
-inline unsigned LoopFilter::BsGet(unsigned val, const ComponentID compIdx) const { return ((val >> (compIdx << 1)) & 3); }
+inline unsigned DeblockingFilter::BsSet(unsigned val, const ComponentID compIdx) const { return (val << (compIdx << 1)); }
+inline unsigned DeblockingFilter::BsGet(unsigned val, const ComponentID compIdx) const { return ((val >> (compIdx << 1)) & 3); }
 
 //! \}
diff --git a/source/Lib/CommonLib/LoopFilter.h b/source/Lib/CommonLib/DeblockingFilter.h
similarity index 95%
rename from source/Lib/CommonLib/LoopFilter.h
rename to source/Lib/CommonLib/DeblockingFilter.h
index 566254023..9deb304c1 100644
--- a/source/Lib/CommonLib/LoopFilter.h
+++ b/source/Lib/CommonLib/DeblockingFilter.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,12 +31,12 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/** \file     LoopFilter.h
+/** \file     DeblockingFilter.h
     \brief    deblocking filter (header)
 */
 
-#ifndef __LOOPFILTER__
-#define __LOOPFILTER__
+#ifndef __DEBLOCKINGFILTER__
+#define __DEBLOCKINGFILTER__
 
 #include "CommonDef.h"
 #include "Unit.h"
@@ -52,7 +52,7 @@
 // ====================================================================================================================
 
 /// deblocking filter class
-class LoopFilter
+class DeblockingFilter
 {
 private:
   static_vector<char, MAX_NUM_PARTS_IN_CTU> m_aapucBS       [NUM_EDGE_DIR];         ///< Bs for [Ver/Hor][Y/U/V][Blk_Idx]
@@ -68,7 +68,7 @@ private:
 private:
 
   // set / get functions
-  void xSetLoopfilterParam        ( const CodingUnit& cu );
+  void xSetDeblockingFilterParam        ( const CodingUnit& cu );
 
   // filtering functions
   unsigned
@@ -107,8 +107,8 @@ private:
 
 public:
 
-  LoopFilter();
-  ~LoopFilter();
+  DeblockingFilter();
+  ~DeblockingFilter();
 
   /// CU-level deblocking function
   void xDeblockCU(CodingUnit& cu, const DeblockEdgeDir edgeDir);
@@ -120,8 +120,7 @@ public:
   void  destroy                   ();
 
   /// picture-level deblocking filter
-  void loopFilterPic              ( CodingStructure& cs
-                                    );
+  void deblockingFilterPic        ( CodingStructure& cs );
 
   static int getBeta              ( const int qp )
   {
diff --git a/source/Lib/CommonLib/DepQuant.cpp b/source/Lib/CommonLib/DepQuant.cpp
index 85c07184d..d7c0175b9 100644
--- a/source/Lib/CommonLib/DepQuant.cpp
+++ b/source/Lib/CommonLib/DepQuant.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -38,7 +38,7 @@
 
 #include <bitset>
 
-
+#include "ContextModelling.h"
 
 
 
@@ -386,9 +386,13 @@ namespace DQIntern
     scanInfo.eosbb      = ( scanInfo.insidePos == 0 );
     scanInfo.spt        = SCAN_ISCSBB;
     if(  scanInfo.insidePos == m_sbbMask && scanIdx > scanInfo.sbbSize && scanIdx < m_numCoeff - 1 )
+    {
       scanInfo.spt      = SCAN_SOCSBB;
+    }
     else if( scanInfo.eosbb && scanIdx > 0 && scanIdx < m_numCoeff - m_sbbSize )
+    {
       scanInfo.spt      = SCAN_EOCSBB;
+    }
     scanInfo.posX = m_scanId2BlkPos[scanIdx].x;
     scanInfo.posY = m_scanId2BlkPos[scanIdx].y;
     if( scanIdx )
@@ -433,10 +437,20 @@ namespace DQIntern
       return m_sigFracBits[std::max(((int) stateId) - 1, 0)];
     }
     inline const CoeffFracBits *gtxFracBits(unsigned stateId) const { return m_gtxFracBits; }
+#if JVET_W0046_RLSCP
+    inline int32_t lastOffset(unsigned scanIdx, int effWidth, int effHeight, bool reverseLast) const
+    {
+      if (reverseLast)
+        return m_lastBitsX[effWidth - 1 - m_scanId2Pos[scanIdx].x] + m_lastBitsY[effHeight - 1 - m_scanId2Pos[scanIdx].y];
+      else
+        return m_lastBitsX[m_scanId2Pos[scanIdx].x] + m_lastBitsY[m_scanId2Pos[scanIdx].y];
+    }
+#else
     inline int32_t              lastOffset(unsigned scanIdx) const
     {
       return m_lastBitsX[m_scanId2Pos[scanIdx].x] + m_lastBitsY[m_scanId2Pos[scanIdx].y];
     }
+#endif
 
   private:
     void  xSetLastCoeffOffset ( const FracBitsAccess& fracBitsAccess, const TUParameters& tuPars, const TransformUnit& tu, const ComponentID compID );
@@ -528,7 +542,7 @@ namespace DQIntern
       const unsigned      lastShift   = ( compID == COMPONENT_Y ? (log2Size+1)>>2 : Clip3<unsigned>(0,2,size>>3) );
       const unsigned      lastOffset  = ( compID == COMPONENT_Y ? ( prefixCtx[log2Size] ) : 0 );
       uint32_t            sumFBits    = 0;
-      unsigned            maxCtxId    = g_uiGroupIdx[std::min<unsigned>(JVET_C0024_ZERO_OUT_TH, size) - 1];
+      unsigned            maxCtxId    = g_groupIdx[std::min<unsigned>(JVET_C0024_ZERO_OUT_TH, size) - 1];
       for( unsigned ctxId = 0; ctxId < maxCtxId; ctxId++ )
       {
         const BinFracBits bits  = fracBitsAccess.getFracBitsArray( ctxSetLast( lastOffset + ( ctxId >> lastShift ) ) );
@@ -538,7 +552,7 @@ namespace DQIntern
       ctxBits  [ maxCtxId ]     = sumFBits + ( maxCtxId>3 ? ((maxCtxId-2)>>1)<<SCALE_BITS : 0 ) + bitOffset;
       for (unsigned pos = 0; pos < std::min<unsigned>(JVET_C0024_ZERO_OUT_TH, size); pos++)
       {
-        lastBits[ pos ]         = ctxBits[ g_uiGroupIdx[ pos ] ];
+        lastBits[pos] = ctxBits[g_groupIdx[pos]];
       }
     }
   }
@@ -756,7 +770,9 @@ namespace DQIntern
       if( level )
       {
         if (enableScalingLists)
+        {
           invQScale = piDequantCoef[rasterPos];//scalingfactor*levelScale
+        }
         if (shift < 0 && (enableScalingLists || scanIdx == lastScanIdx))
         {
           invQScale <<= -shift;
@@ -843,13 +859,38 @@ namespace DQIntern
     uint8_t                     m_memory[ 8 * ( MAX_TB_SIZEY * MAX_TB_SIZEY + MLS_GRP_NUM ) ];
   };
 
+#if JVET_V0106_DEP_QUANT_ENC_OPT
+#define RICEMAX 64
+#define RICE_ORDER_MAX 16
+  const int32_t g_goRiceBits[RICE_ORDER_MAX][RICEMAX] =
+#else
 #define RICEMAX 32
   const int32_t g_goRiceBits[4][RICEMAX] =
+#endif
   {
+#if JVET_V0106_DEP_QUANT_ENC_OPT
+    { 32768, 65536, 98304, 131072, 163840, 196608, 262144, 262144, 327680, 327680, 327680, 327680, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288 },
+    { 65536, 65536, 98304, 98304, 131072, 131072, 163840, 163840, 196608, 196608, 229376, 229376, 294912, 294912, 294912, 294912, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520 },
+    { 98304, 98304, 98304, 98304, 131072, 131072, 131072, 131072, 163840, 163840, 163840, 163840, 196608, 196608, 196608, 196608, 229376, 229376, 229376, 229376, 262144, 262144, 262144, 262144, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752 },
+    { 131072, 131072, 131072, 131072, 131072, 131072, 131072, 131072, 163840, 163840, 163840, 163840, 163840, 163840, 163840, 163840, 196608, 196608, 196608, 196608, 196608, 196608, 196608, 196608, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448 },
+    { 163840, 163840, 163840, 163840, 163840, 163840, 163840, 163840, 163840, 163840, 163840, 163840, 163840, 163840, 163840, 163840, 196608, 196608, 196608, 196608, 196608, 196608, 196608, 196608, 196608, 196608, 196608, 196608, 196608, 196608, 196608, 196608, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144 },
+    { 196608, 196608, 196608, 196608, 196608, 196608, 196608, 196608, 196608, 196608, 196608, 196608, 196608, 196608, 196608, 196608, 196608, 196608, 196608, 196608, 196608, 196608, 196608, 196608, 196608, 196608, 196608, 196608, 196608, 196608, 196608, 196608, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376 },
+    { 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376 },
+    { 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144 },
+    { 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912, 294912 },
+    { 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680 },
+    { 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448 },
+    { 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216 },
+    { 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984 },
+    { 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752 },
+    { 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520, 491520 },
+    { 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288, 524288 },
+#else
     { 32768,  65536,  98304, 131072, 163840, 196608, 262144, 262144, 327680, 327680, 327680, 327680, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752},
     { 65536,  65536,  98304,  98304, 131072, 131072, 163840, 163840, 196608, 196608, 229376, 229376, 294912, 294912, 294912, 294912, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984},
     { 98304,  98304,  98304,  98304, 131072, 131072, 131072, 131072, 163840, 163840, 163840, 163840, 196608, 196608, 196608, 196608, 229376, 229376, 229376, 229376, 262144, 262144, 262144, 262144, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680},
     {131072, 131072, 131072, 131072, 131072, 131072, 131072, 131072, 163840, 163840, 163840, 163840, 163840, 163840, 163840, 163840, 196608, 196608, 196608, 196608, 196608, 196608, 196608, 196608, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376}
+#endif
   };
 
   class State
@@ -859,7 +900,7 @@ namespace DQIntern
     State( const RateEstimator& rateEst, CommonCtx& commonCtx, const int stateId );
 
     template<uint8_t numIPos>
-    inline void updateState(const ScanInfo &scanInfo, const State *prevStates, const Decision &decision);
+    inline void updateState(const ScanInfo &scanInfo, const State *prevStates, const Decision &decision, const int baseLevel, const bool extRiceFlag);
     inline void updateStateEOS(const ScanInfo &scanInfo, const State *prevStates, const State *skipStates,
                                const Decision &decision);
 
@@ -880,70 +921,82 @@ namespace DQIntern
       int64_t         rdCostA   = m_rdCost + pqDataA.deltaDist;
       int64_t         rdCostB   = m_rdCost + pqDataB.deltaDist;
       int64_t         rdCostZ   = m_rdCost;
-        if( m_remRegBins >= 4 )
+      if (m_remRegBins >= 4)
+      {
+        if (pqDataA.absLevel < 4)
         {
-          if( pqDataA.absLevel < 4 )
-            rdCostA += m_coeffFracBits.bits[ pqDataA.absLevel ];
-          else
-          {
-            const TCoeff value = ( pqDataA.absLevel - 4 ) >> 1;
-            rdCostA += m_coeffFracBits.bits[ pqDataA.absLevel - ( value << 1 ) ] + goRiceTab[ value < RICEMAX ? value : RICEMAX - 1 ];
-          }
-          if( pqDataB.absLevel < 4 )
-            rdCostB += m_coeffFracBits.bits[ pqDataB.absLevel ];
-          else
-          {
-            const TCoeff value = ( pqDataB.absLevel - 4 ) >> 1;
-            rdCostB += m_coeffFracBits.bits[ pqDataB.absLevel - ( value << 1 ) ] + goRiceTab[ value < RICEMAX ? value : RICEMAX - 1 ];
-          }
-          if( spt == SCAN_ISCSBB )
-          {
-            rdCostA += m_sigFracBits.intBits[ 1 ];
-            rdCostB += m_sigFracBits.intBits[ 1 ];
-            rdCostZ += m_sigFracBits.intBits[ 0 ];
-          }
-          else if( spt == SCAN_SOCSBB )
-          {
-            rdCostA += m_sbbFracBits.intBits[ 1 ] + m_sigFracBits.intBits[ 1 ];
-            rdCostB += m_sbbFracBits.intBits[ 1 ] + m_sigFracBits.intBits[ 1 ];
-            rdCostZ += m_sbbFracBits.intBits[ 1 ] + m_sigFracBits.intBits[ 0 ];
-          }
-          else if( m_numSigSbb )
-          {
-            rdCostA += m_sigFracBits.intBits[ 1 ];
-            rdCostB += m_sigFracBits.intBits[ 1 ];
-            rdCostZ += m_sigFracBits.intBits[ 0 ];
-          }
-          else
-          {
-            rdCostZ = decisionA.rdCost;
-          }
+          rdCostA += m_coeffFracBits.bits[pqDataA.absLevel];
+        }
+        else
+        {
+          const TCoeff value = (pqDataA.absLevel - 4) >> 1;
+          rdCostA +=
+            m_coeffFracBits.bits[pqDataA.absLevel - (value << 1)] + goRiceTab[value < RICEMAX ? value : RICEMAX - 1];
+        }
+        if (pqDataB.absLevel < 4)
+        {
+          rdCostB += m_coeffFracBits.bits[pqDataB.absLevel];
         }
         else
         {
-          rdCostA += ( 1 << SCALE_BITS ) + goRiceTab[ pqDataA.absLevel <= m_goRiceZero ? pqDataA.absLevel - 1 : ( pqDataA.absLevel < RICEMAX ? pqDataA.absLevel : RICEMAX - 1 ) ];
-          rdCostB += ( 1 << SCALE_BITS ) + goRiceTab[ pqDataB.absLevel <= m_goRiceZero ? pqDataB.absLevel - 1 : ( pqDataB.absLevel < RICEMAX ? pqDataB.absLevel : RICEMAX - 1 ) ];
-          rdCostZ += goRiceTab[ m_goRiceZero ];
+          const TCoeff value = (pqDataB.absLevel - 4) >> 1;
+          rdCostB +=
+            m_coeffFracBits.bits[pqDataB.absLevel - (value << 1)] + goRiceTab[value < RICEMAX ? value : RICEMAX - 1];
         }
-        if( rdCostA < decisionA.rdCost )
+        if (spt == SCAN_ISCSBB)
         {
-          decisionA.rdCost = rdCostA;
-          decisionA.absLevel = pqDataA.absLevel;
-          decisionA.prevId = m_stateId;
+          rdCostA += m_sigFracBits.intBits[1];
+          rdCostB += m_sigFracBits.intBits[1];
+          rdCostZ += m_sigFracBits.intBits[0];
         }
-        if( rdCostZ < decisionA.rdCost )
+        else if (spt == SCAN_SOCSBB)
         {
-          decisionA.rdCost = rdCostZ;
-          decisionA.absLevel = 0;
-          decisionA.prevId = m_stateId;
+          rdCostA += m_sbbFracBits.intBits[1] + m_sigFracBits.intBits[1];
+          rdCostB += m_sbbFracBits.intBits[1] + m_sigFracBits.intBits[1];
+          rdCostZ += m_sbbFracBits.intBits[1] + m_sigFracBits.intBits[0];
         }
-        if( rdCostB < decisionB.rdCost )
+        else if (m_numSigSbb)
         {
-          decisionB.rdCost = rdCostB;
-          decisionB.absLevel = pqDataB.absLevel;
-          decisionB.prevId = m_stateId;
+          rdCostA += m_sigFracBits.intBits[1];
+          rdCostB += m_sigFracBits.intBits[1];
+          rdCostZ += m_sigFracBits.intBits[0];
         }
+        else
+        {
+          rdCostZ = decisionA.rdCost;
+        }
+      }
+      else
+      {
+        rdCostA +=
+          (1 << SCALE_BITS)
+          + goRiceTab[pqDataA.absLevel <= m_goRiceZero ? pqDataA.absLevel - 1
+                                                       : (pqDataA.absLevel < RICEMAX ? pqDataA.absLevel : RICEMAX - 1)];
+        rdCostB +=
+          (1 << SCALE_BITS)
+          + goRiceTab[pqDataB.absLevel <= m_goRiceZero ? pqDataB.absLevel - 1
+                                                       : (pqDataB.absLevel < RICEMAX ? pqDataB.absLevel : RICEMAX - 1)];
+        rdCostZ += goRiceTab[m_goRiceZero];
       }
+      if (rdCostA < decisionA.rdCost)
+      {
+        decisionA.rdCost   = rdCostA;
+        decisionA.absLevel = pqDataA.absLevel;
+        decisionA.prevId   = m_stateId;
+      }
+      if (rdCostZ < decisionA.rdCost)
+      {
+        decisionA.rdCost   = rdCostZ;
+        decisionA.absLevel = 0;
+        decisionA.prevId   = m_stateId;
+      }
+      if (rdCostB < decisionB.rdCost)
+      {
+        decisionB.rdCost   = rdCostB;
+        decisionB.absLevel = pqDataB.absLevel;
+        decisionB.prevId   = m_stateId;
+      }
+    }
 
     inline void checkRdCostStart(int32_t lastOffset, const PQData &pqData, Decision &decision) const
     {
@@ -1004,6 +1057,31 @@ namespace DQIntern
     unsigned                  effHeight;
   };
 
+  unsigned templateAbsCompare(TCoeff sum)
+  {
+    int rangeIdx = 0;
+    if (sum < g_riceT[0])
+    {
+      rangeIdx = 0;
+    }
+    else if (sum < g_riceT[1])
+    {
+      rangeIdx = 1;
+    }
+    else if (sum < g_riceT[2])
+    {
+      rangeIdx = 2;
+    }
+    else if (sum < g_riceT[3])
+    {
+      rangeIdx = 3;
+    }
+    else
+    {
+      rangeIdx = 4;
+    }
+    return g_riceShift[rangeIdx];
+  }
 
   State::State( const RateEstimator& rateEst, CommonCtx& commonCtx, const int stateId )
     : m_sbbFracBits     { { 0, 0 } }
@@ -1015,7 +1093,7 @@ namespace DQIntern
   }
 
   template<uint8_t numIPos>
-  inline void State::updateState(const ScanInfo &scanInfo, const State *prevStates, const Decision &decision)
+  inline void State::updateState(const ScanInfo &scanInfo, const State *prevStates, const Decision &decision, const int baseLevel, const bool extRiceFlag)
   {
     m_rdCost = decision.rdCost;
     if( decision.prevId > -2 )
@@ -1120,8 +1198,19 @@ namespace DQIntern
           UPDATE(4);
         }
 #undef UPDATE
-        int sumAll = std::max(std::min(31, (int)sumAbs - 4 * 5), 0);
-        m_goRicePar = g_auiGoRiceParsCoeff[sumAll];
+        if (extRiceFlag)
+        {
+          unsigned currentShift = templateAbsCompare(sumAbs);
+          sumAbs = sumAbs >> currentShift;
+          int sumAll = std::max(std::min(31, (int)sumAbs - (int)baseLevel), 0);
+          m_goRicePar = g_goRiceParsCoeff[sumAll];
+          m_goRicePar += currentShift;
+        }
+        else
+        {
+          int sumAll = std::max(std::min(31, (int)sumAbs - 4 * 5), 0);
+          m_goRicePar = g_goRiceParsCoeff[sumAll];
+        }
       }
       else
       {
@@ -1158,9 +1247,20 @@ namespace DQIntern
           UPDATE(4);
         }
 #undef UPDATE
-        sumAbs = std::min<TCoeff>(31, sumAbs);
-        m_goRicePar = g_auiGoRiceParsCoeff[sumAbs];
-        m_goRiceZero = g_auiGoRicePosCoeff0(m_stateId, m_goRicePar);
+        if (extRiceFlag)
+        {
+          unsigned currentShift = templateAbsCompare(sumAbs);
+          sumAbs = sumAbs >> currentShift;
+          sumAbs = std::min<TCoeff>(31, sumAbs);
+          m_goRicePar = g_goRiceParsCoeff[sumAbs];
+          m_goRicePar += currentShift;
+        }
+        else
+        {
+          sumAbs = std::min<TCoeff>(31, sumAbs);
+          m_goRicePar = g_goRiceParsCoeff[sumAbs];
+        }
+        m_goRiceZero = g_goRicePosCoeff0(m_stateId, m_goRicePar);
       }
     }
   }
@@ -1290,8 +1390,15 @@ namespace DQIntern
     void    quant   ( TransformUnit& tu, const CCoeffBuf& srcCoeff, const ComponentID compID, const QpParam& cQP, const double lambda, const Ctx& ctx, TCoeff& absSum, bool enableScalingLists, int* quantCoeff );
     void    dequant ( const TransformUnit& tu, CoeffBuf& recCoeff, const ComponentID compID, const QpParam& cQP, bool enableScalingLists, int* quantCoeff );
 
+    int m_baseLevel;
+    bool m_extRiceRRCFlag;
+
   private:
+#if JVET_W0046_RLSCP
+    void    xDecideAndUpdate  ( const TCoeff absCoeff, const ScanInfo &scanInfo, bool zeroOut, TCoeff quantCoeff, int effWidth, int effHeight, bool reverseLast );
+#else
     void    xDecideAndUpdate  ( const TCoeff absCoeff, const ScanInfo& scanInfo, bool zeroOut, TCoeff quantCoeff);
+#endif
     void    xDecide           ( const ScanPosType spt, const TCoeff absCoeff, const int lastOffset, Decision* decisions, bool zeroOut, TCoeff quantCoeff );
 
   private:
@@ -1354,23 +1461,31 @@ namespace DQIntern
     m_prevStates[3].checkRdCosts( spt, pqData[3], pqData[1], decisions[3], decisions[1]);
     if( spt==SCAN_EOCSBB )
     {
-        m_skipStates[0].checkRdCostSkipSbb( decisions[0] );
-        m_skipStates[1].checkRdCostSkipSbb( decisions[1] );
-        m_skipStates[2].checkRdCostSkipSbb( decisions[2] );
-        m_skipStates[3].checkRdCostSkipSbb( decisions[3] );
+      m_skipStates[0].checkRdCostSkipSbb(decisions[0]);
+      m_skipStates[1].checkRdCostSkipSbb(decisions[1]);
+      m_skipStates[2].checkRdCostSkipSbb(decisions[2]);
+      m_skipStates[3].checkRdCostSkipSbb(decisions[3]);
     }
 
     m_startState.checkRdCostStart( lastOffset, pqData[0], decisions[0] );
     m_startState.checkRdCostStart( lastOffset, pqData[2], decisions[2] );
   }
 
+#if JVET_W0046_RLSCP
+  void DepQuant::xDecideAndUpdate( const TCoeff absCoeff, const ScanInfo &scanInfo, bool zeroOut, TCoeff quantCoeff, int effWidth, int effHeight, bool reverseLast )
+#else
   void DepQuant::xDecideAndUpdate( const TCoeff absCoeff, const ScanInfo& scanInfo, bool zeroOut, TCoeff quantCoeff )
+#endif
   {
     Decision* decisions = m_trellis[ scanInfo.scanIdx ];
 
     std::swap( m_prevStates, m_currStates );
 
+#if JVET_W0046_RLSCP
+    xDecide( scanInfo.spt, absCoeff, lastOffset(scanInfo.scanIdx, effWidth, effHeight, reverseLast), decisions, zeroOut, quantCoeff );
+#else
     xDecide( scanInfo.spt, absCoeff, lastOffset(scanInfo.scanIdx), decisions, zeroOut, quantCoeff );
+#endif
 
     if( scanInfo.scanIdx )
     {
@@ -1388,40 +1503,40 @@ namespace DQIntern
         switch( scanInfo.nextNbInfoSbb.num )
         {
         case 0:
-          m_currStates[0].updateState<0>( scanInfo, m_prevStates, decisions[0] );
-          m_currStates[1].updateState<0>( scanInfo, m_prevStates, decisions[1] );
-          m_currStates[2].updateState<0>( scanInfo, m_prevStates, decisions[2] );
-          m_currStates[3].updateState<0>( scanInfo, m_prevStates, decisions[3] );
+          m_currStates[0].updateState<0>(scanInfo, m_prevStates, decisions[0], m_baseLevel, m_extRiceRRCFlag);
+          m_currStates[1].updateState<0>(scanInfo, m_prevStates, decisions[1], m_baseLevel, m_extRiceRRCFlag);
+          m_currStates[2].updateState<0>(scanInfo, m_prevStates, decisions[2], m_baseLevel, m_extRiceRRCFlag);
+          m_currStates[3].updateState<0>(scanInfo, m_prevStates, decisions[3], m_baseLevel, m_extRiceRRCFlag);
           break;
         case 1:
-          m_currStates[0].updateState<1>( scanInfo, m_prevStates, decisions[0] );
-          m_currStates[1].updateState<1>( scanInfo, m_prevStates, decisions[1] );
-          m_currStates[2].updateState<1>( scanInfo, m_prevStates, decisions[2] );
-          m_currStates[3].updateState<1>( scanInfo, m_prevStates, decisions[3] );
+          m_currStates[0].updateState<1>(scanInfo, m_prevStates, decisions[0], m_baseLevel, m_extRiceRRCFlag);
+          m_currStates[1].updateState<1>(scanInfo, m_prevStates, decisions[1], m_baseLevel, m_extRiceRRCFlag);
+          m_currStates[2].updateState<1>(scanInfo, m_prevStates, decisions[2], m_baseLevel, m_extRiceRRCFlag);
+          m_currStates[3].updateState<1>(scanInfo, m_prevStates, decisions[3], m_baseLevel, m_extRiceRRCFlag);
           break;
         case 2:
-          m_currStates[0].updateState<2>( scanInfo, m_prevStates, decisions[0] );
-          m_currStates[1].updateState<2>( scanInfo, m_prevStates, decisions[1] );
-          m_currStates[2].updateState<2>( scanInfo, m_prevStates, decisions[2] );
-          m_currStates[3].updateState<2>( scanInfo, m_prevStates, decisions[3] );
+          m_currStates[0].updateState<2>(scanInfo, m_prevStates, decisions[0], m_baseLevel, m_extRiceRRCFlag);
+          m_currStates[1].updateState<2>(scanInfo, m_prevStates, decisions[1], m_baseLevel, m_extRiceRRCFlag);
+          m_currStates[2].updateState<2>(scanInfo, m_prevStates, decisions[2], m_baseLevel, m_extRiceRRCFlag);
+          m_currStates[3].updateState<2>(scanInfo, m_prevStates, decisions[3], m_baseLevel, m_extRiceRRCFlag);
           break;
         case 3:
-          m_currStates[0].updateState<3>( scanInfo, m_prevStates, decisions[0] );
-          m_currStates[1].updateState<3>( scanInfo, m_prevStates, decisions[1] );
-          m_currStates[2].updateState<3>( scanInfo, m_prevStates, decisions[2] );
-          m_currStates[3].updateState<3>( scanInfo, m_prevStates, decisions[3] );
+          m_currStates[0].updateState<3>(scanInfo, m_prevStates, decisions[0], m_baseLevel, m_extRiceRRCFlag);
+          m_currStates[1].updateState<3>(scanInfo, m_prevStates, decisions[1], m_baseLevel, m_extRiceRRCFlag);
+          m_currStates[2].updateState<3>(scanInfo, m_prevStates, decisions[2], m_baseLevel, m_extRiceRRCFlag);
+          m_currStates[3].updateState<3>(scanInfo, m_prevStates, decisions[3], m_baseLevel, m_extRiceRRCFlag);
           break;
         case 4:
-          m_currStates[0].updateState<4>( scanInfo, m_prevStates, decisions[0] );
-          m_currStates[1].updateState<4>( scanInfo, m_prevStates, decisions[1] );
-          m_currStates[2].updateState<4>( scanInfo, m_prevStates, decisions[2] );
-          m_currStates[3].updateState<4>( scanInfo, m_prevStates, decisions[3] );
+          m_currStates[0].updateState<4>(scanInfo, m_prevStates, decisions[0], m_baseLevel, m_extRiceRRCFlag);
+          m_currStates[1].updateState<4>(scanInfo, m_prevStates, decisions[1], m_baseLevel, m_extRiceRRCFlag);
+          m_currStates[2].updateState<4>(scanInfo, m_prevStates, decisions[2], m_baseLevel, m_extRiceRRCFlag);
+          m_currStates[3].updateState<4>(scanInfo, m_prevStates, decisions[3], m_baseLevel, m_extRiceRRCFlag);
           break;
         default:
-          m_currStates[0].updateState<5>( scanInfo, m_prevStates, decisions[0] );
-          m_currStates[1].updateState<5>( scanInfo, m_prevStates, decisions[1] );
-          m_currStates[2].updateState<5>( scanInfo, m_prevStates, decisions[2] );
-          m_currStates[3].updateState<5>( scanInfo, m_prevStates, decisions[3] );
+          m_currStates[0].updateState<5>(scanInfo, m_prevStates, decisions[0], m_baseLevel, m_extRiceRRCFlag);
+          m_currStates[1].updateState<5>(scanInfo, m_prevStates, decisions[1], m_baseLevel, m_extRiceRRCFlag);
+          m_currStates[2].updateState<5>(scanInfo, m_prevStates, decisions[2], m_baseLevel, m_extRiceRRCFlag);
+          m_currStates[3].updateState<5>(scanInfo, m_prevStates, decisions[3], m_baseLevel, m_extRiceRRCFlag);
         }
       }
 
@@ -1440,6 +1555,8 @@ namespace DQIntern
     //===== reset / pre-init =====
     const TUParameters& tuPars  = *g_Rom.getTUPars( tu.blocks[compID], compID );
     m_quant.initQuantBlock    ( tu, compID, cQP, lambda );
+    m_baseLevel = ctx.getBaseLevel();
+    m_extRiceRRCFlag = tu.cs->sps->getSpsRangeExtension().getRrcRiceExtensionEnableFlag();
     TCoeff*       qCoeff      = tu.getCoeffs( compID ).buf;
     const TCoeff* tCoeff      = srcCoeff.buf;
     const int     numCoeff    = tu.blocks[compID].area();
@@ -1478,7 +1595,9 @@ namespace DQIntern
     {
       if (zeroOutforThres && (tuPars.m_scanId2BlkPos[firstTestPos].x >= ((tuPars.m_width == 32 && zeroOut) ? 16 : 32)
                            || tuPars.m_scanId2BlkPos[firstTestPos].y >= ((tuPars.m_height == 32 && zeroOut) ? 16 : 32)))
+      {
         continue;
+      }
       TCoeff thresTmp = (enableScalingLists) ? TCoeff(thres / (4 * quantCoeff[tuPars.m_scanId2BlkPos[firstTestPos].idx]))
                                              : TCoeff(thres / (4 * defaultQuantisationCoefficient));
 
@@ -1519,10 +1638,20 @@ namespace DQIntern
       if (enableScalingLists)
       {
         m_quant.initQuantBlock(tu, compID, cQP, lambda, quantCoeff[scanInfo.rasterPos]);
+#if JVET_W0046_RLSCP
+        xDecideAndUpdate( abs( tCoeff[scanInfo.rasterPos]), scanInfo, (zeroOut && (scanInfo.posX >= effWidth || scanInfo.posY >= effHeight)), quantCoeff[scanInfo.rasterPos], effectWidth, effectHeight, tu.cu->slice->getReverseLastSigCoeffFlag() );
+#else
         xDecideAndUpdate( abs( tCoeff[scanInfo.rasterPos]), scanInfo, (zeroOut && (scanInfo.posX >= effWidth || scanInfo.posY >= effHeight)), quantCoeff[scanInfo.rasterPos] );
+#endif
       }
       else
+      {
+#if JVET_W0046_RLSCP
+        xDecideAndUpdate( abs( tCoeff[scanInfo.rasterPos]), scanInfo, (zeroOut && (scanInfo.posX >= effWidth || scanInfo.posY >= effHeight)), defaultQuantisationCoefficient, effectWidth, effectHeight, tu.cu->slice->getReverseLastSigCoeffFlag() );
+#else
         xDecideAndUpdate( abs( tCoeff[scanInfo.rasterPos]), scanInfo, (zeroOut && (scanInfo.posX >= effWidth || scanInfo.posY >= effHeight)), defaultQuantisationCoefficient );
+#endif
+      }
     }
 
     //===== find best path =====
diff --git a/source/Lib/CommonLib/DepQuant.h b/source/Lib/CommonLib/DepQuant.h
index eb2685a2e..12168a603 100644
--- a/source/Lib/CommonLib/DepQuant.h
+++ b/source/Lib/CommonLib/DepQuant.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/CommonLib/HRD.cpp b/source/Lib/CommonLib/HRD.cpp
index fcd707c06..b350e913b 100644
--- a/source/Lib/CommonLib/HRD.cpp
+++ b/source/Lib/CommonLib/HRD.cpp
@@ -3,7 +3,7 @@
 * and contributor rights, including patent rights, and no such rights are
 * granted under this license.
 *
-* Copyright (c) 2010-2020, ITU/ISO/IEC
+* Copyright (c) 2010-2021, ITU/ISO/IEC
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/CommonLib/HRD.h b/source/Lib/CommonLib/HRD.h
index 07305789f..2762958eb 100644
--- a/source/Lib/CommonLib/HRD.h
+++ b/source/Lib/CommonLib/HRD.h
@@ -3,7 +3,7 @@
 * and contributor rights, including patent rights, and no such rights are
 * granted under this license.
 *
-* Copyright (c) 2010-2020, ITU/ISO/IEC
+* Copyright (c) 2010-2021, ITU/ISO/IEC
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/CommonLib/Hash.cpp b/source/Lib/CommonLib/Hash.cpp
index a6e7844e9..67bcdc885 100644
--- a/source/Lib/CommonLib/Hash.cpp
+++ b/source/Lib/CommonLib/Hash.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -124,6 +124,7 @@ TComHash::~TComHash()
     m_lookupTable = NULL;
   }
 }
+
 void TComHash::create(int picWidth, int picHeight)
 {
   if (m_lookupTable)
@@ -502,6 +503,7 @@ bool TComHash::isBlock2x2ColSameValue(unsigned char* p, bool includeAllComponent
 
   return true;
 }
+
 bool TComHash::isHorizontalPerfectLuma(const Pel* srcPel, int stride, int width, int height)
 {
   for (int i = 0; i < height; i++)
@@ -532,6 +534,7 @@ bool TComHash::isVerticalPerfectLuma(const Pel* srcPel, int stride, int width, i
   }
   return true;
 }
+
 bool TComHash::getBlockHashValue(const PelUnitBuf &curPicBuf, int width, int height, int xStart, int yStart, const BitDepths bitDepths, uint32_t& hashValue1, uint32_t& hashValue2)
 {
   int addValue = m_blockSizeToIndex[width][height];
diff --git a/source/Lib/CommonLib/Hash.h b/source/Lib/CommonLib/Hash.h
index 2a47b0ffb..06686200a 100644
--- a/source/Lib/CommonLib/Hash.h
+++ b/source/Lib/CommonLib/Hash.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/CommonLib/IbcHashMap.cpp b/source/Lib/CommonLib/IbcHashMap.cpp
index 3b0b2d2f1..7c4cb01b6 100644
--- a/source/Lib/CommonLib/IbcHashMap.cpp
+++ b/source/Lib/CommonLib/IbcHashMap.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/CommonLib/IbcHashMap.h b/source/Lib/CommonLib/IbcHashMap.h
index bd90e10fd..f0ddbae6c 100644
--- a/source/Lib/CommonLib/IbcHashMap.h
+++ b/source/Lib/CommonLib/IbcHashMap.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/CommonLib/InterPrediction.cpp b/source/Lib/CommonLib/InterPrediction.cpp
index 5cfd46a0f..34adec56d 100644
--- a/source/Lib/CommonLib/InterPrediction.cpp
+++ b/source/Lib/CommonLib/InterPrediction.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -698,13 +698,22 @@ void InterPrediction::xPredInterBlk ( const ComponentID& compID, const Predictio
   }
   else
   {
-    int xFrac = mv.hor & ((1 << shiftHor) - 1);
-    int yFrac = mv.ver & ((1 << shiftVer) - 1);
+    int xFrac, yFrac;
     if (isIBC)
     {
       xFrac = yFrac = 0;
       JVET_J0090_SET_CACHE_ENABLE(false);
     }
+    else if (isLuma(compID))
+    {
+      xFrac = mv.hor & 15;
+      yFrac = mv.ver & 15;
+    }
+    else
+    {
+      xFrac = (mv.hor << (1 - ::getComponentScaleX(compID, chFmt))) & 31;
+      yFrac = (mv.ver << (1 - ::getComponentScaleY(compID, chFmt))) & 31;
+    }
 
     PelBuf & dstBuf = dstPic.bufs[compID];
     unsigned width  = dstBuf.width;
@@ -752,12 +761,12 @@ void InterPrediction::xPredInterBlk ( const ComponentID& compID, const Predictio
     if (yFrac == 0)
     {
       m_if.filterHor(compID, (Pel *) refBuf.buf, refBuf.stride, dstBuf.buf, dstBuf.stride, backupWidth, backupHeight,
-                     xFrac, rndRes, chFmt, clpRng, bilinearMC, bilinearMC, useAltHpelIf);
+                     xFrac, rndRes, clpRng, bilinearMC, bilinearMC, useAltHpelIf);
     }
     else if (xFrac == 0)
     {
       m_if.filterVer(compID, (Pel *) refBuf.buf, refBuf.stride, dstBuf.buf, dstBuf.stride, backupWidth, backupHeight,
-                     yFrac, true, rndRes, chFmt, clpRng, bilinearMC, bilinearMC, useAltHpelIf);
+                     yFrac, true, rndRes, clpRng, bilinearMC, bilinearMC, useAltHpelIf);
     }
     else
     {
@@ -774,12 +783,12 @@ void InterPrediction::xPredInterBlk ( const ComponentID& compID, const Predictio
         vFilterSize = NTAPS_BILINEAR;
       }
       m_if.filterHor(compID, (Pel *) refBuf.buf - ((vFilterSize >> 1) - 1) * refBuf.stride, refBuf.stride, tmpBuf.buf,
-                     tmpBuf.stride, backupWidth, backupHeight + vFilterSize - 1, xFrac, false, chFmt, clpRng,
-                     bilinearMC, bilinearMC, useAltHpelIf);
+                     tmpBuf.stride, backupWidth, backupHeight + vFilterSize - 1, xFrac, false, clpRng, bilinearMC,
+                     bilinearMC, useAltHpelIf);
       JVET_J0090_SET_CACHE_ENABLE(false);
       m_if.filterVer(compID, (Pel *) tmpBuf.buf + ((vFilterSize >> 1) - 1) * tmpBuf.stride, tmpBuf.stride, dstBuf.buf,
-                     dstBuf.stride, backupWidth, backupHeight, yFrac, false, rndRes, chFmt, clpRng, bilinearMC,
-                     bilinearMC, useAltHpelIf);
+                     dstBuf.stride, backupWidth, backupHeight, yFrac, false, rndRes, clpRng, bilinearMC, bilinearMC,
+                     useAltHpelIf);
     }
     JVET_J0090_SET_CACHE_ENABLE(
       (srcPadStride == 0)
@@ -869,7 +878,11 @@ bool InterPrediction::isSubblockVectorSpreadOverLimit( int a, int b, int c, int
   return false;
 }
 
+#if GDR_ENABLED
+bool InterPrediction::xPredAffineBlk(const ComponentID &compID, const PredictionUnit &pu, const Picture *refPic, const Mv *_mv, PelUnitBuf &dstPic, const bool &bi, const ClpRng &clpRng, bool genChromaMv, const std::pair<int, int> scalingRatio)
+#else
 void InterPrediction::xPredAffineBlk(const ComponentID &compID, const PredictionUnit &pu, const Picture *refPic, const Mv *_mv, PelUnitBuf &dstPic, const bool &bi, const ClpRng &clpRng, bool genChromaMv, const std::pair<int, int> scalingRatio)
+#endif
 {
 
   JVET_J0090_SET_REF_PICTURE( refPic, compID );
@@ -880,6 +893,13 @@ void InterPrediction::xPredAffineBlk(const ComponentID &compID, const Prediction
   Mv mvLT =_mv[0];
   Mv mvRT =_mv[1];
   Mv mvLB =_mv[2];
+#if GDR_ENABLED
+  bool allOk = true;
+  const CodingStructure &cs = *pu.cs;
+  const bool isEncodeGdrClean = cs.sps->getGDREnabledFlag() && cs.pcv->isEncoder && ((cs.picHeader->getInGdrInterval() && cs.isClean(pu.Y().topRight(), CHANNEL_TYPE_LUMA)) || (cs.picHeader->getNumVerVirtualBoundaries() == 0));
+  const int pux = pu.lx();
+  const int puy = pu.ly();
+#endif
 
   // get affine sub-block width and height
   const int width  = pu.Y().width;
@@ -1104,6 +1124,16 @@ void InterPrediction::xPredAffineBlk(const ComponentID &compID, const Prediction
             iMvScaleTmpVer = tmpMv.getVer();
           }
         }
+#if GDR_ENABLED
+        if (isEncodeGdrClean)
+        {
+          Position subPuPos = Position(pux + w + blockWidth, puy + h + blockHeight);
+          Mv subPuMv = Mv(iMvScaleTmpHor, iMvScaleTmpVer);
+          bool puClean = cs.isClean(subPuPos, subPuMv, refPic);
+
+          allOk = allOk && puClean;
+        }
+#endif
       }
       else
       {
@@ -1124,6 +1154,17 @@ void InterPrediction::xPredAffineBlk(const ComponentID &compID, const Prediction
         }
         iMvScaleTmpHor = curMv.hor;
         iMvScaleTmpVer = curMv.ver;
+
+#if GDR_ENABLED
+        if (isEncodeGdrClean)
+        {
+          Position subPuPos = Position(pux + (w + blockWidth) * 2, puy + (h + blockHeight) * 2);
+          Mv subPuMv = Mv(iMvScaleTmpHor, iMvScaleTmpVer);
+          bool puClean = cs.isClean(subPuPos, subPuMv, refPic);
+
+          allOk = allOk && puClean;
+        }
+#endif
       }
 
       if( xPredInterBlkRPR( scalingRatio, *pu.cs->pps, CompArea( compID, chFmt, pu.blocks[compID].offset( w, h ), Size( blockWidth, blockHeight ) ), refPic, Mv( iMvScaleTmpHor, iMvScaleTmpVer ), dstBuf.buf + w + h * dstBuf.stride, dstBuf.stride, bi, wrapRef, clpRng, 2 ) )
@@ -1135,25 +1176,19 @@ void InterPrediction::xPredAffineBlk(const ComponentID &compID, const Prediction
         // get the MV in high precision
         int xFrac, yFrac, xInt, yInt;
 
-        if (!iScaleX)
+        if (isLuma(compID))
         {
           xInt  = iMvScaleTmpHor >> 4;
           xFrac = iMvScaleTmpHor & 15;
-        }
-        else
-        {
-          xInt  = iMvScaleTmpHor >> 5;
-          xFrac = iMvScaleTmpHor & 31;
-        }
-        if (!iScaleY)
-        {
           yInt  = iMvScaleTmpVer >> 4;
           yFrac = iMvScaleTmpVer & 15;
         }
         else
         {
-          yInt  = iMvScaleTmpVer >> 5;
-          yFrac = iMvScaleTmpVer & 31;
+          xInt  = (iMvScaleTmpHor << (1 - iScaleX)) >> 5;
+          xFrac = (iMvScaleTmpHor << (1 - iScaleX)) & 31;
+          yInt  = (iMvScaleTmpVer << (1 - iScaleY)) >> 5;
+          yFrac = (iMvScaleTmpVer << (1 - iScaleY)) & 31;
         }
 
         const CPelBuf refBuf = refPic->getRecoBuf(
@@ -1176,19 +1211,19 @@ void InterPrediction::xPredAffineBlk(const ComponentID &compID, const Prediction
 
         if (yFrac == 0)
         {
-          m_if.filterHor(compID, (Pel *) ref, refStride, dst, dstStride, bw, bh, xFrac, isLast, chFmt, clpRng);
+          m_if.filterHor(compID, (Pel *) ref, refStride, dst, dstStride, bw, bh, xFrac, isLast, clpRng);
         }
         else if (xFrac == 0)
         {
-          m_if.filterVer(compID, (Pel *) ref, refStride, dst, dstStride, bw, bh, yFrac, true, isLast, chFmt, clpRng);
+          m_if.filterVer(compID, (Pel *) ref, refStride, dst, dstStride, bw, bh, yFrac, true, isLast, clpRng);
         }
         else
         {
           m_if.filterHor(compID, (Pel *) ref - ((vFilterSize >> 1) - 1) * refStride, refStride, tmpBuf.buf,
-                         tmpBuf.stride, bw, bh + vFilterSize - 1, xFrac, false, chFmt, clpRng);
+                         tmpBuf.stride, bw, bh + vFilterSize - 1, xFrac, false, clpRng);
           JVET_J0090_SET_CACHE_ENABLE(false);
           m_if.filterVer(compID, tmpBuf.buf + ((vFilterSize >> 1) - 1) * tmpBuf.stride, tmpBuf.stride, dst, dstStride,
-                         bw, bh, yFrac, false, isLast, chFmt, clpRng);
+                         bw, bh, yFrac, false, isLast, clpRng);
           JVET_J0090_SET_CACHE_ENABLE(true);
         }
         if (enablePROF)
@@ -1234,6 +1269,9 @@ void InterPrediction::xPredAffineBlk(const ComponentID &compID, const Prediction
       }
     }
   }
+#if GDR_ENABLED
+  return allOk;
+#endif
 }
 
 void InterPrediction::applyBiOptFlow(const PredictionUnit &pu, const CPelUnitBuf &yuvSrc0, const CPelUnitBuf &yuvSrc1, const int &refIdx0, const int &refIdx1, PelUnitBuf &yuvDst, const BitDepths &clipBitDepths)
@@ -2314,8 +2352,8 @@ bool InterPrediction::xPredInterBlkRPR( const std::pair<int, int>& scalingRatio,
   const ComponentID compID = blk.compID;
   const bool          rndRes = !bi;
 
-  int shiftHor = MV_FRACTIONAL_BITS_INTERNAL + ::getComponentScaleX( compID, chFmt );
-  int shiftVer = MV_FRACTIONAL_BITS_INTERNAL + ::getComponentScaleY( compID, chFmt );
+  int shiftHor = MV_FRACTIONAL_BITS_INTERNAL + (isLuma(compID) ? 0 : 1);
+  int shiftVer = MV_FRACTIONAL_BITS_INTERNAL + (isLuma(compID) ? 0 : 1);
 
   int width = blk.width;
   int height = blk.height;
@@ -2410,8 +2448,7 @@ bool InterPrediction::xPredInterBlkRPR( const std::pair<int, int>& scalingRatio,
 
     int addX = isLuma( compID ) ? 0 : int( 1 - refPic->cs->sps->getHorCollocatedChromaFlag() ) * 8 * ( scalingRatio.first - SCALE_1X.first );
     int addY = isLuma( compID ) ? 0 : int( 1 - refPic->cs->sps->getVerCollocatedChromaFlag() ) * 8 * ( scalingRatio.second - SCALE_1X.second );
-    
-#if FIX_SUBPICS_W_RPR
+
     int boundLeft   = 0;
     int boundRight  = refPicWidth >> ::getComponentScaleX( compID, chFmt );
     int boundTop    = 0;
@@ -2427,7 +2464,6 @@ bool InterPrediction::xPredInterBlkRPR( const std::pair<int, int>& scalingRatio,
         boundBottom = curSubPic.getSubPicBottom() >> ::getComponentScaleY( compID, chFmt );
       }
     }
-#endif
 
     x0Int = ( ( posX << ( 4 + ::getComponentScaleX( compID, chFmt ) ) ) + mv.getHor() ) * (int64_t)scalingRatio.first + addX;
     x0Int = SIGN( x0Int ) * ( ( llabs( x0Int ) + ( (long long)1 << ( 7 + ::getComponentScaleX( compID, chFmt ) ) ) ) >> ( 8 + ::getComponentScaleX( compID, chFmt ) ) ) + ( ( refPic->getScalingWindow().getWindowLeftOffset() * SPS::getWinUnitX( chFmt ) ) << ( ( posShift - ::getComponentScaleX( compID, chFmt ) ) ) );
@@ -2439,18 +2475,10 @@ bool InterPrediction::xPredInterBlkRPR( const std::pair<int, int>& scalingRatio,
     int vFilterSize = isLuma( compID ) ? NTAPS_LUMA : NTAPS_CHROMA;
 
     int yInt0 = ( (int32_t)y0Int + offY ) >> posShift;
-#if FIX_SUBPICS_W_RPR
     yInt0 = std::min( std::max( boundTop - (NTAPS_LUMA / 2), yInt0 ), boundBottom + (NTAPS_LUMA / 2) );
-#else
-    yInt0 = std::min( std::max( -(NTAPS_LUMA / 2), yInt0 ), ( refPicHeight >> ::getComponentScaleY( compID, chFmt ) ) + (NTAPS_LUMA / 2) );
-#endif
 
     int xInt0 = ( (int32_t)x0Int + offX ) >> posShift;
-#if FIX_SUBPICS_W_RPR
     xInt0 = std::min( std::max( boundLeft - (NTAPS_LUMA / 2), xInt0 ), boundRight + (NTAPS_LUMA / 2) );
-#else
-    xInt0 = std::min( std::max( -(NTAPS_LUMA / 2), xInt0 ), ( refPicWidth >> ::getComponentScaleX( compID, chFmt ) ) + (NTAPS_LUMA / 2) );
-#endif
 
     int refHeight = ((((int32_t)y0Int + (height-1) * stepY) + offY ) >> posShift) - ((((int32_t)y0Int + 0 * stepY) + offY ) >> posShift) + 1;
     refHeight = std::max<int>( 1, refHeight );
@@ -2465,11 +2493,7 @@ bool InterPrediction::xPredInterBlkRPR( const std::pair<int, int>& scalingRatio,
     {
       int posX = (int32_t)x0Int + col * stepX;
       xInt = ( posX + offX ) >> posShift;
-#if FIX_SUBPICS_W_RPR
       xInt = std::min( std::max( boundLeft - (NTAPS_LUMA / 2), xInt ), boundRight + (NTAPS_LUMA / 2) );
-#else
-      xInt = std::min( std::max( -(NTAPS_LUMA / 2), xInt ), ( refPicWidth >> ::getComponentScaleX( compID, chFmt ) ) + (NTAPS_LUMA / 2) );
-#endif
       int xFrac = ( ( posX + offX ) >> ( posShift - shiftHor ) ) & ( ( 1 << shiftHor ) - 1 );
 
       CHECK( xInt0 > xInt, "Wrong horizontal starting point" );
@@ -2478,18 +2502,16 @@ bool InterPrediction::xPredInterBlkRPR( const std::pair<int, int>& scalingRatio,
       refBuf = refPic->getRecoBuf( CompArea( compID, chFmt, offset, Size( 1, refHeight ) ), wrapRef );
       Pel* tempBuf = buffer + col;
 
-      m_if.filterHor( compID, (Pel*)refBuf.buf - ( ( vFilterSize >> 1 ) - 1 ) * refBuf.stride, refBuf.stride, tempBuf, tmpStride, 1, refHeight + vFilterSize - 1 + extSize, xFrac, false, chFmt, clpRng, xFilter, false, useAltHpelIf && scalingRatio.first == 1 << SCALE_RATIO_BITS );
+      m_if.filterHor(compID, (Pel *) refBuf.buf - ((vFilterSize >> 1) - 1) * refBuf.stride, refBuf.stride, tempBuf,
+                     tmpStride, 1, refHeight + vFilterSize - 1 + extSize, xFrac, false, clpRng, xFilter, false,
+                     useAltHpelIf && scalingRatio.first == 1 << SCALE_RATIO_BITS);
     }
 
     for( row = 0; row < height; row++ )
     {
       int posY = (int32_t)y0Int + row * stepY;
       yInt = ( posY + offY ) >> posShift;
-#if FIX_SUBPICS_W_RPR
       yInt = std::min( std::max( boundTop - (NTAPS_LUMA / 2), yInt ), boundBottom + (NTAPS_LUMA / 2) );
-#else
-      yInt = std::min( std::max( -(NTAPS_LUMA / 2), yInt ), ( refPicHeight >> ::getComponentScaleY( compID, chFmt ) ) + (NTAPS_LUMA / 2) );
-#endif
       int yFrac = ( ( posY + offY ) >> ( posShift - shiftVer ) ) & ( ( 1 << shiftVer ) - 1 );
 
       CHECK( yInt0 > yInt, "Wrong vertical starting point" );
@@ -2497,7 +2519,9 @@ bool InterPrediction::xPredInterBlkRPR( const std::pair<int, int>& scalingRatio,
       Pel* tempBuf = buffer + ( yInt - yInt0 ) * tmpStride;
 
       JVET_J0090_SET_CACHE_ENABLE( false );
-      m_if.filterVer( compID, tempBuf + ( ( vFilterSize >> 1 ) - 1 ) * tmpStride, tmpStride, dst + row * dstStride, dstStride, width, 1, yFrac, false, rndRes, chFmt, clpRng, yFilter, false, useAltHpelIf && scalingRatio.second == 1 << SCALE_RATIO_BITS );
+      m_if.filterVer(compID, tempBuf + ((vFilterSize >> 1) - 1) * tmpStride, tmpStride, dst + row * dstStride,
+                     dstStride, width, 1, yFrac, false, rndRes, clpRng, yFilter, false,
+                     useAltHpelIf && scalingRatio.second == 1 << SCALE_RATIO_BITS);
       JVET_J0090_SET_CACHE_ENABLE( true );
     }
   }
diff --git a/source/Lib/CommonLib/InterPrediction.h b/source/Lib/CommonLib/InterPrediction.h
index 6b67d430f..0c9a69509 100644
--- a/source/Lib/CommonLib/InterPrediction.h
+++ b/source/Lib/CommonLib/InterPrediction.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -137,7 +137,11 @@ protected:
   void xCalcBIOPar              (const Pel* srcY0Temp, const Pel* srcY1Temp, const Pel* gradX0, const Pel* gradX1, const Pel* gradY0, const Pel* gradY1, int* dotProductTemp1, int* dotProductTemp2, int* dotProductTemp3, int* dotProductTemp5, int* dotProductTemp6, const int src0Stride, const int src1Stride, const int gradStride, const int widthG, const int heightG, int bitDepth);
   void xCalcBlkGradient         (int sx, int sy, int    *arraysGx2, int     *arraysGxGy, int     *arraysGxdI, int     *arraysGy2, int     *arraysGydI, int     &sGx2, int     &sGy2, int     &sGxGy, int     &sGxdI, int     &sGydI, int width, int height, int unitSize);
   void xWeightedAverage         ( const PredictionUnit& pu, const CPelUnitBuf& pcYuvSrc0, const CPelUnitBuf& pcYuvSrc1, PelUnitBuf& pcYuvDst, const BitDepths& clipBitDepths, const ClpRngs& clpRngs, const bool& bioApplied, const bool lumaOnly = false, const bool chromaOnly = false, PelUnitBuf* yuvDstTmp = NULL );
+#if GDR_ENABLED
+  bool xPredAffineBlk           ( const ComponentID& compID, const PredictionUnit& pu, const Picture* refPic, const Mv* _mv, PelUnitBuf& dstPic, const bool& bi, const ClpRng& clpRng, const bool genChromaMv = false, const std::pair<int, int> scalingRatio = SCALE_1X );
+#else
   void xPredAffineBlk           ( const ComponentID& compID, const PredictionUnit& pu, const Picture* refPic, const Mv* _mv, PelUnitBuf& dstPic, const bool& bi, const ClpRng& clpRng, const bool genChromaMv = false, const std::pair<int, int> scalingRatio = SCALE_1X );
+#endif
 
   static bool xCheckIdenticalMotion( const PredictionUnit& pu );
 
diff --git a/source/Lib/CommonLib/InterpolationFilter.cpp b/source/Lib/CommonLib/InterpolationFilter.cpp
index cfbd190a0..eb79626c6 100644
--- a/source/Lib/CommonLib/InterpolationFilter.cpp
+++ b/source/Lib/CommonLib/InterpolationFilter.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -289,26 +289,6 @@ const TFilterCoeff InterpolationFilter::m_chromaFilterRPR2[CHROMA_INTERPOLATION_
   { -1, 18, 30, 17 }
 };
 
-const TFilterCoeff InterpolationFilter::m_bilinearFilter[LUMA_INTERPOLATION_FILTER_SUB_SAMPLE_POSITIONS][NTAPS_BILINEAR] =
-{
-  { 64,  0, },
-  { 60,  4, },
-  { 56,  8, },
-  { 52, 12, },
-  { 48, 16, },
-  { 44, 20, },
-  { 40, 24, },
-  { 36, 28, },
-  { 32, 32, },
-  { 28, 36, },
-  { 24, 40, },
-  { 20, 44, },
-  { 16, 48, },
-  { 12, 52, },
-  { 8, 56, },
-  { 4, 60, },
-};
-
 const TFilterCoeff InterpolationFilter::m_bilinearFilterPrec4[LUMA_INTERPOLATION_FILTER_SUB_SAMPLE_POSITIONS][NTAPS_BILINEAR] =
 {
   { 16,  0, },
@@ -733,10 +713,11 @@ void InterpolationFilter::filterVer(const ClpRng& clpRng, Pel const *src, int sr
  * \param  height     Height of block
  * \param  frac       Fractional sample offset
  * \param  isLast     Flag indicating whether it is the last filtering operation
- * \param  fmt        Chroma format
  * \param  bitDepth   Bit depth
  */
-void InterpolationFilter::filterHor(const ComponentID compID, Pel const *src, int srcStride, Pel *dst, int dstStride, int width, int height, int frac, bool isLast, const ChromaFormat fmt, const ClpRng& clpRng, int nFilterIdx, bool biMCForDMVR, bool useAltHpelIf)
+void InterpolationFilter::filterHor(const ComponentID compID, Pel const *src, int srcStride, Pel *dst, int dstStride,
+                                    int width, int height, int frac, bool isLast, const ClpRng &clpRng, int nFilterIdx,
+                                    bool biMCForDMVR, bool useAltHpelIf)
 {
   if( frac == 0 && nFilterIdx < 2 )
   {
@@ -784,19 +765,21 @@ void InterpolationFilter::filterHor(const ComponentID compID, Pel const *src, in
   }
   else
   {
-    const uint32_t csx = getComponentScaleX( compID, fmt );
-    CHECK( frac < 0 || csx >= 2 || ( frac << ( 1 - csx ) ) >= CHROMA_INTERPOLATION_FILTER_SUB_SAMPLE_POSITIONS, "Invalid fraction" );
+    CHECK(frac < 0 || frac >= CHROMA_INTERPOLATION_FILTER_SUB_SAMPLE_POSITIONS, "Invalid fraction");
     if( nFilterIdx == 3 )
     {
-      filterHor<NTAPS_CHROMA>( clpRng, src, srcStride, dst, dstStride, width, height, isLast, m_chromaFilterRPR1[frac << ( 1 - csx )], biMCForDMVR );
+      filterHor<NTAPS_CHROMA>(clpRng, src, srcStride, dst, dstStride, width, height, isLast, m_chromaFilterRPR1[frac],
+                              biMCForDMVR);
     }
     else if( nFilterIdx == 4 )
     {
-      filterHor<NTAPS_CHROMA>( clpRng, src, srcStride, dst, dstStride, width, height, isLast, m_chromaFilterRPR2[frac << ( 1 - csx )], biMCForDMVR );
+      filterHor<NTAPS_CHROMA>(clpRng, src, srcStride, dst, dstStride, width, height, isLast, m_chromaFilterRPR2[frac],
+                              biMCForDMVR);
     }
     else
     {
-      filterHor<NTAPS_CHROMA>( clpRng, src, srcStride, dst, dstStride, width, height, isLast, m_chromaFilter[frac << ( 1 - csx )], biMCForDMVR );
+      filterHor<NTAPS_CHROMA>(clpRng, src, srcStride, dst, dstStride, width, height, isLast, m_chromaFilter[frac],
+                              biMCForDMVR);
     }
   }
 }
@@ -815,10 +798,11 @@ void InterpolationFilter::filterHor(const ComponentID compID, Pel const *src, in
  * \param  frac       Fractional sample offset
  * \param  isFirst    Flag indicating whether it is the first filtering operation
  * \param  isLast     Flag indicating whether it is the last filtering operation
- * \param  fmt        Chroma format
  * \param  bitDepth   Bit depth
  */
-void InterpolationFilter::filterVer(const ComponentID compID, Pel const *src, int srcStride, Pel *dst, int dstStride, int width, int height, int frac, bool isFirst, bool isLast, const ChromaFormat fmt, const ClpRng& clpRng, int nFilterIdx, bool biMCForDMVR, bool useAltHpelIf)
+void InterpolationFilter::filterVer(const ComponentID compID, Pel const *src, int srcStride, Pel *dst, int dstStride,
+                                    int width, int height, int frac, bool isFirst, bool isLast, const ClpRng &clpRng,
+                                    int nFilterIdx, bool biMCForDMVR, bool useAltHpelIf)
 {
   if( frac == 0 && nFilterIdx < 2 )
   {
@@ -866,19 +850,21 @@ void InterpolationFilter::filterVer(const ComponentID compID, Pel const *src, in
   }
   else
   {
-    const uint32_t csy = getComponentScaleY( compID, fmt );
-    CHECK( frac < 0 || csy >= 2 || ( frac << ( 1 - csy ) ) >= CHROMA_INTERPOLATION_FILTER_SUB_SAMPLE_POSITIONS, "Invalid fraction" );
+    CHECK(frac < 0 || frac >= CHROMA_INTERPOLATION_FILTER_SUB_SAMPLE_POSITIONS, "Invalid fraction");
     if( nFilterIdx == 3 )
     {
-      filterVer<NTAPS_CHROMA>( clpRng, src, srcStride, dst, dstStride, width, height, isFirst, isLast, m_chromaFilterRPR1[frac << ( 1 - csy )], biMCForDMVR );
+      filterVer<NTAPS_CHROMA>(clpRng, src, srcStride, dst, dstStride, width, height, isFirst, isLast,
+                              m_chromaFilterRPR1[frac], biMCForDMVR);
     }
     else if( nFilterIdx == 4 )
     {
-      filterVer<NTAPS_CHROMA>( clpRng, src, srcStride, dst, dstStride, width, height, isFirst, isLast, m_chromaFilterRPR2[frac << ( 1 - csy )], biMCForDMVR );
+      filterVer<NTAPS_CHROMA>(clpRng, src, srcStride, dst, dstStride, width, height, isFirst, isLast,
+                              m_chromaFilterRPR2[frac], biMCForDMVR);
     }
     else
     {
-      filterVer<NTAPS_CHROMA>( clpRng, src, srcStride, dst, dstStride, width, height, isFirst, isLast, m_chromaFilter[frac << ( 1 - csy )], biMCForDMVR );
+      filterVer<NTAPS_CHROMA>(clpRng, src, srcStride, dst, dstStride, width, height, isFirst, isLast,
+                              m_chromaFilter[frac], biMCForDMVR);
     }
   }
 }
diff --git a/source/Lib/CommonLib/InterpolationFilter.h b/source/Lib/CommonLib/InterpolationFilter.h
index 278e7cf87..373bc1cbb 100644
--- a/source/Lib/CommonLib/InterpolationFilter.h
+++ b/source/Lib/CommonLib/InterpolationFilter.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -68,7 +68,6 @@ public:
   static const TFilterCoeff m_affineLumaFilterRPR2[LUMA_INTERPOLATION_FILTER_SUB_SAMPLE_POSITIONS][NTAPS_LUMA]; ///< Luma filter taps 2x
 private:
   static const TFilterCoeff m_lumaAltHpelIFilter[NTAPS_LUMA]; ///< Luma filter taps
-  static const TFilterCoeff m_bilinearFilter[LUMA_INTERPOLATION_FILTER_SUB_SAMPLE_POSITIONS][NTAPS_BILINEAR]; ///< bilinear filter taps
   static const TFilterCoeff m_bilinearFilterPrec4[LUMA_INTERPOLATION_FILTER_SUB_SAMPLE_POSITIONS][NTAPS_BILINEAR]; ///< bilinear filter taps
 public:
   template<bool isFirst, bool isLast>
@@ -102,8 +101,12 @@ public:
   template <X86_VEXT vext>
   void _initInterpolationFilterX86();
 #endif
-  void filterHor(const ComponentID compID, Pel const* src, int srcStride, Pel *dst, int dstStride, int width, int height, int frac,               bool isLast, const ChromaFormat fmt, const ClpRng& clpRng, int nFilterIdx = 0, bool biMCForDMVR = false, bool useAltHpelIf = false);
-  void filterVer(const ComponentID compID, Pel const* src, int srcStride, Pel *dst, int dstStride, int width, int height, int frac, bool isFirst, bool isLast, const ChromaFormat fmt, const ClpRng& clpRng, int nFilterIdx = 0, bool biMCForDMVR = false, bool useAltHpelIf = false);
+  void filterHor(const ComponentID compID, Pel const *src, int srcStride, Pel *dst, int dstStride, int width,
+                 int height, int frac, bool isLast, const ClpRng &clpRng, int nFilterIdx = 0, bool biMCForDMVR = false,
+                 bool useAltHpelIf = false);
+  void filterVer(const ComponentID compID, Pel const *src, int srcStride, Pel *dst, int dstStride, int width,
+                 int height, int frac, bool isFirst, bool isLast, const ClpRng &clpRng, int nFilterIdx = 0,
+                 bool biMCForDMVR = false, bool useAltHpelIf = false);
 #if JVET_J0090_MEMORY_BANDWITH_MEASURE
   void cacheAssign( CacheModel *cache ) { m_cacheModel = cache; }
 #endif
diff --git a/source/Lib/CommonLib/IntraPrediction.cpp b/source/Lib/CommonLib/IntraPrediction.cpp
index c70917b88..9a1670748 100644
--- a/source/Lib/CommonLib/IntraPrediction.cpp
+++ b/source/Lib/CommonLib/IntraPrediction.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -182,7 +182,7 @@ Pel IntraPrediction::xGetPredValDc( const CPelBuf &pSrc, const Size &dstSize )
 
 int IntraPrediction::getModifiedWideAngle( int width, int height, int predMode )
 {
-  //The function returns a 'modified' wide angle index, given that it is not necessary 
+  //The function returns a 'modified' wide angle index, given that it is not necessary
   //in this software implementation to reserve the values 0 and 1 for Planar and DC to generate the prediction signal.
   //It should only be used to obtain the intraPredAngle parameter.
   //To simply obtain the wide angle index, the function PU::getWideAngle should be used instead.
@@ -196,7 +196,7 @@ int IntraPrediction::getModifiedWideAngle( int width, int height, int predMode )
     }
     else if (height > width && predMode > VDIA_IDX - modeShift[deltaSize])
     {
-      predMode -= (VDIA_IDX - 1); 
+      predMode -= (VDIA_IDX - 1);
     }
   }
   return predMode;
diff --git a/source/Lib/CommonLib/IntraPrediction.h b/source/Lib/CommonLib/IntraPrediction.h
index ff4c6d12e..8f5d504d5 100644
--- a/source/Lib/CommonLib/IntraPrediction.h
+++ b/source/Lib/CommonLib/IntraPrediction.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/CommonLib/MCTS.cpp b/source/Lib/CommonLib/MCTS.cpp
index b0795736d..1690bd4bd 100644
--- a/source/Lib/CommonLib/MCTS.cpp
+++ b/source/Lib/CommonLib/MCTS.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/CommonLib/MCTS.h b/source/Lib/CommonLib/MCTS.h
index 3d9d3bf52..315e8dad9 100644
--- a/source/Lib/CommonLib/MCTS.h
+++ b/source/Lib/CommonLib/MCTS.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/CommonLib/MatrixIntraPrediction.cpp b/source/Lib/CommonLib/MatrixIntraPrediction.cpp
index b8296b1bd..62ac70505 100644
--- a/source/Lib/CommonLib/MatrixIntraPrediction.cpp
+++ b/source/Lib/CommonLib/MatrixIntraPrediction.cpp
@@ -3,7 +3,7 @@
 * and contributor rights, including patent rights, and no such rights are
 * granted under this license.
 *
-* Copyright (c) 2010-2020, ITU/ISO/IEC
+* Copyright (c) 2010-2021, ITU/ISO/IEC
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/CommonLib/MatrixIntraPrediction.h b/source/Lib/CommonLib/MatrixIntraPrediction.h
index 4bbd750d3..67f6c5fd3 100644
--- a/source/Lib/CommonLib/MatrixIntraPrediction.h
+++ b/source/Lib/CommonLib/MatrixIntraPrediction.h
@@ -1,9 +1,9 @@
-/* The copyright in this software is being made available under the BSD
+/* The copyright in this software is being made available under the BSD
 * License, included below. This software may be subject to other third party
 * and contributor rights, including patent rights, and no such rights are
 * granted under this license.
 *
-* Copyright (c) 2010-2020, ITU/ISO/IEC
+* Copyright (c) 2010-2021, ITU/ISO/IEC
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/CommonLib/MipData.h b/source/Lib/CommonLib/MipData.h
index bc7ea3e62..bc8cf49af 100644
--- a/source/Lib/CommonLib/MipData.h
+++ b/source/Lib/CommonLib/MipData.h
@@ -1,9 +1,9 @@
-/* The copyright in this software is being made available under the BSD
+/* The copyright in this software is being made available under the BSD
 * License, included below. This software may be subject to other third party
 * and contributor rights, including patent rights, and no such rights are
 * granted under this license.
 *
-* Copyright (c) 2010-2020, ITU/ISO/IEC
+* Copyright (c) 2010-2021, ITU/ISO/IEC
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/CommonLib/MotionInfo.h b/source/Lib/CommonLib/MotionInfo.h
index 20059c29c..5a9d76e9f 100644
--- a/source/Lib/CommonLib/MotionInfo.h
+++ b/source/Lib/CommonLib/MotionInfo.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -48,12 +48,43 @@
 // ====================================================================================================================
 // Type definition
 // ====================================================================================================================
+#if GDR_ENABLED
+enum MvpType
+{
+  MVP_LEFT,
+  MVP_ABOVE,
+  MVP_ABOVE_RIGHT,
+  MVP_BELOW_LEFT,
+  MVP_ABOVE_LEFT,
+
+  MVP_BELOW_RIGHT,
+  MVP_COMPOSITE,
+
+  MVP_TMVP_C0,
+  MVP_TMVP_C1,
+  MVP_HMVP,
+  MVP_ZERO,
+
+  AFFINE_INHERIT,
+  AFFINE_INHERIT_LB_RB,
+
+  NUM_MVPTYPES
+};
+#endif
 
 /// parameters for AMVP
 struct AMVPInfo
 {
   Mv       mvCand[ AMVP_MAX_NUM_CANDS_MEM ];  ///< array of motion vector predictor candidates
   unsigned numCand;                       ///< number of motion vector predictor candidates
+#if GDR_ENABLED
+  bool     allCandSolidInAbove;
+  bool     mvSolid[AMVP_MAX_NUM_CANDS_MEM];
+  bool     mvValid[AMVP_MAX_NUM_CANDS_MEM];
+
+  Position mvPos[AMVP_MAX_NUM_CANDS_MEM];
+  MvpType  mvType[AMVP_MAX_NUM_CANDS_MEM];
+#endif
 };
 
 struct AffineAMVPInfo
@@ -62,6 +93,25 @@ struct AffineAMVPInfo
   Mv       mvCandRT[ AMVP_MAX_NUM_CANDS_MEM ];  ///< array of affine motion vector predictor candidates for right-top corner
   Mv       mvCandLB[ AMVP_MAX_NUM_CANDS_MEM ];  ///< array of affine motion vector predictor candidates for left-bottom corner
   unsigned numCand;                       ///< number of motion vector predictor candidates
+#if GDR_ENABLED
+  bool     allCandSolidInAbove;  
+
+  bool     mvSolidLT[AMVP_MAX_NUM_CANDS_MEM];
+  bool     mvSolidRT[AMVP_MAX_NUM_CANDS_MEM];
+  bool     mvSolidLB[AMVP_MAX_NUM_CANDS_MEM];
+
+  bool     mvValidLT[AMVP_MAX_NUM_CANDS_MEM];
+  bool     mvValidRT[AMVP_MAX_NUM_CANDS_MEM];
+  bool     mvValidLB[AMVP_MAX_NUM_CANDS_MEM];
+
+  MvpType  mvTypeLT[AMVP_MAX_NUM_CANDS_MEM];
+  MvpType  mvTypeRT[AMVP_MAX_NUM_CANDS_MEM];
+  MvpType  mvTypeLB[AMVP_MAX_NUM_CANDS_MEM];
+  
+  Position mvPosLT[AMVP_MAX_NUM_CANDS_MEM];
+  Position mvPosRT[AMVP_MAX_NUM_CANDS_MEM];
+  Position mvPosLB[AMVP_MAX_NUM_CANDS_MEM];
+#endif
 };
 
 // ====================================================================================================================
@@ -109,6 +159,11 @@ struct MotionInfo
   int16_t   refIdx [ NUM_REF_PIC_LIST_01 ];
   uint8_t         BcwIdx;
   Mv      bv;
+#if GDR_ENABLED
+  bool      sourceClean;  // source Position is clean/dirty
+  Position  sourcePos;    // source Position of Mv
+#endif
+
   MotionInfo() : isInter(false), isIBCmot(false), interDir(0), useAltHpelIf(false), sliceIdx(0), refIdx{ NOT_VALID, NOT_VALID }, BcwIdx(0) { }
   // ensure that MotionInfo(0) produces '\x000....' bit pattern - needed to work with AreaBuf - don't use this constructor for anything else
   MotionInfo(int i) : isInter(i != 0), isIBCmot(false), interDir(0), useAltHpelIf(false), sliceIdx(0), refIdx{ 0,         0 }, BcwIdx(0) { CHECKD(i != 0, "The argument for this constructor has to be '0'"); }
@@ -149,12 +204,20 @@ class BcwMotionParam
   bool       m_readOnly[2][33];       // 2 RefLists, 33 RefFrams
   Mv         m_mv[2][33];
   Distortion m_dist[2][33];
+  
+#if GDR_ENABLED
+  bool       m_mvSolid[2][33];
+#endif
 
   bool       m_readOnlyAffine[2][2][33];
   Mv         m_mvAffine[2][2][33][3];
   Distortion m_distAffine[2][2][33];
   int        m_mvpIdx[2][2][33];
 
+#if GDR_ENABLED
+  bool       m_mvAffineSolid[2][2][33][3];
+#endif
+
 public:
 
   void reset()
@@ -176,6 +239,14 @@ public:
     memset(m_readOnlyAffine, false, 2 * 2 * 33 * sizeof(bool));
     memset(m_distAffine, -1, 2 * 2 * 33 * sizeof(Distortion));
     memset( m_mvpIdx, 0, 2 * 2 * 33 * sizeof( int ) );
+
+#if GDR_ENABLED
+    memset(m_mvSolid, true, 2 * 2 * 33 * sizeof(bool));
+#endif
+
+#if GDR_ENABLED
+    memset(m_mvAffineSolid, true, 2 * 2 * 33 * sizeof(bool));
+#endif
   }
 
   void setReadMode(bool b, uint32_t uiRefList, uint32_t uiRefIdx) { m_readOnly[uiRefList][uiRefIdx] = b; }
@@ -192,12 +263,30 @@ public:
     m_dist[uiRefList][uiRefIdx] = uiDist;
   }
 
+#if GDR_ENABLED
+  void copyFrom(Mv& rcMv, bool& rcMvSolid, Distortion uiDist, uint32_t uiRefList, uint32_t uiRefIdx)
+  {
+    m_mv[uiRefList][uiRefIdx] = rcMv;
+    m_dist[uiRefList][uiRefIdx] = uiDist;
+    m_mvSolid[uiRefList][uiRefIdx] = rcMvSolid;
+  }
+#endif
+
   void copyTo(Mv& rcMv, Distortion& ruiDist, uint32_t uiRefList, uint32_t uiRefIdx)
   {
     rcMv = m_mv[uiRefList][uiRefIdx];
     ruiDist = m_dist[uiRefList][uiRefIdx];
   }
 
+#if GDR_ENABLED
+  void copyTo(Mv& rcMv, bool& rcMvSolid, Distortion& ruiDist, uint32_t uiRefList, uint32_t uiRefIdx)
+  {
+    rcMv      = m_mv[uiRefList][uiRefIdx];
+    ruiDist   = m_dist[uiRefList][uiRefIdx];
+    rcMvSolid = m_mvSolid[uiRefList][uiRefIdx];
+  }
+#endif
+
   Mv& getAffineMv(uint32_t uiRefList, uint32_t uiRefIdx, uint32_t uiAffineMvIdx, int bP4) { return m_mvAffine[bP4][uiRefList][uiRefIdx][uiAffineMvIdx]; }
 
   void copyAffineMvFrom(Mv(&racAffineMvs)[3], Distortion uiDist, uint32_t uiRefList, uint32_t uiRefIdx, int bP4
@@ -217,6 +306,26 @@ public:
     ruiDist = m_distAffine[bP4][uiRefList][uiRefIdx];
     mvpIdx  = m_mvpIdx[bP4][uiRefList][uiRefIdx];
   }
+
+#if GDR_ENABLED
+  void copyAffineMvFrom(Mv(&racAffineMvs)[3], bool(&racAffineMvsSolid)[3], Distortion uiDist, uint32_t uiRefList, uint32_t uiRefIdx, int bP4, const int mvpIdx)
+  {
+    memcpy(m_mvAffine[bP4][uiRefList][uiRefIdx],      racAffineMvs,      3 * sizeof(Mv));
+    memcpy(m_mvAffineSolid[bP4][uiRefList][uiRefIdx], racAffineMvsSolid, 3 * sizeof(bool));
+    m_distAffine[bP4][uiRefList][uiRefIdx] = uiDist;
+    m_mvpIdx[bP4][uiRefList][uiRefIdx]     = mvpIdx;
+  }
+#endif
+
+#if GDR_ENABLED
+  void copyAffineMvTo(Mv acAffineMvs[3], bool acAffineMvsSolid[3], Distortion& ruiDist, uint32_t uiRefList, uint32_t uiRefIdx, int bP4, int& mvpIdx)
+  {
+    memcpy(acAffineMvs,      m_mvAffine[bP4][uiRefList][uiRefIdx],      3 * sizeof(Mv));
+    memcpy(acAffineMvsSolid, m_mvAffineSolid[bP4][uiRefList][uiRefIdx], 3 * sizeof(bool));
+    ruiDist = m_distAffine[bP4][uiRefList][uiRefIdx];
+    mvpIdx  = m_mvpIdx[bP4][uiRefList][uiRefIdx];
+  }
+#endif
 };
 struct LutMotionCand
 {
diff --git a/source/Lib/CommonLib/Mv.cpp b/source/Lib/CommonLib/Mv.cpp
index 105886297..4aa433be2 100644
--- a/source/Lib/CommonLib/Mv.cpp
+++ b/source/Lib/CommonLib/Mv.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/CommonLib/Mv.h b/source/Lib/CommonLib/Mv.h
index 6ac57e1a9..7c8e71ac5 100644
--- a/source/Lib/CommonLib/Mv.h
+++ b/source/Lib/CommonLib/Mv.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/CommonLib/NAL.h b/source/Lib/CommonLib/NAL.h
index 19585c748..ec10c28fc 100644
--- a/source/Lib/CommonLib/NAL.h
+++ b/source/Lib/CommonLib/NAL.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/CommonLib/ParameterSetManager.cpp b/source/Lib/CommonLib/ParameterSetManager.cpp
index 5fb051c6b..49975baf0 100644
--- a/source/Lib/CommonLib/ParameterSetManager.cpp
+++ b/source/Lib/CommonLib/ParameterSetManager.cpp
@@ -3,7 +3,7 @@
 * and contributor rights, including patent rights, and no such rights are
 * granted under this license.
 *
-* Copyright (c) 2010-2020, ITU/ISO/IEC
+* Copyright (c) 2010-2021, ITU/ISO/IEC
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/CommonLib/ParameterSetManager.h b/source/Lib/CommonLib/ParameterSetManager.h
index 6f3a0b615..47e863d6f 100644
--- a/source/Lib/CommonLib/ParameterSetManager.h
+++ b/source/Lib/CommonLib/ParameterSetManager.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -162,7 +162,7 @@ public:
       }
       else
       {
-        CHECK( true, "Wrong APS type" );
+        THROW("Wrong APS type");
       }
     }
     else
diff --git a/source/Lib/CommonLib/PicYuvMD5.cpp b/source/Lib/CommonLib/PicYuvMD5.cpp
index 8c13bd7bc..a15f81ac5 100644
--- a/source/Lib/CommonLib/PicYuvMD5.cpp
+++ b/source/Lib/CommonLib/PicYuvMD5.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -253,9 +253,7 @@ int calcAndPrintHashStatus(const CPelUnitBuf& pic, const SEIDecodedPictureHash*
 
   if (pictureHashSEI)
   {
-#if FIX_TICKET_1405
     CHECK ((uint32_t)pic.bufs.size() != ( pictureHashSEI->singleCompFlag ? 1 : 3 ), "The value of dph_sei_single_component_flag shall be equal to (ChromaFormatIdc == 0).");
-#endif
     switch (pictureHashSEI->method)
     {
       case HASHTYPE_MD5:
diff --git a/source/Lib/CommonLib/Picture.cpp b/source/Lib/CommonLib/Picture.cpp
index a7205badc..675e817aa 100644
--- a/source/Lib/CommonLib/Picture.cpp
+++ b/source/Lib/CommonLib/Picture.cpp
@@ -3,7 +3,7 @@
 * and contributor rights, including patent rights, and no such rights are
 * granted under this license.
 *
-* Copyright (c) 2010-2020, ITU/ISO/IEC
+* Copyright (c) 2010-2021, ITU/ISO/IEC
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
@@ -40,130 +40,6 @@
 #include "ChromaFormat.h"
 #include "CommonLib/InterpolationFilter.h"
 
-
-#if ENABLE_SPLIT_PARALLELISM
-
-int g_wppThreadId( 0 );
-#pragma omp threadprivate(g_wppThreadId)
-
-#if ENABLE_SPLIT_PARALLELISM
-int g_splitThreadId( 0 );
-#pragma omp threadprivate(g_splitThreadId)
-
-int g_splitJobId( 0 );
-#pragma omp threadprivate(g_splitJobId)
-#endif
-
-Scheduler::Scheduler() :
-#if ENABLE_SPLIT_PARALLELISM
-  m_numSplitThreads( 1 )
-#endif
-{
-}
-
-Scheduler::~Scheduler()
-{
-}
-
-#if ENABLE_SPLIT_PARALLELISM
-unsigned Scheduler::getSplitDataId( int jobId ) const
-{
-  if( m_numSplitThreads > 1 && m_hasParallelBuffer )
-  {
-    int splitJobId = jobId == CURR_THREAD_ID ? g_splitJobId : jobId;
-
-    return ( g_wppThreadId * NUM_RESERVERD_SPLIT_JOBS ) + splitJobId;
-  }
-  else
-  {
-    return 0;
-  }
-}
-
-unsigned Scheduler::getSplitPicId( int tId /*= CURR_THREAD_ID */ ) const
-{
-  if( m_numSplitThreads > 1 && m_hasParallelBuffer )
-  {
-    int threadId = tId == CURR_THREAD_ID ? g_splitThreadId : tId;
-
-    return ( g_wppThreadId * m_numSplitThreads ) + threadId;
-  }
-  else
-  {
-    return 0;
-  }
-}
-
-unsigned Scheduler::getSplitJobId() const
-{
-  if( m_numSplitThreads > 1 )
-  {
-    return g_splitJobId;
-  }
-  else
-  {
-    return 0;
-  }
-}
-
-void Scheduler::setSplitJobId( const int jobId )
-{
-  CHECK( g_splitJobId != 0 && jobId != 0, "Need to reset the jobId after usage!" );
-  g_splitJobId = jobId;
-}
-
-void Scheduler::startParallel()
-{
-  m_hasParallelBuffer = true;
-}
-
-void Scheduler::finishParallel()
-{
-  m_hasParallelBuffer = false;
-}
-
-void Scheduler::setSplitThreadId( const int tId )
-{
-  g_splitThreadId = tId == CURR_THREAD_ID ? omp_get_thread_num() : tId;
-}
-
-#endif
-
-
-
-unsigned Scheduler::getDataId() const
-{
-#if ENABLE_SPLIT_PARALLELISM
-  if( m_numSplitThreads > 1 )
-  {
-    return getSplitDataId();
-  }
-#endif
-  return 0;
-}
-
-bool Scheduler::init( const int ctuYsize, const int ctuXsize, const int numWppThreadsRunning, const int numWppExtraLines, const int numSplitThreads )
-{
-#if ENABLE_SPLIT_PARALLELISM
-  m_numSplitThreads = numSplitThreads;
-#endif
-
-  return true;
-}
-
-
-int Scheduler::getNumPicInstances() const
-{
-#if !ENABLE_SPLIT_PARALLELISM
-  return 1;
-#else
-  return ( m_numSplitThreads > 1 ? m_numSplitThreads : 1 );
-#endif
-}
-
-#endif
-
-
 // ---------------------------------------------------------------------------
 // picture methods
 // ---------------------------------------------------------------------------
@@ -186,6 +62,8 @@ Picture::Picture()
   fieldPic             = false;
   topField             = false;
   precedingDRAP        = false;
+  edrapRapId           = -1;
+  m_colourTranfParams  = NULL;
   nonReferencePictureFlag = false;
 
   for( int i = 0; i < MAX_NUM_CHANNEL_TYPE; i++ )
@@ -225,40 +103,43 @@ void Picture::create( const ChromaFormat &_chromaFormat, const Size &size, const
 
 void Picture::destroy()
 {
-#if ENABLE_SPLIT_PARALLELISM
-  for( int jId = 0; jId < PARL_SPLIT_MAX_NUM_THREADS; jId++ )
-#endif
+  for (uint32_t t = 0; t < NUM_PIC_TYPES; t++)
   {
-    for (uint32_t t = 0; t < NUM_PIC_TYPES; t++)
-    {
-      M_BUFS(jId, t).destroy();
-    }
-    m_hashMap.clearAll();
-    if (cs)
+    M_BUFS(jId, t).destroy();
+  }
+  m_hashMap.clearAll();
+  if (cs)
+  {
+#if GDR_ENABLED
+    if (cs->picHeader)
     {
-      cs->destroy();
-      delete cs;
-      cs = nullptr;
+      delete cs->picHeader;
     }
+    cs->picHeader = nullptr;
+#endif
+    cs->destroy();
+    delete cs;
+    cs = nullptr;
+  }
 
-    for (auto &ps: slices)
-    {
-      delete ps;
-    }
-    slices.clear();
+  for (auto &ps: slices)
+  {
+    delete ps;
+  }
+  slices.clear();
 
-    for (auto &psei: SEIs)
-    {
-      delete psei;
-    }
-    SEIs.clear();
+  for (auto &psei: SEIs)
+  {
+    delete psei;
+  }
+  SEIs.clear();
 
-    if (m_spliceIdx)
-    {
-      delete[] m_spliceIdx;
-      m_spliceIdx = NULL;
-    }
+  if (m_spliceIdx)
+  {
+    delete[] m_spliceIdx;
+    m_spliceIdx = NULL;
   }
+  m_invColourTransfBuf = NULL;
 }
 
 void Picture::createTempBuffers( const unsigned _maxCUSize )
@@ -269,21 +150,8 @@ void Picture::createTempBuffers( const unsigned _maxCUSize )
   const Area a = m_ctuArea.Y();
 #endif
 
-#if ENABLE_SPLIT_PARALLELISM
-  scheduler.startParallel();
-
-  for( int jId = 0; jId < scheduler.getNumPicInstances(); jId++ )
-#endif
-  {
-    M_BUFS( jId, PIC_PREDICTION                   ).create( chromaFormat, a,   _maxCUSize );
-    M_BUFS( jId, PIC_RESIDUAL                     ).create( chromaFormat, a,   _maxCUSize );
-#if ENABLE_SPLIT_PARALLELISM
-    if (jId > 0)
-    {
-      M_BUFS(jId, PIC_RECONSTRUCTION).create(chromaFormat, Y(), _maxCUSize, margin, MEMORY_ALIGN_DEF_SIZE);
-    }
-#endif
-  }
+  M_BUFS( jId, PIC_PREDICTION                   ).create( chromaFormat, a,   _maxCUSize );
+  M_BUFS( jId, PIC_RESIDUAL                     ).create( chromaFormat, a,   _maxCUSize );
 
   if (cs)
   {
@@ -293,24 +161,11 @@ void Picture::createTempBuffers( const unsigned _maxCUSize )
 
 void Picture::destroyTempBuffers()
 {
-#if ENABLE_SPLIT_PARALLELISM
-  scheduler.finishParallel();
-
-  for( int jId = 0; jId < scheduler.getNumPicInstances(); jId++ )
-#endif
+  for (uint32_t t = 0; t < NUM_PIC_TYPES; t++)
   {
-    for (uint32_t t = 0; t < NUM_PIC_TYPES; t++)
+    if (t == PIC_RESIDUAL || t == PIC_PREDICTION)
     {
-      if (t == PIC_RESIDUAL || t == PIC_PREDICTION)
-      {
-        M_BUFS(jId, t).destroy();
-      }
-#if ENABLE_SPLIT_PARALLELISM
-      if (t == PIC_RECONSTRUCTION && jId > 0)
-      {
-        M_BUFS(jId, t).destroy();
-      }
-#endif
+      M_BUFS(0, t).destroy();
     }
   }
 
@@ -329,6 +184,8 @@ const CPelUnitBuf Picture::getOrigBuf()                     const { return M_BUF
 
        PelBuf     Picture::getOrigBuf(const ComponentID compID)       { return getBuf(compID, PIC_ORIGINAL); }
 const CPelBuf     Picture::getOrigBuf(const ComponentID compID) const { return getBuf(compID, PIC_ORIGINAL); }
+       PelBuf     Picture::getTrueOrigBuf(const ComponentID compID)       { return getBuf(compID, PIC_TRUE_ORIGINAL); }
+const CPelBuf     Picture::getTrueOrigBuf(const ComponentID compID) const { return getBuf(compID, PIC_TRUE_ORIGINAL); }
        PelUnitBuf Picture::getTrueOrigBuf()                           { return M_BUFS(0, PIC_TRUE_ORIGINAL); }
 const CPelUnitBuf Picture::getTrueOrigBuf()                     const { return M_BUFS(0, PIC_TRUE_ORIGINAL); }
        PelBuf     Picture::getTrueOrigBuf(const CompArea &blk)        { return getBuf(blk, PIC_TRUE_ORIGINAL); }
@@ -388,6 +245,9 @@ void Picture::finalInit( const VPS* vps, const SPS& sps, const PPS& pps, PicHead
   cs->pps     = &pps;
   picHeader->setSPSId( sps.getSPSId() );
   picHeader->setPPSId( pps.getPPSId() );
+#if GDR_ENABLED
+  picHeader->setPic(this);
+#endif
   cs->picHeader = picHeader;
   memcpy(cs->alfApss, alfApss, sizeof(cs->alfApss));
   cs->lmcsAps = lmcsAps;
@@ -395,6 +255,8 @@ void Picture::finalInit( const VPS* vps, const SPS& sps, const PPS& pps, PicHead
   cs->pcv     = pps.pcv;
   m_conformanceWindow = pps.getConformanceWindow();
   m_scalingWindow = pps.getScalingWindow();
+  mixedNaluTypesInPicFlag = pps.getMixedNaluTypesInPicFlag();
+  nonReferencePictureFlag = picHeader->getNonReferencePictureFlag();
 
   if (m_spliceIdx == NULL)
   {
@@ -424,10 +286,10 @@ void Picture::fillSliceLossyLosslessArray(std::vector<uint16_t> sliceLosslessInd
 {
   uint16_t numElementsinsliceLosslessIndexArray = (uint16_t)sliceLosslessIndexArray.size();
   uint32_t numSlices = this->cs->pps->getNumSlicesInPic();
-  m_lossylosslessSliceArray.assign(numSlices, true); // initialize to all slices are lossless 
+  m_lossylosslessSliceArray.assign(numSlices, true); // initialize to all slices are lossless
   if (mixedLossyLossless)
   {
-    m_lossylosslessSliceArray.assign(numSlices, false); // initialize to all slices are lossless 
+    m_lossylosslessSliceArray.assign(numSlices, false); // initialize to all slices are lossless
     CHECK(numElementsinsliceLosslessIndexArray == 0 , "sliceLosslessArray is empty, must need to configure for mixed lossy/lossless");
 
     // mixed lossy/lossless slices, set only lossless slices;
@@ -436,7 +298,7 @@ void Picture::fillSliceLossyLosslessArray(std::vector<uint16_t> sliceLosslessInd
         CHECK(sliceLosslessIndexArray[i] >= numSlices || sliceLosslessIndexArray[i] < 0, "index of lossless slice is out of slice index bound");
         m_lossylosslessSliceArray[sliceLosslessIndexArray[i]] = true;
     }
-  } 
+  }
   CHECK(m_lossylosslessSliceArray.size() < numSlices, "sliceLosslessArray size is less than number of slices");
 }
 
@@ -467,23 +329,6 @@ void Picture::clearSliceBuffer()
   slices.clear();
 }
 
-#if ENABLE_SPLIT_PARALLELISM
-void Picture::finishParallelPart( const UnitArea& area )
-{
-  const UnitArea clipdArea = clipArea( area, *this );
-  const int      sourceID  = scheduler.getSplitPicId( 0 );
-  CHECK( scheduler.getSplitJobId() > 0, "Finish-CU cannot be called from within a mode- or split-parallelized block!" );
-
-  // distribute the reconstruction across all of the parallel workers
-  for( int tId = 1; tId < scheduler.getNumSplitThreads(); tId++ )
-  {
-    const int destID = scheduler.getSplitPicId( tId );
-
-    M_BUFS( destID, PIC_RECONSTRUCTION ).subBuf( clipdArea ).copyFrom( M_BUFS( sourceID, PIC_RECONSTRUCTION ).subBuf( clipdArea ) );
-  }
-}
-#endif
-
 const TFilterCoeff DownsamplingFilterSRC[8][16][12] =
 {
     { // D = 1
@@ -1237,9 +1082,6 @@ PelBuf Picture::getBuf( const CompArea &blk, const PictureType &type )
     return PelBuf();
   }
 
-#if ENABLE_SPLIT_PARALLELISM
-  const int jId = ( type == PIC_ORIGINAL || type == PIC_TRUE_ORIGINAL || type == PIC_ORIGINAL_INPUT || type == PIC_TRUE_ORIGINAL_INPUT ) ? 0 : scheduler.getSplitPicId();
-#endif
 #if !KEEP_PRED_AND_RESI_SIGNALS
   if( type == PIC_RESIDUAL || type == PIC_PREDICTION )
   {
@@ -1261,10 +1103,6 @@ const CPelBuf Picture::getBuf( const CompArea &blk, const PictureType &type ) co
     return PelBuf();
   }
 
-#if ENABLE_SPLIT_PARALLELISM
-  const int jId = ( type == PIC_ORIGINAL || type == PIC_TRUE_ORIGINAL ) ? 0 : scheduler.getSplitPicId();
-
-#endif
 #if !KEEP_PRED_AND_RESI_SIGNALS
   if( type == PIC_RESIDUAL || type == PIC_PREDICTION )
   {
@@ -1305,9 +1143,6 @@ const CPelUnitBuf Picture::getBuf( const UnitArea &unit, const PictureType &type
 
 Pel* Picture::getOrigin( const PictureType &type, const ComponentID compID ) const
 {
-#if ENABLE_SPLIT_PARALLELISM
-  const int jId = ( type == PIC_ORIGINAL || type == PIC_TRUE_ORIGINAL ) ? 0 : scheduler.getSplitPicId();
-#endif
   return M_BUFS( jId, type ).getOrigin( compID );
 }
 
@@ -1386,3 +1221,44 @@ void Picture::addPictureToHashMapForInter()
     }
   }
 }
+void Picture::createColourTransfProcessor(bool firstPictureInSequence, SEIColourTransformApply* ctiCharacteristics, PelStorage* ctiBuf, int width, int height, ChromaFormat fmt, int bitDepth)
+{
+  m_colourTranfParams = ctiCharacteristics;
+  m_invColourTransfBuf = ctiBuf;
+  if (firstPictureInSequence)
+  {
+    // Create and initialize the Colour Transform Processor
+    m_colourTranfParams->create(width, height, fmt, bitDepth);
+
+    //Frame level PelStorage buffer created to apply the Colour Transform
+    m_invColourTransfBuf->create(UnitArea(chromaFormat, Area(0, 0, width, height)));
+  }
+}
+
+PelUnitBuf Picture::getDisplayBuf()
+{
+  int payloadType = 0;
+  std::list<SEI*>::iterator message;
+
+  for (message = SEIs.begin(); message != SEIs.end(); ++message)
+  {
+    payloadType = (*message)->payloadType();
+    if (payloadType == SEI::COLOUR_TRANSFORM_INFO)
+    {
+      // re-init parameters
+      *m_colourTranfParams->m_pColourTransfParams = *static_cast<SEIColourTransformInfo*>(*message);
+      //m_colourTranfParams->m_pColourTransfParams = static_cast<SEIColourTransformInfo*>(*message);
+      break;
+    }
+  }
+
+  m_invColourTransfBuf->copyFrom(getRecoBuf());
+
+  if (m_colourTranfParams->m_pColourTransfParams != NULL)
+  {
+    m_colourTranfParams->generateColourTransfLUTs();
+    m_colourTranfParams->inverseColourTransform(m_invColourTransfBuf);
+  }
+
+  return *m_invColourTransfBuf;
+}
diff --git a/source/Lib/CommonLib/Picture.h b/source/Lib/CommonLib/Picture.h
index 66073bf61..2b6c9d732 100644
--- a/source/Lib/CommonLib/Picture.h
+++ b/source/Lib/CommonLib/Picture.h
@@ -3,7 +3,7 @@
 * and contributor rights, including patent rights, and no such rights are
 * granted under this license.
 *
-* Copyright (c) 2010-2020, ITU/ISO/IEC
+* Copyright (c) 2010-2021, ITU/ISO/IEC
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
@@ -48,51 +48,16 @@
 #include "CodingStructure.h"
 #include "Hash.h"
 #include "MCTS.h"
+#include "SEIColourTransform.h"
 #include <deque>
 
-#if ENABLE_SPLIT_PARALLELISM
-
-#define CURR_THREAD_ID -1
-
-class Scheduler
-{
-public:
-  Scheduler();
-  ~Scheduler();
-
-#if ENABLE_SPLIT_PARALLELISM
-  unsigned getSplitDataId( int jobId = CURR_THREAD_ID ) const;
-  unsigned getSplitPicId ( int tId   = CURR_THREAD_ID ) const;
-  unsigned getSplitJobId () const;
-  void     setSplitJobId ( const int jobId );
-  void     startParallel ();
-  void     finishParallel();
-  void     setSplitThreadId( const int tId = CURR_THREAD_ID );
-  unsigned getNumSplitThreads() const { return m_numSplitThreads; };
-#endif
-  unsigned getDataId     () const;
-  bool init              ( const int ctuYsize, const int ctuXsize, const int numWppThreadsRunning, const int numWppExtraLines, const int numSplitThreads );
-  int  getNumPicInstances() const;
-#if ENABLE_SPLIT_PARALLELISM
-
-  int   m_numSplitThreads;
-  bool  m_hasParallelBuffer;
-#endif
-};
-#endif
 
 class SEI;
 class AQpLayer;
 
 typedef std::list<SEI*> SEIMessages;
 
-
-
-#if ENABLE_SPLIT_PARALLELISM
-#define M_BUFS(JID,PID) m_bufs[JID][PID]
-#else
 #define M_BUFS(JID,PID) m_bufs[PID]
-#endif
 
 struct Picture : public UnitArea
 {
@@ -104,6 +69,10 @@ struct Picture : public UnitArea
 
   void createTempBuffers( const unsigned _maxCUSize );
   void destroyTempBuffers();
+  SEIColourTransformApply* m_colourTranfParams;
+  PelStorage*              m_invColourTransfBuf;
+  void              createColourTransfProcessor(bool firstPictureInSequence, SEIColourTransformApply* ctiCharacteristics, PelStorage* ctiBuf, int width, int height, ChromaFormat fmt, int bitDepth);
+  PelUnitBuf        getDisplayBuf();
 
          PelBuf     getOrigBuf(const CompArea &blk);
   const CPelBuf     getOrigBuf(const CompArea &blk) const;
@@ -113,6 +82,8 @@ struct Picture : public UnitArea
   const CPelUnitBuf getOrigBuf() const;
          PelBuf     getOrigBuf(const ComponentID compID);
   const CPelBuf     getOrigBuf(const ComponentID compID) const;
+         PelBuf     getTrueOrigBuf(const ComponentID compID);
+  const CPelBuf     getTrueOrigBuf(const ComponentID compID) const;
          PelUnitBuf getTrueOrigBuf();
   const CPelUnitBuf getTrueOrigBuf() const;
         PelBuf      getTrueOrigBuf(const CompArea &blk);
@@ -160,6 +131,8 @@ struct Picture : public UnitArea
   void setPictureType(const NalUnitType val)        { m_pictureType = val;          }
   void setBorderExtension( bool bFlag)              { m_bIsBorderExtended = bFlag;}
   Pel* getOrigin( const PictureType &type, const ComponentID compID ) const;
+  int  getEdrapRapId()                        const { return edrapRapId ; }
+  void setEdrapRapId(const int val)                 { edrapRapId = val; }
 
   void setLossyQPValue(int i)                 { m_lossyQP = i; }
   int getLossyQPValue()                       const { return m_lossyQP; }
@@ -217,6 +190,7 @@ public:
   bool fieldPic;
   int  m_prevQP[MAX_NUM_CHANNEL_TYPE];
   bool precedingDRAP; // preceding a DRAP picture in decoding order
+  int  edrapRapId;
   bool nonReferencePictureFlag;
 
   int  poc;
@@ -233,13 +207,9 @@ public:
   int m_lossyQP;
   std::vector<bool> m_lossylosslessSliceArray;
   bool interLayerRefPicFlag;
+  bool mixedNaluTypesInPicFlag;
 
-
-#if ENABLE_SPLIT_PARALLELISM
-  PelStorage m_bufs[PARL_SPLIT_MAX_NUM_JOBS][NUM_PIC_TYPES];
-#else
   PelStorage m_bufs[NUM_PIC_TYPES];
-#endif
   const Picture*           unscaledPic;
 
   TComHash           m_hashMap;
@@ -277,15 +247,6 @@ private:
   UnitArea m_ctuArea;
 #endif
 
-#if ENABLE_SPLIT_PARALLELISM
-public:
-  void finishParallelPart   ( const UnitArea& ctuArea );
-#endif
-#if ENABLE_SPLIT_PARALLELISM
-public:
-  Scheduler                  scheduler;
-#endif
-
 public:
   SAOBlkParam    *getSAO(int id = 0)                        { return &m_sao[id][0]; };
   void            resizeSAO(unsigned numEntries, int dstid) { m_sao[dstid].resize(numEntries); }
diff --git a/source/Lib/CommonLib/ProfileLevelTier.cpp b/source/Lib/CommonLib/ProfileLevelTier.cpp
index a277b36b9..831ed4df2 100644
--- a/source/Lib/CommonLib/ProfileLevelTier.cpp
+++ b/source/Lib/CommonLib/ProfileLevelTier.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -70,9 +70,7 @@ static const LevelTierFeatures mainLevelTierInfo[] =
     { Level::LEVEL6  , 35651584, {    80000,   240000 },      600,      440,       20, 1069547520ULL, {   60000,   240000 }, { 8, 4} },
     { Level::LEVEL6_1, 35651584, {   120000,   480000 },      600,      440,       20, 2139095040ULL, {  120000,   480000 }, { 8, 4} },
     { Level::LEVEL6_2, 35651584, {   180000,   800000 },      600,      440,       20, 4278190080ULL, {  240000,   800000 }, { 8, 4} },
-#if JVET_T0065_LEVEL_6_3
     { Level::LEVEL6_3, 80216064, {   240000,   800000 },     1000,      990,       30, 4812963840ULL, {  320000,   800000 }, { 8, 4} },
-#endif
     { Level::LEVEL15_5, MAX_UINT,{ MAX_UINT, MAX_UINT }, MAX_UINT, MAX_UINT, MAX_UINT, MAX_CNFUINT64, {MAX_UINT, MAX_UINT }, { 0, 0} },
     { Level::NONE    }
 };
@@ -94,6 +92,17 @@ static const ProfileFeatures validProfiles[] = {
   { Profile::MAIN_10_444, "Main_444_10", 10, CHROMA_444, false, 2500, 2750, 3750, 75, mainLevelTierInfo, false },
   { Profile::MULTILAYER_MAIN_10_444, "Multilayer_Main_444_10", 10, CHROMA_444, false, 2500, 2750, 3750, 75,
     mainLevelTierInfo, false },
+#if JVET_W2005_RANGE_EXTENSION_PROFILES
+  { Profile::MAIN_12, "Main_12", 12, CHROMA_420, true, 1500, 1650, 2250, 100, mainLevelTierInfo, false },
+  { Profile::MAIN_12_INTRA, "Main_12_Intra", 12, CHROMA_420, true, 1500, 1650, 2250, 100, mainLevelTierInfo, false },
+  { Profile::MAIN_12_STILL_PICTURE, "Main_12_Still_Picture", 12, CHROMA_420, true, 1500, 1650, 2250, 100, mainLevelTierInfo, false },
+  { Profile::MAIN_12_444, "Main_12_444", 12, CHROMA_444, true, 3000, 3300, 4500, 50, mainLevelTierInfo, false },
+  { Profile::MAIN_12_444_INTRA, "Main_12_444_Intra", 12, CHROMA_444, true, 3000, 3300, 4500, 50, mainLevelTierInfo, false },
+  { Profile::MAIN_12_444_STILL_PICTURE, "Main_12_444_Still_Picture", 12, CHROMA_444, true, 3000, 3300, 4500, 50, mainLevelTierInfo, false },
+  { Profile::MAIN_16_444, "Main_16_444", 16, CHROMA_444, true, 4000, 4400, 6000, 50, mainLevelTierInfo, false },
+  { Profile::MAIN_16_444_INTRA, "Main_16_444_Intra", 16, CHROMA_444, true, 4000, 4400, 6000, 50, mainLevelTierInfo, false },
+  { Profile::MAIN_16_444_STILL_PICTURE, "Main_16_444_Still_Picture", 16, CHROMA_444, true, 4000, 4400, 6000, 50, mainLevelTierInfo, false },
+#endif
   { Profile::NONE, 0 },
 };
 
@@ -146,16 +155,40 @@ ProfileLevelTierFeatures::extractPTLInformation(const SPS &sps)
       }
     }
   }
+#if JVET_W2005_RANGE_EXTENSION_PROFILES
+  if (m_pProfile)
+  {
+    Profile::Name profile = m_pProfile->profile;
+    if (profile == Profile::MAIN_10 || profile == Profile::MAIN_10_444 ||
+        profile == Profile::MULTILAYER_MAIN_10 || profile == Profile::MULTILAYER_MAIN_10_444 ||
+        profile == Profile::MAIN_12 || profile == Profile::MAIN_12_444 || profile == Profile::MAIN_16_444)
+    {
+      m_hbrFactor = 1;
+    }
+    else
+    {
+      m_hbrFactor = 2 - sps.getProfileTierLevel()->getConstraintInfo()->getLowerBitRateConstraintFlag();
+    }
+  }
+#endif
 }
 
 double ProfileLevelTierFeatures::getMinCr() const
 {
+#if JVET_W2005_RANGE_EXTENSION_PROFILES
+  return (m_pLevelTier!=0 && m_pProfile!=0) ? (m_pProfile->minCrScaleFactorx100 * m_pLevelTier->minCrBase[m_tier?1:0] / m_hbrFactor)/100.0 : 0.0 ;
+#else
   return (m_pLevelTier!=0 && m_pProfile!=0) ? (m_pProfile->minCrScaleFactorx100 * m_pLevelTier->minCrBase[m_tier?1:0])/100.0 : 0.0 ;
+#endif
 }
 
 uint64_t ProfileLevelTierFeatures::getCpbSizeInBits() const
 {
+#if JVET_W2005_RANGE_EXTENSION_PROFILES
+  return (m_pLevelTier!=0 && m_pProfile!=0) ? uint64_t(m_pProfile->cpbVclFactor) * m_pLevelTier->maxCpb[m_tier?1:0] * m_hbrFactor : uint64_t(0);
+#else
   return (m_pLevelTier!=0 && m_pProfile!=0) ? uint64_t(m_pProfile->cpbVclFactor) * m_pLevelTier->maxCpb[m_tier?1:0] : uint64_t(0);
+#endif
 }
 
 uint32_t ProfileLevelTierFeatures::getMaxDpbSize( uint32_t picSizeMaxInSamplesY ) const
diff --git a/source/Lib/CommonLib/ProfileLevelTier.h b/source/Lib/CommonLib/ProfileLevelTier.h
index ab3f349a9..ceffdf809 100644
--- a/source/Lib/CommonLib/ProfileLevelTier.h
+++ b/source/Lib/CommonLib/ProfileLevelTier.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -88,6 +88,9 @@ class ProfileLevelTierFeatures
     const ProfileFeatures   *m_pProfile;
     const LevelTierFeatures *m_pLevelTier;
     Level::Tier              m_tier;
+#if JVET_W2005_RANGE_EXTENSION_PROFILES
+    int                      m_hbrFactor;
+#endif
   public:
     ProfileLevelTierFeatures() : m_pProfile(nullptr), m_pLevelTier(nullptr), m_tier(Level::MAIN) {}
 
diff --git a/source/Lib/CommonLib/Quant.cpp b/source/Lib/CommonLib/Quant.cpp
index 789dad2c1..5b09d9426 100644
--- a/source/Lib/CommonLib/Quant.cpp
+++ b/source/Lib/CommonLib/Quant.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -501,14 +501,6 @@ void Quant::init( uint32_t uiMaxTrSize,
   m_resetStore = true;
 }
 
-#if ENABLE_SPLIT_PARALLELISM
-void Quant::copyState( const Quant& other )
-{
-  m_dLambda = other.m_dLambda;
-  memcpy( m_lambdas, other.m_lambdas, sizeof( m_lambdas ) );
-}
-#endif
-
 /** set quantized matrix coefficient for encode
  * \param scalingList            quantized matrix address
  * \param format                 chroma format
@@ -527,7 +519,9 @@ void Quant::setScalingList(ScalingList *scalingList, const int maxLog2TrDynamicR
     for(uint32_t list = 0; list < SCALING_LIST_NUM; list++)
     {
       if (size == SCALING_LIST_2x2 && list < 4)   // skip 2x2 luma
+      {
         continue;
+      }
       scalingListId = g_scalingListId[size][list];
       if (scalingList->getChromaScalingListPresentFlag() || scalingList->isLumaScalingList(scalingListId))
       {
@@ -548,7 +542,11 @@ void Quant::setScalingList(ScalingList *scalingList, const int maxLog2TrDynamicR
   {
     for (uint32_t sizeh = 0; sizeh <= SCALING_LIST_LAST_CODED; sizeh++) //7
     {
-      if (sizew == sizeh || (sizew == SCALING_LIST_1x1 && sizeh<SCALING_LIST_4x4) || (sizeh == SCALING_LIST_1x1 && sizew<SCALING_LIST_4x4)) continue;
+      if (sizew == sizeh || (sizew == SCALING_LIST_1x1 && sizeh < SCALING_LIST_4x4)
+          || (sizeh == SCALING_LIST_1x1 && sizew < SCALING_LIST_4x4))
+      {
+        continue;
+      }
       for (uint32_t list = 0; list < SCALING_LIST_NUM; list++) //9
       {
         int largerSide = (sizew > sizeh) ? sizew : sizeh;
@@ -579,7 +577,9 @@ void Quant::setScalingListDec(const ScalingList &scalingList)
     for(uint32_t list = 0; list < SCALING_LIST_NUM; list++)
     {
       if (size == SCALING_LIST_2x2 && list < 4)   // skip 2x2 luma
+      {
         continue;
+      }
       scalingListId = g_scalingListId[size][list];
       for(int qp = minimumQp; qp < maximumQp; qp++)
       {
@@ -593,7 +593,11 @@ void Quant::setScalingListDec(const ScalingList &scalingList)
   {
     for (uint32_t sizeh = 0; sizeh <= SCALING_LIST_LAST_CODED; sizeh++) //7
     {
-      if (sizew == sizeh || (sizew == SCALING_LIST_1x1 && sizeh<SCALING_LIST_4x4) || (sizeh == SCALING_LIST_1x1 && sizew<SCALING_LIST_4x4)) continue;
+      if (sizew == sizeh || (sizew == SCALING_LIST_1x1 && sizeh < SCALING_LIST_4x4)
+          || (sizeh == SCALING_LIST_1x1 && sizew < SCALING_LIST_4x4))
+      {
+        continue;
+      }
       for (uint32_t list = 0; list < SCALING_LIST_NUM; list++) //9
       {
         int largerSide = (sizew > sizeh) ? sizew : sizeh;
@@ -866,7 +870,9 @@ void Quant::processScalingListDec( const int *coeff, int *dequantcoeff, int invQ
     }
     int largeOne = (width > height) ? width : height;
     if (largeOne > 8)
+    {
       dequantcoeff[0] = invQuantScales * dc;
+    }
     return;
   }
   for (uint32_t j = 0; j<height; j++)
@@ -946,7 +952,10 @@ void Quant::xInitScalingList( const Quant* other )
  */
 void Quant::xDestroyScalingList()
 {
-  if( !m_isScalingListOwner ) return;
+  if (!m_isScalingListOwner)
+  {
+    return;
+  }
 
   delete[] m_quantCoef[0][0][0][0];
 }
@@ -1170,7 +1179,7 @@ void Quant::invTrSkipDeQuantOneSample(TransformUnit &tu, const ComponentID &comp
   const int            channelBitDepth        = sps.getBitDepth(toChannelType(compID));
   const int            iTransformShift        = getTransformShift(channelBitDepth, rect.size(), maxLog2TrDynamicRange);
   const int            scalingListType        = getScalingListType(tu.cu->predMode, compID);
-  
+
   const bool           disableSMForLFNST = tu.cs->slice->getExplicitScalingListUsed() ? tu.cs->slice->getSPS()->getDisableScalingMatrixForLfnstBlks() : false;
   const bool           isLfnstApplied = tu.cu->lfnstIdx > 0 && (tu.cu->isSepTree() ? true : isLuma(compID));
   const bool           disableSMForACT = tu.cs->slice->getSPS()->getScalingMatrixForAlternativeColourSpaceDisabledFlag() && (tu.cs->slice->getSPS()->getScalingMatrixDesignatedColourSpaceFlag() == tu.cu->colorTransform);
diff --git a/source/Lib/CommonLib/Quant.h b/source/Lib/CommonLib/Quant.h
index 752b20d93..b9b0d56c2 100644
--- a/source/Lib/CommonLib/Quant.h
+++ b/source/Lib/CommonLib/Quant.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -49,12 +49,6 @@
 //! \ingroup CommonLib
 //! \{
 
-// ====================================================================================================================
-// Constants
-// ====================================================================================================================
-
-#define QP_BITS                 15
-
 // ====================================================================================================================
 // Class definition
 // ====================================================================================================================
@@ -146,10 +140,6 @@ public:
   // de-quantization
   virtual void dequant           ( const TransformUnit &tu, CoeffBuf &dstCoeff, const ComponentID &compID, const QpParam &cQP );
 
-#if ENABLE_SPLIT_PARALLELISM
-  virtual void copyState         ( const Quant& other );
-#endif
-
 protected:
 
 #if T0196_SELECTIVE_RDOQ
diff --git a/source/Lib/CommonLib/QuantRDOQ.cpp b/source/Lib/CommonLib/QuantRDOQ.cpp
index 9b9eccf28..a57388e29 100644
--- a/source/Lib/CommonLib/QuantRDOQ.cpp
+++ b/source/Lib/CommonLib/QuantRDOQ.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -302,18 +302,18 @@ inline double QuantRDOQ::xGetRateSigCoeffGroup( const BinFracBits& fracBitsSigCG
 */
 inline double QuantRDOQ::xGetRateLast( const int* lastBitsX, const int* lastBitsY, unsigned PosX, unsigned PosY ) const
 {
-  uint32_t    CtxX  = g_uiGroupIdx[PosX];
-  uint32_t    CtxY  = g_uiGroupIdx[PosY];
-  double  Cost  = lastBitsX[ CtxX ] + lastBitsY[ CtxY ];
-  if( CtxX > 3 )
+  uint32_t ctxX = g_groupIdx[PosX];
+  uint32_t ctxY = g_groupIdx[PosY];
+  double   cost = lastBitsX[ctxX] + lastBitsY[ctxY];
+  if (ctxX > 3)
   {
-    Cost += xGetIEPRate() * ((CtxX-2)>>1);
+    cost += xGetIEPRate() * ((ctxX - 2) >> 1);
   }
-  if( CtxY > 3 )
+  if (ctxY > 3)
   {
-    Cost += xGetIEPRate() * ((CtxY-2)>>1);
+    cost += xGetIEPRate() * ((ctxY - 2) >> 1);
   }
-  return xGetICost( Cost );
+  return xGetICost(cost);
 }
 
 
@@ -643,8 +643,19 @@ void QuantRDOQ::xRateDistOptQuant(TransformUnit &tu, const ComponentID &compID,
 
   const TCoeff entropyCodingMinimum = -(1 << maxLog2TrDynamicRange);
   const TCoeff entropyCodingMaximum =  (1 << maxLog2TrDynamicRange) - 1;
-  
+
   CoeffCodingContext cctx(tu, compID, tu.cs->slice->getSignDataHidingEnabledFlag());
+  int baseLevel = cctx.getBaseLevel();
+  if (tu.cs->slice->getSPS()->getSpsRangeExtension().getPersistentRiceAdaptationEnabledFlag())
+  {
+    unsigned riceStats = ctx.getGRAdaptStats((unsigned)compID);
+    TCoeff historyValue = (TCoeff)1 << riceStats;
+    cctx.setHistValue(historyValue);
+  }
+  else
+  {
+    cctx.setHistValue(0);
+  }
   const int    iCGSizeM1      = (1 << cctx.log2CGSize()) - 1;
 
   int     iCGLastScanPos      = -1;
@@ -736,9 +747,8 @@ void QuantRDOQ::xRateDistOptQuant(TransformUnit &tu, const ComponentID &compID,
         uint32_t    goRiceZero    = 0;
         if( remRegBins < 4 )
         {
-          unsigned  sumAbs = cctx.templateAbsSum( iScanPos, piDstCoeff, 0 );
-          goRiceParam             = g_auiGoRiceParsCoeff   [ sumAbs ];
-          goRiceZero              = g_auiGoRicePosCoeff0(0, goRiceParam);
+          goRiceParam = (cctx.*(cctx.deriveRiceRRC))(iScanPos, piDstCoeff, 0);
+          goRiceZero       = g_goRicePosCoeff0(0, goRiceParam);
         }
 
         const BinFracBits fracBitsPar = fracBits.getFracBitsArray( uiParCtx );
@@ -793,8 +803,7 @@ void QuantRDOQ::xRateDistOptQuant(TransformUnit &tu, const ComponentID &compID,
         }
         else if( remRegBins >= 4 )
         {
-          int  sumAll = cctx.templateAbsSum(iScanPos, piDstCoeff, 4);
-          goRiceParam = g_auiGoRiceParsCoeff[sumAll];
+          goRiceParam = (cctx.*(cctx.deriveRiceRRC))(iScanPos, piDstCoeff, baseLevel);
           remRegBins -= (uiLevel < 2 ? uiLevel : 3) + (iScanPos != iLastScanPos);
         }
       }
@@ -954,7 +963,7 @@ void QuantRDOQ::xRateDistOptQuant(TransformUnit &tu, const ComponentID &compID,
     int bitsY = 0;
     int ctxId;
     //X-coordinate
-    for ( ctxId = 0; ctxId < g_uiGroupIdx[dim1-1]; ctxId++)
+    for (ctxId = 0; ctxId < g_groupIdx[dim1 - 1]; ctxId++)
     {
       const BinFracBits fB = fracBits.getFracBitsArray( cctx.lastXCtxId(ctxId) );
       lastBitsX[ ctxId ]   = bitsX + fB.intBits[ 0 ];
@@ -962,7 +971,7 @@ void QuantRDOQ::xRateDistOptQuant(TransformUnit &tu, const ComponentID &compID,
     }
     lastBitsX[ctxId] = bitsX;
     //Y-coordinate
-    for ( ctxId = 0; ctxId < g_uiGroupIdx[dim2-1]; ctxId++)
+    for (ctxId = 0; ctxId < g_groupIdx[dim2 - 1]; ctxId++)
     {
       const BinFracBits fB = fracBits.getFracBitsArray( cctx.lastYCtxId(ctxId) );
       lastBitsY[ ctxId ]   = bitsY + fB.intBits[ 0 ];
@@ -971,6 +980,16 @@ void QuantRDOQ::xRateDistOptQuant(TransformUnit &tu, const ComponentID &compID,
     lastBitsY[ctxId] = bitsY;
   }
 
+#if JVET_W0046_RLSCP
+  unsigned zoTbWdith  = std::min<unsigned>(JVET_C0024_ZERO_OUT_TH, cctx.width());
+  unsigned zoTbHeight = std::min<unsigned>(JVET_C0024_ZERO_OUT_TH, cctx.height());
+  if (tu.cs->sps->getUseMTS() && tu.cu->sbtInfo != 0 && tu.blocks[compID].width <= 32 && tu.blocks[compID].height <= 32
+      && compID == COMPONENT_Y)
+  {
+    zoTbWdith  = (tu.blocks[compID].width == 32) ? 16 : zoTbWdith;
+    zoTbHeight = (tu.blocks[compID].height == 32) ? 16 : zoTbHeight;
+  }
+#endif
 
   bool bFoundLast = false;
   for (int iCGScanPos = iCGLastScanPos; iCGScanPos >= 0; iCGScanPos--)
@@ -997,6 +1016,13 @@ void QuantRDOQ::xRateDistOptQuant(TransformUnit &tu, const ComponentID &compID,
         {
           uint32_t   uiPosY = uiBlkPos >> uiLog2BlockWidth;
           uint32_t   uiPosX = uiBlkPos - ( uiPosY << uiLog2BlockWidth );
+#if JVET_W0046_RLSCP
+          if (tu.cu->slice->getReverseLastSigCoeffFlag())
+          {
+            uiPosX = zoTbWdith - 1 - uiPosX;
+            uiPosY = zoTbHeight - 1 - uiPosY;
+          }
+#endif
           double d64CostLast  = xGetRateLast( lastBitsX, lastBitsY, uiPosX, uiPosY );
 
           double totalCost = d64BaseCost + d64CostLast - pdCostSig[ iScanPos ];
@@ -1300,6 +1326,10 @@ void QuantRDOQ::xRateDistOptQuantTS( TransformUnit &tu, const ComponentID &compI
       const BinFracBits fracBitsPar = fracBits.getFracBitsArray( cctx.parityCtxIdAbsTS() );
 
       goRiceParam = cctx.templateAbsSumTS( scanPos, dstCoeff );
+      if (tu.cu->slice->getSPS()->getSpsRangeExtension().getTSRCRicePresentFlag() && tu.mtsIdx[compID] == MTS_SKIP)
+      {
+        goRiceParam = goRiceParam + tu.cu->slice->get_tsrc_index();
+      }
       unsigned ctxIdSign = cctx.signCtxIdAbsTS(scanPos, dstCoeff, 0);
       const BinFracBits fracBitsSign = fracBits.getFracBitsArray(ctxIdSign);
       const uint8_t     sign         = srcCoeff[ blkPos ] < 0 ? 1 : 0;
@@ -1519,6 +1549,10 @@ void QuantRDOQ::forwardBDPCM(TransformUnit &tu, const ComponentID &compID, const
       const BinFracBits fracBitsPar = fracBits.getFracBitsArray(cctx.parityCtxIdAbsTS());
 
       goRiceParam = cctx.templateAbsSumTS(scanPos, dstCoeff);
+      if (tu.cu->slice->getSPS()->getSpsRangeExtension().getTSRCRicePresentFlag() && tu.mtsIdx[compID] == MTS_SKIP)
+      {
+        goRiceParam = goRiceParam + tu.cu->slice->get_tsrc_index();
+      }
       unsigned ctxIdSign = cctx.signCtxIdAbsTS(scanPos, dstCoeff, dirMode);
       const BinFracBits fracBitsSign = fracBits.getFracBitsArray(ctxIdSign);
       const uint8_t     sign = srcCoeff[blkPos] - predCoeff < 0 ? 1 : 0;
diff --git a/source/Lib/CommonLib/QuantRDOQ.h b/source/Lib/CommonLib/QuantRDOQ.h
index f0e8dee72..c6ae8d11c 100644
--- a/source/Lib/CommonLib/QuantRDOQ.h
+++ b/source/Lib/CommonLib/QuantRDOQ.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/CommonLib/RdCost.cpp b/source/Lib/CommonLib/RdCost.cpp
index 59b97786a..4c8c56564 100644
--- a/source/Lib/CommonLib/RdCost.cpp
+++ b/source/Lib/CommonLib/RdCost.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -222,26 +222,6 @@ void RdCost::init()
   m_pairCheck    = 0;
 }
 
-
-#if ENABLE_SPLIT_PARALLELISM
-
-void RdCost::copyState( const RdCost& other )
-{
-  m_costMode      = other.m_costMode;
-  m_dLambda       = other.m_dLambda;
-  m_DistScale     = other.m_DistScale;
-  memcpy( m_distortionWeight, other.m_distortionWeight, sizeof( m_distortionWeight ) );
-  m_mvPredictor   = other.m_mvPredictor;
-  m_motionLambda  = other.m_motionLambda;
-  m_iCostScale    = other.m_iCostScale;
-  m_dLambdaMotionSAD = other.m_dLambdaMotionSAD;
-#if WCG_EXT
-  m_dLambda_unadjusted  = other.m_dLambda_unadjusted ;
-  m_DistScaleUnadjusted = other.m_DistScaleUnadjusted;
-#endif
-}
-#endif
-
 void RdCost::setDistParam( DistParam &rcDP, const CPelBuf &org, const Pel* piRefY, int iRefStride, int bitDepth, ComponentID compID, int subShiftMode, int step, bool useHadamard )
 {
   rcDP.bitDepth   = bitDepth;
@@ -2950,11 +2930,16 @@ void RdCost::saveUnadjustedLambda()
   m_DistScaleUnadjusted = m_DistScale;
 }
 
-void RdCost::initLumaLevelToWeightTable()
+void RdCost::initLumaLevelToWeightTable(int bitDepth)
 {
-  for (int i = 0; i < LUMA_LEVEL_TO_DQP_LUT_MAXSIZE; i++)
+  int lutSize = 1 << bitDepth;
+  if (m_lumaLevelToWeightPLUT.empty())
+  {
+    m_lumaLevelToWeightPLUT.resize(lutSize, 1.0);
+  }
+  for (int i = 0; i < lutSize; i++)
   {
-    double x = i;
+    double x = bitDepth < 10 ? i << (10 - bitDepth) : bitDepth > 10 ? i >> (bitDepth - 10) : i;
     double y;
 
     y = 0.015 * x - 1.5
diff --git a/source/Lib/CommonLib/RdCost.h b/source/Lib/CommonLib/RdCost.h
index b6da1c65f..5737cdd56 100644
--- a/source/Lib/CommonLib/RdCost.h
+++ b/source/Lib/CommonLib/RdCost.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -293,10 +293,6 @@ public:
     return length;
   }
 
-#if ENABLE_SPLIT_PARALLELISM
-  void copyState( const RdCost& other );
-#endif
-
   // for motion cost
   static uint32_t    xGetExpGolombNumberOfBits( int iVal )
   {
@@ -315,7 +311,7 @@ public:
   uint32_t           getBitsOfVectorWithPredictor( const int x, const int y, const unsigned imvShift )  { return xGetExpGolombNumberOfBits(((x << m_iCostScale) - m_mvPredictor.getHor())>>imvShift) + xGetExpGolombNumberOfBits(((y << m_iCostScale) - m_mvPredictor.getVer())>>imvShift); }
 #if WCG_EXT
          void    saveUnadjustedLambda       ();
-         void    initLumaLevelToWeightTable ();
+         void    initLumaLevelToWeightTable (int bitDepth);
   inline double  getWPSNRLumaLevelWeight    (int val) { return m_lumaLevelToWeightPLUT[val]; }
   void           initLumaLevelToWeightTableReshape();
   void           updateReshapeLumaLevelToWeightTableChromaMD (std::vector<Pel>& ILUT);
@@ -393,6 +389,10 @@ private:
   static Distortion xGetSSE_SIMD    ( const DistParam& pcDtParam );
   template<int iWidth, X86_VEXT vext>
   static Distortion xGetSSE_NxN_SIMD( const DistParam& pcDtParam );
+#if RExt__HIGH_BIT_DEPTH_SUPPORT
+  template<X86_VEXT vext>
+  static Distortion xGetSSE_HBD_SIMD(const DistParam& pcDtParam);
+#endif
 
   template<X86_VEXT vext>
   static Distortion xGetSAD_SIMD    ( const DistParam& pcDtParam );
@@ -400,12 +400,23 @@ private:
   static Distortion xGetSAD_NxN_SIMD( const DistParam& pcDtParam );
   template<X86_VEXT vext>
   static Distortion xGetSAD_IBD_SIMD( const DistParam& pcDtParam );
-
+#if RExt__HIGH_BIT_DEPTH_SUPPORT
+  template<X86_VEXT vext>
+  static Distortion xGetHADs_HBD_SIMD(const DistParam& pcDtParam);
+#else
   template<X86_VEXT vext>
   static Distortion xGetHADs_SIMD   ( const DistParam& pcDtParam );
+#endif
 
   template< X86_VEXT vext >
   static Distortion xGetSADwMask_SIMD( const DistParam& pcDtParam );
+#if RExt__HIGH_BIT_DEPTH_SUPPORT
+  template<X86_VEXT vext>
+  static Distortion xGetSAD_HBD_SIMD(const DistParam& pcDtParam);
+
+  template< X86_VEXT vext >
+  static Distortion xGetSADwMask_HBD_SIMD(const DistParam& pcDtParam);
+#endif
 #endif
 
 public:
diff --git a/source/Lib/CommonLib/RdCostWeightPrediction.cpp b/source/Lib/CommonLib/RdCostWeightPrediction.cpp
index f88f665c0..ad77316af 100644
--- a/source/Lib/CommonLib/RdCostWeightPrediction.cpp
+++ b/source/Lib/CommonLib/RdCostWeightPrediction.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/CommonLib/RdCostWeightPrediction.h b/source/Lib/CommonLib/RdCostWeightPrediction.h
index cf7d55e6f..7ef14fd6e 100644
--- a/source/Lib/CommonLib/RdCostWeightPrediction.h
+++ b/source/Lib/CommonLib/RdCostWeightPrediction.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/CommonLib/Reshape.cpp b/source/Lib/CommonLib/Reshape.cpp
index 21371171a..eb24bbbb6 100644
--- a/source/Lib/CommonLib/Reshape.cpp
+++ b/source/Lib/CommonLib/Reshape.cpp
@@ -3,7 +3,7 @@
 * and contributor rights, including patent rights, and no such rights are
 * granted under this license.
 *
-* Copyright (c) 2010-2020, ITU/ISO/IEC
+* Copyright (c) 2010-2021, ITU/ISO/IEC
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
@@ -65,22 +65,32 @@ void  Reshape::createDec(int bitDepth)
   m_lumaBD = bitDepth;
   m_reshapeLUTSize = 1 << m_lumaBD;
   m_initCW = m_reshapeLUTSize / PIC_CODE_CW_BINS;
-  if (m_fwdLUT.empty())
-    m_fwdLUT.resize(m_reshapeLUTSize, 0);
-  if (m_invLUT.empty())
-    m_invLUT.resize(m_reshapeLUTSize, 0);
+  m_fwdLUT.resize(m_reshapeLUTSize, 0);
+  m_invLUT.resize(m_reshapeLUTSize, 0);
   if (m_binCW.empty())
+  {
     m_binCW.resize(PIC_CODE_CW_BINS, 0);
+  }
   if (m_inputPivot.empty())
+  {
     m_inputPivot.resize(PIC_CODE_CW_BINS + 1, 0);
+  }
   if (m_fwdScaleCoef.empty())
+  {
     m_fwdScaleCoef.resize(PIC_CODE_CW_BINS, 1 << FP_PREC);
+  }
   if (m_invScaleCoef.empty())
+  {
     m_invScaleCoef.resize(PIC_CODE_CW_BINS, 1 << FP_PREC);
+  }
   if (m_reshapePivot.empty())
+  {
     m_reshapePivot.resize(PIC_CODE_CW_BINS + 1, 0);
+  }
   if (m_chromaAdjHelpLUT.empty())
+  {
     m_chromaAdjHelpLUT.resize(PIC_CODE_CW_BINS, 1<<CSCALE_FP_PREC);
+  }
 }
 
 void  Reshape::destroy()
@@ -228,9 +238,13 @@ void Reshape::copySliceReshaperInfo(SliceReshapeInfo& tInfo, SliceReshapeInfo& s
   }
   tInfo.sliceReshaperEnableFlag = sInfo.sliceReshaperEnableFlag;
   if (sInfo.sliceReshaperEnableFlag)
+  {
     tInfo.enableChromaAdj = sInfo.enableChromaAdj;
+  }
   else
+  {
     tInfo.enableChromaAdj = 0;
+  }
 }
 
 /** Construct reshaper from syntax
@@ -243,11 +257,17 @@ void Reshape::constructReshaper()
   int pwlFwdBinLen = m_reshapeLUTSize / PIC_CODE_CW_BINS;
 
   for (int i = 0; i < m_sliceReshapeInfo.reshaperModelMinBinIdx; i++)
+  {
     m_binCW[i] = 0;
+  }
   for (int i = m_sliceReshapeInfo.reshaperModelMaxBinIdx + 1; i < PIC_CODE_CW_BINS; i++)
+  {
     m_binCW[i] = 0;
+  }
   for (int i = m_sliceReshapeInfo.reshaperModelMinBinIdx; i <= m_sliceReshapeInfo.reshaperModelMaxBinIdx; i++)
+  {
     m_binCW[i] = (uint16_t)(m_sliceReshapeInfo.reshaperModelBinCWDelta[i] + (int)m_initCW);
+  }
 
   for (int i = 0; i < pwlFwdLUTsize; i++)
   {
@@ -265,6 +285,22 @@ void Reshape::constructReshaper()
       m_chromaAdjHelpLUT[i] = (int32_t)(m_initCW * (1 << FP_PREC) / ( m_binCW[i] + m_sliceReshapeInfo.chrResScalingOffset ) );
     }
   }
+
+  int sumBinCW = 0;
+  for (int i = m_sliceReshapeInfo.reshaperModelMinBinIdx; i <= m_sliceReshapeInfo.reshaperModelMaxBinIdx; i++)
+  {
+    sumBinCW += m_binCW[i];
+    if (m_binCW[i] != 0)
+    {
+      CHECK((m_binCW[i] + m_sliceReshapeInfo.chrResScalingOffset) < (m_initCW >> 3) || (m_binCW[i] + m_sliceReshapeInfo.chrResScalingOffset) > ((m_initCW << 3) - 1),
+        "It is a requirement of bitstream conformance that, when lmcsCW[ i ] is not equal to 0, ( lmcsCW[ i ] + lmcsDeltaCrs ) shall be in the range of ( OrgCW >> 3 ) to ( ( OrgCW << 3 ) - 1 ), inclusive.");
+    }
+    CHECK(m_binCW[i] < (m_initCW >> 3) || m_binCW[i] > ((m_initCW << 3) - 1), " lmcsCW[ i ] shall be in the range of ( OrgCW >> 3 ) to ( ( OrgCW << 3 ) - 1 if not equal to 0 ).");
+    CHECK((((m_reshapePivot[i] % (1 << (m_lumaBD - 5))) != 0) && ((m_reshapePivot[i] >> (m_lumaBD - 5)) == (m_reshapePivot[i + 1] >> (m_lumaBD - 5)))),
+      "It is a requirement of bitstream conformance that, for i = lmcs_min_bin_idx..LmcsMaxBinIdx, when the value of LmcsPivot[ i ] is not a multiple of 1 << ( BitDepth - 5 ), the value of(LmcsPivot[i] >> (BitDepth - 5)) shall not be equal to the value of(LmcsPivot[i + 1] >> (BitDepth - 5)).");
+  }
+  CHECK(sumBinCW > ((1 << m_lumaBD) - 1), "It is a requirement of bitstream conformance that the following condition is true: Sum_(i = 0) ^ 15 [lmcsCW[i]] <= (1 << BitDepth) - 1.");
+
   for (int lumaSample = 0; lumaSample < m_reshapeLUTSize; lumaSample++)
   {
     int idxY = lumaSample / m_initCW;
diff --git a/source/Lib/CommonLib/Reshape.h b/source/Lib/CommonLib/Reshape.h
index 6b6e9d58e..2d28d9719 100644
--- a/source/Lib/CommonLib/Reshape.h
+++ b/source/Lib/CommonLib/Reshape.h
@@ -3,7 +3,7 @@
 * and contributor rights, including patent rights, and no such rights are
 * granted under this license.
 *
-* Copyright (c) 2010-2020, ITU/ISO/IEC
+* Copyright (c) 2010-2021, ITU/ISO/IEC
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
@@ -74,11 +74,7 @@ protected:
   int                     m_vpduY;
 public:
   Reshape();
-#if ENABLE_SPLIT_PARALLELISM
-  virtual ~Reshape();
-#else
   ~Reshape();
-#endif
 
   void createDec(int bitDepth);
   void destroy();
diff --git a/source/Lib/CommonLib/Rom.cpp b/source/Lib/CommonLib/Rom.cpp
index dc1c29aed..72e8a697f 100644
--- a/source/Lib/CommonLib/Rom.cpp
+++ b/source/Lib/CommonLib/Rom.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -70,9 +70,7 @@ const char* nalUnitTypeToString(NalUnitType type)
   case NAL_UNIT_CODED_SLICE_IDR_N_LP:   return "IDR_N_LP";
   case NAL_UNIT_CODED_SLICE_CRA:        return "CRA";
   case NAL_UNIT_CODED_SLICE_GDR:        return "GDR";
-#if JVET_S0163_ON_TARGETOLS_SUBLAYERS
   case NAL_UNIT_OPI:                    return "OPI";
-#endif
   case NAL_UNIT_DCI:                    return "DCI";
   case NAL_UNIT_VPS:                    return "VPS";
   case NAL_UNIT_SPS:                    return "SPS";
@@ -496,35 +494,13 @@ const int g_invQuantScales[2][SCALING_LIST_REM_NUM] = // can be represented as a
 // Intra prediction
 // ====================================================================================================================
 
-const uint8_t g_aucIntraModeNumFast_UseMPM_2D[7 - MIN_CU_LOG2 + 1][7 - MIN_CU_LOG2 + 1] =
-{
-  {3, 3, 3, 3, 2, 2},  //   4x4,   4x8,   4x16,   4x32,   4x64,   4x128,
-  {3, 3, 3, 3, 3, 2},  //   8x4,   8x8,   8x16,   8x32,   8x64,   8x128,
-  {3, 3, 3, 3, 3, 2},  //  16x4,  16x8,  16x16,  16x32,  16x64,  16x128,
-  {3, 3, 3, 3, 3, 2},  //  32x4,  32x8,  32x16,  32x32,  32x64,  32x128,
-  {2, 3, 3, 3, 3, 2},  //  64x4,  64x8,  64x16,  64x32,  64x64,  64x128,
-  {2, 2, 2, 2, 2, 3},  // 128x4, 128x8, 128x16, 128x32, 128x64, 128x128,
-};
-
-const uint8_t g_aucIntraModeNumFast_UseMPM[MAX_CU_DEPTH] =
-{
-  3,  //   2x2
-  8,  //   4x4
-  8,  //   8x8
-  3,  //  16x16
-  3,  //  32x32
-  3,  //  64x64
-  3   // 128x128
-};
-const uint8_t g_aucIntraModeNumFast_NotUseMPM[MAX_CU_DEPTH] =
-{
-  3,  //   2x2
-  9,  //   4x4
-  9,  //   8x8
-  4,  //  16x16   33
-  4,  //  32x32   33
-  5,  //  64x64   33
-  5   // 128x128
+const uint8_t g_intraModeNumFastUseMPM2D[7 - MIN_CU_LOG2 + 1][7 - MIN_CU_LOG2 + 1] = {
+  { 3, 3, 3, 3, 2, 2 },   //   4x4,   4x8,   4x16,   4x32,   4x64,   4x128,
+  { 3, 3, 3, 3, 3, 2 },   //   8x4,   8x8,   8x16,   8x32,   8x64,   8x128,
+  { 3, 3, 3, 3, 3, 2 },   //  16x4,  16x8,  16x16,  16x32,  16x64,  16x128,
+  { 3, 3, 3, 3, 3, 2 },   //  32x4,  32x8,  32x16,  32x32,  32x64,  32x128,
+  { 2, 3, 3, 3, 3, 2 },   //  64x4,  64x8,  64x16,  64x32,  64x64,  64x128,
+  { 2, 2, 2, 2, 2, 3 },   // 128x4, 128x8, 128x16, 128x32, 128x64, 128x128,
 };
 
 const uint8_t g_chroma422IntraAngleMappingTable[NUM_INTRA_MODE] =
@@ -547,17 +523,21 @@ UnitScale g_miScaling( MIN_CU_LOG2, MIN_CU_LOG2 );
 // ====================================================================================================================
 // Scanning order & context model mapping
 // ====================================================================================================================
-
+int g_riceT[4] = { 32,128, 512, 2048 };
+int g_riceShift[5] = { 0, 2, 4, 6, 8 };
 // scanning order table
 ScanElement *g_scanOrder[SCAN_NUMBER_OF_GROUP_TYPES][SCAN_NUMBER_OF_TYPES][MAX_CU_SIZE / 2 + 1][MAX_CU_SIZE / 2 + 1];
 ScanElement  g_coefTopLeftDiagScan8x8[ MAX_CU_SIZE / 2 + 1 ][ 64 ];
 
-const uint32_t g_uiMinInGroup[LAST_SIGNIFICANT_GROUPS] = { 0,1,2,3,4,6,8,12,16,24,32,48,64,96 };
-const uint32_t g_uiGroupIdx[MAX_TB_SIZEY] = { 0,1,2,3,4,4,5,5,6,6,6,6,7,7,7,7,8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9, 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11 };
-const uint32_t g_auiGoRiceParsCoeff[32] =
-{
-  0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3
-};
+const uint32_t g_minInGroup[LAST_SIGNIFICANT_GROUPS] = { 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96 };
+
+const uint32_t g_groupIdx[MAX_TB_SIZEY] = { 0,  1,  2,  3,  4,  4,  5,  5,  6,  6,  6,  6,  7,  7,  7,  7,
+                                            8,  8,  8,  8,  8,  8,  8,  8,  9,  9,  9,  9,  9,  9,  9,  9,
+                                            10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+                                            11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11 };
+
+const uint32_t g_goRiceParsCoeff[32] = { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2,
+                                         2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3 };
 const char *MatrixType[SCALING_LIST_SIZE_NUM][SCALING_LIST_NUM] =
 {
   {
@@ -799,3 +779,4 @@ int8_t    g_angle2mask[GEO_NUM_ANGLES] = { 0, -1, 1, 2, 3, 4, -1, -1, 5, -1, -1,
 int8_t    g_Dis[GEO_NUM_ANGLES] = { 8, 8, 8, 8, 4, 4, 2, 1, 0, -1, -2, -4, -4, -8, -8, -8, -8, -8, -8, -8, -4, -4, -2, -1, 0, 1, 2, 4, 4, 8, 8, 8 };
 int8_t    g_angle2mirror[GEO_NUM_ANGLES] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2 };
 //! \}
+
diff --git a/source/Lib/CommonLib/Rom.h b/source/Lib/CommonLib/Rom.h
index e7352e3c1..42fa15f1b 100644
--- a/source/Lib/CommonLib/Rom.h
+++ b/source/Lib/CommonLib/Rom.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -87,11 +87,12 @@ static const int g_transformMatrixShift[TRANSFORM_NUMBER_OF_DIRECTIONS] = {  6,
 // ====================================================================================================================
 // Scanning order & context mapping table
 // ====================================================================================================================
-
-extern const uint32_t   g_uiGroupIdx[ MAX_TB_SIZEY ];
-extern const uint32_t   g_uiMinInGroup[ LAST_SIGNIFICANT_GROUPS ];
-extern const uint32_t   g_auiGoRiceParsCoeff     [ 32 ];
-inline uint32_t g_auiGoRicePosCoeff0(int st, uint32_t ricePar)
+extern int g_riceT[4];
+extern int g_riceShift[5];
+extern const uint32_t g_groupIdx[MAX_TB_SIZEY];
+extern const uint32_t g_minInGroup[LAST_SIGNIFICANT_GROUPS];
+extern const uint32_t g_goRiceParsCoeff[32];
+inline uint32_t       g_goRicePosCoeff0(int st, uint32_t ricePar)
 {
   return (st < 2 ? 1 : 2) << ricePar;
 }
@@ -100,9 +101,7 @@ inline uint32_t g_auiGoRicePosCoeff0(int st, uint32_t ricePar)
 // Intra prediction table
 // ====================================================================================================================
 
-extern const uint8_t  g_aucIntraModeNumFast_UseMPM_2D[7 - MIN_CU_LOG2 + 1][7 - MIN_CU_LOG2 + 1];
-extern const uint8_t  g_aucIntraModeNumFast_UseMPM   [MAX_CU_DEPTH];
-extern const uint8_t  g_aucIntraModeNumFast_NotUseMPM[MAX_CU_DEPTH];
+extern const uint8_t g_intraModeNumFastUseMPM2D[7 - MIN_CU_LOG2 + 1][7 - MIN_CU_LOG2 + 1];
 
 extern const uint8_t  g_chroma422IntraAngleMappingTable[NUM_INTRA_MODE];
 
diff --git a/source/Lib/CommonLib/RomLFNST.cpp b/source/Lib/CommonLib/RomLFNST.cpp
index d09e56cde..10bcbbc62 100644
--- a/source/Lib/CommonLib/RomLFNST.cpp
+++ b/source/Lib/CommonLib/RomLFNST.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/CommonLib/RomTr.cpp b/source/Lib/CommonLib/RomTr.cpp
index 294bfd3dd..45690c36f 100644
--- a/source/Lib/CommonLib/RomTr.cpp
+++ b/source/Lib/CommonLib/RomTr.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -387,7 +387,7 @@ const TMatrixCoeff g_trCoreDCT2P64[TRANSFORM_NUMBER_OF_DIRECTIONS][64][64] =
 // DCT-8
 const TMatrixCoeff g_trCoreDCT8P4[TRANSFORM_NUMBER_OF_DIRECTIONS][4][4] =
 {
-  DEFINE_DCT8_P4_MATRIX(21505, 18893, 14081,  7425),
+  DEFINE_DCT8_P4_MATRIX(21505, 18893, 14081,  7424),
   DEFINE_DCT8_P4_MATRIX(84,     74,     55,     29)
 };
 const TMatrixCoeff g_trCoreDCT8P8[TRANSFORM_NUMBER_OF_DIRECTIONS][8][8] =
@@ -409,7 +409,7 @@ const TMatrixCoeff g_trCoreDCT8P32[TRANSFORM_NUMBER_OF_DIRECTIONS][32][32] =
 // DST-7
 const TMatrixCoeff g_trCoreDST7P4[TRANSFORM_NUMBER_OF_DIRECTIONS][4][4] =
 {
-  DEFINE_DST7_P4_MATRIX( 7425, 14081, 18893, 21505),
+  DEFINE_DST7_P4_MATRIX(7424, 14081, 18893, 21505),
   DEFINE_DST7_P4_MATRIX(   29,    55,    74,    84)
 };
 const TMatrixCoeff g_trCoreDST7P8[TRANSFORM_NUMBER_OF_DIRECTIONS][8][8] =
diff --git a/source/Lib/CommonLib/SEI.cpp b/source/Lib/CommonLib/SEI.cpp
index cb27029c4..6650a1b92 100644
--- a/source/Lib/CommonLib/SEI.cpp
+++ b/source/Lib/CommonLib/SEI.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -149,6 +149,293 @@ void SEIPictureTiming::copyTo (SEIPictureTiming& target) const
   target.m_vclCpbDelayOffset = m_vclCpbDelayOffset;
 }
 
+bool SEIScalabilityDimensionInfo::isSDISameContent(SEIScalabilityDimensionInfo* sdiB)
+{
+  if (!sdiB)
+  {
+    return false;
+  }
+  if (m_sdiNumViews != sdiB->m_sdiNumViews)
+  {
+    return false;
+  }
+  if (m_sdiMaxLayersMinus1 != sdiB->m_sdiMaxLayersMinus1)
+  {
+    return false;
+  }
+  if (m_sdiMultiviewInfoFlag != sdiB->m_sdiMultiviewInfoFlag)
+  {
+    return false;
+  }
+  if (m_sdiAuxiliaryInfoFlag != sdiB->m_sdiAuxiliaryInfoFlag)
+  {
+    return false;
+  }
+  if (m_sdiMultiviewInfoFlag || m_sdiAuxiliaryInfoFlag)
+  {
+    if (m_sdiMultiviewInfoFlag)
+    {
+      if (m_sdiViewIdLenMinus1 != sdiB->m_sdiViewIdLenMinus1)
+      {
+        return false;
+      }
+    }
+    for (int i = 0; i <= m_sdiMaxLayersMinus1; i++)
+    {
+      if (m_sdiMultiviewInfoFlag)
+      {
+        if (m_sdiViewIdVal[i] != sdiB->m_sdiViewIdVal[i])
+        {
+          return false;
+        }
+      }
+      if (m_sdiAuxiliaryInfoFlag)
+      {
+        if (m_sdiAuxId[i] != sdiB->m_sdiAuxId[i])
+        {
+          return false;
+        }
+        if (m_sdiAuxId[i] > 0)
+        {
+          if (m_sdiNumAssociatedPrimaryLayersMinus1[i] != sdiB->m_sdiNumAssociatedPrimaryLayersMinus1[i])
+          {
+            return false;
+          }
+          for (int j = 0; j <= m_sdiNumAssociatedPrimaryLayersMinus1[i]; j++)
+          {
+            if (m_sdiAssociatedPrimaryLayerIdx[i][j] != sdiB->m_sdiAssociatedPrimaryLayerIdx[i][j])
+            {
+              return false;
+            }
+          }
+        }
+      }
+    }
+  }
+  return true;
+}
+
+uint32_t SEIMultiviewAcquisitionInfo::getMantissaFocalLengthXLen( int i ) const
+{
+  return xGetSyntaxElementLen( m_maiExponentFocalLengthX[i], m_maiPrecFocalLength, m_maiMantissaFocalLengthX[ i ] );
+}
+
+uint32_t SEIMultiviewAcquisitionInfo::getMantissaFocalLengthYLen( int i ) const
+{
+  return xGetSyntaxElementLen( m_maiExponentFocalLengthY[i], m_maiPrecFocalLength, m_maiMantissaFocalLengthY[ i ]  );
+}
+
+
+uint32_t SEIMultiviewAcquisitionInfo::getMantissaPrincipalPointXLen( int i ) const
+{
+  return xGetSyntaxElementLen( m_maiExponentPrincipalPointX[i], m_maiPrecPrincipalPoint, m_maiMantissaPrincipalPointX[ i ]  );
+}
+
+uint32_t SEIMultiviewAcquisitionInfo::getMantissaPrincipalPointYLen( int i ) const
+{
+  return xGetSyntaxElementLen( m_maiExponentPrincipalPointY[i], m_maiPrecPrincipalPoint, m_maiMantissaPrincipalPointY[ i ] );
+}
+
+uint32_t SEIMultiviewAcquisitionInfo::getMantissaSkewFactorLen( int i ) const
+{
+  return xGetSyntaxElementLen( m_maiExponentSkewFactor[ i ], m_maiPrecSkewFactor, m_maiMantissaSkewFactor[ i ] );
+}
+
+uint32_t SEIMultiviewAcquisitionInfo::getMantissaRLen( int i, int j, int k ) const
+{
+  return xGetSyntaxElementLen( m_maiExponentR[ i ][ j ][ k ], m_maiPrecRotationParam, m_maiMantissaR[ i ][ j] [ k ] );
+}
+
+uint32_t SEIMultiviewAcquisitionInfo::getMantissaTLen( int i, int j ) const
+{
+  return xGetSyntaxElementLen( m_maiExponentT[ i ][ j ], m_maiPrecTranslationParam, m_maiMantissaT[ i ][ j ] );
+}
+uint32_t SEIMultiviewAcquisitionInfo::xGetSyntaxElementLen( int expo, int prec, int val ) const
+{
+  uint32_t len;
+  if( expo == 0 )
+  {
+    len = std::max(0, prec - 30 );
+  }
+  else
+  {
+    len = std::max( 0, expo + prec - 31 );
+  }
+
+  assert( val >= 0 );
+  assert( val <= ( ( 1 << len )- 1) );
+  return len;
+}
+
+bool SEIMultiviewAcquisitionInfo::isMAISameContent(SEIMultiviewAcquisitionInfo *maiB)
+{
+  if (!maiB)
+  {
+    return false;
+  }
+  if (m_maiIntrinsicParamFlag != maiB->m_maiIntrinsicParamFlag)
+  {
+    return false;
+  }
+  if (m_maiExtrinsicParamFlag != maiB->m_maiExtrinsicParamFlag)
+  {
+    return false;
+  }
+  if (m_maiNumViewsMinus1 != maiB->m_maiNumViewsMinus1)
+  {
+    return false;
+  }
+  if (m_maiIntrinsicParamFlag)
+  {
+    if (m_maiIntrinsicParamsEqualFlag != maiB->m_maiIntrinsicParamsEqualFlag)
+    {
+      return false;
+    }
+    if (m_maiPrecFocalLength != maiB->m_maiPrecFocalLength)
+    {
+      return false;
+    }
+    if (m_maiPrecPrincipalPoint != maiB->m_maiPrecPrincipalPoint)
+    {
+      return false;
+    }
+    if (m_maiPrecSkewFactor != maiB->m_maiPrecSkewFactor)
+    {
+      return false;
+    }
+    for (int i = 0; i <= (m_maiIntrinsicParamsEqualFlag ? 0 : m_maiNumViewsMinus1); i++)
+    {
+      if (m_maiSignFocalLengthX[i] != maiB->m_maiSignFocalLengthX[i])
+      {
+        return false;
+      }
+      if (m_maiExponentFocalLengthX[i] != maiB->m_maiExponentFocalLengthX[i])
+      {
+        return false;
+      }
+      if (m_maiMantissaFocalLengthX[i] != maiB->m_maiMantissaFocalLengthX[i])
+      {
+        return false;
+      }
+      if (m_maiSignFocalLengthY[i] != maiB->m_maiSignFocalLengthY[i])
+      {
+        return false;
+      }
+      if (m_maiExponentFocalLengthY[i] != maiB->m_maiExponentFocalLengthY[i])
+      {
+        return false;
+      }
+      if (m_maiMantissaFocalLengthY[i] != maiB->m_maiMantissaFocalLengthY[i])
+      {
+        return false;
+      }
+      if (m_maiSignPrincipalPointX[i] != maiB->m_maiSignPrincipalPointX[i])
+      {
+        return false;
+      }
+      if (m_maiExponentPrincipalPointX[i] != maiB->m_maiExponentPrincipalPointX[i])
+      {
+        return false;
+      }
+      if (m_maiMantissaPrincipalPointX[i] != maiB->m_maiMantissaPrincipalPointX[i])
+      {
+        return false;
+      }
+      if (m_maiSignPrincipalPointY[i] != maiB->m_maiSignPrincipalPointY[i])
+      {
+        return false;
+      }
+      if (m_maiExponentPrincipalPointY[i] != maiB->m_maiExponentPrincipalPointY[i])
+      {
+        return false;
+      }
+      if (m_maiMantissaPrincipalPointY[i] != maiB->m_maiMantissaPrincipalPointY[i])
+      {
+        return false;
+      }
+      if (m_maiSignSkewFactor[i] != maiB->m_maiSignSkewFactor[i])
+      {
+        return false;
+      }
+      if (m_maiExponentSkewFactor[i] != maiB->m_maiExponentSkewFactor[i])
+      {
+        return false;
+      }
+      if (m_maiMantissaSkewFactor[i] != maiB->m_maiMantissaSkewFactor[i])
+      {
+        return false;
+      }
+    }
+  }
+  if (m_maiExtrinsicParamFlag)
+  {
+    if (m_maiPrecRotationParam != maiB->m_maiPrecRotationParam)
+    {
+      return false;
+    }
+    if (m_maiPrecTranslationParam != maiB->m_maiPrecTranslationParam)
+    {
+      return false;
+    }
+    for (int i = 0; i <= m_maiNumViewsMinus1; i++)
+    {
+      for (int j = 0; j < 3; j++)
+      {
+        for (int k = 0; k < 3; k++)
+        {
+          if (m_maiSignR[i][j][k] != maiB->m_maiSignR[i][j][k])
+          {
+            return false;
+          }
+          if (m_maiExponentR[i][j][k] != maiB->m_maiExponentR[i][j][k])
+          {
+            return false;
+          }
+          if (m_maiMantissaR[i][j][k] != maiB->m_maiMantissaR[i][j][k])
+          {
+            return false;
+          }
+        }
+        if (m_maiSignT[i][j] != maiB->m_maiSignT[i][j])
+        {
+          return false;
+        }
+        if (m_maiExponentT[i][j] != maiB->m_maiExponentT[i][j])
+        {
+          return false;
+        }
+        if (m_maiMantissaT[i][j] != maiB->m_maiMantissaT[i][j])
+        {
+          return false;
+        }
+      }
+    }
+  }
+  return true;
+}
+
+#if JVET_W0078_MVP_SEI 
+bool SEIMultiviewViewPosition::isMVPSameContent(SEIMultiviewViewPosition *mvpB)
+{
+  if (!mvpB)
+  {
+    return false;
+  }
+  if (m_mvpNumViewsMinus1 != mvpB->m_mvpNumViewsMinus1)
+  {
+    return false;
+  }
+  for (int i = 0; i <= m_mvpNumViewsMinus1; i++)
+  {
+    if (m_mvpViewPosition[i] != mvpB->m_mvpViewPosition[i])
+    {
+      return false;
+    }
+  }
+  return true;
+}
+#endif
+
 // Static member
 const char *SEI::getSEIMessageString(SEI::PayloadType payloadType)
 {
@@ -161,6 +448,7 @@ const char *SEI::getSEIMessageString(SEI::PayloadType payloadType)
     case SEI::USER_DATA_UNREGISTERED:               return "User data unregistered";
     case SEI::FILM_GRAIN_CHARACTERISTICS:           return "Film grain characteristics";           // not currently decoded
     case SEI::FRAME_PACKING:                        return "Frame packing arrangement";
+    case SEI::DISPLAY_ORIENTATION:                  return "Display orientation";
     case SEI::PARAMETER_SETS_INCLUSION_INDICATION:  return "Parameter sets inclusion indication";
     case SEI::DECODING_UNIT_INFO:                   return "Decoding unit information";
     case SEI::SCALABLE_NESTING:                     return "Scalable nesting";
@@ -173,13 +461,26 @@ const char *SEI::getSEIMessageString(SEI::PayloadType payloadType)
     case SEI::CONTENT_LIGHT_LEVEL_INFO:             return "Content light level information";
     case SEI::AMBIENT_VIEWING_ENVIRONMENT:          return "Ambient viewing environment";
     case SEI::CONTENT_COLOUR_VOLUME:                return "Content colour volume";
+    case SEI::COLOUR_TRANSFORM_INFO:                return "Colour transform information";
     case SEI::EQUIRECTANGULAR_PROJECTION:           return "Equirectangular projection";
     case SEI::SPHERE_ROTATION:                      return "Sphere rotation";
     case SEI::REGION_WISE_PACKING:                  return "Region wise packing information";
     case SEI::OMNI_VIEWPORT:                        return "Omni viewport";
     case SEI::GENERALIZED_CUBEMAP_PROJECTION:       return "Generalized cubemap projection";
+    case SEI::ALPHA_CHANNEL_INFO:                   return "Alpha channel information";
+    case SEI::DEPTH_REPRESENTATION_INFO:            return "Depth representation information";
+    case SEI::MULTIVIEW_ACQUISITION_INFO:           return "Multiview acquisition information";
+#if JVET_W0078_MVP_SEI 
+    case SEI::MULTIVIEW_VIEW_POSITION:              return "Multiview view position";
+#endif
     case SEI::SAMPLE_ASPECT_RATIO_INFO:             return "Sample aspect ratio information";
     case SEI::SUBPICTURE_LEVEL_INFO:                return "Subpicture level information";
+    case SEI::ANNOTATED_REGIONS:                    return "Annotated Region";
+    case SEI::SCALABILITY_DIMENSION_INFO:           return "Scalability dimension information";
+    case SEI::EXTENDED_DRAP_INDICATION:             return "Extended DRAP indication";
+#if JVET_W0133_CONSTRAINED_RASL_ENCODING
+    case SEI::CONSTRAINED_RASL_ENCODING:            return "Constrained RASL encoding";
+#endif
     default:                                        return "Unknown";
   }
 }
diff --git a/source/Lib/CommonLib/SEI.h b/source/Lib/CommonLib/SEI.h
index cb33d7a0c..989745276 100644
--- a/source/Lib/CommonLib/SEI.h
+++ b/source/Lib/CommonLib/SEI.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -61,24 +61,38 @@ public:
     USER_DATA_UNREGISTERED               = 5,
     FILM_GRAIN_CHARACTERISTICS           = 19,
     FRAME_PACKING                        = 45,
+    DISPLAY_ORIENTATION                  = 47,
     PARAMETER_SETS_INCLUSION_INDICATION  = 129,
     DECODING_UNIT_INFO                   = 130,
     DECODED_PICTURE_HASH                 = 132,
     SCALABLE_NESTING                     = 133,
     MASTERING_DISPLAY_COLOUR_VOLUME      = 137,
+    COLOUR_TRANSFORM_INFO                = 142,
     DEPENDENT_RAP_INDICATION             = 145,
     EQUIRECTANGULAR_PROJECTION           = 150,
     SPHERE_ROTATION                      = 154,
     REGION_WISE_PACKING                  = 155,
     OMNI_VIEWPORT                        = 156,
     GENERALIZED_CUBEMAP_PROJECTION       = 153,
+    ALPHA_CHANNEL_INFO                   = 165,
     FRAME_FIELD_INFO                     = 168,
+    DEPTH_REPRESENTATION_INFO            = 177,
+    MULTIVIEW_ACQUISITION_INFO           = 179,
+#if JVET_W0078_MVP_SEI 
+    MULTIVIEW_VIEW_POSITION              = 180,
+#endif
     SUBPICTURE_LEVEL_INFO                = 203,
     SAMPLE_ASPECT_RATIO_INFO             = 204,
     CONTENT_LIGHT_LEVEL_INFO             = 144,
     ALTERNATIVE_TRANSFER_CHARACTERISTICS = 147,
     AMBIENT_VIEWING_ENVIRONMENT          = 148,
     CONTENT_COLOUR_VOLUME                = 149,
+    ANNOTATED_REGIONS                    = 202,
+    SCALABILITY_DIMENSION_INFO           = 205,
+    EXTENDED_DRAP_INDICATION             = 206,
+#if JVET_W0133_CONSTRAINED_RASL_ENCODING
+    CONSTRAINED_RASL_ENCODING            = 207,
+#endif
   };
 
   SEI() {}
@@ -201,6 +215,201 @@ public:
   uint8_t              m_gcmpGuardBandSamplesMinus1;
 };
 
+class SEIScalabilityDimensionInfo : public SEI
+{
+public:
+  PayloadType payloadType() const { return SCALABILITY_DIMENSION_INFO; }
+  SEIScalabilityDimensionInfo()
+  : m_sdiNumViews (0)
+  , m_sdiMaxLayersMinus1 (0)
+  , m_sdiMultiviewInfoFlag (false)
+  , m_sdiAuxiliaryInfoFlag (false)
+  , m_sdiViewIdLenMinus1 (0)
+  {
+  }
+  virtual ~SEIScalabilityDimensionInfo() {}
+  bool isSDISameContent(SEIScalabilityDimensionInfo* sdiB);
+
+  int                   m_sdiNumViews;
+  int                   m_sdiMaxLayersMinus1;
+  bool                  m_sdiMultiviewInfoFlag;
+  bool                  m_sdiAuxiliaryInfoFlag;
+  int                   m_sdiViewIdLenMinus1;
+  std::vector<int>      m_sdiLayerId;
+  std::vector<int>      m_sdiViewIdVal;
+  std::vector<int>      m_sdiAuxId;
+  std::vector<int>      m_sdiNumAssociatedPrimaryLayersMinus1;
+  std::vector<std::vector<int>> m_sdiAssociatedPrimaryLayerIdx;
+};
+
+class SEIMultiviewAcquisitionInfo : public SEI
+{
+public:
+  PayloadType payloadType( ) const { return MULTIVIEW_ACQUISITION_INFO; }
+  SEIMultiviewAcquisitionInfo ( ) { };
+  ~SEIMultiviewAcquisitionInfo( ) { };
+  SEI* getCopy( ) const { return new SEIMultiviewAcquisitionInfo(*this); };
+  bool isMAISameContent(SEIMultiviewAcquisitionInfo* maiB);
+
+  void resizeArrays( )
+  {
+    int numViews = m_maiIntrinsicParamsEqualFlag ? 1 : m_maiNumViewsMinus1 + 1;
+    m_maiSignFocalLengthX       .resize( numViews );
+    m_maiExponentFocalLengthX   .resize( numViews );
+    m_maiMantissaFocalLengthX   .resize( numViews );
+    m_maiSignFocalLengthY       .resize( numViews );
+    m_maiExponentFocalLengthY   .resize( numViews );
+    m_maiMantissaFocalLengthY   .resize( numViews );
+    m_maiSignPrincipalPointX    .resize( numViews );
+    m_maiExponentPrincipalPointX.resize( numViews );
+    m_maiMantissaPrincipalPointX.resize( numViews );
+    m_maiSignPrincipalPointY    .resize( numViews );
+    m_maiExponentPrincipalPointY.resize( numViews );
+    m_maiMantissaPrincipalPointY.resize( numViews );
+    m_maiSignSkewFactor         .resize( numViews );
+    m_maiExponentSkewFactor     .resize( numViews );
+    m_maiMantissaSkewFactor     .resize( numViews );
+
+    m_maiSignR                  .resize( m_maiNumViewsMinus1 + 1 );
+    m_maiExponentR              .resize( m_maiNumViewsMinus1 + 1 );
+    m_maiMantissaR              .resize( m_maiNumViewsMinus1 + 1 );
+    m_maiSignT                  .resize( m_maiNumViewsMinus1 + 1 );
+    m_maiExponentT              .resize( m_maiNumViewsMinus1 + 1 );
+    m_maiMantissaT              .resize( m_maiNumViewsMinus1 + 1 );
+
+    for( int i = 0; i <= m_maiNumViewsMinus1 ; i++ )
+    {
+      m_maiSignR    [i].resize( 3 );
+      m_maiExponentR[i].resize( 3 );
+      m_maiMantissaR[i].resize( 3 );
+      m_maiSignT    [i].resize( 3 );
+      m_maiExponentT[i].resize( 3 );
+      m_maiMantissaT[i].resize( 3 );
+
+      for (int j = 0; j < 3; j++)
+      {
+        m_maiSignR    [i][j].resize( 3 );
+        m_maiExponentR[i][j].resize( 3 );
+        m_maiMantissaR[i][j].resize( 3 );
+      }
+    }
+  }
+
+  uint32_t getMantissaFocalLengthXLen   (int i) const;
+  uint32_t getMantissaFocalLengthYLen   (int i) const;
+  uint32_t getMantissaPrincipalPointXLen(int i) const;
+  uint32_t getMantissaPrincipalPointYLen(int i) const;
+  uint32_t getMantissaSkewFactorLen     (int i) const;
+  uint32_t getMantissaRLen              (int i, int j, int k ) const;
+  uint32_t getMantissaTLen              (int i, int j )        const;
+
+  bool              m_maiIntrinsicParamFlag;
+  bool              m_maiExtrinsicParamFlag;
+  int               m_maiNumViewsMinus1;
+  bool              m_maiIntrinsicParamsEqualFlag;
+  int               m_maiPrecFocalLength;
+  int               m_maiPrecPrincipalPoint;
+  int               m_maiPrecSkewFactor;
+  std::vector<bool> m_maiSignFocalLengthX;
+  std::vector<int>  m_maiExponentFocalLengthX;
+  std::vector<int>  m_maiMantissaFocalLengthX;
+  std::vector<bool> m_maiSignFocalLengthY;
+  std::vector<int>  m_maiExponentFocalLengthY;
+  std::vector<int>  m_maiMantissaFocalLengthY;
+  std::vector<bool> m_maiSignPrincipalPointX;
+  std::vector<int>  m_maiExponentPrincipalPointX;
+  std::vector<int>  m_maiMantissaPrincipalPointX;
+  std::vector<bool> m_maiSignPrincipalPointY;
+  std::vector<int>  m_maiExponentPrincipalPointY;
+  std::vector<int>  m_maiMantissaPrincipalPointY;
+  std::vector<bool> m_maiSignSkewFactor;
+  std::vector<int>  m_maiExponentSkewFactor;
+  std::vector<int>  m_maiMantissaSkewFactor;
+  int               m_maiPrecRotationParam;
+  int               m_maiPrecTranslationParam;
+  std::vector< std::vector<std::vector<bool>>> m_maiSignR;
+  std::vector< std::vector<std::vector<int>>>  m_maiExponentR;
+  std::vector< std::vector<std::vector<int>>>  m_maiMantissaR;
+  std::vector< std::vector<bool>> m_maiSignT;
+  std::vector< std::vector<int>>  m_maiExponentT;
+  std::vector< std::vector<int>>  m_maiMantissaT;
+private:
+  uint32_t xGetSyntaxElementLen( int expo, int prec, int val ) const;
+};
+
+#if JVET_W0078_MVP_SEI 
+class SEIMultiviewViewPosition : public SEI
+{
+public:
+  PayloadType payloadType() const { return MULTIVIEW_VIEW_POSITION; }
+  SEIMultiviewViewPosition() { };
+  ~SEIMultiviewViewPosition() { };
+  bool isMVPSameContent(SEIMultiviewViewPosition* mvpB);
+
+  int               m_mvpNumViewsMinus1;
+  std::vector<int>  m_mvpViewPosition;
+};
+#endif
+
+class SEIAlphaChannelInfo : public SEI
+{
+public:
+  PayloadType payloadType() const { return ALPHA_CHANNEL_INFO; }
+  SEIAlphaChannelInfo()
+  : m_aciCancelFlag (false)
+  , m_aciUseIdc (0)
+  , m_aciBitDepthMinus8 (0)
+  , m_aciTransparentValue (0)
+  , m_aciOpaqueValue (255)
+  , m_aciIncrFlag (false)
+  , m_aciClipFlag (false)
+  , m_aciClipTypeFlag (false)
+  {};
+  virtual ~SEIAlphaChannelInfo() {};
+
+  bool m_aciCancelFlag;
+  int  m_aciUseIdc;
+  int  m_aciBitDepthMinus8;
+  int  m_aciTransparentValue;
+  int  m_aciOpaqueValue;
+  bool m_aciIncrFlag;
+  bool m_aciClipFlag;
+  bool m_aciClipTypeFlag;
+};
+
+class SEIDepthRepresentationInfo : public SEI
+{
+public:
+  PayloadType payloadType() const { return DEPTH_REPRESENTATION_INFO; }
+  SEIDepthRepresentationInfo()
+  : m_driZNearFlag (false)
+  , m_driZFarFlag (false)
+  , m_driDMinFlag (false)
+  , m_driDMaxFlag (false)
+  , m_driZNear (0.0)
+  , m_driZFar (0.0)
+  , m_driDMin (0.0)
+  , m_driDMax (0.0)
+  , m_driDepthRepresentationType (0)
+  , m_driDisparityRefViewId (0)
+  , m_driDepthNonlinearRepresentationNumMinus1 (0)
+  {};
+  virtual ~SEIDepthRepresentationInfo() {};
+
+  bool m_driZNearFlag;
+  bool m_driZFarFlag;
+  bool m_driDMinFlag;
+  bool m_driDMaxFlag;
+  double m_driZNear;
+  double m_driZFar;
+  double m_driDMin;
+  double m_driDMax;
+  int m_driDepthRepresentationType;
+  int m_driDisparityRefViewId;
+  int m_driDepthNonlinearRepresentationNumMinus1;
+  std::vector<int> m_driDepthNonlinearRepresentationModel;
+};
+
 class SEISampleAspectRatioInfo : public SEI
 {
 public:
@@ -244,9 +453,7 @@ public:
   virtual ~SEIDecodedPictureHash() {}
 
   HashType method;
-#if FIX_TICKET_1405
   bool     singleCompFlag;
-#endif
 
   PictureHash m_pictureHash;
 };
@@ -384,7 +591,7 @@ public:
   SEIDecodingUnitInfo()
     : m_decodingUnitIdx(0)
     , m_dpbOutputDuDelayPresentFlag(false)
-    , m_picSptDpbOutputDuDelay(0)
+    , m_picSptDpbOutputDuDelay(-1)
   {
     ::memset(m_duiSubLayerDelaysPresentFlag, 0, sizeof(m_duiSubLayerDelaysPresentFlag));
     ::memset(m_duSptCpbRemovalDelayIncrement, 0, sizeof(m_duSptCpbRemovalDelayIncrement));
@@ -456,6 +663,19 @@ public:
   bool m_upsampledAspectRatio;
 };
 
+class SEIDisplayOrientation : public SEI
+{
+public:
+  PayloadType payloadType() const { return DISPLAY_ORIENTATION; }
+
+  SEIDisplayOrientation() {}
+  virtual ~SEIDisplayOrientation() {}
+
+  bool                  m_doCancelFlag;
+  bool                  m_doPersistenceFlag;
+  int                   m_doTransformType;
+};
+
 class SEIParameterSetsInclusionIndication : public SEI
 {
 public:
@@ -619,6 +839,28 @@ public:
   uint16_t m_ambientLightY;
 };
 
+class SEIColourTransformInfo : public SEI
+{
+public:
+  PayloadType payloadType() const { return COLOUR_TRANSFORM_INFO; }
+  SEIColourTransformInfo() { }
+
+  virtual ~SEIColourTransformInfo() { }
+
+  uint16_t m_id;
+  bool     m_signalInfoFlag;
+  bool     m_fullRangeFlag;
+  uint16_t m_primaries;
+  uint16_t m_transferFunction;
+  uint16_t m_matrixCoefs;
+  bool     m_crossComponentFlag;
+  bool     m_crossComponentInferred;
+  uint16_t m_numberChromaLutMinus1;
+  int      m_chromaOffset;
+  uint16_t m_bitdepth;
+  uint16_t m_log2NumberOfPointsPerLut;
+  LutModel m_lut[MAX_NUM_COMPONENT];
+};
 class SEIContentColourVolume : public SEI
 {
 public:
@@ -667,9 +909,95 @@ public:
   std::vector<std::vector<std::vector<int>>> m_refLevelFraction;
 };
 
+class SEIAnnotatedRegions : public SEI
+{
+public:
+  PayloadType payloadType() const { return ANNOTATED_REGIONS; }
+  SEIAnnotatedRegions() {}
+  virtual ~SEIAnnotatedRegions() {}
+
+  void copyFrom(const SEIAnnotatedRegions &seiAnnotatedRegions)
+  {
+    (*this) = seiAnnotatedRegions;
+  }
+
+  struct AnnotatedRegionObject
+  {
+    AnnotatedRegionObject() :
+      objectCancelFlag(false),
+      objectLabelValid(false),
+      boundingBoxValid(false)
+    { }
+    bool objectCancelFlag;
+
+    bool objectLabelValid;
+    uint32_t objLabelIdx;            // only valid if bObjectLabelValid
+
+    bool boundingBoxValid;
+    uint32_t boundingBoxTop;         // only valid if bBoundingBoxValid
+    uint32_t boundingBoxLeft;
+    uint32_t boundingBoxWidth;
+    uint32_t boundingBoxHeight;
+
+    bool partialObjectFlag;        // only valid if bPartialObjectFlagValid
+    uint32_t objectConfidence;
+  };
+  struct AnnotatedRegionLabel
+  {
+    AnnotatedRegionLabel() : labelValid(false) { }
+    bool        labelValid;
+    std::string label;           // only valid if bLabelValid
+  };
+
+  struct AnnotatedRegionHeader
+  {
+    AnnotatedRegionHeader() : m_cancelFlag(true), m_receivedSettingsOnce(false) { }
+    bool      m_cancelFlag;
+    bool      m_receivedSettingsOnce; // used for decoder conformance checking. Other confidence flags must be unchanged once this flag is set.
+
+    bool      m_notOptimizedForViewingFlag;
+    bool      m_trueMotionFlag;
+    bool      m_occludedObjectFlag;
+    bool      m_partialObjectFlagPresentFlag;
+    bool      m_objectLabelPresentFlag;
+    bool      m_objectConfidenceInfoPresentFlag;
+    uint32_t      m_objectConfidenceLength;         // Only valid if m_objectConfidenceInfoPresentFlag
+    bool      m_objectLabelLanguagePresentFlag; // Only valid if m_objectLabelPresentFlag
+    std::string m_annotatedRegionsObjectLabelLang;
+  };
+  typedef uint32_t AnnotatedRegionObjectIndex;
+  typedef uint32_t AnnotatedRegionLabelIndex;
+
+  AnnotatedRegionHeader m_hdr;
+  std::vector<std::pair<AnnotatedRegionObjectIndex, AnnotatedRegionObject> > m_annotatedRegions;
+  std::vector<std::pair<AnnotatedRegionLabelIndex,  AnnotatedRegionLabel>  > m_annotatedLabels;
+};
+
+class SEIExtendedDrapIndication : public SEI
+{
+public:
+  PayloadType payloadType() const { return EXTENDED_DRAP_INDICATION; }
 
+  SEIExtendedDrapIndication() {}
+  virtual ~SEIExtendedDrapIndication() {}
+
+  int               m_edrapIndicationRapIdMinus1;
+  bool              m_edrapIndicationLeadingPicturesDecodableFlag;
+  int               m_edrapIndicationReservedZero12Bits;
+  int               m_edrapIndicationNumRefRapPicsMinus1;
+  std::vector<int>  m_edrapIndicationRefRapId;
+};
 
+#if JVET_W0133_CONSTRAINED_RASL_ENCODING
+class SEIConstrainedRaslIndication : public SEI
+{
+public:
+  PayloadType payloadType() const { return CONSTRAINED_RASL_ENCODING; }
+  SEIConstrainedRaslIndication() { }
 
+  virtual ~SEIConstrainedRaslIndication() { }
+};
+#endif
 //! \}
 
 
diff --git a/source/Lib/CommonLib/SEIColourTransform.cpp b/source/Lib/CommonLib/SEIColourTransform.cpp
new file mode 100644
index 000000000..721da6604
--- /dev/null
+++ b/source/Lib/CommonLib/SEIColourTransform.cpp
@@ -0,0 +1,199 @@
+/* The copyright in this software is being made available under the BSD
+ * License, included below. This software may be subject to other third party
+ * and contributor rights, including patent rights, and no such rights are
+ * granted under this license.
+ *
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
+ * 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.
+ *  * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
+ *    be used to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * 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     SEIColourTransform.cpp
+     \brief    Colour transform SEI
+ */
+
+#include "SEIColourTransform.h"
+
+#include "SEI.h"
+#include "Unit.h"
+#include "Buffer.h"
+
+SEIColourTransformApply::SEIColourTransformApply()
+  : m_width               (0)
+  , m_height              (0)
+  , m_chromaFormat        (NUM_CHROMA_FORMAT)
+  , m_bitDepth            (0)
+  , m_pColourTransfParams (NULL)
+{
+}
+
+void SEIColourTransformApply::create(uint32_t width, uint32_t height, ChromaFormat fmt, uint8_t bitDepth)
+{
+  m_width               = width;
+  m_height              = height;
+  m_chromaFormat        = fmt;
+  m_bitDepth            = bitDepth;
+  m_pColourTransfParams = new SEIColourTransformInfo;
+  m_lutSize             = 1 << m_bitDepth;
+  for (int i = 0; i < MAX_NUM_COMPONENT; i++)
+  {
+    m_mapLut[i].resize(m_lutSize, 0);
+  }
+}
+
+SEIColourTransformApply::~SEIColourTransformApply()
+{
+  delete m_pColourTransfParams;
+}
+
+void SEIColourTransformApply::inverseColourTransform(PelStorage* transformBuf)
+{
+  uint8_t   numComp = m_chromaFormat ? MAX_NUM_COMPONENT : 1;
+  PelBuf*   buffY   = &transformBuf->Y();
+  PelBuf*   buffCb  = &transformBuf->Cb();
+  PelBuf*   buffCr  = &transformBuf->Cr();
+
+  if (numComp == 3)
+  {
+    if (m_pColourTransfParams->m_crossComponentFlag) 
+    {
+      buffCb->applyChromaCTI(buffY->buf, buffY->stride, m_mapLut[COMPONENT_Cb], m_bitDepth, m_chromaFormat, false);
+      buffCr->applyChromaCTI(buffY->buf, buffY->stride, m_mapLut[COMPONENT_Cr], m_bitDepth, m_chromaFormat, false);
+    }
+    else 
+    {
+      buffCb->applyLumaCTI(m_mapLut[COMPONENT_Cb]); // apply direct mapping like in luma (no cross component mapping); same function, but different lut.
+      buffCr->applyLumaCTI(m_mapLut[COMPONENT_Cr]);
+    }
+  }
+  buffY->applyLumaCTI(m_mapLut[COMPONENT_Y]);
+}
+
+void SEIColourTransformApply::generateColourTransfLUTs()
+{
+  uint8_t numComp     = m_chromaFormat ? MAX_NUM_COMPONENT : 1;
+  int numPreLutPoints = 1 << m_pColourTransfParams->m_log2NumberOfPointsPerLut;
+  int dynamicRange    = 1 << m_bitDepth;
+  const int orgCW     = dynamicRange / numPreLutPoints;
+  int scalingPreLut   = 1 << ( 11 - (int)floorLog2(orgCW) ); // scale-up values from cfg file (chroma preLut is scaled down in cfg)
+
+  std::vector<Pel> pivotInPoints;
+  std::vector<Pel> pivotMappedPointsY(numPreLutPoints+1);
+  std::vector<Pel> pivotMappedPointsX(numPreLutPoints+1);
+
+  // Create Inverse Luma LUT - same for all possible combinations of ctiCrossComp and ctiChromaLutInferred
+
+  std::vector<int> invScale(numPreLutPoints);
+
+  pivotInPoints = m_pColourTransfParams->m_lut[0].lutValues;
+  pivotMappedPointsX[0] = pivotInPoints[0];
+  pivotMappedPointsY[0] = 0;
+  for (int j = 1; j < numPreLutPoints; j++) 
+  {
+    pivotMappedPointsX[j] = pivotMappedPointsX[j - 1] + pivotInPoints[j];
+    pivotMappedPointsY[j] = j * orgCW;
+  }
+
+  for (int i = 0; i < numPreLutPoints; i++)
+  {
+    invScale[i] = ((int32_t)m_pColourTransfParams->m_lut[0].lutValues[i + 1] * (1 << FP_PREC) + (1 << (floorLog2(orgCW) - 1))) >> floorLog2(orgCW);
+  }
+
+  for (int i = 0; i < dynamicRange; i++)
+  {
+    int idx = i / orgCW;
+    int tempVal = pivotMappedPointsX[idx] + ((invScale[idx] * (i - pivotMappedPointsY[idx]) + (1 << (FP_PREC - 1))) >> FP_PREC);
+    m_mapLut[0][i] = Clip3((Pel)0, (Pel)(dynamicRange - 1), (Pel)(tempVal));
+  }
+
+  //  calculate chroma LUTs
+  if (m_pColourTransfParams->m_crossComponentInferred == 0)
+  {    
+    for (int i = 1; i < numComp; i++) 
+    { // loop for U and V
+      if (m_pColourTransfParams->m_crossComponentFlag == 1)
+      {
+        // cross-component U and V LUT
+        for (int j = 0; j < dynamicRange; j++) 
+        {
+          int     idx     = j / orgCW;
+          int  slope = scalingPreLut * (m_pColourTransfParams->m_lut[i].lutValues[idx + 1] - m_pColourTransfParams->m_lut[i].lutValues[idx]);
+          m_mapLut[i][j] = scalingPreLut * m_pColourTransfParams->m_lut[i].lutValues[idx] + slope * (j - pivotMappedPointsY[idx]) / orgCW;
+        }
+      }
+      else
+      {
+        // intra-component Chroma (U and V) LUT
+        // initialize pivot points
+        pivotInPoints = m_pColourTransfParams->m_lut[i].lutValues;
+        pivotMappedPointsX[0] = pivotInPoints[0];
+        for (int j = 1; j <= numPreLutPoints; j++) 
+        {
+          pivotMappedPointsX[j] = pivotMappedPointsX[j-1] + pivotInPoints[j];
+        }
+
+        for (int i = 0; i < numPreLutPoints; i++)
+        {
+          invScale[i] = ((int32_t)m_pColourTransfParams->m_lut[0].lutValues[i + 1] * (1 << FP_PREC) + (1 << (floorLog2(orgCW) - 1))) >> floorLog2(orgCW);
+        }
+
+        for (int j = 0; j < dynamicRange; j++) 
+        {
+          int idx = j / orgCW;
+          int tempVal = pivotMappedPointsX[idx] + ((invScale[idx] * (j - pivotMappedPointsY[idx]) + (1 << (FP_PREC - 1))) >> FP_PREC);
+          m_mapLut[i][j] = Clip3((Pel)0, (Pel)(dynamicRange - 1), (Pel)(tempVal));
+        }
+      }
+    }
+  }
+  else
+  {
+    int chrOffset = m_pColourTransfParams->m_chromaOffset;
+
+    std::vector<int> chromaAdjHelpLUT (numPreLutPoints);
+    for (int i = 0; i < numPreLutPoints; i++)
+    {
+      chromaAdjHelpLUT[i] = (m_pColourTransfParams->m_lut[0].lutValues[i + 1] == 0) ? (1 << CSCALE_FP_PREC) : ((int32_t)((m_pColourTransfParams->m_lut[0].lutValues[i + 1] + chrOffset) * (1 << FP_PREC) / orgCW));
+    }
+
+    // generate smoothed chroma LUT as done by JVET-U0078
+    std::vector<int> interpLut(numPreLutPoints + 1);
+    for (int i = 1; i < numPreLutPoints; i++) 
+    {
+      interpLut[i] = (chromaAdjHelpLUT[i] + chromaAdjHelpLUT[i - 1] + 1) / 2;
+    }
+    interpLut[0]                = chromaAdjHelpLUT[0];
+    interpLut[numPreLutPoints]  = chromaAdjHelpLUT[numPreLutPoints - 1];
+
+    for (int i = 0; i < dynamicRange; i++)
+    {
+      int idx = i / orgCW;
+      int slope = interpLut[idx + 1] - interpLut[idx];
+      m_mapLut[1][i] = interpLut[idx] + slope * (i - pivotMappedPointsY[idx]) / orgCW;
+      m_mapLut[2][i] = m_mapLut[1][i];
+    }
+  }
+}
diff --git a/source/Lib/CommonLib/SEIColourTransform.h b/source/Lib/CommonLib/SEIColourTransform.h
new file mode 100644
index 000000000..feebfe7ae
--- /dev/null
+++ b/source/Lib/CommonLib/SEIColourTransform.h
@@ -0,0 +1,71 @@
+/* The copyright in this software is being made available under the BSD
+ * License, included below. This software may be subject to other third party
+ * and contributor rights, including patent rights, and no such rights are
+ * granted under this license.
+ *
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
+ * 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.
+ *  * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
+ *    be used to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * 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     SEIColourTransform.h
+     \brief    Colour transform SEI
+ */
+
+#ifndef __SEIFILMCOLOURTRANFORMAPPLY__
+#define __SEIFILMCOLOURTRANFORMAPPLY__
+
+#include "CommonDef.h"
+//! \ingroup CommonLib
+//! \{
+
+struct PelStorage;
+class SEIColourTransformInfo;
+
+class SEIColourTransformApply
+{
+private:
+  uint32_t                     m_width;
+  uint32_t                     m_height;
+  ChromaFormat                 m_chromaFormat;
+  uint8_t                      m_bitDepth;
+  uint32_t                     m_lutSize;
+  std::vector<Pel>             m_mapLut[MAX_NUM_COMPONENT];
+
+public:
+  SEIColourTransformInfo*      m_pColourTransfParams;
+
+public:
+  SEIColourTransformApply();
+  virtual ~SEIColourTransformApply();
+
+  void create                   (uint32_t width, uint32_t height, ChromaFormat fmt, uint8_t bitDepth);
+  void inverseColourTransform   (PelStorage* transformBuf);
+  void generateColourTransfLUTs ();
+
+};// END CLASS DEFINITION SEIColourTransformApply
+
+#endif
\ No newline at end of file
diff --git a/source/Lib/CommonLib/SampleAdaptiveOffset.cpp b/source/Lib/CommonLib/SampleAdaptiveOffset.cpp
index a34b44676..1eed30383 100644
--- a/source/Lib/CommonLib/SampleAdaptiveOffset.cpp
+++ b/source/Lib/CommonLib/SampleAdaptiveOffset.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/CommonLib/SampleAdaptiveOffset.h b/source/Lib/CommonLib/SampleAdaptiveOffset.h
index b8b47d48f..e2487056b 100644
--- a/source/Lib/CommonLib/SampleAdaptiveOffset.h
+++ b/source/Lib/CommonLib/SampleAdaptiveOffset.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/CommonLib/Slice.cpp b/source/Lib/CommonLib/Slice.cpp
index 7531b345c..55461434f 100644
--- a/source/Lib/CommonLib/Slice.cpp
+++ b/source/Lib/CommonLib/Slice.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -74,11 +74,17 @@ Slice::Slice()
 , m_deblockingFilterCrBetaOffsetDiv2( 0 )
 , m_deblockingFilterCrTcOffsetDiv2  ( 0 )
 , m_depQuantEnabledFlag             ( false )
+#if JVET_W0046_RLSCP
+, m_reverseLastSigCoeffFlag         ( false )
+#endif
 , m_signDataHidingEnabledFlag       ( false )
 , m_tsResidualCodingDisabledFlag  ( false )
 , m_pendingRasInit                ( false )
 , m_bCheckLDC                     ( false )
 , m_biDirPred                    ( false )
+#if JVET_W0133_CONSTRAINED_RASL_ENCODING
+, m_lmChromaCheckDisable          ( false )
+#endif
 , m_iSliceQpDelta                 ( 0 )
 , m_iDepth                        ( 0 )
 , m_pcSPS                         ( NULL )
@@ -98,11 +104,21 @@ Slice::Slice()
 , m_substreamSizes                ( )
 , m_numEntryPoints                ( 0 )
 , m_cabacInitFlag                 ( false )
- , m_sliceSubPicId               ( 0 )
+, m_sliceSubPicId                 ( 0 )
 , m_encCABACTableIdx              (I_SLICE)
 , m_iProcessingStartTime          ( 0 )
 , m_dProcessingTime               ( 0 )
+, m_tsrc_index                    ( 0 )
 {
+  for (uint32_t i = 0; i < MAX_TSRC_RICE; i++)
+  {
+    m_riceBit[i] = 0;
+  }
+
+#if JVET_W0046_RLSCP
+  m_cnt_right_bottom = 0;
+#endif
+
   for(uint32_t i=0; i<NUM_REF_PIC_LIST_01; i++)
   {
     m_aiNumRefIdx[i] = 0;
@@ -141,9 +157,9 @@ Slice::Slice()
 
   memset(m_alfApss, 0, sizeof(m_alfApss));
   m_ccAlfFilterParam.reset();
-  resetTileGroupAlfEnabledFlag();
-  resetTileGroupCcAlCbfEnabledFlag();
-  resetTileGroupCcAlCrfEnabledFlag();
+  resetAlfEnabledFlag();
+  resetCcAlCbfEnabledFlag();
+  resetCcAlCrfEnabledFlag();
 
   m_sliceMap.initSliceMap();
 }
@@ -171,6 +187,9 @@ void Slice::initSlice()
   m_bCheckLDC = false;
 
   m_biDirPred = false;
+#if JVET_W0133_CONSTRAINED_RASL_ENCODING
+  m_lmChromaCheckDisable = false;
+#endif
   m_symRefIdx[0] = -1;
   m_symRefIdx[1] = -1;
 
@@ -189,12 +208,20 @@ void Slice::initSlice()
   m_useLTforDRAP         = false;
   m_isDRAP               = false;
   m_latestDRAPPOC        = MAX_INT;
-  resetTileGroupAlfEnabledFlag();
+  m_edrapRapId           = 0;
+  m_enableEdrapSEI       = false;
+  m_edrapRapId           = 0;
+  m_useLTforEdrap        = false;
+  m_edrapNumRefRapPics   = 0;
+  m_edrapRefRapIds.resize(0);
+  m_latestEDRAPPOC       = MAX_INT;
+  m_latestEdrapLeadingPicDecodableFlag = false;
+  resetAlfEnabledFlag();
   m_ccAlfFilterParam.reset();
-  m_tileGroupCcAlfCbEnabledFlag = 0;
-  m_tileGroupCcAlfCrEnabledFlag = 0;
-  m_tileGroupCcAlfCbApsId = -1;
-  m_tileGroupCcAlfCrApsId = -1;
+  m_ccAlfCbEnabledFlag = 0;
+  m_ccAlfCrEnabledFlag = 0;
+  m_ccAlfCbApsId = -1;
+  m_ccAlfCrApsId = -1;
   m_nuhLayerId = 0;
 }
 
@@ -238,16 +265,16 @@ void Slice::inheritFromPicHeader( PicHeader *picHeader, const PPS *pps, const SP
   setSaoEnabledFlag(CHANNEL_TYPE_LUMA,     picHeader->getSaoEnabledFlag(CHANNEL_TYPE_LUMA));
   setSaoEnabledFlag(CHANNEL_TYPE_CHROMA,   picHeader->getSaoEnabledFlag(CHANNEL_TYPE_CHROMA));
 
-  setTileGroupAlfEnabledFlag(COMPONENT_Y,  picHeader->getAlfEnabledFlag(COMPONENT_Y));
-  setTileGroupAlfEnabledFlag(COMPONENT_Cb, picHeader->getAlfEnabledFlag(COMPONENT_Cb));
-  setTileGroupAlfEnabledFlag(COMPONENT_Cr, picHeader->getAlfEnabledFlag(COMPONENT_Cr));
-  setTileGroupNumAps(picHeader->getNumAlfAps());
-  setAlfAPSs(picHeader->getAlfAPSs());
-  setTileGroupApsIdChroma(picHeader->getAlfApsIdChroma());
-  setTileGroupCcAlfCbEnabledFlag(picHeader->getCcAlfEnabledFlag(COMPONENT_Cb));
-  setTileGroupCcAlfCrEnabledFlag(picHeader->getCcAlfEnabledFlag(COMPONENT_Cr));
-  setTileGroupCcAlfCbApsId(picHeader->getCcAlfCbApsId());
-  setTileGroupCcAlfCrApsId(picHeader->getCcAlfCrApsId());
+  setAlfEnabledFlag(COMPONENT_Y,  picHeader->getAlfEnabledFlag(COMPONENT_Y));
+  setAlfEnabledFlag(COMPONENT_Cb, picHeader->getAlfEnabledFlag(COMPONENT_Cb));
+  setAlfEnabledFlag(COMPONENT_Cr, picHeader->getAlfEnabledFlag(COMPONENT_Cr));
+  setNumAlfApsIdsLuma(picHeader->getNumAlfApsIdsLuma());
+  setAlfApsIdsLuma(picHeader->getAlfApsIdsLuma());
+  setAlfApsIdChroma(picHeader->getAlfApsIdChroma());
+  setCcAlfCbEnabledFlag(picHeader->getCcAlfEnabledFlag(COMPONENT_Cb));
+  setCcAlfCrEnabledFlag(picHeader->getCcAlfEnabledFlag(COMPONENT_Cr));
+  setCcAlfCbApsId(picHeader->getCcAlfCbApsId());
+  setCcAlfCrApsId(picHeader->getCcAlfCrApsId());
   m_ccAlfFilterParam.ccAlfFilterEnabled[COMPONENT_Cb - 1] = picHeader->getCcAlfEnabledFlag(COMPONENT_Cb);
   m_ccAlfFilterParam.ccAlfFilterEnabled[COMPONENT_Cr - 1] = picHeader->getCcAlfEnabledFlag(COMPONENT_Cr);
 }
@@ -490,8 +517,7 @@ void Slice::constructRefPicList(PicList& rcListPic)
       pcRefPic = xGetRefPic( rcListPic, getPOC(), refLayerId );
       pcRefPic->longTerm = true;
     }
-    else
-    if (!m_RPL1.isRefPicLongterm(ii))
+    else if (!m_RPL1.isRefPicLongterm(ii))
     {
       pcRefPic = xGetRefPic(rcListPic, getPOC() + m_RPL1.getRefPicIdentifier(ii), m_pcPic->layerId);
       pcRefPic->longTerm = false;
@@ -614,7 +640,7 @@ void Slice::checkRPL(const ReferencePictureList* pRPL0, const ReferencePictureLi
 
   int irapPOC = getAssociatedIRAPPOC();
 
-  const int numEntries[] = { pRPL0->getNumberOfShorttermPictures() + pRPL0->getNumberOfLongtermPictures() + pRPL0->getNumberOfInterLayerPictures(), pRPL1->getNumberOfShorttermPictures() + pRPL1->getNumberOfLongtermPictures() + pRPL1->getNumberOfInterLayerPictures() };
+  int numEntries[] = { pRPL0->getNumberOfShorttermPictures() + pRPL0->getNumberOfLongtermPictures() + pRPL0->getNumberOfInterLayerPictures(), pRPL1->getNumberOfShorttermPictures() + pRPL1->getNumberOfLongtermPictures() + pRPL1->getNumberOfInterLayerPictures() };
   const int numActiveEntries[] = { getNumRefIdx( REF_PIC_LIST_0 ), getNumRefIdx( REF_PIC_LIST_1 ) };
   const ReferencePictureList* rpl[] = { pRPL0, pRPL1 };
   const bool fieldSeqFlag = getSPS()->getFieldSeqFlag();
@@ -666,9 +692,7 @@ void Slice::checkRPL(const ReferencePictureList* pRPL0, const ReferencePictureLi
         }
 
         // Generated reference picture does not have picture header
-        const bool isGeneratedRefPic = pcRefPic->slices[0]->getPicHeader() ? false : true;
-
-        const bool nonReferencePictureFlag = isGeneratedRefPic ? pcRefPic->slices[0]->getPicHeader()->getNonReferencePictureFlag() : pcRefPic->nonReferencePictureFlag;
+        const bool nonReferencePictureFlag = pcRefPic->nonReferencePictureFlag;
         CHECK( pcRefPic == m_pcPic || nonReferencePictureFlag, "The picture referred to by each entry in RefPicList[ 0 ] or RefPicList[ 1 ] shall not be the current picture and shall have ph_non_ref_pic_flag equal to 0" );
 
         if( i < numActiveEntries[refPicList] )
@@ -685,23 +709,20 @@ void Slice::checkRPL(const ReferencePictureList* pRPL0, const ReferencePictureLi
           if( m_eNalUnitType == NAL_UNIT_CODED_SLICE_RADL )
           {
             CHECK( refPicDecodingOrderNumber < associatedIRAPDecodingOrderNumber, "RADL picture detected that violate the rule that no active entry in RefPicList[] shall precede the associated IRAP picture in decoding order" );
-#if JVET_S0084_S0110_RADL
-            // Checking this: "When the current picture is a RADL picture, there shall be no active entry in RefPicList[ 0 ] or 
+            // Checking this: "When the current picture is a RADL picture, there shall be no active entry in RefPicList[ 0 ] or
             // RefPicList[ 1 ] that is any of the following: A RASL picture with pps_mixed_nalu_types_in_pic_flag is equal to 0
             for (int i = 0; i < pcRefPic->numSlices; i++)
             {
-              if (pcRefPic->slices[i]->getPPS()->getMixedNaluTypesInPicFlag() == 0)
+              if (!pcRefPic->mixedNaluTypesInPicFlag)
               {
                 CHECK(pcRefPic->slices[i]->getNalUnitType() == NAL_UNIT_CODED_SLICE_RASL, "When the current picture is a RADL picture, there shall be no active entry in RefPicList[ 0 ] or RefPicList[ 1 ] that is a RASL picture with pps_mixed_nalu_types_in_pic_flag is equal to 0");
               }
             }
-#endif
 
           }
 
           CHECK( pcRefPic->temporalId > m_pcPic->temporalId, "The picture referred to by each active entry in RefPicList[ 0 ] or RefPicList[ 1 ] shall be present in the DPB and shall have TemporalId less than or equal to that of the current picture." );
         }
-#if JVET_R0046_IRAP_ASPECT2
         // Add a constraint on an ILRP being either an IRAP picture or having TemporalId less than or equal to
         // Max (0, vps_max_tid_il_ref_pics_plus1[ refPicVpsLayerId ] - 1 ), with refPicVpsLayerId equal to the value of
         // the nuh_layer_id of the referenced picture.
@@ -710,12 +731,13 @@ void Slice::checkRPL(const ReferencePictureList* pRPL0, const ReferencePictureLi
           bool cond1      = (pcRefPic->getPictureType() == NAL_UNIT_CODED_SLICE_GDR);
           bool cond2      = (pcRefPic->slices[0]->getPicHeader()->getRecoveryPocCnt() == 0);
           bool cond3      = (pcRefPic->cs->slice->isIRAP());
-          
+
           const VPS *vps                  = pcRefPic->cs->vps;
-          const int  maxTidILRefPicsPlus1 = vps->getMaxTidIlRefPicsPlus1(layerIdx, pcRefPic->layerId);
+          const int  maxTidILRefPicsPlus1 =
+            vps->getMaxTidIlRefPicsPlus1(layerIdx, vps->getGeneralLayerIdx(pcRefPic->layerId));
           bool cond4 = (pcRefPic->temporalId < maxTidILRefPicsPlus1);
 
-          CHECK((cond1 && cond2) || cond3 || cond4,
+          CHECK(!((cond1 && cond2) || cond3 || cond4),
                 "Either of the following conditions shall apply for the picture referred to by each ILRP entry, when "
                 "present, in RefPicList[ 0 ] or RefPicList[ 1 ] of a slice of the current picture:-The picture is a "
                 "GDR picture with "
@@ -724,7 +746,6 @@ void Slice::checkRPL(const ReferencePictureList* pRPL0, const ReferencePictureLi
                 "where currLayerIdx and refLayerIdx are equal to "
                 "GeneralLayerIdx[ nuh_layer_id ] and GeneralLayerIdx[ refpicLayerId ], respectively. ");
         }
-#endif
       }
     }
   }
@@ -901,6 +922,16 @@ void Slice::copySliceInfo(Slice *pSrc, bool cpyAlmostAll)
   m_depQuantEnabledFlag               = pSrc->m_depQuantEnabledFlag;
   m_signDataHidingEnabledFlag         = pSrc->m_signDataHidingEnabledFlag;
   m_tsResidualCodingDisabledFlag      = pSrc->m_tsResidualCodingDisabledFlag;
+  m_tsrc_index                        = pSrc->m_tsrc_index;
+
+  for (i = 0; i < MAX_TSRC_RICE; i++)
+  {
+    m_riceBit[i] = pSrc->m_riceBit[i];
+  }
+#if JVET_W0046_RLSCP
+  m_reverseLastSigCoeffFlag = pSrc->m_reverseLastSigCoeffFlag;
+  m_cnt_right_bottom        = pSrc->m_cnt_right_bottom;
+#endif
 
   for (i = 0; i < NUM_REF_PIC_LIST_01; i++)
   {
@@ -916,6 +947,9 @@ void Slice::copySliceInfo(Slice *pSrc, bool cpyAlmostAll)
   m_iSliceQpDelta        = pSrc->m_iSliceQpDelta;
 
   m_biDirPred = pSrc->m_biDirPred;
+#if JVET_W0133_CONSTRAINED_RASL_ENCODING
+  m_lmChromaCheckDisable = pSrc->m_lmChromaCheckDisable;;
+#endif
   m_symRefIdx[0] = pSrc->m_symRefIdx[0];
   m_symRefIdx[1] = pSrc->m_symRefIdx[1];
 
@@ -935,20 +969,35 @@ void Slice::copySliceInfo(Slice *pSrc, bool cpyAlmostAll)
     }
     m_bIsUsedAsLongTerm[i][MAX_NUM_REF] = pSrc->m_bIsUsedAsLongTerm[i][MAX_NUM_REF];
   }
-  if( cpyAlmostAll ) m_iDepth = pSrc->m_iDepth;
+  if (cpyAlmostAll)
+  {
+    m_iDepth = pSrc->m_iDepth;
+  }
 
   // access channel
-  if (cpyAlmostAll) m_RPL0 = pSrc->m_RPL0;
-  if (cpyAlmostAll) m_RPL1 = pSrc->m_RPL1;
+  if (cpyAlmostAll)
+  {
+    m_RPL0 = pSrc->m_RPL0;
+  }
+  if (cpyAlmostAll)
+  {
+    m_RPL1 = pSrc->m_RPL1;
+  }
   m_iLastIDR             = pSrc->m_iLastIDR;
 
-  if( cpyAlmostAll ) m_pcPic  = pSrc->m_pcPic;
+  if (cpyAlmostAll)
+  {
+    m_pcPic = pSrc->m_pcPic;
+  }
 
   m_pcPicHeader          = pSrc->m_pcPicHeader;
   m_colFromL0Flag        = pSrc->m_colFromL0Flag;
   m_colRefIdx            = pSrc->m_colRefIdx;
 
-  if( cpyAlmostAll ) setLambdas(pSrc->getLambdas());
+  if (cpyAlmostAll)
+  {
+    setLambdas(pSrc->getLambdas());
+  }
 
   for (i = 0; i < NUM_REF_PIC_LIST_01; i++)
   {
@@ -988,14 +1037,17 @@ void Slice::copySliceInfo(Slice *pSrc, bool cpyAlmostAll)
 
   m_cabacInitFlag                 = pSrc->m_cabacInitFlag;
   memcpy(m_alfApss, pSrc->m_alfApss, sizeof(m_alfApss)); // this might be quite unsafe
-  memcpy( m_tileGroupAlfEnabledFlag, pSrc->m_tileGroupAlfEnabledFlag, sizeof(m_tileGroupAlfEnabledFlag));
-  m_tileGroupNumAps               = pSrc->m_tileGroupNumAps;
-  m_tileGroupLumaApsId            = pSrc->m_tileGroupLumaApsId;
-  m_tileGroupChromaApsId          = pSrc->m_tileGroupChromaApsId;
+  memcpy( m_alfEnabledFlag, pSrc->m_alfEnabledFlag, sizeof(m_alfEnabledFlag));
+  m_numAlfApsIdsLuma              = pSrc->m_numAlfApsIdsLuma;
+  m_alfApsIdsLuma                 = pSrc->m_alfApsIdsLuma;
+  m_alfApsIdChroma                = pSrc->m_alfApsIdChroma;
   m_disableSATDForRd              = pSrc->m_disableSATDForRd;
   m_isLossless = pSrc->m_isLossless;
 
-  if( cpyAlmostAll ) m_encCABACTableIdx  = pSrc->m_encCABACTableIdx;
+  if (cpyAlmostAll)
+  {
+    m_encCABACTableIdx = pSrc->m_encCABACTableIdx;
+  }
   for( int i = 0; i < NUM_REF_PIC_LIST_01; i ++ )
   {
     for (int j = 0; j < MAX_NUM_REF_PICS; j ++ )
@@ -1006,10 +1058,10 @@ void Slice::copySliceInfo(Slice *pSrc, bool cpyAlmostAll)
   m_ccAlfFilterParam                        = pSrc->m_ccAlfFilterParam;
   m_ccAlfFilterControl[0]                   = pSrc->m_ccAlfFilterControl[0];
   m_ccAlfFilterControl[1]                   = pSrc->m_ccAlfFilterControl[1];
-  m_tileGroupCcAlfCbEnabledFlag             = pSrc->m_tileGroupCcAlfCbEnabledFlag;
-  m_tileGroupCcAlfCrEnabledFlag             = pSrc->m_tileGroupCcAlfCrEnabledFlag;
-  m_tileGroupCcAlfCbApsId                   = pSrc->m_tileGroupCcAlfCbApsId;
-  m_tileGroupCcAlfCrApsId                   = pSrc->m_tileGroupCcAlfCrApsId;
+  m_ccAlfCbEnabledFlag             = pSrc->m_ccAlfCbEnabledFlag;
+  m_ccAlfCrEnabledFlag             = pSrc->m_ccAlfCrEnabledFlag;
+  m_ccAlfCbApsId                   = pSrc->m_ccAlfCbApsId;
+  m_ccAlfCrApsId                   = pSrc->m_ccAlfCrApsId;
 }
 
 
@@ -1061,7 +1113,7 @@ void Slice::checkLeadingPictureRestrictions(PicList& rcListPic, const PPS& pps)
   if(this->getAssociatedIRAPPOC() > this->getPOC())
   {
     //check this only when pps_mixed_nalu_types_in_pic_flag is equal to 0
-    if (pps.getMixedNaluTypesInPicFlag() == 0)
+    if (!pps.getMixedNaluTypesInPicFlag())
     {
       // Do not check IRAP pictures since they may get a POC lower than their associated IRAP
       if (nalUnitType < NAL_UNIT_CODED_SLICE_IDR_W_RADL ||
@@ -1075,7 +1127,7 @@ void Slice::checkLeadingPictureRestrictions(PicList& rcListPic, const PPS& pps)
 
   if (this->getAssociatedIRAPPOC() <= this->getPOC())
   {
-    if (pps.getMixedNaluTypesInPicFlag() == 0)
+    if (!pps.getMixedNaluTypesInPicFlag())
     {
       CHECK(nalUnitType == NAL_UNIT_CODED_SLICE_RASL || nalUnitType == NAL_UNIT_CODED_SLICE_RADL, "When a picture is not a leading picture, it shall not be a RADL or RASL picture.");
     }
@@ -1113,41 +1165,44 @@ void Slice::checkLeadingPictureRestrictions(PicList& rcListPic, const PPS& pps)
     }
     const Slice* pcSlice = pcPic->slices[0];
 
-    if (pcSlice->getPicHeader()->getPicOutputFlag() == 1 && !this->getNoOutputOfPriorPicsFlag() && pcPic->layerId == this->m_nuhLayerId)
+    if(pcSlice->getPicHeader()) // Generated reference picture does not have picture header
     {
-      if ((nalUnitType == NAL_UNIT_CODED_SLICE_CRA || nalUnitType == NAL_UNIT_CODED_SLICE_IDR_N_LP || nalUnitType == NAL_UNIT_CODED_SLICE_IDR_W_RADL) && !pps.getMixedNaluTypesInPicFlag())
+      if (pcSlice->getPicHeader()->getPicOutputFlag() == 1 && !this->getNoOutputOfPriorPicsFlag() && pcPic->layerId == this->m_nuhLayerId)
       {
-        CHECK(pcPic->poc >= this->getPOC(), "Any picture, with nuh_layer_id equal to a particular value layerId, that precedes an IRAP picture with nuh_layer_id "
-              "equal to layerId in decoding order shall precede the IRAP picture in output order.");
+        if ((nalUnitType == NAL_UNIT_CODED_SLICE_CRA || nalUnitType == NAL_UNIT_CODED_SLICE_IDR_N_LP || nalUnitType == NAL_UNIT_CODED_SLICE_IDR_W_RADL) && !pps.getMixedNaluTypesInPicFlag())
+        {
+          CHECK(pcPic->poc >= this->getPOC(), "Any picture, with nuh_layer_id equal to a particular value layerId, that precedes an IRAP picture with nuh_layer_id "
+                "equal to layerId in decoding order shall precede the IRAP picture in output order.");
+        }
       }
-    }
 
-    if (pcSlice->getPicHeader()->getPicOutputFlag() == 1 && pcPic->layerId == this->m_nuhLayerId)
-    {
-      if (nalUnitType == NAL_UNIT_CODED_SLICE_RADL)
+      if (pcSlice->getPicHeader()->getPicOutputFlag() == 1 && pcPic->layerId == this->m_nuhLayerId)
       {
-        if (this->getAssociatedIRAPPOC() > pcSlice->getAssociatedIRAPPOC() && !pps.getMixedNaluTypesInPicFlag())
+        if (nalUnitType == NAL_UNIT_CODED_SLICE_RADL)
         {
-          if (this->getAssociatedIRAPPOC() != pcPic->poc)
+          if (this->getAssociatedIRAPPOC() > pcSlice->getAssociatedIRAPPOC() && !pps.getMixedNaluTypesInPicFlag())
           {
-            CHECK(pcPic->poc >= this->getPOC(), "Any picture, with nuh_layer_id equal to a particular value layerId, that precedes an IRAP picture with nuh_layer_id "
-                  "equal to layerId in decoding order shall precede any RADL picture associated with the IRAP picture in output order.");
+            if (this->getAssociatedIRAPPOC() != pcPic->poc)
+            {
+              CHECK(pcPic->poc >= this->getPOC(), "Any picture, with nuh_layer_id equal to a particular value layerId, that precedes an IRAP picture with nuh_layer_id "
+                    "equal to layerId in decoding order shall precede any RADL picture associated with the IRAP picture in output order.");
+            }
           }
         }
       }
-    }
 
-    if (pcSlice->getPicHeader()->getPicOutputFlag() == 1 && !this->getPicHeader()->getNoOutputBeforeRecoveryFlag() && pcPic->layerId == this->m_nuhLayerId
-        && nalUnitType != NAL_UNIT_CODED_SLICE_GDR && this->getPicHeader()->getRecoveryPocCnt() != -1)
-    {
-      if (this->getPOC() == this->getPicHeader()->getRecoveryPocCnt() + this->getPrevGDRInSameLayerPOC())
+      if (pcSlice->getPicHeader()->getPicOutputFlag() == 1 && !this->getPicHeader()->getNoOutputBeforeRecoveryFlag() && pcPic->layerId == this->m_nuhLayerId
+          && nalUnitType != NAL_UNIT_CODED_SLICE_GDR && this->getPicHeader()->getRecoveryPocCnt() != -1)
       {
-        CHECK(pcPic->poc >= this->getPOC(), "Any picture, with nuh_layer_id equal to a particular value layerId, that precedes a recovery point picture with "
-              "nuh_layer_id equal to layerId in decoding order shall precede the recovery point picture in output order.");
+        if (this->getPOC() == this->getPicHeader()->getRecoveryPocCnt() + this->getPrevGDRInSameLayerPOC())
+        {
+          CHECK(pcPic->poc >= this->getPOC(), "Any picture, with nuh_layer_id equal to a particular value layerId, that precedes a recovery point picture with "
+                "nuh_layer_id equal to layerId in decoding order shall precede the recovery point picture in output order.");
+        }
       }
     }
 
-    if ((nalUnitType == NAL_UNIT_CODED_SLICE_RASL || nalUnitType == NAL_UNIT_CODED_SLICE_RADL) && 
+    if ((nalUnitType == NAL_UNIT_CODED_SLICE_RASL || nalUnitType == NAL_UNIT_CODED_SLICE_RADL) &&
       (pcSlice->getNalUnitType() != NAL_UNIT_CODED_SLICE_RASL && pcSlice->getNalUnitType() != NAL_UNIT_CODED_SLICE_RADL) && !pps.getMixedNaluTypesInPicFlag())
     {
       if (pcSlice->getAssociatedIRAPPOC() == this->getAssociatedIRAPPOC() && pcPic->layerId == this->m_nuhLayerId)
@@ -1254,14 +1309,18 @@ void Slice::checkSubpicTypeConstraints(PicList& rcListPic, const ReferencePictur
       bool isBufPicOutput = false;
       int bufSubpicType = NAL_UNIT_INVALID;
       int bufSubpicPrevIRAPSubpicPOC = 0;
-      for (int i = 0; i < bufPic->numSlices; i++)
+
+      if (bufPic->slices[0]->getPicHeader() != NULL) // Generated reference picture does not have picture header
       {
-        if (bufPic->sliceSubpicIdx[i] == curSubpicIdx)
+        for (int i = 0; i < bufPic->numSlices; i++)
         {
-          isBufPicOutput = bufPic->slices[i]->getPicHeader()->getPicOutputFlag();
-          bufSubpicType = bufPic->slices[i]->getNalUnitType();
-          bufSubpicPrevIRAPSubpicPOC = bufPic->slices[i]->getPrevIRAPSubpicPOC();
-          break;
+          if (bufPic->sliceSubpicIdx[i] == curSubpicIdx)
+          {
+            isBufPicOutput = bufPic->slices[i]->getPicHeader()->getPicOutputFlag();
+            bufSubpicType = bufPic->slices[i]->getNalUnitType();
+            bufSubpicPrevIRAPSubpicPOC = bufPic->slices[i]->getPrevIRAPSubpicPOC();
+            break;
+          }
         }
       }
 
@@ -1494,7 +1553,7 @@ void Slice::applyReferencePictureListBasedMarking( PicList& rcListPic, const Ref
   int i, isReference;
   checkLeadingPictureRestrictions(rcListPic, pps);
 
-  bool isNeedToCheck = (this->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP || this->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL) ? false : true;
+  bool isNeedToCheck = (this->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP || this->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL) && !pps.getMixedNaluTypesInPicFlag() ? false : true;
 
   // mark long-term reference pictures in List0
   for( i = 0; i < pRPL0->getNumberOfShorttermPictures() + pRPL0->getNumberOfLongtermPictures() + pRPL0->getNumberOfInterLayerPictures(); i++ )
@@ -1635,7 +1694,9 @@ void Slice::applyReferencePictureListBasedMarking( PicList& rcListPic, const Ref
     Picture* pcPic = *(iterPic++);
 
     if (!pcPic->referenced)
+    {
       continue;
+    }
 
     isReference = 0;
     // loop through all pictures in the Reference Picture Set
@@ -1752,7 +1813,10 @@ int Slice::checkThatAllRefPicsAreAvailable(PicList& rcListPic, const ReferencePi
   int isAvailable = 0;
   int notPresentPoc = 0;
 
-  if (this->isIDRorBLA()) return 0; //Assume that all pic in the DPB will be flushed anyway so no need to check.
+  if (this->isIDRorBLA())
+  {
+    return 0;   // Assume that all pic in the DPB will be flushed anyway so no need to check.
+  }
 
   int numberOfPictures = pRPL->getNumberOfLongtermPictures() + pRPL->getNumberOfShorttermPictures() + pRPL->getNumberOfInterLayerPictures();
   //Check long term ref pics
@@ -1816,7 +1880,7 @@ int Slice::checkThatAllRefPicsAreAvailable(PicList& rcListPic, const ReferencePi
     {
       if (printErrors)
       {
-        msg(ERROR, "\nCurrent picture: %d Long-term reference picture with POC = %3d seems to have been removed or not correctly decoded.", this->getPOC(), notPresentPoc);
+        msg(ERROR, "Error: Current picture: %d Long-term reference picture with POC = %3d seems to have been removed or not correctly decoded.\n", this->getPOC(), notPresentPoc);
       }
       return notPresentPoc;
     }
@@ -1828,7 +1892,9 @@ int Slice::checkThatAllRefPicsAreAvailable(PicList& rcListPic, const ReferencePi
   for (int ii = 0; ii < numberOfPictures; ii++)
   {
     if (pRPL->isRefPicLongterm(ii))
+    {
       continue;
+    }
 
     notPresentPoc = this->getPOC() + pRPL->getRefPicIdentifier(ii);
     isAvailable = 0;
@@ -1847,7 +1913,7 @@ int Slice::checkThatAllRefPicsAreAvailable(PicList& rcListPic, const ReferencePi
     {
       if (printErrors)
       {
-        msg(ERROR, "\nCurrent picture: %d Short-term reference picture with POC = %3d seems to have been removed or not correctly decoded.", this->getPOC(), notPresentPoc);
+        msg(ERROR, "Error: Current picture: %d Short-term reference picture with POC = %3d seems to have been removed or not correctly decoded.\n", this->getPOC(), notPresentPoc);
       }
       return notPresentPoc;
     }
@@ -1926,7 +1992,7 @@ int Slice::checkThatAllRefPicsAreAvailable(PicList& rcListPic, const ReferencePi
     {
       if (printErrors)
       {
-        msg(ERROR, "\nCurrent picture: %d Long-term reference picture with POC = %3d seems to have been removed or not correctly decoded.", this->getPOC(), notPresentPoc);
+        msg(ERROR, "Error: Current picture: %d Long-term reference picture with POC = %3d seems to have been removed or not correctly decoded.\n", this->getPOC(), notPresentPoc);
       }
       *refPicIndex = ii;
       return notPresentPoc;
@@ -1939,7 +2005,9 @@ int Slice::checkThatAllRefPicsAreAvailable(PicList& rcListPic, const ReferencePi
   for (int ii = 0; ii < numberOfPictures; ii++)
   {
     if (pRPL->isRefPicLongterm(ii))
+    {
       continue;
+    }
 
     notPresentPoc = this->getPOC() + pRPL->getRefPicIdentifier(ii);
     isAvailable = 0;
@@ -1958,7 +2026,7 @@ int Slice::checkThatAllRefPicsAreAvailable(PicList& rcListPic, const ReferencePi
     {
       if (printErrors)
       {
-        msg(ERROR, "\nCurrent picture: %d Short-term reference picture with POC = %3d seems to have been removed or not correctly decoded.", this->getPOC(), notPresentPoc);
+        msg(ERROR, "Error: Current picture: %d Short-term reference picture with POC = %3d seems to have been removed or not correctly decoded.\n", this->getPOC(), notPresentPoc);
       }
       *refPicIndex = ii;
       return notPresentPoc;
@@ -1981,8 +2049,7 @@ bool Slice::isPOCInRefPicList(const ReferencePictureList *rpl, int poc )
         return true;
       }
     }
-    else
-    if (rpl->isRefPicLongterm(i))
+    else if (rpl->isRefPicLongterm(i))
     {
       if (poc == rpl->getRefPicIdentifier(i))
       {
@@ -2010,6 +2077,15 @@ bool Slice::isPocRestrictedByDRAP( int poc, bool precedingDRAPInDecodingOrder )
          ( cvsHasPreviousDRAP() && getPOC() > getLatestDRAPPOC() && (precedingDRAPInDecodingOrder || poc < getLatestDRAPPOC()) );
 }
 
+bool Slice::isPocRestrictedByEdrap( int poc )
+{
+  if (!getEnableEdrapSEI())
+  {
+    return false;
+  }
+  return getEdrapRapId() > 0 && poc != getAssociatedIRAPPOC();
+}
+
 void Slice::checkConformanceForDRAP( uint32_t temporalId )
 {
   if (!(isDRAP() || cvsHasPreviousDRAP()))
@@ -2071,6 +2147,59 @@ void Slice::checkConformanceForDRAP( uint32_t temporalId )
   }
 }
 
+void Slice::checkConformanceForEDRAP( uint32_t temporalId )
+{
+  if (!(getEdrapRapId() > 0 || cvsHasPreviousEDRAP()))
+  {
+    return;
+  }
+
+  if (getEdrapRapId() > 0)
+  {
+    if (!(getNalUnitType() == NalUnitType::NAL_UNIT_CODED_SLICE_TRAIL ||
+          getNalUnitType() == NalUnitType::NAL_UNIT_CODED_SLICE_STSA))
+    {
+      msg( WARNING, "Warning, non-conforming bitstream. The EDRAP picture should be a trailing picture.\n");
+    }
+    if ( temporalId != 0)
+    {
+      msg( WARNING, "Warning, non-conforming bitstream. The EDRAP picture shall have a temporal sublayer identifier equal to 0.\n");
+    }
+    for (int i = 0; i < getNumRefIdx(REF_PIC_LIST_0); i++)
+    {
+      if (getRefPic(REF_PIC_LIST_0,i)->getEdrapRapId() < 0)
+      {
+        msg( WARNING, "Warning, non-conforming bitstream. Any picture that is in the same layer and follows the EDRAP picture in both decoding order and output order does not include, in the active entries of its reference picture lists, any picture that is in the same layer and precedes the EDRAP picture in decoding order or output order, with the exception of the referenceablePictures.\n");
+      }
+    }
+    for (int i = 0; i < getNumRefIdx(REF_PIC_LIST_1); i++)
+    {
+      if (getRefPic(REF_PIC_LIST_1,i)->getEdrapRapId() < 0)
+      {
+        msg( WARNING, "Warning, non-conforming bitstream. Any picture that is in the same layer and follows the EDRAP picture in both decoding order and output order does not include, in the active entries of its reference picture lists, any picture that is in the same layer and precedes the EDRAP picture in decoding order or output order, with the exception of the referenceablePictures.\n");
+      }
+    }
+  }
+
+  if (cvsHasPreviousEDRAP() && getPOC() > getLatestEDRAPPOC() && getLatestEdrapLeadingPicDecodableFlag())
+  {
+    for (int i = 0; i < getNumRefIdx(REF_PIC_LIST_0); i++)
+    {
+      if (getRefPic(REF_PIC_LIST_0,i)->getPOC() < getLatestEDRAPPOC() && getRefPic(REF_PIC_LIST_0,i)->getEdrapRapId() < 0)
+      {
+        msg( WARNING, "Warning, non-conforming bitstream. Any picture that is in the same layer and follows the EDRAP picture in decoding order and precedes the EDRAP picture in output order does not include, in the active entries of its reference picture lists, any picture that is in the same layer and precedes the EDRAP picture in decoding order, with the exception of the referenceablePictures. Problem is POC %d in RPL0.\n", getRefPic(REF_PIC_LIST_0,i)->getPOC());
+      }
+    }
+    for (int i = 0; i < getNumRefIdx(REF_PIC_LIST_1); i++)
+    {
+      if (getRefPic(REF_PIC_LIST_1,i)->getPOC() < getLatestEDRAPPOC() && getRefPic(REF_PIC_LIST_1,i)->getEdrapRapId() < 0)
+      {
+        msg( WARNING, "Warning, non-conforming bitstream. Any picture that is in the same layer and follows the EDRAP picture in decoding order and precedes the EDRAP picture in output order does not include, in the active entries of its reference picture lists, any picture that is in the same layer and precedes the EDRAP picture in decoding order, with the exception of the referenceablePictures. Problem is POC %d in RPL1\n", getRefPic(REF_PIC_LIST_1,i)->getPOC());
+      }
+    }
+  }
+}
+
 
 //! get AC and DC values for weighted pred
 void  Slice::getWpAcDcParam(const WPACDCParam *&wp) const
@@ -2184,8 +2313,7 @@ unsigned Slice::getMinPictureDistance() const
   {
     minPicDist = 0;
   }
-  else
-  if( ! isIntra() )
+  else if (!isIntra())
   {
     const int currPOC  = getPOC();
     for (int refIdx = 0; refIdx < getNumRefIdx(REF_PIC_LIST_0); refIdx++)
@@ -2234,9 +2362,6 @@ VPS::VPS()
   {
     m_vpsLayerId[i] = 0;
     m_vpsIndependentLayerFlag[i] = true;
-#if !JVET_R0193
-    m_vpsMaxTidIlRefPicsPlus1[i] = 7;
-#endif
     m_generalLayerIdx[i] = 0;
     for (int j = 0; j < MAX_VPS_LAYERS; j++)
     {
@@ -2330,11 +2455,7 @@ void VPS::deriveOutputLayerSets()
 
   m_numOutputLayersInOls[0] = 1;
   m_outputLayerIdInOls[0][0] = m_vpsLayerId[0];
-#if JVET_R0193_S0141
   m_numSubLayersInLayerInOLS[0][0] = m_ptlMaxTemporalId[m_olsPtlIdx[0]] + 1;
-#else
-  m_numSubLayersInLayerInOLS[0][0] = m_vpsMaxSubLayers;
-#endif
   layerUsedAsOutputLayerFlag[0] = 1;
   for (int i = 1; i < m_maxLayers; i++)
   {
@@ -2353,7 +2474,6 @@ void VPS::deriveOutputLayerSets()
     {
       m_numOutputLayersInOls[i] = 1;
       m_outputLayerIdInOls[i][0] = m_vpsLayerId[i];
-#if JVET_R0193_S0141
       if (m_vpsEachLayerIsAnOlsFlag)
       {
         m_numSubLayersInLayerInOLS[i][0] = m_ptlMaxTemporalId[m_olsPtlIdx[i]] + 1;
@@ -2372,15 +2492,8 @@ void VPS::deriveOutputLayerSets()
               m_numSubLayersInLayerInOLS[i][k] = maxSublayerNeeded;
             }
           }
+        }
       }
-      }
-#else
-      for(int  j = 0; j < i  &&  ( m_vpsOlsModeIdc  ==  0 ); j++ )
-      {
-        m_numSubLayersInLayerInOLS[i][j] = m_vpsMaxTidIlRefPicsPlus1[i];
-      }
-      m_numSubLayersInLayerInOLS[i][i] = m_vpsMaxSubLayers;
-#endif
     }
     else if( m_vpsOlsModeIdc == 1 )
     {
@@ -2389,19 +2502,13 @@ void VPS::deriveOutputLayerSets()
       for( int j = 0; j < m_numOutputLayersInOls[i]; j++ )
       {
         m_outputLayerIdInOls[i][j] = m_vpsLayerId[j];
-#if JVET_R0193_S0141
         m_numSubLayersInLayerInOLS[i][j] = m_ptlMaxTemporalId[m_olsPtlIdx[i]] + 1;
-#else
-        m_numSubLayersInLayerInOLS[i][j] = m_vpsMaxSubLayers;
-#endif
       }
     }
     else if( m_vpsOlsModeIdc == 2 )
     {
       int j = 0;
-#if JVET_R0193
       int highestIncludedLayer = 0;
-#endif
       for( j = 0; j  <  m_maxLayers; j++ )
       {
         m_numSubLayersInLayerInOLS[i][j] = 0;
@@ -2412,17 +2519,11 @@ void VPS::deriveOutputLayerSets()
         if( m_vpsOlsOutputLayerFlag[i][k] )
         {
           layerIncludedInOlsFlag[i][k] = 1;
-#if JVET_R0193
           highestIncludedLayer = k;
-#endif
           layerUsedAsOutputLayerFlag[k] = 1;
           outputLayerIdx[i][j] = k;
           m_outputLayerIdInOls[i][j++] = m_vpsLayerId[k];
-#if JVET_R0193_S0141
           m_numSubLayersInLayerInOLS[i][k] = m_ptlMaxTemporalId[m_olsPtlIdx[i]] + 1;
-#else
-          m_numSubLayersInLayerInOLS[i][k] = m_vpsMaxSubLayers;
-#endif
         }
       }
       m_numOutputLayersInOls[i] = j;
@@ -2433,15 +2534,8 @@ void VPS::deriveOutputLayerSets()
         for( int k = 0; k < numRefLayers[idx]; k++ )
         {
           layerIncludedInOlsFlag[i][refLayerIdx[idx][k]] = 1;
-#if !JVET_R0193
-          if( m_numSubLayersInLayerInOLS[i][ refLayerIdx[idx][k] ] < m_vpsMaxTidIlRefPicsPlus1[ m_outputLayerIdInOls[i][j] ] )
-          {
-            m_numSubLayersInLayerInOLS[i][ refLayerIdx[idx][k] ] =  m_vpsMaxTidIlRefPicsPlus1[ m_outputLayerIdInOls[i][j] ];
-          }
-#endif
         }
       }
-#if JVET_R0193
       for (int k = highestIncludedLayer - 1; k >= 0; k--)
       {
         if (layerIncludedInOlsFlag[i][k] && !m_vpsOlsOutputLayerFlag[i][k])
@@ -2456,7 +2550,6 @@ void VPS::deriveOutputLayerSets()
           }
         }
       }
-#endif
     }
   }
   for (int i = 0; i < m_maxLayers; i++)
@@ -2547,7 +2640,6 @@ void VPS::deriveTargetOutputLayerSet( int targetOlsIdx )
   }
 }
 
-#if JVET_S0163_ON_TARGETOLS_SUBLAYERS
 int VPS::deriveTargetOLSIdx(void)
 {
   int lowestIdx = 0;
@@ -2579,7 +2671,6 @@ uint32_t VPS::getMaxTidinTOls(int m_targetOlsIdx)
   return getPtlMaxTemporalId(getOlsPtlIdx(m_targetOlsIdx));
 }
 
-#endif
 
 // ------------------------------------------------------------------------------------------------
 // Picture Header
@@ -2619,9 +2710,9 @@ PicHeader::PicHeader()
 , m_profDisabledFlag                              ( 0 )
 , m_jointCbCrSignFlag                             ( 0 )
 , m_qpDelta                                       ( 0 )
-, m_numAlfAps                                     ( 0 )
-, m_alfApsId                                      ( 0 )
-, m_alfChromaApsId                                ( 0 )
+, m_numAlfApsIdsLuma                              ( 0 )
+, m_alfApsIdsLuma                                 ( 0 )
+, m_alfApsIdChroma                                ( 0 )
 , m_deblockingFilterOverrideFlag                  ( 0 )
 , m_deblockingFilterDisable                       ( 0 )
 , m_deblockingFilterBetaOffsetDiv2                ( 0 )
@@ -2661,14 +2752,14 @@ PicHeader::PicHeader()
   m_RPL1.setLtrpInSliceHeaderFlag(0);
   m_RPL1.setNumberOfInterLayerPictures( 0 );
 
-  m_alfApsId.resize(0);
+  m_alfApsIdsLuma.resize(0);
 
   resetWpScaling();
 }
 
 PicHeader::~PicHeader()
 {
-  m_alfApsId.resize(0);
+  m_alfApsIdsLuma.resize(0);
 }
 
 /**
@@ -2706,8 +2797,8 @@ void PicHeader::initPicHeader()
   m_profDisabledFlag                              = 0;
   m_jointCbCrSignFlag                             = 0;
   m_qpDelta                                       = 0;
-  m_numAlfAps                                     = 0;
-  m_alfChromaApsId                                = 0;
+  m_numAlfApsIdsLuma                              = 0;
+  m_alfApsIdChroma                                = 0;
   m_deblockingFilterOverrideFlag                  = 0;
   m_deblockingFilterDisable                       = 0;
   m_deblockingFilterBetaOffsetDiv2                = 0;
@@ -2744,7 +2835,11 @@ void PicHeader::initPicHeader()
   m_RPL1.setNumberOfLongtermPictures(0);
   m_RPL1.setLtrpInSliceHeaderFlag(0);
 
-  m_alfApsId.resize(0);
+  m_alfApsIdsLuma.resize(0);
+#if GDR_ENABLED
+  m_inGdrInterval      = false;
+  m_lastGdrIntervalPoc = -1;
+#endif
 }
 
 const WPScalingParam *PicHeader::getWpScaling(const RefPicList refPicList, const int refIdx) const
@@ -2798,9 +2893,14 @@ SPSRExt::SPSRExt()
  : m_transformSkipRotationEnabledFlag   (false)
  , m_transformSkipContextEnabledFlag    (false)
  , m_extendedPrecisionProcessingFlag    (false)
+ , m_tsrcRicePresentFlag                (false)
  , m_intraSmoothingDisabledFlag         (false)
  , m_highPrecisionOffsetsEnabledFlag    (false)
+ , m_rrcRiceExtensionEnableFlag(false)
  , m_persistentRiceAdaptationEnabledFlag(false)
+#if JVET_W0046_RLSCP
+ , m_reverseLastSigCoeffEnabledFlag     (false)
+#endif
  , m_cabacBypassAlignmentEnabledFlag    (false)
 {
 }
@@ -3112,6 +3212,7 @@ PPS::PPS()
 , m_conformanceWindowFlag            (false)
 , m_picWidthInLumaSamples(352)
 , m_picHeightInLumaSamples( 288 )
+, m_explicitScalingWindowFlag        (false)
 , m_wrapAroundEnabledFlag            (false)
 , m_picWidthMinusWrapAroundOffset    (0)
 , m_wrapAroundOffset                 (0)
@@ -3504,7 +3605,7 @@ void PPS::initSubPic(const SPS &sps)
     m_subPics[i].setSubPicWidthInCTUs(sps.getSubPicWidth(i));
     m_subPics[i].setSubPicHeightInCTUs(sps.getSubPicHeight(i));
 
-    uint32_t firstCTU = sps.getSubPicCtuTopLeftY(i) * m_picWidthInCtu + sps.getSubPicCtuTopLeftX(i); 	
+    uint32_t firstCTU = sps.getSubPicCtuTopLeftY(i) * m_picWidthInCtu + sps.getSubPicCtuTopLeftX(i);
     m_subPics[i].setFirstCTUInSubPic(firstCTU);
     uint32_t lastCTU = (sps.getSubPicCtuTopLeftY(i) + sps.getSubPicHeight(i) - 1) * m_picWidthInCtu + sps.getSubPicCtuTopLeftX(i) + sps.getSubPicWidth(i) - 1;
     m_subPics[i].setLastCTUInSubPic(lastCTU);
@@ -3551,7 +3652,7 @@ void PPS::initSubPic(const SPS &sps)
         {
           // add ctus in a slice to the subpicture it belongs to
           m_subPics[i].addCTUsToSubPic(m_sliceMap[j].getCtuAddrList());
-	  numSlicesInSubPic++;
+          numSlicesInSubPic++;
           idxLastSliceInSubpic = j;
         }
         else if (idxFirstSliceAfterSubpic == m_numSlicesInPic && idxLastSliceInSubpic != -1)
@@ -3811,42 +3912,39 @@ bool ScalingList::isNotDefaultScalingList()
   return !isAllDefault;
 }
 
-/** get scaling matrix from RefMatrixID
- * \param sizeId    size index
- * \param listId    index of input matrix
- * \param refListId index of reference matrix
- */
-int ScalingList::lengthUvlc(int uiCode)
+int ScalingList::lengthUvlc(int code)
 {
-  if (uiCode < 0) printf("Error UVLC! \n");
+  CHECK(code < 0,        "Unsigned VLC cannot be negative");
+  CHECK(code == MAX_INT, "Maximum supported UVLC code is MAX_INT-1");
 
-  int uiLength = 1;
-  int uiTemp = ++uiCode;
+  int length = 1;
+  int temp = ++code;
 
-  CHECK(!uiTemp, "Integer overflow");
 
-  while (1 != uiTemp)
+  while (1 != temp)
   {
-    uiTemp >>= 1;
-    uiLength += 2;
+    temp >>= 1;
+    length += 2;
   }
-  return (uiLength >> 1) + ((uiLength + 1) >> 1);
+  return (length >> 1) + ((length + 1) >> 1);
 }
-int ScalingList::lengthSvlc(int uiCode)
+
+int ScalingList::lengthSvlc(int code)
 {
-  uint32_t uiCode2 = uint32_t(uiCode <= 0 ? (-uiCode) << 1 : (uiCode << 1) - 1);
-  int uiLength = 1;
-  int uiTemp = ++uiCode2;
+  uint32_t code2 = uint32_t(code <= 0 ? (-code) << 1 : (code << 1) - 1);
+  int length = 1;
+  int temp = ++code2;
 
-  CHECK(!uiTemp, "Integer overflow");
+  CHECK(temp < 0, "Integer overflow constructing SVLC code");
 
-  while (1 != uiTemp)
+  while (1 != temp)
   {
-    uiTemp >>= 1;
-    uiLength += 2;
+    temp >>= 1;
+    length += 2;
   }
-  return (uiLength >> 1) + ((uiLength + 1) >> 1);
+  return (length >> 1) + ((length + 1) >> 1);
 }
+
 void ScalingList::codePredScalingList(int* scalingList, const int* scalingListPred, int scalingListDC, int scalingListPredDC, int scalingListId, int& bitsCost) //sizeId, listId is current to-be-coded matrix idx
 {
   int deltaValue = 0;
@@ -3886,6 +3984,7 @@ void ScalingList::codePredScalingList(int* scalingList, const int* scalingListPr
     bitsCost += lengthSvlc(data);
   }
 }
+
 void ScalingList::codeScalingList(int* scalingList, int scalingListDC, int scalingListId, int& bitsCost) //sizeId, listId is current to-be-coded matrix idx
 {
   int matrixSize = (scalingListId < SCALING_LIST_1D_START_4x4) ? 2 : (scalingListId < SCALING_LIST_1D_START_8x8) ? 4 : 8;
@@ -3904,7 +4003,9 @@ void ScalingList::codeScalingList(int* scalingList, int scalingListDC, int scali
   for (int i = 0; i < coefNum; i++)
   {
     if (scalingListId >= SCALING_LIST_1D_START_64x64 && scan[i].x >= 4 && scan[i].y >= 4)
+    {
       continue;
+    }
     data = int8_t(src[scan[i].idx] - nextCoef);
     nextCoef = src[scan[i].idx];
 
@@ -3923,18 +4024,20 @@ void ScalingList::CheckBestPredScalingList(int scalingListId, int predListId, in
   int matrixSize = (scalingListId < SCALING_LIST_1D_START_4x4) ? 2 : (scalingListId < SCALING_LIST_1D_START_8x8) ? 4 : 8;
   int predMatrixSize = (predListId < SCALING_LIST_1D_START_4x4) ? 2 : (predListId < SCALING_LIST_1D_START_8x8) ? 4 : 8;
 
-  if (matrixSize != predMatrixSize) printf("Predictor size mismatch! \n");
+  CHECK(matrixSize != predMatrixSize, "Predictor size mismatch");
 
   bitsCost = 2 + lengthUvlc(scalingListId - predListId);
   //copy-flag + predictor-mode-flag + deltaListId
   codePredScalingList(scalingList, scalingListPred, scalingListDC, scalingListPredDC, scalingListId, bitsCost);
   BitsCount = bitsCost;
 }
+
 void ScalingList::processRefMatrix(uint32_t scalinListId, uint32_t refListId)
 {
   int matrixSize = (scalinListId < SCALING_LIST_1D_START_4x4) ? 2 : (scalinListId < SCALING_LIST_1D_START_8x8) ? 4 : 8;
   ::memcpy(getScalingListAddress(scalinListId), ((scalinListId == refListId) ? getScalingListDefaultAddress(refListId) : getScalingListAddress(refListId)), sizeof(int)*matrixSize*matrixSize);
 }
+
 void ScalingList::checkPredMode(uint32_t scalingListId)
 {
   int bestBitsCount = MAX_INT;
@@ -3949,7 +4052,9 @@ void ScalingList::checkPredMode(uint32_t scalingListId)
     int matrixSize = (scalingListId < SCALING_LIST_1D_START_4x4) ? 2 : (scalingListId < SCALING_LIST_1D_START_8x8) ? 4 : 8;
     int predMatrixSize = (predListIdx < SCALING_LIST_1D_START_4x4) ? 2 : (predListIdx < SCALING_LIST_1D_START_8x8) ? 4 : 8;
     if (((scalingListId == SCALING_LIST_1D_START_2x2 || scalingListId == SCALING_LIST_1D_START_4x4 || scalingListId == SCALING_LIST_1D_START_8x8) && predListIdx != (int)scalingListId) || matrixSize != predMatrixSize)
+    {
       continue;
+    }
     const int* refScalingList = (scalingListId == predListIdx) ? getScalingListDefaultAddress(predListIdx) : getScalingListAddress(predListIdx);
     const int refDC = (predListIdx < SCALING_LIST_1D_START_16x16) ? refScalingList[0] : (scalingListId == predListIdx) ? 16 : getScalingListDC(predListIdx);
     if (!::memcmp(getScalingListAddress(scalingListId), refScalingList, sizeof(int)*matrixSize*matrixSize) // check value of matrix
@@ -4230,9 +4335,13 @@ uint32_t PreCalcValues::getValIdx( const Slice &slice, const ChannelType chType
 uint32_t PreCalcValues::getMaxBtDepth( const Slice &slice, const ChannelType chType ) const
 {
   if ( slice.getPicHeader()->getSplitConsOverrideFlag() )
+  {
     return slice.getPicHeader()->getMaxMTTHierarchyDepth( slice.getSliceType(), ISingleTree ? CHANNEL_TYPE_LUMA : chType);
+  }
   else
-  return maxBtDepth[getValIdx( slice, chType )];
+  {
+    return maxBtDepth[getValIdx(slice, chType)];
+  }
 }
 
 uint32_t PreCalcValues::getMinBtSize( const Slice &slice, const ChannelType chType ) const
@@ -4243,9 +4352,13 @@ uint32_t PreCalcValues::getMinBtSize( const Slice &slice, const ChannelType chTy
 uint32_t PreCalcValues::getMaxBtSize( const Slice &slice, const ChannelType chType ) const
 {
   if (slice.getPicHeader()->getSplitConsOverrideFlag())
+  {
     return slice.getPicHeader()->getMaxBTSize( slice.getSliceType(), ISingleTree ? CHANNEL_TYPE_LUMA : chType);
+  }
   else
+  {
     return maxBtSize[getValIdx(slice, chType)];
+  }
 }
 
 uint32_t PreCalcValues::getMinTtSize( const Slice &slice, const ChannelType chType ) const
@@ -4256,16 +4369,24 @@ uint32_t PreCalcValues::getMinTtSize( const Slice &slice, const ChannelType chTy
 uint32_t PreCalcValues::getMaxTtSize( const Slice &slice, const ChannelType chType ) const
 {
   if (slice.getPicHeader()->getSplitConsOverrideFlag())
+  {
     return slice.getPicHeader()->getMaxTTSize( slice.getSliceType(), ISingleTree ? CHANNEL_TYPE_LUMA : chType);
+  }
   else
-  return maxTtSize[getValIdx( slice, chType )];
+  {
+    return maxTtSize[getValIdx(slice, chType)];
+  }
 }
 uint32_t PreCalcValues::getMinQtSize( const Slice &slice, const ChannelType chType ) const
 {
   if (slice.getPicHeader()->getSplitConsOverrideFlag())
+  {
     return slice.getPicHeader()->getMinQTSize( slice.getSliceType(), ISingleTree ? CHANNEL_TYPE_LUMA : chType);
+  }
   else
-  return minQtSize[getValIdx( slice, chType )];
+  {
+    return minQtSize[getValIdx(slice, chType)];
+  }
 }
 
 void Slice::scaleRefPicList( Picture *scaledRefPic[ ], PicHeader *picHeader, APS** apss, APS* lmcsAps, APS* scalingListAps, const bool isDecoder )
@@ -4451,64 +4572,233 @@ bool Slice::checkRPR()
 
 bool             operator == (const ConstraintInfo& op1, const ConstraintInfo& op2)
 {
-  if( op1.m_intraOnlyConstraintFlag                      != op2.m_intraOnlyConstraintFlag                        ) return false;
-  if( op1.m_maxBitDepthConstraintIdc                     != op2.m_maxBitDepthConstraintIdc                       ) return false;
-  if( op1.m_maxChromaFormatConstraintIdc                 != op2.m_maxChromaFormatConstraintIdc                   ) return false;
-  if( op1.m_onePictureOnlyConstraintFlag                 != op2.m_onePictureOnlyConstraintFlag                   ) return false;
-  if( op1.m_lowerBitRateConstraintFlag                   != op2.m_lowerBitRateConstraintFlag                     ) return false;
-  if (op1.m_allLayersIndependentConstraintFlag           != op2.m_allLayersIndependentConstraintFlag             ) return false;
-  if (op1.m_noMrlConstraintFlag                          != op2.m_noMrlConstraintFlag                            ) return false;
-  if (op1.m_noIspConstraintFlag                          != op2.m_noIspConstraintFlag                            ) return false;
-  if (op1.m_noMipConstraintFlag                          != op2.m_noMipConstraintFlag                            ) return false;
-  if (op1.m_noLfnstConstraintFlag                        != op2.m_noLfnstConstraintFlag                          ) return false;
-  if (op1.m_noMmvdConstraintFlag                         != op2.m_noMmvdConstraintFlag                           ) return false;
-  if (op1.m_noSmvdConstraintFlag                         != op2.m_noSmvdConstraintFlag                           ) return false;
-  if (op1.m_noProfConstraintFlag                         != op2.m_noProfConstraintFlag                           ) return false;
-  if (op1.m_noPaletteConstraintFlag                      != op2.m_noPaletteConstraintFlag                        ) return false;
-  if (op1.m_noActConstraintFlag                          != op2.m_noActConstraintFlag                            ) return false;
-  if (op1.m_noLmcsConstraintFlag                         != op2.m_noLmcsConstraintFlag                           ) return false;
-  if (op1.m_noExplicitScaleListConstraintFlag            != op2.m_noExplicitScaleListConstraintFlag              ) return false;
-  if (op1.m_noVirtualBoundaryConstraintFlag              != op2.m_noVirtualBoundaryConstraintFlag                ) return false;
-  if (op1.m_noChromaQpOffsetConstraintFlag               != op2.m_noChromaQpOffsetConstraintFlag                 ) return false;
-  if (op1.m_noRprConstraintFlag                          != op2.m_noRprConstraintFlag                            ) return false;
-  if (op1.m_noResChangeInClvsConstraintFlag              != op2.m_noResChangeInClvsConstraintFlag                ) return false;
-  if (op1.m_noMttConstraintFlag                          != op2.m_noMttConstraintFlag                            ) return false;
-  if( op1.m_noQtbttDualTreeIntraConstraintFlag           != op2.m_noQtbttDualTreeIntraConstraintFlag             ) return false;
-  if( op1.m_noPartitionConstraintsOverrideConstraintFlag != op2.m_noPartitionConstraintsOverrideConstraintFlag   ) return false;
-  if( op1.m_noSaoConstraintFlag                          != op2.m_noSaoConstraintFlag                            ) return false;
-  if( op1.m_noAlfConstraintFlag                          != op2.m_noAlfConstraintFlag                            ) return false;
-  if( op1.m_noCCAlfConstraintFlag                        != op2.m_noCCAlfConstraintFlag                          ) return false;
-  if (op1.m_noWeightedPredictionConstraintFlag           != op2.m_noWeightedPredictionConstraintFlag             ) return false;
-  if( op1.m_noRefWraparoundConstraintFlag                != op2.m_noRefWraparoundConstraintFlag                  ) return false;
-  if( op1.m_noTemporalMvpConstraintFlag                  != op2.m_noTemporalMvpConstraintFlag                    ) return false;
-  if( op1.m_noSbtmvpConstraintFlag                       != op2.m_noSbtmvpConstraintFlag                         ) return false;
-  if( op1.m_noAmvrConstraintFlag                         != op2.m_noAmvrConstraintFlag                           ) return false;
-  if( op1.m_noBdofConstraintFlag                         != op2.m_noBdofConstraintFlag                           ) return false;
-  if( op1.m_noDmvrConstraintFlag                         != op2.m_noDmvrConstraintFlag                           ) return false;
-  if( op1.m_noCclmConstraintFlag                         != op2.m_noCclmConstraintFlag                           ) return false;
-  if( op1.m_noMtsConstraintFlag                          != op2.m_noMtsConstraintFlag                            ) return false;
-  if( op1.m_noSbtConstraintFlag                          != op2.m_noSbtConstraintFlag                            ) return false;
-  if( op1.m_noAffineMotionConstraintFlag                 != op2.m_noAffineMotionConstraintFlag                   ) return false;
-  if( op1.m_noBcwConstraintFlag                          != op2.m_noBcwConstraintFlag                            ) return false;
-  if( op1.m_noIbcConstraintFlag                          != op2.m_noIbcConstraintFlag                            ) return false;
-  if( op1.m_noCiipConstraintFlag                         != op2.m_noCiipConstraintFlag                           ) return false;
-  if( op1.m_noLadfConstraintFlag                         != op2.m_noLadfConstraintFlag                           ) return false;
-  if( op1.m_noTransformSkipConstraintFlag                != op2.m_noTransformSkipConstraintFlag                  ) return false;
-  if( op1.m_noBDPCMConstraintFlag                        != op2.m_noBDPCMConstraintFlag                          ) return false;
-  if( op1.m_noJointCbCrConstraintFlag                    != op2.m_noJointCbCrConstraintFlag                      ) return false;
-  if( op1.m_noCuQpDeltaConstraintFlag                    != op2.m_noCuQpDeltaConstraintFlag                      ) return false;
-  if( op1.m_noDepQuantConstraintFlag                     != op2.m_noDepQuantConstraintFlag                       ) return false;
-  if( op1.m_noSignDataHidingConstraintFlag               != op2.m_noSignDataHidingConstraintFlag                 ) return false;
-  if( op1.m_noTrailConstraintFlag                        != op2.m_noTrailConstraintFlag                          ) return false;
-  if( op1.m_noStsaConstraintFlag                         != op2.m_noStsaConstraintFlag                           ) return false;
-  if( op1.m_noRaslConstraintFlag                         != op2.m_noRaslConstraintFlag                           ) return false;
-  if( op1.m_noRadlConstraintFlag                         != op2.m_noRadlConstraintFlag                           ) return false;
-  if( op1.m_noIdrConstraintFlag                          != op2.m_noIdrConstraintFlag                            ) return false;
-  if( op1.m_noCraConstraintFlag                          != op2.m_noCraConstraintFlag                            ) return false;
-  if( op1.m_noGdrConstraintFlag                          != op2.m_noGdrConstraintFlag                            ) return false;
-  if( op1.m_noApsConstraintFlag                          != op2.m_noApsConstraintFlag                            ) return false;
+  if (op1.m_intraOnlyConstraintFlag != op2.m_intraOnlyConstraintFlag)
+  {
+    return false;
+  }
+  if (op1.m_maxBitDepthConstraintIdc != op2.m_maxBitDepthConstraintIdc)
+  {
+    return false;
+  }
+  if (op1.m_maxChromaFormatConstraintIdc != op2.m_maxChromaFormatConstraintIdc)
+  {
+    return false;
+  }
+  if (op1.m_onePictureOnlyConstraintFlag != op2.m_onePictureOnlyConstraintFlag)
+  {
+    return false;
+  }
+  if (op1.m_lowerBitRateConstraintFlag != op2.m_lowerBitRateConstraintFlag)
+  {
+    return false;
+  }
+  if (op1.m_allLayersIndependentConstraintFlag != op2.m_allLayersIndependentConstraintFlag)
+  {
+    return false;
+  }
+  if (op1.m_noMrlConstraintFlag != op2.m_noMrlConstraintFlag)
+  {
+    return false;
+  }
+  if (op1.m_noIspConstraintFlag != op2.m_noIspConstraintFlag)
+  {
+    return false;
+  }
+  if (op1.m_noMipConstraintFlag != op2.m_noMipConstraintFlag)
+  {
+    return false;
+  }
+  if (op1.m_noLfnstConstraintFlag != op2.m_noLfnstConstraintFlag)
+  {
+    return false;
+  }
+  if (op1.m_noMmvdConstraintFlag != op2.m_noMmvdConstraintFlag)
+  {
+    return false;
+  }
+  if (op1.m_noSmvdConstraintFlag != op2.m_noSmvdConstraintFlag)
+  {
+    return false;
+  }
+  if (op1.m_noProfConstraintFlag != op2.m_noProfConstraintFlag)
+  {
+    return false;
+  }
+  if (op1.m_noPaletteConstraintFlag != op2.m_noPaletteConstraintFlag)
+  {
+    return false;
+  }
+  if (op1.m_noActConstraintFlag != op2.m_noActConstraintFlag)
+  {
+    return false;
+  }
+  if (op1.m_noLmcsConstraintFlag != op2.m_noLmcsConstraintFlag)
+  {
+    return false;
+  }
+  if (op1.m_noExplicitScaleListConstraintFlag != op2.m_noExplicitScaleListConstraintFlag)
+  {
+    return false;
+  }
+  if (op1.m_noVirtualBoundaryConstraintFlag != op2.m_noVirtualBoundaryConstraintFlag)
+  {
+    return false;
+  }
+  if (op1.m_noChromaQpOffsetConstraintFlag != op2.m_noChromaQpOffsetConstraintFlag)
+  {
+    return false;
+  }
+  if (op1.m_noRprConstraintFlag != op2.m_noRprConstraintFlag)
+  {
+    return false;
+  }
+  if (op1.m_noResChangeInClvsConstraintFlag != op2.m_noResChangeInClvsConstraintFlag)
+  {
+    return false;
+  }
+  if (op1.m_noMttConstraintFlag != op2.m_noMttConstraintFlag)
+  {
+    return false;
+  }
+  if (op1.m_noQtbttDualTreeIntraConstraintFlag != op2.m_noQtbttDualTreeIntraConstraintFlag)
+  {
+    return false;
+  }
+  if (op1.m_noPartitionConstraintsOverrideConstraintFlag != op2.m_noPartitionConstraintsOverrideConstraintFlag)
+  {
+    return false;
+  }
+  if (op1.m_noSaoConstraintFlag != op2.m_noSaoConstraintFlag)
+  {
+    return false;
+  }
+  if (op1.m_noAlfConstraintFlag != op2.m_noAlfConstraintFlag)
+  {
+    return false;
+  }
+  if (op1.m_noCCAlfConstraintFlag != op2.m_noCCAlfConstraintFlag)
+  {
+    return false;
+  }
+  if (op1.m_noWeightedPredictionConstraintFlag != op2.m_noWeightedPredictionConstraintFlag)
+  {
+    return false;
+  }
+  if (op1.m_noRefWraparoundConstraintFlag != op2.m_noRefWraparoundConstraintFlag)
+  {
+    return false;
+  }
+  if (op1.m_noTemporalMvpConstraintFlag != op2.m_noTemporalMvpConstraintFlag)
+  {
+    return false;
+  }
+  if (op1.m_noSbtmvpConstraintFlag != op2.m_noSbtmvpConstraintFlag)
+  {
+    return false;
+  }
+  if (op1.m_noAmvrConstraintFlag != op2.m_noAmvrConstraintFlag)
+  {
+    return false;
+  }
+  if (op1.m_noBdofConstraintFlag != op2.m_noBdofConstraintFlag)
+  {
+    return false;
+  }
+  if (op1.m_noDmvrConstraintFlag != op2.m_noDmvrConstraintFlag)
+  {
+    return false;
+  }
+  if (op1.m_noCclmConstraintFlag != op2.m_noCclmConstraintFlag)
+  {
+    return false;
+  }
+  if (op1.m_noMtsConstraintFlag != op2.m_noMtsConstraintFlag)
+  {
+    return false;
+  }
+  if (op1.m_noSbtConstraintFlag != op2.m_noSbtConstraintFlag)
+  {
+    return false;
+  }
+  if (op1.m_noAffineMotionConstraintFlag != op2.m_noAffineMotionConstraintFlag)
+  {
+    return false;
+  }
+  if (op1.m_noBcwConstraintFlag != op2.m_noBcwConstraintFlag)
+  {
+    return false;
+  }
+  if (op1.m_noIbcConstraintFlag != op2.m_noIbcConstraintFlag)
+  {
+    return false;
+  }
+  if (op1.m_noCiipConstraintFlag != op2.m_noCiipConstraintFlag)
+  {
+    return false;
+  }
+  if (op1.m_noLadfConstraintFlag != op2.m_noLadfConstraintFlag)
+  {
+    return false;
+  }
+  if (op1.m_noTransformSkipConstraintFlag != op2.m_noTransformSkipConstraintFlag)
+  {
+    return false;
+  }
+  if (op1.m_noBDPCMConstraintFlag != op2.m_noBDPCMConstraintFlag)
+  {
+    return false;
+  }
+  if (op1.m_noJointCbCrConstraintFlag != op2.m_noJointCbCrConstraintFlag)
+  {
+    return false;
+  }
+  if (op1.m_noCuQpDeltaConstraintFlag != op2.m_noCuQpDeltaConstraintFlag)
+  {
+    return false;
+  }
+  if (op1.m_noDepQuantConstraintFlag != op2.m_noDepQuantConstraintFlag)
+  {
+    return false;
+  }
+  if (op1.m_noSignDataHidingConstraintFlag != op2.m_noSignDataHidingConstraintFlag)
+  {
+    return false;
+  }
+  if (op1.m_noTrailConstraintFlag != op2.m_noTrailConstraintFlag)
+  {
+    return false;
+  }
+  if (op1.m_noStsaConstraintFlag != op2.m_noStsaConstraintFlag)
+  {
+    return false;
+  }
+  if (op1.m_noRaslConstraintFlag != op2.m_noRaslConstraintFlag)
+  {
+    return false;
+  }
+  if (op1.m_noRadlConstraintFlag != op2.m_noRadlConstraintFlag)
+  {
+    return false;
+  }
+  if (op1.m_noIdrConstraintFlag != op2.m_noIdrConstraintFlag)
+  {
+    return false;
+  }
+  if (op1.m_noCraConstraintFlag != op2.m_noCraConstraintFlag)
+  {
+    return false;
+  }
+  if (op1.m_noGdrConstraintFlag != op2.m_noGdrConstraintFlag)
+  {
+    return false;
+  }
+  if (op1.m_noApsConstraintFlag != op2.m_noApsConstraintFlag)
+  {
+    return false;
+  }
   return true;
 }
+
 bool             operator != (const ConstraintInfo& op1, const ConstraintInfo& op2)
 {
   return !(op1 == op2);
@@ -4516,14 +4806,38 @@ bool             operator != (const ConstraintInfo& op1, const ConstraintInfo& o
 
 bool             operator == (const ProfileTierLevel& op1, const ProfileTierLevel& op2)
 {
-  if (op1.m_tierFlag        != op2.m_tierFlag) return false;
-  if (op1.m_profileIdc      != op2.m_profileIdc) return false;
-  if (op1.m_numSubProfile   != op2.m_numSubProfile) return false;
-  if (op1.m_levelIdc        != op2.m_levelIdc) return false;
-  if (op1.m_frameOnlyConstraintFlag != op2.m_frameOnlyConstraintFlag) return false;
-  if (op1.m_multiLayerEnabledFlag   != op2.m_multiLayerEnabledFlag) return false;
-  if (op1.m_constraintInfo  != op2.m_constraintInfo) return false;
-  if (op1.m_subProfileIdc   != op2.m_subProfileIdc) return false;
+  if (op1.m_tierFlag != op2.m_tierFlag)
+  {
+    return false;
+  }
+  if (op1.m_profileIdc != op2.m_profileIdc)
+  {
+    return false;
+  }
+  if (op1.m_numSubProfile != op2.m_numSubProfile)
+  {
+    return false;
+  }
+  if (op1.m_levelIdc != op2.m_levelIdc)
+  {
+    return false;
+  }
+  if (op1.m_frameOnlyConstraintFlag != op2.m_frameOnlyConstraintFlag)
+  {
+    return false;
+  }
+  if (op1.m_multiLayerEnabledFlag != op2.m_multiLayerEnabledFlag)
+  {
+    return false;
+  }
+  if (op1.m_constraintInfo != op2.m_constraintInfo)
+  {
+    return false;
+  }
+  if (op1.m_subProfileIdc != op2.m_subProfileIdc)
+  {
+    return false;
+  }
 
   for (int i = 0; i < MAX_TLAYER - 1; i++)
   {
@@ -4541,6 +4855,7 @@ bool             operator == (const ProfileTierLevel& op1, const ProfileTierLeve
   }
   return true;
 }
+
 bool             operator != (const ProfileTierLevel& op1, const ProfileTierLevel& op2)
 {
   return !(op1 == op2);
@@ -4573,12 +4888,10 @@ void xTraceVPSHeader()
   DTRACE( g_trace_ctx, D_HEADER, "=========== Video Parameter Set     ===========\n" );
 }
 
-#if JVET_S0163_ON_TARGETOLS_SUBLAYERS
 void xTraceOPIHeader()
 {
   DTRACE(g_trace_ctx, D_HEADER, "=========== Operating Point Information     ===========\n");
 }
-#endif
 
 void xTraceDCIHeader()
 {
diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h
index fc7fbeeb2..f328bc56f 100644
--- a/source/Lib/CommonLib/Slice.h
+++ b/source/Lib/CommonLib/Slice.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -923,7 +923,6 @@ public:
   }
 };
 
-#if JVET_S0163_ON_TARGETOLS_SUBLAYERS
 class OPI
 {
 private:
@@ -952,7 +951,6 @@ public:
   void setOpiHtidPlus1(uint32_t val) { m_opihtidplus1 = val; }
 
 };
-#endif
 
 class VPS
 {
@@ -967,11 +965,7 @@ private:
   uint32_t              m_vpsCfgPredDirection[MAX_VPS_SUBLAYERS];
   bool                  m_vpsIndependentLayerFlag[MAX_VPS_LAYERS];
   bool                  m_vpsDirectRefLayerFlag[MAX_VPS_LAYERS][MAX_VPS_LAYERS];
-#if JVET_R0193
   std::vector<std::vector<uint32_t>>              m_vpsMaxTidIlRefPicsPlus1;
-#else
-  uint32_t              m_vpsMaxTidIlRefPicsPlus1[MAX_VPS_LAYERS];
-#endif
   bool                  m_vpsEachLayerIsAnOlsFlag;
   uint32_t              m_vpsOlsModeIdc;
   uint32_t              m_vpsNumOutputLayerSets;
@@ -1045,14 +1039,19 @@ public:
 
   bool              getIndependentLayerFlag(uint32_t layerIdx) const { return m_vpsIndependentLayerFlag[layerIdx]; }
   void              setIndependentLayerFlag(uint32_t layerIdx, bool t) { m_vpsIndependentLayerFlag[layerIdx] = t; }
-#if JVET_R0193
-  uint32_t          getMaxTidIlRefPicsPlus1(uint32_t layerIdx, uint32_t refLayerIdx) const { return m_vpsMaxTidIlRefPicsPlus1[layerIdx][refLayerIdx]; }
-  void              setMaxTidIlRefPicsPlus1(uint32_t layerIdx, uint32_t refLayerIdx, uint32_t i) { m_vpsMaxTidIlRefPicsPlus1[layerIdx][refLayerIdx] = i; }
+  uint32_t getMaxTidIlRefPicsPlus1(const uint32_t layerIdx, const uint32_t refLayerIdx) const
+  {
+    CHECK(layerIdx >= m_vpsMaxTidIlRefPicsPlus1.size(), "layerIdx out of bounds");
+    CHECK(refLayerIdx >= m_vpsMaxTidIlRefPicsPlus1[layerIdx].size(), "refLayerIdx out of bounds");
+    return m_vpsMaxTidIlRefPicsPlus1[layerIdx][refLayerIdx];
+  }
+  void setMaxTidIlRefPicsPlus1(const uint32_t layerIdx, const uint32_t refLayerIdx, const uint32_t i)
+  {
+    CHECK(layerIdx >= m_vpsMaxTidIlRefPicsPlus1.size(), "layerIdx out of bounds");
+    CHECK(refLayerIdx >= m_vpsMaxTidIlRefPicsPlus1[layerIdx].size(), "refLayerIdx out of bounds");
+    m_vpsMaxTidIlRefPicsPlus1[layerIdx][refLayerIdx] = i;
+  }
   void              setMaxTidIlRefPicsPlus1(std::vector<std::vector<uint32_t>> i) { m_vpsMaxTidIlRefPicsPlus1 = i; }
-#else
-  uint32_t          getMaxTidIlRefPicsPlus1(uint32_t layerIdx) const { return m_vpsMaxTidIlRefPicsPlus1[layerIdx]; }
-  void              setMaxTidIlRefPicsPlus1(uint32_t layerIdx, uint32_t i) { m_vpsMaxTidIlRefPicsPlus1[layerIdx] = i; }
-#endif
 
   bool              getDirectRefLayerFlag(uint32_t layerIdx, uint32_t refLayerIdx) const { return m_vpsDirectRefLayerFlag[layerIdx][refLayerIdx]; }
   void              setDirectRefLayerFlag(uint32_t layerIdx, uint32_t refLayerIdx, bool t) { m_vpsDirectRefLayerFlag[layerIdx][refLayerIdx] = t; }
@@ -1132,10 +1131,8 @@ public:
 
   void              deriveOutputLayerSets();
   void              deriveTargetOutputLayerSet( int targetOlsIdx );
-#if JVET_S0163_ON_TARGETOLS_SUBLAYERS
   int               deriveTargetOLSIdx();
   uint32_t          getMaxTidinTOls(int m_targetOlsIdx);
-#endif
 
   void              checkVPS();
 
@@ -1305,11 +1302,17 @@ private:
   bool             m_transformSkipRotationEnabledFlag;
   bool             m_transformSkipContextEnabledFlag;
   bool             m_extendedPrecisionProcessingFlag;
+  bool             m_tsrcRicePresentFlag;
   bool             m_intraSmoothingDisabledFlag;
   bool             m_highPrecisionOffsetsEnabledFlag;
+  bool             m_rrcRiceExtensionEnableFlag;
   bool             m_persistentRiceAdaptationEnabledFlag;
+#if JVET_W0046_RLSCP
+  bool             m_reverseLastSigCoeffEnabledFlag;
+#endif
   bool             m_cabacBypassAlignmentEnabledFlag;
 
+
 public:
   SPSRExt();
 
@@ -1318,9 +1321,14 @@ public:
     return getTransformSkipRotationEnabledFlag()
         || getTransformSkipContextEnabledFlag()
         || getExtendedPrecisionProcessingFlag()
+        || getTSRCRicePresentFlag()
         || getIntraSmoothingDisabledFlag()
         || getHighPrecisionOffsetsEnabledFlag()
+        || getRrcRiceExtensionEnableFlag()
         || getPersistentRiceAdaptationEnabledFlag()
+#if JVET_W0046_RLSCP
+        || getReverseLastSigCoeffEnabledFlag()
+#endif
         || getCabacBypassAlignmentEnabledFlag();
   }
 
@@ -1334,15 +1342,26 @@ public:
   bool getExtendedPrecisionProcessingFlag() const                                      { return m_extendedPrecisionProcessingFlag;      }
   void setExtendedPrecisionProcessingFlag(bool value)                                  { m_extendedPrecisionProcessingFlag = value;     }
 
+  bool getTSRCRicePresentFlag() const                                                  { return m_tsrcRicePresentFlag;                  }
+  void setTSRCRicePresentFlag(bool b)                                                  { m_tsrcRicePresentFlag = b;                     }
+
   bool getIntraSmoothingDisabledFlag() const                                           { return m_intraSmoothingDisabledFlag;           }
   void setIntraSmoothingDisabledFlag(bool bValue)                                      { m_intraSmoothingDisabledFlag=bValue;           }
 
   bool getHighPrecisionOffsetsEnabledFlag() const                                      { return m_highPrecisionOffsetsEnabledFlag;      }
   void setHighPrecisionOffsetsEnabledFlag(bool value)                                  { m_highPrecisionOffsetsEnabledFlag = value;     }
 
+  bool getRrcRiceExtensionEnableFlag()                                                 const { return m_rrcRiceExtensionEnableFlag; }
+  void setRrcRiceExtensionEnableFlag(const bool value)                                       { m_rrcRiceExtensionEnableFlag = value; }
+
   bool getPersistentRiceAdaptationEnabledFlag() const                                  { return m_persistentRiceAdaptationEnabledFlag;  }
   void setPersistentRiceAdaptationEnabledFlag(const bool value)                        { m_persistentRiceAdaptationEnabledFlag = value; }
 
+#if JVET_W0046_RLSCP
+  bool getReverseLastSigCoeffEnabledFlag() const                                       { return m_reverseLastSigCoeffEnabledFlag;       }
+  void setReverseLastSigCoeffEnabledFlag(bool value)                                   { m_reverseLastSigCoeffEnabledFlag = value;      }
+#endif
+
   bool getCabacBypassAlignmentEnabledFlag() const                                      { return m_cabacBypassAlignmentEnabledFlag;      }
   void setCabacBypassAlignmentEnabledFlag(const bool value)                            { m_cabacBypassAlignmentEnabledFlag = value;     }
 };
@@ -1712,8 +1731,11 @@ public:
   void                    setEntropyCodingSyncEnabledFlag(bool val)                                       { m_entropyCodingSyncEnabledFlag = val;                                }
   bool                    getEntryPointsPresentFlag() const                                               { return m_entryPointPresentFlag;                                      }
   void                    setEntryPointsPresentFlag(bool val)                                             { m_entryPointPresentFlag = val;                                       }
-  int                     getMaxLog2TrDynamicRange(ChannelType channelType) const                         { return getSpsRangeExtension().getExtendedPrecisionProcessingFlag() ? std::max<int>(15, int(m_bitDepths.recon[channelType] + 6)) : 15; }
-
+#if JVET_W0178_CONSTRAINTS_ON_REXT_TOOLS
+  int                     getMaxLog2TrDynamicRange(ChannelType channelType) const                         { return getSpsRangeExtension().getExtendedPrecisionProcessingFlag() ? std::min<int>(20, int(m_bitDepths.recon[channelType] + 6)) : 15; }
+#else
+  int                     getMaxLog2TrDynamicRange(ChannelType channelType) const                         { return getSpsRangeExtension().getExtendedPrecisionProcessingFlag() && int(m_bitDepths.recon[channelType]) > 10 ? std::min<int>(20, int(m_bitDepths.recon[channelType] + 6)) : 15; }
+#endif
   int                     getDifferentialLumaChromaBitDepth() const                                       { return int(m_bitDepths.recon[CHANNEL_TYPE_LUMA]) - int(m_bitDepths.recon[CHANNEL_TYPE_CHROMA]); }
   int                     getQpBDOffset(ChannelType type) const                                           { return m_qpBDOffset[type];                                           }
   void                    setQpBDOffset(ChannelType type, int i)                                          { m_qpBDOffset[type] = i;                                              }
@@ -2001,6 +2023,7 @@ private:
   uint32_t         m_picWidthInLumaSamples;
   uint32_t         m_picHeightInLumaSamples;
   Window           m_conformanceWindow;
+  bool             m_explicitScalingWindowFlag;
   Window           m_scalingWindow;
 
   bool             m_wrapAroundEnabledFlag;               //< reference wrap around enabled or not
@@ -2243,11 +2266,13 @@ public:
   const Window&           getConformanceWindow() const                                    { return  m_conformanceWindow; }
   void                    setConformanceWindow( Window& conformanceWindow )               { m_conformanceWindow = conformanceWindow; }
 
+  void                    setExplicitScalingWindowFlag(bool flag)                         { m_explicitScalingWindowFlag = flag; }
+  bool                    getExplicitScalingWindowFlag() const                            { return m_explicitScalingWindowFlag; }
   Window&                 getScalingWindow()                                              { return  m_scalingWindow; }
   const Window&           getScalingWindow()                                        const { return  m_scalingWindow; }
   void                    setScalingWindow( Window& scalingWindow )                       { m_scalingWindow = scalingWindow; }
 
-  int                     getMixedNaluTypesInPicFlag() const                              { return m_mixedNaluTypesInPicFlag; }
+  bool                    getMixedNaluTypesInPicFlag() const                              { return m_mixedNaluTypesInPicFlag; }
   void                    setMixedNaluTypesInPicFlag( const bool flag )                   { m_mixedNaluTypesInPicFlag = flag; }
 };
 
@@ -2335,6 +2360,10 @@ private:
   bool                        m_nonReferencePictureFlag;                                //!< non-reference picture flag
   bool                        m_gdrOrIrapPicFlag;                                       //!< gdr or irap picture flag
   bool                        m_gdrPicFlag;                                             //!< gradual decoding refresh picture flag
+#if GDR_ENABLED
+  bool                        m_inGdrInterval;
+  int                         m_lastGdrIntervalPoc;
+#endif
   uint32_t                    m_recoveryPocCnt;                                         //!< recovery POC count
   bool                        m_noOutputBeforeRecoveryFlag;                             //!< NoOutputBeforeRecoveryFlag
   bool                        m_handleCraAsCvsStartFlag;                                //!< HandleCraAsCvsStartFlag
@@ -2374,9 +2403,9 @@ private:
   int                         m_qpDelta;                                                //!< value of Qp delta
   bool                        m_saoEnabledFlag[MAX_NUM_CHANNEL_TYPE];                   //!< sao enabled flags for each channel
   bool                        m_alfEnabledFlag[MAX_NUM_COMPONENT];                      //!< alf enabled flags for each component
-  int                         m_numAlfAps;                                              //!< number of alf aps active for the picture
-  std::vector<int>            m_alfApsId;                                               //!< list of alf aps for the picture
-  int                         m_alfChromaApsId;                                         //!< chroma alf aps ID
+  int                         m_numAlfApsIdsLuma;                                       //!< number of alf aps active for the picture
+  std::vector<int>            m_alfApsIdsLuma;                                          //!< list of alf aps for the picture
+  int                         m_alfApsIdChroma;                                         //!< chroma alf aps ID
   bool m_ccalfEnabledFlag[MAX_NUM_COMPONENT];
   int  m_ccalfCbApsId;
   int  m_ccalfCrApsId;
@@ -2421,6 +2450,10 @@ public:
   bool                        getGdrOrIrapPicFlag() const                               { return m_gdrOrIrapPicFlag;                                                                   }
   void                        setGdrPicFlag( bool b )                                   { m_gdrPicFlag = b;                                                                            }
   bool                        getGdrPicFlag() const                                     { return m_gdrPicFlag;                                                                         }
+#if GDR_ENABLED
+  void                        setInGdrInterval(bool b)                                  { m_inGdrInterval = b;                                                                         }
+  bool                        getInGdrInterval() const                                  { return m_inGdrInterval;                                                                      }  
+#endif
   void                        setRecoveryPocCnt( uint32_t u )                           { m_recoveryPocCnt = u;                                                                        }
   uint32_t                    getRecoveryPocCnt() const                                 { return m_recoveryPocCnt;                                                                     }
   void                        setSPSId( uint32_t u )                                    { m_spsId = u;                                                                                 }
@@ -2492,17 +2525,16 @@ public:
   bool                        getSaoEnabledFlag(ChannelType chType) const               { return m_saoEnabledFlag[chType];                                                             }
   void                        setAlfEnabledFlag(ComponentID compId, bool b)             { m_alfEnabledFlag[compId] = b;                                                                }
   bool                        getAlfEnabledFlag(ComponentID compId) const               { return m_alfEnabledFlag[compId];                                                             }
-  void                        setNumAlfAps(int i)                                       { m_numAlfAps = i;                                                                             }
-  int                         getNumAlfAps() const                                      { return m_numAlfAps;                                                                          }
-  void                        setAlfApsIdChroma(int i)                                  { m_alfChromaApsId = i;                                                                        }
-  int                         getAlfApsIdChroma() const                                 { return m_alfChromaApsId;                                                                     }
-  void setCcAlfEnabledFlag(ComponentID compId, bool b) { m_ccalfEnabledFlag[compId] = b; }
-  bool getCcAlfEnabledFlag(ComponentID compId) const { return m_ccalfEnabledFlag[compId]; }
-
-  void setCcAlfCbApsId(int i) { m_ccalfCbApsId = i; }
-  int  getCcAlfCbApsId() const { return m_ccalfCbApsId; }
-  void setCcAlfCrApsId(int i) { m_ccalfCrApsId = i; }
-  int  getCcAlfCrApsId() const { return m_ccalfCrApsId; }
+  void                        setNumAlfApsIdsLuma(int i)                                { m_numAlfApsIdsLuma = i;                                                                      }
+  int                         getNumAlfApsIdsLuma() const                               { return m_numAlfApsIdsLuma;                                                                   }
+  void                        setAlfApsIdChroma(int i)                                  { m_alfApsIdChroma = i;                                                                        }
+  int                         getAlfApsIdChroma() const                                 { return m_alfApsIdChroma;                                                                     }
+  void                        setCcAlfEnabledFlag(ComponentID compId, bool b)           { m_ccalfEnabledFlag[compId] = b; }
+  bool                        getCcAlfEnabledFlag(ComponentID compId) const             { return m_ccalfEnabledFlag[compId]; }
+  void                        setCcAlfCbApsId(int i)                                    { m_ccalfCbApsId = i; }
+  int                         getCcAlfCbApsId() const                                   { return m_ccalfCbApsId; }
+  void                        setCcAlfCrApsId(int i)                                    { m_ccalfCrApsId = i; }
+  int                         getCcAlfCrApsId() const                                   { return m_ccalfCrApsId; }
   void                        setDeblockingFilterOverrideFlag( bool b )                 { m_deblockingFilterOverrideFlag = b;                                                          }
   bool                        getDeblockingFilterOverrideFlag() const                   { return m_deblockingFilterOverrideFlag;                                                       }
   void                        setDeblockingFilterDisable( bool b )                      { m_deblockingFilterDisable= b;                                                                }
@@ -2561,14 +2593,14 @@ public:
   unsigned                    getMaxTTSize(SliceType   slicetype,
                                        ChannelType chType = CHANNEL_TYPE_LUMA) const    { return slicetype == I_SLICE ? (chType == CHANNEL_TYPE_LUMA ? m_maxTTSize[0] : m_maxTTSize[2]) : m_maxTTSize[1];                                  }
 
-  void                        setAlfAPSs(std::vector<int> apsIDs)                       { m_alfApsId.resize(m_numAlfAps);
-                                                                                          for (int i = 0; i < m_numAlfAps; i++)
+  void                        setAlfApsIdsLuma(std::vector<int> apsIDs)                 { m_alfApsIdsLuma.resize(m_numAlfApsIdsLuma);
+                                                                                          for (int i = 0; i < m_numAlfApsIdsLuma; i++)
                                                                                           {
-                                                                                            m_alfApsId[i] = apsIDs[i];
+                                                                                            m_alfApsIdsLuma[i] = apsIDs[i];
                                                                                           }
                                                                                         }
 
-  std::vector<int>            getAlfAPSs() const                                        { return m_alfApsId; }
+  std::vector<int>            getAlfApsIdsLuma() const                                  { return m_alfApsIdsLuma; }
 
   void                        setWpScaling(WPScalingParam *wp)
   {
@@ -2610,6 +2642,13 @@ private:
   bool                       m_useLTforDRAP;
   bool                       m_isDRAP;
   int                        m_latestDRAPPOC;
+  bool                       m_enableEdrapSEI;
+  int                        m_edrapRapId;
+  bool                       m_useLTforEdrap;
+  int                        m_edrapNumRefRapPics;
+  std::vector<int>           m_edrapRefRapIds;
+  int                        m_latestEDRAPPOC;
+  bool                       m_latestEdrapLeadingPicDecodableFlag;
   ReferencePictureList        m_RPL0;            //< RPL for L0 when present in slice header
   ReferencePictureList        m_RPL1;            //< RPL for L1 when present in slice header
   int                         m_rpl0Idx;              //< index of used RPL in the SPS or -1 for local RPL in the slice header
@@ -2633,6 +2672,10 @@ private:
   int                        m_deblockingFilterCrBetaOffsetDiv2;  //< beta offset for deblocking filter
   int                        m_deblockingFilterCrTcOffsetDiv2;    //< tc offset for deblocking filter
   bool                       m_depQuantEnabledFlag;               //!< dependent quantization enabled flag
+  int                        m_riceBaseLevelValue;    //< baseLevel value for abs_remainder 
+#if JVET_W0046_RLSCP
+  bool                       m_reverseLastSigCoeffFlag;
+#endif
   bool                       m_signDataHidingEnabledFlag;         //!< sign data hiding enabled flag
   bool                       m_tsResidualCodingDisabledFlag;
   int                        m_list1IdxToList0Idx[MAX_NUM_REF];
@@ -2642,6 +2685,9 @@ private:
   bool                       m_bCheckLDC;
 
   bool                       m_biDirPred;
+#if JVET_W0133_CONSTRAINED_RASL_ENCODING
+  bool                       m_lmChromaCheckDisable;
+#endif
   int                        m_symRefIdx[2];
 
   //  Data
@@ -2700,16 +2746,21 @@ private:
 
   int                        m_rpPicOrderCntVal;
   APS*                       m_alfApss[ALF_CTB_MAX_NUM_APS];
-  bool                       m_tileGroupAlfEnabledFlag[MAX_NUM_COMPONENT];
-  int                        m_tileGroupNumAps;
-  std::vector<int>           m_tileGroupLumaApsId;
-  int                        m_tileGroupChromaApsId;
-  bool                       m_tileGroupCcAlfCbEnabledFlag;
-  bool                       m_tileGroupCcAlfCrEnabledFlag;
-  int                        m_tileGroupCcAlfCbApsId;
-  int                        m_tileGroupCcAlfCrApsId;
+  bool                       m_alfEnabledFlag[MAX_NUM_COMPONENT];
+  int                        m_numAlfApsIdsLuma;
+  std::vector<int>           m_alfApsIdsLuma;
+  int                        m_alfApsIdChroma;
+  bool                       m_ccAlfCbEnabledFlag;
+  bool                       m_ccAlfCrEnabledFlag;
+  int                        m_ccAlfCbApsId;
+  int                        m_ccAlfCrApsId;
   bool                       m_disableSATDForRd;
   bool                       m_isLossless;
+  int                        m_tsrc_index;
+  unsigned                   m_riceBit[8];
+#if JVET_W0046_RLSCP
+  int                        m_cnt_right_bottom;
+#endif
 public:
                               Slice();
   virtual                     ~Slice();
@@ -2825,6 +2876,12 @@ public:
   void                        setDeblockingFilterCrTcOffsetDiv2( int i )             { m_deblockingFilterCrTcOffsetDiv2 = i;                           }
   void                        setDepQuantEnabledFlag( bool b )                       { m_depQuantEnabledFlag = b;                                                                   }
   bool                        getDepQuantEnabledFlag() const                         { return m_depQuantEnabledFlag;                                                                }  
+  void                        setRiceBaseLevel(int b) { m_riceBaseLevelValue = b; }
+  int                         getRiceBaseLevel() const { return m_riceBaseLevelValue; }
+#if JVET_W0046_RLSCP
+  void                        setReverseLastSigCoeffFlag( bool b )                   { m_reverseLastSigCoeffFlag = b;                                }
+  bool                        getReverseLastSigCoeffFlag() const                     { return m_reverseLastSigCoeffFlag;                             }
+#endif
   void                        setSignDataHidingEnabledFlag( bool b )                 { m_signDataHidingEnabledFlag = b;                                                             }
   bool                        getSignDataHidingEnabledFlag() const                   { return m_signDataHidingEnabledFlag;                                                          }  
   void                        setTSResidualCodingDisabledFlag(bool b) { m_tsResidualCodingDisabledFlag = b; }
@@ -2843,11 +2900,18 @@ public:
 
   void                        setBiDirPred( bool b, int refIdx0, int refIdx1 ) { m_biDirPred = b; m_symRefIdx[0] = refIdx0; m_symRefIdx[1] = refIdx1; }
   bool                        getBiDirPred() const { return m_biDirPred; }
+#if JVET_W0133_CONSTRAINED_RASL_ENCODING
+  void                        setDisableLmChromaCheck( bool b )  { m_lmChromaCheckDisable = b; }
+  bool                        getDisableLmChromaCheck() const { return m_lmChromaCheckDisable; }
+#endif
   int                         getSymRefIdx( int refList ) const { return m_symRefIdx[refList]; }
 
   bool                        isIntra() const                                        { return m_eSliceType == I_SLICE;                               }
   bool                        isInterB() const                                       { return m_eSliceType == B_SLICE;                               }
   bool                        isInterP() const                                       { return m_eSliceType == P_SLICE;                               }
+#if GDR_ENABLED
+  bool                        isInterGDR() const { return (m_eSliceType == B_SLICE && m_eNalUnitType == NAL_UNIT_CODED_SLICE_GDR); }  
+#endif
 
   bool                        getEnableDRAPSEI () const                              { return m_enableDRAPSEI;                                       }
   void                        setEnableDRAPSEI ( bool b )                            { m_enableDRAPSEI = b;                                          }
@@ -2861,6 +2925,24 @@ public:
   bool                        isPocRestrictedByDRAP( int poc, bool precedingDRAPinDecodingOrder );
   bool                        isPOCInRefPicList( const ReferencePictureList *rpl, int poc );
   void                        checkConformanceForDRAP( uint32_t temporalId );
+  bool                        getEnableEdrapSEI () const                             { return m_enableEdrapSEI; }
+  void                        setEnableEdrapSEI ( bool b )                           { m_enableEdrapSEI = b; }
+  int                         getEdrapRapId () const                                 { return m_edrapRapId; }
+  void                        setEdrapRapId (int i)                                  { m_edrapRapId = i; }
+  bool                        getUseLTforEdrap () const                              { return m_useLTforEdrap; }
+  void                        setUseLTforEdrap ( bool b )                            { m_useLTforEdrap = b; }
+  int                         getEdrapNumRefRapPics () const                         { return m_edrapNumRefRapPics; }
+  void                        setEdrapNumRefRapPics (int i)                          { m_edrapNumRefRapPics = i; }
+  int                         getEdrapRefRapId (int idx) const                       { return m_edrapRefRapIds[idx]; }
+  void                        addEdrapRefRapIds (int i)                              { m_edrapRefRapIds.push_back(i); }
+  void                        deleteEdrapRefRapIds (int i)                           { m_edrapRefRapIds.erase(m_edrapRefRapIds.begin() + i); m_edrapNumRefRapPics--; }
+  bool                        isPocRestrictedByEdrap( int poc );
+  void                        setLatestEDRAPPOC ( int i )                            { m_latestEDRAPPOC = i; }
+  int                         getLatestEDRAPPOC () const                             { return m_latestEDRAPPOC; }
+  bool                        cvsHasPreviousEDRAP() const                            { return m_latestEDRAPPOC != MAX_INT; }
+  void                        setLatestEdrapLeadingPicDecodableFlag ( bool b )       { m_latestEdrapLeadingPicDecodableFlag = b; }
+  bool                        getLatestEdrapLeadingPicDecodableFlag () const         { return m_latestEdrapLeadingPicDecodableFlag; }
+  void                        checkConformanceForEDRAP( uint32_t temporalId );
 
   void                        setLambdas( const double lambdas[MAX_NUM_COMPONENT] )  { for (int component = 0; component < MAX_NUM_COMPONENT; component++) m_lambdas[component] = lambdas[component]; }
   const double*               getLambdas() const                                     { return m_lambdas;                                             }
@@ -2974,34 +3056,34 @@ public:
   void resetProcessingTime()       { m_dProcessingTime = m_iProcessingStartTime = 0; }
   double getProcessingTime() const { return m_dProcessingTime; }
 
-  void                        resetTileGroupAlfEnabledFlag() { memset(m_tileGroupAlfEnabledFlag, 0, sizeof(m_tileGroupAlfEnabledFlag)); }
-  bool                        getTileGroupAlfEnabledFlag(ComponentID compId) const { return m_tileGroupAlfEnabledFlag[compId]; }
-  void                        setTileGroupAlfEnabledFlag(ComponentID compId, bool b) { m_tileGroupAlfEnabledFlag[compId] = b; }
-  int                         getTileGroupNumAps() const { return m_tileGroupNumAps; }
-  void                        setTileGroupNumAps(int i) { m_tileGroupNumAps = i; }
-  int                         getTileGroupApsIdChroma() const { return m_tileGroupChromaApsId; }
-  void                        setTileGroupApsIdChroma(int i) { m_tileGroupChromaApsId = i; }
-  std::vector<int32_t>        getTileGroupApsIdLuma() const { return m_tileGroupLumaApsId; }
-  void                        setAlfAPSs(std::vector<int> ApsIDs)
+  void                        resetAlfEnabledFlag() { memset(m_alfEnabledFlag, 0, sizeof(m_alfEnabledFlag)); }
+  bool                        getAlfEnabledFlag(ComponentID compId) const { return m_alfEnabledFlag[compId]; }
+  void                        setAlfEnabledFlag(ComponentID compId, bool b) { m_alfEnabledFlag[compId] = b; }
+  int                         getNumAlfApsIdsLuma() const { return m_numAlfApsIdsLuma; }
+  void                        setNumAlfApsIdsLuma(int i) { m_numAlfApsIdsLuma = i; }
+  int                         getAlfApsIdChroma() const { return m_alfApsIdChroma; }
+  void                        setAlfApsIdChroma(int i) { m_alfApsIdChroma = i; }
+  std::vector<int>            getAlfApsIdsLuma() const { return m_alfApsIdsLuma; }
+  void                        setAlfApsIdsLuma(std::vector<int> apsIDs)
   {
-    m_tileGroupLumaApsId.resize(m_tileGroupNumAps);
-    for (int i = 0; i < m_tileGroupNumAps; i++)
+    m_alfApsIdsLuma.resize(m_numAlfApsIdsLuma);
+    for (int i = 0; i < m_numAlfApsIdsLuma; i++)
     {
-      m_tileGroupLumaApsId[i] = ApsIDs[i];
+      m_alfApsIdsLuma[i] = apsIDs[i];
     }
   }
-  void resetTileGroupCcAlCbfEnabledFlag() { m_tileGroupCcAlfCbEnabledFlag = 0; }
-  void resetTileGroupCcAlCrfEnabledFlag() { m_tileGroupCcAlfCrEnabledFlag = 0; }
-
-  void setTileGroupCcAlfCbEnabledFlag(bool b) { m_tileGroupCcAlfCbEnabledFlag = b; }
-  void setTileGroupCcAlfCrEnabledFlag(bool b) { m_tileGroupCcAlfCrEnabledFlag = b; }
-  void setTileGroupCcAlfCbApsId(int i) { m_tileGroupCcAlfCbApsId = i; }
-  void setTileGroupCcAlfCrApsId(int i) { m_tileGroupCcAlfCrApsId = i; }
-
-  bool getTileGroupCcAlfCbEnabledFlag() { return m_tileGroupCcAlfCbEnabledFlag; }
-  bool getTileGroupCcAlfCrEnabledFlag() { return m_tileGroupCcAlfCrEnabledFlag; }
-  int  getTileGroupCcAlfCbApsId() { return m_tileGroupCcAlfCbApsId; }
-  int  getTileGroupCcAlfCrApsId() { return m_tileGroupCcAlfCrApsId; }
+  void resetCcAlCbfEnabledFlag() { m_ccAlfCbEnabledFlag = 0; }
+  void resetCcAlCrfEnabledFlag() { m_ccAlfCrEnabledFlag = 0; }
+
+  void setCcAlfCbEnabledFlag(bool b) { m_ccAlfCbEnabledFlag = b; }
+  void setCcAlfCrEnabledFlag(bool b) { m_ccAlfCrEnabledFlag = b; }
+  void setCcAlfCbApsId(int i) { m_ccAlfCbApsId = i; }
+  void setCcAlfCrApsId(int i) { m_ccAlfCrApsId = i; }
+
+  bool getCcAlfCbEnabledFlag() { return m_ccAlfCbEnabledFlag; }
+  bool getCcAlfCrEnabledFlag() { return m_ccAlfCrEnabledFlag; }
+  int  getCcAlfCbApsId() { return m_ccAlfCbApsId; }
+  int  getCcAlfCrApsId() { return m_ccAlfCrApsId; }
   void                        setDisableSATDForRD(bool b) { m_disableSATDForRd = b; }
   bool                        getDisableSATDForRD() { return m_disableSATDForRd; }
   void                        setLossless(bool b) { m_isLossless = b; }
@@ -3017,6 +3099,14 @@ public:
 
   CcAlfFilterParam            m_ccAlfFilterParam;
   uint8_t*                    m_ccAlfFilterControl[2];
+  void                        set_tsrc_index(int v) { m_tsrc_index = v; }
+  int                         get_tsrc_index() const { return m_tsrc_index; }
+  void                        setRiceBit(int idx, int i) { m_riceBit[idx] = i; }
+  unsigned                    getRiceBit(int idx) const { return m_riceBit[idx]; }
+#if JVET_W0046_RLSCP
+  void updateCntRightBottom(int v) { m_cnt_right_bottom += v; }
+  int  getCntRightBottom() { return m_cnt_right_bottom; }
+#endif
 
 protected:
   Picture*              xGetRefPic( PicList& rcListPic, const int poc, const int layerId );
@@ -3111,9 +3201,7 @@ public:
 
 #if ENABLE_TRACING
 void xTraceVPSHeader();
-#if JVET_S0163_ON_TARGETOLS_SUBLAYERS
 void xTraceOPIHeader();
-#endif
 void xTraceDCIHeader();
 void xTraceSPSHeader();
 void xTracePPSHeader();
diff --git a/source/Lib/CommonLib/TrQuant.cpp b/source/Lib/CommonLib/TrQuant.cpp
index 95e339fff..59d4c22de 100644
--- a/source/Lib/CommonLib/TrQuant.cpp
+++ b/source/Lib/CommonLib/TrQuant.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -208,13 +208,6 @@ TrQuant::~TrQuant()
   }
 }
 
-#if ENABLE_SPLIT_PARALLELISM
-void TrQuant::copyState( const TrQuant& other )
-{
-  m_quant->copyState( *other.m_quant );
-}
-#endif
-
 void TrQuant::xDeQuant(const TransformUnit &tu,
                              CoeffBuf      &dstCoeff,
                        const ComponentID   &compID,
diff --git a/source/Lib/CommonLib/TrQuant.h b/source/Lib/CommonLib/TrQuant.h
index 72c951024..f93ab67de 100644
--- a/source/Lib/CommonLib/TrQuant.h
+++ b/source/Lib/CommonLib/TrQuant.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -115,10 +115,6 @@ public:
   void   lambdaAdjustColorTrans(bool forward) { m_quant->lambdaAdjustColorTrans(forward); }
   void   resetStore() { m_quant->resetStore(); }
 
-#if ENABLE_SPLIT_PARALLELISM
-  void    copyState( const TrQuant& other );
-#endif
-
 protected:
   TCoeff   m_tempCoeff[MAX_TB_SIZEY * MAX_TB_SIZEY];
 
diff --git a/source/Lib/CommonLib/TrQuant_EMT.cpp b/source/Lib/CommonLib/TrQuant_EMT.cpp
index fd2e3917d..7c37001ce 100644
--- a/source/Lib/CommonLib/TrQuant_EMT.cpp
+++ b/source/Lib/CommonLib/TrQuant_EMT.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/CommonLib/TrQuant_EMT.h b/source/Lib/CommonLib/TrQuant_EMT.h
index d6e6a2a2d..11d30ff74 100644
--- a/source/Lib/CommonLib/TrQuant_EMT.h
+++ b/source/Lib/CommonLib/TrQuant_EMT.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h
index 9a224f53d..39d73bb22 100644
--- a/source/Lib/CommonLib/TypeDef.h
+++ b/source/Lib/CommonLib/TypeDef.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -53,26 +53,41 @@
 // clang-format off
 
 //########### place macros to be removed in next cycle below this line ###############
+#define JVET_W0133_CONSTRAINED_RASL_ENCODING              1 // SEI message for Constrained RASL encoding for bitstream switching
 
 #define JVET_S0176_ITEM5                                  1 // JVET-S0176 #5: When an SLI SEI message is present for a CVS, the value of sps_num_subpics_minus1 shall be the same for all the SPSs referenced by the pictures in the layers with multiple subpictures per picture.
-#define JVET_S0096_RPL_CONSTRAINT                         1// JVET-S0096 aspect 1: When pps_rpl_info_in_ph_flag is equal to 1 and ph_inter_slice_allowed_flag is equal to 1, the value of num_ref_entries[ 0 ][ RplsIdx[ 0 ] ] shall be greater than 0.
-#define JVET_S0078_NOOUTPUTPRIORPICFLAG                   0 // JVET-S0078: Handling of NoOutputOfPriorPicsFlag in output process
-#define JVET_S0219_ASPECT1                                1 // JVET-S0219 aspect1 : removal non-referred APS parameter set in the non-output layer.
-#define JVET_R0193                                        1 // JVET-R0193: signalling of the number of maximum sublayers used for inter-layer prediction for each layer
-#define JVET_R0193_S0141                                  1 // JVET-S0141 item 47 : item 47: In the general sub-bitstream extraction process, specify the conditions under which an output sub-bitstream is required to be a conforming bitstream such that the value of tIdTarget is specified to be in the range of 0 to vps_ptl_max_tid[ vps_ols_ptl_idx[ targetOlsIdx ] ], inclusive (instead of 0 to 6 inclusive). (JVET-S0158 aspect 1)
-#define JVET_T0065_LEVEL_6_3                              1 // JVET-T0065: Add level 6.3
-#define JVET_T0091_LMCS_ENC_OVERFLOW_FIX                  1 // JVET-T0091: LMCS encoder overflow fix at high bit-depth for SDR
-#define JVET_S0163_ON_TARGETOLS_SUBLAYERS                 1 // JVET-S0163: On target OLS and sublayers for decoding (OPI NAL Unit)
-#define JVET_R0266_GCI                                    1 // JVET-R0266 #5: Specify that no_gdr_constraint_flag equal to 1 specifies that sps_gdr_enabled_flag shall be equal to 0
-#define JVET_S0084_S0110_RADL                             1 // When the current picture is a RADL picture, allow RASL pictures with pps_mixed_nalu_types_in_pic_flag is equal to 1 in active entries in RefPicList[ 0 ] or RefPicList[ 1 ]
-#define FIX_TICKET_1405                                   1 // Add dph_sei_single_component_flag and dph_sei_reserved_zero_7bits syntax to decoded picture hash SEI message
-#define FIX_SUBPICS_W_RPR                                 1 // Fix handling of RPR with subpictures (via scaling windows with no resolution change)
-#define JVET_S0175_ASPECT5                                1 // use u(8) instead of u(4) for (ffi_)display_elemental_periods_minus1 and pt_display_elemental_periods_minus1
-#define JVET_S0175_ASPECT6                                1 // The general_nal_hrd_params_present_flag and general_vcl_hrd_params_present_flag are allowed to both be equal to 0
-#define JVET_R0046_IRAP_ASPECT2                           1 // Add a constraint on an ILRP being either an IRAP picture or having TemporalId less than or equal to Max (0, vps_max_tid_il_ref_pics_plus1[ refPicVpsLayerId ] - 1 )
-#define JVET_T0064                                        1 // JVET-T0064: control of filter strength for ALF
+
+#define JVET_W0078_MVP_SEI                                1 // JVET-W0078 Multiview view position SEI message
+
+#define JVET_W0129_ENABLE_ALF_TRUEORG                    1 // Using true original samples for ALF as default setting
+
+#define JVET_W0134_UNIFORM_METRICS_LOG                    1 // change metrics output for easy parsing
+
+#define JVET_W0070_W0121_SPSRE_CLEANUP                    1 // JVET-W0070 Proposal 3 & JVET-W0121 Option 1 : condition the signaling of sps_ts_residual_coding_rice_present_in_sh_flag
+
+#define JVET_W0043                                        1 // Alignment of smooth block QP control with adaptive QP in VTM
+
+#define JVET_W0178_CONSTRAINTS_ON_REXT_TOOLS              1 // JVET-W0178: bitstream constraints on RExt tools for low bit-depth (bit-depth <=10)
+
+#define JVET_W0046_RLSCP                                  1 // JVET-W0046: CE1.1 reverse last significant coefficient position
+
+#define JVET_W2005_RANGE_EXTENSION_PROFILES               1 // JVET-W2005 (JVET-W0136 profile plus meeting decisions)
+
+#define JVET_S0154_ASPECT9_AND_S0158_ASPECT4              1 // JVET-S0154 #9:  In the subpicture sub-bitstream extraction process, insert SEI NAL units to directly contain those SEI messages that were scalable-nested HRD-related SEI messages that apply to the output bitstream, and remove their original container SEI NAL units from the output bitstream. When the target OLS includes only one layer, apply the same for scalable-nested non-HRD-related SEI messages.
+                                                            // JVET-S0158 #4c: Insert SEI NAL units to directly contain those SEI messages that were scalable-nested HRD-related SEI messages that apply to the output bitstream, and remove their original container SEI NAL units from the output bitstream. When the target OLS includes only one layer, apply the same for scalable-nested non-HRD-related SEI messages.
+
+
+#define JVET_S0117_VB                                     1 // sub-picture extraction VB rewriting
 
 //########### place macros to be be kept below this line ###############
+#define GDR_ENABLED   1
+
+#if GDR_ENABLED
+#define GDR_LEAK_TEST  0
+#define GDR_ENC_TRACE  0
+#define GDR_DEC_TRACE  0
+#endif
+
 #define JVET_S0257_DUMP_360SEI_MESSAGE                    1 // Software support of 360 SEI messages
 
 #define JVET_R0351_HIGH_BIT_DEPTH_ENABLED                 0 // JVET-R0351: high bit depth coding enabled (increases accuracies of some calculations, e.g. transforms)
@@ -110,17 +125,6 @@ typedef std::pair<int, int>  TrCost;
 #define JVET_O0756_CALCULATE_HDRMETRICS                   1
 #endif
 
-#ifndef ENABLE_SPLIT_PARALLELISM
-#define ENABLE_SPLIT_PARALLELISM                          0
-#endif
-#if ENABLE_SPLIT_PARALLELISM
-#define PARL_SPLIT_MAX_NUM_JOBS                           6                             // number of parallel jobs that can be defined and need memory allocated
-#define NUM_RESERVERD_SPLIT_JOBS                        ( PARL_SPLIT_MAX_NUM_JOBS + 1 )  // number of all data structures including the merge thread (0)
-#define PARL_SPLIT_MAX_NUM_THREADS                        PARL_SPLIT_MAX_NUM_JOBS
-#define NUM_SPLIT_THREADS_IF_MSVC                         4
-
-#endif
-
 // clang-format on
 
 // ====================================================================================================================
@@ -201,7 +205,7 @@ typedef std::pair<int, int>  TrCost;
 
 // SIMD optimizations
 #define SIMD_ENABLE                                       1
-#define ENABLE_SIMD_OPT                                 ( SIMD_ENABLE && !RExt__HIGH_BIT_DEPTH_SUPPORT )    ///< SIMD optimizations, no impact on RD performance
+#define ENABLE_SIMD_OPT                                 SIMD_ENABLE                                         ///< SIMD optimizations, no impact on RD performance
 #define ENABLE_SIMD_OPT_MCIF                            ( 1 && ENABLE_SIMD_OPT )                            ///< SIMD optimization for the interpolation filter, no impact on RD performance
 #define ENABLE_SIMD_OPT_BUFFER                          ( 1 && ENABLE_SIMD_OPT )                            ///< SIMD optimization for the buffer operations, no impact on RD performance
 #define ENABLE_SIMD_OPT_DIST                            ( 1 && ENABLE_SIMD_OPT )                            ///< SIMD optimization for the distortion calculations(SAD,SSE,HADAMARD), no impact on RD performance
@@ -243,9 +247,11 @@ typedef std::pair<int, int>  TrCost;
 #if RExt__HIGH_BIT_DEPTH_SUPPORT
 #define FULL_NBIT                                         1 ///< When enabled, use distortion measure derived from all bits of source data, otherwise discard (bitDepth - 8) least-significant bits of distortion
 #define RExt__HIGH_PRECISION_FORWARD_TRANSFORM            1 ///< 0 use original 6-bit transform matrices for both forward and inverse transform, 1 (default) = use original matrices for inverse transform and high precision matrices for forward transform
+#define JVET_V0106_DEP_QUANT_ENC_OPT                      1 ///< 0 use original g_goRiceBits[4][32] LUT for codeword length estimation at encoder, 1 (default) use extended g_goRiceBits[16][64] LUT for codeword length estimation at encoder
 #else
 #define FULL_NBIT                                         1 ///< When enabled, use distortion measure derived from all bits of source data, otherwise discard (bitDepth - 8) least-significant bits of distortion
 #define RExt__HIGH_PRECISION_FORWARD_TRANSFORM            0 ///< 0 (default) use original 6-bit transform matrices for both forward and inverse transform, 1 = use original matrices for inverse transform and high precision matrices for forward transform
+#define JVET_V0106_DEP_QUANT_ENC_OPT                      0 ///< 0 (default) use original g_goRiceBits[4][32] LUT for codeword length estimation at encoder, 1 - use extended g_goRiceBits[16][64] LUT for codeword length estimation at encoder
 #endif
 
 #if FULL_NBIT
@@ -692,6 +698,9 @@ namespace Profile
   enum Name
   {
     NONE                                 = 0,
+#if JVET_W2005_RANGE_EXTENSION_PROFILES
+    INTRA                                = 8,
+#endif
     STILL_PICTURE                        = 64,
     MAIN_10                              = 1,
     MAIN_10_STILL_PICTURE                = MAIN_10 | STILL_PICTURE,
@@ -701,6 +710,17 @@ namespace Profile
     MAIN_10_444_STILL_PICTURE            = MAIN_10_444 | STILL_PICTURE,
     MULTILAYER_MAIN_10_444               = 49,
     MULTILAYER_MAIN_10_444_STILL_PICTURE = MULTILAYER_MAIN_10_444 | STILL_PICTURE,
+#if JVET_W2005_RANGE_EXTENSION_PROFILES
+    MAIN_12                              = 2,
+    MAIN_12_444                          = 34,
+    MAIN_16_444                          = 36,
+    MAIN_12_INTRA                        = MAIN_12 | INTRA,
+    MAIN_12_444_INTRA                    = MAIN_12_444 | INTRA,
+    MAIN_16_444_INTRA                    = MAIN_16_444 | INTRA,
+    MAIN_12_STILL_PICTURE                = MAIN_12 | STILL_PICTURE,
+    MAIN_12_444_STILL_PICTURE            = MAIN_12_444 | STILL_PICTURE,
+    MAIN_16_444_STILL_PICTURE            = MAIN_16_444 | STILL_PICTURE,
+#endif
   };
 }
 
@@ -730,9 +750,7 @@ namespace Level
     LEVEL6   = 96,
     LEVEL6_1 = 99,
     LEVEL6_2 = 102,
-#if JVET_T0065_LEVEL_6_3
     LEVEL6_3 = 105,
-#endif
     LEVEL15_5 = 255,
   };
 }
@@ -791,11 +809,7 @@ enum NalUnitType
   NAL_UNIT_CODED_SLICE_GDR,         // 10
 
   NAL_UNIT_RESERVED_IRAP_VCL_11,
-#if JVET_S0163_ON_TARGETOLS_SUBLAYERS
   NAL_UNIT_OPI,                     // 12
-#else
-  NAL_UNIT_RESERVED_IRAP_VCL_12,
-#endif
   NAL_UNIT_DCI,                     // 13
   NAL_UNIT_VPS,                     // 14
   NAL_UNIT_SPS,                     // 15
@@ -920,8 +934,12 @@ struct LFCUParam
   bool leftEdge;                         ///< indicates left edge
   bool topEdge;                          ///< indicates top edge
 };
-
-
+struct LutModel
+{
+  bool             presentFlag = false;
+  int              numLutValues = 0;
+  std::vector<Pel> lutValues;
+};
 
 struct PictureHash
 {
@@ -1229,20 +1247,8 @@ template<typename T>
 class dynamic_cache
 {
   std::vector<T*> m_cache;
-#if ENABLE_SPLIT_PARALLELISM
-  int64_t         m_cacheId;
-#endif
 
 public:
-
-#if ENABLE_SPLIT_PARALLELISM
-  dynamic_cache()
-  {
-    static int cacheId = 0;
-    m_cacheId = cacheId++;
-  }
-
-#endif
   ~dynamic_cache()
   {
     deleteEntries();
@@ -1267,48 +1273,22 @@ public:
     {
       ret = m_cache.back();
       m_cache.pop_back();
-#if ENABLE_SPLIT_PARALLELISM
-      CHECK( ret->cacheId != m_cacheId, "Putting item into wrong cache!" );
-      CHECK( !ret->cacheUsed,           "Fetched an element that should've been in cache!!" );
-#endif
     }
     else
     {
       ret = new T;
     }
 
-#if ENABLE_SPLIT_PARALLELISM
-    ret->cacheId   = m_cacheId;
-    ret->cacheUsed = false;
-
-#endif
     return ret;
   }
 
   void cache( T* el )
   {
-#if ENABLE_SPLIT_PARALLELISM
-    CHECK( el->cacheId != m_cacheId, "Putting item into wrong cache!" );
-    CHECK( el->cacheUsed,            "Putting cached item back into cache!" );
-
-    el->cacheUsed = true;
-
-#endif
     m_cache.push_back( el );
   }
 
   void cache( std::vector<T*>& vel )
   {
-#if ENABLE_SPLIT_PARALLELISM
-    for( auto el : vel )
-    {
-      CHECK( el->cacheId != m_cacheId, "Putting item into wrong cache!" );
-      CHECK( el->cacheUsed,            "Putting cached item back into cache!" );
-
-      el->cacheUsed = true;
-    }
-
-#endif
     m_cache.insert( m_cache.end(), vel.begin(), vel.end() );
     vel.clear();
   }
diff --git a/source/Lib/CommonLib/Unit.cpp b/source/Lib/CommonLib/Unit.cpp
index ab3fc757e..8f9787c6c 100644
--- a/source/Lib/CommonLib/Unit.cpp
+++ b/source/Lib/CommonLib/Unit.cpp
@@ -3,7 +3,7 @@
 * and contributor rights, including patent rights, and no such rights are
 * granted under this license.
 *
-* Copyright (c) 2010-2020, ITU/ISO/IEC
+* Copyright (c) 2010-2021, ITU/ISO/IEC
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
@@ -557,6 +557,10 @@ void PredictionUnit::initData()
     for ( uint32_t j = 0; j < 3; j++ )
     {
       mvAffi[i][j].setZero();
+#if GDR_ENABLED
+      mvAffiSolid[i][j] = true;
+      mvAffiValid[i][j] = true;
+#endif
     }
   }
   ciipFlag = false;
diff --git a/source/Lib/CommonLib/Unit.h b/source/Lib/CommonLib/Unit.h
index 8a6858fdf..b6b0c44e4 100644
--- a/source/Lib/CommonLib/Unit.h
+++ b/source/Lib/CommonLib/Unit.h
@@ -3,7 +3,7 @@
 * and contributor rights, including patent rights, and no such rights are
 * granted under this license.
 *
-* Copyright (c) 2010-2020, ITU/ISO/IEC
+* Copyright (c) 2010-2021, ITU/ISO/IEC
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
@@ -350,11 +350,7 @@ struct CodingUnit : public UnitArea
 
   TransformUnit *firstTU;
   TransformUnit *lastTU;
-#if ENABLE_SPLIT_PARALLELISM
 
-  int64_t cacheId;
-  bool    cacheUsed;
-#endif
   const uint8_t     getSbtIdx() const { assert( ( ( sbtInfo >> 0 ) & 0xf ) < NUMBER_SBT_IDX ); return ( sbtInfo >> 0 ) & 0xf; }
   const uint8_t     getSbtPos() const { return ( sbtInfo >> 4 ) & 0x3; }
   void              setSbtIdx( uint8_t idx ) { CHECK( idx >= NUMBER_SBT_IDX, "sbt_idx wrong" ); sbtInfo = ( idx << 0 ) + ( sbtInfo & 0xf0 ); }
@@ -394,12 +390,25 @@ struct InterPredictionData
   uint8_t     mvpNum  [NUM_REF_PIC_LIST_01];
   Mv        mvd     [NUM_REF_PIC_LIST_01];
   Mv        mv      [NUM_REF_PIC_LIST_01];
+#if GDR_ENABLED 
+  bool      mvSolid[NUM_REF_PIC_LIST_01];
+  bool      mvValid[NUM_REF_PIC_LIST_01];
+  bool      mvpSolid[NUM_REF_PIC_LIST_01];
+  MvpType   mvpType[NUM_REF_PIC_LIST_01];
+  Position  mvpPos[NUM_REF_PIC_LIST_01];
+#endif
   int16_t     refIdx  [NUM_REF_PIC_LIST_01];
   MergeType mergeType;
   bool      mvRefine;
   Mv        mvdL0SubPu[MAX_NUM_SUBCU_DMVR];
   Mv        mvdAffi [NUM_REF_PIC_LIST_01][3];
   Mv        mvAffi[NUM_REF_PIC_LIST_01][3];
+#if GDR_ENABLED
+  bool      mvAffiSolid[NUM_REF_PIC_LIST_01][3];
+  bool      mvAffiValid[NUM_REF_PIC_LIST_01][3];
+  MvpType   mvAffiType[NUM_REF_PIC_LIST_01][3];
+  Position  mvAffiPos[NUM_REF_PIC_LIST_01][3];
+#endif
   bool      ciipFlag;
 
   Mv        bv;                             // block vector for IBC
@@ -434,12 +443,6 @@ struct PredictionUnit : public UnitArea, public IntraPredictionData, public Inte
   const MotionInfo& getMotionInfo( const Position& pos ) const;
   MotionBuf         getMotionBuf();
   CMotionBuf        getMotionBuf() const;
-
-#if ENABLE_SPLIT_PARALLELISM
-
-  int64_t cacheId;
-  bool    cacheUsed;
-#endif
 };
 
 // ---------------------------------------------------------------------------
@@ -490,11 +493,6 @@ struct TransformUnit : public UnitArea
         Pel*      getPLTIndex(const ComponentID id);
         bool*     getRunTypes(const ComponentID id);
 
-#if ENABLE_SPLIT_PARALLELISM
-  int64_t cacheId;
-  bool    cacheUsed;
-
-#endif
 private:
   TCoeff *m_coeffs[ MAX_NUM_TBLOCKS ];
   Pel    *m_pcmbuf[ MAX_NUM_TBLOCKS ];
diff --git a/source/Lib/CommonLib/UnitPartitioner.cpp b/source/Lib/CommonLib/UnitPartitioner.cpp
index 7c2a0c02b..afdb0e978 100644
--- a/source/Lib/CommonLib/UnitPartitioner.cpp
+++ b/source/Lib/CommonLib/UnitPartitioner.cpp
@@ -3,7 +3,7 @@
 * and contributor rights, including patent rights, and no such rights are
 * granted under this license.
 *
-* Copyright (c) 2010-2020, ITU/ISO/IEC
+* Copyright (c) 2010-2021, ITU/ISO/IEC
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/CommonLib/UnitPartitioner.h b/source/Lib/CommonLib/UnitPartitioner.h
index 4ed645937..6b5651036 100644
--- a/source/Lib/CommonLib/UnitPartitioner.h
+++ b/source/Lib/CommonLib/UnitPartitioner.h
@@ -3,7 +3,7 @@
 * and contributor rights, including patent rights, and no such rights are
 * granted under this license.
 *
-* Copyright (c) 2010-2020, ITU/ISO/IEC
+* Copyright (c) 2010-2021, ITU/ISO/IEC
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/CommonLib/UnitTools.cpp b/source/Lib/CommonLib/UnitTools.cpp
index f76f64ea2..f759784f3 100644
--- a/source/Lib/CommonLib/UnitTools.cpp
+++ b/source/Lib/CommonLib/UnitTools.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -101,48 +101,86 @@ void CS::setRefinedMotionField(CodingStructure &cs)
 
 bool CU::getRprScaling( const SPS* sps, const PPS* curPPS, Picture* refPic, int& xScale, int& yScale )
 {
-  const Window& curScalingWindow = curPPS->getScalingWindow();
-  int curPicWidth = curPPS->getPicWidthInLumaSamples()   - SPS::getWinUnitX( sps->getChromaFormatIdc() ) * (curScalingWindow.getWindowLeftOffset() + curScalingWindow.getWindowRightOffset());
-  int curPicHeight = curPPS->getPicHeightInLumaSamples() - SPS::getWinUnitY( sps->getChromaFormatIdc() ) * (curScalingWindow.getWindowTopOffset()  + curScalingWindow.getWindowBottomOffset());
-
-  const Window& refScalingWindow = refPic->getScalingWindow();
-  int refPicWidth = refPic->getPicWidthInLumaSamples()   - SPS::getWinUnitX( sps->getChromaFormatIdc() ) * (refScalingWindow.getWindowLeftOffset() + refScalingWindow.getWindowRightOffset());
-  int refPicHeight = refPic->getPicHeightInLumaSamples() - SPS::getWinUnitY( sps->getChromaFormatIdc() ) * (refScalingWindow.getWindowTopOffset()  + refScalingWindow.getWindowBottomOffset());
-
-  xScale = ( ( refPicWidth << SCALE_RATIO_BITS ) + ( curPicWidth >> 1 ) ) / curPicWidth;
-  yScale = ( ( refPicHeight << SCALE_RATIO_BITS ) + ( curPicHeight >> 1 ) ) / curPicHeight;
-
-  int curSeqMaxPicWidthY = sps->getMaxPicWidthInLumaSamples();                  // sps_pic_width_max_in_luma_samples
-  int curSeqMaxPicHeightY = sps->getMaxPicHeightInLumaSamples();                // sps_pic_height_max_in_luma_samples
-  int curPicWidthY = curPPS->getPicWidthInLumaSamples();                        // pps_pic_width_in_luma_samples
-  int curPicHeightY = curPPS->getPicHeightInLumaSamples();                      // pps_pic_height_in_luma_samples
-  int max8MinCbSizeY = std::max((int)8, (1<<sps->getLog2MinCodingBlockSize())); // Max(8, MinCbSizeY)
+  const int subWidthC  = SPS::getWinUnitX(sps->getChromaFormatIdc());
+  const int subHeightC = SPS::getWinUnitY(sps->getChromaFormatIdc());
 
-  CHECK((curPicWidth * curSeqMaxPicWidthY) < refPicWidth * (curPicWidthY - max8MinCbSizeY), "(curPicWidth * curSeqMaxPicWidthY) should be greater than or equal to refPicWidth * (curPicWidthY - max8MinCbSizeY))");
-  CHECK((curPicHeight * curSeqMaxPicHeightY) < refPicHeight * (curPicHeightY - max8MinCbSizeY), "(curPicHeight * curSeqMaxPicHeightY) should be greater than or equal to refPicHeight * (curPicHeightY - max8MinCbSizeY))");
-
-  CHECK(curPicWidth * 2 < refPicWidth, "curPicWidth * 2 shall be greater than or equal to refPicWidth");
-  CHECK(curPicHeight * 2 < refPicHeight, "curPicHeight * 2 shall be greater than or equal to refPicHeight");
-  CHECK(curPicWidth > refPicWidth * 8, "curPicWidth shall be less than or equal to refPicWidth * 8");
-  CHECK(curPicHeight > refPicHeight * 8, "curPicHeight shall be less than or equal to refPicHeight * 8");
+  const Window& curScalingWindow = curPPS->getScalingWindow();
 
-  int subWidthC = SPS::getWinUnitX(sps->getChromaFormatIdc());
-  int subHeightC = SPS::getWinUnitY(sps->getChromaFormatIdc());
+  const int curLeftOffset   = subWidthC * curScalingWindow.getWindowLeftOffset();
+  const int curRightOffset  = subWidthC * curScalingWindow.getWindowRightOffset();
+  const int curTopOffset    = subHeightC * curScalingWindow.getWindowTopOffset();
+  const int curBottomOffset = subHeightC * curScalingWindow.getWindowBottomOffset();
 
-  CHECK(subWidthC * curScalingWindow.getWindowLeftOffset() < (-curPicWidthY) * 15, "The value of SubWidthC * pps_scaling_win_left_offset shall be greater than or equal to -pps_pic_width_in_luma_samples * 15");
-  CHECK(subWidthC * curScalingWindow.getWindowLeftOffset() >= curPicWidthY, "The value of SubWidthC * pps_scaling_win_left_offset shall be less than pps_pic_width_in_luma_samples");
-  CHECK(subWidthC * curScalingWindow.getWindowRightOffset() < (-curPicWidthY) * 15, "The value of SubWidthC * pps_scaling_win_right_offset shall be greater than or equal to -pps_pic_width_in_luma_samples * 15");
-  CHECK(subWidthC * curScalingWindow.getWindowRightOffset() >= curPicWidthY, "The value of SubWidthC * pps_scaling_win_right_offset shall be less than pps_pic_width_in_luma_samples");
+  // Note: 64-bit integers are used for sizes such as to avoid possible overflows in corner cases
+  const int64_t curPicScalWinWidth  = curPPS->getPicWidthInLumaSamples() - (curLeftOffset + curRightOffset);
+  const int64_t curPicScalWinHeight = curPPS->getPicHeightInLumaSamples() - (curTopOffset + curBottomOffset);
 
-  CHECK(subHeightC * curScalingWindow.getWindowTopOffset() < (-curPicHeightY) * 15, "The value of SubHeightC * pps_scaling_win_top_offset shall be greater than or equal to -pps_pic_height_in_luma_samples * 15");
-  CHECK(subHeightC * curScalingWindow.getWindowTopOffset() >= curPicHeightY, "The value of SubHeightC * pps_scaling_win_top_offset shall be less than pps_pic_height_in_luma_samples");
-  CHECK(subHeightC * curScalingWindow.getWindowBottomOffset() < (-curPicHeightY) * 15, "The value of SubHeightC *pps_scaling_win_bottom_offset shall be greater than or equal to -pps_pic_height_in_luma_samples * 15");
-  CHECK(subHeightC * curScalingWindow.getWindowBottomOffset() >= curPicHeightY, "The value of SubHeightC *pps_scaling_win_bottom_offset shall be less than pps_pic_height_in_luma_samples");
+  const Window& refScalingWindow = refPic->getScalingWindow();
 
-  CHECK(subWidthC * (curScalingWindow.getWindowLeftOffset() + curScalingWindow.getWindowRightOffset()) < (-curPicWidthY) * 15, "The value of SubWidthC * ( pps_scaling_win_left_offset + pps_scaling_win_right_offset ) shall be greater than or equal to -pps_pic_width_in_luma_samples * 15");
-  CHECK(subWidthC * (curScalingWindow.getWindowLeftOffset() + curScalingWindow.getWindowRightOffset()) >= curPicWidthY, "The value of SubWidthC * ( pps_scaling_win_left_offset + pps_scaling_win_right_offset ) shall be less than pps_pic_width_in_luma_samples");
-  CHECK(subHeightC * (curScalingWindow.getWindowTopOffset() + curScalingWindow.getWindowBottomOffset()) < (-curPicHeightY) * 15, "The value of SubHeightC * ( pps_scaling_win_top_offset + pps_scaling_win_bottom_offset ) shall be greater than or equal to -pps_pic_height_in_luma_samples * 15");
-  CHECK(subHeightC * (curScalingWindow.getWindowTopOffset() + curScalingWindow.getWindowBottomOffset()) >= curPicHeightY, "The value of SubHeightC * ( pps_scaling_win_top_offset + pps_scaling_win_bottom_offset ) shall be less than pps_pic_height_in_luma_samples");
+  const int refLeftOffset   = subWidthC * refScalingWindow.getWindowLeftOffset();
+  const int refRightOffset  = subWidthC * refScalingWindow.getWindowRightOffset();
+  const int refTopOffset    = subHeightC * refScalingWindow.getWindowTopOffset();
+  const int refBottomOffset = subHeightC * refScalingWindow.getWindowBottomOffset();
+
+  const int64_t refPicScalWinWidth  = refPic->getPicWidthInLumaSamples() - (refLeftOffset + refRightOffset);
+  const int64_t refPicScalWinHeight = refPic->getPicHeightInLumaSamples() - (refTopOffset + refBottomOffset);
+
+  CHECK(curPicScalWinWidth * 2 < refPicScalWinWidth,
+        "curPicScalWinWidth * 2 shall be greater than or equal to refPicScalWinWidth");
+  CHECK(curPicScalWinHeight * 2 < refPicScalWinHeight,
+        "curPicScalWinHeight * 2 shall be greater than or equal to refPicScalWinHeight");
+  CHECK(curPicScalWinWidth > refPicScalWinWidth * 8,
+        "curPicScalWinWidth shall be less than or equal to refPicScalWinWidth * 8");
+  CHECK(curPicScalWinHeight > refPicScalWinHeight * 8,
+        "curPicScalWinHeight shall be less than or equal to refPicScalWinHeight * 8");
+
+  xScale = (int) (((refPicScalWinWidth << SCALE_RATIO_BITS) + (curPicScalWinWidth >> 1)) / curPicScalWinWidth);
+  yScale = (int) (((refPicScalWinHeight << SCALE_RATIO_BITS) + (curPicScalWinHeight >> 1)) / curPicScalWinHeight);
+
+  const int maxPicWidth  = sps->getMaxPicWidthInLumaSamples();    // sps_pic_width_max_in_luma_samples
+  const int maxPicHeight = sps->getMaxPicHeightInLumaSamples();   // sps_pic_height_max_in_luma_samples
+  const int curPicWidth  = curPPS->getPicWidthInLumaSamples();    // pps_pic_width_in_luma_samples
+  const int curPicHeight = curPPS->getPicHeightInLumaSamples();   // pps_pic_height_in_luma_samples
+
+  const int picSizeIncrement = std::max((int) 8, (1 << sps->getLog2MinCodingBlockSize()));   // Max(8, MinCbSizeY)
+
+  CHECK((curPicScalWinWidth * maxPicWidth) < refPicScalWinWidth * (curPicWidth - picSizeIncrement),
+        "(curPicScalWinWidth * maxPicWidth) should be greater than or equal to refPicScalWinWidth * (curPicWidth - "
+        "picSizeIncrement))");
+  CHECK((curPicScalWinHeight * maxPicHeight) < refPicScalWinHeight * (curPicHeight - picSizeIncrement),
+        "(curPicScalWinHeight * maxPicHeight) should be greater than or equal to refPicScalWinHeight * (curPicHeight - "
+        "picSizeIncrement))");
+
+  CHECK(curLeftOffset < -curPicWidth * 15, "The value of SubWidthC * pps_scaling_win_left_offset shall be greater "
+                                           "than or equal to -pps_pic_width_in_luma_samples * 15");
+  CHECK(curLeftOffset >= curPicWidth,
+        "The value of SubWidthC * pps_scaling_win_left_offset shall be less than pps_pic_width_in_luma_samples");
+  CHECK(curRightOffset < -curPicWidth * 15, "The value of SubWidthC * pps_scaling_win_right_offset shall be greater "
+                                            "than or equal to -pps_pic_width_in_luma_samples * 15");
+  CHECK(curRightOffset >= curPicWidth,
+        "The value of SubWidthC * pps_scaling_win_right_offset shall be less than pps_pic_width_in_luma_samples");
+
+  CHECK(curTopOffset < -curPicHeight * 15, "The value of SubHeightC * pps_scaling_win_top_offset shall be greater "
+                                           "than or equal to -pps_pic_height_in_luma_samples * 15");
+  CHECK(curTopOffset >= curPicHeight,
+        "The value of SubHeightC * pps_scaling_win_top_offset shall be less than pps_pic_height_in_luma_samples");
+  CHECK(curBottomOffset < (-curPicHeight) * 15, "The value of SubHeightC * pps_scaling_win_bottom_offset shall be "
+                                                "greater than or equal to -pps_pic_height_in_luma_samples * 15");
+  CHECK(curBottomOffset >= curPicHeight,
+        "The value of SubHeightC * pps_scaling_win_bottom_offset shall be less than pps_pic_height_in_luma_samples");
+
+  CHECK(curLeftOffset + curRightOffset < -curPicWidth * 15,
+        "The value of SubWidthC * ( pps_scaling_win_left_offset + pps_scaling_win_right_offset ) shall be greater than "
+        "or equal to -pps_pic_width_in_luma_samples * 15");
+  CHECK(curLeftOffset + curRightOffset >= curPicWidth,
+        "The value of SubWidthC * ( pps_scaling_win_left_offset + pps_scaling_win_right_offset ) shall be less than "
+        "pps_pic_width_in_luma_samples");
+  CHECK(curTopOffset + curBottomOffset < -curPicHeight * 15,
+        "The value of SubHeightC * ( pps_scaling_win_top_offset + pps_scaling_win_bottom_offset ) shall be greater "
+        "than or equal to -pps_pic_height_in_luma_samples * 15");
+  CHECK(curTopOffset + curBottomOffset >= curPicHeight,
+        "The value of SubHeightC * ( pps_scaling_win_top_offset + pps_scaling_win_bottom_offset ) shall be less than "
+        "pps_pic_height_in_luma_samples");
 
   return refPic->isRefScaled( curPPS );
 }
@@ -170,7 +208,7 @@ void CU::checkConformanceILRP(Slice *slice)
     return;
   }
 
-  //constraint 1: The picture referred to by each active entry in RefPicList[ 0 ] or RefPicList[ 1 ] has the same subpicture layout as the current picture 
+  //constraint 1: The picture referred to by each active entry in RefPicList[ 0 ] or RefPicList[ 1 ] has the same subpicture layout as the current picture
   bool isAllRefSameSubpicLayout = true;
   for (int refList = 0; refList < numRefList; refList++) // loop over l0 and l1
   {
@@ -349,6 +387,10 @@ void CU::saveMotionInHMVP( const CodingUnit& cu, const bool isToBeDone )
   {
     MotionInfo mi = pu.getMotionInfo();
 
+#if GDR_ENABLED
+    mi.sourcePos   = pu.lumaPos();
+    mi.sourceClean = pu.cs->isClean(mi.sourcePos, CHANNEL_TYPE_LUMA);
+#endif
     mi.BcwIdx = (mi.interDir == 3) ? cu.BcwIdx : BCW_DEFAULT;
 
     const unsigned log2ParallelMergeLevel = (pu.cs->sps->getLog2ParallelMergeLevelMinus2() + 2);
@@ -788,7 +830,7 @@ uint32_t PU::getCoLocatedIntraLumaMode(const PredictionUnit &pu)
 
 int PU::getWideAngle( const TransformUnit &tu, const uint32_t dirMode, const ComponentID compID )
 {
-  //This function returns a wide angle index taking into account that the values 0 and 1 are reserved 
+  //This function returns a wide angle index taking into account that the values 0 and 1 are reserved
   //for Planar and DC respectively, as defined in the Spec. Text.
   if( dirMode < 2 )
   {
@@ -817,7 +859,12 @@ int PU::getWideAngle( const TransformUnit &tu, const uint32_t dirMode, const Com
 bool PU::addMergeHMVPCand(const CodingStructure &cs, MergeCtx &mrgCtx, const int &mrgCandIdx,
                           const uint32_t maxNumMergeCandMin1, int &cnt, const bool isAvailableA1,
                           const MotionInfo miLeft, const bool isAvailableB1, const MotionInfo miAbove,
-                          const bool ibcFlag, const bool isGt4x4)
+                          const bool ibcFlag, const bool isGt4x4
+#if GDR_ENABLED
+                         ,const PredictionUnit &pu
+                         ,bool &allCandSolidInAbove
+#endif
+)
 {
   const Slice& slice = *cs.slice;
   MotionInfo miNeighbor;
@@ -825,9 +872,26 @@ bool PU::addMergeHMVPCand(const CodingStructure &cs, MergeCtx &mrgCtx, const int
   auto &lut = ibcFlag ? cs.motionLut.lutIbc : cs.motionLut.lut;
   int num_avai_candInLUT = (int)lut.size();
 
+#if GDR_ENABLED
+  const bool isEncodeGdrClean = cs.sps->getGDREnabledFlag() && cs.pcv->isEncoder && ((cs.picHeader->getInGdrInterval() && cs.isClean(pu.Y().topRight(), CHANNEL_TYPE_LUMA)) || (cs.picHeader->getNumVerVirtualBoundaries() == 0));
+
+  bool  vbOnCtuBoundary = true;
+  if (isEncodeGdrClean)
+  {
+    vbOnCtuBoundary = (pu.cs->picHeader->getNumVerVirtualBoundaries() == 0) || (pu.cs->picHeader->getVirtualBoundariesPosX(0) % pu.cs->sps->getMaxCUWidth() == 0);
+    allCandSolidInAbove = allCandSolidInAbove && vbOnCtuBoundary;
+  }
+#endif
   for (int mrgIdx = 1; mrgIdx <= num_avai_candInLUT; mrgIdx++)
   {
     miNeighbor = lut[num_avai_candInLUT - mrgIdx];
+#if GDR_ENABLED
+    Position sourcePos = Position(0, 0);
+    if (isEncodeGdrClean)
+    {
+      sourcePos = miNeighbor.sourcePos;
+    }
+#endif
 
     if ( mrgIdx > 2 || ((mrgIdx > 1 || !isGt4x4) && ibcFlag)
       || ((!isAvailableA1 || (miLeft != miNeighbor)) && (!isAvailableB1 || (miAbove != miNeighbor))) )
@@ -837,9 +901,28 @@ bool PU::addMergeHMVPCand(const CodingStructure &cs, MergeCtx &mrgCtx, const int
       mrgCtx.BcwIdx            [cnt] = (miNeighbor.interDir == 3) ? miNeighbor.BcwIdx : BCW_DEFAULT;
 
       mrgCtx.mvFieldNeighbours[cnt << 1].setMvField(miNeighbor.mv[0], miNeighbor.refIdx[0]);
+#if GDR_ENABLED
+      if (isEncodeGdrClean)
+      {
+        // note : cannot gaurantee the order/value in the lut if any of the lut is in dirty area
+        mrgCtx.mvPos[(cnt << 1) + 0]   = sourcePos;
+        mrgCtx.mvSolid[(cnt << 1) + 0] = allCandSolidInAbove && vbOnCtuBoundary;
+        mrgCtx.mvValid[(cnt << 1) + 0] = cs.isClean(pu.Y().bottomRight(), miNeighbor.mv[0], REF_PIC_LIST_0, miNeighbor.refIdx[0]);
+        allCandSolidInAbove = allCandSolidInAbove && vbOnCtuBoundary;
+      }
+#endif
       if (slice.isInterB())
       {
         mrgCtx.mvFieldNeighbours[(cnt << 1) + 1].setMvField(miNeighbor.mv[1], miNeighbor.refIdx[1]);
+#if GDR_ENABLED
+        if (isEncodeGdrClean)
+        {
+          mrgCtx.mvPos[(cnt << 1) + 1]   = sourcePos;
+          mrgCtx.mvSolid[(cnt << 1) + 1] = allCandSolidInAbove && vbOnCtuBoundary;
+          mrgCtx.mvValid[(cnt << 1) + 1] = cs.isClean(pu.Y().bottomRight(), miNeighbor.mv[1], REF_PIC_LIST_1, miNeighbor.refIdx[1]);
+          allCandSolidInAbove = allCandSolidInAbove && vbOnCtuBoundary;
+        }
+#endif
       }
 
       if (mrgCandIdx == cnt)
@@ -867,6 +950,11 @@ void PU::getIBCMergeCandidates(const PredictionUnit &pu, MergeCtx& mrgCtx, const
 {
   const CodingStructure &cs = *pu.cs;
   const uint32_t maxNumMergeCand = pu.cs->sps->getMaxNumIBCMergeCand();
+#if GDR_ENABLED
+  const bool isEncodeGdrClean = cs.sps->getGDREnabledFlag() && cs.pcv->isEncoder && ((cs.picHeader->getInGdrInterval() && cs.isClean(pu.Y().topRight(), CHANNEL_TYPE_LUMA)) || (cs.picHeader->getNumVerVirtualBoundaries() == 0));
+  bool  allCandSolidInAbove = true;
+#endif
+
   for (uint32_t ui = 0; ui < maxNumMergeCand; ++ui)
   {
     mrgCtx.BcwIdx[ui] = BCW_DEFAULT;
@@ -874,6 +962,15 @@ void PU::getIBCMergeCandidates(const PredictionUnit &pu, MergeCtx& mrgCtx, const
     mrgCtx.mrgTypeNeighbours[ui] = MRG_TYPE_IBC;
     mrgCtx.mvFieldNeighbours[ui * 2].refIdx = NOT_VALID;
     mrgCtx.mvFieldNeighbours[ui * 2 + 1].refIdx = NOT_VALID;
+#if GDR_ENABLED
+    if (isEncodeGdrClean)
+    {
+      mrgCtx.mvSolid[(ui << 1) + 0] = true;
+      mrgCtx.mvSolid[(ui << 1) + 1] = true;
+      mrgCtx.mvValid[(ui << 1) + 0] = true;
+      mrgCtx.mvValid[(ui << 1) + 1] = true;
+    }
+#endif
     mrgCtx.useAltHpelIf[ui] = false;
   }
 
@@ -899,6 +996,12 @@ void PU::getIBCMergeCandidates(const PredictionUnit &pu, MergeCtx& mrgCtx, const
     mrgCtx.interDirNeighbours[cnt] = miLeft.interDir;
     // get Mv from Left
     mrgCtx.mvFieldNeighbours[cnt << 1].setMvField(miLeft.mv[0], miLeft.refIdx[0]);
+#if GDR_ENABLED
+    if (isEncodeGdrClean)
+    {
+      mrgCtx.mvSolid[(cnt << 1) + 0] = cs.isClean(posLB.offset(-1, 0), pu.chType);
+    }
+#endif
     if (mrgCandIdx == cnt)
     {
       return;
@@ -925,6 +1028,12 @@ void PU::getIBCMergeCandidates(const PredictionUnit &pu, MergeCtx& mrgCtx, const
       mrgCtx.interDirNeighbours[cnt] = miAbove.interDir;
       // get Mv from Above
       mrgCtx.mvFieldNeighbours[cnt << 1].setMvField(miAbove.mv[0], miAbove.refIdx[0]);
+#if GDR_ENABLED
+      if (isEncodeGdrClean)
+      {
+        mrgCtx.mvSolid[(cnt << 1) + 0] = cs.isClean(posRT.offset(0, -1), pu.chType);
+      }
+#endif
       if (mrgCandIdx == cnt)
       {
         return;
@@ -942,8 +1051,19 @@ void PU::getIBCMergeCandidates(const PredictionUnit &pu, MergeCtx& mrgCtx, const
 
   if (cnt != maxNumMergeCand)
   {
+#if GDR_ENABLED
+    bool allCandSolidInAbove = true;
+    bool bFound = addMergeHMVPCand(cs, mrgCtx, mrgCandIdx, maxNumMergeCand, cnt
+      , isAvailableA1, miLeft, isAvailableB1, miAbove
+      , true
+      , isGt4x4
+      , pu
+      , allCandSolidInAbove
+    );
+#else
     bool bFound = addMergeHMVPCand(cs, mrgCtx, mrgCandIdx, maxNumMergeCand, cnt, isAvailableA1, miLeft, isAvailableB1,
                                    miAbove, true, isGt4x4);
+#endif
 
     if (bFound)
     {
@@ -955,6 +1075,14 @@ void PU::getIBCMergeCandidates(const PredictionUnit &pu, MergeCtx& mrgCtx, const
     {
       mrgCtx.mvFieldNeighbours[cnt * 2].setMvField(Mv(0, 0), MAX_NUM_REF);
       mrgCtx.interDirNeighbours[cnt] = 1;
+#if GDR_ENABLED
+      // GDR: zero mv(0,0)
+      if (isEncodeGdrClean)
+      {
+        mrgCtx.mvSolid[cnt << 1] = true && allCandSolidInAbove;
+        allCandSolidInAbove       = true && allCandSolidInAbove;
+      }
+#endif
       if (mrgCandIdx == cnt)
       {
         return;
@@ -974,6 +1102,10 @@ void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx,
   const Slice &slice         = *pu.cs->slice;
   const uint32_t maxNumMergeCand = pu.cs->sps->getMaxNumMergeCand();
   CHECK (maxNumMergeCand > MRG_MAX_NUM_CANDS, "selected maximum number of merge candidate exceeds global limit");
+#if GDR_ENABLED
+  const bool isEncodeGdrClean = cs.sps->getGDREnabledFlag() && cs.pcv->isEncoder && ((cs.picHeader->getInGdrInterval() && cs.isClean(pu.Y().topRight(), CHANNEL_TYPE_LUMA)) || (cs.picHeader->getNumVerVirtualBoundaries() == 0));
+  bool  allCandSolidInAbove = true;
+#endif
   for (uint32_t ui = 0; ui < maxNumMergeCand; ++ui)
   {
     mrgCtx.BcwIdx[ui] = BCW_DEFAULT;
@@ -981,6 +1113,17 @@ void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx,
     mrgCtx.mrgTypeNeighbours [ui] = MRG_TYPE_DEFAULT_N;
     mrgCtx.mvFieldNeighbours[(ui << 1)    ].refIdx = NOT_VALID;
     mrgCtx.mvFieldNeighbours[(ui << 1) + 1].refIdx = NOT_VALID;
+#if GDR_ENABLED
+    if (isEncodeGdrClean)
+    {
+      mrgCtx.mvSolid[(ui << 1) + 0] = true;
+      mrgCtx.mvSolid[(ui << 1) + 1] = true;
+      mrgCtx.mvValid[(ui << 1) + 0] = true;
+      mrgCtx.mvValid[(ui << 1) + 1] = true;
+      mrgCtx.mvPos[(ui << 1) + 0] = Position(0, 0);
+      mrgCtx.mvPos[(ui << 1) + 1] = Position(0, 0);
+    }
+#endif
     mrgCtx.useAltHpelIf[ui] = false;
   }
 
@@ -1010,9 +1153,27 @@ void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx,
     mrgCtx.BcwIdx[cnt] = (mrgCtx.interDirNeighbours[cnt] == 3) ? puAbove->cu->BcwIdx : BCW_DEFAULT;
     mrgCtx.mvFieldNeighbours[cnt << 1].setMvField(miAbove.mv[0], miAbove.refIdx[0]);
 
+#if GDR_ENABLED
+    if (isEncodeGdrClean)
+    {
+      Position pos = puAbove->lumaPos();
+      mrgCtx.mvPos[(cnt << 1) + 0] = pos;
+      mrgCtx.mvSolid[(cnt << 1) + 0] = cs.isClean(pos, pu.chType);
+      mrgCtx.mvValid[(cnt << 1) + 0] = cs.isClean(pu.Y().bottomRight(), miAbove.mv[0], REF_PIC_LIST_0, miAbove.refIdx[0]);
+    }
+#endif
     if (slice.isInterB())
     {
       mrgCtx.mvFieldNeighbours[(cnt << 1) + 1].setMvField(miAbove.mv[1], miAbove.refIdx[1]);
+#if GDR_ENABLED
+      if (isEncodeGdrClean)
+      {
+        Position pos = puAbove->lumaPos();
+        mrgCtx.mvPos[(cnt << 1) + 1] = pos;
+        mrgCtx.mvSolid[(cnt << 1) + 1] = cs.isClean(pos, pu.chType);
+        mrgCtx.mvValid[(cnt << 1) + 1] = cs.isClean(pu.Y().bottomRight(), miAbove.mv[1], REF_PIC_LIST_1, miAbove.refIdx[1]);
+      }
+#endif
     }
     if (mrgCandIdx == cnt)
     {
@@ -1045,10 +1206,28 @@ void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx,
       mrgCtx.BcwIdx[cnt] = (mrgCtx.interDirNeighbours[cnt] == 3) ? puLeft->cu->BcwIdx : BCW_DEFAULT;
       // get Mv from Left
       mrgCtx.mvFieldNeighbours[cnt << 1].setMvField(miLeft.mv[0], miLeft.refIdx[0]);
+#if GDR_ENABLED
+      if (isEncodeGdrClean)
+      {
+        Position pos = puLeft->lumaPos();
+        mrgCtx.mvPos[(cnt << 1) + 0] = pos;
+        mrgCtx.mvSolid[(cnt << 1) + 0] = cs.isClean(pos, pu.chType);
+        mrgCtx.mvValid[(cnt << 1) + 0] = cs.isClean(pu.Y().bottomRight(), miLeft.mv[0], REF_PIC_LIST_0, miLeft.refIdx[0]);
+      }
+#endif
 
       if (slice.isInterB())
       {
         mrgCtx.mvFieldNeighbours[(cnt << 1) + 1].setMvField(miLeft.mv[1], miLeft.refIdx[1]);
+#if GDR_ENABLED
+        if (isEncodeGdrClean)
+        {
+          Position pos = puLeft->lumaPos();
+          mrgCtx.mvPos[(cnt << 1) + 1] = pos;
+          mrgCtx.mvSolid[(cnt << 1) + 1] = cs.isClean(pos, pu.chType);
+          mrgCtx.mvValid[(cnt << 1) + 1] = cs.isClean(pu.Y().bottomRight(), miLeft.mv[1], REF_PIC_LIST_1, miLeft.refIdx[1]);
+        }
+#endif
       }
       if (mrgCandIdx == cnt)
       {
@@ -1083,10 +1262,28 @@ void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx,
       // get Mv from Above-right
       mrgCtx.BcwIdx[cnt] = (mrgCtx.interDirNeighbours[cnt] == 3) ? puAboveRight->cu->BcwIdx : BCW_DEFAULT;
       mrgCtx.mvFieldNeighbours[cnt << 1].setMvField( miAboveRight.mv[0], miAboveRight.refIdx[0] );
+#if GDR_ENABLED
+      if (isEncodeGdrClean)
+      {
+        Position pos = puAboveRight->lumaPos();
+        mrgCtx.mvPos[(cnt << 1) + 0] = pos;
+        mrgCtx.mvSolid[(cnt << 1) + 0] = cs.isClean(pos, pu.chType);
+        mrgCtx.mvValid[(cnt << 1) + 0] = cs.isClean(pu.Y().bottomRight(), miAboveRight.mv[0], REF_PIC_LIST_0, miAboveRight.refIdx[0]);
+      }
+#endif
 
       if( slice.isInterB() )
       {
         mrgCtx.mvFieldNeighbours[( cnt << 1 ) + 1].setMvField( miAboveRight.mv[1], miAboveRight.refIdx[1] );
+#if GDR_ENABLED
+        if (isEncodeGdrClean)
+        {
+          Position pos = puAboveRight->lumaPos();
+          mrgCtx.mvPos[(cnt << 1) + 1] = pos;
+          mrgCtx.mvSolid[(cnt << 1) + 1] = cs.isClean(pos, pu.chType);
+          mrgCtx.mvValid[(cnt << 1) + 1] = cs.isClean(pu.Y().bottomRight(), miAboveRight.mv[1], REF_PIC_LIST_1, miAboveRight.refIdx[1]);
+        }
+#endif
       }
 
       if (mrgCandIdx == cnt)
@@ -1120,10 +1317,28 @@ void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx,
       mrgCtx.BcwIdx[cnt] = (mrgCtx.interDirNeighbours[cnt] == 3) ? puLeftBottom->cu->BcwIdx : BCW_DEFAULT;
       // get Mv from Bottom-Left
       mrgCtx.mvFieldNeighbours[cnt << 1].setMvField( miBelowLeft.mv[0], miBelowLeft.refIdx[0] );
+#if GDR_ENABLED
+      if (isEncodeGdrClean)
+      {
+        Position pos = puLeftBottom->lumaPos();
+        mrgCtx.mvPos[(cnt << 1) + 0] = pos;
+        mrgCtx.mvSolid[(cnt << 1) + 0] = cs.isClean(pos, pu.chType);
+        mrgCtx.mvValid[(cnt << 1) + 0] = cs.isClean(pu.Y().bottomRight(), miBelowLeft.mv[0], REF_PIC_LIST_0, miBelowLeft.refIdx[0]);
+      }
+#endif
 
       if( slice.isInterB() )
       {
         mrgCtx.mvFieldNeighbours[( cnt << 1 ) + 1].setMvField( miBelowLeft.mv[1], miBelowLeft.refIdx[1] );
+#if GDR_ENABLED
+        if (isEncodeGdrClean)
+        {
+          Position pos = puLeftBottom->lumaPos();
+          mrgCtx.mvPos[(cnt << 1) + 1] = pos;
+          mrgCtx.mvSolid[(cnt << 1) + 1] = cs.isClean(pos, pu.chType);
+          mrgCtx.mvValid[(cnt << 1) + 1] = cs.isClean(pu.Y().bottomRight(), miBelowLeft.mv[1], REF_PIC_LIST_1, miBelowLeft.refIdx[1]);
+        }
+#endif
       }
 
       if (mrgCandIdx == cnt)
@@ -1160,10 +1375,28 @@ void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx,
         mrgCtx.BcwIdx[cnt] = (mrgCtx.interDirNeighbours[cnt] == 3) ? puAboveLeft->cu->BcwIdx : BCW_DEFAULT;
         // get Mv from Above-Left
         mrgCtx.mvFieldNeighbours[cnt << 1].setMvField( miAboveLeft.mv[0], miAboveLeft.refIdx[0] );
+#if GDR_ENABLED
+        if (isEncodeGdrClean)
+        {
+          Position pos = puAboveLeft->lumaPos();
+          mrgCtx.mvPos[(cnt << 1) + 0] = pos;
+          mrgCtx.mvSolid[(cnt << 1) + 0] = cs.isClean(pos, pu.chType);
+          mrgCtx.mvValid[(cnt << 1) + 0] = cs.isClean(pu.Y().bottomRight(), miAboveLeft.mv[0], REF_PIC_LIST_0, miAboveLeft.refIdx[0]);
+        }
+#endif
 
         if( slice.isInterB() )
         {
           mrgCtx.mvFieldNeighbours[( cnt << 1 ) + 1].setMvField( miAboveLeft.mv[1], miAboveLeft.refIdx[1] );
+#if GDR_ENABLED
+          if (isEncodeGdrClean)
+          {
+            Position pos = puAboveLeft->lumaPos();
+            mrgCtx.mvPos[(cnt << 1) + 1] = pos;
+            mrgCtx.mvSolid[(cnt << 1) + 1] = cs.isClean(pos, pu.chType);
+            mrgCtx.mvValid[(cnt << 1) + 1] = cs.isClean(pu.Y().bottomRight(), miAboveLeft.mv[1], REF_PIC_LIST_1, miAboveLeft.refIdx[1]);
+          }
+#endif
         }
 
         if (mrgCandIdx == cnt)
@@ -1187,6 +1420,12 @@ void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx,
     // offset the pos to be sure to "point" to the same position the uiAbsPartIdx would've pointed to
     Position posRB = pu.Y().bottomRight().offset( -3, -3 );
     const PreCalcValues& pcv = *cs.pcv;
+#if GDR_ENABLED
+    bool posC0inCurPicSolid = true;
+    bool posC1inCurPicSolid = true;
+    bool posC0inRefPicSolid = true;
+    bool posC1inRefPicSolid = true;
+#endif
 
     Position posC0;
     Position posC1 = pu.Y().center();
@@ -1218,6 +1457,24 @@ void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx,
     {
       dir     |= 1;
       mrgCtx.mvFieldNeighbours[2 * uiArrayAddr].setMvField(cColMv, iRefIdx);
+#if GDR_ENABLED
+      if (isEncodeGdrClean)
+      {
+        Mv ccMv;
+
+        posC0inCurPicSolid = cs.isClean(posC0, CHANNEL_TYPE_LUMA);
+        posC1inCurPicSolid = cs.isClean(posC1, CHANNEL_TYPE_LUMA);
+        posC0inRefPicSolid = cs.isClean(posC0, REF_PIC_LIST_0, iRefIdx);
+        posC1inRefPicSolid = cs.isClean(posC1, REF_PIC_LIST_0, iRefIdx);
+
+        bool isMVP0exist = C0Avail && getColocatedMVP(pu, REF_PIC_LIST_0, posC0, ccMv, iRefIdx, false);
+
+        Position pos = isMVP0exist ? posC0 : posC1;
+        mrgCtx.mvPos[2 * uiArrayAddr] = pos;
+        mrgCtx.mvSolid[2 * uiArrayAddr] = isMVP0exist ? (posC0inCurPicSolid && posC0inRefPicSolid) : (posC1inCurPicSolid && posC1inRefPicSolid);
+        mrgCtx.mvValid[2 * uiArrayAddr] = cs.isClean(pu.Y().bottomRight(), ccMv, REF_PIC_LIST_0, iRefIdx);
+      }
+#endif
     }
 
     if (slice.isInterB())
@@ -1228,6 +1485,24 @@ void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx,
       {
         dir     |= 2;
         mrgCtx.mvFieldNeighbours[2 * uiArrayAddr + 1].setMvField(cColMv, iRefIdx);
+#if GDR_ENABLED
+        if (isEncodeGdrClean)
+        {
+          Mv ccMv;
+
+          posC0inCurPicSolid = cs.isClean(posC0, CHANNEL_TYPE_LUMA);
+          posC1inCurPicSolid = cs.isClean(posC1, CHANNEL_TYPE_LUMA);
+          posC0inRefPicSolid = cs.isClean(posC0, REF_PIC_LIST_1, iRefIdx);
+          posC1inRefPicSolid = cs.isClean(posC1, REF_PIC_LIST_1, iRefIdx);
+
+          bool isMVP0exist = C0Avail && getColocatedMVP(pu, REF_PIC_LIST_1, posC0, ccMv, iRefIdx, false);
+
+          Position pos = isMVP0exist ? posC0 : posC1;
+          mrgCtx.mvPos[2 * uiArrayAddr + 1] = pos;
+          mrgCtx.mvSolid[2 * uiArrayAddr + 1] = isMVP0exist ? (posC0inCurPicSolid && posC0inRefPicSolid) : (posC1inCurPicSolid && posC1inRefPicSolid);
+          mrgCtx.mvValid[2 * uiArrayAddr + 1] = cs.isClean(pu.Y().bottomRight(), ccMv, REF_PIC_LIST_1, iRefIdx);
+        }
+#endif
       }
     }
 
@@ -1259,8 +1534,16 @@ void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx,
   if (cnt != maxNumMergeCandMin1)
   {
     bool isGt4x4 = true;
+#if GDR_ENABLED
+    allCandSolidInAbove = true;
+#endif
+#if GDR_ENABLED
+    bool bFound  = addMergeHMVPCand(cs, mrgCtx, mrgCandIdx, maxNumMergeCandMin1, cnt, isAvailableA1, miLeft,
+                                   isAvailableB1, miAbove, CU::isIBC(*pu.cu), isGt4x4, pu, allCandSolidInAbove);
+#else
     bool bFound  = addMergeHMVPCand(cs, mrgCtx, mrgCandIdx, maxNumMergeCandMin1, cnt, isAvailableA1, miLeft,
                                    isAvailableB1, miAbove, CU::isIBC(*pu.cu), isGt4x4);
+#endif
 
     if (bFound)
     {
@@ -1283,6 +1566,12 @@ void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx,
         const short refIdxI = mrgCtx.mvFieldNeighbours[0 * 2 + refListId].refIdx;
         const short refIdxJ = mrgCtx.mvFieldNeighbours[1 * 2 + refListId].refIdx;
 
+#if GDR_ENABLED
+        // GDR: Pairwise average candidate
+        bool mvISolid = mrgCtx.mvSolid[0 * 2 + refListId];
+        bool mvJSolid = mrgCtx.mvSolid[1 * 2 + refListId];
+        bool mvSolid = true;
+#endif
         // both MVs are invalid, skip
         if( (refIdxI == NOT_VALID) && (refIdxJ == NOT_VALID) )
         {
@@ -1302,17 +1591,53 @@ void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx,
           roundAffineMv(avgMv.hor, avgMv.ver, 1);
 
           mrgCtx.mvFieldNeighbours[cnt * 2 + refListId].setMvField( avgMv, refIdxI );
+#if GDR_ENABLED
+          // GDR: Pairwise single I,J candidate
+          if (isEncodeGdrClean)
+          {
+            mvSolid = mvISolid && mvJSolid && allCandSolidInAbove;
+
+            mrgCtx.mvPos[cnt * 2 + refListId] = Position(0, 0);
+            mrgCtx.mvSolid[cnt * 2 + refListId] = mvSolid && allCandSolidInAbove;
+            mrgCtx.mvValid[cnt * 2 + refListId] = cs.isClean(pu.Y().bottomRight(), avgMv, (RefPicList)refListId, refIdxI);
+            allCandSolidInAbove = mvSolid && allCandSolidInAbove;
+          }
+#endif
         }
         // only one MV is valid, take the only one MV
         else if( refIdxI != NOT_VALID )
         {
           Mv singleMv = mrgCtx.mvFieldNeighbours[0 * 2 + refListId].mv;
           mrgCtx.mvFieldNeighbours[cnt * 2 + refListId].setMvField( singleMv, refIdxI );
+#if GDR_ENABLED
+          // GDR: Pairwise single I,J candidate
+          if (isEncodeGdrClean)
+          {
+            mvSolid = mvISolid && allCandSolidInAbove;
+
+            mrgCtx.mvPos[cnt * 2 + refListId] = Position(0, 0);
+            mrgCtx.mvSolid[cnt * 2 + refListId] = mvSolid && allCandSolidInAbove;
+            mrgCtx.mvValid[cnt * 2 + refListId] = cs.isClean(pu.Y().bottomRight(), singleMv, (RefPicList)refListId, refIdxI);
+            allCandSolidInAbove = mvSolid && allCandSolidInAbove;
+          }
+#endif
         }
         else if( refIdxJ != NOT_VALID )
         {
           Mv singleMv = mrgCtx.mvFieldNeighbours[1 * 2 + refListId].mv;
           mrgCtx.mvFieldNeighbours[cnt * 2 + refListId].setMvField( singleMv, refIdxJ );
+#if GDR_ENABLED
+          // GDR: Pairwise single I,J candidate
+          if (isEncodeGdrClean)
+          {
+            mvSolid = mvJSolid && allCandSolidInAbove;
+
+            mrgCtx.mvPos[cnt * 2 + refListId] = Position(0, 0);
+            mrgCtx.mvSolid[cnt * 2 + refListId] = mvSolid && allCandSolidInAbove;
+            mrgCtx.mvValid[cnt * 2 + refListId] = cs.isClean(pu.Y().bottomRight(), singleMv, (RefPicList)refListId, refIdxJ);
+            allCandSolidInAbove = mvSolid && allCandSolidInAbove;
+          }
+#endif
         }
       }
 
@@ -1343,10 +1668,30 @@ void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx,
     mrgCtx.mvFieldNeighbours  [uiArrayAddr << 1].setMvField(Mv(0, 0), r);
     mrgCtx.useAltHpelIf[uiArrayAddr] = false;
 
+#if GDR_ENABLED
+    // GDR: zero mv(0,0)
+    if (isEncodeGdrClean)
+    {
+      mrgCtx.mvPos[uiArrayAddr << 1] = Position(0, 0);
+      mrgCtx.mvSolid[uiArrayAddr << 1] = true && allCandSolidInAbove;
+      mrgCtx.mvValid[uiArrayAddr << 1] = cs.isClean(pu.Y().bottomRight(), Mv(0, 0), REF_PIC_LIST_0, r);
+      allCandSolidInAbove = true && allCandSolidInAbove;
+    }
+#endif
     if (slice.isInterB())
     {
       mrgCtx.interDirNeighbours [ uiArrayAddr          ] = 3;
       mrgCtx.mvFieldNeighbours  [(uiArrayAddr << 1) + 1].setMvField(Mv(0, 0), r);
+#if GDR_ENABLED
+      // GDR: zero mv(0,0)
+      if (isEncodeGdrClean)
+      {
+        mrgCtx.mvPos[(uiArrayAddr << 1) + 1] = Position(0, 0);
+        mrgCtx.mvSolid[(uiArrayAddr << 1) + 1] = true && allCandSolidInAbove;
+        mrgCtx.mvValid[(uiArrayAddr << 1) + 1] = cs.isClean(pu.Y().bottomRight(), Mv(0, 0), (RefPicList)REF_PIC_LIST_1, r);
+        allCandSolidInAbove = true && allCandSolidInAbove;
+      }
+#endif
     }
 
     if ( mrgCtx.interDirNeighbours[uiArrayAddr] == 1 && pu.cs->slice->getRefPic(REF_PIC_LIST_0, mrgCtx.mvFieldNeighbours[uiArrayAddr << 1].refIdx)->getPOC() == pu.cs->slice->getPOC())
@@ -1464,6 +1809,20 @@ void PU::getInterMMVDMergeCandidates(const PredictionUnit &pu, MergeCtx& mrgCtx,
   int currBaseNum = 0;
   const uint16_t maxNumMergeCand = mrgCtx.numValidMergeCand;
 
+#if GDR_ENABLED
+  const CodingStructure &cs = *pu.cs;
+  const bool isEncodeGdrClean = cs.sps->getGDREnabledFlag() && cs.pcv->isEncoder && ((cs.picHeader->getInGdrInterval() && cs.isClean(pu.Y().topRight(), CHANNEL_TYPE_LUMA)) || (cs.picHeader->getNumVerVirtualBoundaries() == 0));
+#endif
+
+#if GDR_ENABLED
+  for (int k = 0; k < MMVD_BASE_MV_NUM; k++)
+  {
+    mrgCtx.mmvdSolid[k][0] = true;
+    mrgCtx.mmvdSolid[k][1] = true;
+    mrgCtx.mmvdValid[k][0] = true;
+    mrgCtx.mmvdValid[k][1] = true;
+  }
+#endif
   for (k = 0; k < maxNumMergeCand; k++)
   {
     if (mrgCtx.mrgTypeNeighbours[k] == MRG_TYPE_DEFAULT_N)
@@ -1475,16 +1834,37 @@ void PU::getInterMMVDMergeCandidates(const PredictionUnit &pu, MergeCtx& mrgCtx,
       {
         mrgCtx.mmvdBaseMv[currBaseNum][0] = mrgCtx.mvFieldNeighbours[(k << 1)];
         mrgCtx.mmvdBaseMv[currBaseNum][1] = mrgCtx.mvFieldNeighbours[(k << 1) + 1];
+#if GDR_ENABLED
+        if (isEncodeGdrClean)
+        {
+          mrgCtx.mmvdSolid[currBaseNum][0] = mrgCtx.mvSolid[(k << 1) + 0];
+          mrgCtx.mmvdSolid[currBaseNum][1] = mrgCtx.mvSolid[(k << 1) + 1];
+        }
+#endif
       }
       else if (refIdxList0 >= 0)
       {
         mrgCtx.mmvdBaseMv[currBaseNum][0] = mrgCtx.mvFieldNeighbours[(k << 1)];
         mrgCtx.mmvdBaseMv[currBaseNum][1] = MvField(Mv(0, 0), -1);
+#if GDR_ENABLED
+        if (isEncodeGdrClean)
+        {
+          mrgCtx.mmvdSolid[currBaseNum][0] = mrgCtx.mvSolid[(k << 1) + 0];
+          mrgCtx.mmvdSolid[currBaseNum][1] = true;
+        }
+#endif
       }
       else if (refIdxList1 >= 0)
       {
         mrgCtx.mmvdBaseMv[currBaseNum][0] = MvField(Mv(0, 0), -1);
         mrgCtx.mmvdBaseMv[currBaseNum][1] = mrgCtx.mvFieldNeighbours[(k << 1) + 1];
+#if GDR_ENABLED
+        if (isEncodeGdrClean)
+        {
+          mrgCtx.mmvdSolid[currBaseNum][0] = true;
+          mrgCtx.mmvdSolid[currBaseNum][1] = mrgCtx.mvSolid[(k << 1) + 1];
+        }
+#endif
       }
       mrgCtx.mmvdUseAltHpelIf[currBaseNum] = mrgCtx.useAltHpelIf[k];
 
@@ -1826,6 +2206,10 @@ void PU::fillMvpCand(PredictionUnit &pu, const RefPicList &eRefPicList, const in
   Position posRT = pu.Y().topRight();
   Position posLB = pu.Y().bottomLeft();
 
+#if GDR_ENABLED
+  const bool isEncodeGdrClean = cs.sps->getGDREnabledFlag() && cs.pcv->isEncoder && ((cs.picHeader->getInGdrInterval() && cs.isClean(pu.Y().topRight(), CHANNEL_TYPE_LUMA)) || (cs.picHeader->getNumVerVirtualBoundaries() == 0));
+  bool &allCandSolidInAbove = amvpInfo.allCandSolidInAbove;
+#endif
   {
     bool bAdded = addMVPCandUnscaled( pu, eRefPicList, refIdx, posLB, MD_BELOW_LEFT, *pInfo );
 
@@ -1896,6 +2280,24 @@ void PU::fillMvpCand(PredictionUnit &pu, const RefPicList &eRefPicList, const in
     }
     if ( ( C0Avail && getColocatedMVP( pu, eRefPicList, posC0, cColMv, refIdx_Col, false ) ) || getColocatedMVP( pu, eRefPicList, posC1, cColMv, refIdx_Col, false ) )
     {
+#if GDR_ENABLED
+      if (isEncodeGdrClean)
+      {
+        Mv   ccMv;
+        bool posC0inCurPicSolid = cs.isClean(posC0, CHANNEL_TYPE_LUMA);
+        bool posC1inCurPicSolid = cs.isClean(posC1, CHANNEL_TYPE_LUMA);
+        bool posC0inRefPicSolid = cs.isClean(posC0, REF_PIC_LIST_0, refIdx_Col);
+        bool posC1inRefPicSolid = cs.isClean(posC1, REF_PIC_LIST_0, refIdx_Col);
+
+        bool isMVP0exist = C0Avail && getColocatedMVP(pu, eRefPicList, posC0, ccMv, refIdx_Col, false);
+
+        Position pos = isMVP0exist ? posC0 : posC1;
+        pInfo->mvPos[pInfo->numCand]   = pos;
+        pInfo->mvType[pInfo->numCand]  = isMVP0exist ? MVP_TMVP_C0 : MVP_TMVP_C1;
+        pInfo->mvSolid[pInfo->numCand] = allCandSolidInAbove && (isMVP0exist ? (posC0inCurPicSolid && posC0inRefPicSolid) : (posC1inCurPicSolid && posC1inRefPicSolid));
+        allCandSolidInAbove = allCandSolidInAbove && pInfo->mvSolid[pInfo->numCand];
+      }
+#endif
       cColMv.roundTransPrecInternal2Amvr(pu.cu->imv);
       pInfo->mvCand[pInfo->numCand++] = cColMv;
     }
@@ -1914,6 +2316,13 @@ void PU::fillMvpCand(PredictionUnit &pu, const RefPicList &eRefPicList, const in
 
   while (pInfo->numCand < AMVP_MAX_NUM_CANDS)
   {
+#if GDR_ENABLED
+    if (isEncodeGdrClean)
+    {
+      pInfo->mvType[pInfo->numCand] = MVP_ZERO;
+      allCandSolidInAbove = pInfo->mvSolid[pInfo->numCand] = true && allCandSolidInAbove;
+    }
+#endif
     pInfo->mvCand[pInfo->numCand] = Mv( 0, 0 );
     pInfo->numCand++;
   }
@@ -1930,6 +2339,9 @@ bool PU::addAffineMVPCandUnscaled( const PredictionUnit &pu, const RefPicList &r
   const PredictionUnit *neibPU = NULL;
   Position neibPos;
 
+#if GDR_ENABLED
+  const bool isEncodeGdrClean = cs.sps->getGDREnabledFlag() && cs.pcv->isEncoder && ((cs.picHeader->getInGdrInterval() && cs.isClean(pu.Y().topRight(), CHANNEL_TYPE_LUMA)) || (cs.picHeader->getNumVerVirtualBoundaries() == 0));
+#endif
   switch ( dir )
   {
   case MD_LEFT:
@@ -1959,6 +2371,11 @@ bool PU::addAffineMVPCandUnscaled( const PredictionUnit &pu, const RefPicList &r
   }
 
   Mv outputAffineMv[3];
+#if GDR_ENABLED
+  bool     outputAffineMvSolid[3];
+  MvpType  outputAffineMvType[3];
+  Position outputAffineMvPos[3];
+#endif
   const MotionInfo& neibMi = neibPU->getMotionInfo( neibPos );
 
   const int        currRefPOC = cs.slice->getRefPic( refPicList, refIdx )->getPOC();
@@ -1974,15 +2391,54 @@ bool PU::addAffineMVPCandUnscaled( const PredictionUnit &pu, const RefPicList &r
       continue;
     }
 
+#if GDR_ENABLED
+    // note : get MV from neihgbor of neibPu (LB, RB) and save to outputAffineMv
+    if (isEncodeGdrClean)
+    {
+      xInheritedAffineMv(pu, neibPU, eRefPicListIndex, outputAffineMv, outputAffineMvSolid, outputAffineMvType, outputAffineMvPos);
+    }
+    else
+    {
+      xInheritedAffineMv(pu, neibPU, eRefPicListIndex, outputAffineMv);
+    }
+#else
     xInheritedAffineMv( pu, neibPU, eRefPicListIndex, outputAffineMv );
+#endif
     outputAffineMv[0].roundAffinePrecInternal2Amvr(pu.cu->imv);
     outputAffineMv[1].roundAffinePrecInternal2Amvr(pu.cu->imv);
     affiAMVPInfo.mvCandLT[affiAMVPInfo.numCand] = outputAffineMv[0];
     affiAMVPInfo.mvCandRT[affiAMVPInfo.numCand] = outputAffineMv[1];
+#if GDR_ENABLED
+    bool neighClean = true;
+
+    if (isEncodeGdrClean)
+    {
+      neighClean = cs.isClean(neibPU->Y().pos(), CHANNEL_TYPE_LUMA);
+
+      affiAMVPInfo.mvSolidLT[affiAMVPInfo.numCand] = neighClean && outputAffineMvSolid[0];
+      affiAMVPInfo.mvSolidRT[affiAMVPInfo.numCand] = neighClean && outputAffineMvSolid[1];
+
+      affiAMVPInfo.mvTypeLT[affiAMVPInfo.numCand]  = outputAffineMvType[0];
+      affiAMVPInfo.mvTypeRT[affiAMVPInfo.numCand]  = outputAffineMvType[1];
+
+      affiAMVPInfo.mvPosLT[affiAMVPInfo.numCand]   = outputAffineMvPos[0];
+      affiAMVPInfo.mvPosRT[affiAMVPInfo.numCand]   = outputAffineMvPos[1];
+    }
+#endif
     if ( pu.cu->affineType == AFFINEMODEL_6PARAM )
     {
       outputAffineMv[2].roundAffinePrecInternal2Amvr(pu.cu->imv);
       affiAMVPInfo.mvCandLB[affiAMVPInfo.numCand] = outputAffineMv[2];
+#if GDR_ENABLED
+      if (isEncodeGdrClean)
+      {
+        neighClean = cs.isClean(neibPU->Y().pos(), CHANNEL_TYPE_LUMA);
+
+        affiAMVPInfo.mvSolidLB[affiAMVPInfo.numCand] = neighClean && outputAffineMvSolid[2];
+        affiAMVPInfo.mvTypeLB[affiAMVPInfo.numCand]  = outputAffineMvType[2];
+        affiAMVPInfo.mvPosLB[affiAMVPInfo.numCand]   = outputAffineMvPos[2];
+      }
+#endif
     }
     affiAMVPInfo.numCand++;
     return true;
@@ -1990,6 +2446,132 @@ bool PU::addAffineMVPCandUnscaled( const PredictionUnit &pu, const RefPicList &r
 
   return false;
 }
+#if GDR_ENABLED
+void PU::xInheritedAffineMv(const PredictionUnit &pu, const PredictionUnit* puNeighbour, RefPicList eRefPicList, Mv rcMv[3], bool rcMvSolid[3], MvpType rcMvType[3], Position rcMvPos[3])
+{
+  const CodingStructure &cs = *pu.cs;
+  const bool isEncodeGdrClean = cs.sps->getGDREnabledFlag() && cs.pcv->isEncoder && ((cs.picHeader->getInGdrInterval() && cs.isClean(pu.Y().topRight(), CHANNEL_TYPE_LUMA)) || (cs.picHeader->getNumVerVirtualBoundaries() == 0));
+
+  int posNeiX = puNeighbour->Y().pos().x;
+  int posNeiY = puNeighbour->Y().pos().y;
+  int posCurX = pu.Y().pos().x;
+  int posCurY = pu.Y().pos().y;
+
+  int neiW = puNeighbour->Y().width;
+  int curW = pu.Y().width;
+  int neiH = puNeighbour->Y().height;
+  int curH = pu.Y().height;
+
+  Mv mvLT, mvRT, mvLB;
+
+  mvLT = puNeighbour->mvAffi[eRefPicList][0];
+  mvRT = puNeighbour->mvAffi[eRefPicList][1];
+  mvLB = puNeighbour->mvAffi[eRefPicList][2];
+
+
+#if GDR_ENABLED
+  bool neighClean = true;
+
+  if (isEncodeGdrClean)
+  {
+    neighClean = cs.isClean(puNeighbour->Y().pos(), CHANNEL_TYPE_LUMA);
+
+    rcMvSolid[0] = neighClean;
+    rcMvSolid[1] = neighClean;
+    rcMvSolid[2] = neighClean;
+
+    rcMvType[0] = AFFINE_INHERIT;
+    rcMvType[1] = AFFINE_INHERIT;
+    rcMvType[2] = AFFINE_INHERIT;
+
+    rcMvPos[0] = puNeighbour->Y().pos();
+    rcMvPos[1] = puNeighbour->Y().pos();
+    rcMvPos[2] = puNeighbour->Y().pos();
+  }
+#endif
+
+
+  bool isTopCtuBoundary = false;
+  if ((posNeiY + neiH) % pu.cs->sps->getCTUSize() == 0 && (posNeiY + neiH) == posCurY)
+  {
+    // use bottom-left and bottom-right sub-block MVs for inheritance
+    const Position posRB = puNeighbour->Y().bottomRight();
+    const Position posLB = puNeighbour->Y().bottomLeft();
+
+    mvLT = puNeighbour->getMotionInfo(posLB).mv[eRefPicList];
+    mvRT = puNeighbour->getMotionInfo(posRB).mv[eRefPicList];
+
+#if GDR_ENABLED
+    if (isEncodeGdrClean)
+    {
+      neighClean = cs.isClean(puNeighbour->Y().pos(), CHANNEL_TYPE_LUMA);
+
+      rcMvSolid[0] = cs.isClean(posLB, CHANNEL_TYPE_LUMA);
+      rcMvSolid[1] = cs.isClean(posRB, CHANNEL_TYPE_LUMA);
+      rcMvSolid[2] = neighClean;
+
+      rcMvType[0]  = AFFINE_INHERIT_LB_RB;
+      rcMvType[1]  = AFFINE_INHERIT_LB_RB;
+      rcMvType[2]  = AFFINE_INHERIT_LB_RB;
+
+      rcMvPos[0]   = posLB;
+      rcMvPos[1]   = posRB;
+      rcMvPos[2]   = puNeighbour->Y().pos();
+    }
+#endif
+
+    posNeiY += neiH;
+    isTopCtuBoundary = true;
+  }
+
+  int shift = MAX_CU_DEPTH;
+  int iDMvHorX, iDMvHorY, iDMvVerX, iDMvVerY;
+
+  iDMvHorX = (mvRT - mvLT).getHor() << (shift - floorLog2(neiW));
+  iDMvHorY = (mvRT - mvLT).getVer() << (shift - floorLog2(neiW));
+  if (puNeighbour->cu->affineType == AFFINEMODEL_6PARAM && !isTopCtuBoundary)
+  {
+    iDMvVerX = (mvLB - mvLT).getHor() << (shift - floorLog2(neiH));
+    iDMvVerY = (mvLB - mvLT).getVer() << (shift - floorLog2(neiH));
+  }
+  else
+  {
+    iDMvVerX = -iDMvHorY;
+    iDMvVerY = iDMvHorX;
+  }
+
+  int iMvScaleHor = mvLT.getHor() << shift;
+  int iMvScaleVer = mvLT.getVer() << shift;
+  int horTmp, verTmp;
+
+  // v0
+  horTmp = iMvScaleHor + iDMvHorX * (posCurX - posNeiX) + iDMvVerX * (posCurY - posNeiY);
+  verTmp = iMvScaleVer + iDMvHorY * (posCurX - posNeiX) + iDMvVerY * (posCurY - posNeiY);
+  roundAffineMv(horTmp, verTmp, shift);
+  rcMv[0].hor = horTmp;
+  rcMv[0].ver = verTmp;
+  rcMv[0].clipToStorageBitDepth();
+
+  // v1
+  horTmp = iMvScaleHor + iDMvHorX * (posCurX + curW - posNeiX) + iDMvVerX * (posCurY - posNeiY);
+  verTmp = iMvScaleVer + iDMvHorY * (posCurX + curW - posNeiX) + iDMvVerY * (posCurY - posNeiY);
+  roundAffineMv(horTmp, verTmp, shift);
+  rcMv[1].hor = horTmp;
+  rcMv[1].ver = verTmp;
+  rcMv[1].clipToStorageBitDepth();
+
+  // v2
+  if (pu.cu->affineType == AFFINEMODEL_6PARAM)
+  {
+    horTmp = iMvScaleHor + iDMvHorX * (posCurX - posNeiX) + iDMvVerX * (posCurY + curH - posNeiY);
+    verTmp = iMvScaleVer + iDMvHorY * (posCurX - posNeiX) + iDMvVerY * (posCurY + curH - posNeiY);
+    roundAffineMv(horTmp, verTmp, shift);
+    rcMv[2].hor = horTmp;
+    rcMv[2].ver = verTmp;
+    rcMv[2].clipToStorageBitDepth();
+  }
+}
+#endif
 
 void PU::xInheritedAffineMv( const PredictionUnit &pu, const PredictionUnit* puNeighbour, RefPicList eRefPicList, Mv rcMv[3] )
 {
@@ -2078,8 +2660,31 @@ void PU::fillAffineMvpCand(PredictionUnit &pu, const RefPicList &eRefPicList, co
     return;
   }
 
+#if GDR_ENABLED
+  const CodingStructure &cs = *pu.cs;
+  const bool isEncodeGdrClean = cs.sps->getGDREnabledFlag() && cs.pcv->isEncoder && ((cs.picHeader->getInGdrInterval() && cs.isClean(pu.Y().topRight(), CHANNEL_TYPE_LUMA)) || (cs.picHeader->getNumVerVirtualBoundaries() == 0));
+  bool &allCandSolidInAbove = affiAMVPInfo.allCandSolidInAbove;
+
+  if (isEncodeGdrClean)
+  {
+    allCandSolidInAbove = true;
+
+    affiAMVPInfo.allCandSolidInAbove = true;
+    for (int i = 0; i < AMVP_MAX_NUM_CANDS_MEM; i++)
+    {
+      affiAMVPInfo.mvSolidLT[i] = true;
+      affiAMVPInfo.mvSolidRT[i] = true;
+      affiAMVPInfo.mvSolidLB[i] = true;
+    }
+  }
+#endif
   // insert inherited affine candidates
   Mv outputAffineMv[3];
+#if GDR_ENABLED
+  bool     outputAffineMvSolid[3];
+  MvpType  outputAffineMvType[3];
+  Position outputAffineMvPos[3];
+#endif
   Position posLT = pu.Y().topLeft();
   Position posRT = pu.Y().topRight();
   Position posLB = pu.Y().bottomLeft();
@@ -2117,6 +2722,18 @@ void PU::fillAffineMvpCand(PredictionUnit &pu, const RefPicList &eRefPicList, co
   AMVPInfo amvpInfo0;
   amvpInfo0.numCand = 0;
 
+#if GDR_ENABLED
+  if (isEncodeGdrClean)
+  {
+    amvpInfo0.allCandSolidInAbove = true;
+    for (int i = 0; i < AMVP_MAX_NUM_CANDS_MEM; i++)
+    {
+      amvpInfo0.mvSolid[i] = true;
+      amvpInfo0.mvValid[i] = true;
+    }
+  }
+#endif
+
   // A->C: Above Left, Above, Left
   addMVPCandUnscaled( pu, eRefPicList, refIdx, posLT, MD_ABOVE_LEFT, amvpInfo0 );
   if ( amvpInfo0.numCand < 1 )
@@ -2133,6 +2750,18 @@ void PU::fillAffineMvpCand(PredictionUnit &pu, const RefPicList &eRefPicList, co
   AMVPInfo amvpInfo1;
   amvpInfo1.numCand = 0;
 
+#if GDR_ENABLED
+  if (isEncodeGdrClean)
+  {
+    amvpInfo1.allCandSolidInAbove = true;
+    for (int i = 0; i < AMVP_MAX_NUM_CANDS_MEM; i++)
+    {
+      amvpInfo1.mvSolid[i] = true;
+      amvpInfo1.mvValid[i] = true;
+    }
+  }
+#endif
+
   // D->E: Above, Above Right
   addMVPCandUnscaled( pu, eRefPicList, refIdx, posRT, MD_ABOVE, amvpInfo1 );
   if ( amvpInfo1.numCand < 1 )
@@ -2145,6 +2774,18 @@ void PU::fillAffineMvpCand(PredictionUnit &pu, const RefPicList &eRefPicList, co
   AMVPInfo amvpInfo2;
   amvpInfo2.numCand = 0;
 
+#if GDR_ENABLED
+  if (isEncodeGdrClean)
+  {
+    amvpInfo2.allCandSolidInAbove = true;
+    for (int i = 0; i < AMVP_MAX_NUM_CANDS_MEM; i++)
+    {
+      amvpInfo2.mvSolid[i] = true;
+      amvpInfo2.mvValid[i] = true;
+    }
+  }
+#endif
+
   // F->G: Left, Below Left
   addMVPCandUnscaled( pu, eRefPicList, refIdx, posLB, MD_LEFT, amvpInfo2 );
   if ( amvpInfo2.numCand < 1 )
@@ -2157,6 +2798,24 @@ void PU::fillAffineMvpCand(PredictionUnit &pu, const RefPicList &eRefPicList, co
   outputAffineMv[1] = amvpInfo1.mvCand[0];
   outputAffineMv[2] = amvpInfo2.mvCand[0];
 
+#if GDR_ENABLED
+  if (isEncodeGdrClean)
+  {
+    outputAffineMvSolid[0] = amvpInfo0.mvSolid[0] && allCandSolidInAbove;
+    outputAffineMvSolid[1] = amvpInfo1.mvSolid[0] && allCandSolidInAbove;
+    outputAffineMvSolid[2] = amvpInfo2.mvSolid[0] && allCandSolidInAbove;
+
+    outputAffineMvPos[0] = amvpInfo0.mvPos[0];
+    outputAffineMvPos[1] = amvpInfo1.mvPos[0];
+    outputAffineMvPos[2] = amvpInfo2.mvPos[0];
+
+    outputAffineMvType[0] = amvpInfo0.mvType[0];
+    outputAffineMvType[1] = amvpInfo1.mvType[0];
+    outputAffineMvType[2] = amvpInfo2.mvType[0];
+
+    allCandSolidInAbove = allCandSolidInAbove && outputAffineMvSolid[0] && outputAffineMvSolid[1] && outputAffineMvSolid[2];
+  }
+#endif
   outputAffineMv[0].roundAffinePrecInternal2Amvr(pu.cu->imv);
   outputAffineMv[1].roundAffinePrecInternal2Amvr(pu.cu->imv);
   outputAffineMv[2].roundAffinePrecInternal2Amvr(pu.cu->imv);
@@ -2166,6 +2825,24 @@ void PU::fillAffineMvpCand(PredictionUnit &pu, const RefPicList &eRefPicList, co
     affiAMVPInfo.mvCandLT[affiAMVPInfo.numCand] = outputAffineMv[0];
     affiAMVPInfo.mvCandRT[affiAMVPInfo.numCand] = outputAffineMv[1];
     affiAMVPInfo.mvCandLB[affiAMVPInfo.numCand] = outputAffineMv[2];
+#if GDR_ENABLED
+    if (isEncodeGdrClean)
+    {
+      affiAMVPInfo.mvSolidLT[affiAMVPInfo.numCand] = outputAffineMvSolid[0] && allCandSolidInAbove;
+      affiAMVPInfo.mvSolidRT[affiAMVPInfo.numCand] = outputAffineMvSolid[1] && allCandSolidInAbove;
+      affiAMVPInfo.mvSolidLB[affiAMVPInfo.numCand] = outputAffineMvSolid[2] && allCandSolidInAbove;
+
+      affiAMVPInfo.mvPosLT[affiAMVPInfo.numCand] = outputAffineMvPos[0];
+      affiAMVPInfo.mvPosRT[affiAMVPInfo.numCand] = outputAffineMvPos[1];
+      affiAMVPInfo.mvPosLB[affiAMVPInfo.numCand] = outputAffineMvPos[2];
+
+      affiAMVPInfo.mvTypeLT[affiAMVPInfo.numCand] = outputAffineMvType[0];
+      affiAMVPInfo.mvTypeRT[affiAMVPInfo.numCand] = outputAffineMvType[1];
+      affiAMVPInfo.mvTypeLB[affiAMVPInfo.numCand] = outputAffineMvType[2];
+
+      allCandSolidInAbove = allCandSolidInAbove && outputAffineMvSolid[0] && outputAffineMvSolid[1] && outputAffineMvSolid[2];
+    }
+#endif
     affiAMVPInfo.numCand++;
   }
 
@@ -2179,6 +2856,24 @@ void PU::fillAffineMvpCand(PredictionUnit &pu, const RefPicList &eRefPicList, co
         affiAMVPInfo.mvCandLT[affiAMVPInfo.numCand] = outputAffineMv[i];
         affiAMVPInfo.mvCandRT[affiAMVPInfo.numCand] = outputAffineMv[i];
         affiAMVPInfo.mvCandLB[affiAMVPInfo.numCand] = outputAffineMv[i];
+#if GDR_ENABLED
+        if (isEncodeGdrClean)
+        {
+          affiAMVPInfo.mvSolidLT[affiAMVPInfo.numCand] = outputAffineMvSolid[i] && allCandSolidInAbove;
+          affiAMVPInfo.mvSolidRT[affiAMVPInfo.numCand] = outputAffineMvSolid[i] && allCandSolidInAbove;
+          affiAMVPInfo.mvSolidLB[affiAMVPInfo.numCand] = outputAffineMvSolid[i] && allCandSolidInAbove;
+
+          affiAMVPInfo.mvPosLT[affiAMVPInfo.numCand] = outputAffineMvPos[i];
+          affiAMVPInfo.mvPosRT[affiAMVPInfo.numCand] = outputAffineMvPos[i];
+          affiAMVPInfo.mvPosLB[affiAMVPInfo.numCand] = outputAffineMvPos[i];
+
+          affiAMVPInfo.mvTypeLT[affiAMVPInfo.numCand] = outputAffineMvType[i];
+          affiAMVPInfo.mvTypeRT[affiAMVPInfo.numCand] = outputAffineMvType[i];
+          affiAMVPInfo.mvTypeLB[affiAMVPInfo.numCand] = outputAffineMvType[i];
+
+          allCandSolidInAbove = allCandSolidInAbove && outputAffineMvSolid[i];
+        }
+#endif
         affiAMVPInfo.numCand++;
       }
     }
@@ -2218,6 +2913,52 @@ void PU::fillAffineMvpCand(PredictionUnit &pu, const RefPicList &eRefPicList, co
         affiAMVPInfo.mvCandLT[affiAMVPInfo.numCand] = cColMv;
         affiAMVPInfo.mvCandRT[affiAMVPInfo.numCand] = cColMv;
         affiAMVPInfo.mvCandLB[affiAMVPInfo.numCand] = cColMv;
+#if GDR_ENABLED
+        if (isEncodeGdrClean)
+        {
+          Mv ccMv;
+
+          bool posC0inCurPicSolid = cs.isClean(posC0, CHANNEL_TYPE_LUMA);
+          bool posC1inCurPicSolid = cs.isClean(posC1, CHANNEL_TYPE_LUMA);
+          bool posC0inRefPicSolid = cs.isClean(posC0, eRefPicList, refIdxCol);
+          bool posC1inRefPicSolid = cs.isClean(posC1, eRefPicList, refIdxCol);
+
+          bool isMVP0exist = C0Avail && getColocatedMVP(pu, eRefPicList, posC0, ccMv, refIdxCol, false);
+
+          if (isMVP0exist)
+          {
+            affiAMVPInfo.mvSolidLT[affiAMVPInfo.numCand] = posC0inCurPicSolid && posC0inRefPicSolid && allCandSolidInAbove;
+            affiAMVPInfo.mvSolidRT[affiAMVPInfo.numCand] = posC0inCurPicSolid && posC0inRefPicSolid && allCandSolidInAbove;
+            affiAMVPInfo.mvSolidLB[affiAMVPInfo.numCand] = posC0inCurPicSolid && posC0inRefPicSolid && allCandSolidInAbove;
+
+            affiAMVPInfo.mvPosLT[affiAMVPInfo.numCand] = posC0;
+            affiAMVPInfo.mvPosRT[affiAMVPInfo.numCand] = posC0;
+            affiAMVPInfo.mvPosLB[affiAMVPInfo.numCand] = posC0;
+
+            affiAMVPInfo.mvTypeLT[affiAMVPInfo.numCand] = MVP_TMVP_C0;
+            affiAMVPInfo.mvTypeRT[affiAMVPInfo.numCand] = MVP_TMVP_C0;
+            affiAMVPInfo.mvTypeLB[affiAMVPInfo.numCand] = MVP_TMVP_C0;
+
+            allCandSolidInAbove = allCandSolidInAbove && affiAMVPInfo.mvSolidLT[affiAMVPInfo.numCand] && affiAMVPInfo.mvSolidRT[affiAMVPInfo.numCand] && affiAMVPInfo.mvSolidLB[affiAMVPInfo.numCand];
+          }
+          else
+          {
+            affiAMVPInfo.mvSolidLT[affiAMVPInfo.numCand] = posC1inCurPicSolid && posC1inRefPicSolid && allCandSolidInAbove;
+            affiAMVPInfo.mvSolidRT[affiAMVPInfo.numCand] = posC1inCurPicSolid && posC1inRefPicSolid && allCandSolidInAbove;
+            affiAMVPInfo.mvSolidLB[affiAMVPInfo.numCand] = posC1inCurPicSolid && posC1inRefPicSolid && allCandSolidInAbove;
+
+            affiAMVPInfo.mvPosLT[affiAMVPInfo.numCand] = posC1;
+            affiAMVPInfo.mvPosRT[affiAMVPInfo.numCand] = posC1;
+            affiAMVPInfo.mvPosLB[affiAMVPInfo.numCand] = posC1;
+
+            affiAMVPInfo.mvTypeLT[affiAMVPInfo.numCand] = MVP_TMVP_C1;
+            affiAMVPInfo.mvTypeRT[affiAMVPInfo.numCand] = MVP_TMVP_C1;
+            affiAMVPInfo.mvTypeLB[affiAMVPInfo.numCand] = MVP_TMVP_C1;
+
+            allCandSolidInAbove = allCandSolidInAbove && affiAMVPInfo.mvSolidLT[affiAMVPInfo.numCand] && affiAMVPInfo.mvSolidRT[affiAMVPInfo.numCand] && affiAMVPInfo.mvSolidLB[affiAMVPInfo.numCand];
+          }
+        }
+#endif
         affiAMVPInfo.numCand++;
       }
     }
@@ -2230,6 +2971,24 @@ void PU::fillAffineMvpCand(PredictionUnit &pu, const RefPicList &eRefPicList, co
         affiAMVPInfo.mvCandLT[affiAMVPInfo.numCand].setZero();
         affiAMVPInfo.mvCandRT[affiAMVPInfo.numCand].setZero();
         affiAMVPInfo.mvCandLB[affiAMVPInfo.numCand].setZero();
+#if GDR_ENABLED
+        if (isEncodeGdrClean)
+        {
+          affiAMVPInfo.mvSolidLT[affiAMVPInfo.numCand] = true && allCandSolidInAbove;
+          affiAMVPInfo.mvSolidRT[affiAMVPInfo.numCand] = true && allCandSolidInAbove;
+          affiAMVPInfo.mvSolidLB[affiAMVPInfo.numCand] = true && allCandSolidInAbove;
+
+          affiAMVPInfo.mvPosLT[affiAMVPInfo.numCand] = Position(0, 0);
+          affiAMVPInfo.mvPosRT[affiAMVPInfo.numCand] = Position(0, 0);
+          affiAMVPInfo.mvPosLB[affiAMVPInfo.numCand] = Position(0, 0);
+
+          affiAMVPInfo.mvTypeLT[affiAMVPInfo.numCand] = MVP_ZERO;
+          affiAMVPInfo.mvTypeRT[affiAMVPInfo.numCand] = MVP_ZERO;
+          affiAMVPInfo.mvTypeLB[affiAMVPInfo.numCand] = MVP_ZERO;
+
+          allCandSolidInAbove = allCandSolidInAbove && affiAMVPInfo.mvSolidLT[affiAMVPInfo.numCand] && affiAMVPInfo.mvSolidRT[affiAMVPInfo.numCand] && affiAMVPInfo.mvSolidLB[affiAMVPInfo.numCand];
+        }
+#endif
         affiAMVPInfo.numCand++;
       }
     }
@@ -2249,6 +3008,11 @@ bool PU::addMVPCandUnscaled( const PredictionUnit &pu, const RefPicList &eRefPic
   const PredictionUnit *neibPU = NULL;
         Position neibPos;
 
+#if GDR_ENABLED
+  const bool isEncodeGdrClean = cs.sps->getGDREnabledFlag() && cs.pcv->isEncoder && ((cs.picHeader->getInGdrInterval() && cs.isClean(pu.Y().topRight(), CHANNEL_TYPE_LUMA)) || (cs.picHeader->getNumVerVirtualBoundaries() == 0));
+  bool &allCandSolidInAbove = info.allCandSolidInAbove;
+#endif
+
   switch (eDir)
   {
   case MD_LEFT:
@@ -2289,6 +3053,18 @@ bool PU::addMVPCandUnscaled( const PredictionUnit &pu, const RefPicList &eRefPic
 
     if( neibRefIdx >= 0 && currRefPOC == cs.slice->getRefPOC( eRefPicListIndex, neibRefIdx ) )
     {
+#if GDR_ENABLED
+      if (isEncodeGdrClean)
+      {
+        bool isSolid = cs.isClean(neibPos, CHANNEL_TYPE_LUMA);
+
+        info.mvSolid[info.numCand] = isSolid && allCandSolidInAbove;
+        info.mvType[info.numCand] = (MvpType)eDir;
+        info.mvPos[info.numCand] = neibPos;
+
+        allCandSolidInAbove = isSolid && allCandSolidInAbove;
+      }
+#endif
       info.mvCand[info.numCand++] = neibMi.mv[eRefPicListIndex];
       return true;
     }
@@ -2308,6 +3084,22 @@ void PU::addAMVPHMVPCand(const PredictionUnit &pu, const RefPicList eRefPicList,
   int num_allowedCand = std::min(MAX_NUM_HMVP_AVMPCANDS, num_avai_candInLUT);
   const RefPicList eRefPicList2nd = (eRefPicList == REF_PIC_LIST_0) ? REF_PIC_LIST_1 : REF_PIC_LIST_0;
 
+#if GDR_ENABLED
+  CodingStructure &cs = *pu.cs;
+  const bool isEncodeGdrClean = cs.sps->getGDREnabledFlag() && cs.pcv->isEncoder && ((cs.picHeader->getInGdrInterval() && cs.isClean(pu.Y().topRight(), CHANNEL_TYPE_LUMA)) || (cs.picHeader->getNumVerVirtualBoundaries() == 0));
+  bool &allCandSolidInAbove = info.allCandSolidInAbove;
+#endif
+
+
+#if GDR_ENABLED
+  bool vbOnCtuBoundary = true;
+  if (isEncodeGdrClean)
+  {
+    vbOnCtuBoundary = (pu.cs->picHeader->getNumVerVirtualBoundaries() == 0) || (pu.cs->picHeader->getVirtualBoundariesPosX(0) % pu.cs->sps->getMaxCUWidth() == 0);
+    allCandSolidInAbove = allCandSolidInAbove && vbOnCtuBoundary;
+  }
+#endif
+
   for (int mrgIdx = 1; mrgIdx <= num_allowedCand; mrgIdx++)
   {
     if (info.numCand >= AMVP_MAX_NUM_CANDS)
@@ -2326,6 +3118,15 @@ void PU::addAMVPHMVPCand(const PredictionUnit &pu, const RefPicList eRefPicList,
         Mv pmv = neibMi.mv[eRefPicListIndex];
         pmv.roundTransPrecInternal2Amvr(pu.cu->imv);
 
+#if GDR_ENABLED
+        if (isEncodeGdrClean)
+        {
+          info.mvPos[info.numCand]   = neibMi.sourcePos;
+          info.mvType[info.numCand]  = MVP_HMVP;
+          info.mvSolid[info.numCand] = allCandSolidInAbove && vbOnCtuBoundary; //  cs.isClean(neibMi.soPos, CHANNEL_TYPE_LUMA);
+          allCandSolidInAbove = allCandSolidInAbove && vbOnCtuBoundary;
+        }
+#endif
         info.mvCand[info.numCand++] = pmv;
         if (info.numCand >= AMVP_MAX_NUM_CANDS)
         {
@@ -2458,9 +3259,7 @@ void PU::getAffineControlPointCand(const PredictionUnit &pu, MotionInfo mi[4], b
         cMv[l][1].clipToStorageBitDepth();
         break;
 
-      default:
-        CHECK( 1, "Invalid model index!\n" );
-        break;
+      default: THROW("Invalid model index!"); break;
       }
     }
     else
@@ -2554,6 +3353,9 @@ void PU::getAffineMergeCand( const PredictionUnit &pu, AffineMergeCtx& affMrgCtx
   const Slice &slice = *pu.cs->slice;
   const uint32_t maxNumAffineMergeCand = slice.getPicHeader()->getMaxNumAffineMergeCand();
   const unsigned plevel = pu.cs->sps->getLog2ParallelMergeLevelMinus2() + 2;
+#if GDR_ENABLED
+  const bool isEncodeGdrClean = cs.sps->getGDREnabledFlag() && cs.pcv->isEncoder && ((cs.picHeader->getInGdrInterval() && cs.isClean(pu.Y().topRight(), CHANNEL_TYPE_LUMA)) || (cs.picHeader->getNumVerVirtualBoundaries() == 0));
+#endif
 
   for ( int i = 0; i < maxNumAffineMergeCand; i++ )
   {
@@ -2561,12 +3363,33 @@ void PU::getAffineMergeCand( const PredictionUnit &pu, AffineMergeCtx& affMrgCtx
     {
       affMrgCtx.mvFieldNeighbours[(i << 1) + 0][mvNum].setMvField( Mv(), -1 );
       affMrgCtx.mvFieldNeighbours[(i << 1) + 1][mvNum].setMvField( Mv(), -1 );
+#if GDR_ENABLED
+      if (isEncodeGdrClean)
+      {
+        affMrgCtx.mvSolid[(i << 1) + 0][mvNum] = true;
+        affMrgCtx.mvSolid[(i << 1) + 1][mvNum] = true;
+        affMrgCtx.mvValid[(i << 1) + 0][mvNum] = true;
+        affMrgCtx.mvValid[(i << 1) + 1][mvNum] = true;
+      }
+#endif
     }
     affMrgCtx.interDirNeighbours[i] = 0;
     affMrgCtx.affineType[i] = AFFINEMODEL_4PARAM;
     affMrgCtx.mergeType[i] = MRG_TYPE_DEFAULT_N;
     affMrgCtx.BcwIdx[i] = BCW_DEFAULT;
   }
+#if GDR_ENABLED
+  if (isEncodeGdrClean)
+  {
+    MergeCtx &mrgCtx = *affMrgCtx.mrgCtx;
+    int numMergeCand = MRG_MAX_NUM_CANDS << 1;
+    for (int i = 0; i < numMergeCand; i++)
+    {
+      mrgCtx.mvSolid[i] = true;
+      mrgCtx.mvValid[i] = true;
+    }
+  }
+#endif
 
   affMrgCtx.numValidMergeCand = 0;
   affMrgCtx.maxNumMergeCand = maxNumAffineMergeCand;
@@ -2603,6 +3426,14 @@ void PU::getAffineMergeCand( const PredictionUnit &pu, AffineMergeCtx& affMrgCtx
       {
         mrgCtx.mvFieldNeighbours[(pos << 1) + 1].setMvField( miLeft.mv[1], miLeft.refIdx[1] );
       }
+#if GDR_ENABLED
+      // check if the (puLeft) is in clean area
+      if (isEncodeGdrClean)
+      {
+        mrgCtx.mvSolid[(pos << 1) + 0] = cs.isClean(puLeft->Y().bottomRight(), CHANNEL_TYPE_LUMA);
+        mrgCtx.mvSolid[(pos << 1) + 1] = cs.isClean(puLeft->Y().bottomRight(), CHANNEL_TYPE_LUMA);
+      }
+#endif
       pos++;
     }
 
@@ -2615,6 +3446,13 @@ void PU::getAffineMergeCand( const PredictionUnit &pu, AffineMergeCtx& affMrgCtx
       {
         affMrgCtx.mvFieldNeighbours[(affMrgCtx.numValidMergeCand << 1) + 0][mvNum].setMvField( mrgCtx.mvFieldNeighbours[(pos << 1) + 0].mv, mrgCtx.mvFieldNeighbours[(pos << 1) + 0].refIdx );
         affMrgCtx.mvFieldNeighbours[(affMrgCtx.numValidMergeCand << 1) + 1][mvNum].setMvField( mrgCtx.mvFieldNeighbours[(pos << 1) + 1].mv, mrgCtx.mvFieldNeighbours[(pos << 1) + 1].refIdx );
+#if GDR_ENABLED
+        if (isEncodeGdrClean)
+        {
+          affMrgCtx.mvSolid[(affMrgCtx.numValidMergeCand << 1) + 0][mvNum] = mrgCtx.mvSolid[(pos << 1) + 0];
+          affMrgCtx.mvSolid[(affMrgCtx.numValidMergeCand << 1) + 1][mvNum] = mrgCtx.mvSolid[(pos << 1) + 1];
+        }
+#endif
       }
       affMrgCtx.interDirNeighbours[affMrgCtx.numValidMergeCand] = mrgCtx.interDirNeighbours[pos];
 
@@ -2645,17 +3483,44 @@ void PU::getAffineMergeCand( const PredictionUnit &pu, AffineMergeCtx& affMrgCtx
     {
       // derive Mv from Neigh affine PU
       Mv cMv[2][3];
+#if GDR_ENABLED
+      bool    cMvSolid[2][3] = { {true, true, true}, {true, true, true} };
+      MvpType cMvType[2][3];
+      Position cMvPos[2][3];
+#endif
       const PredictionUnit* puNeigh = npu[idx];
       pu.cu->affineType = puNeigh->cu->affineType;
       if ( puNeigh->interDir != 2 )
       {
-        xInheritedAffineMv( pu, puNeigh, REF_PIC_LIST_0, cMv[0] );
+#if GDR_ENABLED
+        if (isEncodeGdrClean)
+        {
+          xInheritedAffineMv(pu, puNeigh, REF_PIC_LIST_0, cMv[0], cMvSolid[0], cMvType[0], cMvPos[0]);
+        }
+        else
+        {
+          xInheritedAffineMv(pu, puNeigh, REF_PIC_LIST_0, cMv[0]);
+        }
+#else
+        xInheritedAffineMv(pu, puNeigh, REF_PIC_LIST_0, cMv[0]);
+#endif
       }
       if ( slice.isInterB() )
       {
         if ( puNeigh->interDir != 1 )
         {
-          xInheritedAffineMv( pu, puNeigh, REF_PIC_LIST_1, cMv[1] );
+#if GDR_ENABLED
+          if (isEncodeGdrClean)
+          {
+            xInheritedAffineMv(pu, puNeigh, REF_PIC_LIST_1, cMv[1], cMvSolid[1], cMvType[1], cMvPos[1]);
+          }
+          else
+          {
+            xInheritedAffineMv(pu, puNeigh, REF_PIC_LIST_1, cMv[1]);
+          }
+#else
+          xInheritedAffineMv(pu, puNeigh, REF_PIC_LIST_1, cMv[1]);
+#endif
         }
       }
 
@@ -2663,6 +3528,13 @@ void PU::getAffineMergeCand( const PredictionUnit &pu, AffineMergeCtx& affMrgCtx
       {
         affMrgCtx.mvFieldNeighbours[(affMrgCtx.numValidMergeCand << 1) + 0][mvNum].setMvField( cMv[0][mvNum], puNeigh->refIdx[0] );
         affMrgCtx.mvFieldNeighbours[(affMrgCtx.numValidMergeCand << 1) + 1][mvNum].setMvField( cMv[1][mvNum], puNeigh->refIdx[1] );
+#if GDR_ENABLED
+        if (isEncodeGdrClean)
+        {
+          affMrgCtx.mvSolid[(affMrgCtx.numValidMergeCand << 1) + 0][mvNum] = cMvSolid[0][mvNum];
+          affMrgCtx.mvSolid[(affMrgCtx.numValidMergeCand << 1) + 1][mvNum] = cMvSolid[0][mvNum];
+        }
+#endif
       }
       affMrgCtx.interDirNeighbours[affMrgCtx.numValidMergeCand] = puNeigh->interDir;
       affMrgCtx.affineType[affMrgCtx.numValidMergeCand] = (EAffineModel)(puNeigh->cu->affineType);
@@ -2690,6 +3562,9 @@ void PU::getAffineMergeCand( const PredictionUnit &pu, AffineMergeCtx& affMrgCtx
       int8_t neighBcw[2] = { BCW_DEFAULT, BCW_DEFAULT };
       // control point: LT B2->B3->A2
       const Position posLT[3] = { pu.Y().topLeft().offset( -1, -1 ), pu.Y().topLeft().offset( 0, -1 ), pu.Y().topLeft().offset( -1, 0 ) };
+#if GDR_ENABLED
+      bool miSolid[4] = { false, false, false, false };
+#endif
       for ( int i = 0; i < 3; i++ )
       {
         const Position pos = posLT[i];
@@ -2700,6 +3575,12 @@ void PU::getAffineMergeCand( const PredictionUnit &pu, AffineMergeCtx& affMrgCtx
           isAvailable[0] = true;
           mi[0] = puNeigh->getMotionInfo( pos );
           neighBcw[0] = puNeigh->cu->BcwIdx;
+#if GDR_ENABLED
+          if (isEncodeGdrClean)
+          {
+            miSolid[0] = cs.isClean(puNeigh->Y().topRight(), CHANNEL_TYPE_LUMA);
+          }
+#endif
           break;
         }
       }
@@ -2716,6 +3597,12 @@ void PU::getAffineMergeCand( const PredictionUnit &pu, AffineMergeCtx& affMrgCtx
           isAvailable[1] = true;
           mi[1] = puNeigh->getMotionInfo( pos );
           neighBcw[1] = puNeigh->cu->BcwIdx;
+#if GDR_ENABLED
+          if (isEncodeGdrClean)
+          {
+            miSolid[1] = cs.isClean(puNeigh->Y().topRight(), CHANNEL_TYPE_LUMA);
+          }
+#endif
           break;
         }
       }
@@ -2731,6 +3618,12 @@ void PU::getAffineMergeCand( const PredictionUnit &pu, AffineMergeCtx& affMrgCtx
         {
           isAvailable[2] = true;
           mi[2] = puNeigh->getMotionInfo( pos );
+#if GDR_ENABLED
+          if (isEncodeGdrClean)
+          {
+            miSolid[2] = cs.isClean(puNeigh->Y().topRight(), CHANNEL_TYPE_LUMA);
+          }
+#endif
           break;
         }
       }
@@ -2772,6 +3665,15 @@ void PU::getAffineMergeCand( const PredictionUnit &pu, AffineMergeCtx& affMrgCtx
           mi[3].refIdx[0] = refIdx;
           mi[3].interDir = 1;
           isAvailable[3] = true;
+#if GDR_ENABLED
+          if (isEncodeGdrClean)
+          {
+            bool posL0inCurPicSolid = cs.isClean(posC0, CHANNEL_TYPE_LUMA);
+            bool posL0inRefPicSolid = cs.isClean(posC0, REF_PIC_LIST_0, refIdx);
+
+            miSolid[3] = posL0inCurPicSolid && posL0inRefPicSolid;
+          }
+#endif
         }
 
         if ( slice.isInterB() )
@@ -2783,6 +3685,15 @@ void PU::getAffineMergeCand( const PredictionUnit &pu, AffineMergeCtx& affMrgCtx
             mi[3].refIdx[1] = refIdx;
             mi[3].interDir |= 2;
             isAvailable[3] = true;
+#if GDR_ENABLED
+            if (isEncodeGdrClean)
+            {
+              bool posL1inCurPicSolid = cs.isClean(posC0, CHANNEL_TYPE_LUMA);
+              bool posL1inRefPicSolid = cs.isClean(posC0, REF_PIC_LIST_1, refIdx);
+
+              miSolid[3] = (mi[3].interDir & 1) ? (miSolid[3] && posL1inCurPicSolid && posL1inRefPicSolid) : (posL1inCurPicSolid && posL1inRefPicSolid);
+            }
+#endif
           }
         }
       }
@@ -2799,12 +3710,36 @@ void PU::getAffineMergeCand( const PredictionUnit &pu, AffineMergeCtx& affMrgCtx
         { 0, 2 },             // 5:  LT, LB
       };
 
+#if GDR_ENABLED
+      bool modelSolid[6] =
+      {
+        miSolid[0] && miSolid[1] && miSolid[2],
+        miSolid[0] && miSolid[1] && miSolid[3],
+        miSolid[0] && miSolid[2] && miSolid[3],
+        miSolid[1] && miSolid[2] && miSolid[3],
+        miSolid[0] && miSolid[1],
+        miSolid[0] && miSolid[2]
+      };
+#endif
       int verNum[6] = { 3, 3, 3, 3, 2, 2 };
       int startIdx = pu.cs->sps->getUseAffineType() ? 0 : 4;
       for ( int idx = startIdx; idx < modelNum; idx++ )
       {
         int modelIdx = order[idx];
+#if GDR_ENABLED
+        int affinNumValidCand = affMrgCtx.numValidMergeCand;
+#endif
         getAffineControlPointCand(pu, mi, isAvailable, model[modelIdx], ((modelIdx == 3) ? neighBcw[1] : neighBcw[0]), modelIdx, verNum[modelIdx], affMrgCtx);
+#if GDR_ENABLED
+        if (isEncodeGdrClean)
+        {
+          for (int i = 0; i < 3; i++)
+          {
+            affMrgCtx.mvSolid[(affinNumValidCand << 1) + 0][i] = modelSolid[modelIdx];
+            affMrgCtx.mvSolid[(affinNumValidCand << 1) + 1][i] = modelSolid[modelIdx];
+          }
+        }
+#endif
         if ( affMrgCtx.numValidMergeCand != 0 && affMrgCtx.numValidMergeCand - 1 == mrgCandIdx )
         {
           return;
@@ -2827,6 +3762,12 @@ void PU::getAffineMergeCand( const PredictionUnit &pu, AffineMergeCtx& affMrgCtx
     for ( int mvNum = 0; mvNum < 3; mvNum++ )
     {
       affMrgCtx.mvFieldNeighbours[(cnt << 1) + 0][mvNum].setMvField( Mv( 0, 0 ), 0 );
+#if GDR_ENABLED
+      if (isEncodeGdrClean)
+      {
+        affMrgCtx.mvSolid[(cnt << 1) + 0][mvNum] = true;
+      }
+#endif
     }
     affMrgCtx.interDirNeighbours[cnt] = 1;
 
@@ -2835,6 +3776,12 @@ void PU::getAffineMergeCand( const PredictionUnit &pu, AffineMergeCtx& affMrgCtx
       for ( int mvNum = 0; mvNum < 3; mvNum++ )
       {
         affMrgCtx.mvFieldNeighbours[(cnt << 1) + 1][mvNum].setMvField( Mv( 0, 0 ), 0 );
+#if GDR_ENABLED
+        if (isEncodeGdrClean)
+        {
+          affMrgCtx.mvSolid[(cnt << 1) + 1][mvNum] = true;
+        }
+#endif
       }
       affMrgCtx.interDirNeighbours[cnt] = 3;
     }
@@ -2971,15 +3918,32 @@ bool PU::getInterMergeSubPuMvpCand(const PredictionUnit &pu, MergeCtx& mrgCtx, b
   const Picture *pColPic = slice.getRefPic(RefPicList(slice.isInterB() ? 1 - slice.getColFromL0Flag() : 0), slice.getColRefIdx());
   Mv cTMv;
 
+#if GDR_ENABLED
+  const CodingStructure& cs = *pu.cs;
+  const bool isEncodeGdrClean = cs.sps->getGDREnabledFlag() && cs.pcv->isEncoder && ((cs.picHeader->getInGdrInterval() && cs.isClean(pu.Y().topRight(), CHANNEL_TYPE_LUMA)) || (cs.picHeader->getNumVerVirtualBoundaries() == 0));
+  bool isSubPuSolid[2] = { true, true };
+#endif
   if ( count )
   {
     if ( (mrgCtx.interDirNeighbours[0] & (1 << REF_PIC_LIST_0)) && slice.getRefPic( REF_PIC_LIST_0, mrgCtx.mvFieldNeighbours[REF_PIC_LIST_0].refIdx ) == pColPic )
     {
       cTMv = mrgCtx.mvFieldNeighbours[REF_PIC_LIST_0].mv;
+#if GDR_ENABLED
+      if (isEncodeGdrClean)
+      {
+        isSubPuSolid[REF_PIC_LIST_0] = mrgCtx.mvSolid[REF_PIC_LIST_0];
+      }
+#endif
     }
     else if ( slice.isInterB() && (mrgCtx.interDirNeighbours[0] & (1 << REF_PIC_LIST_1)) && slice.getRefPic( REF_PIC_LIST_1, mrgCtx.mvFieldNeighbours[REF_PIC_LIST_1].refIdx ) == pColPic )
     {
       cTMv = mrgCtx.mvFieldNeighbours[REF_PIC_LIST_1].mv;
+#if GDR_ENABLED
+      if (isEncodeGdrClean)
+      {
+        isSubPuSolid[REF_PIC_LIST_1] = mrgCtx.mvSolid[REF_PIC_LIST_1];
+      }
+#endif
     }
   }
 
@@ -3035,6 +3999,12 @@ bool PU::getInterMergeSubPuMvpCand(const PredictionUnit &pu, MergeCtx& mrgCtx, b
         // set as default, for further motion vector field spanning
         mrgCtx.mvFieldNeighbours[(count << 1) + currRefListId].setMvField(cColMv, 0);
         mrgCtx.interDirNeighbours[count] |= (1 << currRefListId);
+#if GDR_ENABLED
+        if (isEncodeGdrClean)
+        {
+          mrgCtx.mvSolid[(count << 1) + currRefListId] = cs.isClean(centerPos, currRefPicList, refIdx);
+        }
+#endif
         LICFlag = tempLICFlag;
         mrgCtx.BcwIdx[count] = BCW_DEFAULT;
         found = true;
@@ -3088,6 +4058,12 @@ bool PU::getInterMergeSubPuMvpCand(const PredictionUnit &pu, MergeCtx& mrgCtx, b
               mi.refIdx[currRefListId] = 0;
               mi.mv[currRefListId]     = cColMv;
               found                    = true;
+#if GDR_ENABLED
+              if (isEncodeGdrClean)
+              {
+                isSubPuSolid[currRefPicList] = isSubPuSolid[currRefPicList] && cs.isClean(colPos, currRefPicList, refIdx);
+              }
+#endif
             }
           }
         }
@@ -3113,6 +4089,16 @@ bool PU::getInterMergeSubPuMvpCand(const PredictionUnit &pu, MergeCtx& mrgCtx, b
       }
     }
   }
+
+#if GDR_ENABLED
+  if (isEncodeGdrClean)
+  {
+    // the final if it is solid
+    mrgCtx.mvSolid[(count << 1) + 0] = mrgCtx.mvSolid[(count << 1) + 0] && isSubPuSolid[0];
+    mrgCtx.mvSolid[(count << 1) + 1] = mrgCtx.mvSolid[(count << 1) + 1] && isSubPuSolid[1];
+  }
+#endif
+
   return true;
 }
 
@@ -3290,6 +4276,10 @@ void PU::getGeoMergeCandidates( const PredictionUnit &pu, MergeCtx& geoMrgCtx )
   const uint32_t maxNumMergeCand = pu.cs->sps->getMaxNumMergeCand();
   geoMrgCtx.numValidMergeCand = 0;
 
+#if GDR_ENABLED
+  CodingStructure &cs = *pu.cs;
+  const bool isEncodeGdrClean = cs.sps->getGDREnabledFlag() && cs.pcv->isEncoder && ((cs.picHeader->getInGdrInterval() && cs.isClean(pu.Y().topRight(), CHANNEL_TYPE_LUMA)) || (cs.picHeader->getNumVerVirtualBoundaries() == 0));
+#endif
   for (int32_t i = 0; i < GEO_MAX_NUM_UNI_CANDS; i++)
   {
     geoMrgCtx.BcwIdx[i] = BCW_DEFAULT;
@@ -3299,6 +4289,13 @@ void PU::getGeoMergeCandidates( const PredictionUnit &pu, MergeCtx& geoMrgCtx )
     geoMrgCtx.mvFieldNeighbours[(i << 1) + 1].refIdx = NOT_VALID;
     geoMrgCtx.mvFieldNeighbours[(i << 1)].mv = Mv();
     geoMrgCtx.mvFieldNeighbours[(i << 1) + 1].mv = Mv();
+#if GDR_ENABLED
+    if (isEncodeGdrClean)
+    {
+      geoMrgCtx.mvSolid[(i << 1) + 0] = true;
+      geoMrgCtx.mvSolid[(i << 1) + 1] = true;
+    }
+#endif
     geoMrgCtx.useAltHpelIf[i] = false;
   }
 
@@ -3315,6 +4312,18 @@ void PU::getGeoMergeCandidates( const PredictionUnit &pu, MergeCtx& geoMrgCtx )
       geoMrgCtx.mvFieldNeighbours[(geoMrgCtx.numValidMergeCand << 1) + parity].mv = tmpMergeCtx.mvFieldNeighbours[(i << 1) + parity].mv;
       geoMrgCtx.mvFieldNeighbours[(geoMrgCtx.numValidMergeCand << 1) + !parity].refIdx = -1;
       geoMrgCtx.mvFieldNeighbours[(geoMrgCtx.numValidMergeCand << 1) + parity].refIdx = tmpMergeCtx.mvFieldNeighbours[(i << 1) + parity].refIdx;
+#if GDR_ENABLED
+      if (isEncodeGdrClean)
+      {
+        Mv  mv = tmpMergeCtx.mvFieldNeighbours[(i << 1) + parity].mv;
+        int refIdx = tmpMergeCtx.mvFieldNeighbours[(i << 1) + parity].refIdx;
+        RefPicList refPicList = parity ? REF_PIC_LIST_1 : REF_PIC_LIST_0;
+        geoMrgCtx.mvSolid[(geoMrgCtx.numValidMergeCand << 1) + !parity] = true;
+        geoMrgCtx.mvSolid[(geoMrgCtx.numValidMergeCand << 1) + parity] = tmpMergeCtx.mvSolid[(i << 1) + parity];
+        geoMrgCtx.mvValid[(geoMrgCtx.numValidMergeCand << 1) + !parity] = true;
+        geoMrgCtx.mvValid[(geoMrgCtx.numValidMergeCand << 1) + parity] = cs.isClean(pu.Y().bottomRight(), mv, refPicList, refIdx);
+      }
+#endif
       geoMrgCtx.numValidMergeCand++;
       if (geoMrgCtx.numValidMergeCand == GEO_MAX_NUM_UNI_CANDS)
       {
@@ -3331,6 +4340,18 @@ void PU::getGeoMergeCandidates( const PredictionUnit &pu, MergeCtx& geoMrgCtx )
       geoMrgCtx.mvFieldNeighbours[(geoMrgCtx.numValidMergeCand << 1) + parity].mv = Mv(0, 0);
       geoMrgCtx.mvFieldNeighbours[(geoMrgCtx.numValidMergeCand << 1) + !parity].refIdx = tmpMergeCtx.mvFieldNeighbours[(i << 1) + !parity].refIdx;
       geoMrgCtx.mvFieldNeighbours[(geoMrgCtx.numValidMergeCand << 1) + parity].refIdx = -1;
+#if GDR_ENABLED
+      if (isEncodeGdrClean)
+      {
+        Mv  mv = tmpMergeCtx.mvFieldNeighbours[(i << 1) + !parity].mv;
+        int refIdx = tmpMergeCtx.mvFieldNeighbours[(i << 1) + !parity].refIdx;
+        RefPicList refPicList = (!parity) ? REF_PIC_LIST_1 : REF_PIC_LIST_0;
+        geoMrgCtx.mvSolid[(geoMrgCtx.numValidMergeCand << 1) + !parity] = tmpMergeCtx.mvSolid[(i << 1) + !parity];
+        geoMrgCtx.mvSolid[(geoMrgCtx.numValidMergeCand << 1) + parity] = true;
+        geoMrgCtx.mvValid[(geoMrgCtx.numValidMergeCand << 1) + !parity] = cs.isClean(pu.Y().bottomRight(), mv, refPicList, refIdx);
+        geoMrgCtx.mvValid[(geoMrgCtx.numValidMergeCand << 1) + parity] = true;
+      }
+#endif
       geoMrgCtx.numValidMergeCand++;
       if (geoMrgCtx.numValidMergeCand == GEO_MAX_NUM_UNI_CANDS)
       {
@@ -3601,7 +4622,7 @@ uint8_t CU::targetSbtAllowed( uint8_t sbtIdx, uint8_t sbtAllowed )
   case SBT_HOR_HALF: val = ( ( sbtAllowed >> SBT_HOR_HALF ) & 0x1 ); break;
   case SBT_VER_QUAD: val = ( ( sbtAllowed >> SBT_VER_QUAD ) & 0x1 ); break;
   case SBT_HOR_QUAD: val = ( ( sbtAllowed >> SBT_HOR_QUAD ) & 0x1 ); break;
-  default:           CHECK( 1, "unknown SBT type" );
+  default: THROW("unknown SBT type");
   }
   return val;
 }
diff --git a/source/Lib/CommonLib/UnitTools.h b/source/Lib/CommonLib/UnitTools.h
index c87fbdc93..5b5e0ddc2 100644
--- a/source/Lib/CommonLib/UnitTools.h
+++ b/source/Lib/CommonLib/UnitTools.h
@@ -3,7 +3,7 @@
 * and contributor rights, including patent rights, and no such rights are
 * granted under this license.
 *
-* Copyright (c) 2010-2020, ITU/ISO/IEC
+* Copyright (c) 2010-2021, ITU/ISO/IEC
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
@@ -148,11 +148,18 @@ namespace PU
   void fillIBCMvpCand                 (PredictionUnit &pu, AMVPInfo &amvpInfo);
   void fillAffineMvpCand              (      PredictionUnit &pu, const RefPicList &eRefPicList, const int &refIdx, AffineAMVPInfo &affiAMVPInfo);
   bool addMVPCandUnscaled             (const PredictionUnit &pu, const RefPicList &eRefPicList, const int &iRefIdx, const Position &pos, const MvpDir &eDir, AMVPInfo &amvpInfo);
+#if GDR_ENABLED
+  void xInheritedAffineMv(const PredictionUnit &pu, const PredictionUnit* puNeighbour, RefPicList eRefPicList, Mv rcMv[3], bool rcMvSolid[3], MvpType rcMvType[3], Position rcMvPos[3]);  
+#endif
   void xInheritedAffineMv             ( const PredictionUnit &pu, const PredictionUnit* puNeighbour, RefPicList eRefPicList, Mv rcMv[3] );
   bool addMergeHMVPCand               (const CodingStructure &cs, MergeCtx& mrgCtx, const int& mrgCandIdx, const uint32_t maxNumMergeCandMin1, int &cnt
     , const bool isAvailableA1, const MotionInfo miLeft, const bool isAvailableB1, const MotionInfo miAbove
     , const bool ibcFlag
     , const bool isGt4x4
+#if GDR_ENABLED
+    , const PredictionUnit &pu
+    , bool &allCandSolidInAbove  
+#endif
   );
   void addAMVPHMVPCand                (const PredictionUnit &pu, const RefPicList eRefPicList, const int currRefPOC, AMVPInfo &info);
   bool addAffineMVPCandUnscaled       ( const PredictionUnit &pu, const RefPicList &refPicList, const int &refIdx, const Position &pos, const MvpDir &dir, AffineAMVPInfo &affiAmvpInfo );
@@ -203,8 +210,8 @@ int getMipSizeId      (const Size& block);
 bool allowLfnstWithMip(const Size& block);
 
 template<typename T, size_t N>
-uint32_t updateCandList(T uiMode, double uiCost, static_vector<T, N>& candModeList, static_vector<double, N>& candCostList
-  , size_t uiFastCandNum = N, int* iserttPos = nullptr)
+uint32_t updateCandList(T mode, double uiCost, static_vector<T, N> &candModeList,
+                        static_vector<double, N> &candCostList, size_t uiFastCandNum = N, int *iserttPos = nullptr)
 {
   CHECK( std::min( uiFastCandNum, candModeList.size() ) != std::min( uiFastCandNum, candCostList.size() ), "Sizes do not match!" );
   CHECK( uiFastCandNum > candModeList.capacity(), "The vector is to small to hold all the candidates!" );
@@ -225,7 +232,7 @@ uint32_t updateCandList(T uiMode, double uiCost, static_vector<T, N>& candModeLi
       candModeList[currSize - i] = candModeList[currSize - 1 - i];
       candCostList[currSize - i] = candCostList[currSize - 1 - i];
     }
-    candModeList[currSize - shift] = uiMode;
+    candModeList[currSize - shift] = mode;
     candCostList[currSize - shift] = uiCost;
     if (iserttPos != nullptr)
     {
@@ -235,7 +242,7 @@ uint32_t updateCandList(T uiMode, double uiCost, static_vector<T, N>& candModeLi
   }
   else if( currSize < uiFastCandNum )
   {
-    candModeList.insert( candModeList.end() - shift, uiMode );
+    candModeList.insert(candModeList.end() - shift, mode);
     candCostList.insert( candCostList.end() - shift, uiCost );
     if (iserttPos != nullptr)
     {
diff --git a/source/Lib/CommonLib/WeightPrediction.cpp b/source/Lib/CommonLib/WeightPrediction.cpp
index 1493d087b..b9f0a550c 100644
--- a/source/Lib/CommonLib/WeightPrediction.cpp
+++ b/source/Lib/CommonLib/WeightPrediction.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -414,7 +414,10 @@ void  WeightPrediction::xWeightedPredictionBi(const PredictionUnit       &pu,
 
   CHECK( !pu.cs->pps->getWPBiPred(), "Weighted Bi-prediction disabled" );
 
-  if (iRefIdx0 < 0 && iRefIdx1 < 0) return;
+  if (iRefIdx0 < 0 && iRefIdx1 < 0)
+  {
+    return;
+  }
 
   getWpScaling(pu.cu->slice, iRefIdx0, iRefIdx1, pwp0, pwp1, maxNumComp);
 
diff --git a/source/Lib/CommonLib/WeightPrediction.h b/source/Lib/CommonLib/WeightPrediction.h
index 80915b618..9f4a56785 100644
--- a/source/Lib/CommonLib/WeightPrediction.h
+++ b/source/Lib/CommonLib/WeightPrediction.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/CommonLib/dtrace.cpp b/source/Lib/CommonLib/dtrace.cpp
index 3500c6be6..c9b983cd1 100644
--- a/source/Lib/CommonLib/dtrace.cpp
+++ b/source/Lib/CommonLib/dtrace.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -47,83 +47,88 @@
 #include "dtrace_next.h"
 
 
-
 void Channel::update( std::map< CType, int > state )
 {
-
-    for( std::list<Rule>::iterator rules_iter = rule_list.begin();
-            rules_iter != rule_list.end();
-            ++rules_iter ) {
-        /* iterate over conditions, get the state of the condition type
-         * and check if contion is met:
-         *     if not -> go to next rule
-         *        yes -> go to next condition
-         * if all conditions are met: set channel active and return */
-        bool probe = true;
-
-        for( Rule::iterator cond_iter = rules_iter->begin();
-                cond_iter != rules_iter->end();
-                ++cond_iter ) {
-            int sVal = state[cond_iter->type];
-            if( !cond_iter->eval( cond_iter->rval, sVal ) ) {
-                probe = false;
-                break;
-            }
-        }
-        if( probe ) {
-            _active = true;
-            return;
-        }
+  for (std::list<Rule>::iterator rules_iter = rule_list.begin(); rules_iter != rule_list.end(); ++rules_iter)
+  {
+    /* iterate over conditions, get the state of the condition type
+     * and check if contion is met:
+     *     if not -> go to next rule
+     *        yes -> go to next condition
+     * if all conditions are met: set channel active and return */
+    bool probe = true;
+
+    for (Rule::iterator cond_iter = rules_iter->begin(); cond_iter != rules_iter->end(); ++cond_iter)
+    {
+      int sVal = state[cond_iter->type];
+      if (!cond_iter->eval(cond_iter->rval, sVal))
+      {
+        probe = false;
+        break;
+      }
     }
+    if (probe)
+    {
+      _active = true;
+      return;
+    }
+  }
 
-    _active = false;
+  _active = false;
 }
 
 void Channel::add( std::vector<Condition> rule )
 {
-    rule_list.push_back( rule );
+  rule_list.push_back(rule);
 }
 
 static inline
 std::vector<std::string> &split( const std::string &s, char delim, std::vector<std::string> &elems )
 {
-    std::stringstream ss( s );
-    std::string item;
-    while ( std::getline( ss, item, delim ) ) {
-        elems.push_back( item );
-    }
-    return elems;
+  std::stringstream ss(s);
+  std::string       item;
+  while (std::getline(ss, item, delim))
+  {
+    elems.push_back(item);
+  }
+  return elems;
 }
 
 static inline
 std::vector<std::string> split( const std::string &s, char delim )
 {
-    std::vector<std::string> elems;
-    split( s, delim, elems );
-    return elems;
+  std::vector<std::string> elems;
+  split(s, delim, elems);
+  return elems;
 }
 
 CDTrace::CDTrace( const char *filename, vstring channel_names )
     : copy(false), m_trace_file(NULL), m_error_code( 0 )
 {
-    if( filename )
-        m_trace_file = fopen( filename, "w" );
+  if (filename)
+  {
+    m_trace_file = fopen(filename, "w");
+  }
 
-    int i = 0;
-    for( vstring::iterator ci = channel_names.begin(); ci != channel_names.end(); ++ci ) {
-        deserializationTable[*ci] = i++;
-        chanRules.push_back( Channel() );
-    }
+  int i = 0;
+  for (vstring::iterator ci = channel_names.begin(); ci != channel_names.end(); ++ci)
+  {
+    deserializationTable[*ci] = i++;
+    chanRules.push_back(Channel());
+  }
 }
 
 CDTrace::CDTrace( const char *filename, const dtrace_channels_t& channels )
   : copy( false ), m_trace_file( NULL ), m_error_code( 0 )
 {
   if( filename )
+  {
     m_trace_file = fopen( filename, "w" );
+  }
 
   //int i = 0;
-  for( dtrace_channels_t::const_iterator ci = channels.begin(); ci != channels.end(); ++ci ) {
+  for (dtrace_channels_t::const_iterator ci = channels.begin(); ci != channels.end(); ++ci)
+  {
     deserializationTable[ci->channel_name] = ci->channel_number/*i++*/;
     chanRules.push_back( Channel() );
   }
@@ -131,13 +136,13 @@ CDTrace::CDTrace( const char *filename, const dtrace_channels_t& channels )
 
 CDTrace::CDTrace( const CDTrace& other )
 {
-    copy = true;
-    m_trace_file         = other.m_trace_file;
-    chanRules            = other.chanRules;
-    condition_types      = other.condition_types;
-    state                = other.state;
-    deserializationTable = other.deserializationTable;
-    m_error_code         = other.m_error_code;
+  copy                 = true;
+  m_trace_file         = other.m_trace_file;
+  chanRules            = other.chanRules;
+  condition_types      = other.condition_types;
+  state                = other.state;
+  deserializationTable = other.deserializationTable;
+  m_error_code         = other.m_error_code;
 }
 
 CDTrace::CDTrace( const std::string& sTracingFile, const std::string& sTracingRule, const dtrace_channels_t& channels )
@@ -152,28 +157,30 @@ CDTrace::CDTrace( const std::string& sTracingFile, const std::string& sTracingRu
 
 void CDTrace::swap( CDTrace& other )
 {
-    using std::swap;
-    CDTrace& first = *this;
-    CDTrace& second = other;
-    swap(first.copy,second.copy);
-    swap(first.m_trace_file,second.m_trace_file);
-    swap(first.chanRules,second.chanRules);
-    swap(first.condition_types,second.condition_types);
-    swap(first.state,second.state);
-    swap(first.deserializationTable,second.deserializationTable);
+  using std::swap;
+  CDTrace &first  = *this;
+  CDTrace &second = other;
+  swap(first.copy, second.copy);
+  swap(first.m_trace_file, second.m_trace_file);
+  swap(first.chanRules, second.chanRules);
+  swap(first.condition_types, second.condition_types);
+  swap(first.state, second.state);
+  swap(first.deserializationTable, second.deserializationTable);
 }
 
 CDTrace& CDTrace::operator=( const CDTrace& other )
 {
-    CDTrace tmp(other);
-    swap( tmp );
-    return *this;
+  CDTrace tmp(other);
+  swap(tmp);
+  return *this;
 }
 
 CDTrace::~CDTrace()
 {
-    if( !copy && m_trace_file )
-        fclose( m_trace_file );
+  if (!copy && m_trace_file)
+  {
+    fclose(m_trace_file);
+  }
 }
 
 bool _cf_eq ( int bound, int val ) { return ( val==bound ); }
@@ -183,65 +190,93 @@ bool _cf_ge ( int bound, int val ) { return ( val>=bound ); }
 
 int CDTrace::addRule( std::string rulestring )
 {
-    vstring chans_conds = split( rulestring, ':' );
-    vstring channels = split( chans_conds[0], ',' );
-    vstring conditions = split( chans_conds[1], ',' );
-
-    /* parse the rules first */
-    std::vector<Condition> rule;
-    for( vstring::iterator ci = conditions.begin(); ci != conditions.end(); ++ci ) {
-        /* find one of "==", "!=", "<=", ">=" */
-        const char *ops_[] = { "==", "!=", "<=", ">=" };
-        vstring operators( ops_,&ops_[sizeof( ops_ )/sizeof( ops_[0] )] );
-        vstring::iterator oi = operators.begin();
-        std::size_t pos = std::string::npos;
-        do {
-            if( ( pos = ci->find( *oi ) ) != std::string::npos ) break;
-        } while( ++oi != operators.end() );
-
-        /* No operator found, malformed rules string -> abort */
-        if( pos == std::string::npos ) return -2;
-
-        CType ctype( *ci,0,pos );
-        int value = std::atoi( ci->substr( pos+2, ci->length()-( pos+2 ) ).c_str() );
-        //if( condition_types.find( ctype ) == condition_types.end() ) return 0;
-
-        /* partially apply the condition value to the associated
-         * condtion function and append it to the rule */
-        bool ( *cfunc )( int,int );
-        if( "==" == *oi ) cfunc = _cf_eq;
-        else if( "!=" == *oi ) cfunc = _cf_neq;
-        else if( "<=" == *oi ) cfunc = _cf_le;
-        else if( ">=" == *oi ) cfunc = _cf_ge;
-        else return 0; // this is already taken care of
-
-        rule.push_back( Condition( ctype, cfunc, value ) );
+  vstring chans_conds = split(rulestring, ':');
+  vstring channels    = split(chans_conds[0], ',');
+  vstring conditions  = split(chans_conds[1], ',');
+
+  /* parse the rules first */
+  std::vector<Condition> rule;
+  for (vstring::iterator ci = conditions.begin(); ci != conditions.end(); ++ci)
+  {
+    /* find one of "==", "!=", "<=", ">=" */
+    const char *      ops_[] = { "==", "!=", "<=", ">=" };
+    vstring           operators(ops_, &ops_[sizeof(ops_) / sizeof(ops_[0])]);
+    vstring::iterator oi  = operators.begin();
+    std::size_t       pos = std::string::npos;
+    do
+    {
+      if ((pos = ci->find(*oi)) != std::string::npos)
+      {
+        break;
+      }
+    } while (++oi != operators.end());
+
+    /* No operator found, malformed rules string -> abort */
+    if (pos == std::string::npos)
+    {
+      return -2;
+    }
+
+    CType ctype(*ci, 0, pos);
+    int   value = std::atoi(ci->substr(pos + 2, ci->length() - (pos + 2)).c_str());
+    // if( condition_types.find( ctype ) == condition_types.end() ) return 0;
+
+    /* partially apply the condition value to the associated
+     * condtion function and append it to the rule */
+    bool (*cfunc)(int, int);
+    if ("==" == *oi)
+    {
+      cfunc = _cf_eq;
+    }
+    else if ("!=" == *oi)
+    {
+      cfunc = _cf_neq;
+    }
+    else if ("<=" == *oi)
+    {
+      cfunc = _cf_le;
+    }
+    else if (">=" == *oi)
+    {
+      cfunc = _cf_ge;
+    }
+    else
+    {
+      return 0;   // this is already taken care of
     }
 
-    /* add the rule to each channel */
-    for( vstring::iterator chan_iter = channels.begin(); chan_iter != channels.end(); ++chan_iter ) {
-        std::map< Key, int>::iterator ichan = deserializationTable.find(*chan_iter);
-        if( ichan != deserializationTable.end() )
-            chanRules[ichan->second].add( rule );
-        else
-            return -3;
+    rule.push_back(Condition(ctype, cfunc, value));
+  }
+
+  /* add the rule to each channel */
+  for (vstring::iterator chan_iter = channels.begin(); chan_iter != channels.end(); ++chan_iter)
+  {
+    std::map<Key, int>::iterator ichan = deserializationTable.find(*chan_iter);
+    if (ichan != deserializationTable.end())
+    {
+      chanRules[ichan->second].add(rule);
     }
+    else
+    {
+      return -3;
+    }
+  }
 
-    //return (int)channels.size();
-    return 0;
+  // return (int)channels.size();
+  return 0;
 }
 
 bool CDTrace::update( state_type stateval )
 {
-    state[stateval.first] = stateval.second;
+  state[stateval.first] = stateval.second;
 
-    /* pass over all the channel rules */
-    for( std::vector< Channel >::iterator citer = chanRules.begin(); citer != chanRules.end(); ++citer )
-    {
-        citer->update( state );
-    }
+  /* pass over all the channel rules */
+  for (std::vector<Channel>::iterator citer = chanRules.begin(); citer != chanRules.end(); ++citer)
+  {
+    citer->update(state);
+  }
 
-    return true;
+  return true;
 }
 
 void CDTrace::getChannelsList( std::string& sChannels )
@@ -251,7 +286,9 @@ void CDTrace::getChannelsList( std::string& sChannels )
   if( deserializationTable.size() > 0 )
   {
     for( channel_map_t::iterator it = deserializationTable.begin(); it != deserializationTable.end(); ++it )
+    {
       sChannels += it->first + "\n";
+    }
   }
 }
 
@@ -261,8 +298,12 @@ const char* CDTrace::getChannelName( int channel_number )
   if( deserializationTable.size() > 0 )
   {
     for( channel_map_t::iterator it = deserializationTable.begin(); it != deserializationTable.end(); ++it )
+    {
       if( it->second == channel_number )
+      {
         return it->first.c_str();
+      }
+    }
   }
   return not_found;
 }
@@ -273,9 +314,13 @@ std::string CDTrace::getErrMessage()
   if( m_error_code )
   {
     if( m_error_code == -2 )
+    {
       str = ( " - DTrace ERROR: Add tracing rule failed: DECERR_DTRACE_BAD_RULE" );
+    }
     else if( m_error_code == -3 )
+    {
       str = ( " - DTrace ERROR: Add tracing rule failed: DECERR_DTRACE_UNKNOWN_CHANNEL" );
+    }
     else
     {
       str = " - DTrace ERROR: Undefined error";
@@ -296,7 +341,9 @@ void CDTrace::dtrace( int k, const char *format, /*va_list args*/... )
     fflush( m_trace_file );
     va_end ( args );
     if( bCount )
+    {
       chanRules[k].incrementCounter();
+    }
   }
   return;
 }
diff --git a/source/Lib/CommonLib/dtrace.h b/source/Lib/CommonLib/dtrace.h
index 9e10e201b..f26c557a1 100644
--- a/source/Lib/CommonLib/dtrace.h
+++ b/source/Lib/CommonLib/dtrace.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/CommonLib/dtrace_blockstatistics.cpp b/source/Lib/CommonLib/dtrace_blockstatistics.cpp
index 86ff4413d..d92ae1e17 100644
--- a/source/Lib/CommonLib/dtrace_blockstatistics.cpp
+++ b/source/Lib/CommonLib/dtrace_blockstatistics.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -684,8 +684,8 @@ void writeAllData(const CodingStructure& cs, const UnitArea& ctuArea)
                 {
                   const Mv mv = pixMi.mv[REF_PIC_LIST_0];
 #if BLOCK_STATS_AS_CSV
-                  g_trace_ctx->dtrace<false>( 
-                    D_BLOCK_STATISTICS_ALL, 
+                  g_trace_ctx->dtrace<false>(
+                    D_BLOCK_STATISTICS_ALL,
                     "BlockStat;%d;%4d;%4d;%2d;%2d;%s;%4d;%4d\n",
                      cs.picture->poc,
                      pu.lx() + 4*x,
@@ -713,8 +713,8 @@ void writeAllData(const CodingStructure& cs, const UnitArea& ctuArea)
                 {
                   const Mv mv = pixMi.mv[REF_PIC_LIST_1];
 #if BLOCK_STATS_AS_CSV
-                  g_trace_ctx->dtrace<false>( 
-                    D_BLOCK_STATISTICS_ALL, 
+                  g_trace_ctx->dtrace<false>(
+                    D_BLOCK_STATISTICS_ALL,
                     "BlockStat;%d;%4d;%4d;%2d;%2d;%s;%4d;%4d\n",
                      cs.picture->poc,
                      pu.lx() + 4*x,
@@ -743,8 +743,8 @@ void writeAllData(const CodingStructure& cs, const UnitArea& ctuArea)
                   {
                     const Mv mv = pixMi.mv[REF_PIC_LIST_0];
 #if BLOCK_STATS_AS_CSV
-                  g_trace_ctx->dtrace<false>( 
-                    D_BLOCK_STATISTICS_ALL, 
+                  g_trace_ctx->dtrace<false>(
+                    D_BLOCK_STATISTICS_ALL,
                     "BlockStat;%d;%4d;%4d;%2d;%2d;%s;%4d;%4d\n",
                      cs.picture->poc,
                      pu.lx() + 4*x,
@@ -767,12 +767,12 @@ void writeAllData(const CodingStructure& cs, const UnitArea& ctuArea)
                      mv.hor,
                      mv.ver);
 #endif
-                  }                
+                  }
                   {
                     const Mv mv = pixMi.mv[REF_PIC_LIST_1];
 #if BLOCK_STATS_AS_CSV
-                  g_trace_ctx->dtrace<false>( 
-                    D_BLOCK_STATISTICS_ALL, 
+                  g_trace_ctx->dtrace<false>(
+                    D_BLOCK_STATISTICS_ALL,
                     "BlockStat;%d;%4d;%4d;%2d;%2d;%s;%4d;%4d\n",
                      cs.picture->poc,
                      pu.lx() + 4*x,
@@ -795,7 +795,7 @@ void writeAllData(const CodingStructure& cs, const UnitArea& ctuArea)
                      mv.hor,
                      mv.ver);
 #endif
-                  }                                    
+                  }
                 }
               }
             }
@@ -1140,7 +1140,7 @@ void writeAllCodedData(const CodingStructure & cs, const UnitArea & ctuArea)
           }
           default:
           {
-            CHECK(1, "Invalid prediction mode");
+            THROW("Invalid prediction mode");
             break;
           }
         }
diff --git a/source/Lib/CommonLib/dtrace_blockstatistics.h b/source/Lib/CommonLib/dtrace_blockstatistics.h
index 1a294fdbf..f9eff9ce1 100644
--- a/source/Lib/CommonLib/dtrace_blockstatistics.h
+++ b/source/Lib/CommonLib/dtrace_blockstatistics.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/CommonLib/dtrace_buffer.h b/source/Lib/CommonLib/dtrace_buffer.h
index afba4a3ce..e30551076 100644
--- a/source/Lib/CommonLib/dtrace_buffer.h
+++ b/source/Lib/CommonLib/dtrace_buffer.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/CommonLib/dtrace_codingstruct.h b/source/Lib/CommonLib/dtrace_codingstruct.h
index 656942903..672f7f441 100644
--- a/source/Lib/CommonLib/dtrace_codingstruct.h
+++ b/source/Lib/CommonLib/dtrace_codingstruct.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/CommonLib/dtrace_next.h b/source/Lib/CommonLib/dtrace_next.h
index 7ef78cca9..8281ae766 100644
--- a/source/Lib/CommonLib/dtrace_next.h
+++ b/source/Lib/CommonLib/dtrace_next.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/CommonLib/version.h b/source/Lib/CommonLib/version.h
index 66cfa83e9..f1c5cd405 100644
--- a/source/Lib/CommonLib/version.h
+++ b/source/Lib/CommonLib/version.h
@@ -1,3 +1,3 @@
 #if ! defined( VTM_VERSION )
-#define VTM_VERSION "10.2"
+#define VTM_VERSION "14.0"
 #endif
diff --git a/source/Lib/CommonLib/x86/AdaptiveLoopFilterX86.h b/source/Lib/CommonLib/x86/AdaptiveLoopFilterX86.h
index 962620313..a8962b1eb 100644
--- a/source/Lib/CommonLib/x86/AdaptiveLoopFilterX86.h
+++ b/source/Lib/CommonLib/x86/AdaptiveLoopFilterX86.h
@@ -40,7 +40,523 @@
 #else
 #include <x86intrin.h>
 #endif
+#if RExt__HIGH_BIT_DEPTH_SUPPORT
+static void simdFilter5x5Blk_HBD(AlfClassifier **classifier, const PelUnitBuf &recDst, const CPelUnitBuf &recSrc,
+  const Area &blkDst, const Area &blk, const ComponentID compId, const short *filterSet,
+  const Pel *fClipSet, const ClpRng &clpRng, CodingStructure &cs, const int vbCTUHeight,
+  int vbPos)
+
+{
+  CHECK((vbCTUHeight & (vbCTUHeight - 1)) != 0, "vbCTUHeight must be a power of 2");
+  CHECK(!isChroma(compId), "ALF 5x5 filter is for chroma only");
+
+  const CPelBuf srcBuffer = recSrc.get(compId);
+  PelBuf        dstBuffer = recDst.get(compId);
+
+  const size_t srcStride = srcBuffer.stride;
+  const size_t dstStride = dstBuffer.stride;
+
+  constexpr int shift = AdaptiveLoopFilter::m_NUM_BITS - 1;
+  constexpr int round = 1 << (shift - 1);
+  const __m128i offset1 = _mm_set1_epi32((1 << ((shift + 3) - 1)) - round);
+
+  const size_t width = blk.width;
+  const size_t height = blk.height;
+
+  constexpr size_t step_x = 4;
+  constexpr size_t step_y = 4;
+
+  CHECK(blk.y % step_y, "Wrong startHeight in filtering");
+  CHECK(blk.x % step_x, "Wrong startWidth in filtering");
+  CHECK(height % step_y, "Wrong endHeight in filtering");
+  CHECK(width % step_x, "Wrong endWidth in filtering");
+
+  const Pel *src = srcBuffer.buf + blk.y * srcStride + blk.x;
+  Pel *      dst = dstBuffer.buf + blkDst.y * dstStride + blkDst.x;
+
+  const __m128i offset = _mm_set1_epi32(round);
+  const __m128i min = _mm_set1_epi32(clpRng.min);
+  const __m128i max = _mm_set1_epi32(clpRng.max);
+  const __m128i zeros = _mm_setzero_si128();
+
+  __m128i params[2][3];
+  __m128i fs = _mm_lddqu_si128((__m128i *) filterSet);
+  params[0][0] = _mm_cvtepi16_epi32(_mm_shuffle_epi32(fs, 0x00));
+  params[0][1] = _mm_cvtepi16_epi32(_mm_shuffle_epi32(fs, 0x55));
+  params[0][2] = _mm_cvtepi16_epi32(_mm_shuffle_epi32(fs, 0xaa));
+  __m128i fcLo = _mm_lddqu_si128((__m128i *) fClipSet);
+  __m128i fcHi = _mm_loadl_epi64((__m128i *) (fClipSet + 4));
+  params[1][0] = _mm_shuffle_epi32(fcLo, 0x44);
+  params[1][1] = _mm_shuffle_epi32(fcLo, 0xee);
+  params[1][2] = _mm_shuffle_epi32(fcHi, 0x44);
+
+  for (size_t i = 0; i < height; i += step_y)
+  {
+    for (size_t j = 0; j < width; j += step_x)
+    {
+      for (size_t ii = 0; ii < step_y; ii++)
+      {
+        const Pel *img0, *img1, *img2, *img3, *img4;
+
+        img0 = src + j + ii * srcStride;
+        img1 = img0 + srcStride;
+        img2 = img0 - srcStride;
+        img3 = img1 + srcStride;
+        img4 = img2 - srcStride;
+
+        const int yVb = (blkDst.y + i + ii) & (vbCTUHeight - 1);
+        if (yVb < vbPos && (yVb >= vbPos - 2))   // above
+        {
+          img1 = (yVb == vbPos - 1) ? img0 : img1;
+          img3 = (yVb >= vbPos - 2) ? img1 : img3;
+
+          img2 = (yVb == vbPos - 1) ? img0 : img2;
+          img4 = (yVb >= vbPos - 2) ? img2 : img4;
+        }
+        else if (yVb >= vbPos && (yVb <= vbPos + 1))   // bottom
+        {
+          img2 = (yVb == vbPos) ? img0 : img2;
+          img4 = (yVb <= vbPos + 1) ? img2 : img4;
+
+          img1 = (yVb == vbPos) ? img0 : img1;
+          img3 = (yVb <= vbPos + 1) ? img1 : img3;
+        }
+        __m128i cur = _mm_lddqu_si128((const __m128i *) img0);
+        __m128i accum = offset;
+
+        auto process2coeffs = [&](const int i, const Pel *ptr0, const Pel *ptr1, const Pel *ptr2, const Pel *ptr3) {
+          const __m128i val00 = _mm_sub_epi32(_mm_lddqu_si128((const __m128i *) ptr0), cur);
+          const __m128i val10 = _mm_sub_epi32(_mm_lddqu_si128((const __m128i *) ptr2), cur);
+          const __m128i val01 = _mm_sub_epi32(_mm_lddqu_si128((const __m128i *) ptr1), cur);
+          const __m128i val11 = _mm_sub_epi32(_mm_lddqu_si128((const __m128i *) ptr3), cur);
+          __m128i val01A = _mm_unpacklo_epi32(val00, val10);
+          __m128i val01B = _mm_unpackhi_epi32(val00, val10);
+          __m128i val01C = _mm_unpacklo_epi32(val01, val11);
+          __m128i val01D = _mm_unpackhi_epi32(val01, val11);
+
+          __m128i limit01A = params[1][i];
+
+          val01A = _mm_min_epi32(val01A, limit01A);
+          val01B = _mm_min_epi32(val01B, limit01A);
+          val01C = _mm_min_epi32(val01C, limit01A);
+          val01D = _mm_min_epi32(val01D, limit01A);
+
+          limit01A = _mm_sub_epi32(zeros, limit01A);
+
+          val01A = _mm_max_epi32(val01A, limit01A);
+          val01B = _mm_max_epi32(val01B, limit01A);
+          val01C = _mm_max_epi32(val01C, limit01A);
+          val01D = _mm_max_epi32(val01D, limit01A);
+
+          val01A = _mm_add_epi32(val01A, val01C);
+          val01B = _mm_add_epi32(val01B, val01D);
+
+          __m128i coeff01 = params[0][i];
+
+          val01A = _mm_mullo_epi32(val01A, coeff01);
+          val01B = _mm_mullo_epi32(val01B, coeff01);
+
+          accum = _mm_add_epi32(accum, _mm_hadd_epi32(val01A, val01B));
+        };
+
+        process2coeffs(0, img3 + 0, img4 + 0, img1 + 1, img2 - 1);
+        process2coeffs(1, img1 + 0, img2 + 0, img1 - 1, img2 + 1);
+        process2coeffs(2, img0 + 2, img0 - 2, img0 + 1, img0 - 1);
+
+        bool isNearVBabove = yVb < vbPos && (yVb >= vbPos - 1);
+        bool isNearVBbelow = yVb >= vbPos && (yVb <= vbPos);
+        if (!(isNearVBabove || isNearVBbelow))
+        {
+          accum = _mm_srai_epi32(accum, shift);
+        }
+        else
+        {
+          accum = _mm_srai_epi32(_mm_add_epi32(accum, offset1), shift + 3);
+        }
+        accum = _mm_add_epi32(accum, cur);
+        accum = _mm_min_epi32(max, _mm_max_epi32(accum, min));
+
+        _mm_storeu_si128((__m128i *) (dst + ii * dstStride + j), accum);
+      }
+    }
+
+    src += srcStride * step_y;
+    dst += dstStride * step_y;
+  }
+}
+
+static void simdDeriveClassificationBlk_HBD(AlfClassifier **classifier, int **laplacian[NUM_DIRECTIONS],
+  const CPelBuf &srcLuma, const Area &blkDst, const Area &blk, const int shift,
+  const int vbCTUHeight, int vbPos)
+{
+  CHECK((blk.height & 7) != 0, "Block height must be a multiple of 8");
+  CHECK((blk.width & 7) != 0, "Block width must be a multiple of 8");
+  CHECK((vbCTUHeight & (vbCTUHeight - 1)) != 0, "vbCTUHeight must be a power of 2");
+
+  const size_t imgStride = srcLuma.stride;
+  const Pel *  srcExt = srcLuma.buf;
+
+  const int imgHExtended = blk.height + 4;
+  const int imgWExtended = blk.width + 4;
+
+  const int posX = blk.pos().x;
+  const int posY = blk.pos().y;
+
+  // 18x40 array
+  uint32_t colSums[(AdaptiveLoopFilter::m_CLASSIFICATION_BLK_SIZE + 4) >> 1]
+    [AdaptiveLoopFilter::m_CLASSIFICATION_BLK_SIZE + 8];
+
+  for (int i = 0; i < imgHExtended; i += 2)
+  {
+    const size_t offset = (i + posY - 3) * imgStride + posX - 3;
+
+    const Pel *imgY0 = &srcExt[offset];
+    const Pel *imgY1 = &srcExt[offset + imgStride];
+    const Pel *imgY2 = &srcExt[offset + imgStride * 2];
+    const Pel *imgY3 = &srcExt[offset + imgStride * 3];
+
+    // pixel padding for gradient calculation
+    int pos = blkDst.pos().y - 2 + i;
+    int posInCTU = pos & (vbCTUHeight - 1);
+    if (pos > 0 && posInCTU == vbPos - 2)
+    {
+      imgY3 = imgY2;
+    }
+    else if (pos > 0 && posInCTU == vbPos)
+    {
+      imgY0 = imgY1;
+    }
+
+    __m128i prev_hv = _mm_setzero_si128();  __m128i prev_di = _mm_setzero_si128();
+
+    for (int j = 0; j < imgWExtended; j += 8)
+    {
+      const __m128i x0_lo = _mm_lddqu_si128((const __m128i *) (imgY0 + j));
+      const __m128i x0_hi = _mm_lddqu_si128((const __m128i *) (imgY0 + j + 4));
+      const __m128i x1_lo = _mm_lddqu_si128((const __m128i *) (imgY1 + j));
+      const __m128i x1_hi = _mm_lddqu_si128((const __m128i *) (imgY1 + j + 4));
+      const __m128i x2_lo = _mm_lddqu_si128((const __m128i *) (imgY2 + j));
+      const __m128i x2_hi = _mm_lddqu_si128((const __m128i *) (imgY2 + j + 4));
+      const __m128i x3_lo = _mm_lddqu_si128((const __m128i *) (imgY3 + j));
+      const __m128i x3_hi = _mm_lddqu_si128((const __m128i *) (imgY3 + j + 4));
+
+      const __m128i x4_lo = _mm_lddqu_si128((const __m128i *) (imgY0 + j + 2));
+      const __m128i x4_hi = _mm_lddqu_si128((const __m128i *) (imgY0 + j + 6));
+      const __m128i x5_lo = _mm_lddqu_si128((const __m128i *) (imgY1 + j + 2));
+      const __m128i x5_hi = _mm_lddqu_si128((const __m128i *) (imgY1 + j + 6));
+      const __m128i x6_lo = _mm_lddqu_si128((const __m128i *) (imgY2 + j + 2));
+      const __m128i x6_hi = _mm_lddqu_si128((const __m128i *) (imgY2 + j + 6));
+      const __m128i x7_lo = _mm_lddqu_si128((const __m128i *) (imgY3 + j + 2));
+      const __m128i x7_hi = _mm_lddqu_si128((const __m128i *) (imgY3 + j + 6));
+
+      const __m128i nw_lo = _mm_blend_epi16(x0_lo, x1_lo, 0xcc);
+      const __m128i nw_hi = _mm_blend_epi16(x0_hi, x1_hi, 0xcc);
+      const __m128i n_lo = _mm_blend_epi16(x0_lo, x5_lo, 0x33);
+      const __m128i n_hi = _mm_blend_epi16(x0_hi, x5_hi, 0x33);
+      const __m128i ne_lo = _mm_blend_epi16(x4_lo, x5_lo, 0xcc);
+      const __m128i ne_hi = _mm_blend_epi16(x4_hi, x5_hi, 0xcc);
+      const __m128i w_lo = _mm_blend_epi16(x1_lo, x2_lo, 0xcc);
+      const __m128i w_hi = _mm_blend_epi16(x1_hi, x2_hi, 0xcc);
+      const __m128i e_lo = _mm_blend_epi16(x5_lo, x6_lo, 0xcc);
+      const __m128i e_hi = _mm_blend_epi16(x5_hi, x6_hi, 0xcc);
+      const __m128i sw_lo = _mm_blend_epi16(x2_lo, x3_lo, 0xcc);
+      const __m128i sw_hi = _mm_blend_epi16(x2_hi, x3_hi, 0xcc);
+      const __m128i s_lo = _mm_blend_epi16(x2_lo, x7_lo, 0x33);
+      const __m128i s_hi = _mm_blend_epi16(x2_hi, x7_hi, 0x33);
+      const __m128i se_lo = _mm_blend_epi16(x6_lo, x7_lo, 0xcc);
+      const __m128i se_hi = _mm_blend_epi16(x6_hi, x7_hi, 0xcc);
+
+      __m128i c_lo = _mm_slli_epi32(_mm_blend_epi16(x1_lo, x6_lo, 0x33), 1);
+      __m128i c_hi = _mm_slli_epi32(_mm_blend_epi16(x1_hi, x6_hi, 0x33), 1);
+      __m128i d_lo = _mm_shuffle_epi32(c_lo, 0xb1);
+      __m128i d_hi = _mm_shuffle_epi32(c_hi, 0xb1);
+
+      const __m128i ver_lo = _mm_abs_epi32(_mm_sub_epi32(c_lo, _mm_add_epi32(n_lo, s_lo)));
+      const __m128i ver_hi = _mm_abs_epi32(_mm_sub_epi32(c_hi, _mm_add_epi32(n_hi, s_hi)));
+      const __m128i hor_lo = _mm_abs_epi32(_mm_sub_epi32(d_lo, _mm_add_epi32(w_lo, e_lo)));
+      const __m128i hor_hi = _mm_abs_epi32(_mm_sub_epi32(d_hi, _mm_add_epi32(w_hi, e_hi)));
+      const __m128i di0_lo = _mm_abs_epi32(_mm_sub_epi32(d_lo, _mm_add_epi32(nw_lo, se_lo)));
+      const __m128i di0_hi = _mm_abs_epi32(_mm_sub_epi32(d_hi, _mm_add_epi32(nw_hi, se_hi)));
+      const __m128i di1_lo = _mm_abs_epi32(_mm_sub_epi32(d_lo, _mm_add_epi32(ne_lo, sw_lo)));
+      const __m128i di1_hi = _mm_abs_epi32(_mm_sub_epi32(d_hi, _mm_add_epi32(ne_hi, sw_hi)));
+
+      const __m128i v = _mm_hadd_epi32(ver_lo, ver_hi);
+      const __m128i h = _mm_hadd_epi32(hor_lo, hor_hi);
+      const __m128i di0 = _mm_hadd_epi32(di0_lo, di0_hi);
+      const __m128i di1 = _mm_hadd_epi32(di1_lo, di1_hi);
+      const __m128i all_hv = _mm_hadd_epi32(v, h);
+      const __m128i all_di = _mm_hadd_epi32(di0, di1);
+
+      const __m128i t_hv = _mm_blend_epi16(all_hv, prev_hv, 0xcc);
+      const __m128i t_di = _mm_blend_epi16(all_di, prev_di, 0xcc);
+
+      const __m128i cmb0 = _mm_hadd_epi32(t_hv, t_di);
+      const __m128i cmb1 = _mm_hadd_epi32(all_hv, all_di);
+      _mm_storeu_si128((__m128i *) &colSums[i >> 1][j], cmb0);
+      _mm_storeu_si128((__m128i *) &colSums[i >> 1][j + 4], cmb1);
+
+      prev_hv = all_hv;
+      prev_di = all_di;
+    }
+  }
+
+  const __m128i zeros = _mm_setzero_si128();
+  for (int i = 0; i < (blk.height >> 1); i += 4)
+  {
+    for (int j = 0; j < blk.width; j += 8)
+    {
+      __m128i x0l, x1l, x2l, x3l, x4l, x5l, x6l, x7l;
+      __m128i x0h, x1h, x2h, x3h, x4h, x5h, x6h, x7h;
+
+      const uint32_t z = (2 * i + blkDst.pos().y) & (vbCTUHeight - 1);
+      const uint32_t z2 = (2 * i + 4 + blkDst.pos().y) & (vbCTUHeight - 1);
+
+      x0l = (z == vbPos) ? zeros : _mm_lddqu_si128((__m128i *) &colSums[i + 0][j + 4]);
+      x0h = (z == vbPos) ? zeros : _mm_lddqu_si128((__m128i *) &colSums[i + 0][j + 8]);
+      x1l = _mm_lddqu_si128((__m128i *) &colSums[i + 1][j + 4]);
+      x1h = _mm_lddqu_si128((__m128i *) &colSums[i + 1][j + 8]);
+      x2l = _mm_lddqu_si128((__m128i *) &colSums[i + 2][j + 4]);
+      x2h = _mm_lddqu_si128((__m128i *) &colSums[i + 2][j + 8]);
+      x3l = (z == vbPos - 4) ? zeros : _mm_lddqu_si128((__m128i *) &colSums[i + 3][j + 4]);
+      x3h = (z == vbPos - 4) ? zeros : _mm_lddqu_si128((__m128i *) &colSums[i + 3][j + 8]);
+
+      x4l = (z2 == vbPos) ? zeros : _mm_lddqu_si128((__m128i *) &colSums[i + 2][j + 4]);
+      x4h = (z2 == vbPos) ? zeros : _mm_lddqu_si128((__m128i *) &colSums[i + 2][j + 8]);
+      x5l = _mm_lddqu_si128((__m128i *) &colSums[i + 3][j + 4]);
+      x5h = _mm_lddqu_si128((__m128i *) &colSums[i + 3][j + 8]);
+      x6l = _mm_lddqu_si128((__m128i *) &colSums[i + 4][j + 4]);
+      x6h = _mm_lddqu_si128((__m128i *) &colSums[i + 4][j + 8]);
+      x7l = (z2 == vbPos - 4) ? zeros : _mm_lddqu_si128((__m128i *) &colSums[i + 5][j + 4]);
+      x7h = (z2 == vbPos - 4) ? zeros : _mm_lddqu_si128((__m128i *) &colSums[i + 5][j + 8]);
+
+      x0l = _mm_add_epi32(x0l, x1l);
+      x2l = _mm_add_epi32(x2l, x3l);
+      x4l = _mm_add_epi32(x4l, x5l);
+      x6l = _mm_add_epi32(x6l, x7l);
+      x0h = _mm_add_epi32(x0h, x1h);
+      x2h = _mm_add_epi32(x2h, x3h);
+      x4h = _mm_add_epi32(x4h, x5h);
+      x6h = _mm_add_epi32(x6h, x7h);
+
+      x0l = _mm_add_epi32(x0l, x2l);
+      x4l = _mm_add_epi32(x4l, x6l);
+      x0h = _mm_add_epi32(x0h, x2h);
+      x4h = _mm_add_epi32(x4h, x6h);
+
+      x2l = _mm_unpacklo_epi32(x0l, x4l);
+      x2h = _mm_unpackhi_epi32(x0l, x4l);
+      x6l = _mm_unpacklo_epi32(x0h, x4h);
+      x6h = _mm_unpackhi_epi32(x0h, x4h);
+
+      __m128i sumV = _mm_unpacklo_epi32(x2l, x6l);
+      __m128i sumH = _mm_unpackhi_epi32(x2l, x6l);
+      __m128i sumD0 = _mm_unpacklo_epi32(x2h, x6h);
+      __m128i sumD1 = _mm_unpackhi_epi32(x2h, x6h);
+
+      __m128i tempAct = _mm_add_epi32(sumV, sumH);
+
+      const uint32_t scale = (z == vbPos - 4 || z == vbPos) ? 96 : 64;
+      const uint32_t scale2 = (z2 == vbPos - 4 || z2 == vbPos) ? 96 : 64;
+      __m128i activity = _mm_mullo_epi32(tempAct, _mm_unpacklo_epi64(_mm_set1_epi32(scale), _mm_set1_epi32(scale2)));
+      activity = _mm_srl_epi32(activity, _mm_cvtsi32_si128(shift));
+      activity = _mm_min_epi32(activity, _mm_set1_epi32(15));
+      __m128i classIdx = _mm_shuffle_epi8(_mm_setr_epi8(0, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4), activity);
+
+      __m128i dirTempHVMinus1 = _mm_cmpgt_epi32(sumV, sumH);
+      __m128i hv1 = _mm_max_epi32(sumV, sumH);
+      __m128i hv0 = _mm_min_epi32(sumV, sumH);
+
+      __m128i dirTempDMinus1 = _mm_cmpgt_epi32(sumD0, sumD1);
+      __m128i d1 = _mm_max_epi32(sumD0, sumD1);
+      __m128i d0 = _mm_min_epi32(sumD0, sumD1);
+
+      __m128i a = _mm_xor_si128(_mm_mullo_epi32(d1, hv0), _mm_set1_epi32(0x80000000));
+      __m128i b = _mm_xor_si128(_mm_mullo_epi32(hv1, d0), _mm_set1_epi32(0x80000000));
+      __m128i dirIdx = _mm_cmpgt_epi32(a, b);
+      __m128i hvd1 = _mm_blendv_epi8(hv1, d1, dirIdx);
+      __m128i hvd0 = _mm_blendv_epi8(hv0, d0, dirIdx);
+
+      __m128i strength1 = _mm_cmpgt_epi32(hvd1, _mm_add_epi32(hvd0, hvd0));
+      __m128i strength2 = _mm_cmpgt_epi32(_mm_add_epi32(hvd1, hvd1), _mm_add_epi32(hvd0, _mm_slli_epi32(hvd0, 3)));
+      __m128i offset = _mm_and_si128(strength1, _mm_set1_epi32(5));
+      classIdx = _mm_add_epi32(classIdx, offset);
+      classIdx = _mm_add_epi32(classIdx, _mm_and_si128(strength2, _mm_set1_epi32(5)));
+      offset = _mm_andnot_si128(dirIdx, offset);
+      offset = _mm_add_epi32(offset, offset);
+      classIdx = _mm_add_epi32(classIdx, offset);
+
+      __m128i transposeIdx = _mm_set1_epi32(3);
+      transposeIdx = _mm_add_epi32(transposeIdx, dirTempHVMinus1);
+      transposeIdx = _mm_add_epi32(transposeIdx, dirTempDMinus1);
+      transposeIdx = _mm_add_epi32(transposeIdx, dirTempDMinus1);
+
+      int yOffset = 2 * i + blkDst.pos().y;
+      int xOffset = j + blkDst.pos().x;
 
+      static_assert(sizeof(AlfClassifier) == 2, "ALFClassifier type must be 16 bits wide");
+      __m128i v;
+      v = _mm_unpacklo_epi8(classIdx, transposeIdx);
+      v = _mm_shuffle_epi8(v, _mm_setr_epi8(0, 1, 0, 1, 0, 1, 0, 1, 8, 9, 8, 9, 8, 9, 8, 9));
+      _mm_storeu_si128((__m128i *) (classifier[yOffset] + xOffset), v);
+      _mm_storeu_si128((__m128i *) (classifier[yOffset + 1] + xOffset), v);
+      _mm_storeu_si128((__m128i *) (classifier[yOffset + 2] + xOffset), v);
+      _mm_storeu_si128((__m128i *) (classifier[yOffset + 3] + xOffset), v);
+      v = _mm_unpackhi_epi8(classIdx, transposeIdx);
+      v = _mm_shuffle_epi8(v, _mm_setr_epi8(0, 1, 0, 1, 0, 1, 0, 1, 8, 9, 8, 9, 8, 9, 8, 9));
+      _mm_storeu_si128((__m128i *) (classifier[yOffset + 4] + xOffset), v);
+      _mm_storeu_si128((__m128i *) (classifier[yOffset + 5] + xOffset), v);
+      _mm_storeu_si128((__m128i *) (classifier[yOffset + 6] + xOffset), v);
+      _mm_storeu_si128((__m128i *) (classifier[yOffset + 7] + xOffset), v);
+    }
+  }
+}
+
+#ifdef USE_AVX2
+static void simdFilter5x5Blk_HBD_AVX2(AlfClassifier **classifier, const PelUnitBuf &recDst, const CPelUnitBuf &recSrc,
+  const Area &blkDst, const Area &blk, const ComponentID compId, const short *filterSet,
+  const Pel *fClipSet, const ClpRng &clpRng, CodingStructure &cs, const int vbCTUHeight,
+  int vbPos)
+
+{
+  CHECK((vbCTUHeight & (vbCTUHeight - 1)) != 0, "vbCTUHeight must be a power of 2");
+  CHECK(!isChroma(compId), "ALF 5x5 filter is for chroma only");
+
+  const CPelBuf srcBuffer = recSrc.get(compId);
+  PelBuf        dstBuffer = recDst.get(compId);
+
+  const size_t srcStride = srcBuffer.stride;
+  const size_t dstStride = dstBuffer.stride;
+
+  constexpr int shift = AdaptiveLoopFilter::m_NUM_BITS - 1;
+  constexpr int round = 1 << (shift - 1);
+  const __m256i offset1 = _mm256_set1_epi32((1 << ((shift + 3) - 1)) - round);
+
+  const size_t width = blk.width;
+  const size_t height = blk.height;
+
+  constexpr size_t step_x = 8;
+  constexpr size_t step_y = 4;
+
+  CHECK(blk.y % step_y, "Wrong startHeight in filtering");
+  CHECK(blk.x % step_x, "Wrong startWidth in filtering");
+  CHECK(height % step_y, "Wrong endHeight in filtering");
+  CHECK(width % step_x, "Wrong endWidth in filtering");
+
+  const Pel *src = srcBuffer.buf + blk.y * srcStride + blk.x;
+  Pel *      dst = dstBuffer.buf + blkDst.y * dstStride + blkDst.x;
+
+  const __m256i offset = _mm256_set1_epi32(round);
+  const __m256i min = _mm256_set1_epi32(clpRng.min);
+  const __m256i max = _mm256_set1_epi32(clpRng.max);
+  const __m256i zeros = _mm256_setzero_si256();
+
+  __m128i params[2][3];
+  __m128i fs = _mm_lddqu_si128((__m128i *) filterSet);
+  params[0][0] = _mm_cvtepi16_epi32(_mm_shuffle_epi32(fs, 0x00));
+  params[0][1] = _mm_cvtepi16_epi32(_mm_shuffle_epi32(fs, 0x55));
+  params[0][2] = _mm_cvtepi16_epi32(_mm_shuffle_epi32(fs, 0xaa));
+  __m128i fcLo = _mm_lddqu_si128((__m128i *) fClipSet);
+  __m128i fcHi = _mm_loadl_epi64((__m128i *) (fClipSet + 4));
+  params[1][0] = _mm_shuffle_epi32(fcLo, 0x44);
+  params[1][1] = _mm_shuffle_epi32(fcLo, 0xee);
+  params[1][2] = _mm_shuffle_epi32(fcHi, 0x44);
+
+  for (size_t i = 0; i < height; i += step_y)
+  {
+    for (size_t j = 0; j < width; j += step_x)
+    {
+      for (size_t ii = 0; ii < step_y; ii++)
+      {
+        const Pel *img0, *img1, *img2, *img3, *img4;
+
+        img0 = src + j + ii * srcStride;
+        img1 = img0 + srcStride;
+        img2 = img0 - srcStride;
+        img3 = img1 + srcStride;
+        img4 = img2 - srcStride;
+
+        const int yVb = (blkDst.y + i + ii) & (vbCTUHeight - 1);
+        if (yVb < vbPos && (yVb >= vbPos - 2))   // above
+        {
+          img1 = (yVb == vbPos - 1) ? img0 : img1;
+          img3 = (yVb >= vbPos - 2) ? img1 : img3;
+
+          img2 = (yVb == vbPos - 1) ? img0 : img2;
+          img4 = (yVb >= vbPos - 2) ? img2 : img4;
+        }
+        else if (yVb >= vbPos && (yVb <= vbPos + 1))   // bottom
+        {
+          img2 = (yVb == vbPos) ? img0 : img2;
+          img4 = (yVb <= vbPos + 1) ? img2 : img4;
+
+          img1 = (yVb == vbPos) ? img0 : img1;
+          img3 = (yVb <= vbPos + 1) ? img1 : img3;
+        }
+        __m256i cur = _mm256_lddqu_si256((const __m256i *) img0);
+        __m256i accum = offset;
+
+        auto process2coeffs = [&](const int i, const Pel *ptr0, const Pel *ptr1, const Pel *ptr2, const Pel *ptr3) {
+          const __m256i val00 = _mm256_sub_epi32(_mm256_lddqu_si256((const __m256i *) ptr0), cur);
+          const __m256i val10 = _mm256_sub_epi32(_mm256_lddqu_si256((const __m256i *) ptr2), cur);
+          const __m256i val01 = _mm256_sub_epi32(_mm256_lddqu_si256((const __m256i *) ptr1), cur);
+          const __m256i val11 = _mm256_sub_epi32(_mm256_lddqu_si256((const __m256i *) ptr3), cur);
+          __m256i val01A = _mm256_unpacklo_epi32(val00, val10);
+          __m256i val01B = _mm256_unpackhi_epi32(val00, val10);
+          __m256i val01C = _mm256_unpacklo_epi32(val01, val11);
+          __m256i val01D = _mm256_unpackhi_epi32(val01, val11);
+
+          __m256i limit01A = _mm256_inserti128_si256(_mm256_castsi128_si256(params[1][i]), params[1][i], 1);
+
+          val01A = _mm256_min_epi32(val01A, limit01A);
+          val01B = _mm256_min_epi32(val01B, limit01A);
+          val01C = _mm256_min_epi32(val01C, limit01A);
+          val01D = _mm256_min_epi32(val01D, limit01A);
+
+          limit01A = _mm256_sub_epi32(zeros, limit01A);
+
+          val01A = _mm256_max_epi32(val01A, limit01A);
+          val01B = _mm256_max_epi32(val01B, limit01A);
+          val01C = _mm256_max_epi32(val01C, limit01A);
+          val01D = _mm256_max_epi32(val01D, limit01A);
+
+          val01A = _mm256_add_epi32(val01A, val01C);
+          val01B = _mm256_add_epi32(val01B, val01D);
+
+          __m256i coeff01 = _mm256_inserti128_si256(_mm256_castsi128_si256(params[0][i]), params[0][i], 1);
+
+          val01A = _mm256_mullo_epi32(val01A, coeff01);
+          val01B = _mm256_mullo_epi32(val01B, coeff01);
+
+          accum = _mm256_add_epi32(accum, _mm256_hadd_epi32(val01A, val01B));
+        };
+
+        process2coeffs(0, img3 + 0, img4 + 0, img1 + 1, img2 - 1);
+        process2coeffs(1, img1 + 0, img2 + 0, img1 - 1, img2 + 1);
+        process2coeffs(2, img0 + 2, img0 - 2, img0 + 1, img0 - 1);
+
+        bool isNearVBabove = yVb < vbPos && (yVb >= vbPos - 1);
+        bool isNearVBbelow = yVb >= vbPos && (yVb <= vbPos);
+        if (!(isNearVBabove || isNearVBbelow))
+        {
+          accum = _mm256_srai_epi32(accum, shift);
+        }
+        else
+        {
+          accum = _mm256_srai_epi32(_mm256_add_epi32(accum, offset1), shift + 3);
+        }
+        accum = _mm256_add_epi32(accum, cur);
+        accum = _mm256_min_epi32(max, _mm256_max_epi32(accum, min));
+
+        _mm256_store_si256((__m256i *) (dst + ii * dstStride + j), accum);
+      }
+    }
+
+    src += srcStride * step_y;
+    dst += dstStride * step_y;
+  }
+}
+#endif
+#else
 template<X86_VEXT vext>
 static void simdDeriveClassificationBlk(AlfClassifier **classifier, int **laplacian[NUM_DIRECTIONS],
                                         const CPelBuf &srcLuma, const Area &blkDst, const Area &blk, const int shift,
@@ -449,7 +965,7 @@ static void simdFilter5x5Blk(AlfClassifier **classifier, const PelUnitBuf &recDs
     dst += dstStride * STEP_Y;
   }
 }
-
+#endif
 constexpr uint16_t sh(int x)
 {
   return 0x0202 * (x & 7) + 0x0100 + 0x1010 * (x & 8);
@@ -473,7 +989,488 @@ static const uint16_t shuffleTab[4][2][8] = {
     { sh(1), sh(0), sh(2), sh(6), sh(12), sh(13), sh(14), sh(15) },
   },
 };
+#if RExt__HIGH_BIT_DEPTH_SUPPORT
+constexpr uint32_t shuffle32(int x)
+{
+  return 0x04040404 * (x & 3) + 0x03020100 + ((x & 4) ? 0x10101010 : 0x00000000) + ((x & 8) ? 0x20202020 : 0x00000000);
+}
+
+static const uint32_t shuffleTab32[4][3][4] = {
+  {
+    { shuffle32(0), shuffle32(1), shuffle32(2),  shuffle32(3)  },
+    { shuffle32(4), shuffle32(5), shuffle32(6),  shuffle32(7)  },
+    { shuffle32(8), shuffle32(9), shuffle32(10), shuffle32(11) },
+  },
+  {
+    { shuffle32(9), shuffle32(4), shuffle32(10), shuffle32(8) },
+    { shuffle32(1), shuffle32(5), shuffle32(11), shuffle32(7) },
+    { shuffle32(3), shuffle32(0), shuffle32(2),  shuffle32(6) },
+  },
+  {
+    { shuffle32(0), shuffle32(3), shuffle32(2),  shuffle32(1)  },
+    { shuffle32(8), shuffle32(7), shuffle32(6),  shuffle32(5)  },
+    { shuffle32(4), shuffle32(9), shuffle32(10), shuffle32(11) },
+  },
+  {
+    { shuffle32(9), shuffle32(8), shuffle32(10), shuffle32(4) },
+    { shuffle32(3), shuffle32(7), shuffle32(11), shuffle32(5) },
+    { shuffle32(1), shuffle32(0), shuffle32(2),  shuffle32(6) },
+  },
+};
 
+static void simdFilter7x7Blk_HBD(AlfClassifier **classifier, const PelUnitBuf &recDst, const CPelUnitBuf &recSrc,
+  const Area &blkDst, const Area &blk, const ComponentID compId, const short *filterSet,
+  const Pel *fClipSet, const ClpRng &clpRng, CodingStructure &cs, const int vbCTUHeight,
+  int vbPos)
+{
+  CHECK((vbCTUHeight & (vbCTUHeight - 1)) != 0, "vbCTUHeight must be a power of 2");
+  CHECK(isChroma(compId), "7x7 ALF filter is meant for luma only");
+
+  const CPelBuf srcBuffer = recSrc.get(compId);
+  PelBuf        dstBuffer = recDst.get(compId);
+
+  const size_t srcStride = srcBuffer.stride;
+  const size_t dstStride = dstBuffer.stride;
+
+  constexpr int shift = AdaptiveLoopFilter::m_NUM_BITS - 1;
+  constexpr int round = 1 << (shift - 1);
+
+  const size_t width = blk.width;
+  const size_t height = blk.height;
+
+  constexpr size_t step_x = 4;
+  constexpr size_t step_y = 4;
+
+  CHECK(blk.y % step_y, "Wrong startHeight in filtering");
+  CHECK(blk.x % step_x, "Wrong startWidth in filtering");
+  CHECK(height % step_y, "Wrong endHeight in filtering");
+  CHECK(width % step_x, "Wrong endWidth in filtering");
+
+  const Pel *src = srcBuffer.buf + blk.y * srcStride + blk.x;
+  Pel *      dst = dstBuffer.buf + blkDst.y * dstStride + blkDst.x;
+
+  const __m128i offset = _mm_set1_epi32(round);
+  const __m128i offset1 = _mm_set1_epi32((1 << ((shift + 3) - 1)) - round);
+  const __m128i min = _mm_set1_epi32(clpRng.min);
+  const __m128i max = _mm_set1_epi32(clpRng.max);
+  const __m128i zeros = _mm_setzero_si128();
+
+  const __m128i cmp1 = _mm_set1_epi8((char)0x0f);
+  const __m128i cmp2 = _mm_set1_epi8((char)0xf0);
+  const __m128i mask1 = _mm_set1_epi8((char)0x10);
+  const __m128i mask2 = _mm_set1_epi8((char)0x20);
+
+  for (size_t i = 0; i < height; i += step_y)  // + 4
+  {
+    const AlfClassifier *pClass = classifier[blkDst.y + i] + blkDst.x;
+
+    for (size_t j = 0; j < width; j += step_x)  // + 4
+    {
+      __m128i params[2][6];
+
+      const AlfClassifier &cl = pClass[j];
+
+      const int transposeIdx = cl.transposeIdx;
+      const int classIdx = cl.classIdx;
+
+      __m128i rawCoeff0, rawCoeff1;
+      rawCoeff0 = _mm_lddqu_si128((const __m128i *) (filterSet + classIdx * MAX_NUM_ALF_LUMA_COEFF));
+      rawCoeff1 = _mm_loadl_epi64((const __m128i *) (filterSet + classIdx * MAX_NUM_ALF_LUMA_COEFF + 8));
+
+      const __m128i s0 = _mm_lddqu_si128((const __m128i *) shuffleTab[transposeIdx][0]);
+      const __m128i s1 = _mm_xor_si128(s0, _mm_set1_epi8((char)0x80));
+      const __m128i s2 = _mm_lddqu_si128((const __m128i *) shuffleTab[transposeIdx][1]);
+      const __m128i s3 = _mm_xor_si128(s2, _mm_set1_epi8((char)0x80));
+
+      const __m128i rawCoeffLo = _mm_or_si128(_mm_shuffle_epi8(rawCoeff0, s0), _mm_shuffle_epi8(rawCoeff1, s1));
+      const __m128i rawCoeffHi = _mm_or_si128(_mm_shuffle_epi8(rawCoeff0, s2), _mm_shuffle_epi8(rawCoeff1, s3));
+
+      params[0][0] = _mm_cvtepi16_epi32(_mm_shuffle_epi32(rawCoeffLo, 0x00));
+      params[0][1] = _mm_cvtepi16_epi32(_mm_shuffle_epi32(rawCoeffLo, 0x55));
+      params[0][2] = _mm_cvtepi16_epi32(_mm_shuffle_epi32(rawCoeffLo, 0xaa));
+      params[0][3] = _mm_cvtepi16_epi32(_mm_shuffle_epi32(rawCoeffLo, 0xff));
+      params[0][4] = _mm_cvtepi16_epi32(_mm_shuffle_epi32(rawCoeffHi, 0x00));
+      params[0][5] = _mm_cvtepi16_epi32(_mm_shuffle_epi32(rawCoeffHi, 0x55));
+
+      __m128i rawClip0, rawClip1, rawClip2;
+      rawClip0 = _mm_lddqu_si128((const __m128i *) (fClipSet + classIdx * MAX_NUM_ALF_LUMA_COEFF));
+      rawClip1 = _mm_lddqu_si128((const __m128i *) (fClipSet + classIdx * MAX_NUM_ALF_LUMA_COEFF + 4));
+      rawClip2 = _mm_lddqu_si128((const __m128i *) (fClipSet + classIdx * MAX_NUM_ALF_LUMA_COEFF + 8));
+
+      __m128i mask;
+      __m128i s00, s01, s02, s10, s11, s12, s20, s21, s22;
+      __m128i src0 = _mm_lddqu_si128((const __m128i *) shuffleTab32[transposeIdx][0]);
+      mask = _mm_and_si128(_mm_cmpgt_epi8(src0, cmp1), cmp2);
+      s00 = _mm_or_si128(src0, mask);
+      s01 = _mm_xor_si128(src0, mask1);
+      mask = _mm_and_si128(_mm_cmpgt_epi8(s01, cmp1), cmp2);
+      s01 = _mm_or_si128(s01, mask);
+      s02 = _mm_xor_si128(src0, mask2);
+      mask = _mm_and_si128(_mm_cmpgt_epi8(s02, cmp1), cmp2);
+      s02 = _mm_or_si128(s02, mask);
+
+      __m128i src1 = _mm_lddqu_si128((const __m128i *) shuffleTab32[transposeIdx][1]);
+      mask = _mm_and_si128(_mm_cmpgt_epi8(src1, cmp1), cmp2);
+      s10 = _mm_or_si128(src1, mask);
+      s11 = _mm_xor_si128(src1, mask1);
+      mask = _mm_and_si128(_mm_cmpgt_epi8(s11, cmp1), cmp2);
+      s11 = _mm_or_si128(s11, mask);
+      s12 = _mm_xor_si128(src1, mask2);
+      mask = _mm_and_si128(_mm_cmpgt_epi8(s12, cmp1), cmp2);
+      s12 = _mm_or_si128(s12, mask);
+
+      __m128i src2 = _mm_lddqu_si128((const __m128i *) shuffleTab32[transposeIdx][2]);
+      mask = _mm_and_si128(_mm_cmpgt_epi8(src2, cmp1), cmp2);
+      s20 = _mm_or_si128(src2, mask);
+      s21 = _mm_xor_si128(src2, mask1);
+      mask = _mm_and_si128(_mm_cmpgt_epi8(s21, cmp1), cmp2);
+      s21 = _mm_or_si128(s21, mask);
+      s22 = _mm_xor_si128(src2, mask2);
+      mask = _mm_and_si128(_mm_cmpgt_epi8(s22, cmp1), cmp2);
+      s22 = _mm_or_si128(s22, mask);
+
+      const __m128i rawClipLo = _mm_or_si128(_mm_or_si128(_mm_shuffle_epi8(rawClip0, s00), _mm_shuffle_epi8(rawClip1, s01)), _mm_shuffle_epi8(rawClip2, s02));
+      const __m128i rawClipMl = _mm_or_si128(_mm_or_si128(_mm_shuffle_epi8(rawClip0, s10), _mm_shuffle_epi8(rawClip1, s11)), _mm_shuffle_epi8(rawClip2, s12));
+      const __m128i rawClipHi = _mm_or_si128(_mm_or_si128(_mm_shuffle_epi8(rawClip0, s20), _mm_shuffle_epi8(rawClip1, s21)), _mm_shuffle_epi8(rawClip2, s22));
+
+      params[1][0] = _mm_shuffle_epi32(rawClipLo, 0x44);
+      params[1][1] = _mm_shuffle_epi32(rawClipLo, 0xee);
+      params[1][2] = _mm_shuffle_epi32(rawClipMl, 0x44);
+      params[1][3] = _mm_shuffle_epi32(rawClipMl, 0xee);
+      params[1][4] = _mm_shuffle_epi32(rawClipHi, 0x44);
+      params[1][5] = _mm_shuffle_epi32(rawClipHi, 0xee);
+
+      for (size_t ii = 0; ii < step_y; ii++)
+      {
+        const Pel *img0, *img1, *img2, *img3, *img4, *img5, *img6;
+
+        img0 = src + j + ii * srcStride;
+        img1 = img0 + srcStride;
+        img2 = img0 - srcStride;
+        img3 = img1 + srcStride;
+        img4 = img2 - srcStride;
+        img5 = img3 + srcStride;
+        img6 = img4 - srcStride;
+
+        const int yVb = (blkDst.y + i + ii) & (vbCTUHeight - 1);
+        if (yVb < vbPos && (yVb >= vbPos - 4))   // above
+        {
+          img1 = (yVb == vbPos - 1) ? img0 : img1;
+          img3 = (yVb >= vbPos - 2) ? img1 : img3;
+          img5 = (yVb >= vbPos - 3) ? img3 : img5;
+
+          img2 = (yVb == vbPos - 1) ? img0 : img2;
+          img4 = (yVb >= vbPos - 2) ? img2 : img4;
+          img6 = (yVb >= vbPos - 3) ? img4 : img6;
+        }
+        else if (yVb >= vbPos && (yVb <= vbPos + 3))   // bottom
+        {
+          img2 = (yVb == vbPos) ? img0 : img2;
+          img4 = (yVb <= vbPos + 1) ? img2 : img4;
+          img6 = (yVb <= vbPos + 2) ? img4 : img6;
+
+          img1 = (yVb == vbPos) ? img0 : img1;
+          img3 = (yVb <= vbPos + 1) ? img1 : img3;
+          img5 = (yVb <= vbPos + 2) ? img3 : img5;
+        }
+        __m128i cur = _mm_lddqu_si128((const __m128i *) img0);
+        __m128i accum = offset;
+
+        auto process2coeffs = [&](const int i, const Pel *ptr0, const Pel *ptr1, const Pel *ptr2, const Pel *ptr3) {
+          const __m128i val00 = _mm_sub_epi32(_mm_lddqu_si128((const __m128i *) ptr0), cur);
+          const __m128i val10 = _mm_sub_epi32(_mm_lddqu_si128((const __m128i *) ptr2), cur);
+          const __m128i val01 = _mm_sub_epi32(_mm_lddqu_si128((const __m128i *) ptr1), cur);
+          const __m128i val11 = _mm_sub_epi32(_mm_lddqu_si128((const __m128i *) ptr3), cur);
+
+          __m128i val01A = _mm_unpacklo_epi32(val00, val10);
+          __m128i val01B = _mm_unpackhi_epi32(val00, val10);
+          __m128i val01C = _mm_unpacklo_epi32(val01, val11);
+          __m128i val01D = _mm_unpackhi_epi32(val01, val11);
+
+          __m128i limit01 = params[1][i];
+
+          val01A = _mm_min_epi32(val01A, limit01);
+          val01B = _mm_min_epi32(val01B, limit01);
+          val01C = _mm_min_epi32(val01C, limit01);
+          val01D = _mm_min_epi32(val01D, limit01);
+
+          limit01 = _mm_sub_epi32(zeros, limit01);
+
+          val01A = _mm_max_epi32(val01A, limit01);
+          val01B = _mm_max_epi32(val01B, limit01);
+          val01C = _mm_max_epi32(val01C, limit01);
+          val01D = _mm_max_epi32(val01D, limit01);
+
+          val01A = _mm_add_epi32(val01A, val01C);
+          val01B = _mm_add_epi32(val01B, val01D);
+
+          const __m128i coeff01 = params[0][i];
+
+          val01A = _mm_mullo_epi32(val01A, coeff01);
+          val01B = _mm_mullo_epi32(val01B, coeff01);
+
+          accum = _mm_add_epi32(accum, _mm_hadd_epi32(val01A, val01B));
+        };
+
+
+        process2coeffs(0, img5 + 0, img6 + 0, img3 + 1, img4 - 1);
+        process2coeffs(1, img3 + 0, img4 + 0, img3 - 1, img4 + 1);
+        process2coeffs(2, img1 + 2, img2 - 2, img1 + 1, img2 - 1);
+        process2coeffs(3, img1 + 0, img2 + 0, img1 - 1, img2 + 1);
+        process2coeffs(4, img1 - 2, img2 + 2, img0 + 3, img0 - 3);
+        process2coeffs(5, img0 + 2, img0 - 2, img0 + 1, img0 - 1);
+
+
+        bool isNearVBabove = yVb < vbPos && (yVb >= vbPos - 1);
+        bool isNearVBbelow = yVb >= vbPos && (yVb <= vbPos);
+        if (!(isNearVBabove || isNearVBbelow))
+        {
+          accum = _mm_srai_epi32(accum, shift);
+        }
+        else
+        {
+          accum = _mm_srai_epi32(_mm_add_epi32(accum, offset1), shift + 3);
+        }
+        accum = _mm_add_epi32(accum, cur);
+        accum = _mm_min_epi32(max, _mm_max_epi32(accum, min));
+
+        _mm_storeu_si128((__m128i *) (dst + ii * dstStride + j), accum);
+      }
+    }
+
+    src += srcStride * step_y;
+    dst += dstStride * step_y;
+  }
+}
+
+#ifdef USE_AVX2
+static void simdFilter7x7Blk_HBD_AVX2(AlfClassifier **classifier, const PelUnitBuf &recDst, const CPelUnitBuf &recSrc,
+  const Area &blkDst, const Area &blk, const ComponentID compId, const short *filterSet,
+  const Pel *fClipSet, const ClpRng &clpRng, CodingStructure &cs, const int vbCTUHeight,
+  int vbPos)
+{
+  CHECK((vbCTUHeight & (vbCTUHeight - 1)) != 0, "vbCTUHeight must be a power of 2");
+  CHECK(isChroma(compId), "7x7 ALF filter is meant for luma only");
+
+  const CPelBuf srcBuffer = recSrc.get(compId);
+  PelBuf        dstBuffer = recDst.get(compId);
+
+  const size_t srcStride = srcBuffer.stride;
+  const size_t dstStride = dstBuffer.stride;
+
+  constexpr int shift = AdaptiveLoopFilter::m_NUM_BITS - 1;
+  constexpr int round = 1 << (shift - 1);
+
+  const size_t width = blk.width;
+  const size_t height = blk.height;
+
+  constexpr size_t step_x = 8;
+  constexpr size_t step_y = 4;
+
+  CHECK(blk.y % step_y, "Wrong startHeight in filtering");
+  CHECK(blk.x % step_x, "Wrong startWidth in filtering");
+  CHECK(height % step_y, "Wrong endHeight in filtering");
+  CHECK(width % step_x, "Wrong endWidth in filtering");
+
+  const Pel *src = srcBuffer.buf + blk.y * srcStride + blk.x;
+  Pel *      dst = dstBuffer.buf + blkDst.y * dstStride + blkDst.x;
+
+  const __m256i offset = _mm256_set1_epi32(round);
+  const __m256i offset1 = _mm256_set1_epi32((1 << ((shift + 3) - 1)) - round);
+  const __m256i min = _mm256_set1_epi32(clpRng.min);
+  const __m256i max = _mm256_set1_epi32(clpRng.max);
+  const __m256i zeros = _mm256_setzero_si256();
+
+  const __m128i cmp1 = _mm_set1_epi8((char)0x0f);
+  const __m128i cmp2 = _mm_set1_epi8((char)0xf0);
+  const __m128i mask1 = _mm_set1_epi8((char)0x10);
+  const __m128i mask2 = _mm_set1_epi8((char)0x20);
+
+  for (size_t i = 0; i < height; i += step_y)  // + 4
+  {
+    const AlfClassifier *pClass = classifier[blkDst.y + i] + blkDst.x;
+
+    for (size_t j = 0; j < width; j += step_x)  // + 8
+    {
+      __m128i params[2][2][6];
+
+      for (int k = 0; k < 2; k++)
+      {
+        const AlfClassifier &cl = pClass[j + (k << 2)];
+        const int transposeIdx = cl.transposeIdx;
+        const int classIdx = cl.classIdx;
+
+        __m128i rawCoeff0, rawCoeff1;
+        rawCoeff0 = _mm_lddqu_si128((const __m128i *) (filterSet + classIdx * MAX_NUM_ALF_LUMA_COEFF));
+        rawCoeff1 = _mm_loadl_epi64((const __m128i *) (filterSet + classIdx * MAX_NUM_ALF_LUMA_COEFF + 8));
+
+        const __m128i s0 = _mm_lddqu_si128((const __m128i *) shuffleTab[transposeIdx][0]);
+        const __m128i s1 = _mm_xor_si128(s0, _mm_set1_epi8((char)0x80));
+        const __m128i s2 = _mm_lddqu_si128((const __m128i *) shuffleTab[transposeIdx][1]);
+        const __m128i s3 = _mm_xor_si128(s2, _mm_set1_epi8((char)0x80));
+
+        const __m128i rawCoeffLo = _mm_or_si128(_mm_shuffle_epi8(rawCoeff0, s0), _mm_shuffle_epi8(rawCoeff1, s1));
+        const __m128i rawCoeffHi = _mm_or_si128(_mm_shuffle_epi8(rawCoeff0, s2), _mm_shuffle_epi8(rawCoeff1, s3));
+
+        params[k][0][0] = _mm_cvtepi16_epi32(_mm_shuffle_epi32(rawCoeffLo, 0x00));
+        params[k][0][1] = _mm_cvtepi16_epi32(_mm_shuffle_epi32(rawCoeffLo, 0x55));
+        params[k][0][2] = _mm_cvtepi16_epi32(_mm_shuffle_epi32(rawCoeffLo, 0xaa));
+        params[k][0][3] = _mm_cvtepi16_epi32(_mm_shuffle_epi32(rawCoeffLo, 0xff));
+        params[k][0][4] = _mm_cvtepi16_epi32(_mm_shuffle_epi32(rawCoeffHi, 0x00));
+        params[k][0][5] = _mm_cvtepi16_epi32(_mm_shuffle_epi32(rawCoeffHi, 0x55));
+
+        __m128i rawClip0, rawClip1, rawClip2;
+        rawClip0 = _mm_lddqu_si128((const __m128i *) (fClipSet + classIdx * MAX_NUM_ALF_LUMA_COEFF));
+        rawClip1 = _mm_lddqu_si128((const __m128i *) (fClipSet + classIdx * MAX_NUM_ALF_LUMA_COEFF + 4));
+        rawClip2 = _mm_lddqu_si128((const __m128i *) (fClipSet + classIdx * MAX_NUM_ALF_LUMA_COEFF + 8));
+
+        __m128i mask;
+        __m128i s00, s01, s02, s10, s11, s12, s20, s21, s22;
+        __m128i src0 = _mm_lddqu_si128((const __m128i *) shuffleTab32[transposeIdx][0]);
+        mask = _mm_and_si128(_mm_cmpgt_epi8(src0, cmp1), cmp2);
+        s00 = _mm_or_si128(src0, mask);
+        s01 = _mm_xor_si128(src0, mask1);
+        mask = _mm_and_si128(_mm_cmpgt_epi8(s01, cmp1), cmp2);
+        s01 = _mm_or_si128(s01, mask);
+        s02 = _mm_xor_si128(src0, mask2);
+        mask = _mm_and_si128(_mm_cmpgt_epi8(s02, cmp1), cmp2);
+        s02 = _mm_or_si128(s02, mask);
+
+        __m128i src1 = _mm_lddqu_si128((const __m128i *) shuffleTab32[transposeIdx][1]);
+        mask = _mm_and_si128(_mm_cmpgt_epi8(src1, cmp1), cmp2);
+        s10 = _mm_or_si128(src1, mask);
+        s11 = _mm_xor_si128(src1, mask1);
+        mask = _mm_and_si128(_mm_cmpgt_epi8(s11, cmp1), cmp2);
+        s11 = _mm_or_si128(s11, mask);
+        s12 = _mm_xor_si128(src1, mask2);
+        mask = _mm_and_si128(_mm_cmpgt_epi8(s12, cmp1), cmp2);
+        s12 = _mm_or_si128(s12, mask);
+
+        __m128i src2 = _mm_lddqu_si128((const __m128i *) shuffleTab32[transposeIdx][2]);
+        mask = _mm_and_si128(_mm_cmpgt_epi8(src2, cmp1), cmp2);
+        s20 = _mm_or_si128(src2, mask);
+        s21 = _mm_xor_si128(src2, mask1);
+        mask = _mm_and_si128(_mm_cmpgt_epi8(s21, cmp1), cmp2);
+        s21 = _mm_or_si128(s21, mask);
+        s22 = _mm_xor_si128(src2, mask2);
+        mask = _mm_and_si128(_mm_cmpgt_epi8(s22, cmp1), cmp2);
+        s22 = _mm_or_si128(s22, mask);
+
+        const __m128i rawClipLo = _mm_or_si128(_mm_or_si128(_mm_shuffle_epi8(rawClip0, s00), _mm_shuffle_epi8(rawClip1, s01)), _mm_shuffle_epi8(rawClip2, s02));
+        const __m128i rawClipMl = _mm_or_si128(_mm_or_si128(_mm_shuffle_epi8(rawClip0, s10), _mm_shuffle_epi8(rawClip1, s11)), _mm_shuffle_epi8(rawClip2, s12));
+        const __m128i rawClipHi = _mm_or_si128(_mm_or_si128(_mm_shuffle_epi8(rawClip0, s20), _mm_shuffle_epi8(rawClip1, s21)), _mm_shuffle_epi8(rawClip2, s22));
+
+        params[k][1][0] = _mm_shuffle_epi32(rawClipLo, 0x44);
+        params[k][1][1] = _mm_shuffle_epi32(rawClipLo, 0xee);
+        params[k][1][2] = _mm_shuffle_epi32(rawClipMl, 0x44);
+        params[k][1][3] = _mm_shuffle_epi32(rawClipMl, 0xee);
+        params[k][1][4] = _mm_shuffle_epi32(rawClipHi, 0x44);
+        params[k][1][5] = _mm_shuffle_epi32(rawClipHi, 0xee);
+      }
+
+      for (size_t ii = 0; ii < step_y; ii++)
+      {
+        const Pel *img0, *img1, *img2, *img3, *img4, *img5, *img6;
+
+        img0 = src + j + ii * srcStride;
+        img1 = img0 + srcStride;
+        img2 = img0 - srcStride;
+        img3 = img1 + srcStride;
+        img4 = img2 - srcStride;
+        img5 = img3 + srcStride;
+        img6 = img4 - srcStride;
+
+        const int yVb = (blkDst.y + i + ii) & (vbCTUHeight - 1);
+        if (yVb < vbPos && (yVb >= vbPos - 4))   // above
+        {
+          img1 = (yVb == vbPos - 1) ? img0 : img1;
+          img3 = (yVb >= vbPos - 2) ? img1 : img3;
+          img5 = (yVb >= vbPos - 3) ? img3 : img5;
+
+          img2 = (yVb == vbPos - 1) ? img0 : img2;
+          img4 = (yVb >= vbPos - 2) ? img2 : img4;
+          img6 = (yVb >= vbPos - 3) ? img4 : img6;
+        }
+        else if (yVb >= vbPos && (yVb <= vbPos + 3))   // bottom
+        {
+          img2 = (yVb == vbPos) ? img0 : img2;
+          img4 = (yVb <= vbPos + 1) ? img2 : img4;
+          img6 = (yVb <= vbPos + 2) ? img4 : img6;
+
+          img1 = (yVb == vbPos) ? img0 : img1;
+          img3 = (yVb <= vbPos + 1) ? img1 : img3;
+          img5 = (yVb <= vbPos + 2) ? img3 : img5;
+        }
+        __m256i cur = _mm256_lddqu_si256((const __m256i *) img0);
+        __m256i accum = offset;
+
+        auto process2coeffs = [&](const int i, const Pel *ptr0, const Pel *ptr1, const Pel *ptr2, const Pel *ptr3) {
+          const __m256i val00 = _mm256_sub_epi32(_mm256_lddqu_si256((const __m256i *) ptr0), cur);
+          const __m256i val10 = _mm256_sub_epi32(_mm256_lddqu_si256((const __m256i *) ptr2), cur);
+          const __m256i val01 = _mm256_sub_epi32(_mm256_lddqu_si256((const __m256i *) ptr1), cur);
+          const __m256i val11 = _mm256_sub_epi32(_mm256_lddqu_si256((const __m256i *) ptr3), cur);
+
+          __m256i val01A = _mm256_unpacklo_epi32(val00, val10);
+          __m256i val01B = _mm256_unpackhi_epi32(val00, val10);
+          __m256i val01C = _mm256_unpacklo_epi32(val01, val11);
+          __m256i val01D = _mm256_unpackhi_epi32(val01, val11);
+
+          __m256i limit01 = _mm256_inserti128_si256(_mm256_castsi128_si256(params[0][1][i]), params[1][1][i], 1);
+
+          val01A = _mm256_min_epi32(val01A, limit01);
+          val01B = _mm256_min_epi32(val01B, limit01);
+          val01C = _mm256_min_epi32(val01C, limit01);
+          val01D = _mm256_min_epi32(val01D, limit01);
+
+          limit01 = _mm256_sub_epi32(zeros, limit01);
+
+          val01A = _mm256_max_epi32(val01A, limit01);
+          val01B = _mm256_max_epi32(val01B, limit01);
+          val01C = _mm256_max_epi32(val01C, limit01);
+          val01D = _mm256_max_epi32(val01D, limit01);
+
+          val01A = _mm256_add_epi32(val01A, val01C);
+          val01B = _mm256_add_epi32(val01B, val01D);
+
+          const __m256i coeff01 = _mm256_inserti128_si256(_mm256_castsi128_si256(params[0][0][i]), params[1][0][i], 1);
+
+          val01A = _mm256_mullo_epi32(val01A, coeff01);
+          val01B = _mm256_mullo_epi32(val01B, coeff01);
+
+          accum = _mm256_add_epi32(accum, _mm256_hadd_epi32(val01A, val01B));
+        };
+
+        process2coeffs(0, img5 + 0, img6 + 0, img3 + 1, img4 - 1);
+        process2coeffs(1, img3 + 0, img4 + 0, img3 - 1, img4 + 1);
+        process2coeffs(2, img1 + 2, img2 - 2, img1 + 1, img2 - 1);
+        process2coeffs(3, img1 + 0, img2 + 0, img1 - 1, img2 + 1);
+        process2coeffs(4, img1 - 2, img2 + 2, img0 + 3, img0 - 3);
+        process2coeffs(5, img0 + 2, img0 - 2, img0 + 1, img0 - 1);
+
+
+        bool isNearVBabove = yVb < vbPos && (yVb >= vbPos - 1);
+        bool isNearVBbelow = yVb >= vbPos && (yVb <= vbPos);
+        if (!(isNearVBabove || isNearVBbelow))
+        {
+          accum = _mm256_srai_epi32(accum, shift);
+        }
+        else
+        {
+          accum = _mm256_srai_epi32(_mm256_add_epi32(accum, offset1), shift + 3);
+        }
+        accum = _mm256_add_epi32(accum, cur);
+        accum = _mm256_min_epi32(max, _mm256_max_epi32(accum, min));
+
+        _mm256_store_si256((__m256i *) (dst + ii * dstStride + j), accum);
+      }
+    }
+
+    src += srcStride * step_y;
+    dst += dstStride * step_y;
+  }
+}
+#endif
+#else
 template<X86_VEXT vext>
 static void simdFilter7x7Blk(AlfClassifier **classifier, const PelUnitBuf &recDst, const CPelUnitBuf &recSrc,
   const Area &blkDst, const Area &blk, const ComponentID compId, const short *filterSet,
@@ -672,13 +1669,29 @@ static void simdFilter7x7Blk(AlfClassifier **classifier, const PelUnitBuf &recDs
     dst += dstStride * STEP_Y;
   }
 }
-
+#endif
 template <X86_VEXT vext>
 void AdaptiveLoopFilter::_initAdaptiveLoopFilterX86()
 {
+#if RExt__HIGH_BIT_DEPTH_SUPPORT
+  m_deriveClassificationBlk = simdDeriveClassificationBlk_HBD;
+#ifdef USE_AVX2
+  if (vext >= AVX2)
+  {
+    m_filter5x5Blk = simdFilter5x5Blk_HBD_AVX2;
+    m_filter7x7Blk = simdFilter7x7Blk_HBD_AVX2;
+  }
+  else
+#endif
+  {
+    m_filter5x5Blk = simdFilter5x5Blk_HBD;
+    m_filter7x7Blk = simdFilter7x7Blk_HBD;
+  }
+#else
   m_deriveClassificationBlk = simdDeriveClassificationBlk<vext>;
   m_filter5x5Blk = simdFilter5x5Blk<vext>;
   m_filter7x7Blk = simdFilter7x7Blk<vext>;
+#endif
 }
 
 template void AdaptiveLoopFilter::_initAdaptiveLoopFilterX86<SIMDX86>();
diff --git a/source/Lib/CommonLib/x86/AffineGradientSearchX86.h b/source/Lib/CommonLib/x86/AffineGradientSearchX86.h
index bc8676e25..f6a3d95d7 100644
--- a/source/Lib/CommonLib/x86/AffineGradientSearchX86.h
+++ b/source/Lib/CommonLib/x86/AffineGradientSearchX86.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -306,14 +306,468 @@ static void simdEqualCoeffComputer( Pel *pResidue, int residueStride, int **ppDe
     idx2 -= (width);
   }
 }
+#if RExt__HIGH_BIT_DEPTH_SUPPORT
+template<X86_VEXT vext>
+static void simdHorizontalSobelFilter_HBD_SIMD(Pel *const pPred, const int predStride, int *const pDerivate, const int derivateBufStride, const int width, const int height)
+{
+  __m128i pred[4];
+  __m128i pred2x[2];
+  __m128i intermediates[4];
+  __m128i derivate[2];
+
+  assert(!(height % 2));
+  assert(!(width % 4));
+
+  /* Derivates of the rows and columns at the boundary are done at the end of this function */
+  /* The value of col and row indicate the columns and rows for which the derivates have already been computed */
+
+  int col = 1;
+#if USE_AVX2
+  if (vext >= AVX2)
+  {
+    __m256i pred256[4];
+    __m256i pred2x256[2];
+    __m256i intermediates256[4];
+    __m256i derivate256[2];
+
+    for (; (col + 6) < width; col += 6)
+    {
+      pred256[0] = _mm256_lddqu_si256((__m256i *)&pPred[col - 1]);
+      pred256[1] = _mm256_lddqu_si256((__m256i *)&pPred[predStride + col - 1]);
+
+      for (int row = 1; row < (height - 1); row += 2)
+      {
+        pred256[2] = _mm256_lddqu_si256((__m256i *)&pPred[(row + 1) * predStride + col - 1]);
+        pred256[3] = _mm256_lddqu_si256((__m256i *)&pPred[(row + 2) * predStride + col - 1]);
+
+        pred2x256[0] = _mm256_slli_epi32(pred256[1], 1);
+        pred2x256[1] = _mm256_slli_epi32(pred256[2], 1);
+
+        intermediates256[0] = _mm256_add_epi32(pred2x256[0], pred256[0]);
+        intermediates256[2] = _mm256_add_epi32(pred2x256[1], pred256[1]);
+
+        intermediates256[0] = _mm256_add_epi32(intermediates256[0], pred256[2]);
+        intermediates256[2] = _mm256_add_epi32(intermediates256[2], pred256[3]);
+
+        pred256[0] = pred256[2];
+        pred256[1] = pred256[3];
+
+        intermediates256[1] = _mm256_permute4x64_epi64(intermediates256[0], 0xf9);
+        intermediates256[3] = _mm256_permute4x64_epi64(intermediates256[2], 0xf9);
+
+        derivate256[0] = _mm256_sub_epi32(intermediates256[1], intermediates256[0]);
+        derivate256[1] = _mm256_sub_epi32(intermediates256[3], intermediates256[2]);
+
+        _mm_storeu_si128((__m128i *)&pDerivate[col + row * derivateBufStride], _mm256_castsi256_si128(derivate256[0]));
+        _mm_storel_epi64((__m128i *)&pDerivate[col + 4 + row * derivateBufStride], _mm256_castsi256_si128(_mm256_permute4x64_epi64(derivate256[0], 0xaa)));
+
+        _mm_storeu_si128((__m128i *)&pDerivate[col + (row + 1) * derivateBufStride], _mm256_castsi256_si128(derivate256[1]));
+        _mm_storel_epi64((__m128i *)&pDerivate[col + 4 + (row + 1) * derivateBufStride], _mm256_castsi256_si128(_mm256_permute4x64_epi64(derivate256[1], 0xaa)));
+      }
+    }
+  }
+#endif
+
+  for (; (col + 2) < width; col += 2)
+  {
+    pred[0] = _mm_lddqu_si128((__m128i *)&pPred[col - 1]);
+    pred[1] = _mm_lddqu_si128((__m128i *)&pPred[predStride + col - 1]);
+
+    for (int row = 1; row < (height - 1); row += 2)
+    {
+      pred[2] = _mm_lddqu_si128((__m128i *)&pPred[(row + 1) * predStride + col - 1]);
+      pred[3] = _mm_lddqu_si128((__m128i *)&pPred[(row + 2) * predStride + col - 1]);
+
+      pred2x[0] = _mm_slli_epi32(pred[1], 1);
+      pred2x[1] = _mm_slli_epi32(pred[2], 1);
+
+      intermediates[0] = _mm_add_epi32(pred2x[0], pred[0]);
+      intermediates[2] = _mm_add_epi32(pred2x[1], pred[1]);
+
+      intermediates[0] = _mm_add_epi32(intermediates[0], pred[2]);
+      intermediates[2] = _mm_add_epi32(intermediates[2], pred[3]);
+
+      pred[0] = pred[2];
+      pred[1] = pred[3];
+
+      intermediates[1] = _mm_srli_si128(intermediates[0], 8);
+      intermediates[3] = _mm_srli_si128(intermediates[2], 8);
+
+      derivate[0] = _mm_sub_epi32(intermediates[1], intermediates[0]);
+      derivate[1] = _mm_sub_epi32(intermediates[3], intermediates[2]);
+
+      _mm_storel_epi64((__m128i *)&pDerivate[col + row * derivateBufStride], derivate[0]);
+      _mm_storel_epi64((__m128i *)&pDerivate[col + (row + 1) * derivateBufStride], derivate[1]);
+    }
+  }
+
+  for (int j = 1; j < (height - 1); j++)
+  {
+    pDerivate[j * derivateBufStride] = pDerivate[j * derivateBufStride + 1];
+    pDerivate[j * derivateBufStride + (width - 1)] = pDerivate[j * derivateBufStride + (width - 2)];
+  }
+
+  memcpy(pDerivate, pDerivate + derivateBufStride, width * sizeof(pDerivate[0]));
+  memcpy(pDerivate + (height - 1) * derivateBufStride, pDerivate + (height - 2) * derivateBufStride, width * sizeof(pDerivate[0])
+  );
+}
+
+template<X86_VEXT vext>
+static void simdVerticalSobelFilter_HBD_SIMD(Pel *const pPred, const int predStride, int *const pDerivate, const int derivateBufStride, const int width, const int height)
+{
+  __m128i pred[4];
+  __m128i intermediates[6];
+  __m128i derivate[2];
+
+  assert(!(height % 2));
+  assert(!(width % 4));
+
+  int col = 1;
+#if USE_AVX2
+  if (vext >= AVX2)
+  {
+    __m256i pred256[4];
+    __m256i intermediates256[6];
+    __m256i derivate256[2];
+    __m256i shuffle256 = _mm256_set_epi32(0x00000007, 0x00000007, 0x00000006, 0x00000005, 0x00000004, 0x00000003, 0x00000002, 0x00000001);
+
+    for (; (col + 6) < width; col += 6)
+    {
+      pred256[0] = _mm256_lddqu_si256((__m256i *)&pPred[col - 1]);
+      pred256[1] = _mm256_lddqu_si256((__m256i *)&pPred[predStride + col - 1]);
+
+      for (int row = 1; row < (height - 1); row += 2)
+      {
+        pred256[2] = _mm256_lddqu_si256((__m256i *)&pPred[(row + 1) * predStride + col - 1]);
+        pred256[3] = _mm256_lddqu_si256((__m256i *)&pPred[(row + 2) * predStride + col - 1]);
+
+        intermediates256[0] = _mm256_sub_epi32(pred256[2], pred256[0]);
+        intermediates256[3] = _mm256_sub_epi32(pred256[3], pred256[1]);
+
+        pred256[0] = pred256[2];
+        pred256[1] = pred256[3];
+
+        intermediates256[1] = _mm256_permutevar8x32_epi32(intermediates256[0], shuffle256);
+        intermediates256[4] = _mm256_permutevar8x32_epi32(intermediates256[3], shuffle256);
+        intermediates256[2] = _mm256_permute4x64_epi64(intermediates256[0], 0xf9);
+        intermediates256[5] = _mm256_permute4x64_epi64(intermediates256[3], 0xf9);
+
+        intermediates256[1] = _mm256_slli_epi32(intermediates256[1], 1);
+        intermediates256[4] = _mm256_slli_epi32(intermediates256[4], 1);
+
+        intermediates256[0] = _mm256_add_epi32(intermediates256[0], intermediates256[2]);
+        intermediates256[3] = _mm256_add_epi32(intermediates256[3], intermediates256[5]);
+
+        derivate256[0] = _mm256_add_epi32(intermediates256[0], intermediates256[1]);
+        derivate256[1] = _mm256_add_epi32(intermediates256[3], intermediates256[4]);
+
+        _mm_storeu_si128((__m128i *)&pDerivate[col + row * derivateBufStride], _mm256_castsi256_si128(derivate256[0]));
+        _mm_storel_epi64((__m128i *)&pDerivate[col + 4 + row * derivateBufStride], _mm256_castsi256_si128(_mm256_permute4x64_epi64(derivate256[0], 0xaa)));
+
+        _mm_storeu_si128((__m128i *)&pDerivate[col + (row + 1) * derivateBufStride], _mm256_castsi256_si128(derivate256[1]));
+        _mm_storel_epi64((__m128i *)&pDerivate[col + 4 + (row + 1) * derivateBufStride], _mm256_castsi256_si128(_mm256_permute4x64_epi64(derivate256[1], 0xaa)));
+      }
+    }
+  }
+#endif
+
+  /* Derivates of the rows and columns at the boundary are done at the end of this function */
+  /* The value of col and row indicate the columns and rows for which the derivates have already been computed */
+  for (; (col + 2) < width; col += 2)
+  {
+    pred[0] = _mm_lddqu_si128((__m128i *)&pPred[col - 1]);
+    pred[1] = _mm_lddqu_si128((__m128i *)&pPred[predStride + col - 1]);
+
+    for (int row = 1; row < (height - 1); row += 2)
+    {
+      pred[2] = _mm_lddqu_si128((__m128i *)&pPred[(row + 1) * predStride + col - 1]);
+      pred[3] = _mm_lddqu_si128((__m128i *)&pPred[(row + 2) * predStride + col - 1]);
+
+      intermediates[0] = _mm_sub_epi32(pred[2], pred[0]);
+      intermediates[3] = _mm_sub_epi32(pred[3], pred[1]);
+
+      pred[0] = pred[2];
+      pred[1] = pred[3];
+
+      intermediates[1] = _mm_srli_si128(intermediates[0], 4);
+      intermediates[4] = _mm_srli_si128(intermediates[3], 4);
+      intermediates[2] = _mm_srli_si128(intermediates[0], 8);
+      intermediates[5] = _mm_srli_si128(intermediates[3], 8);
+
+      intermediates[1] = _mm_slli_epi32(intermediates[1], 1);
+      intermediates[4] = _mm_slli_epi32(intermediates[4], 1);
+
+      intermediates[0] = _mm_add_epi32(intermediates[0], intermediates[2]);
+      intermediates[3] = _mm_add_epi32(intermediates[3], intermediates[5]);
+
+      derivate[0] = _mm_add_epi32(intermediates[0], intermediates[1]);
+      derivate[1] = _mm_add_epi32(intermediates[3], intermediates[4]);
+
+      _mm_storel_epi64((__m128i *)&pDerivate[col + row * derivateBufStride], derivate[0]);
+      _mm_storel_epi64((__m128i *)&pDerivate[col + (row + 1) * derivateBufStride], derivate[1]);
+    }
+  }
+
+  for (int j = 1; j < (height - 1); j++)
+  {
+    pDerivate[j * derivateBufStride] = pDerivate[j * derivateBufStride + 1];
+    pDerivate[j * derivateBufStride + (width - 1)] = pDerivate[j * derivateBufStride + (width - 2)];
+  }
+
+  memcpy(pDerivate, pDerivate + derivateBufStride, width * sizeof(pDerivate[0]));
+  memcpy(pDerivate + (height - 1) * derivateBufStride, pDerivate + (height - 2) * derivateBufStride, width * sizeof(pDerivate[0]));
+}
+
+#define CALC_EQUAL_COEFF_16PXLS(x1,x2,y1,y2,tmp0,tmp1,tmp2,tmp3,inter0,inter1,inter2,inter3,loadLocation)         \
+{                                                                                                                 \
+inter0 = _mm256_mul_epi32(x1, y1);                                                                                \
+inter1 = _mm256_mul_epi32(tmp0, tmp2);                                                                            \
+inter2 = _mm256_mul_epi32(x2, y2);                                                                                \
+inter3 = _mm256_mul_epi32(tmp1, tmp3);                                                                            \
+inter2 = _mm256_add_epi64(inter0, inter2);                                                                        \
+inter3 = _mm256_add_epi64(inter1, inter3);                                                                        \
+inter0 = _mm256_castsi128_si256(_mm_loadl_epi64(loadLocation));                                                   \
+inter3 = _mm256_add_epi64(inter2, inter3);                                                                        \
+inter1 = _mm256_permute4x64_epi64(inter3, 0x4e);                                                                  \
+inter3 = _mm256_add_epi64(inter1, inter3);                                                                        \
+inter1 = _mm256_permute4x64_epi64(inter3, 0xb1);                                                                  \
+inter3 = _mm256_add_epi64(inter1, inter3);                                                                        \
+inter3 = _mm256_add_epi64(inter0, inter3);                                                                        \
+}
+
+template<X86_VEXT vext>
+static void simdEqualCoeffComputer_HBD_SIMD(Pel *pResidue, int residueStride, int **ppDerivate, int derivateBufStride, int64_t(*pEqualCoeff)[7], int width, int height, bool b6Param)
+{
+  int n = b6Param ? 6 : 4;
+  CHECK((width & 8), "width of affine block should be multiple of 8");
+
+#if USE_AVX2
+  if (vext >= AVX2)
+  {
+    int idx1 = -2 * derivateBufStride - 8;
+    int idx2 = -derivateBufStride - 8;
+
+    __m256i tmp[4];
+    __m256i intermediate[4];
+    __m256i residue[2];
+    __m256i coef[12];
+
+    // Add directly to indexes to get new index
+    __m256i four = _mm256_set1_epi32(4);
+    __m256i eight = _mm256_set1_epi32(8);
+    __m256i shuffle = _mm256_set_epi32(0x00000007, 0x00000007, 0x00000006, 0x00000005, 0x00000004, 0x00000003, 0x00000002, 0x00000001);
+    __m256i indxJ = _mm256_set1_epi32(-2);
+
+    for (int j = 0; j < height; j += 2)
+    {
+      if (!(j & 3))
+        indxJ = _mm256_add_epi32(indxJ, four);
+      __m256i indxK = _mm256_set_epi32(-2, -2, -2, -2, -6, -6, -6, -6);
+      idx1 += (derivateBufStride << 1);
+      idx2 += (derivateBufStride << 1);
+
+      for (int k = 0; k < width; k += 8)
+      {
+        idx1 += 8;
+        idx2 += 8;
+        indxK = _mm256_add_epi32(indxK, eight);
+
+        if (b6Param)
+        {
+          // coef[0-5] for iC[0-5] of 1st row of pixels
+          coef[0] = _mm256_lddqu_si256((__m256i *)&ppDerivate[0][idx1]);
+          coef[2] = _mm256_lddqu_si256((__m256i *)&ppDerivate[1][idx1]);
+          coef[1] = _mm256_mullo_epi32(indxK, coef[0]);
+          coef[3] = _mm256_mullo_epi32(indxK, coef[2]);
+          coef[4] = _mm256_mullo_epi32(indxJ, coef[0]);
+          coef[5] = _mm256_mullo_epi32(indxJ, coef[2]);
+
+          // coef[6-11] for iC[0-5] of 2nd row of pixels
+          coef[6] = _mm256_lddqu_si256((__m256i *)&ppDerivate[0][idx2]);
+          coef[8] = _mm256_lddqu_si256((__m256i *)&ppDerivate[1][idx2]);
+          coef[7] = _mm256_mullo_epi32(indxK, coef[6]);
+          coef[9] = _mm256_mullo_epi32(indxK, coef[8]);
+          coef[10] = _mm256_mullo_epi32(indxJ, coef[6]);
+          coef[11] = _mm256_mullo_epi32(indxJ, coef[8]);
+        }
+        else
+        {
+          // coef[0-3] for iC[0-3] of 1st row of pixels
+          coef[0] = _mm256_lddqu_si256((__m256i *)&ppDerivate[0][idx1]);
+          coef[2] = _mm256_lddqu_si256((__m256i *)&ppDerivate[1][idx1]);
+          coef[1] = _mm256_mullo_epi32(indxK, coef[0]);
+          coef[3] = _mm256_mullo_epi32(indxJ, coef[0]);
+          tmp[0] = _mm256_mullo_epi32(indxJ, coef[2]);
+          tmp[1] = _mm256_mullo_epi32(indxK, coef[2]);
+          coef[1] = _mm256_add_epi32(coef[1], tmp[0]);
+          coef[3] = _mm256_sub_epi32(coef[3], tmp[1]);
+
+          // coef[4-7] for iC[0-3] of 1st row of pixels
+          coef[4] = _mm256_lddqu_si256((__m256i *)&ppDerivate[0][idx2]);
+          coef[6] = _mm256_lddqu_si256((__m256i *)&ppDerivate[1][idx2]);
+          coef[5] = _mm256_mullo_epi32(indxK, coef[4]);
+          coef[7] = _mm256_mullo_epi32(indxJ, coef[4]);
+          tmp[2] = _mm256_mullo_epi32(indxJ, coef[6]);
+          tmp[3] = _mm256_mullo_epi32(indxK, coef[6]);
+          coef[5] = _mm256_add_epi32(coef[5], tmp[2]);
+          coef[7] = _mm256_sub_epi32(coef[7], tmp[3]);
+        }
+
+        // Residue
+        residue[0] = _mm256_lddqu_si256((__m256i *)&pResidue[idx1]);
+        residue[1] = _mm256_lddqu_si256((__m256i *)&pResidue[idx2]);
+        residue[0] = _mm256_slli_epi32(residue[0], 3);
+        residue[1] = _mm256_slli_epi32(residue[1], 3);
+
+        // Calculation of coefficient matrix
+        for (int col = 0; col < n; col++)
+        {
+          tmp[0] = _mm256_permutevar8x32_epi32(coef[0 + col], shuffle);
+          tmp[1] = _mm256_permutevar8x32_epi32(coef[n + col], shuffle);
+          CALC_EQUAL_COEFF_16PXLS(coef[0 + col], coef[n + col], coef[0 + col], coef[n + col], tmp[0], tmp[1], tmp[0], tmp[1], intermediate[0], intermediate[1], intermediate[2], intermediate[3], (const __m128i*)&pEqualCoeff[col + 1][col]);
+          _mm_storel_epi64((__m128i*)&pEqualCoeff[col + 1][col], _mm256_castsi256_si128(intermediate[3]));
+
+          for (int row = col + 1; row < n; row++)
+          {
+            tmp[2] = _mm256_permutevar8x32_epi32(coef[0 + row], shuffle);
+            tmp[3] = _mm256_permutevar8x32_epi32(coef[n + row], shuffle);
+            CALC_EQUAL_COEFF_16PXLS(coef[0 + col], coef[n + col], coef[0 + row], coef[n + row], tmp[0], tmp[1], tmp[2], tmp[3], intermediate[0], intermediate[1], intermediate[2], intermediate[3], (const __m128i*)&pEqualCoeff[col + 1][row]);
+            _mm_storel_epi64((__m128i*)&pEqualCoeff[col + 1][row], _mm256_castsi256_si128(intermediate[3]));
+            _mm_storel_epi64((__m128i*)&pEqualCoeff[row + 1][col], _mm256_castsi256_si128(intermediate[3]));
+          }
+
+          tmp[2] = _mm256_permutevar8x32_epi32(residue[0], shuffle);
+          tmp[3] = _mm256_permutevar8x32_epi32(residue[1], shuffle);
+          CALC_EQUAL_COEFF_16PXLS(coef[0 + col], coef[n + col], residue[0], residue[1], tmp[0], tmp[1], tmp[2], tmp[3], intermediate[0], intermediate[1], intermediate[2], intermediate[3], (const __m128i*)&pEqualCoeff[col + 1][n]);
+          _mm_storel_epi64((__m128i*)&pEqualCoeff[col + 1][n], _mm256_castsi256_si128(intermediate[3]));
+        }
+      }
+
+      idx1 -= (width);
+      idx2 -= (width);
+    }
+  }
+  else
+#endif
+  {
+    int idx1 = -2 * derivateBufStride - 4;
+    int idx2 = -derivateBufStride - 4;
+
+    __m128i four;
+    __m128i tmp[4];
+    __m128i intermediate[4];
+    __m128i indxK, indxJ;
+    __m128i residue[2];
+    __m128i coef[12];
 
+    // Add directly to indexes to get new index
+    four = _mm_set1_epi32(4);
+    indxJ = _mm_set1_epi32(-2);
+
+    for (int j = 0; j < height; j += 2)
+    {
+      if (!(j & 3))
+        indxJ = _mm_add_epi32(indxJ, four);
+      indxK = _mm_set1_epi32(-2);
+      idx1 += (derivateBufStride << 1);
+      idx2 += (derivateBufStride << 1);
+
+      for (int k = 0; k < width; k += 4)
+      {
+        idx1 += 4;
+        idx2 += 4;
+        indxK = _mm_add_epi32(indxK, four);
+
+        if (b6Param)
+        {
+          // coef[0-5] for iC[0-5] of 1st row of pixels
+          coef[0] = _mm_lddqu_si128((const __m128i*)&ppDerivate[0][idx1]);
+          coef[2] = _mm_lddqu_si128((const __m128i*)&ppDerivate[1][idx1]);
+          coef[1] = _mm_mullo_epi32(indxK, coef[0]);
+          coef[3] = _mm_mullo_epi32(indxK, coef[2]);
+          coef[4] = _mm_mullo_epi32(indxJ, coef[0]);
+          coef[5] = _mm_mullo_epi32(indxJ, coef[2]);
+
+          // coef[6-11] for iC[0-5] of 2nd row of pixels
+          coef[6] = _mm_lddqu_si128((const __m128i*)&ppDerivate[0][idx2]);
+          coef[8] = _mm_lddqu_si128((const __m128i*)&ppDerivate[1][idx2]);
+          coef[7] = _mm_mullo_epi32(indxK, coef[6]);
+          coef[9] = _mm_mullo_epi32(indxK, coef[8]);
+          coef[10] = _mm_mullo_epi32(indxJ, coef[6]);
+          coef[11] = _mm_mullo_epi32(indxJ, coef[8]);
+        }
+        else
+        {
+          // coef[0-3] for iC[0-3] of 1st row of pixels
+          coef[0] = _mm_lddqu_si128((const __m128i*)&ppDerivate[0][idx1]);
+          coef[2] = _mm_lddqu_si128((const __m128i*)&ppDerivate[1][idx1]);
+          coef[1] = _mm_mullo_epi32(indxK, coef[0]);
+          coef[3] = _mm_mullo_epi32(indxJ, coef[0]);
+          tmp[0] = _mm_mullo_epi32(indxJ, coef[2]);
+          tmp[1] = _mm_mullo_epi32(indxK, coef[2]);
+          coef[1] = _mm_add_epi32(coef[1], tmp[0]);
+          coef[3] = _mm_sub_epi32(coef[3], tmp[1]);
+
+          // coef[4-7] for iC[0-3] of 1st row of pixels
+          coef[4] = _mm_lddqu_si128((const __m128i*)&ppDerivate[0][idx2]);
+          coef[6] = _mm_lddqu_si128((const __m128i*)&ppDerivate[1][idx2]);
+          coef[5] = _mm_mullo_epi32(indxK, coef[4]);
+          coef[7] = _mm_mullo_epi32(indxJ, coef[4]);
+          tmp[2] = _mm_mullo_epi32(indxJ, coef[6]);
+          tmp[3] = _mm_mullo_epi32(indxK, coef[6]);
+          coef[5] = _mm_add_epi32(coef[5], tmp[2]);
+          coef[7] = _mm_sub_epi32(coef[7], tmp[3]);
+        }
+
+        // Residue
+        residue[0] = _mm_lddqu_si128((__m128i *)&pResidue[idx1]);
+        residue[1] = _mm_lddqu_si128((__m128i *)&pResidue[idx2]);
+        residue[0] = _mm_slli_epi32(residue[0], 3);
+        residue[1] = _mm_slli_epi32(residue[1], 3);
+
+        // Calculation of coefficient matrix
+        for (int col = 0; col < n; col++)
+        {
+          tmp[0] = _mm_srli_si128(coef[0 + col], 4);
+          tmp[1] = _mm_srli_si128(coef[n + col], 4);
+          CALC_EQUAL_COEFF_8PXLS(coef[0 + col], coef[n + col], coef[0 + col], coef[n + col], tmp[0], tmp[1], tmp[0], tmp[1], intermediate[0], intermediate[1], intermediate[2], intermediate[3], (const __m128i*)&pEqualCoeff[col + 1][col]);
+          _mm_storel_epi64((__m128i*)&pEqualCoeff[col + 1][col], intermediate[3]);
+
+          for (int row = col + 1; row < n; row++)
+          {
+            tmp[2] = _mm_srli_si128(coef[0 + row], 4);
+            tmp[3] = _mm_srli_si128(coef[n + row], 4);
+            CALC_EQUAL_COEFF_8PXLS(coef[0 + col], coef[n + col], coef[0 + row], coef[n + row], tmp[0], tmp[1], tmp[2], tmp[3], intermediate[0], intermediate[1], intermediate[2], intermediate[3], (const __m128i*)&pEqualCoeff[col + 1][row]);
+            _mm_storel_epi64((__m128i*)&pEqualCoeff[col + 1][row], intermediate[3]);
+            _mm_storel_epi64((__m128i*)&pEqualCoeff[row + 1][col], intermediate[3]);
+          }
+
+          tmp[2] = _mm_srli_si128(residue[0], 4);
+          tmp[3] = _mm_srli_si128(residue[1], 4);
+          CALC_EQUAL_COEFF_8PXLS(coef[0 + col], coef[n + col], residue[0], residue[1], tmp[0], tmp[1], tmp[2], tmp[3], intermediate[0], intermediate[1], intermediate[2], intermediate[3], (const __m128i*)&pEqualCoeff[col + 1][n]);
+          _mm_storel_epi64((__m128i*)&pEqualCoeff[col + 1][n], intermediate[3]);
+        }
+      }
+
+      idx1 -= (width);
+      idx2 -= (width);
+    }
+  }
+}
+#endif
 
 template <X86_VEXT vext>
 void AffineGradientSearch::_initAffineGradientSearchX86()
 {
+#if RExt__HIGH_BIT_DEPTH_SUPPORT
+  m_HorizontalSobelFilter = simdHorizontalSobelFilter_HBD_SIMD<vext>;
+  m_VerticalSobelFilter = simdVerticalSobelFilter_HBD_SIMD<vext>;
+  m_EqualCoeffComputer = simdEqualCoeffComputer_HBD_SIMD<vext>;
+#else
   m_HorizontalSobelFilter = simdHorizontalSobelFilter<vext>;
   m_VerticalSobelFilter = simdVerticalSobelFilter<vext>;
   m_EqualCoeffComputer = simdEqualCoeffComputer<vext>;
+#endif
 }
 
 template void AffineGradientSearch::_initAffineGradientSearchX86<SIMDX86>();
diff --git a/source/Lib/CommonLib/x86/BufferX86.h b/source/Lib/CommonLib/x86/BufferX86.h
index c763a2977..9c49b1c56 100644
--- a/source/Lib/CommonLib/x86/BufferX86.h
+++ b/source/Lib/CommonLib/x86/BufferX86.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -224,7 +224,7 @@ void paddingSimd(Pel *dst, int stride, int width, int height, int padSize)
   }
   else
   {
-    CHECK(false, "padding size must be 1 or 2");
+    THROW("padding size must be 1 or 2");
   }
 }
 
@@ -477,7 +477,438 @@ void applyPROF_SSE(Pel* dstPel, int dstStride, const Pel* srcPel, int srcStride,
 #endif
   }
 }
+#if RExt__HIGH_BIT_DEPTH_SUPPORT
+template< X86_VEXT vext, bool PAD = true >
+void gradFilterHBD_SIMD(Pel* src, int srcStride, int width, int height, int gradStride, Pel* gradX, Pel* gradY, const int bitDepth)
+{
+  Pel* srcTmp = src + srcStride + 1;
+  Pel* gradXTmp = gradX + gradStride + 1;
+  Pel* gradYTmp = gradY + gradStride + 1;
+
+  int widthInside = width - 2 * BIO_EXTEND_SIZE;
+  int heightInside = height - 2 * BIO_EXTEND_SIZE;
+  int shift1 = 6;
+  assert((widthInside & 3) == 0);
+
+#ifdef USE_AVX2
+  if (vext >= AVX2)
+  {
+    for (int y = 0; y < heightInside; y++)
+    {
+      for (int x = 0; x < widthInside; x += 8)
+      {
+        __m256i mmPixTop = _mm256_srai_epi32(_mm256_lddqu_si256((__m256i*) (srcTmp + x - srcStride)), shift1);
+        __m256i mmPixBottom = _mm256_srai_epi32(_mm256_lddqu_si256((__m256i*) (srcTmp + x + srcStride)), shift1);
+        __m256i mmPixLeft = _mm256_srai_epi32(_mm256_lddqu_si256((__m256i*) (srcTmp + x - 1)), shift1);
+        __m256i mmPixRight = _mm256_srai_epi32(_mm256_lddqu_si256((__m256i*) (srcTmp + x + 1)), shift1);
+
+        __m256i mmGradVer = _mm256_sub_epi32(mmPixBottom, mmPixTop);
+        __m256i mmGradHor = _mm256_sub_epi32(mmPixRight, mmPixLeft);
+
+        _mm256_storeu_si256((__m256i *) (gradYTmp + x), mmGradVer);
+        _mm256_storeu_si256((__m256i *) (gradXTmp + x), mmGradHor);
+      }
+      gradXTmp += gradStride;
+      gradYTmp += gradStride;
+      srcTmp += srcStride;
+    }
+  }
+  else
+#endif
+  {
+    __m128i mmShift1 = _mm_cvtsi32_si128(shift1);
+    for (int y = 0; y < heightInside; y++)
+    {
+      for (int x = 0; x < widthInside; x += 4)
+      {
+        __m128i mmPixTop = _mm_sra_epi32(_mm_lddqu_si128((__m128i*) (srcTmp + x - srcStride)), mmShift1);
+        __m128i mmPixBottom = _mm_sra_epi32(_mm_lddqu_si128((__m128i*) (srcTmp + x + srcStride)), mmShift1);
+        __m128i mmPixLeft = _mm_sra_epi32(_mm_lddqu_si128((__m128i*) (srcTmp + x - 1)), mmShift1);
+        __m128i mmPixRight = _mm_sra_epi32(_mm_lddqu_si128((__m128i*) (srcTmp + x + 1)), mmShift1);
+
+        __m128i mmGradVer = _mm_sub_epi32(mmPixBottom, mmPixTop);
+        __m128i mmGradHor = _mm_sub_epi32(mmPixRight, mmPixLeft);
+
+        _mm_storeu_si128((__m128i *) (gradYTmp + x), mmGradVer);
+        _mm_storeu_si128((__m128i *) (gradXTmp + x), mmGradHor);
+      }
+      gradXTmp += gradStride;
+      gradYTmp += gradStride;
+      srcTmp += srcStride;
+    }
+  }
+
+  if (PAD)
+  {
+    gradXTmp = gradX + gradStride + 1;
+    gradYTmp = gradY + gradStride + 1;
+    for (int y = 0; y < heightInside; y++)
+    {
+      gradXTmp[-1] = gradXTmp[0];
+      gradXTmp[widthInside] = gradXTmp[widthInside - 1];
+      gradXTmp += gradStride;
+
+      gradYTmp[-1] = gradYTmp[0];
+      gradYTmp[widthInside] = gradYTmp[widthInside - 1];
+      gradYTmp += gradStride;
+    }
+
+    gradXTmp = gradX + gradStride;
+    gradYTmp = gradY + gradStride;
+    ::memcpy(gradXTmp - gradStride, gradXTmp, sizeof(Pel)*(width));
+    ::memcpy(gradXTmp + heightInside * gradStride, gradXTmp + (heightInside - 1)*gradStride, sizeof(Pel)*(width));
+    ::memcpy(gradYTmp - gradStride, gradYTmp, sizeof(Pel)*(width));
+    ::memcpy(gradYTmp + heightInside * gradStride, gradYTmp + (heightInside - 1)*gradStride, sizeof(Pel)*(width));
+  }
+}
+
+template< X86_VEXT vext >
+void calcBIOSumsHBD_SIMD(const Pel* srcY0Tmp, const Pel* srcY1Tmp, Pel* gradX0, Pel* gradX1, Pel* gradY0, Pel* gradY1, int xu, int yu, const int src0Stride, const int src1Stride, const int widthG, const int bitDepth, int* sumAbsGX, int* sumAbsGY, int* sumDIX, int* sumDIY, int* sumSignGY_GX)
+{
+  int shift4 = 4;
+  int shift5 = 1;
+
+#ifdef USE_AVX2
+  if (vext >= AVX2)
+  {
+    __m256i sumAbsGXTmp = _mm256_setzero_si256();
+    __m256i sumDIXTmp = _mm256_setzero_si256();
+    __m256i sumAbsGYTmp = _mm256_setzero_si256();
+    __m256i sumDIYTmp = _mm256_setzero_si256();
+    __m256i sumSignGyGxTmp = _mm256_setzero_si256();
+
+    for (int y = 0; y < 6; y++)
+    {
+      auto load6values = [](const Pel *ptr)
+      {
+        __m256i a = _mm256_castsi128_si256(_mm_lddqu_si128((__m128i *) ptr));
+        __m128i b = _mm_loadl_epi64((__m128i *)(ptr + 4));
+        return _mm256_inserti128_si256(a, b, 1);
+      };
+
+      __m256i shiftSrcY0Tmp = _mm256_srai_epi32(load6values(srcY0Tmp), shift4);  // srcY0Tmp[x] >> shift4
+      __m256i shiftSrcY1Tmp = _mm256_srai_epi32(load6values(srcY1Tmp), shift4);  // srcY1Tmp[x] >> shift4
+      __m256i loadGradX0 = load6values(gradX0);  // gradX0[x]
+      __m256i loadGradX1 = load6values(gradX1);  // gradX1[x]
+      __m256i loadGradY0 = load6values(gradY0);  // gradY0[x]
+      __m256i loadGradY1 = load6values(gradY1);  // gradY1[x]
+
+      __m256i subTemp1 = _mm256_sub_epi32(shiftSrcY1Tmp, shiftSrcY0Tmp);  // (srcY1Tmp[x] >> shift4) - (srcY0Tmp[x] >> shift4)
+      __m256i packTempX = _mm256_srai_epi32(_mm256_add_epi32(loadGradX0, loadGradX1), shift5);  // (gradX0[x] + gradX1[x]) >> shift5
+      __m256i packTempY = _mm256_srai_epi32(_mm256_add_epi32(loadGradY0, loadGradY1), shift5);  // (gradY0[x] + gradY1[x]) >> shift5
+      __m256i gX = _mm256_abs_epi32(packTempX);  // abs(tmpGX)
+      __m256i gY = _mm256_abs_epi32(packTempY);  // abs(tmpGY)
+      __m256i dIX = _mm256_sign_epi32(subTemp1, packTempX);  // (tmpGX < 0 ? -tmpDI : (tmpGX == 0 ? 0 : tmpDI))
+      __m256i dIY = _mm256_sign_epi32(subTemp1, packTempY);  // (tmpGY < 0 ? -tmpDI : (tmpGY == 0 ? 0 : tmpDI))
+      __m256i signGY_GX = _mm256_sign_epi32(packTempX, packTempY);  // (tmpGY < 0 ? -tmpGX : (tmpGY == 0 ? 0 : tmpGX))
+
+      sumAbsGXTmp = _mm256_add_epi32(sumAbsGXTmp, gX);
+      sumDIXTmp = _mm256_add_epi32(sumDIXTmp, dIX);
+      sumAbsGYTmp = _mm256_add_epi32(sumAbsGYTmp, gY);
+      sumDIYTmp = _mm256_add_epi32(sumDIYTmp, dIY);
+      sumSignGyGxTmp = _mm256_add_epi32(sumSignGyGxTmp, signGY_GX);
+
+      srcY0Tmp += src0Stride;
+      srcY1Tmp += src1Stride;
+      gradX0 += widthG;
+      gradX1 += widthG;
+      gradY0 += widthG;
+      gradY1 += widthG;
+    }
+
+    __m256i mm_gx_gy_l = _mm256_unpacklo_epi32(sumAbsGXTmp, sumAbsGYTmp);
+    __m256i mm_gx_gy_h = _mm256_unpackhi_epi32(sumAbsGXTmp, sumAbsGYTmp);
+    __m256i mm_dIx_dIy_l = _mm256_unpacklo_epi32(sumDIXTmp, sumDIYTmp);
+    __m256i mm_dIx_dIy_h = _mm256_unpackhi_epi32(sumDIXTmp, sumDIYTmp);
+    __m256i c1 = _mm256_unpacklo_epi64(mm_gx_gy_l, mm_dIx_dIy_l);
+    __m256i c2 = _mm256_unpackhi_epi64(mm_gx_gy_l, mm_dIx_dIy_l);
+    __m256i c3 = _mm256_unpacklo_epi64(mm_gx_gy_h, mm_dIx_dIy_h);
+    __m256i c4 = _mm256_unpackhi_epi64(mm_gx_gy_h, mm_dIx_dIy_h);
+
+    c1 = _mm256_add_epi32(c1, c2);
+    c1 = _mm256_add_epi32(c1, c3);
+    c1 = _mm256_add_epi32(c1, c4);
+    c1 = _mm256_add_epi32(c1, _mm256_permute4x64_epi64(c1, 0xee));
+    *sumAbsGX = _mm_cvtsi128_si32(_mm256_castsi256_si128(c1));
+    *sumAbsGY = _mm_cvtsi128_si32(_mm256_castsi256_si128(_mm256_shuffle_epi32(c1, 0x55)));
+    *sumDIX = _mm_cvtsi128_si32(_mm256_castsi256_si128(_mm256_shuffle_epi32(c1, 0xaa)));
+    *sumDIY = _mm_cvtsi128_si32(_mm256_castsi256_si128(_mm256_shuffle_epi32(c1, 0xff)));
+
+    sumSignGyGxTmp = _mm256_add_epi32(sumSignGyGxTmp, _mm256_permute4x64_epi64(sumSignGyGxTmp, 0x4e));   // 01001110
+    sumSignGyGxTmp = _mm256_add_epi32(sumSignGyGxTmp, _mm256_permute4x64_epi64(sumSignGyGxTmp, 0xb1));   // 10110001
+    sumSignGyGxTmp = _mm256_add_epi32(sumSignGyGxTmp, _mm256_shuffle_epi32(sumSignGyGxTmp, 0x55));
+    *sumSignGY_GX = _mm_cvtsi128_si32(_mm256_castsi256_si128(sumSignGyGxTmp));
+  }
+  else
+#endif
+  {
+    __m128i sumAbsGXTmp = _mm_setzero_si128();
+    __m128i sumDIXTmp = _mm_setzero_si128();
+    __m128i sumAbsGYTmp = _mm_setzero_si128();
+    __m128i sumDIYTmp = _mm_setzero_si128();
+    __m128i sumSignGyGxTmp = _mm_setzero_si128();
 
+    for (int y = 0; y < 6; y++)
+    {
+      // the first 4 samples
+      __m128i shiftSrcY0Tmp = _mm_srai_epi32(_mm_lddqu_si128((__m128i*)srcY0Tmp), shift4);  // srcY0Tmp[x] >> shift4
+      __m128i shiftSrcY1Tmp = _mm_srai_epi32(_mm_lddqu_si128((__m128i*)srcY1Tmp), shift4);  // srcY1Tmp[x] >> shift4
+      __m128i loadGradX0 = _mm_lddqu_si128((__m128i*)gradX0);  // gradX0[x]
+      __m128i loadGradX1 = _mm_lddqu_si128((__m128i*)gradX1);  // gradX1[x]
+      __m128i loadGradY0 = _mm_lddqu_si128((__m128i*)gradY0);  // gradY0[x]
+      __m128i loadGradY1 = _mm_lddqu_si128((__m128i*)gradY1);  // gradY1[x]
+
+      __m128i subTemp1 = _mm_sub_epi32(shiftSrcY1Tmp, shiftSrcY0Tmp);  // (srcY1Tmp[x] >> shift4) - (srcY0Tmp[x] >> shift4)
+      __m128i packTempX = _mm_srai_epi32(_mm_add_epi32(loadGradX0, loadGradX1), shift5);  // (gradX0[x] + gradX1[x]) >> shift5
+      __m128i packTempY = _mm_srai_epi32(_mm_add_epi32(loadGradY0, loadGradY1), shift5);  // (gradY0[x] + gradY1[x]) >> shift5
+      __m128i gX = _mm_abs_epi32(packTempX);  // abs(tmpGX)
+      __m128i gY = _mm_abs_epi32(packTempY);  // abs(tmpGY)
+      __m128i dIX = _mm_sign_epi32(subTemp1, packTempX);  // (tmpGX < 0 ? -tmpDI : (tmpGX == 0 ? 0 : tmpDI))
+      __m128i dIY = _mm_sign_epi32(subTemp1, packTempY);  // (tmpGY < 0 ? -tmpDI : (tmpGY == 0 ? 0 : tmpDI))
+      __m128i signGY_GX = _mm_sign_epi32(packTempX, packTempY);  // (tmpGY < 0 ? -tmpGX : (tmpGY == 0 ? 0 : tmpGX))
+
+      sumAbsGXTmp = _mm_add_epi32(sumAbsGXTmp, gX);
+      sumDIXTmp = _mm_add_epi32(sumDIXTmp, dIX);
+      sumAbsGYTmp = _mm_add_epi32(sumAbsGYTmp, gY);
+      sumDIYTmp = _mm_add_epi32(sumDIYTmp, dIY);
+      sumSignGyGxTmp = _mm_add_epi32(sumSignGyGxTmp, signGY_GX);
+
+      // the following two samples
+      shiftSrcY0Tmp = _mm_srai_epi32(_mm_cvtsi64_si128(*(long long*)(srcY0Tmp + 4)), shift4);  // srcY0Tmp[x] >> shift4
+      shiftSrcY1Tmp = _mm_srai_epi32(_mm_cvtsi64_si128(*(long long*)(srcY1Tmp + 4)), shift4);  // srcY1Tmp[x] >> shift4
+      loadGradX0 = _mm_cvtsi64_si128(*(long long*)(gradX0 + 4));  // gradX0[x]
+      loadGradX1 = _mm_cvtsi64_si128(*(long long*)(gradX1 + 4));  // gradX1[x]
+      loadGradY0 = _mm_cvtsi64_si128(*(long long*)(gradY0 + 4));  // gradY0[x]
+      loadGradY1 = _mm_cvtsi64_si128(*(long long*)(gradY1 + 4));  // gradY1[x]
+
+      subTemp1 = _mm_sub_epi32(shiftSrcY1Tmp, shiftSrcY0Tmp);  // (srcY1Tmp[x] >> shift4) - (srcY0Tmp[x] >> shift4)
+      packTempX = _mm_srai_epi32(_mm_add_epi32(loadGradX0, loadGradX1), shift5);  // (gradX0[x] + gradX1[x]) >> shift5
+      packTempY = _mm_srai_epi32(_mm_add_epi32(loadGradY0, loadGradY1), shift5);  // (gradY0[x] + gradY1[x]) >> shift5
+      gX = _mm_abs_epi32(packTempX);  // abs(tmpGX)
+      gY = _mm_abs_epi32(packTempY);  // abs(tmpGY)
+      dIX = _mm_sign_epi32(subTemp1, packTempX);  // (tmpGX < 0 ? -tmpDI : (tmpGX == 0 ? 0 : tmpDI))
+      dIY = _mm_sign_epi32(subTemp1, packTempY);  // (tmpGY < 0 ? -tmpDI : (tmpGY == 0 ? 0 : tmpDI))
+      signGY_GX = _mm_sign_epi32(packTempX, packTempY);  // (tmpGY < 0 ? -tmpGX : (tmpGY == 0 ? 0 : tmpGX))
+
+      sumAbsGXTmp = _mm_add_epi32(sumAbsGXTmp, gX);
+      sumDIXTmp = _mm_add_epi32(sumDIXTmp, dIX);
+      sumAbsGYTmp = _mm_add_epi32(sumAbsGYTmp, gY);
+      sumDIYTmp = _mm_add_epi32(sumDIYTmp, dIY);
+      sumSignGyGxTmp = _mm_add_epi32(sumSignGyGxTmp, signGY_GX);
+
+      srcY0Tmp += src0Stride;
+      srcY1Tmp += src1Stride;
+      gradX0 += widthG;
+      gradX1 += widthG;
+      gradY0 += widthG;
+      gradY1 += widthG;
+    }
+
+    __m128i a12 = _mm_unpacklo_epi32(sumAbsGXTmp, sumAbsGYTmp);
+    __m128i a3 = _mm_unpackhi_epi32(sumAbsGXTmp, sumAbsGYTmp);
+    __m128i b12 = _mm_unpacklo_epi32(sumDIXTmp, sumDIYTmp);
+    __m128i b3 = _mm_unpackhi_epi32(sumDIXTmp, sumDIYTmp);
+    __m128i c1 = _mm_unpacklo_epi64(a12, b12);
+    __m128i c2 = _mm_unpackhi_epi64(a12, b12);
+    __m128i c3 = _mm_unpacklo_epi64(a3, b3);
+    __m128i c4 = _mm_unpackhi_epi64(a3, b3);
+
+    c1 = _mm_add_epi32(c1, c2);
+    c1 = _mm_add_epi32(c1, c3);
+    c1 = _mm_add_epi32(c1, c4);
+
+    *sumAbsGX = _mm_cvtsi128_si32(c1);
+    *sumAbsGY = _mm_cvtsi128_si32(_mm_shuffle_epi32(c1, 0x55));
+    *sumDIX = _mm_cvtsi128_si32(_mm_shuffle_epi32(c1, 0xaa));
+    *sumDIY = _mm_cvtsi128_si32(_mm_shuffle_epi32(c1, 0xff));
+
+    sumSignGyGxTmp = _mm_add_epi32(sumSignGyGxTmp, _mm_shuffle_epi32(sumSignGyGxTmp, 0x4e));   // 01001110
+    sumSignGyGxTmp = _mm_add_epi32(sumSignGyGxTmp, _mm_shuffle_epi32(sumSignGyGxTmp, 0xb1));   // 10110001
+    *sumSignGY_GX = _mm_cvtsi128_si32(sumSignGyGxTmp);
+  }
+}
+
+template< X86_VEXT vext >
+void addBIOAvg4HBD_SIMD(const Pel* src0, int src0Stride, const Pel* src1, int src1Stride, Pel *dst, int dstStride, const Pel *gradX0, const Pel *gradX1, const Pel *gradY0, const Pel*gradY1, int gradStride, int width, int height, int tmpx, int tmpy, int shift, int offset, const ClpRng& clpRng)
+{
+#ifdef USE_AVX2
+  if (vext >= AVX2)
+  {
+    __m256i mm_tmpx = _mm256_set1_epi32(tmpx);
+    __m256i mm_tmpy = _mm256_set1_epi32(tmpy);
+    __m256i mm_offset = _mm256_set1_epi32(offset);
+    __m256i vibdimin = _mm256_set1_epi32(clpRng.min);
+    __m256i vibdimax = _mm256_set1_epi32(clpRng.max);
+
+    int src0Stride2 = (src0Stride << 1);
+    int src1Stride2 = (src1Stride << 1);
+    int dstStride2 = (dstStride << 1);
+    int gradStride2 = (gradStride << 1);
+
+    for (int y = 0; y < height; y += 2)
+    {
+      for (int x = 0; x < width; x += 4)
+      {
+        __m256i mm_gradX0 = _mm256_castsi128_si256(_mm_lddqu_si128((__m128i *)(gradX0 + x)));
+        mm_gradX0 = _mm256_inserti128_si256(mm_gradX0, _mm_lddqu_si128((__m128i *)(gradX0 + x + gradStride)), 1);
+        __m256i mm_gradX1 = _mm256_castsi128_si256(_mm_lddqu_si128((__m128i *)(gradX1 + x)));
+        mm_gradX1 = _mm256_inserti128_si256(mm_gradX1, _mm_lddqu_si128((__m128i *)(gradX1 + x + gradStride)), 1);
+        __m256i mm_gradY0 = _mm256_castsi128_si256(_mm_lddqu_si128((__m128i *)(gradY0 + x)));
+        mm_gradY0 = _mm256_inserti128_si256(mm_gradY0, _mm_lddqu_si128((__m128i *)(gradY0 + x + gradStride)), 1);
+        __m256i mm_gradY1 = _mm256_castsi128_si256(_mm_lddqu_si128((__m128i *)(gradY1 + x)));
+        mm_gradY1 = _mm256_inserti128_si256(mm_gradY1, _mm_lddqu_si128((__m128i *)(gradY1 + x + gradStride)), 1);
+
+        __m256i mm_gradX = _mm256_sub_epi32(mm_gradX0, mm_gradX1);
+        __m256i mm_gradY = _mm256_sub_epi32(mm_gradY0, mm_gradY1);
+        __m256i mm_sum = _mm256_add_epi32(_mm256_mullo_epi32(mm_gradX, mm_tmpx), _mm256_mullo_epi32(mm_gradY, mm_tmpy));
+
+        __m256i mm_src0 = _mm256_castsi128_si256(_mm_lddqu_si128((__m128i *)(src0 + x)));
+        mm_src0 = _mm256_inserti128_si256(mm_src0, _mm_lddqu_si128((__m128i *)(src0 + x + src0Stride)), 1);
+        __m256i mm_src1 = _mm256_castsi128_si256(_mm_lddqu_si128((__m128i *)(src1 + x)));
+        mm_src1 = _mm256_inserti128_si256(mm_src1, _mm_lddqu_si128((__m128i *)(src1 + x + src1Stride)), 1);
+        __m256i mm_src = _mm256_add_epi32(mm_src0, mm_src1);
+
+        mm_sum = _mm256_add_epi32(mm_sum, mm_src);
+        mm_sum = _mm256_srai_epi32(_mm256_add_epi32(mm_sum, mm_offset), shift);
+        mm_sum = _mm256_min_epi32(_mm256_max_epi32(mm_sum, vibdimin), vibdimax);
+
+        _mm_storeu_si128((__m128i *) (dst + x), _mm256_castsi256_si128(mm_sum));
+        _mm_storeu_si128((__m128i *) (dst + x + dstStride), _mm256_castsi256_si128(_mm256_permute4x64_epi64(mm_sum, 0xee)));
+      }
+      dst += dstStride2;     src0 += src0Stride2;   src1 += src1Stride2;
+      gradX0 += gradStride2; gradX1 += gradStride2; gradY0 += gradStride2; gradY1 += gradStride2;
+    }
+  }
+  else
+#endif
+  {
+    __m128i mm_tmpx = _mm_set1_epi32(tmpx);
+    __m128i mm_tmpy = _mm_set1_epi32(tmpy);
+    __m128i mm_offset = _mm_set1_epi32(offset);
+    __m128i vibdimin = _mm_set1_epi32(clpRng.min);
+    __m128i vibdimax = _mm_set1_epi32(clpRng.max);
+
+    for (int y = 0; y < height; y++)
+    {
+      for (int x = 0; x < width; x += 4)
+      {
+        __m128i mm_gradX = _mm_sub_epi32(_mm_lddqu_si128((__m128i *)(gradX0 + x)), _mm_lddqu_si128((__m128i *) (gradX1 + x)));
+        __m128i mm_gradY = _mm_sub_epi32(_mm_lddqu_si128((__m128i *)(gradY0 + x)), _mm_lddqu_si128((__m128i *) (gradY1 + x)));
+        __m128i mm_sum = _mm_add_epi32(_mm_mullo_epi32(mm_gradX, mm_tmpx), _mm_mullo_epi32(mm_gradY, mm_tmpy));
+        __m128i mm_src = _mm_add_epi32(_mm_lddqu_si128((__m128i *)(src0 + x)), _mm_lddqu_si128((__m128i *)(src1 + x)));
+        mm_sum = _mm_add_epi32(mm_sum, mm_src);
+        mm_sum = _mm_srai_epi32(_mm_add_epi32(mm_sum, mm_offset), shift);
+        mm_sum = _mm_min_epi32(_mm_max_epi32(mm_sum, vibdimin), vibdimax);
+        _mm_storeu_si128((__m128i *) (dst + x), mm_sum);
+      }
+      dst += dstStride;     src0 += src0Stride;   src1 += src1Stride;
+      gradX0 += gradStride; gradX1 += gradStride; gradY0 += gradStride; gradY1 += gradStride;
+    }
+  }
+}
+
+template< X86_VEXT vext >
+void applyPROFHBD_SIMD(Pel* dstPel, int dstStride, const Pel* srcPel, int srcStride, int width, int height, const Pel* gradX, const Pel* gradY, int gradStride, const int* dMvX, const int* dMvY, int dMvStride, const bool& bi, int shiftNum, Pel offset, const ClpRng& clpRng)
+{
+  CHECKD((width & 3), "block width error!");
+  const int dILimit = 1 << std::max<int>(clpRng.bd + 1, 13);
+
+#ifdef USE_AVX2
+  if (vext >= AVX2)
+  {
+    __m256i mm_dmvx, mm_dmvy, mm_gradx, mm_grady, mm_dI, mm_src;
+    __m256i mm_offset = _mm256_set1_epi32(offset);
+    __m256i vibdimin = _mm256_set1_epi32(clpRng.min);
+    __m256i vibdimax = _mm256_set1_epi32(clpRng.max);
+    __m256i mm_dimin = _mm256_set1_epi32(-dILimit);
+    __m256i mm_dimax = _mm256_set1_epi32(dILimit - 1);
+
+    for (int h = 0; h < height; h += 2)
+    {
+      const int* vX = dMvX;
+      const int* vY = dMvY;
+      const Pel* gX = gradX;
+      const Pel* gY = gradY;
+      const Pel* src = srcPel;
+      Pel*       dst = dstPel;
+
+      for (int w = 0; w < width; w += 4)
+      {
+        mm_dmvx = _mm256_inserti128_si256(_mm256_castsi128_si256(_mm_lddqu_si128((__m128i *)vX)), _mm_lddqu_si128((__m128i *)(vX + dMvStride)), 1);
+        mm_dmvy = _mm256_inserti128_si256(_mm256_castsi128_si256(_mm_lddqu_si128((__m128i *)vY)), _mm_lddqu_si128((__m128i *)(vY + dMvStride)), 1);
+        mm_gradx = _mm256_inserti128_si256(_mm256_castsi128_si256(_mm_lddqu_si128((__m128i *)gX)), _mm_lddqu_si128((__m128i *)(gX + gradStride)), 1);
+        mm_grady = _mm256_inserti128_si256(_mm256_castsi128_si256(_mm_lddqu_si128((__m128i *)gY)), _mm_lddqu_si128((__m128i *)(gY + gradStride)), 1);
+        mm_src = _mm256_inserti128_si256(_mm256_castsi128_si256(_mm_lddqu_si128((__m128i *)src)), _mm_lddqu_si128((__m128i *)(src + srcStride)), 1);
+
+        mm_dI = _mm256_add_epi32(_mm256_mullo_epi32(mm_dmvx, mm_gradx), _mm256_mullo_epi32(mm_dmvy, mm_grady));
+        mm_dI = _mm256_min_epi32(mm_dimax, _mm256_max_epi32(mm_dimin, mm_dI));
+        mm_dI = _mm256_add_epi32(mm_src, mm_dI);
+
+        if (!bi)
+        {
+          mm_dI = _mm256_srai_epi32(_mm256_add_epi32(mm_dI, mm_offset), shiftNum);
+          mm_dI = _mm256_min_epi32(vibdimax, _mm256_max_epi32(vibdimin, mm_dI));
+        }
+
+        _mm_storeu_si128((__m128i *)dst, _mm256_castsi256_si128(mm_dI));
+        _mm_storeu_si128((__m128i *)(dst + dstStride), _mm256_castsi256_si128(_mm256_permute4x64_epi64(mm_dI, 0xee)));
+        vX += 4; vY += 4; gX += 4; gY += 4; src += 4; dst += 4;
+      }
+      dMvX += (dMvStride << 1);
+      dMvY += (dMvStride << 1);
+      gradX += (gradStride << 1);
+      gradY += (gradStride << 1);
+      srcPel += (srcStride << 1);
+      dstPel += (dstStride << 1);
+    }
+  }
+  else
+#endif
+  {
+    __m128i mm_dmvx, mm_dmvy, mm_gradx, mm_grady, mm_dI;
+    __m128i mm_offset = _mm_set1_epi32(offset);
+    __m128i vibdimin = _mm_set1_epi32(clpRng.min);
+    __m128i vibdimax = _mm_set1_epi32(clpRng.max);
+    __m128i mm_dimin = _mm_set1_epi32(-dILimit);
+    __m128i mm_dimax = _mm_set1_epi32(dILimit - 1);
+
+    for (int h = 0; h < height; h++)
+    {
+      const int* vX = dMvX;
+      const int* vY = dMvY;
+      const Pel* gX = gradX;
+      const Pel* gY = gradY;
+      const Pel* src = srcPel;
+      Pel*       dst = dstPel;
+
+      for (int w = 0; w < width; w += 4)
+      {
+        mm_dmvx = _mm_lddqu_si128((__m128i *)vX);
+        mm_dmvy = _mm_lddqu_si128((__m128i *)vY);
+        mm_gradx = _mm_lddqu_si128((__m128i*)gX);
+        mm_grady = _mm_lddqu_si128((__m128i*)gY);
+        mm_dI = _mm_add_epi32(_mm_mullo_epi32(mm_dmvx, mm_gradx), _mm_mullo_epi32(mm_dmvy, mm_grady));
+        mm_dI = _mm_min_epi32(mm_dimax, _mm_max_epi32(mm_dimin, mm_dI));
+        mm_dI = _mm_add_epi32(_mm_lddqu_si128((__m128i *)src), mm_dI);
+        if (!bi)
+        {
+          mm_dI = _mm_srai_epi32(_mm_add_epi32(mm_dI, mm_offset), shiftNum);
+          mm_dI = _mm_min_epi32(vibdimax, _mm_max_epi32(vibdimin, mm_dI));
+        }
+
+        _mm_storeu_si128((__m128i *)dst, mm_dI);
+        vX += 4; vY += 4; gX += 4; gY += 4; src += 4; dst += 4;
+      }
+      dMvX += dMvStride;
+      dMvY += dMvStride;
+      gradX += gradStride;
+      gradY += gradStride;
+      srcPel += srcStride;
+      dstPel += dstStride;
+    }
+  }
+}
+#endif
 
 template< X86_VEXT vext >
 void roundIntVector_SIMD(int* v, int size, unsigned int nShift, const int dmvLimit)
@@ -1002,7 +1433,286 @@ void linTf_SSE( const Pel* src, int srcStride, Pel *dst, int dstStride, int widt
     }
   }
 }
+#if RExt__HIGH_BIT_DEPTH_SUPPORT
+template< X86_VEXT vext, int W >
+void addAvg_HBD_SIMD(const Pel* src0, int src0Stride, const Pel* src1, int src1Stride, Pel *dst, int dstStride, int width, int height, int shift, int offset, const ClpRng& clpRng)
+{
+  CHECK((width & 3), "the function only supports width multiple of 4");
 
+  __m128i voffset = _mm_set1_epi32(offset);
+  __m128i vibdimin = _mm_set1_epi32(clpRng.min);
+  __m128i vibdimax = _mm_set1_epi32(clpRng.max);
+
+#ifdef USE_AVX2
+  __m256i mm256_voffset = _mm256_set1_epi32(offset);
+  __m256i mm256_vibdimin = _mm256_set1_epi32(clpRng.min);
+  __m256i mm256_vibdimax = _mm256_set1_epi32(clpRng.max);
+#endif
+
+  for (int row = 0; row < height; row++)
+  {
+    int col = 0;
+#ifdef USE_AVX2
+    if (vext >= AVX2)
+    {
+      for (; col < ((width >> 3) << 3); col += 8)
+      {
+        __m256i vsum = _mm256_lddqu_si256((const __m256i *)&src0[col]);
+        __m256i vdst = _mm256_lddqu_si256((const __m256i *)&src1[col]);
+        vsum = _mm256_add_epi32(vsum, vdst);
+        vsum = _mm256_add_epi32(vsum, mm256_voffset);
+        vsum = _mm256_srai_epi32(vsum, shift);
+
+        vsum = _mm256_min_epi32(mm256_vibdimax, _mm256_max_epi32(mm256_vibdimin, vsum));
+        _mm256_storeu_si256((__m256i *)&dst[col], vsum);
+      }
+    }
+#endif
+
+    for (; col < width; col += 4)
+    {
+      __m128i vsum = _mm_lddqu_si128((const __m128i *)&src0[col]);
+      __m128i vdst = _mm_lddqu_si128((const __m128i *)&src1[col]);
+      vsum = _mm_add_epi32(vsum, vdst);
+      vsum = _mm_add_epi32(vsum, voffset);
+      vsum = _mm_srai_epi32(vsum, shift);
+
+      vsum = _mm_min_epi32(vibdimax, _mm_max_epi32(vibdimin, vsum));
+      _mm_storeu_si128((__m128i *)&dst[col], vsum);
+    }
+
+    src0 += src0Stride;
+    src1 += src1Stride;
+    dst += dstStride;
+  }
+}
+
+template< X86_VEXT vext, int W >
+void reco_HBD_SIMD(const Pel* src0, int src0Stride, const Pel* src1, int src1Stride, Pel *dst, int dstStride, int width, int height, const ClpRng& clpRng)
+{
+  CHECK((width & 3), "the function only supports width multiple of 4");
+
+
+  __m128i vbdmin = _mm_set1_epi32(clpRng.min);
+  __m128i vbdmax = _mm_set1_epi32(clpRng.max);
+
+#ifdef USE_AVX2
+  __m256i mm256_vbdmin = _mm256_set1_epi32(clpRng.min);
+  __m256i mm256_vbdmax = _mm256_set1_epi32(clpRng.max);
+#endif
+
+  for (int row = 0; row < height; row++)
+  {
+    int col = 0;
+#ifdef USE_AVX2
+    if (vext >= AVX2)
+    {
+      for (; col < ((width >> 3) << 3); col += 8)
+      {
+        __m256i vsrc = _mm256_lddqu_si256((const __m256i *)&src0[col]);
+        __m256i vdst = _mm256_lddqu_si256((const __m256i *)&src1[col]);
+
+        vdst = _mm256_add_epi32(vdst, vsrc);
+        vdst = _mm256_min_epi32(mm256_vbdmax, _mm256_max_epi32(mm256_vbdmin, vdst));
+        _mm256_storeu_si256((__m256i *)&dst[col], vdst);
+      }
+    }
+#endif
+    for (; col < width; col += 4)
+    {
+      __m128i vsrc = _mm_lddqu_si128((const __m128i *)&src0[col]);
+      __m128i vdst = _mm_lddqu_si128((const __m128i *)&src1[col]);
+
+      vdst = _mm_add_epi32(vdst, vsrc);
+      vdst = _mm_min_epi32(vbdmax, _mm_max_epi32(vbdmin, vdst));
+
+      _mm_storeu_si128((__m128i *)&dst[col], vdst);
+    }
+
+    src0 += src0Stride;
+    src1 += src1Stride;
+    dst += dstStride;
+  }
+}
+
+#if ENABLE_SIMD_OPT_BCW
+template< X86_VEXT vext, int W >
+void removeHighFreq_HBD_SIMD(Pel* src0, int src0Stride, const Pel* src1, int src1Stride, int width, int height)
+{
+  CHECK((width & 3), "the function only supports width multiple of 4");
+  for (int row = 0; row < height; row++)
+  {
+    int col = 0;
+#ifdef USE_AVX2
+    if (vext >= AVX2)
+    {
+      __m256i mm256_vsrc0, mm256_vsrc1;
+      for (; col < ((width >> 3) << 3); col += 8)
+      {
+        mm256_vsrc0 = _mm256_lddqu_si256((const __m256i *)&src0[col]);
+        mm256_vsrc1 = _mm256_lddqu_si256((const __m256i *)&src1[col]);
+
+        mm256_vsrc0 = _mm256_sub_epi32(_mm256_slli_epi32(mm256_vsrc0, 1), mm256_vsrc1);
+        _mm256_storeu_si256((__m256i *)&src0[col], mm256_vsrc0);
+      }
+    }
+#endif
+    __m128i vsrc0, vsrc1;
+    for (; col < width; col += 4)
+    {
+      vsrc0 = _mm_lddqu_si128((const __m128i *)&src0[col]);
+      vsrc1 = _mm_lddqu_si128((const __m128i *)&src1[col]);
+
+      vsrc0 = _mm_sub_epi32(_mm_slli_epi32(vsrc0, 1), vsrc1);
+      _mm_store_si128((__m128i *)&src0[col], vsrc0);
+    }
+    src0 += src0Stride;
+    src1 += src1Stride;
+  }
+}
+
+template< X86_VEXT vext, int W >
+void removeWeightHighFreq_HBD_SIMD(Pel* src0, int src0Stride, const Pel* src1, int src1Stride, int width, int height, int shift, int bcwWeight)
+{
+  CHECK((width & 3), "the function only supports width multiple of 4");
+
+  int normalizer = ((1 << 16) + (bcwWeight > 0 ? (bcwWeight >> 1) : -(bcwWeight >> 1))) / bcwWeight;
+  int weight0 = normalizer << g_BcwLog2WeightBase;
+  int weight1 = (g_BcwWeightBase - bcwWeight)*normalizer;
+  Intermediate_Int offset = Intermediate_Int(1) << (shift - 1);
+
+#ifdef USE_AVX2
+  if (vext >= AVX2)
+  {
+    __m256i voffset = _mm256_set1_epi64x(offset);
+    __m256i vw0 = _mm256_set1_epi32(weight0);
+    __m256i vw1 = _mm256_set1_epi32(weight1);
+
+    __m256i vdst, vsrc;
+    for (int row = 0; row < height; row++)
+    {
+      for (int col = 0; col < width; col += 4)
+      {
+        __m256i vsrc0 = _mm256_inserti128_si256(_mm256_castsi128_si256(_mm_lddqu_si128((__m128i *)&src0[col])), _mm_lddqu_si128((__m128i *)&src0[col + 2]), 1);
+        __m256i vsrc1 = _mm256_inserti128_si256(_mm256_castsi128_si256(_mm_lddqu_si128((__m128i *)&src1[col])), _mm_lddqu_si128((__m128i *)&src1[col + 2]), 1);
+        vsrc0 = _mm256_shuffle_epi32(vsrc0, 0x50);
+        vsrc1 = _mm256_shuffle_epi32(vsrc1, 0x50);
+
+        vdst = _mm256_mul_epi32(vsrc0, vw0);
+        vsrc = _mm256_mul_epi32(vsrc1, vw1);
+        vdst = _mm256_add_epi64(_mm256_sub_epi64(vdst, vsrc), voffset);
+
+        *(src0 + col) = (Pel)(_mm256_extract_epi64(vdst, 0) >> shift);
+        *(src0 + col + 1) = (Pel)(_mm256_extract_epi64(vdst, 1) >> shift);
+        *(src0 + col + 2) = (Pel)(_mm256_extract_epi64(vdst, 2) >> shift);
+        *(src0 + col + 3) = (Pel)(_mm256_extract_epi64(vdst, 3) >> shift);
+      }
+      src0 += src0Stride;
+      src1 += src1Stride;
+    }
+  }
+  else
+#endif
+  {
+    __m128i voffset = _mm_set_epi64x(offset, offset);
+    __m128i vw0 = _mm_set1_epi32(weight0);
+    __m128i vw1 = _mm_set1_epi32(weight1);
+
+    __m128i vdst, vsrc;
+    for (int row = 0; row < height; row++)
+    {
+      for (int col = 0; col < width; col += 4)
+      {
+        __m128i vsrc0 = _mm_lddqu_si128((__m128i *)&src0[col]);
+        __m128i vsrc1 = _mm_lddqu_si128((__m128i *)&src1[col]);
+
+        vdst = _mm_mul_epi32(vsrc0, vw0);
+        vsrc = _mm_mul_epi32(vsrc1, vw1);
+        vdst = _mm_add_epi64(_mm_sub_epi64(vdst, vsrc), voffset);
+
+        *(src0 + col) = (Pel)(_mm_extract_epi64(vdst, 0) >> shift);
+        *(src0 + col + 2) = (Pel)(_mm_extract_epi64(vdst, 1) >> shift);
+
+        vsrc0 = _mm_srli_si128(vsrc0, 4);
+        vsrc1 = _mm_srli_si128(vsrc1, 4);
+
+        vdst = _mm_mul_epi32(vsrc0, vw0);
+        vsrc = _mm_mul_epi32(vsrc1, vw1);
+        vdst = _mm_add_epi64(_mm_sub_epi64(vdst, vsrc), voffset);
+
+        *(src0 + col + 1) = (Pel)(_mm_extract_epi64(vdst, 0) >> shift);
+        *(src0 + col + 3) = (Pel)(_mm_extract_epi64(vdst, 1) >> shift);
+      }
+      src0 += src0Stride;
+      src1 += src1Stride;
+    }
+  }
+}
+#endif
+
+template<bool clip, typename T> static inline void do_clip_hbd(T& vreg, T& vbdmin, T& vbdmax);
+template<> inline void do_clip_hbd<false, __m128i>(__m128i&, __m128i&, __m128i&) { }
+#ifdef USE_AVX2
+template<> inline void do_clip_hbd<false, __m256i>(__m256i&, __m256i&, __m256i&) { }
+#endif
+template<> inline void do_clip_hbd<true, __m128i>(__m128i& vreg, __m128i& vbdmin, __m128i& vbdmax) { vreg = _mm_min_epi32(vbdmax, _mm_max_epi32(vbdmin, vreg)); }
+#ifdef USE_AVX2
+template<> inline void do_clip_hbd<true, __m256i>(__m256i& vreg, __m256i& vbdmin, __m256i& vbdmax) { vreg = _mm256_min_epi32(vbdmax, _mm256_max_epi32(vbdmin, vreg)); }
+#endif
+
+template<X86_VEXT vext, int W, bool doAdd, bool mult, bool doShift, bool shiftR, bool clip>
+void linTf_HBD_SIMD(const Pel* src, int srcStride, Pel *dst, int dstStride, int width, int height, int scale, int shift, int offset, const ClpRng& clpRng)
+{
+  CHECK((width & 3), "the function only supports width multiple of 4");
+
+  __m128i vbdmin = _mm_set1_epi32(clpRng.min);
+  __m128i vbdmax = _mm_set1_epi32(clpRng.max);
+  __m128i voffset = _mm_set1_epi32(offset);
+  __m128i vscale = _mm_set1_epi32(scale);
+  __m128i val;
+
+#ifdef USE_AVX2
+  __m256i mm256_vbdmin = _mm256_set1_epi32(clpRng.min);
+  __m256i mm256_vbdmax = _mm256_set1_epi32(clpRng.max);
+  __m256i mm256_voffset = _mm256_set1_epi32(offset);
+  __m256i mm256_vscale = _mm256_set1_epi32(scale);
+  __m256i mm256_val;
+#endif
+
+  for (int row = 0; row < height; row++)
+  {
+    int col = 0;
+#ifdef USE_AVX2
+    if (vext >= AVX2)
+    {
+      for (; col < ((width >> 3) << 3); col += 8)
+      {
+        mm256_val = _mm256_lddqu_si256((const __m256i *)&src[col]);
+        do_mult<mult, __m256i>(mm256_val, mm256_vscale);
+        do_shift<doShift, shiftR, __m256i>(mm256_val, shift);
+        do_add<doAdd, __m256i>(mm256_val, mm256_voffset);
+        do_clip_hbd<clip, __m256i>(mm256_val, mm256_vbdmin, mm256_vbdmax);
+
+        _mm256_storeu_si256((__m256i *)&dst[col], mm256_val);
+      }
+    }
+#endif
+    for (; col < width; col += 4)
+    {
+      val = _mm_lddqu_si128((const __m128i *)&src[col]);
+      do_mult<mult, __m128i>(val, vscale);
+      do_shift<doShift, shiftR, __m128i>(val, shift);
+      do_add<doAdd, __m128i>(val, voffset);
+      do_clip_hbd<clip, __m128i>(val, vbdmin, vbdmax);
+
+      _mm_storeu_si128((__m128i *)&dst[col], val);
+    }
+
+    src += srcStride;
+    dst += dstStride;
+  }
+}
+#endif
 template<X86_VEXT vext, int W>
 void linTf_SSE_entry( const Pel* src, int srcStride, Pel *dst, int dstStride, int width, int height, int scale, int shift, int offset, const ClpRng& clpRng, bool clip )
 {
@@ -1010,6 +1720,40 @@ void linTf_SSE_entry( const Pel* src, int srcStride, Pel *dst, int dstStride, in
 
   switch( fn )
   {
+#if RExt__HIGH_BIT_DEPTH_SUPPORT
+  case  0: linTf_HBD_SIMD<vext, W, true, true, true, true, true >(src, srcStride, dst, dstStride, width, height, scale, shift, offset, clpRng); break;
+  case  1: linTf_HBD_SIMD<vext, W, true, true, true, true, false>(src, srcStride, dst, dstStride, width, height, scale, shift, offset, clpRng); break;
+  case  2: linTf_HBD_SIMD<vext, W, true, true, true, false, true >(src, srcStride, dst, dstStride, width, height, scale, -shift, offset, clpRng); break;
+  case  3: linTf_HBD_SIMD<vext, W, true, true, true, false, false>(src, srcStride, dst, dstStride, width, height, scale, -shift, offset, clpRng); break;
+  case  4: linTf_HBD_SIMD<vext, W, true, true, false, true, true >(src, srcStride, dst, dstStride, width, height, scale, shift, offset, clpRng); break;
+  case  5: linTf_HBD_SIMD<vext, W, true, true, false, true, false>(src, srcStride, dst, dstStride, width, height, scale, shift, offset, clpRng); break;
+  case  6: linTf_HBD_SIMD<vext, W, true, true, false, false, true >(src, srcStride, dst, dstStride, width, height, scale, -shift, offset, clpRng); break;
+  case  7: linTf_HBD_SIMD<vext, W, true, true, false, false, false>(src, srcStride, dst, dstStride, width, height, scale, -shift, offset, clpRng); break;
+  case  8: linTf_HBD_SIMD<vext, W, true, false, true, true, true >(src, srcStride, dst, dstStride, width, height, scale, shift, offset, clpRng); break;
+  case  9: linTf_HBD_SIMD<vext, W, true, false, true, true, false>(src, srcStride, dst, dstStride, width, height, scale, shift, offset, clpRng); break;
+  case 10: linTf_HBD_SIMD<vext, W, true, false, true, false, true >(src, srcStride, dst, dstStride, width, height, scale, -shift, offset, clpRng); break;
+  case 11: linTf_HBD_SIMD<vext, W, true, false, true, false, false>(src, srcStride, dst, dstStride, width, height, scale, -shift, offset, clpRng); break;
+  case 12: linTf_HBD_SIMD<vext, W, true, false, false, true, true >(src, srcStride, dst, dstStride, width, height, scale, shift, offset, clpRng); break;
+  case 13: linTf_HBD_SIMD<vext, W, true, false, false, true, false>(src, srcStride, dst, dstStride, width, height, scale, shift, offset, clpRng); break;
+  case 14: linTf_HBD_SIMD<vext, W, true, false, false, false, true >(src, srcStride, dst, dstStride, width, height, scale, -shift, offset, clpRng); break;
+  case 15: linTf_HBD_SIMD<vext, W, true, false, false, false, false>(src, srcStride, dst, dstStride, width, height, scale, -shift, offset, clpRng); break;
+  case 16: linTf_HBD_SIMD<vext, W, false, true, true, true, true >(src, srcStride, dst, dstStride, width, height, scale, shift, offset, clpRng); break;
+  case 17: linTf_HBD_SIMD<vext, W, false, true, true, true, false>(src, srcStride, dst, dstStride, width, height, scale, shift, offset, clpRng); break;
+  case 18: linTf_HBD_SIMD<vext, W, false, true, true, false, true >(src, srcStride, dst, dstStride, width, height, scale, -shift, offset, clpRng); break;
+  case 19: linTf_HBD_SIMD<vext, W, false, true, true, false, false>(src, srcStride, dst, dstStride, width, height, scale, -shift, offset, clpRng); break;
+  case 20: linTf_HBD_SIMD<vext, W, false, true, false, true, true >(src, srcStride, dst, dstStride, width, height, scale, shift, offset, clpRng); break;
+  case 21: linTf_HBD_SIMD<vext, W, false, true, false, true, false>(src, srcStride, dst, dstStride, width, height, scale, shift, offset, clpRng); break;
+  case 22: linTf_HBD_SIMD<vext, W, false, true, false, false, true >(src, srcStride, dst, dstStride, width, height, scale, -shift, offset, clpRng); break;
+  case 23: linTf_HBD_SIMD<vext, W, false, true, false, false, false>(src, srcStride, dst, dstStride, width, height, scale, -shift, offset, clpRng); break;
+  case 24: linTf_HBD_SIMD<vext, W, false, false, true, true, true >(src, srcStride, dst, dstStride, width, height, scale, shift, offset, clpRng); break;
+  case 25: linTf_HBD_SIMD<vext, W, false, false, true, true, false>(src, srcStride, dst, dstStride, width, height, scale, shift, offset, clpRng); break;
+  case 26: linTf_HBD_SIMD<vext, W, false, false, true, false, true >(src, srcStride, dst, dstStride, width, height, scale, -shift, offset, clpRng); break;
+  case 27: linTf_HBD_SIMD<vext, W, false, false, true, false, false>(src, srcStride, dst, dstStride, width, height, scale, -shift, offset, clpRng); break;
+  case 28: linTf_HBD_SIMD<vext, W, false, false, false, true, true >(src, srcStride, dst, dstStride, width, height, scale, shift, offset, clpRng); break;
+  case 29: linTf_HBD_SIMD<vext, W, false, false, false, true, false>(src, srcStride, dst, dstStride, width, height, scale, shift, offset, clpRng); break;
+  case 30: linTf_HBD_SIMD<vext, W, false, false, false, false, true >(src, srcStride, dst, dstStride, width, height, scale, -shift, offset, clpRng); break;
+  case 31: linTf_HBD_SIMD<vext, W, false, false, false, false, false>(src, srcStride, dst, dstStride, width, height, scale, -shift, offset, clpRng); break;
+#else
   case  0: linTf_SSE<vext, W, true,  true,  true,  true,  true >( src, srcStride, dst, dstStride, width, height, scale,  shift, offset, clpRng ); break;
   case  1: linTf_SSE<vext, W, true,  true,  true,  true,  false>( src, srcStride, dst, dstStride, width, height, scale,  shift, offset, clpRng ); break;
   case  2: linTf_SSE<vext, W, true,  true,  true,  false, true >( src, srcStride, dst, dstStride, width, height, scale, -shift, offset, clpRng ); break;
@@ -1042,6 +1786,7 @@ void linTf_SSE_entry( const Pel* src, int srcStride, Pel *dst, int dstStride, in
   case 29: linTf_SSE<vext, W, false, false, false, true,  false>( src, srcStride, dst, dstStride, width, height, scale,  shift, offset, clpRng ); break;
   case 30: linTf_SSE<vext, W, false, false, false, false, true >( src, srcStride, dst, dstStride, width, height, scale, -shift, offset, clpRng ); break;
   case 31: linTf_SSE<vext, W, false, false, false, false, false>( src, srcStride, dst, dstStride, width, height, scale, -shift, offset, clpRng ); break;
+#endif
   default:
     THROW( "Unknown parametrization of the linear transformation" );
     break;
@@ -1051,6 +1796,29 @@ void linTf_SSE_entry( const Pel* src, int srcStride, Pel *dst, int dstStride, in
 template<X86_VEXT vext>
 void PelBufferOps::_initPelBufOpsX86()
 {
+#if RExt__HIGH_BIT_DEPTH_SUPPORT
+  addAvg8 = addAvg_HBD_SIMD<vext, 8>;
+  addAvg4 = addAvg_HBD_SIMD<vext, 4>;
+
+  addBIOAvg4 = addBIOAvg4HBD_SIMD<vext>;
+  bioGradFilter = gradFilterHBD_SIMD<vext>;
+  calcBIOSums = calcBIOSumsHBD_SIMD<vext>;
+
+  reco8 = reco_HBD_SIMD<vext, 8>;
+  reco4 = reco_HBD_SIMD<vext, 4>;
+
+  linTf8 = linTf_SSE_entry<vext, 8>;
+  linTf4 = linTf_SSE_entry<vext, 4>;
+#if ENABLE_SIMD_OPT_BCW
+  removeWeightHighFreq8 = removeWeightHighFreq_HBD_SIMD<vext, 8>;
+  removeWeightHighFreq4 = removeWeightHighFreq_HBD_SIMD<vext, 4>;
+  removeHighFreq8 = removeHighFreq_HBD_SIMD<vext, 8>;
+  removeHighFreq4 = removeHighFreq_HBD_SIMD<vext, 4>;
+#endif
+
+  profGradFilter = gradFilterHBD_SIMD<vext, false>;
+  applyPROF = applyPROFHBD_SIMD<vext>;
+#else
   addAvg8 = addAvg_SSE<vext, 8>;
   addAvg4 = addAvg_SSE<vext, 4>;
 
@@ -1073,6 +1841,7 @@ void PelBufferOps::_initPelBufOpsX86()
 #endif
   profGradFilter = gradFilter_SSE<vext, false>;
   applyPROF      = applyPROF_SSE<vext>;
+#endif
   roundIntVector = roundIntVector_SIMD<vext>;
 }
 
diff --git a/source/Lib/CommonLib/x86/CommonDefX86.cpp b/source/Lib/CommonLib/x86/CommonDefX86.cpp
index 448b627bb..3c9a19481 100644
--- a/source/Lib/CommonLib/x86/CommonDefX86.cpp
+++ b/source/Lib/CommonLib/x86/CommonDefX86.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/CommonLib/x86/CommonDefX86.h b/source/Lib/CommonLib/x86/CommonDefX86.h
index 29f90397f..b00469dbd 100644
--- a/source/Lib/CommonLib/x86/CommonDefX86.h
+++ b/source/Lib/CommonLib/x86/CommonDefX86.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/CommonLib/x86/IbcHashMapX86.h b/source/Lib/CommonLib/x86/IbcHashMapX86.h
index 2d0ce5f03..0d8eb6669 100644
--- a/source/Lib/CommonLib/x86/IbcHashMapX86.h
+++ b/source/Lib/CommonLib/x86/IbcHashMapX86.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/CommonLib/x86/InitX86.cpp b/source/Lib/CommonLib/x86/InitX86.cpp
index 458839510..5908746d2 100644
--- a/source/Lib/CommonLib/x86/InitX86.cpp
+++ b/source/Lib/CommonLib/x86/InitX86.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/CommonLib/x86/InterpolationFilterX86.h b/source/Lib/CommonLib/x86/InterpolationFilterX86.h
index 3e52ef6fb..336734f99 100644
--- a/source/Lib/CommonLib/x86/InterpolationFilterX86.h
+++ b/source/Lib/CommonLib/x86/InterpolationFilterX86.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -621,7 +621,7 @@ template<X86_VEXT vext, int N, bool shiftBack>
 static void simdInterpolateVerM8( const int16_t *src, int srcStride, int16_t *dst, int dstStride, int width, int height, int shift, int offset, const ClpRng& clpRng, int16_t const *coeff )
 {
 //   src -= ( N / 2 - 1 ) * srcStride;
-  const Pel *srcOrig = src;
+  const int16_t *srcOrig = src;
   int16_t *dstOrig = dst;
 
   __m128i vcoeff[N / 2], vsrc[N];
@@ -1155,184 +1155,1229 @@ static void simdInterpolateN2_10BIT_M4(const int16_t* src, int srcStride, int16_
     dst += dstStride;
   }
 }
-
-template<X86_VEXT vext, int N, bool isVertical, bool isFirst, bool isLast>
-static void simdFilter( const ClpRng& clpRng, Pel const *src, int srcStride, Pel *dst, int dstStride, int width, int height, TFilterCoeff const *coeff, bool biMCForDMVR)
+#if RExt__HIGH_BIT_DEPTH_SUPPORT
+template<X86_VEXT vext, int N, bool shiftBack>
+static void simdInterpolateHorM8_HBD(const Pel* src, int srcStride, Pel *dst, int dstStride, int width, int height, int shift, int offset, const ClpRng& clpRng, Pel const *coeff)
 {
-  int row, col;
-
-  Pel c[8];
-  c[0] = coeff[0];
-  c[1] = coeff[1];
-  if( N >= 4 )
-  {
-    c[2] = coeff[2];
-    c[3] = coeff[3];
-  }
-  if( N >= 6 )
+  const int filterSpan = (N - 1);
+  _mm_prefetch((const char*)src + srcStride, _MM_HINT_T0);
+  _mm_prefetch((const char*)src + (width >> 1) + srcStride, _MM_HINT_T0);
+  _mm_prefetch((const char*)src + width + filterSpan + srcStride, _MM_HINT_T0);
+
+  __m128i voffset = _mm_set1_epi32(offset);
+  __m128i vibdimin = _mm_set1_epi32(clpRng.min);
+  __m128i vibdimax = _mm_set1_epi32(clpRng.max);
+  __m128i vcoeffh0, vcoeffh1;
+  __m128i vsrc0, vsrc1;
+  __m128i vsuma, vsumb;
+
+  vcoeffh0 = _mm_lddqu_si128((__m128i const *)coeff);
+  if (N == 8)
   {
-    c[4] = coeff[4];
-    c[5] = coeff[5];
+    vcoeffh1 = _mm_lddqu_si128((__m128i const *)(coeff + 4));
   }
-  if( N == 8 )
+
+  for (int row = 0; row < height; row++)
   {
-    c[6] = coeff[6];
-    c[7] = coeff[7];
+    _mm_prefetch((const char*)src + 2 * srcStride, _MM_HINT_T0);
+    _mm_prefetch((const char*)src + (width >> 1) + 2 * srcStride, _MM_HINT_T0);
+    _mm_prefetch((const char*)src + width + filterSpan + 2 * srcStride, _MM_HINT_T0);
+
+    for (int col = 0; col < width; col += 8)
+    {
+      __m128i vtmp[4];
+      for (int i = 0; i < 8; i += 2)
+      {
+        if (N == 8)
+        {
+          __m128i vsrc00 = _mm_lddqu_si128((__m128i const *)&src[col + i]);
+          __m128i vsrc01 = _mm_lddqu_si128((__m128i const *)&src[col + i + 4]);
+          vsrc0 = _mm_add_epi32(_mm_mullo_epi32(vsrc00, vcoeffh0), _mm_mullo_epi32(vsrc01, vcoeffh1));
+
+          __m128i vsrc10 = _mm_lddqu_si128((__m128i const *)&src[col + i + 1]);
+          __m128i vsrc11 = _mm_lddqu_si128((__m128i const *)&src[col + i + 5]);
+          vsrc1 = _mm_add_epi32(_mm_mullo_epi32(vsrc10, vcoeffh0), _mm_mullo_epi32(vsrc11, vcoeffh1));
+        }
+        else
+        {
+          vsrc0 = _mm_mullo_epi32(_mm_lddqu_si128((__m128i const *)&src[col + i]), vcoeffh0);
+          vsrc1 = _mm_mullo_epi32(_mm_lddqu_si128((__m128i const *)&src[col + i + 1]), vcoeffh0);
+        }
+
+        vtmp[i / 2] = _mm_hadd_epi32(vsrc0, vsrc1);
+      }
+
+      vsuma = _mm_hadd_epi32(vtmp[0], vtmp[1]);
+      vsumb = _mm_hadd_epi32(vtmp[2], vtmp[3]);
+
+      vsuma = _mm_add_epi32(vsuma, voffset);
+      vsumb = _mm_add_epi32(vsumb, voffset);
+
+      vsuma = _mm_srai_epi32(vsuma, shift);
+      vsumb = _mm_srai_epi32(vsumb, shift);
+
+      if (shiftBack)
+      {
+        vsuma = _mm_min_epi32(vibdimax, _mm_max_epi32(vibdimin, vsuma));
+        vsumb = _mm_min_epi32(vibdimax, _mm_max_epi32(vibdimin, vsumb));
+      }
+      _mm_storeu_si128((__m128i *)&dst[col], vsuma);
+      _mm_storeu_si128((__m128i *)&dst[col + 4], vsumb);
+    }
+    src += srcStride;
+    dst += dstStride;
   }
+}
 
-  int cStride = ( isVertical ) ? srcStride : 1;
-  src -= ( N/2 - 1 ) * cStride;
+template<X86_VEXT vext, int N, bool shiftBack>
+static void simdInterpolateHorM8_HBD_AVX2(const Pel* src, int srcStride, Pel *dst, int dstStride, int width, int height, int shift, int offset, const ClpRng& clpRng, Pel const *coeff)
+{
+#ifdef USE_AVX2
+  const int filterSpan = (N - 1);
+  _mm_prefetch((const char*)(src + srcStride), _MM_HINT_T0);
+  _mm_prefetch((const char*)(src + (width >> 1) + srcStride), _MM_HINT_T0);
+  _mm_prefetch((const char*)(src + width + filterSpan + srcStride), _MM_HINT_T0);
 
-  int offset;
-  int headRoom = IF_INTERNAL_FRAC_BITS(clpRng.bd);
-  int shift    = IF_FILTER_PREC;
-  // with the current settings (IF_INTERNAL_PREC = 14 and IF_FILTER_PREC = 6), though headroom can be
-  // negative for bit depths greater than 14, shift will remain non-negative for bit depths of 8->20
-  CHECK( shift < 0, "Negative shift" );
+  __m256i voffset = _mm256_set1_epi32(offset);
+  __m256i vibdimin = _mm256_set1_epi32(clpRng.min);
+  __m256i vibdimax = _mm256_set1_epi32(clpRng.max);
 
+  __m256i vcoeff[N];
+  for (int i = 0; i < N; i++)
+  {
+    vcoeff[i] = _mm256_set1_epi32(coeff[i]);
+  }
 
-  if( isLast )
+  for (int row = 0; row < height; row++)
   {
-    shift += ( isFirst ) ? 0 : headRoom;
-    offset = 1 << ( shift - 1 );
-    offset += ( isFirst ) ? 0 : IF_INTERNAL_OFFS << IF_FILTER_PREC;
+    _mm_prefetch((const char*)(src + 2 * srcStride), _MM_HINT_T0);
+    _mm_prefetch((const char*)(src + (width >> 1) + 2 * srcStride), _MM_HINT_T0);
+    _mm_prefetch((const char*)(src + width + filterSpan + 2 * srcStride), _MM_HINT_T0);
+
+    for (int col = 0; col < width; col += 8)
+    {
+      __m256i vsum = _mm256_setzero_si256();
+      for (int i = 0; i < N; i++)
+      {
+        __m256i vsrc = _mm256_lddqu_si256((__m256i *)&src[col + i]);
+        vsum = _mm256_add_epi32(vsum, _mm256_mullo_epi32(vsrc, vcoeff[i]));
+      }
+      vsum = _mm256_add_epi32(vsum, voffset);
+      vsum = _mm256_srai_epi32(vsum, shift);
+      if (shiftBack)
+      {
+        vsum = _mm256_min_epi32(vibdimax, _mm256_max_epi32(vibdimin, vsum));
+      }
+      _mm256_storeu_si256((__m256i *)&dst[col], vsum);
+    }
+    src += srcStride;
+    dst += dstStride;
   }
-  else
+#endif
+}
+
+template<X86_VEXT vext, int N, bool shiftBack>
+static void simdInterpolateVerM8_HBD(const Pel *src, int srcStride, Pel *dst, int dstStride, int width, int height, int shift, int offset, const ClpRng& clpRng, Pel const *coeff)
+{
+  const Pel *srcOrig = src;
+  Pel *dstOrig = dst;
+
+  __m128i vcoeff[N], vsrc0[N], vsrc1[N];
+  __m128i vzero = _mm_setzero_si128();
+  __m128i voffset = _mm_set1_epi32(offset);
+  __m128i vibdimin = _mm_set1_epi32(clpRng.min);
+  __m128i vibdimax = _mm_set1_epi32(clpRng.max);
+
+  __m128i vsuma, vsumb;
+  for (int i = 0; i < N; i++)
   {
-    shift -= ( isFirst ) ? headRoom : 0;
-    offset = ( isFirst ) ? -IF_INTERNAL_OFFS << shift : 0;
+    vcoeff[i] = _mm_set1_epi32(coeff[i]);
   }
 
-  if (biMCForDMVR)
+  for (int col = 0; col < width; col += 8)
   {
-    if( isFirst )
+    for (int i = 0; i < N - 1; i++)
     {
-      shift = IF_FILTER_PREC_BILINEAR - (IF_INTERNAL_PREC_BILINEAR - clpRng.bd);
-      offset = 1 << (shift - 1);
+      vsrc0[i] = _mm_lddqu_si128((__m128i const *)&src[col + i * srcStride]);
+      vsrc1[i] = _mm_lddqu_si128((__m128i const *)&src[col + 4 + i * srcStride]);
     }
-    else
+
+    for (int row = 0; row < height; row++)
     {
-      shift = 4;
-      offset = 1 << (shift - 1);
+      vsrc0[N - 1] = _mm_lddqu_si128((__m128i const *)&src[col + (N - 1) * srcStride]);
+      vsrc1[N - 1] = _mm_lddqu_si128((__m128i const *)&src[col + 4 + (N - 1) * srcStride]);
+
+      vsuma = vsumb = vzero;
+      for (int i = 0; i < N; i++)
+      {
+        vsuma = _mm_add_epi32(vsuma, _mm_mullo_epi32(vsrc0[i], vcoeff[i]));
+        vsumb = _mm_add_epi32(vsumb, _mm_mullo_epi32(vsrc1[i], vcoeff[i]));
+      }
+
+      for (int i = 0; i < N - 1; i++)
+      {
+        vsrc0[i] = vsrc0[i + 1];
+        vsrc1[i] = vsrc1[i + 1];
+      }
+
+      vsuma = _mm_add_epi32(vsuma, voffset);
+      vsumb = _mm_add_epi32(vsumb, voffset);
+
+      vsuma = _mm_srai_epi32(vsuma, shift);
+      vsumb = _mm_srai_epi32(vsumb, shift);
+
+      if (shiftBack) //clip
+      {
+        vsuma = _mm_min_epi32(vibdimax, _mm_max_epi32(vibdimin, vsuma));
+        vsumb = _mm_min_epi32(vibdimax, _mm_max_epi32(vibdimin, vsumb));
+      }
+
+      _mm_storeu_si128((__m128i *)&dst[col], vsuma);
+      _mm_storeu_si128((__m128i *)&dst[col + 4], vsumb);
+
+      src += srcStride;
+      dst += dstStride;
     }
+    src = srcOrig;
+    dst = dstOrig;
+  }
+}
+
+template<X86_VEXT vext, int N, bool shiftBack>
+static void simdInterpolateVerM8_HBD_AVX2(const Pel *src, int srcStride, Pel *dst, int dstStride, int width, int height, int shift, int offset, const ClpRng& clpRng, Pel const *coeff)
+{
+#ifdef USE_AVX2
+  __m256i voffset = _mm256_set1_epi32(offset);
+  __m256i vibdimin = _mm256_set1_epi32(clpRng.min);
+  __m256i vibdimax = _mm256_set1_epi32(clpRng.max);
+
+  __m256i vsrc[N], vcoeff[N];
+  for (int i = 0; i < N; i++)
+  {
+    vcoeff[i] = _mm256_set1_epi32(coeff[i]);
   }
+
+  const Pel *srcOrig = src;
+  Pel *dstOrig = dst;
+
+  for (int col = 0; col < width; col += 8)
   {
-    if( N == 8 && !( width & 0x07 ) )
+    for (int i = 0; i < N - 1; i++)
     {
-      if( !isVertical )
+      vsrc[i] = _mm256_loadu_si256((const __m256i *)&src[col + i * srcStride]);
+    }
+
+    for (int row = 0; row < height; row++)
+    {
+      vsrc[N - 1] = _mm256_loadu_si256((const __m256i *)&src[col + (N - 1) * srcStride]);
+
+      __m256i vsum = _mm256_setzero_si256();
+      for (int i = 0; i < N; i++)
       {
-        if( vext>= AVX2 )
-          simdInterpolateHorM8_AVX2<vext, 8, isLast>( src, srcStride, dst, dstStride, width, height, shift, offset, clpRng, c );
-        else
-          simdInterpolateHorM8<vext, 8, isLast>( src, srcStride, dst, dstStride, width, height, shift, offset, clpRng, c );
+        vsum = _mm256_add_epi32(vsum, _mm256_mullo_epi32(vsrc[i], vcoeff[i]));
       }
-      else
+
+      for (int i = 0; i < N - 1; i++)
       {
-        if( vext>= AVX2 )
-          simdInterpolateVerM8_AVX2<vext, 8, isLast>( src, srcStride, dst, dstStride, width, height, shift, offset, clpRng, c );
-        else
-          simdInterpolateVerM8<vext, 8, isLast>( src, srcStride, dst, dstStride, width, height, shift, offset, clpRng, c );
+        vsrc[i] = vsrc[i + 1];
       }
-      return;
-    }
-    else if( N == 8 && !( width & 0x03 ) )
-    {
-      if( !isVertical )
+
+      vsum = _mm256_add_epi32(vsum, voffset);
+      vsum = _mm256_srai_epi32(vsum, shift);
+
+      if (shiftBack)
       {
-        simdInterpolateHorM4<vext, 8, isLast>( src, srcStride, dst, dstStride, width, height, shift, offset, clpRng, c );
+        vsum = _mm256_min_epi32(vibdimax, _mm256_max_epi32(vibdimin, vsum));
       }
-      else
-        simdInterpolateVerM4<vext, 8, isLast>( src, srcStride, dst, dstStride, width, height, shift, offset, clpRng, c );
-      return;
+      _mm256_storeu_si256((__m256i *)&dst[col], vsum);
+
+      src += srcStride;
+      dst += dstStride;
     }
-    else if( N == 4 && !( width & 0x03 ) )
+    src = srcOrig;
+    dst = dstOrig;
+  }
+#endif
+}
+
+template<X86_VEXT vext, int N, bool shiftBack>
+static void simdInterpolateHorM4_HBD(const Pel* src, int srcStride, Pel *dst, int dstStride, int width, int height, int shift, int offset, const ClpRng& clpRng, Pel const *coeff)
+{
+  __m128i voffset = _mm_set1_epi32(offset);
+  __m128i vibdimin = _mm_set1_epi32(clpRng.min);
+  __m128i vibdimax = _mm_set1_epi32(clpRng.max);
+  __m128i vcoeffh0, vcoeffh1, vsum;
+  vcoeffh0 = _mm_lddqu_si128((__m128i const *)coeff);
+  if (N == 8)
+  {
+    vcoeffh1 = _mm_lddqu_si128((__m128i const *)(coeff + 4));
+  }
+
+  for (int row = 0; row < height; row++)
+  {
+    for (int col = 0; col < width; col += 4)
     {
-      if( !isVertical )
+      if (N == 8)
       {
-        if( ( width % 8 ) == 0 )
+        __m128i vtmp[2];
+        for (int i = 0; i < 4; i += 2)
         {
-          if( vext>= AVX2 )
-            simdInterpolateHorM8_AVX2<vext, 4, isLast>( src, srcStride, dst, dstStride, width, height, shift, offset, clpRng, c );
-          else
-            simdInterpolateHorM8<vext, 4, isLast>( src, srcStride, dst, dstStride, width, height, shift, offset, clpRng, c );
+          __m128i vsrc00 = _mm_lddqu_si128((__m128i const *)&src[col + i]);
+          __m128i vsrc01 = _mm_lddqu_si128((__m128i const *)&src[col + i + 4]);
+          __m128i vsrc10 = _mm_lddqu_si128((__m128i const *)&src[col + i + 1]);
+          __m128i vsrc11 = _mm_lddqu_si128((__m128i const *)&src[col + i + 5]);
+
+          __m128i vsrc0 = _mm_add_epi32(_mm_mullo_epi32(vsrc00, vcoeffh0), _mm_mullo_epi32(vsrc01, vcoeffh1));
+          __m128i vsrc1 = _mm_add_epi32(_mm_mullo_epi32(vsrc10, vcoeffh0), _mm_mullo_epi32(vsrc11, vcoeffh1));
+          vtmp[i / 2] = _mm_hadd_epi32(vsrc0, vsrc1);
         }
-        else
-          simdInterpolateHorM4<vext, 4, isLast>( src, srcStride, dst, dstStride, width, height, shift, offset, clpRng, c );
+        vsum = _mm_hadd_epi32(vtmp[0], vtmp[1]);
       }
       else
-        simdInterpolateVerM4<vext, 4, isLast>( src, srcStride, dst, dstStride, width, height, shift, offset, clpRng, c );
-      return;
-    }
-    else if (biMCForDMVR)
-    {
-      if (N == 2 && !(width & 0x03))
       {
-        if (clpRng.bd <= 10)
-        {
-        simdInterpolateN2_10BIT_M4<vext, isLast>(src, srcStride, dst, dstStride, cStride, width, height, shift, offset, clpRng, c);
-        }
-        else
-        {
-          simdInterpolateN2_HIGHBIT_M4<vext, isLast>(src, srcStride, dst, dstStride, cStride, width, height, shift, offset, clpRng, c);
-        }
-        return;
+        __m128i vsrc0 = _mm_lddqu_si128((__m128i const *)&src[col]);
+        __m128i vsrc1 = _mm_lddqu_si128((__m128i const *)&src[col + 1]);
+        __m128i vsrc2 = _mm_lddqu_si128((__m128i const *)&src[col + 2]);
+        __m128i vsrc3 = _mm_lddqu_si128((__m128i const *)&src[col + 3]);
+
+        vsrc0 = _mm_mullo_epi32(vsrc0, vcoeffh0);
+        vsrc1 = _mm_mullo_epi32(vsrc1, vcoeffh0);
+        vsrc2 = _mm_mullo_epi32(vsrc2, vcoeffh0);
+        vsrc3 = _mm_mullo_epi32(vsrc3, vcoeffh0);
+
+        __m128i vsrca = _mm_hadd_epi32(vsrc0, vsrc1);
+        __m128i vsrcb = _mm_hadd_epi32(vsrc2, vsrc3);
+        vsum = _mm_hadd_epi32(vsrca, vsrcb);
       }
+
+      vsum = _mm_add_epi32(vsum, voffset);
+      vsum = _mm_srai_epi32(vsum, shift);
+      if (shiftBack)
+      {
+        vsum = _mm_min_epi32(vibdimax, _mm_max_epi32(vibdimin, vsum));
+      }
+      _mm_storeu_si128((__m128i *)&dst[col], vsum);
     }
-    else if( N == 2 && !( width & 0x07 ) )
-    {
-      simdInterpolateN2_M8<vext, isLast>( src, srcStride, dst, dstStride, cStride, width, height, shift, offset, clpRng, c );
-      return;
-    }
-    else if( N == 2 && !( width & 0x03 ) )
-    {
-      simdInterpolateN2_M4<vext, isLast>( src, srcStride, dst, dstStride, cStride, width, height, shift, offset, clpRng, c );
-      return;
-    }
+    src += srcStride;
+    dst += dstStride;
   }
+}
 
-  for( row = 0; row < height; row++ )
+template<X86_VEXT vext, int N, bool shiftBack>
+static void simdInterpolateVerM4_HBD(const Pel *src, int srcStride, Pel *dst, int dstStride, int width, int height, int shift, int offset, const ClpRng& clpRng, Pel const *coeff)
+{
+  const Pel *srcOrig = src;
+  Pel *dstOrig = dst;
+
+  __m128i vsum, vcoeff[N], vsrc[N];
+  __m128i vzero = _mm_setzero_si128();
+  __m128i voffset = _mm_set1_epi32(offset);
+  __m128i vibdimin = _mm_set1_epi32(clpRng.min);
+  __m128i vibdimax = _mm_set1_epi32(clpRng.max);
+  for (int i = 0; i < N; i++)
   {
-    for( col = 0; col < width; col++ )
+    vcoeff[i] = _mm_set1_epi32(coeff[i]);
+  }
+
+  for (int col = 0; col < width; col += 4)
+  {
+    for (int i = 0; i < N - 1; i++)
     {
-      int sum;
+      vsrc[i] = _mm_lddqu_si128((__m128i const *)&src[col + i * srcStride]);
+    }
 
-      sum  = src[col + 0 * cStride] * c[0];
-      sum += src[col + 1 * cStride] * c[1];
-      if( N >= 4 )
-      {
-        sum += src[col + 2 * cStride] * c[2];
-        sum += src[col + 3 * cStride] * c[3];
-      }
-      if( N >= 6 )
+    for (int row = 0; row < height; row++)
+    {
+      vsrc[N - 1] = _mm_lddqu_si128((__m128i const *)&src[col + (N - 1) * srcStride]);
+
+      vsum = vzero;
+      for (int i = 0; i < N; i++)
       {
-        sum += src[col + 4 * cStride] * c[4];
-        sum += src[col + 5 * cStride] * c[5];
+        vsum = _mm_add_epi32(vsum, _mm_mullo_epi32(vsrc[i], vcoeff[i]));
       }
-      if( N == 8 )
+
+      vsum = _mm_add_epi32(vsum, voffset);
+      vsum = _mm_srai_epi32(vsum, shift);
+
+      if (shiftBack)
       {
-        sum += src[col + 6 * cStride] * c[6];
-        sum += src[col + 7 * cStride] * c[7];
+        vsum = _mm_min_epi32(vibdimax, _mm_max_epi32(vibdimin, vsum));
       }
 
-      Pel val = ( sum + offset ) >> shift;
-      if( isLast )
+      _mm_storeu_si128((__m128i *)&dst[col], vsum);
+
+      for (int i = 0; i < N - 1; i++)
       {
-        val = ClipPel( val, clpRng );
+        vsrc[i] = vsrc[i + 1];
       }
-      dst[col] = val;
-    }
 
-    src += srcStride;
-    dst += dstStride;
+      src += srcStride;
+      dst += dstStride;
+    }
+    src = srcOrig;
+    dst = dstOrig;
   }
 }
 
-template< X86_VEXT vext >
-void xWeightedGeoBlk_SSE(const PredictionUnit &pu, const uint32_t width, const uint32_t height, const ComponentID compIdx, const uint8_t splitDir, PelUnitBuf& predDst, PelUnitBuf& predSrc0, PelUnitBuf& predSrc1)
+template<X86_VEXT vext, bool isLast>
+static void simdInterpolateN2_M8_HBD(const Pel* src, int srcStride, Pel *dst, int dstStride, int cStride, int width, int height, int shift, int offset, const ClpRng& clpRng, Pel const *c)
 {
-  Pel* dst = predDst.get(compIdx).buf;
-  Pel* src0 = predSrc0.get(compIdx).buf;
-  Pel* src1 = predSrc1.get(compIdx).buf;
+  int row, col;
+  __m128i mmOffset = _mm_set1_epi32(offset);
+  __m128i mmMin = _mm_set1_epi32(clpRng.min);
+  __m128i mmMax = _mm_set1_epi32(clpRng.max);
+  __m128i mmCoeff[2];
+  for (int n = 0; n < 2; n++)
+  {
+    mmCoeff[n] = _mm_set1_epi32(c[n]);
+  }
+
+  for (row = 0; row < height; row++)
+  {
+    for (col = 0; col < width; col += 8)
+    {
+      const Pel* src_tmp = src;
+      __m128i vsuma = _mm_setzero_si128();
+      __m128i vsumb = _mm_setzero_si128();
+
+      for (int i = 0; i < 2; i++)
+      {
+        __m128i vsrc0 = _mm_lddqu_si128((__m128i *)&src_tmp[col]);
+        __m128i vsrc1 = _mm_lddqu_si128((__m128i *)&src_tmp[col + 4]);
+        vsuma = _mm_add_epi32(vsuma, _mm_mullo_epi32(vsrc0, mmCoeff[i]));
+        vsumb = _mm_add_epi32(vsumb, _mm_mullo_epi32(vsrc1, mmCoeff[i]));
+        src_tmp += cStride;
+      }
+
+      vsuma = _mm_srai_epi32(_mm_add_epi32(vsuma, mmOffset), shift);
+      vsumb = _mm_srai_epi32(_mm_add_epi32(vsumb, mmOffset), shift);
+      if (isLast)
+      {
+        vsuma = _mm_min_epi32(mmMax, _mm_max_epi32(mmMin, vsuma));
+        vsumb = _mm_min_epi32(mmMax, _mm_max_epi32(mmMin, vsumb));
+      }
+
+      _mm_storeu_si128((__m128i *)&dst[col], vsuma);
+      _mm_storeu_si128((__m128i *)&dst[col + 4], vsumb);
+    }
+    src += srcStride;
+    dst += dstStride;
+  }
+}
+
+template<X86_VEXT vext, bool isLast>
+static void simdInterpolateN2_M4_HBD(const Pel* src, int srcStride, Pel *dst, int dstStride, int cStride, int width, int height, int shift, int offset, const ClpRng& clpRng, Pel const *c)
+{
+  int row, col;
+  __m128i mmOffset = _mm_set1_epi32(offset);
+  __m128i mmMin = _mm_set1_epi32(clpRng.min);
+  __m128i mmMax = _mm_set1_epi32(clpRng.max);
+  __m128i mmCoeff[2];
+  for (int n = 0; n < 2; n++)
+  {
+    mmCoeff[n] = _mm_set1_epi32(c[n]);
+  }
+
+  for (row = 0; row < height; row++)
+  {
+    for (col = 0; col < width; col += 4)
+    {
+      const Pel* src_tmp = src;
+      __m128i vsum = _mm_setzero_si128();
+
+      for (int i = 0; i < 2; i++)
+      {
+        __m128i vsrc = _mm_lddqu_si128((__m128i *)&src_tmp[col]);
+        vsum = _mm_add_epi32(vsum, _mm_mullo_epi32(vsrc, mmCoeff[i]));
+        src_tmp += cStride;
+      }
+
+      vsum = _mm_srai_epi32(_mm_add_epi32(vsum, mmOffset), shift);
+      if (isLast)
+      {
+        vsum = _mm_min_epi32(mmMax, _mm_max_epi32(mmMin, vsum));
+      }
+
+      _mm_storeu_si128((__m128i *)&dst[col], vsum);
+    }
+    src += srcStride;
+    dst += dstStride;
+  }
+}
+
+template<X86_VEXT vext, bool isLast>
+static void simdInterpolateN2_HBD_M4(const Pel* src, int srcStride, Pel *dst, int dstStride, int cStride, int width, int height, int shift, int offset, const ClpRng& clpRng, Pel const *c)
+{
+  CHECK(isLast, "Not Supported");
+  CHECK(width % 4 != 0, "Not Supported");
+
+  __m128i mmOffset = _mm_set1_epi32(offset);
+  __m128i mmCoeff[2];
+  for (int n = 0; n < 2; n++)
+  {
+    mmCoeff[n] = _mm_set1_epi32(c[n]);
+  }
+
+  for (int row = 0; row < height; row++)
+  {
+    for (int col = 0; col < width; col += 4)
+    {
+      const Pel* src_tmp = src;
+      __m128i vsum = _mm_setzero_si128();
+      for (int i = 0; i < 2; i++)
+      {
+        __m128i vsrc = _mm_lddqu_si128((__m128i *)&src_tmp[col]);
+        vsum = _mm_add_epi32(vsum, _mm_mullo_epi32(vsrc, mmCoeff[i]));
+        src_tmp += cStride;
+      }
+      vsum = _mm_srai_epi32(_mm_add_epi32(vsum, mmOffset), shift);
+      _mm_storeu_si128((__m128i *)&dst[col], vsum);
+    }
+    src += srcStride;
+    dst += dstStride;
+  }
+}
+
+template<X86_VEXT vext, bool isLast>
+static void simdInterpolateN2_HBD_M4_AVX2(const Pel* src, int srcStride, Pel *dst, int dstStride, int cStride, int width, int height, int shift, int offset, const ClpRng& clpRng, Pel const *c)
+{
+#ifdef USE_AVX2
+  CHECK(isLast, "Not Supported");
+  CHECK(width % 4 != 0, "Not Supported");
+
+  __m256i mmOffset = _mm256_set1_epi32(offset);
+  __m256i mmCoeff[2];
+  for (int n = 0; n < 2; n++)
+  {
+    mmCoeff[n] = _mm256_set1_epi32(c[n]);
+  }
+
+  int srcStride2 = (srcStride << 1);
+  int dstStride2 = (dstStride << 1);
+
+  for (int row = 0; row < height; row += 2)
+  {
+    for (int col = 0; col < width; col += 4)
+    {
+      const Pel* src_tmp = src;
+      __m256i vsum = _mm256_setzero_si256();
+      for (int i = 0; i < 2; i++)
+      {
+        __m256i vsrc = _mm256_castsi128_si256(_mm_lddqu_si128((__m128i *)&src_tmp[col]));
+        vsrc = _mm256_inserti128_si256(vsrc, _mm_lddqu_si128((__m128i *)&src_tmp[col + srcStride]), 1);
+        vsum = _mm256_add_epi32(vsum, _mm256_mullo_epi32(vsrc, mmCoeff[i]));
+        src_tmp += cStride;
+      }
+      vsum = _mm256_srai_epi32(_mm256_add_epi32(vsum, mmOffset), shift);
+
+      _mm_storeu_si128((__m128i *)&dst[col], _mm256_castsi256_si128(vsum));
+      _mm_storeu_si128((__m128i *)&dst[col + dstStride], _mm256_castsi256_si128(_mm256_permute4x64_epi64(vsum, 0xee)));
+    }
+    src += srcStride2;
+    dst += dstStride2;
+  }
+#endif
+}
+
+template<X86_VEXT vext, bool isFirst, bool isLast>
+static void simdFilterCopy_HBD(const ClpRng& clpRng, const Pel* src, int srcStride, Pel* dst, int dstStride, int width, int height, bool biMCForDMVR)
+{
+  int row;
+
+  if (isFirst == isLast)
+  {
+    for (row = 0; row < height; row++)
+    {
+      memcpy(&dst[0], &src[0], width * sizeof(Pel));
+      src += srcStride;
+      dst += dstStride;
+    }
+  }
+  else if (isFirst)
+  {
+    if (width & 1)
+    {
+      InterpolationFilter::filterCopy<isFirst, isLast>(clpRng, src, srcStride, dst, dstStride, width, height,
+                                                       biMCForDMVR);
+      return;
+    }
+
+    if (biMCForDMVR)
+    {
+      int shift10BitOut = (clpRng.bd - IF_INTERNAL_PREC_BILINEAR);
+      if (shift10BitOut <= 0)
+      {
+        const __m128i shift = _mm_cvtsi32_si128(-shift10BitOut);
+        for (row = 0; row < height; row++)
+        {
+          int col = 0;
+#ifdef USE_AVX2
+          if (vext >= AVX2)
+          {
+            for (; col < ((width >> 3) << 3); col += 8)
+            {
+              __m256i val = _mm256_lddqu_si256((__m256i *) &src[col]);
+              val         = _mm256_sll_epi32(val, shift);
+              _mm256_storeu_si256((__m256i *) &dst[col], val);
+            }
+          }
+#endif
+
+          for (; col < ((width >> 2) << 2); col += 4)
+          {
+            __m128i val = _mm_lddqu_si128((__m128i *) &src[col]);
+            val         = _mm_sll_epi32(val, shift);
+            _mm_storeu_si128((__m128i *) &dst[col], val);
+          }
+
+          for (; col < width; col += 2)
+          {
+            __m128i val = _mm_loadl_epi64((__m128i *) &src[col]);
+            val         = _mm_sll_epi32(val, shift);
+            _mm_storel_epi64((__m128i *) &dst[col], val);
+          }
+          src += srcStride;
+          dst += dstStride;
+        }
+      }
+      else
+      {
+        int offset = (1 << (shift10BitOut - 1));
+        for (row = 0; row < height; row++)
+        {
+          int col = 0;
+#ifdef USE_AVX2
+          if (vext >= AVX2)
+          {
+            __m256i mm256_offset = _mm256_set1_epi32(offset);
+            for (; col < ((width >> 3) << 3); col += 8)
+            {
+              __m256i vsrc = _mm256_lddqu_si256((__m256i *) &src[col]);
+              vsrc         = _mm256_srai_epi32(_mm256_add_epi32(vsrc, mm256_offset), shift10BitOut);
+              _mm256_storeu_si256((__m256i *) &dst[col], vsrc);
+            }
+          }
+#endif
+
+          __m128i mm128_offset = _mm_set1_epi32(offset);
+          for (; col < ((width >> 2) << 2); col += 4)
+          {
+            __m128i vsrc = _mm_lddqu_si128((__m128i *) &src[col]);
+            vsrc         = _mm_srai_epi32(_mm_add_epi32(vsrc, mm128_offset), shift10BitOut);
+            _mm_storeu_si128((__m128i *) &dst[col], vsrc);
+          }
+
+          for (; col < width; col += 2)
+          {
+            __m128i vsrc = _mm_loadl_epi64((__m128i *) &src[col]);
+            vsrc         = _mm_srai_epi32(_mm_add_epi32(vsrc, mm128_offset), shift10BitOut);
+            _mm_storel_epi64((__m128i *) &dst[col], vsrc);
+          }
+          src += srcStride;
+          dst += dstStride;
+        }
+      }
+    }
+    else
+    {
+      const int shift = IF_INTERNAL_FRAC_BITS(clpRng.bd);
+      for (row = 0; row < height; row++)
+      {
+        int col = 0;
+#ifdef USE_AVX2
+        if (vext >= AVX2)
+        {
+          __m256i mm256_offset = _mm256_set1_epi32(IF_INTERNAL_OFFS);
+          for (; col < ((width >> 3) << 3); col += 8)
+          {
+            __m256i vsrc = _mm256_lddqu_si256((__m256i *)&src[col]);
+            vsrc = _mm256_sub_epi32(_mm256_slli_epi32(vsrc, shift), mm256_offset);
+            _mm256_storeu_si256((__m256i *)&dst[col], vsrc);
+          }
+        }
+#endif
+
+        __m128i mm128_offset = _mm_set1_epi32(IF_INTERNAL_OFFS);
+        for (; col < ((width >> 2) << 2); col += 4)
+        {
+          __m128i vsrc = _mm_lddqu_si128((__m128i *)&src[col]);
+          vsrc = _mm_sub_epi32(_mm_slli_epi32(vsrc, shift), mm128_offset);
+          _mm_storeu_si128((__m128i *)&dst[col], vsrc);
+        }
+
+        for (; col < width; col += 2)
+        {
+          __m128i vsrc = _mm_loadl_epi64((__m128i *)&src[col]);
+          vsrc = _mm_sub_epi32(_mm_slli_epi32(vsrc, shift), mm128_offset);
+          _mm_storel_epi64((__m128i *)&dst[col], vsrc);
+        }
+        src += srcStride;
+        dst += dstStride;
+      }
+    }
+  }
+  else
+  {
+    if (width & 1)
+    {
+      InterpolationFilter::filterCopy<isFirst, isLast>(clpRng, src, srcStride, dst, dstStride, width, height,
+                                                       biMCForDMVR);
+      return;
+    }
+
+    CHECK(biMCForDMVR, "isLast must be false when biMCForDMVR is true");
+    const int shift = IF_INTERNAL_FRAC_BITS(clpRng.bd);
+    for (row = 0; row < height; row++)
+    {
+      int col = 0;
+#ifdef USE_AVX2
+      if (vext >= AVX2)
+      {
+        __m256i mm256_offset = _mm256_set1_epi32(IF_INTERNAL_OFFS);
+        __m256i mm256_min    = _mm256_set1_epi32(clpRng.min);
+        __m256i mm256_max    = _mm256_set1_epi32(clpRng.max);
+        for (; col < ((width >> 3) << 3); col += 8)
+        {
+          __m256i vsrc = _mm256_lddqu_si256((__m256i *) &src[col]);
+          vsrc         = _mm256_add_epi32(vsrc, mm256_offset);
+          if (shift <= 0)
+          {
+            vsrc = _mm256_slli_epi32(vsrc, (-shift));
+          }
+          else
+          {
+            vsrc = _mm256_srai_epi32(_mm256_add_epi32(vsrc, _mm256_set1_epi32(1 << (shift - 1))), shift);
+          }
+          vsrc = _mm256_min_epi32(mm256_max, _mm256_max_epi32(mm256_min, vsrc));
+
+          _mm256_storeu_si256((__m256i *) &dst[col], vsrc);
+        }
+      }
+#endif
+
+      __m128i mm128_offset = _mm_set1_epi32(IF_INTERNAL_OFFS);
+      __m128i mm128_min    = _mm_set1_epi32(clpRng.min);
+      __m128i mm128_max    = _mm_set1_epi32(clpRng.max);
+      for (; col < ((width >> 2) << 2); col += 4)
+      {
+        __m128i vsrc = _mm_lddqu_si128((__m128i *) &src[col]);
+        vsrc         = _mm_add_epi32(vsrc, mm128_offset);
+        if (shift <= 0)
+        {
+          vsrc = _mm_slli_epi32(vsrc, (-shift));
+        }
+        else
+        {
+          vsrc = _mm_srai_epi32(_mm_add_epi32(vsrc, _mm_set1_epi32(1 << (shift - 1))), shift);
+        }
+        vsrc = _mm_min_epi32(mm128_max, _mm_max_epi32(mm128_min, vsrc));
+
+        _mm_storeu_si128((__m128i *) &dst[col], vsrc);
+      }
+
+      for (; col < width; col += 2)
+      {
+        __m128i vsrc = _mm_loadl_epi64((__m128i *) &src[col]);
+        vsrc         = _mm_add_epi32(vsrc, mm128_offset);
+        if (shift <= 0)
+        {
+          vsrc = _mm_slli_epi32(vsrc, (-shift));
+        }
+        else
+        {
+          vsrc = _mm_srai_epi32(_mm_add_epi32(vsrc, _mm_set1_epi32(1 << (shift - 1))), shift);
+        }
+        vsrc = _mm_min_epi32(mm128_max, _mm_max_epi32(mm128_min, vsrc));
+
+        _mm_storel_epi64((__m128i *) &dst[col], vsrc);
+      }
+
+      src += srcStride;
+      dst += dstStride;
+    }
+  }
+}
+
+template< X86_VEXT vext >
+void xWeightedGeoBlk_HBD_SIMD(const PredictionUnit &pu, const uint32_t width, const uint32_t height, const ComponentID compIdx, const uint8_t splitDir, PelUnitBuf& predDst, PelUnitBuf& predSrc0, PelUnitBuf& predSrc1)
+{
+  Pel* dst = predDst.get(compIdx).buf;
+  Pel* src0 = predSrc0.get(compIdx).buf;
+  Pel* src1 = predSrc1.get(compIdx).buf;
+  int32_t strideDst = predDst.get(compIdx).stride;
+  int32_t strideSrc0 = predSrc0.get(compIdx).stride;
+  int32_t strideSrc1 = predSrc1.get(compIdx).stride;
+
+  const char    log2WeightBase = 3;
+  const ClpRng  clpRng = pu.cu->slice->clpRngs().comp[compIdx];
+  const int32_t shiftWeighted = IF_INTERNAL_FRAC_BITS(clpRng.bd) + log2WeightBase;
+  const int32_t offsetWeighted = (1 << (shiftWeighted - 1)) + (IF_INTERNAL_OFFS << log2WeightBase);
+
+  int16_t wIdx = floorLog2(pu.lwidth()) - GEO_MIN_CU_LOG2;
+  int16_t hIdx = floorLog2(pu.lheight()) - GEO_MIN_CU_LOG2;
+  int16_t angle = g_GeoParams[splitDir][0];
+  int16_t stepY = 0;
+  int16_t* weight = nullptr;
+  if (g_angle2mirror[angle] == 2)
+  {
+    stepY = -GEO_WEIGHT_MASK_SIZE;
+    weight = &g_globalGeoWeights[g_angle2mask[angle]][(GEO_WEIGHT_MASK_SIZE - 1 - g_weightOffset[splitDir][hIdx][wIdx][1]) * GEO_WEIGHT_MASK_SIZE + g_weightOffset[splitDir][hIdx][wIdx][0]];
+  }
+  else if (g_angle2mirror[angle] == 1)
+  {
+    stepY = GEO_WEIGHT_MASK_SIZE;
+    weight = &g_globalGeoWeights[g_angle2mask[angle]][g_weightOffset[splitDir][hIdx][wIdx][1] * GEO_WEIGHT_MASK_SIZE + (GEO_WEIGHT_MASK_SIZE - 1 - g_weightOffset[splitDir][hIdx][wIdx][0])];
+  }
+  else
+  {
+    stepY = GEO_WEIGHT_MASK_SIZE;
+    weight = &g_globalGeoWeights[g_angle2mask[angle]][g_weightOffset[splitDir][hIdx][wIdx][1] * GEO_WEIGHT_MASK_SIZE + g_weightOffset[splitDir][hIdx][wIdx][0]];
+  }
+
+  const __m128i mmEight = _mm_set1_epi16(8);
+  const __m128i mmOffset = _mm_set1_epi32(offsetWeighted);
+  const __m128i mmShift = _mm_cvtsi32_si128(shiftWeighted);
+  const __m128i mmMin = _mm_set1_epi32(clpRng.min);
+  const __m128i mmMax = _mm_set1_epi32(clpRng.max);
+
+  if (compIdx != COMPONENT_Y && pu.chromaFormat == CHROMA_420)
+    stepY <<= 1;
+
+  if (width == 4)
+  {
+    // it will occur to chroma only
+    for (int y = 0; y < height; y++)
+    {
+      __m128i s0 = _mm_lddqu_si128((__m128i *) (src0));
+      __m128i s1 = _mm_lddqu_si128((__m128i *) (src1));
+      __m128i w0;
+      if (g_angle2mirror[angle] == 1)
+      {
+        w0 = _mm_loadu_si128((__m128i *) (weight - (8 - 1)));
+        const __m128i shuffle_mask = _mm_set_epi8(1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14);
+        w0 = _mm_shuffle_epi8(w0, shuffle_mask);
+      }
+      else
+      {
+        w0 = _mm_loadu_si128((__m128i *) (weight));
+      }
+      w0 = _mm_shuffle_epi8(w0, _mm_setr_epi8(0, 1, 4, 5, 8, 9, 12, 13, 0, 0, 0, 0, 0, 0, 0, 0));
+      __m128i w1 = _mm_sub_epi16(mmEight, w0);
+
+      w0 = _mm_cvtepi16_epi32(w0);
+      w1 = _mm_cvtepi16_epi32(w1);
+
+      s0 = _mm_add_epi32(_mm_mullo_epi32(s0, w0), _mm_mullo_epi32(s1, w1));
+      s0 = _mm_sra_epi32(_mm_add_epi32(s0, mmOffset), mmShift);
+      s0 = _mm_min_epi32(mmMax, _mm_max_epi32(s0, mmMin));
+
+      _mm_storeu_si128((__m128i *)dst, s0);
+
+      dst += strideDst;
+      src0 += strideSrc0;
+      src1 += strideSrc1;
+      weight += stepY;
+    }
+  }
+#ifdef USE_AVX2
+  else if ((vext >= AVX2) && (width >= 16))
+  {
+    const __m256i mmEightAVX2 = _mm256_set1_epi16(8);
+    const __m256i mmOffsetAVX2 = _mm256_set1_epi32(offsetWeighted);
+    const __m256i mmMinAVX2 = _mm256_set1_epi32(clpRng.min);
+    const __m256i mmMaxAVX2 = _mm256_set1_epi32(clpRng.max);
+    for (int y = 0; y < height; y++)
+    {
+      for (int x = 0; x < width; x += 16)
+      {
+        __m256i s00 = _mm256_lddqu_si256((__m256i *) (src0 + x));
+        __m256i s01 = _mm256_lddqu_si256((__m256i *) (src0 + x + 8));
+        __m256i s10 = _mm256_lddqu_si256((__m256i *) (src1 + x));
+        __m256i s11 = _mm256_lddqu_si256((__m256i *) (src1 + x + 8));
+
+        __m256i w0 = _mm256_lddqu_si256((__m256i *) (weight + x));
+        if (compIdx != COMPONENT_Y && pu.chromaFormat != CHROMA_444)
+        {
+          const __m256i mask = _mm256_set_epi16(0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1);
+          __m256i w0p0, w0p1;
+          if (g_angle2mirror[angle] == 1)
+          {
+            w0p0 = _mm256_lddqu_si256((__m256i *) (weight - (x << 1) - (16 - 1))); // first sub-sample the required weights.
+            w0p1 = _mm256_lddqu_si256((__m256i *) (weight - (x << 1) - 16 - (16 - 1)));
+            const __m256i shuffle_mask = _mm256_set_epi8(1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14, 1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14);
+            w0p0 = _mm256_shuffle_epi8(w0p0, shuffle_mask);
+            w0p0 = _mm256_permute4x64_epi64(w0p0, _MM_SHUFFLE(1, 0, 3, 2));
+            w0p1 = _mm256_shuffle_epi8(w0p1, shuffle_mask);
+            w0p1 = _mm256_permute4x64_epi64(w0p1, _MM_SHUFFLE(1, 0, 3, 2));
+          }
+          else
+          {
+            w0p0 = _mm256_lddqu_si256((__m256i *) (weight + (x << 1))); // first sub-sample the required weights.
+            w0p1 = _mm256_lddqu_si256((__m256i *) (weight + (x << 1) + 16));
+          }
+          w0p0 = _mm256_mullo_epi16(w0p0, mask);
+          w0p1 = _mm256_mullo_epi16(w0p1, mask);
+          w0 = _mm256_packs_epi16(w0p0, w0p1);
+          w0 = _mm256_permute4x64_epi64(w0, _MM_SHUFFLE(3, 1, 2, 0));
+        }
+        else
+        {
+          if (g_angle2mirror[angle] == 1)
+          {
+            w0 = _mm256_lddqu_si256((__m256i *) (weight - x - (16 - 1)));
+            const __m256i shuffle_mask = _mm256_set_epi8(1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14, 1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14);
+            w0 = _mm256_shuffle_epi8(w0, shuffle_mask);
+            w0 = _mm256_permute4x64_epi64(w0, _MM_SHUFFLE(1, 0, 3, 2));
+          }
+          else
+          {
+            w0 = _mm256_lddqu_si256((__m256i *) (weight + x));
+          }
+        }
+        __m256i w1 = _mm256_sub_epi16(mmEightAVX2, w0);
+
+        __m256i w00 = _mm256_cvtepi16_epi32(_mm256_castsi256_si128(w0));
+        __m256i w01 = _mm256_cvtepi16_epi32(_mm256_castsi256_si128(_mm256_permute4x64_epi64(w0, 0xee)));
+        __m256i w10 = _mm256_cvtepi16_epi32(_mm256_castsi256_si128(w1));
+        __m256i w11 = _mm256_cvtepi16_epi32(_mm256_castsi256_si128(_mm256_permute4x64_epi64(w1, 0xee)));
+
+        __m256i s0 = _mm256_add_epi32(_mm256_mullo_epi32(s00, w00), _mm256_mullo_epi32(s10, w10));
+        __m256i s1 = _mm256_add_epi32(_mm256_mullo_epi32(s01, w01), _mm256_mullo_epi32(s11, w11));
+
+        s0 = _mm256_sra_epi32(_mm256_add_epi32(s0, mmOffsetAVX2), mmShift);
+        s1 = _mm256_sra_epi32(_mm256_add_epi32(s1, mmOffsetAVX2), mmShift);
+
+        s0 = _mm256_min_epi32(mmMaxAVX2, _mm256_max_epi32(s0, mmMinAVX2));
+        s1 = _mm256_min_epi32(mmMaxAVX2, _mm256_max_epi32(s1, mmMinAVX2));
+
+        _mm256_storeu_si256((__m256i *) (dst + x), s0);
+        _mm256_storeu_si256((__m256i *) (dst + x + 8), s1);
+      }
+
+      dst += strideDst;
+      src0 += strideSrc0;
+      src1 += strideSrc1;
+      weight += stepY;
+    }
+  }
+#endif
+  else
+  {
+    for (int y = 0; y < height; y++)
+    {
+      for (int x = 0; x < width; x += 8)
+      {
+        __m128i s00 = _mm_lddqu_si128((__m128i *) (src0 + x));
+        __m128i s01 = _mm_lddqu_si128((__m128i *) (src0 + x + 4));
+        __m128i s10 = _mm_lddqu_si128((__m128i *) (src1 + x));
+        __m128i s11 = _mm_lddqu_si128((__m128i *) (src1 + x + 4));
+        __m128i w0;
+        if (compIdx != COMPONENT_Y && pu.chromaFormat != CHROMA_444)
+        {
+          const __m128i mask = _mm_set_epi16(0, 1, 0, 1, 0, 1, 0, 1);
+          __m128i w0p0, w0p1;
+          if (g_angle2mirror[angle] == 1)
+          {
+            w0p0 = _mm_lddqu_si128((__m128i *) (weight - (x << 1) - (8 - 1))); // first sub-sample the required weights.
+            w0p1 = _mm_lddqu_si128((__m128i *) (weight - (x << 1) - 8 - (8 - 1)));
+            const __m128i shuffle_mask = _mm_set_epi8(1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14);
+            w0p0 = _mm_shuffle_epi8(w0p0, shuffle_mask);
+            w0p1 = _mm_shuffle_epi8(w0p1, shuffle_mask);
+          }
+          else
+          {
+            w0p0 = _mm_lddqu_si128((__m128i *) (weight + (x << 1))); // first sub-sample the required weights.
+            w0p1 = _mm_lddqu_si128((__m128i *) (weight + (x << 1) + 8));
+          }
+          w0p0 = _mm_mullo_epi16(w0p0, mask);
+          w0p1 = _mm_mullo_epi16(w0p1, mask);
+          w0 = _mm_packs_epi32(w0p0, w0p1);
+        }
+        else
+        {
+          if (g_angle2mirror[angle] == 1)
+          {
+            w0 = _mm_lddqu_si128((__m128i *) (weight - x - (8 - 1)));  // 16b
+            const __m128i shuffle_mask = _mm_set_epi8(1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14);
+            w0 = _mm_shuffle_epi8(w0, shuffle_mask);
+          }
+          else
+          {
+            w0 = _mm_lddqu_si128((__m128i *) (weight + x));
+          }
+        }
+        __m128i w1 = _mm_sub_epi16(mmEight, w0);
+
+        __m128i w00 = _mm_cvtepi16_epi32(w0);
+        __m128i w01 = _mm_cvtepi16_epi32(_mm_shuffle_epi32(w0, 0xee));
+        __m128i w10 = _mm_cvtepi16_epi32(w1);
+        __m128i w11 = _mm_cvtepi16_epi32(_mm_shuffle_epi32(w1, 0xee));
+
+        __m128i s0 = _mm_add_epi32(_mm_mullo_epi32(s00, w00), _mm_mullo_epi32(s10, w10));
+        __m128i s1 = _mm_add_epi32(_mm_mullo_epi32(s01, w01), _mm_mullo_epi32(s11, w11));
+
+        s0 = _mm_sra_epi32(_mm_add_epi32(s0, mmOffset), mmShift);
+        s1 = _mm_sra_epi32(_mm_add_epi32(s1, mmOffset), mmShift);
+
+        s0 = _mm_min_epi32(mmMax, _mm_max_epi32(s0, mmMin));
+        s1 = _mm_min_epi32(mmMax, _mm_max_epi32(s1, mmMin));
+
+        _mm_storeu_si128((__m128i *) (dst + x), s0);
+        _mm_storeu_si128((__m128i *) (dst + x + 4), s1);
+      }
+      dst += strideDst;
+      src0 += strideSrc0;
+      src1 += strideSrc1;
+      weight += stepY;
+    }
+  }
+}
+#endif
+template<X86_VEXT vext, int N, bool isVertical, bool isFirst, bool isLast>
+static void simdFilter( const ClpRng& clpRng, Pel const *src, int srcStride, Pel *dst, int dstStride, int width, int height, TFilterCoeff const *coeff, bool biMCForDMVR)
+{
+  int row, col;
+
+  Pel c[8];
+  c[0] = coeff[0];
+  c[1] = coeff[1];
+  if( N >= 4 )
+  {
+    c[2] = coeff[2];
+    c[3] = coeff[3];
+  }
+  if( N >= 6 )
+  {
+    c[4] = coeff[4];
+    c[5] = coeff[5];
+  }
+  if( N == 8 )
+  {
+    c[6] = coeff[6];
+    c[7] = coeff[7];
+  }
+
+  int cStride = ( isVertical ) ? srcStride : 1;
+  src -= ( N/2 - 1 ) * cStride;
+
+  int offset;
+  int headRoom = IF_INTERNAL_FRAC_BITS(clpRng.bd);
+  int shift    = IF_FILTER_PREC;
+  // with the current settings (IF_INTERNAL_PREC = 14 and IF_FILTER_PREC = 6), though headroom can be
+  // negative for bit depths greater than 14, shift will remain non-negative for bit depths of 8->20
+  CHECK( shift < 0, "Negative shift" );
+
+
+  if( isLast )
+  {
+    shift += ( isFirst ) ? 0 : headRoom;
+    offset = 1 << ( shift - 1 );
+    offset += ( isFirst ) ? 0 : IF_INTERNAL_OFFS << IF_FILTER_PREC;
+  }
+  else
+  {
+    shift -= ( isFirst ) ? headRoom : 0;
+    offset = ( isFirst ) ? -IF_INTERNAL_OFFS << shift : 0;
+  }
+
+  if (biMCForDMVR)
+  {
+    if( isFirst )
+    {
+      shift = IF_FILTER_PREC_BILINEAR - (IF_INTERNAL_PREC_BILINEAR - clpRng.bd);
+      offset = 1 << (shift - 1);
+    }
+    else
+    {
+      shift = 4;
+      offset = 1 << (shift - 1);
+    }
+  }
+  {
+    if( N == 8 && !( width & 0x07 ) )
+    {
+      if( !isVertical )
+      {
+#if RExt__HIGH_BIT_DEPTH_SUPPORT
+        if (vext >= AVX2)
+        {
+          simdInterpolateHorM8_HBD_AVX2<vext, 8, isLast>(src, srcStride, dst, dstStride, width, height, shift, offset, clpRng, c);
+        }
+        else
+        {
+          simdInterpolateHorM8_HBD<vext, 8, isLast>(src, srcStride, dst, dstStride, width, height, shift, offset, clpRng, c);
+        }
+#else
+        if( vext>= AVX2 )
+          simdInterpolateHorM8_AVX2<vext, 8, isLast>( src, srcStride, dst, dstStride, width, height, shift, offset, clpRng, c );
+        else
+          simdInterpolateHorM8<vext, 8, isLast>( src, srcStride, dst, dstStride, width, height, shift, offset, clpRng, c );
+#endif
+      }
+      else
+      {
+#if RExt__HIGH_BIT_DEPTH_SUPPORT
+        if (vext >= AVX2)
+        {
+          simdInterpolateVerM8_HBD_AVX2<vext, 8, isLast>(src, srcStride, dst, dstStride, width, height, shift, offset, clpRng, c);
+        }
+        else
+        {
+          simdInterpolateVerM8_HBD<vext, 8, isLast>(src, srcStride, dst, dstStride, width, height, shift, offset, clpRng, c);
+        }
+#else
+        if( vext>= AVX2 )
+          simdInterpolateVerM8_AVX2<vext, 8, isLast>( src, srcStride, dst, dstStride, width, height, shift, offset, clpRng, c );
+        else
+          simdInterpolateVerM8<vext, 8, isLast>( src, srcStride, dst, dstStride, width, height, shift, offset, clpRng, c );
+#endif
+      }
+      return;
+    }
+    else if( N == 8 && !( width & 0x03 ) )
+    {
+      if( !isVertical )
+      {
+#if RExt__HIGH_BIT_DEPTH_SUPPORT
+        simdInterpolateHorM4_HBD<vext, 8, isLast>(src, srcStride, dst, dstStride, width, height, shift, offset, clpRng, c);
+#else
+        simdInterpolateHorM4<vext, 8, isLast>( src, srcStride, dst, dstStride, width, height, shift, offset, clpRng, c );
+#endif
+      }
+      else
+#if RExt__HIGH_BIT_DEPTH_SUPPORT
+        simdInterpolateVerM4_HBD<vext, 8, isLast>(src, srcStride, dst, dstStride, width, height, shift, offset, clpRng, c);
+#else
+        simdInterpolateVerM4<vext, 8, isLast>( src, srcStride, dst, dstStride, width, height, shift, offset, clpRng, c );
+#endif
+      return;
+    }
+    else if( N == 4 && !( width & 0x03 ) )
+    {
+      if( !isVertical )
+      {
+        if( ( width % 8 ) == 0 )
+        {
+#if RExt__HIGH_BIT_DEPTH_SUPPORT
+          if (vext >= AVX2)
+          {
+            simdInterpolateHorM8_HBD_AVX2<vext, 4, isLast>(src, srcStride, dst, dstStride, width, height, shift, offset, clpRng, c);
+          }
+          else
+          {
+            simdInterpolateHorM8_HBD<vext, 4, isLast>(src, srcStride, dst, dstStride, width, height, shift, offset, clpRng, c);
+          }
+#else
+          if( vext>= AVX2 )
+            simdInterpolateHorM8_AVX2<vext, 4, isLast>( src, srcStride, dst, dstStride, width, height, shift, offset, clpRng, c );
+          else
+            simdInterpolateHorM8<vext, 4, isLast>( src, srcStride, dst, dstStride, width, height, shift, offset, clpRng, c );
+#endif
+        }
+        else
+#if RExt__HIGH_BIT_DEPTH_SUPPORT
+          simdInterpolateHorM4_HBD<vext, 4, isLast>(src, srcStride, dst, dstStride, width, height, shift, offset, clpRng, c);
+#else
+          simdInterpolateHorM4<vext, 4, isLast>( src, srcStride, dst, dstStride, width, height, shift, offset, clpRng, c );
+#endif
+      }
+      else
+#if RExt__HIGH_BIT_DEPTH_SUPPORT
+        simdInterpolateVerM4_HBD<vext, 4, isLast>(src, srcStride, dst, dstStride, width, height, shift, offset, clpRng, c);
+#else
+        simdInterpolateVerM4<vext, 4, isLast>( src, srcStride, dst, dstStride, width, height, shift, offset, clpRng, c );
+#endif
+      return;
+    }
+    else if (biMCForDMVR)
+    {
+      if (N == 2 && !(width & 0x03))
+      {
+#if RExt__HIGH_BIT_DEPTH_SUPPORT
+        if (vext >= AVX2)
+        {
+          simdInterpolateN2_HBD_M4_AVX2<vext, isLast>(src, srcStride, dst, dstStride, cStride, width, height, shift, offset, clpRng, c);
+        }
+        else
+        {
+          simdInterpolateN2_HBD_M4<vext, isLast>(src, srcStride, dst, dstStride, cStride, width, height, shift, offset, clpRng, c);
+        }
+#else
+        if (clpRng.bd <= 10)
+        {
+        simdInterpolateN2_10BIT_M4<vext, isLast>(src, srcStride, dst, dstStride, cStride, width, height, shift, offset, clpRng, c);
+        }
+        else
+        {
+          simdInterpolateN2_HIGHBIT_M4<vext, isLast>(src, srcStride, dst, dstStride, cStride, width, height, shift, offset, clpRng, c);
+        }
+#endif
+        return;
+      }
+    }
+    else if( N == 2 && !( width & 0x07 ) )
+    {
+#if RExt__HIGH_BIT_DEPTH_SUPPORT
+    simdInterpolateN2_M8_HBD<vext, isLast>(src, srcStride, dst, dstStride, cStride, width, height, shift, offset, clpRng, c);
+#else
+      simdInterpolateN2_M8<vext, isLast>( src, srcStride, dst, dstStride, cStride, width, height, shift, offset, clpRng, c );
+#endif
+      return;
+    }
+    else if( N == 2 && !( width & 0x03 ) )
+    {
+#if RExt__HIGH_BIT_DEPTH_SUPPORT
+      simdInterpolateN2_M4_HBD<vext, isLast>(src, srcStride, dst, dstStride, cStride, width, height, shift, offset, clpRng, c);
+#else
+      simdInterpolateN2_M4<vext, isLast>( src, srcStride, dst, dstStride, cStride, width, height, shift, offset, clpRng, c );
+#endif
+      return;
+    }
+  }
+
+  for( row = 0; row < height; row++ )
+  {
+    for( col = 0; col < width; col++ )
+    {
+      int sum;
+
+      sum  = src[col + 0 * cStride] * c[0];
+      sum += src[col + 1 * cStride] * c[1];
+      if( N >= 4 )
+      {
+        sum += src[col + 2 * cStride] * c[2];
+        sum += src[col + 3 * cStride] * c[3];
+      }
+      if( N >= 6 )
+      {
+        sum += src[col + 4 * cStride] * c[4];
+        sum += src[col + 5 * cStride] * c[5];
+      }
+      if( N == 8 )
+      {
+        sum += src[col + 6 * cStride] * c[6];
+        sum += src[col + 7 * cStride] * c[7];
+      }
+
+      Pel val = ( sum + offset ) >> shift;
+      if( isLast )
+      {
+        val = ClipPel( val, clpRng );
+      }
+      dst[col] = val;
+    }
+
+    src += srcStride;
+    dst += dstStride;
+  }
+}
+
+template< X86_VEXT vext >
+void xWeightedGeoBlk_SSE(const PredictionUnit &pu, const uint32_t width, const uint32_t height, const ComponentID compIdx, const uint8_t splitDir, PelUnitBuf& predDst, PelUnitBuf& predSrc0, PelUnitBuf& predSrc1)
+{
+  Pel* dst = predDst.get(compIdx).buf;
+  Pel* src0 = predSrc0.get(compIdx).buf;
+  Pel* src1 = predSrc1.get(compIdx).buf;
   int32_t strideDst = predDst.get(compIdx).stride;
   int32_t strideSrc0 = predSrc0.get(compIdx).stride;
   int32_t strideSrc1 = predSrc1.get(compIdx).stride;
@@ -1550,6 +2595,45 @@ void xWeightedGeoBlk_SSE(const PredictionUnit &pu, const uint32_t width, const u
 template <X86_VEXT vext>
 void InterpolationFilter::_initInterpolationFilterX86()
 {
+#if RExt__HIGH_BIT_DEPTH_SUPPORT
+  // [taps][bFirst][bLast]
+  m_filterHor[0][0][0] = simdFilter<vext, 8, false, false, false>;
+  m_filterHor[0][0][1] = simdFilter<vext, 8, false, false, true>;
+  m_filterHor[0][1][0] = simdFilter<vext, 8, false, true, false>;
+  m_filterHor[0][1][1] = simdFilter<vext, 8, false, true, true>;
+
+  m_filterHor[1][0][0] = simdFilter<vext, 4, false, false, false>;
+  m_filterHor[1][0][1] = simdFilter<vext, 4, false, false, true>;
+  m_filterHor[1][1][0] = simdFilter<vext, 4, false, true, false>;
+  m_filterHor[1][1][1] = simdFilter<vext, 4, false, true, true>;
+
+  m_filterHor[2][0][0] = simdFilter<vext, 2, false, false, false>;
+  m_filterHor[2][0][1] = simdFilter<vext, 2, false, false, true>;
+  m_filterHor[2][1][0] = simdFilter<vext, 2, false, true, false>;
+  m_filterHor[2][1][1] = simdFilter<vext, 2, false, true, true>;
+
+  m_filterVer[0][0][0] = simdFilter<vext, 8, true, false, false>;
+  m_filterVer[0][0][1] = simdFilter<vext, 8, true, false, true>;
+  m_filterVer[0][1][0] = simdFilter<vext, 8, true, true, false>;
+  m_filterVer[0][1][1] = simdFilter<vext, 8, true, true, true>;
+
+  m_filterVer[1][0][0] = simdFilter<vext, 4, true, false, false>;
+  m_filterVer[1][0][1] = simdFilter<vext, 4, true, false, true>;
+  m_filterVer[1][1][0] = simdFilter<vext, 4, true, true, false>;
+  m_filterVer[1][1][1] = simdFilter<vext, 4, true, true, true>;
+
+  m_filterVer[2][0][0] = simdFilter<vext, 2, true, false, false>;
+  m_filterVer[2][0][1] = simdFilter<vext, 2, true, false, true>;
+  m_filterVer[2][1][0] = simdFilter<vext, 2, true, true, false>;
+  m_filterVer[2][1][1] = simdFilter<vext, 2, true, true, true>;
+
+  m_filterCopy[0][0] = simdFilterCopy_HBD<vext, false, false>;
+  m_filterCopy[0][1] = simdFilterCopy_HBD<vext, false, true>;
+  m_filterCopy[1][0] = simdFilterCopy_HBD<vext, true, false>;
+  m_filterCopy[1][1] = simdFilterCopy_HBD<vext, true, true>;
+
+  m_weightedGeoBlk = xWeightedGeoBlk_HBD_SIMD<vext>;
+#else
   // [taps][bFirst][bLast]
   m_filterHor[0][0][0] = simdFilter<vext, 8, false, false, false>;
   m_filterHor[0][0][1] = simdFilter<vext, 8, false, false, true>;
@@ -1587,6 +2671,7 @@ void InterpolationFilter::_initInterpolationFilterX86()
   m_filterCopy[1][1]   = simdFilterCopy<vext, true, true>;
 
   m_weightedGeoBlk = xWeightedGeoBlk_SSE<vext>;
+#endif
 }
 
 template void InterpolationFilter::_initInterpolationFilterX86<SIMDX86>();
diff --git a/source/Lib/CommonLib/x86/RdCostX86.h b/source/Lib/CommonLib/x86/RdCostX86.h
index a41f090ae..eb44a8c3a 100644
--- a/source/Lib/CommonLib/x86/RdCostX86.h
+++ b/source/Lib/CommonLib/x86/RdCostX86.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -455,7 +455,1714 @@ Distortion RdCost::xGetSAD_NxN_SIMD( const DistParam &rcDtParam )
   return uiSum >> DISTORTION_PRECISION_ADJUSTMENT(rcDtParam.bitDepth);
 }
 
+#if RExt__HIGH_BIT_DEPTH_SUPPORT
+static Distortion xCalcHAD2x2_HBD_SSE(const Torg *piOrg, const Tcur *piCur, const int iStrideOrg, const int iStrideCur)
+{
+  __m128i m1[2], m2[2];
+  for (int k = 0; k < 2; k++)
+  {
+    m1[k] = _mm_sub_epi32(_mm_loadl_epi64((const __m128i*)piOrg), _mm_loadl_epi64((const __m128i*)piCur));
+    piOrg += iStrideOrg;
+    piCur += iStrideCur;
+  }
+
+  // vertical
+  m2[0] = _mm_add_epi32(m1[0], m1[1]);
+  m2[1] = _mm_sub_epi32(m1[0], m1[1]);
+
+  // transpose
+  m1[0] = _mm_unpacklo_epi32(m2[0], m2[1]);
+  m1[1] = _mm_shuffle_epi32(m1[0], 0xee);
+
+  // horizontal
+  m2[0] = _mm_abs_epi32(_mm_add_epi32(m1[0], m1[1]));
+  m2[1] = _mm_abs_epi32(_mm_sub_epi32(m1[0], m1[1]));
+
+  Distortion absDc = _mm_cvtsi128_si32(m2[0]);
+
+  // abs
+  __m128i Sum = _mm_add_epi32(m2[0], m2[1]);
+  Sum = _mm_hadd_epi32(Sum, Sum);
+
+  Distortion sad = _mm_cvtsi128_si32(Sum);
+#if JVET_R0164_MEAN_SCALED_SATD
+  sad -= absDc;
+  sad += absDc >> 2;
+#endif
+
+  return sad;
+}
+
+static Distortion xCalcHAD4x4_HBD_SSE(const Torg *piOrg, const Tcur *piCur, const int iStrideOrg, const int iStrideCur)
+{
+  __m128i r0 = _mm_lddqu_si128((const __m128i*)&piOrg[0]);
+  __m128i r1 = _mm_lddqu_si128((const __m128i*)&piOrg[iStrideOrg]);
+  __m128i r2 = _mm_lddqu_si128((const __m128i*)&piOrg[2 * iStrideOrg]);
+  __m128i r3 = _mm_lddqu_si128((const __m128i*)&piOrg[3 * iStrideOrg]);
+  __m128i r4 = _mm_lddqu_si128((const __m128i*)&piCur[0]);
+  __m128i r5 = _mm_lddqu_si128((const __m128i*)&piCur[iStrideCur]);
+  __m128i r6 = _mm_lddqu_si128((const __m128i*)&piCur[2 * iStrideCur]);
+  __m128i r7 = _mm_lddqu_si128((const __m128i*)&piCur[3 * iStrideCur]);
+
+  r0 = _mm_sub_epi32(r0, r4);
+  r1 = _mm_sub_epi32(r1, r5);
+  r2 = _mm_sub_epi32(r2, r6);
+  r3 = _mm_sub_epi32(r3, r7);
+
+  // first stage
+  r4 = r0;
+  r5 = r1;
+
+  r0 = _mm_add_epi32(r0, r3);
+  r1 = _mm_add_epi32(r1, r2);
+
+  r4 = _mm_sub_epi32(r4, r3);
+  r5 = _mm_sub_epi32(r5, r2);
+
+  r2 = r0;
+  r3 = r4;
+
+  r0 = _mm_add_epi32(r0, r1);
+  r2 = _mm_sub_epi32(r2, r1);
+  r3 = _mm_sub_epi32(r3, r5);
+  r5 = _mm_add_epi32(r5, r4);
+
+  // shuffle - flip matrix for vertical transform
+  r4 = _mm_unpacklo_epi32(r0, r5);
+  r5 = _mm_unpackhi_epi32(r0, r5);
+  r6 = _mm_unpacklo_epi32(r2, r3);
+  r7 = _mm_unpackhi_epi32(r2, r3);
+
+  r0 = _mm_unpacklo_epi64(r4, r6);
+  r1 = _mm_unpackhi_epi64(r4, r6);
+  r2 = _mm_unpacklo_epi64(r5, r7);
+  r3 = _mm_unpackhi_epi64(r5, r7);
+
+  // second stage
+  r4 = r0;
+  r5 = r1;
+
+  r0 = _mm_add_epi32(r0, r3);
+  r1 = _mm_add_epi32(r1, r2);
+
+  r4 = _mm_sub_epi32(r4, r3);
+  r5 = _mm_sub_epi32(r5, r2);
+
+  r2 = r0;
+  r3 = r4;
+
+  r0 = _mm_add_epi32(r0, r1);
+  r2 = _mm_sub_epi32(r2, r1);
+  r3 = _mm_sub_epi32(r3, r5);
+  r5 = _mm_add_epi32(r5, r4);
+
+  // abs
+  __m128i Sum = _mm_abs_epi32(r0);
+#if JVET_R0164_MEAN_SCALED_SATD
+  Distortion absDc = _mm_cvtsi128_si32(Sum);
+#endif
+  Sum = _mm_add_epi32(Sum, _mm_abs_epi32(r2));
+  Sum = _mm_add_epi32(Sum, _mm_abs_epi32(r3));
+  Sum = _mm_add_epi32(Sum, _mm_abs_epi32(r5));
+  Sum = _mm_hadd_epi32(Sum, Sum);
+  Sum = _mm_hadd_epi32(Sum, Sum);
+
+  Distortion sad = _mm_cvtsi128_si32(Sum);
+
+#if JVET_R0164_MEAN_SCALED_SATD
+  sad -= absDc;
+  sad += absDc >> 2;
+#endif
+  sad = ((sad + 1) >> 1);
+
+  return sad;
+}
+
+static Distortion xCalcHAD8x8_HBD_SSE(const Torg *piOrg, const Tcur *piCur, const int iStrideOrg, const int iStrideCur)
+{
+  __m128i m1[8][2], m2[8][2];
+
+  for (int k = 0; k < 8; k++)
+  {
+    m2[k][0] = _mm_sub_epi32(_mm_lddqu_si128((__m128i *) piOrg), _mm_lddqu_si128((__m128i *) piCur));
+    m2[k][1] = _mm_sub_epi32(_mm_lddqu_si128((__m128i *)(piOrg + 4)), _mm_lddqu_si128((__m128i *)(piCur + 4)));
+    piCur += iStrideCur;
+    piOrg += iStrideOrg;
+  }
+
+  for (int i = 0; i < 2; i++)
+  {
+    // vertical
+    m1[0][i] = _mm_add_epi32(m2[0][i], m2[4][i]);
+    m1[1][i] = _mm_add_epi32(m2[1][i], m2[5][i]);
+    m1[2][i] = _mm_add_epi32(m2[2][i], m2[6][i]);
+    m1[3][i] = _mm_add_epi32(m2[3][i], m2[7][i]);
+    m1[4][i] = _mm_sub_epi32(m2[0][i], m2[4][i]);
+    m1[5][i] = _mm_sub_epi32(m2[1][i], m2[5][i]);
+    m1[6][i] = _mm_sub_epi32(m2[2][i], m2[6][i]);
+    m1[7][i] = _mm_sub_epi32(m2[3][i], m2[7][i]);
+
+    m2[0][i] = _mm_add_epi32(m1[0][i], m1[2][i]);
+    m2[1][i] = _mm_add_epi32(m1[1][i], m1[3][i]);
+    m2[2][i] = _mm_sub_epi32(m1[0][i], m1[2][i]);
+    m2[3][i] = _mm_sub_epi32(m1[1][i], m1[3][i]);
+    m2[4][i] = _mm_add_epi32(m1[4][i], m1[6][i]);
+    m2[5][i] = _mm_add_epi32(m1[5][i], m1[7][i]);
+    m2[6][i] = _mm_sub_epi32(m1[4][i], m1[6][i]);
+    m2[7][i] = _mm_sub_epi32(m1[5][i], m1[7][i]);
+
+    m1[0][i] = _mm_add_epi32(m2[0][i], m2[1][i]);
+    m1[1][i] = _mm_sub_epi32(m2[0][i], m2[1][i]);
+    m1[2][i] = _mm_add_epi32(m2[2][i], m2[3][i]);
+    m1[3][i] = _mm_sub_epi32(m2[2][i], m2[3][i]);
+    m1[4][i] = _mm_add_epi32(m2[4][i], m2[5][i]);
+    m1[5][i] = _mm_sub_epi32(m2[4][i], m2[5][i]);
+    m1[6][i] = _mm_add_epi32(m2[6][i], m2[7][i]);
+    m1[7][i] = _mm_sub_epi32(m2[6][i], m2[7][i]);
+
+    // transpose
+    m2[0][i] = _mm_unpacklo_epi32(m1[0][i], m1[1][i]);
+    m2[1][i] = _mm_unpacklo_epi32(m1[2][i], m1[3][i]);
+    m2[2][i] = _mm_unpackhi_epi32(m1[0][i], m1[1][i]);
+    m2[3][i] = _mm_unpackhi_epi32(m1[2][i], m1[3][i]);
+    m2[4][i] = _mm_unpacklo_epi32(m1[4][i], m1[5][i]);
+    m2[5][i] = _mm_unpacklo_epi32(m1[6][i], m1[7][i]);
+    m2[6][i] = _mm_unpackhi_epi32(m1[4][i], m1[5][i]);
+    m2[7][i] = _mm_unpackhi_epi32(m1[6][i], m1[7][i]);
+
+    m1[0][i] = _mm_unpacklo_epi64(m2[0][i], m2[1][i]);
+    m1[1][i] = _mm_unpackhi_epi64(m2[0][i], m2[1][i]);
+    m1[2][i] = _mm_unpacklo_epi64(m2[2][i], m2[3][i]);
+    m1[3][i] = _mm_unpackhi_epi64(m2[2][i], m2[3][i]);
+    m1[4][i] = _mm_unpacklo_epi64(m2[4][i], m2[5][i]);
+    m1[5][i] = _mm_unpackhi_epi64(m2[4][i], m2[5][i]);
+    m1[6][i] = _mm_unpacklo_epi64(m2[6][i], m2[7][i]);
+    m1[7][i] = _mm_unpackhi_epi64(m2[6][i], m2[7][i]);
+  }
+
+  // transpose
+  __m128i n1[8][2];
+  __m128i n2[8][2];
+
+  for (int i = 0; i < 8; i++)
+  {
+    int ii = i % 4;
+    int ij = i >> 2;
+
+    n2[i][0] = m1[ii][ij];
+    n2[i][1] = m1[ii + 4][ij];
+  }
+
+  for (int i = 0; i < 2; i++)
+  {
+    // horizontal
+    n1[0][i] = _mm_add_epi32(n2[0][i], n2[4][i]);
+    n1[1][i] = _mm_add_epi32(n2[1][i], n2[5][i]);
+    n1[2][i] = _mm_add_epi32(n2[2][i], n2[6][i]);
+    n1[3][i] = _mm_add_epi32(n2[3][i], n2[7][i]);
+    n1[4][i] = _mm_sub_epi32(n2[0][i], n2[4][i]);
+    n1[5][i] = _mm_sub_epi32(n2[1][i], n2[5][i]);
+    n1[6][i] = _mm_sub_epi32(n2[2][i], n2[6][i]);
+    n1[7][i] = _mm_sub_epi32(n2[3][i], n2[7][i]);
+
+    n2[0][i] = _mm_add_epi32(n1[0][i], n1[2][i]);
+    n2[1][i] = _mm_add_epi32(n1[1][i], n1[3][i]);
+    n2[2][i] = _mm_sub_epi32(n1[0][i], n1[2][i]);
+    n2[3][i] = _mm_sub_epi32(n1[1][i], n1[3][i]);
+    n2[4][i] = _mm_add_epi32(n1[4][i], n1[6][i]);
+    n2[5][i] = _mm_add_epi32(n1[5][i], n1[7][i]);
+    n2[6][i] = _mm_sub_epi32(n1[4][i], n1[6][i]);
+    n2[7][i] = _mm_sub_epi32(n1[5][i], n1[7][i]);
+
+    n1[0][i] = _mm_abs_epi32(_mm_add_epi32(n2[0][i], n2[1][i]));
+    n1[1][i] = _mm_abs_epi32(_mm_sub_epi32(n2[0][i], n2[1][i]));
+    n1[2][i] = _mm_abs_epi32(_mm_add_epi32(n2[2][i], n2[3][i]));
+    n1[3][i] = _mm_abs_epi32(_mm_sub_epi32(n2[2][i], n2[3][i]));
+    n1[4][i] = _mm_abs_epi32(_mm_add_epi32(n2[4][i], n2[5][i]));
+    n1[5][i] = _mm_abs_epi32(_mm_sub_epi32(n2[4][i], n2[5][i]));
+    n1[6][i] = _mm_abs_epi32(_mm_add_epi32(n2[6][i], n2[7][i]));
+    n1[7][i] = _mm_abs_epi32(_mm_sub_epi32(n2[6][i], n2[7][i]));
+  }
+
+  for (int i = 0; i < 8; i++)
+  {
+    m1[i][0] = _mm_add_epi32(n1[i][0], n1[i][1]);
+  }
+
+  m1[0][0] = _mm_add_epi32(m1[0][0], m1[1][0]);
+  m1[2][0] = _mm_add_epi32(m1[2][0], m1[3][0]);
+  m1[4][0] = _mm_add_epi32(m1[4][0], m1[5][0]);
+  m1[6][0] = _mm_add_epi32(m1[6][0], m1[7][0]);
+
+  m1[0][0] = _mm_add_epi32(m1[0][0], m1[2][0]);
+  m1[4][0] = _mm_add_epi32(m1[4][0], m1[6][0]);
+  __m128i iSum = _mm_add_epi32(m1[0][0], m1[4][0]);
+
+  iSum = _mm_hadd_epi32(iSum, iSum);
+  iSum = _mm_hadd_epi32(iSum, iSum);
+
+  Distortion sad = _mm_cvtsi128_si32(iSum);
+#if JVET_R0164_MEAN_SCALED_SATD
+  Distortion absDc = _mm_cvtsi128_si32(n1[0][0]);
+  sad -= absDc;
+  sad += absDc >> 2;
+#endif
+  sad = ((sad + 2) >> 2);
+
+  return sad;
+}
+
+static Distortion xCalcHAD4x8_HBD_SSE(const Torg *piOrg, const Tcur *piCur, const int iStrideOrg, const int iStrideCur)
+{
+  __m128i m1[8], m2[8];
+
+  for (int k = 0; k < 8; k++)
+  {
+    m2[k] = _mm_sub_epi32(_mm_lddqu_si128((__m128i*)piOrg), _mm_lddqu_si128((__m128i*)piCur));
+    piCur += iStrideCur;
+    piOrg += iStrideOrg;
+  }
+
+  // vertical
+  m1[0] = _mm_add_epi32(m2[0], m2[4]);
+  m1[1] = _mm_add_epi32(m2[1], m2[5]);
+  m1[2] = _mm_add_epi32(m2[2], m2[6]);
+  m1[3] = _mm_add_epi32(m2[3], m2[7]);
+  m1[4] = _mm_sub_epi32(m2[0], m2[4]);
+  m1[5] = _mm_sub_epi32(m2[1], m2[5]);
+  m1[6] = _mm_sub_epi32(m2[2], m2[6]);
+  m1[7] = _mm_sub_epi32(m2[3], m2[7]);
+
+  m2[0] = _mm_add_epi32(m1[0], m1[2]);
+  m2[1] = _mm_add_epi32(m1[1], m1[3]);
+  m2[2] = _mm_sub_epi32(m1[0], m1[2]);
+  m2[3] = _mm_sub_epi32(m1[1], m1[3]);
+  m2[4] = _mm_add_epi32(m1[4], m1[6]);
+  m2[5] = _mm_add_epi32(m1[5], m1[7]);
+  m2[6] = _mm_sub_epi32(m1[4], m1[6]);
+  m2[7] = _mm_sub_epi32(m1[5], m1[7]);
+
+  m1[0] = _mm_add_epi32(m2[0], m2[1]);
+  m1[1] = _mm_sub_epi32(m2[0], m2[1]);
+  m1[2] = _mm_add_epi32(m2[2], m2[3]);
+  m1[3] = _mm_sub_epi32(m2[2], m2[3]);
+  m1[4] = _mm_add_epi32(m2[4], m2[5]);
+  m1[5] = _mm_sub_epi32(m2[4], m2[5]);
+  m1[6] = _mm_add_epi32(m2[6], m2[7]);
+  m1[7] = _mm_sub_epi32(m2[6], m2[7]);
+
+  // transpose
+  __m128i n1[4][2], n2[4][2];
+
+  n2[0][0] = _mm_unpacklo_epi32(m1[0], m1[1]);
+  n2[0][1] = _mm_unpackhi_epi32(m1[0], m1[1]);
+  n2[1][0] = _mm_unpacklo_epi32(m1[2], m1[3]);
+  n2[1][1] = _mm_unpackhi_epi32(m1[2], m1[3]);
+  n2[2][0] = _mm_unpacklo_epi32(m1[4], m1[5]);
+  n2[2][1] = _mm_unpackhi_epi32(m1[4], m1[5]);
+  n2[3][0] = _mm_unpacklo_epi32(m1[6], m1[7]);
+  n2[3][1] = _mm_unpackhi_epi32(m1[6], m1[7]);
+
+  n1[0][0] = _mm_unpacklo_epi64(n2[0][0], n2[1][0]);
+  n1[0][1] = _mm_unpacklo_epi64(n2[2][0], n2[3][0]);
+  n1[1][0] = _mm_unpackhi_epi64(n2[0][0], n2[1][0]);
+  n1[1][1] = _mm_unpackhi_epi64(n2[2][0], n2[3][0]);
+  n1[2][0] = _mm_unpacklo_epi64(n2[0][1], n2[1][1]);
+  n1[2][1] = _mm_unpacklo_epi64(n2[2][1], n2[3][1]);
+  n1[3][0] = _mm_unpackhi_epi64(n2[0][1], n2[1][1]);
+  n1[3][1] = _mm_unpackhi_epi64(n2[2][1], n2[3][1]);
+
+  // horizontal
+  for (int i = 0; i < 2; i++)
+  {
+    n2[0][i] = _mm_add_epi32(n1[0][i], n1[2][i]);
+    n2[1][i] = _mm_add_epi32(n1[1][i], n1[3][i]);
+    n2[2][i] = _mm_sub_epi32(n1[0][i], n1[2][i]);
+    n2[3][i] = _mm_sub_epi32(n1[1][i], n1[3][i]);
+
+    n1[0][i] = _mm_abs_epi32(_mm_add_epi32(n2[0][i], n2[1][i]));
+    n1[1][i] = _mm_abs_epi32(_mm_sub_epi32(n2[0][i], n2[1][i]));
+    n1[2][i] = _mm_abs_epi32(_mm_add_epi32(n2[2][i], n2[3][i]));
+    n1[3][i] = _mm_abs_epi32(_mm_sub_epi32(n2[2][i], n2[3][i]));
+  }
+
+  for (int i = 0; i < 4; i++)
+  {
+    m1[i] = _mm_add_epi32(n1[i][0], n1[i][1]);
+  }
+
+  Distortion absDc = _mm_cvtsi128_si32(n1[0][0]);
+  m1[0] = _mm_add_epi32(m1[0], m1[1]);
+  m1[2] = _mm_add_epi32(m1[2], m1[3]);
+
+  __m128i iSum = _mm_add_epi32(m1[0], m1[2]);
+  iSum = _mm_hadd_epi32(iSum, iSum);
+  iSum = _mm_hadd_epi32(iSum, iSum);
+
+  Distortion sad = _mm_cvtsi128_si32(iSum);
+#if JVET_R0164_MEAN_SCALED_SATD
+  sad -= absDc;
+  sad += absDc >> 2;
+#endif
+  sad = (Distortion)(sad / sqrt(4.0 * 8) * 2);
+
+  return sad;
+}
+
+static Distortion xCalcHAD8x4_HBD_SSE(const Torg *piOrg, const Tcur *piCur, const int iStrideOrg, const int iStrideCur)
+{
+  __m128i m1[8][2], m2[8][2];
+
+  for (int k = 0; k < 4; k++)
+  {
+    m1[k][0] = _mm_sub_epi32(_mm_lddqu_si128((__m128i*) piOrg), _mm_lddqu_si128((__m128i*) piCur));
+    m1[k][1] = _mm_sub_epi32(_mm_lddqu_si128((__m128i*)(piOrg + 4)), _mm_lddqu_si128((__m128i*)(piCur + 4)));
+    piCur += iStrideCur;
+    piOrg += iStrideOrg;
+  }
+
+  // vertical
+  for (int i = 0; i < 2; i++)
+  {
+    m2[0][i] = _mm_add_epi32(m1[0][i], m1[2][i]);
+    m2[1][i] = _mm_add_epi32(m1[1][i], m1[3][i]);
+    m2[2][i] = _mm_sub_epi32(m1[0][i], m1[2][i]);
+    m2[3][i] = _mm_sub_epi32(m1[1][i], m1[3][i]);
+
+    m1[0][i] = _mm_add_epi32(m2[0][i], m2[1][i]);
+    m1[1][i] = _mm_sub_epi32(m2[0][i], m2[1][i]);
+    m1[2][i] = _mm_add_epi32(m2[2][i], m2[3][i]);
+    m1[3][i] = _mm_sub_epi32(m2[2][i], m2[3][i]);
+  }
+
+  // transpose
+  m2[0][0] = _mm_unpacklo_epi32(m1[0][0], m1[1][0]);
+  m2[0][1] = _mm_unpacklo_epi32(m1[0][1], m1[1][1]);
+  m2[1][0] = _mm_unpacklo_epi32(m1[2][0], m1[3][0]);
+  m2[1][1] = _mm_unpacklo_epi32(m1[2][1], m1[3][1]);
+  m2[2][0] = _mm_unpackhi_epi32(m1[0][0], m1[1][0]);
+  m2[2][1] = _mm_unpackhi_epi32(m1[0][1], m1[1][1]);
+  m2[3][0] = _mm_unpackhi_epi32(m1[2][0], m1[3][0]);
+  m2[3][1] = _mm_unpackhi_epi32(m1[2][1], m1[3][1]);
+
+  __m128i n1[8], n2[8];
+  n2[0] = _mm_unpacklo_epi64(m2[0][0], m2[1][0]);
+  n2[1] = _mm_unpackhi_epi64(m2[0][0], m2[1][0]);
+  n2[2] = _mm_unpacklo_epi64(m2[2][0], m2[3][0]);
+  n2[3] = _mm_unpackhi_epi64(m2[2][0], m2[3][0]);
+  n2[4] = _mm_unpacklo_epi64(m2[0][1], m2[1][1]);
+  n2[5] = _mm_unpackhi_epi64(m2[0][1], m2[1][1]);
+  n2[6] = _mm_unpacklo_epi64(m2[2][1], m2[3][1]);
+  n2[7] = _mm_unpackhi_epi64(m2[2][1], m2[3][1]);
+
+  // horizontal
+  n1[0] = _mm_add_epi32(n2[0], n2[4]);
+  n1[1] = _mm_add_epi32(n2[1], n2[5]);
+  n1[2] = _mm_add_epi32(n2[2], n2[6]);
+  n1[3] = _mm_add_epi32(n2[3], n2[7]);
+  n1[4] = _mm_sub_epi32(n2[0], n2[4]);
+  n1[5] = _mm_sub_epi32(n2[1], n2[5]);
+  n1[6] = _mm_sub_epi32(n2[2], n2[6]);
+  n1[7] = _mm_sub_epi32(n2[3], n2[7]);
+
+  n2[0] = _mm_add_epi32(n1[0], n1[2]);
+  n2[1] = _mm_add_epi32(n1[1], n1[3]);
+  n2[2] = _mm_sub_epi32(n1[0], n1[2]);
+  n2[3] = _mm_sub_epi32(n1[1], n1[3]);
+  n2[4] = _mm_add_epi32(n1[4], n1[6]);
+  n2[5] = _mm_add_epi32(n1[5], n1[7]);
+  n2[6] = _mm_sub_epi32(n1[4], n1[6]);
+  n2[7] = _mm_sub_epi32(n1[5], n1[7]);
+
+  n1[0] = _mm_abs_epi32(_mm_add_epi32(n2[0], n2[1]));
+  n1[1] = _mm_abs_epi32(_mm_sub_epi32(n2[0], n2[1]));
+  n1[2] = _mm_abs_epi32(_mm_add_epi32(n2[2], n2[3]));
+  n1[3] = _mm_abs_epi32(_mm_sub_epi32(n2[2], n2[3]));
+  n1[4] = _mm_abs_epi32(_mm_add_epi32(n2[4], n2[5]));
+  n1[5] = _mm_abs_epi32(_mm_sub_epi32(n2[4], n2[5]));
+  n1[6] = _mm_abs_epi32(_mm_add_epi32(n2[6], n2[7]));
+  n1[7] = _mm_abs_epi32(_mm_sub_epi32(n2[6], n2[7]));
+
+#if JVET_R0164_MEAN_SCALED_SATD
+  Distortion absDc = _mm_cvtsi128_si32(n1[0]);
+#endif
+  n1[0] = _mm_add_epi32(n1[0], n1[1]);
+  n1[1] = _mm_add_epi32(n1[2], n1[3]);
+  n1[2] = _mm_add_epi32(n1[4], n1[5]);
+  n1[3] = _mm_add_epi32(n1[6], n1[7]);
+
+  n1[0] = _mm_add_epi32(n1[0], n1[1]);
+  n1[1] = _mm_add_epi32(n1[2], n1[3]);
+
+  __m128i iSum = _mm_add_epi32(n1[0], n1[1]);
+  iSum = _mm_hadd_epi32(iSum, iSum);
+  iSum = _mm_hadd_epi32(iSum, iSum);
+
+  Distortion sad = _mm_cvtsi128_si32(iSum);
+#if JVET_R0164_MEAN_SCALED_SATD
+  sad -= absDc;
+  sad += absDc >> 2;
+#endif
+  sad = (Distortion)(sad / sqrt(4.0 * 8) * 2);
+  return sad;
+}
+
+static Distortion xCalcHAD16x8_HBD_SSE(const Torg *piOrg, const Tcur *piCur, const int iStrideOrg, const int iStrideCur)
+{
+  __m128i m1[16][2][2], m2[16][2][2];
+  __m128i iSum = _mm_setzero_si128();
+
+  for (int l = 0; l < 2; l++)
+  {
+    const Torg *piOrgPtr = piOrg + l * 8;
+    const Tcur *piCurPtr = piCur + l * 8;
+    for (int k = 0; k < 8; k++)
+    {
+      m2[k][l][0] = _mm_sub_epi32(_mm_lddqu_si128((__m128i*)  piOrgPtr), _mm_lddqu_si128((__m128i*)  piCurPtr));
+      m2[k][l][1] = _mm_sub_epi32(_mm_lddqu_si128((__m128i*) (piOrgPtr + 4)), _mm_lddqu_si128((__m128i*) (piCurPtr + 4)));
+      piCurPtr += iStrideCur;
+      piOrgPtr += iStrideOrg;
+    }
+
+    for (int i = 0; i < 2; i++)
+    {
+      //vertical
+      m1[0][l][i] = _mm_add_epi32(m2[0][l][i], m2[4][l][i]);
+      m1[1][l][i] = _mm_add_epi32(m2[1][l][i], m2[5][l][i]);
+      m1[2][l][i] = _mm_add_epi32(m2[2][l][i], m2[6][l][i]);
+      m1[3][l][i] = _mm_add_epi32(m2[3][l][i], m2[7][l][i]);
+      m1[4][l][i] = _mm_sub_epi32(m2[0][l][i], m2[4][l][i]);
+      m1[5][l][i] = _mm_sub_epi32(m2[1][l][i], m2[5][l][i]);
+      m1[6][l][i] = _mm_sub_epi32(m2[2][l][i], m2[6][l][i]);
+      m1[7][l][i] = _mm_sub_epi32(m2[3][l][i], m2[7][l][i]);
+
+      m2[0][l][i] = _mm_add_epi32(m1[0][l][i], m1[2][l][i]);
+      m2[1][l][i] = _mm_add_epi32(m1[1][l][i], m1[3][l][i]);
+      m2[2][l][i] = _mm_sub_epi32(m1[0][l][i], m1[2][l][i]);
+      m2[3][l][i] = _mm_sub_epi32(m1[1][l][i], m1[3][l][i]);
+      m2[4][l][i] = _mm_add_epi32(m1[4][l][i], m1[6][l][i]);
+      m2[5][l][i] = _mm_add_epi32(m1[5][l][i], m1[7][l][i]);
+      m2[6][l][i] = _mm_sub_epi32(m1[4][l][i], m1[6][l][i]);
+      m2[7][l][i] = _mm_sub_epi32(m1[5][l][i], m1[7][l][i]);
+
+      m1[0][l][i] = _mm_add_epi32(m2[0][l][i], m2[1][l][i]);
+      m1[1][l][i] = _mm_sub_epi32(m2[0][l][i], m2[1][l][i]);
+      m1[2][l][i] = _mm_add_epi32(m2[2][l][i], m2[3][l][i]);
+      m1[3][l][i] = _mm_sub_epi32(m2[2][l][i], m2[3][l][i]);
+      m1[4][l][i] = _mm_add_epi32(m2[4][l][i], m2[5][l][i]);
+      m1[5][l][i] = _mm_sub_epi32(m2[4][l][i], m2[5][l][i]);
+      m1[6][l][i] = _mm_add_epi32(m2[6][l][i], m2[7][l][i]);
+      m1[7][l][i] = _mm_sub_epi32(m2[6][l][i], m2[7][l][i]);
+    }
+  }
+
+  // 4 x 8x4 blocks
+  // 0 1
+  // 2 3
+#if JVET_R0164_MEAN_SCALED_SATD
+  uint32_t absDc = 0;
+#endif
+
+  // transpose and do horizontal in two steps
+  for (int l = 0; l < 2; l++)
+  {
+    int off = l * 4;
+
+    __m128i n1[16];
+    __m128i n2[16];
+
+    m2[0][0][0] = _mm_unpacklo_epi32(m1[0 + off][0][0], m1[1 + off][0][0]);
+    m2[1][0][0] = _mm_unpacklo_epi32(m1[2 + off][0][0], m1[3 + off][0][0]);
+    m2[2][0][0] = _mm_unpackhi_epi32(m1[0 + off][0][0], m1[1 + off][0][0]);
+    m2[3][0][0] = _mm_unpackhi_epi32(m1[2 + off][0][0], m1[3 + off][0][0]);
+
+    m2[0][0][1] = _mm_unpacklo_epi32(m1[0 + off][0][1], m1[1 + off][0][1]);
+    m2[1][0][1] = _mm_unpacklo_epi32(m1[2 + off][0][1], m1[3 + off][0][1]);
+    m2[2][0][1] = _mm_unpackhi_epi32(m1[0 + off][0][1], m1[1 + off][0][1]);
+    m2[3][0][1] = _mm_unpackhi_epi32(m1[2 + off][0][1], m1[3 + off][0][1]);
+
+    n1[0] = _mm_unpacklo_epi64(m2[0][0][0], m2[1][0][0]);
+    n1[1] = _mm_unpackhi_epi64(m2[0][0][0], m2[1][0][0]);
+    n1[2] = _mm_unpacklo_epi64(m2[2][0][0], m2[3][0][0]);
+    n1[3] = _mm_unpackhi_epi64(m2[2][0][0], m2[3][0][0]);
+    n1[4] = _mm_unpacklo_epi64(m2[0][0][1], m2[1][0][1]);
+    n1[5] = _mm_unpackhi_epi64(m2[0][0][1], m2[1][0][1]);
+    n1[6] = _mm_unpacklo_epi64(m2[2][0][1], m2[3][0][1]);
+    n1[7] = _mm_unpackhi_epi64(m2[2][0][1], m2[3][0][1]);
+
+    // transpose 8x4 -> 4x8, block 1(3)
+    m2[8 + 0][0][0] = _mm_unpacklo_epi32(m1[0 + off][1][0], m1[1 + off][1][0]);
+    m2[8 + 1][0][0] = _mm_unpacklo_epi32(m1[2 + off][1][0], m1[3 + off][1][0]);
+    m2[8 + 2][0][0] = _mm_unpackhi_epi32(m1[0 + off][1][0], m1[1 + off][1][0]);
+    m2[8 + 3][0][0] = _mm_unpackhi_epi32(m1[2 + off][1][0], m1[3 + off][1][0]);
+
+    m2[8 + 0][0][1] = _mm_unpacklo_epi32(m1[0 + off][1][1], m1[1 + off][1][1]);
+    m2[8 + 1][0][1] = _mm_unpacklo_epi32(m1[2 + off][1][1], m1[3 + off][1][1]);
+    m2[8 + 2][0][1] = _mm_unpackhi_epi32(m1[0 + off][1][1], m1[1 + off][1][1]);
+    m2[8 + 3][0][1] = _mm_unpackhi_epi32(m1[2 + off][1][1], m1[3 + off][1][1]);
+
+    n1[8 + 0] = _mm_unpacklo_epi64(m2[8 + 0][0][0], m2[8 + 1][0][0]);
+    n1[8 + 1] = _mm_unpackhi_epi64(m2[8 + 0][0][0], m2[8 + 1][0][0]);
+    n1[8 + 2] = _mm_unpacklo_epi64(m2[8 + 2][0][0], m2[8 + 3][0][0]);
+    n1[8 + 3] = _mm_unpackhi_epi64(m2[8 + 2][0][0], m2[8 + 3][0][0]);
+    n1[8 + 4] = _mm_unpacklo_epi64(m2[8 + 0][0][1], m2[8 + 1][0][1]);
+    n1[8 + 5] = _mm_unpackhi_epi64(m2[8 + 0][0][1], m2[8 + 1][0][1]);
+    n1[8 + 6] = _mm_unpacklo_epi64(m2[8 + 2][0][1], m2[8 + 3][0][1]);
+    n1[8 + 7] = _mm_unpackhi_epi64(m2[8 + 2][0][1], m2[8 + 3][0][1]);
+
+    n2[0] = _mm_add_epi32(n1[0], n1[8]);
+    n2[1] = _mm_add_epi32(n1[1], n1[9]);
+    n2[2] = _mm_add_epi32(n1[2], n1[10]);
+    n2[3] = _mm_add_epi32(n1[3], n1[11]);
+    n2[4] = _mm_add_epi32(n1[4], n1[12]);
+    n2[5] = _mm_add_epi32(n1[5], n1[13]);
+    n2[6] = _mm_add_epi32(n1[6], n1[14]);
+    n2[7] = _mm_add_epi32(n1[7], n1[15]);
+    n2[8] = _mm_sub_epi32(n1[0], n1[8]);
+    n2[9] = _mm_sub_epi32(n1[1], n1[9]);
+    n2[10] = _mm_sub_epi32(n1[2], n1[10]);
+    n2[11] = _mm_sub_epi32(n1[3], n1[11]);
+    n2[12] = _mm_sub_epi32(n1[4], n1[12]);
+    n2[13] = _mm_sub_epi32(n1[5], n1[13]);
+    n2[14] = _mm_sub_epi32(n1[6], n1[14]);
+    n2[15] = _mm_sub_epi32(n1[7], n1[15]);
+
+    n1[0] = _mm_add_epi32(n2[0], n2[4]);
+    n1[1] = _mm_add_epi32(n2[1], n2[5]);
+    n1[2] = _mm_add_epi32(n2[2], n2[6]);
+    n1[3] = _mm_add_epi32(n2[3], n2[7]);
+    n1[4] = _mm_sub_epi32(n2[0], n2[4]);
+    n1[5] = _mm_sub_epi32(n2[1], n2[5]);
+    n1[6] = _mm_sub_epi32(n2[2], n2[6]);
+    n1[7] = _mm_sub_epi32(n2[3], n2[7]);
+    n1[8] = _mm_add_epi32(n2[8], n2[12]);
+    n1[9] = _mm_add_epi32(n2[9], n2[13]);
+    n1[10] = _mm_add_epi32(n2[10], n2[14]);
+    n1[11] = _mm_add_epi32(n2[11], n2[15]);
+    n1[12] = _mm_sub_epi32(n2[8], n2[12]);
+    n1[13] = _mm_sub_epi32(n2[9], n2[13]);
+    n1[14] = _mm_sub_epi32(n2[10], n2[14]);
+    n1[15] = _mm_sub_epi32(n2[11], n2[15]);
+
+    n2[0] = _mm_add_epi32(n1[0], n1[2]);
+    n2[1] = _mm_add_epi32(n1[1], n1[3]);
+    n2[2] = _mm_sub_epi32(n1[0], n1[2]);
+    n2[3] = _mm_sub_epi32(n1[1], n1[3]);
+    n2[4] = _mm_add_epi32(n1[4], n1[6]);
+    n2[5] = _mm_add_epi32(n1[5], n1[7]);
+    n2[6] = _mm_sub_epi32(n1[4], n1[6]);
+    n2[7] = _mm_sub_epi32(n1[5], n1[7]);
+    n2[8] = _mm_add_epi32(n1[8], n1[10]);
+    n2[9] = _mm_add_epi32(n1[9], n1[11]);
+    n2[10] = _mm_sub_epi32(n1[8], n1[10]);
+    n2[11] = _mm_sub_epi32(n1[9], n1[11]);
+    n2[12] = _mm_add_epi32(n1[12], n1[14]);
+    n2[13] = _mm_add_epi32(n1[13], n1[15]);
+    n2[14] = _mm_sub_epi32(n1[12], n1[14]);
+    n2[15] = _mm_sub_epi32(n1[13], n1[15]);
+
+    n1[0] = _mm_abs_epi32(_mm_add_epi32(n2[0], n2[1]));
+    n1[1] = _mm_abs_epi32(_mm_sub_epi32(n2[0], n2[1]));
+    n1[2] = _mm_abs_epi32(_mm_add_epi32(n2[2], n2[3]));
+    n1[3] = _mm_abs_epi32(_mm_sub_epi32(n2[2], n2[3]));
+    n1[4] = _mm_abs_epi32(_mm_add_epi32(n2[4], n2[5]));
+    n1[5] = _mm_abs_epi32(_mm_sub_epi32(n2[4], n2[5]));
+    n1[6] = _mm_abs_epi32(_mm_add_epi32(n2[6], n2[7]));
+    n1[7] = _mm_abs_epi32(_mm_sub_epi32(n2[6], n2[7]));
+    n1[8] = _mm_abs_epi32(_mm_add_epi32(n2[8], n2[9]));
+    n1[9] = _mm_abs_epi32(_mm_sub_epi32(n2[8], n2[9]));
+    n1[10] = _mm_abs_epi32(_mm_add_epi32(n2[10], n2[11]));
+    n1[11] = _mm_abs_epi32(_mm_sub_epi32(n2[10], n2[11]));
+    n1[12] = _mm_abs_epi32(_mm_add_epi32(n2[12], n2[13]));
+    n1[13] = _mm_abs_epi32(_mm_sub_epi32(n2[12], n2[13]));
+    n1[14] = _mm_abs_epi32(_mm_add_epi32(n2[14], n2[15]));
+    n1[15] = _mm_abs_epi32(_mm_sub_epi32(n2[14], n2[15]));
+
+#if JVET_R0164_MEAN_SCALED_SATD
+    if (l == 0)
+      absDc = _mm_cvtsi128_si32(n1[0]);
+#endif
+
+    // sum up
+    n1[0] = _mm_add_epi32(n1[0], n1[1]);
+    n1[2] = _mm_add_epi32(n1[2], n1[3]);
+    n1[4] = _mm_add_epi32(n1[4], n1[5]);
+    n1[6] = _mm_add_epi32(n1[6], n1[7]);
+    n1[8] = _mm_add_epi32(n1[8], n1[9]);
+    n1[10] = _mm_add_epi32(n1[10], n1[11]);
+    n1[12] = _mm_add_epi32(n1[12], n1[13]);
+    n1[14] = _mm_add_epi32(n1[14], n1[15]);
+
+    n1[0] = _mm_add_epi32(n1[0], n1[2]);
+    n1[4] = _mm_add_epi32(n1[4], n1[6]);
+    n1[8] = _mm_add_epi32(n1[8], n1[10]);
+    n1[12] = _mm_add_epi32(n1[12], n1[14]);
+
+    n1[0] = _mm_add_epi32(n1[0], n1[4]);
+    n1[8] = _mm_add_epi32(n1[8], n1[12]);
+
+    n1[0] = _mm_add_epi32(n1[0], n1[8]);
+    iSum = _mm_add_epi32(iSum, n1[0]);
+  }
+
+  iSum = _mm_hadd_epi32(iSum, iSum);
+  iSum = _mm_hadd_epi32(iSum, iSum);
+
+  Distortion sad = _mm_cvtsi128_si32(iSum);
+
+#if JVET_R0164_MEAN_SCALED_SATD
+  sad -= absDc;
+  sad += absDc >> 2;
+#endif
+  sad = (Distortion)(sad / sqrt(16.0 * 8) * 2);
+
+  return sad;
+}
+
+static Distortion xCalcHAD8x16_HBD_SSE(const Torg *piOrg, const Tcur *piCur, const int iStrideOrg, const int iStrideCur)
+{
+  __m128i m1[2][16], m2[2][16];
+  __m128i iSum = _mm_setzero_si128();
+
+  for (int k = 0; k < 16; k++)
+  {
+    m1[0][k] = _mm_sub_epi32(_mm_lddqu_si128((__m128i*) piOrg), _mm_lddqu_si128((__m128i*) piCur));
+    m1[1][k] = _mm_sub_epi32(_mm_lddqu_si128((__m128i*)(piOrg + 4)), _mm_lddqu_si128((__m128i*)(piCur + 4)));
+    piCur += iStrideCur;
+    piOrg += iStrideOrg;
+  }
+
+  for (int i = 0; i < 2; i++)
+  {
+    // vertical
+    m2[i][0] = _mm_add_epi32(m1[i][0], m1[i][8]);
+    m2[i][1] = _mm_add_epi32(m1[i][1], m1[i][9]);
+    m2[i][2] = _mm_add_epi32(m1[i][2], m1[i][10]);
+    m2[i][3] = _mm_add_epi32(m1[i][3], m1[i][11]);
+    m2[i][4] = _mm_add_epi32(m1[i][4], m1[i][12]);
+    m2[i][5] = _mm_add_epi32(m1[i][5], m1[i][13]);
+    m2[i][6] = _mm_add_epi32(m1[i][6], m1[i][14]);
+    m2[i][7] = _mm_add_epi32(m1[i][7], m1[i][15]);
+    m2[i][8] = _mm_sub_epi32(m1[i][0], m1[i][8]);
+    m2[i][9] = _mm_sub_epi32(m1[i][1], m1[i][9]);
+    m2[i][10] = _mm_sub_epi32(m1[i][2], m1[i][10]);
+    m2[i][11] = _mm_sub_epi32(m1[i][3], m1[i][11]);
+    m2[i][12] = _mm_sub_epi32(m1[i][4], m1[i][12]);
+    m2[i][13] = _mm_sub_epi32(m1[i][5], m1[i][13]);
+    m2[i][14] = _mm_sub_epi32(m1[i][6], m1[i][14]);
+    m2[i][15] = _mm_sub_epi32(m1[i][7], m1[i][15]);
+
+    m1[i][0] = _mm_add_epi32(m2[i][0], m2[i][4]);
+    m1[i][1] = _mm_add_epi32(m2[i][1], m2[i][5]);
+    m1[i][2] = _mm_add_epi32(m2[i][2], m2[i][6]);
+    m1[i][3] = _mm_add_epi32(m2[i][3], m2[i][7]);
+    m1[i][4] = _mm_sub_epi32(m2[i][0], m2[i][4]);
+    m1[i][5] = _mm_sub_epi32(m2[i][1], m2[i][5]);
+    m1[i][6] = _mm_sub_epi32(m2[i][2], m2[i][6]);
+    m1[i][7] = _mm_sub_epi32(m2[i][3], m2[i][7]);
+    m1[i][8] = _mm_add_epi32(m2[i][8], m2[i][12]);
+    m1[i][9] = _mm_add_epi32(m2[i][9], m2[i][13]);
+    m1[i][10] = _mm_add_epi32(m2[i][10], m2[i][14]);
+    m1[i][11] = _mm_add_epi32(m2[i][11], m2[i][15]);
+    m1[i][12] = _mm_sub_epi32(m2[i][8], m2[i][12]);
+    m1[i][13] = _mm_sub_epi32(m2[i][9], m2[i][13]);
+    m1[i][14] = _mm_sub_epi32(m2[i][10], m2[i][14]);
+    m1[i][15] = _mm_sub_epi32(m2[i][11], m2[i][15]);
+
+    m2[i][0] = _mm_add_epi32(m1[i][0], m1[i][2]);
+    m2[i][1] = _mm_add_epi32(m1[i][1], m1[i][3]);
+    m2[i][2] = _mm_sub_epi32(m1[i][0], m1[i][2]);
+    m2[i][3] = _mm_sub_epi32(m1[i][1], m1[i][3]);
+    m2[i][4] = _mm_add_epi32(m1[i][4], m1[i][6]);
+    m2[i][5] = _mm_add_epi32(m1[i][5], m1[i][7]);
+    m2[i][6] = _mm_sub_epi32(m1[i][4], m1[i][6]);
+    m2[i][7] = _mm_sub_epi32(m1[i][5], m1[i][7]);
+    m2[i][8] = _mm_add_epi32(m1[i][8], m1[i][10]);
+    m2[i][9] = _mm_add_epi32(m1[i][9], m1[i][11]);
+    m2[i][10] = _mm_sub_epi32(m1[i][8], m1[i][10]);
+    m2[i][11] = _mm_sub_epi32(m1[i][9], m1[i][11]);
+    m2[i][12] = _mm_add_epi32(m1[i][12], m1[i][14]);
+    m2[i][13] = _mm_add_epi32(m1[i][13], m1[i][15]);
+    m2[i][14] = _mm_sub_epi32(m1[i][12], m1[i][14]);
+    m2[i][15] = _mm_sub_epi32(m1[i][13], m1[i][15]);
+
+    m1[i][0] = _mm_add_epi32(m2[i][0], m2[i][1]);
+    m1[i][1] = _mm_sub_epi32(m2[i][0], m2[i][1]);
+    m1[i][2] = _mm_add_epi32(m2[i][2], m2[i][3]);
+    m1[i][3] = _mm_sub_epi32(m2[i][2], m2[i][3]);
+    m1[i][4] = _mm_add_epi32(m2[i][4], m2[i][5]);
+    m1[i][5] = _mm_sub_epi32(m2[i][4], m2[i][5]);
+    m1[i][6] = _mm_add_epi32(m2[i][6], m2[i][7]);
+    m1[i][7] = _mm_sub_epi32(m2[i][6], m2[i][7]);
+    m1[i][8] = _mm_add_epi32(m2[i][8], m2[i][9]);
+    m1[i][9] = _mm_sub_epi32(m2[i][8], m2[i][9]);
+    m1[i][10] = _mm_add_epi32(m2[i][10], m2[i][11]);
+    m1[i][11] = _mm_sub_epi32(m2[i][10], m2[i][11]);
+    m1[i][12] = _mm_add_epi32(m2[i][12], m2[i][13]);
+    m1[i][13] = _mm_sub_epi32(m2[i][12], m2[i][13]);
+    m1[i][14] = _mm_add_epi32(m2[i][14], m2[i][15]);
+    m1[i][15] = _mm_sub_epi32(m2[i][14], m2[i][15]);
+  }
+
+  // process horizontal in two steps ( 2 x 8x8 blocks )
+  for (int l = 0; l < 4; l++)
+  {
+    int off = l * 4;
+
+    for (int i = 0; i < 2; i++)
+    {
+      // transpose 4x4
+      m2[i][0 + off] = _mm_unpacklo_epi32(m1[i][0 + off], m1[i][1 + off]);
+      m2[i][1 + off] = _mm_unpackhi_epi32(m1[i][0 + off], m1[i][1 + off]);
+      m2[i][2 + off] = _mm_unpacklo_epi32(m1[i][2 + off], m1[i][3 + off]);
+      m2[i][3 + off] = _mm_unpackhi_epi32(m1[i][2 + off], m1[i][3 + off]);
+
+      m1[i][0 + off] = _mm_unpacklo_epi64(m2[i][0 + off], m2[i][2 + off]);
+      m1[i][1 + off] = _mm_unpackhi_epi64(m2[i][0 + off], m2[i][2 + off]);
+      m1[i][2 + off] = _mm_unpacklo_epi64(m2[i][1 + off], m2[i][3 + off]);
+      m1[i][3 + off] = _mm_unpackhi_epi64(m2[i][1 + off], m2[i][3 + off]);
+    }
+  }
+
+#if JVET_R0164_MEAN_SCALED_SATD
+  uint32_t absDc = 0;
+#endif
+
+  for (int l = 0; l < 2; l++)
+  {
+    int off = l * 8;
+
+    __m128i n1[2][8];
+    __m128i n2[2][8];
+
+    for (int i = 0; i < 8; i++)
+    {
+      int ii = i % 4;
+      int ij = i >> 2;
+
+      n2[0][i] = m1[ij][off + ii];
+      n2[1][i] = m1[ij][off + ii + 4];
+    }
+
+    for (int i = 0; i < 2; i++)
+    {
+      n1[i][0] = _mm_add_epi32(n2[i][0], n2[i][4]);
+      n1[i][1] = _mm_add_epi32(n2[i][1], n2[i][5]);
+      n1[i][2] = _mm_add_epi32(n2[i][2], n2[i][6]);
+      n1[i][3] = _mm_add_epi32(n2[i][3], n2[i][7]);
+      n1[i][4] = _mm_sub_epi32(n2[i][0], n2[i][4]);
+      n1[i][5] = _mm_sub_epi32(n2[i][1], n2[i][5]);
+      n1[i][6] = _mm_sub_epi32(n2[i][2], n2[i][6]);
+      n1[i][7] = _mm_sub_epi32(n2[i][3], n2[i][7]);
+
+      n2[i][0] = _mm_add_epi32(n1[i][0], n1[i][2]);
+      n2[i][1] = _mm_add_epi32(n1[i][1], n1[i][3]);
+      n2[i][2] = _mm_sub_epi32(n1[i][0], n1[i][2]);
+      n2[i][3] = _mm_sub_epi32(n1[i][1], n1[i][3]);
+      n2[i][4] = _mm_add_epi32(n1[i][4], n1[i][6]);
+      n2[i][5] = _mm_add_epi32(n1[i][5], n1[i][7]);
+      n2[i][6] = _mm_sub_epi32(n1[i][4], n1[i][6]);
+      n2[i][7] = _mm_sub_epi32(n1[i][5], n1[i][7]);
+
+      n1[i][0] = _mm_abs_epi32(_mm_add_epi32(n2[i][0], n2[i][1]));
+      n1[i][1] = _mm_abs_epi32(_mm_sub_epi32(n2[i][0], n2[i][1]));
+      n1[i][2] = _mm_abs_epi32(_mm_add_epi32(n2[i][2], n2[i][3]));
+      n1[i][3] = _mm_abs_epi32(_mm_sub_epi32(n2[i][2], n2[i][3]));
+      n1[i][4] = _mm_abs_epi32(_mm_add_epi32(n2[i][4], n2[i][5]));
+      n1[i][5] = _mm_abs_epi32(_mm_sub_epi32(n2[i][4], n2[i][5]));
+      n1[i][6] = _mm_abs_epi32(_mm_add_epi32(n2[i][6], n2[i][7]));
+      n1[i][7] = _mm_abs_epi32(_mm_sub_epi32(n2[i][6], n2[i][7]));
+
+#if JVET_R0164_MEAN_SCALED_SATD
+      if (l + i == 0)
+        absDc = _mm_cvtsi128_si32(n1[i][0]);
+#endif
+    }
+
+    for (int i = 0; i < 8; i++)
+    {
+      n2[0][i] = _mm_add_epi32(n1[0][i], n1[1][i]);
+    }
+
+    n2[0][0] = _mm_add_epi32(n2[0][0], n2[0][1]);
+    n2[0][2] = _mm_add_epi32(n2[0][2], n2[0][3]);
+    n2[0][4] = _mm_add_epi32(n2[0][4], n2[0][5]);
+    n2[0][6] = _mm_add_epi32(n2[0][6], n2[0][7]);
+
+    n2[0][0] = _mm_add_epi32(n2[0][0], n2[0][2]);
+    n2[0][4] = _mm_add_epi32(n2[0][4], n2[0][6]);
+    iSum = _mm_add_epi32(iSum, _mm_add_epi32(n2[0][0], n2[0][4]));
+  }
+
+  iSum = _mm_hadd_epi32(iSum, iSum);
+  iSum = _mm_hadd_epi32(iSum, iSum);
+
+  Distortion sad = _mm_cvtsi128_si32(iSum);
+#if JVET_R0164_MEAN_SCALED_SATD
+  sad -= absDc;
+  sad += absDc >> 2;
+#endif
+  sad = (Distortion)(sad / sqrt(16.0 * 8) * 2);
+
+  return sad;
+}
+
+#ifdef USE_AVX2
+static Distortion xCalcHAD4x4_HBD_AVX2(const Torg *piOrg, const Tcur *piCur, const int iStrideOrg, const int iStrideCur)
+{
+  __m256i r0 = _mm256_castsi128_si256(_mm_lddqu_si128((const __m128i*)&piOrg[0]));
+  __m256i r1 = _mm256_castsi128_si256(_mm_lddqu_si128((const __m128i*)&piOrg[iStrideOrg]));
+  __m256i r2 = _mm256_castsi128_si256(_mm_lddqu_si128((const __m128i*)&piOrg[2 * iStrideOrg]));
+  __m256i r3 = _mm256_castsi128_si256(_mm_lddqu_si128((const __m128i*)&piOrg[3 * iStrideOrg]));
+  __m256i r4 = _mm256_castsi128_si256(_mm_lddqu_si128((const __m128i*)&piCur[0]));
+  __m256i r5 = _mm256_castsi128_si256(_mm_lddqu_si128((const __m128i*)&piCur[iStrideCur]));
+  __m256i r6 = _mm256_castsi128_si256(_mm_lddqu_si128((const __m128i*)&piCur[2 * iStrideCur]));
+  __m256i r7 = _mm256_castsi128_si256(_mm_lddqu_si128((const __m128i*)&piCur[3 * iStrideCur]));
+
+  r0 = _mm256_sub_epi32(r0, r4);
+  r1 = _mm256_sub_epi32(r1, r5);
+  r2 = _mm256_sub_epi32(r2, r6);
+  r3 = _mm256_sub_epi32(r3, r7);
+
+  // first stage
+  r4 = r0;
+  r5 = r1;
+
+  r0 = _mm256_add_epi32(r0, r3);
+  r1 = _mm256_add_epi32(r1, r2);
+
+  r4 = _mm256_sub_epi32(r4, r3);
+  r5 = _mm256_sub_epi32(r5, r2);
+
+  r2 = r0;
+  r3 = r4;
+
+  r0 = _mm256_add_epi32(r0, r1);
+  r2 = _mm256_sub_epi32(r2, r1);
+  r3 = _mm256_sub_epi32(r3, r5);
+  r5 = _mm256_add_epi32(r5, r4);
+
+  // shuffle - flip matrix for vertical transform
+  r0 = _mm256_permute4x64_epi64(r0, 0x50);
+  r2 = _mm256_permute4x64_epi64(r2, 0x50);
+  r3 = _mm256_permute4x64_epi64(r3, 0x50);
+  r5 = _mm256_permute4x64_epi64(r5, 0x50);
+
+  r0 = _mm256_unpacklo_epi32(r0, r5);
+  r2 = _mm256_unpacklo_epi32(r2, r3);
+
+  r1 = r0;
+  r0 = _mm256_unpacklo_epi64(r0, r2);
+  r1 = _mm256_unpackhi_epi64(r1, r2);
+
+  r2 = _mm256_permute4x64_epi64(r0, 0xee);
+  r3 = _mm256_permute4x64_epi64(r1, 0xee);
+
+  // second stage
+  r4 = r0;
+  r5 = r1;
+
+  r0 = _mm256_add_epi32(r0, r3);
+  r1 = _mm256_add_epi32(r1, r2);
+
+  r4 = _mm256_sub_epi32(r4, r3);
+  r5 = _mm256_sub_epi32(r5, r2);
+
+  r2 = r0;
+  r3 = r4;
+
+  r0 = _mm256_add_epi32(r0, r1);
+  r2 = _mm256_sub_epi32(r2, r1);
+  r3 = _mm256_sub_epi32(r3, r5);
+  r5 = _mm256_add_epi32(r5, r4);
+
+  // abs
+  __m256i Sum = _mm256_abs_epi32(r0);
+#if JVET_R0164_MEAN_SCALED_SATD
+  Distortion absDc = _mm_cvtsi128_si32(_mm256_castsi256_si128(Sum));
+#endif
+  Sum = _mm256_add_epi32(Sum, _mm256_abs_epi32(r2));
+  Sum = _mm256_add_epi32(Sum, _mm256_abs_epi32(r3));
+  Sum = _mm256_add_epi32(Sum, _mm256_abs_epi32(r5));
+  Sum = _mm256_hadd_epi32(Sum, Sum);
+  Sum = _mm256_hadd_epi32(Sum, Sum);
+
+  Distortion sad = _mm_cvtsi128_si32(_mm256_castsi256_si128(Sum));
+
+#if JVET_R0164_MEAN_SCALED_SATD
+  sad -= absDc;
+  sad += absDc >> 2;
+#endif
+  sad = ((sad + 1) >> 1);
+
+  return sad;
+}
+
+static Distortion xCalcHAD8x8_HBD_AVX2(const Torg *piOrg, const Tcur *piCur, const int iStrideOrg, const int iStrideCur)
+{
+  __m256i m1[8], m2[8];
+
+  for (int k = 0; k < 8; k++)
+  {
+    m2[k] = _mm256_sub_epi32(_mm256_lddqu_si256((__m256i *) piOrg), _mm256_lddqu_si256((__m256i *) piCur));
+    piCur += iStrideCur;
+    piOrg += iStrideOrg;
+  }
+
+  // vertical
+  m1[0] = _mm256_add_epi32(m2[0], m2[4]);
+  m1[1] = _mm256_add_epi32(m2[1], m2[5]);
+  m1[2] = _mm256_add_epi32(m2[2], m2[6]);
+  m1[3] = _mm256_add_epi32(m2[3], m2[7]);
+  m1[4] = _mm256_sub_epi32(m2[0], m2[4]);
+  m1[5] = _mm256_sub_epi32(m2[1], m2[5]);
+  m1[6] = _mm256_sub_epi32(m2[2], m2[6]);
+  m1[7] = _mm256_sub_epi32(m2[3], m2[7]);
+
+  m2[0] = _mm256_add_epi32(m1[0], m1[2]);
+  m2[1] = _mm256_add_epi32(m1[1], m1[3]);
+  m2[2] = _mm256_sub_epi32(m1[0], m1[2]);
+  m2[3] = _mm256_sub_epi32(m1[1], m1[3]);
+  m2[4] = _mm256_add_epi32(m1[4], m1[6]);
+  m2[5] = _mm256_add_epi32(m1[5], m1[7]);
+  m2[6] = _mm256_sub_epi32(m1[4], m1[6]);
+  m2[7] = _mm256_sub_epi32(m1[5], m1[7]);
+
+  m1[0] = _mm256_add_epi32(m2[0], m2[1]);
+  m1[1] = _mm256_sub_epi32(m2[0], m2[1]);
+  m1[2] = _mm256_add_epi32(m2[2], m2[3]);
+  m1[3] = _mm256_sub_epi32(m2[2], m2[3]);
+  m1[4] = _mm256_add_epi32(m2[4], m2[5]);
+  m1[5] = _mm256_sub_epi32(m2[4], m2[5]);
+  m1[6] = _mm256_add_epi32(m2[6], m2[7]);
+  m1[7] = _mm256_sub_epi32(m2[6], m2[7]);
+
+  // transpose
+  m2[0] = _mm256_unpacklo_epi32(m1[0], m1[1]);
+  m2[1] = _mm256_unpacklo_epi32(m1[2], m1[3]);
+  m2[2] = _mm256_unpacklo_epi32(m1[4], m1[5]);
+  m2[3] = _mm256_unpacklo_epi32(m1[6], m1[7]);
+  m2[4] = _mm256_unpackhi_epi32(m1[0], m1[1]);
+  m2[5] = _mm256_unpackhi_epi32(m1[2], m1[3]);
+  m2[6] = _mm256_unpackhi_epi32(m1[4], m1[5]);
+  m2[7] = _mm256_unpackhi_epi32(m1[6], m1[7]);
+
+  m1[0] = _mm256_unpacklo_epi64(m2[0], m2[1]);
+  m1[1] = _mm256_unpacklo_epi64(m2[2], m2[3]);
+  m1[2] = _mm256_unpacklo_epi64(m2[4], m2[5]);
+  m1[3] = _mm256_unpacklo_epi64(m2[6], m2[7]);
+  m1[4] = _mm256_unpackhi_epi64(m2[0], m2[1]);
+  m1[5] = _mm256_unpackhi_epi64(m2[2], m2[3]);
+  m1[6] = _mm256_unpackhi_epi64(m2[4], m2[5]);
+  m1[7] = _mm256_unpackhi_epi64(m2[6], m2[7]);
+
+  m2[0] = _mm256_permute2x128_si256(m1[0], m1[1], 0x20);
+  m2[4] = _mm256_permute2x128_si256(m1[0], m1[1], 0x31);
+  m2[2] = _mm256_permute2x128_si256(m1[2], m1[3], 0x20);
+  m2[6] = _mm256_permute2x128_si256(m1[2], m1[3], 0x31);
+  m2[1] = _mm256_permute2x128_si256(m1[4], m1[5], 0x20);
+  m2[5] = _mm256_permute2x128_si256(m1[4], m1[5], 0x31);
+  m2[3] = _mm256_permute2x128_si256(m1[6], m1[7], 0x20);
+  m2[7] = _mm256_permute2x128_si256(m1[6], m1[7], 0x31);
+
+  // horizontal
+  m1[0] = _mm256_add_epi32(m2[0], m2[4]);
+  m1[1] = _mm256_add_epi32(m2[1], m2[5]);
+  m1[2] = _mm256_add_epi32(m2[2], m2[6]);
+  m1[3] = _mm256_add_epi32(m2[3], m2[7]);
+  m1[4] = _mm256_sub_epi32(m2[0], m2[4]);
+  m1[5] = _mm256_sub_epi32(m2[1], m2[5]);
+  m1[6] = _mm256_sub_epi32(m2[2], m2[6]);
+  m1[7] = _mm256_sub_epi32(m2[3], m2[7]);
+
+  m2[0] = _mm256_add_epi32(m1[0], m1[2]);
+  m2[1] = _mm256_add_epi32(m1[1], m1[3]);
+  m2[2] = _mm256_sub_epi32(m1[0], m1[2]);
+  m2[3] = _mm256_sub_epi32(m1[1], m1[3]);
+  m2[4] = _mm256_add_epi32(m1[4], m1[6]);
+  m2[5] = _mm256_add_epi32(m1[5], m1[7]);
+  m2[6] = _mm256_sub_epi32(m1[4], m1[6]);
+  m2[7] = _mm256_sub_epi32(m1[5], m1[7]);
+
+  m1[0] = _mm256_abs_epi32(_mm256_add_epi32(m2[0], m2[1]));
+  m1[1] = _mm256_abs_epi32(_mm256_sub_epi32(m2[0], m2[1]));
+  m1[2] = _mm256_abs_epi32(_mm256_add_epi32(m2[2], m2[3]));
+  m1[3] = _mm256_abs_epi32(_mm256_sub_epi32(m2[2], m2[3]));
+  m1[4] = _mm256_abs_epi32(_mm256_add_epi32(m2[4], m2[5]));
+  m1[5] = _mm256_abs_epi32(_mm256_sub_epi32(m2[4], m2[5]));
+  m1[6] = _mm256_abs_epi32(_mm256_add_epi32(m2[6], m2[7]));
+  m1[7] = _mm256_abs_epi32(_mm256_sub_epi32(m2[6], m2[7]));
+
+  m2[0] = _mm256_add_epi32(m1[0], m1[1]);
+  m2[2] = _mm256_add_epi32(m1[2], m1[3]);
+  m2[4] = _mm256_add_epi32(m1[4], m1[5]);
+  m2[6] = _mm256_add_epi32(m1[6], m1[7]);
+
+  m2[0] = _mm256_add_epi32(m2[0], m2[2]);
+  m2[4] = _mm256_add_epi32(m2[4], m2[6]);
+  __m256i iSum = _mm256_add_epi32(m2[0], m2[4]);
+
+  iSum = _mm256_hadd_epi32(iSum, iSum);
+  iSum = _mm256_hadd_epi32(iSum, iSum);
+
+  Distortion sad = _mm_cvtsi128_si32(_mm256_castsi256_si128(iSum));
+  sad += _mm_cvtsi128_si32(_mm256_castsi256_si128(_mm256_permute4x64_epi64(iSum, 0xee)));
+#if JVET_R0164_MEAN_SCALED_SATD
+  Distortion absDc = _mm_cvtsi128_si32(_mm256_castsi256_si128(m1[0]));
+  sad -= absDc;
+  sad += absDc >> 2;
+#endif
+  sad = ((sad + 2) >> 2);
+
+  return sad;
+}
+
+static Distortion xCalcHAD4x8_HBD_AVX2(const Torg *piOrg, const Tcur *piCur, const int iStrideOrg, const int iStrideCur)
+{
+  __m256i m1[8], m2[8], n1[4], n2[4];
+  for (int k = 0; k < 8; k++)
+  {
+    m2[k] = _mm256_sub_epi32(_mm256_castsi128_si256(_mm_lddqu_si128((__m128i*)piOrg)), _mm256_castsi128_si256(_mm_lddqu_si128((__m128i*)piCur)));
+    piCur += iStrideCur;
+    piOrg += iStrideOrg;
+  }
+
+  // vertical
+  m1[0] = _mm256_add_epi32(m2[0], m2[4]);
+  m1[1] = _mm256_add_epi32(m2[1], m2[5]);
+  m1[2] = _mm256_add_epi32(m2[2], m2[6]);
+  m1[3] = _mm256_add_epi32(m2[3], m2[7]);
+  m1[4] = _mm256_sub_epi32(m2[0], m2[4]);
+  m1[5] = _mm256_sub_epi32(m2[1], m2[5]);
+  m1[6] = _mm256_sub_epi32(m2[2], m2[6]);
+  m1[7] = _mm256_sub_epi32(m2[3], m2[7]);
+
+  m2[0] = _mm256_add_epi32(m1[0], m1[2]);
+  m2[1] = _mm256_add_epi32(m1[1], m1[3]);
+  m2[2] = _mm256_sub_epi32(m1[0], m1[2]);
+  m2[3] = _mm256_sub_epi32(m1[1], m1[3]);
+  m2[4] = _mm256_add_epi32(m1[4], m1[6]);
+  m2[5] = _mm256_add_epi32(m1[5], m1[7]);
+  m2[6] = _mm256_sub_epi32(m1[4], m1[6]);
+  m2[7] = _mm256_sub_epi32(m1[5], m1[7]);
+
+  m1[0] = _mm256_permute4x64_epi64(_mm256_add_epi32(m2[0], m2[1]), 0x50);
+  m1[1] = _mm256_permute4x64_epi64(_mm256_sub_epi32(m2[0], m2[1]), 0x50);
+  m1[2] = _mm256_permute4x64_epi64(_mm256_add_epi32(m2[2], m2[3]), 0x50);
+  m1[3] = _mm256_permute4x64_epi64(_mm256_sub_epi32(m2[2], m2[3]), 0x50);
+  m1[4] = _mm256_permute4x64_epi64(_mm256_add_epi32(m2[4], m2[5]), 0x50);
+  m1[5] = _mm256_permute4x64_epi64(_mm256_sub_epi32(m2[4], m2[5]), 0x50);
+  m1[6] = _mm256_permute4x64_epi64(_mm256_add_epi32(m2[6], m2[7]), 0x50);
+  m1[7] = _mm256_permute4x64_epi64(_mm256_sub_epi32(m2[6], m2[7]), 0x50);
+
+  // transpose
+  m2[0] = _mm256_unpacklo_epi32(m1[0], m1[1]);
+  m2[1] = _mm256_unpacklo_epi32(m1[2], m1[3]);
+  m2[2] = _mm256_unpacklo_epi32(m1[4], m1[5]);
+  m2[3] = _mm256_unpacklo_epi32(m1[6], m1[7]);
+
+  m1[0] = _mm256_unpacklo_epi64(m2[0], m2[1]);
+  m1[1] = _mm256_unpackhi_epi64(m2[0], m2[1]);
+  m1[2] = _mm256_unpacklo_epi64(m2[2], m2[3]);
+  m1[3] = _mm256_unpackhi_epi64(m2[2], m2[3]);
+
+  n1[0] = _mm256_inserti128_si256(m1[0], _mm256_castsi256_si128(m1[2]), 1);
+  n1[1] = _mm256_inserti128_si256(m1[1], _mm256_castsi256_si128(m1[3]), 1);
+  n1[2] = _mm256_inserti128_si256(m1[2], _mm256_castsi256_si128(_mm256_permute4x64_epi64(m1[0], 0xee)), 0);
+  n1[3] = _mm256_inserti128_si256(m1[3], _mm256_castsi256_si128(_mm256_permute4x64_epi64(m1[1], 0xee)), 0);
+
+  n2[0] = _mm256_add_epi32(n1[0], n1[2]);
+  n2[1] = _mm256_add_epi32(n1[1], n1[3]);
+  n2[2] = _mm256_sub_epi32(n1[0], n1[2]);
+  n2[3] = _mm256_sub_epi32(n1[1], n1[3]);
+
+  n1[0] = _mm256_abs_epi32(_mm256_add_epi32(n2[0], n2[1]));
+  n1[1] = _mm256_abs_epi32(_mm256_sub_epi32(n2[0], n2[1]));
+  n1[2] = _mm256_abs_epi32(_mm256_add_epi32(n2[2], n2[3]));
+  n1[3] = _mm256_abs_epi32(_mm256_sub_epi32(n2[2], n2[3]));
+#if JVET_R0164_MEAN_SCALED_SATD
+  Distortion absDc = _mm_cvtsi128_si32(_mm256_castsi256_si128(n1[0]));
+#endif
+
+  m1[0] = _mm256_add_epi32(n1[0], n1[1]);
+  m1[2] = _mm256_add_epi32(n1[2], n1[3]);
+
+  __m256i iSum = _mm256_add_epi32(m1[0], m1[2]);
+  iSum = _mm256_hadd_epi32(iSum, iSum);
+  iSum = _mm256_hadd_epi32(iSum, iSum);
+
+  Distortion sad = _mm_cvtsi128_si32(_mm256_castsi256_si128(iSum));
+  sad += _mm_cvtsi128_si32(_mm256_castsi256_si128(_mm256_permute4x64_epi64(iSum, 0xee)));
+
+#if JVET_R0164_MEAN_SCALED_SATD
+  sad -= absDc;
+  sad += absDc >> 2;
+#endif
+  sad = (Distortion)(sad / sqrt(4.0 * 8) * 2);
+
+  return sad;
+}
+
+static Distortion xCalcHAD8x4_HBD_AVX2(const Torg *piOrg, const Tcur *piCur, const int iStrideOrg, const int iStrideCur)
+{
+  __m256i m1[8], m2[8];
+
+  for (int k = 0; k < 4; k++)
+  {
+    m1[k] = _mm256_sub_epi32(_mm256_lddqu_si256((__m256i*) piOrg), _mm256_lddqu_si256((__m256i*) piCur));
+    piCur += iStrideCur;
+    piOrg += iStrideOrg;
+  }
+
+  // vertical
+  m2[0] = _mm256_add_epi32(m1[0], m1[2]);
+  m2[1] = _mm256_add_epi32(m1[1], m1[3]);
+  m2[2] = _mm256_sub_epi32(m1[0], m1[2]);
+  m2[3] = _mm256_sub_epi32(m1[1], m1[3]);
+
+  m1[0] = _mm256_add_epi32(m2[0], m2[1]);
+  m1[1] = _mm256_sub_epi32(m2[0], m2[1]);
+  m1[2] = _mm256_add_epi32(m2[2], m2[3]);
+  m1[3] = _mm256_sub_epi32(m2[2], m2[3]);
+
+  // transpose
+  m2[0] = _mm256_unpacklo_epi32(m1[0], m1[1]);
+  m2[1] = _mm256_unpacklo_epi32(m1[2], m1[3]);
+  m2[2] = _mm256_unpackhi_epi32(m1[0], m1[1]);
+  m2[3] = _mm256_unpackhi_epi32(m1[2], m1[3]);
+
+  m1[0] = _mm256_unpacklo_epi64(m2[0], m2[1]);
+  m1[1] = _mm256_unpackhi_epi64(m2[0], m2[1]);
+  m1[2] = _mm256_unpacklo_epi64(m2[2], m2[3]);
+  m1[3] = _mm256_unpackhi_epi64(m2[2], m2[3]);
+
+  m2[0] = m1[0];
+  m2[1] = m1[1];
+  m2[2] = m1[2];
+  m2[3] = m1[3];
+  m2[4] = _mm256_permute4x64_epi64(m1[0], 0xee);
+  m2[5] = _mm256_permute4x64_epi64(m1[1], 0xee);
+  m2[6] = _mm256_permute4x64_epi64(m1[2], 0xee);
+  m2[7] = _mm256_permute4x64_epi64(m1[3], 0xee);
+
+  // horizontal
+  m1[0] = _mm256_add_epi32(m2[0], m2[4]);
+  m1[1] = _mm256_add_epi32(m2[1], m2[5]);
+  m1[2] = _mm256_add_epi32(m2[2], m2[6]);
+  m1[3] = _mm256_add_epi32(m2[3], m2[7]);
+  m1[4] = _mm256_sub_epi32(m2[0], m2[4]);
+  m1[5] = _mm256_sub_epi32(m2[1], m2[5]);
+  m1[6] = _mm256_sub_epi32(m2[2], m2[6]);
+  m1[7] = _mm256_sub_epi32(m2[3], m2[7]);
+
+  m2[0] = _mm256_add_epi32(m1[0], m1[2]);
+  m2[1] = _mm256_add_epi32(m1[1], m1[3]);
+  m2[2] = _mm256_sub_epi32(m1[0], m1[2]);
+  m2[3] = _mm256_sub_epi32(m1[1], m1[3]);
+  m2[4] = _mm256_add_epi32(m1[4], m1[6]);
+  m2[5] = _mm256_add_epi32(m1[5], m1[7]);
+  m2[6] = _mm256_sub_epi32(m1[4], m1[6]);
+  m2[7] = _mm256_sub_epi32(m1[5], m1[7]);
+
+  m1[0] = _mm256_abs_epi32(_mm256_add_epi32(m2[0], m2[1]));
+  m1[1] = _mm256_abs_epi32(_mm256_sub_epi32(m2[0], m2[1]));
+  m1[2] = _mm256_abs_epi32(_mm256_add_epi32(m2[2], m2[3]));
+  m1[3] = _mm256_abs_epi32(_mm256_sub_epi32(m2[2], m2[3]));
+  m1[4] = _mm256_abs_epi32(_mm256_add_epi32(m2[4], m2[5]));
+  m1[5] = _mm256_abs_epi32(_mm256_sub_epi32(m2[4], m2[5]));
+  m1[6] = _mm256_abs_epi32(_mm256_add_epi32(m2[6], m2[7]));
+  m1[7] = _mm256_abs_epi32(_mm256_sub_epi32(m2[6], m2[7]));
+
+#if JVET_R0164_MEAN_SCALED_SATD
+  Distortion absDc = _mm_cvtsi128_si32(_mm256_castsi256_si128(m1[0]));
+#endif
+  m1[0] = _mm256_add_epi32(m1[0], m1[1]);
+  m1[1] = _mm256_add_epi32(m1[2], m1[3]);
+  m1[2] = _mm256_add_epi32(m1[4], m1[5]);
+  m1[3] = _mm256_add_epi32(m1[6], m1[7]);
+
+  m1[0] = _mm256_add_epi32(m1[0], m1[1]);
+  m1[1] = _mm256_add_epi32(m1[2], m1[3]);
+
+  __m256i iSum = _mm256_add_epi32(m1[0], m1[1]);
+  iSum = _mm256_hadd_epi32(iSum, iSum);
+  iSum = _mm256_hadd_epi32(iSum, iSum);
+
+  Distortion sad = _mm_cvtsi128_si32(_mm256_castsi256_si128(iSum));
+#if JVET_R0164_MEAN_SCALED_SATD
+  sad -= absDc;
+  sad += absDc >> 2;
+#endif
+  sad = (Distortion)(sad / sqrt(4.0 * 8) * 2);
+  return sad;
+}
+
+static Distortion xCalcHAD16x8_HBD_AVX2(const Torg *piOrg, const Tcur *piCur, const int iStrideOrg, const int iStrideCur)
+{
+  __m256i m1[16], m2[16];
+
+  for (int k = 0; k < 8; k++)
+  {
+    m1[k] = _mm256_sub_epi32(_mm256_lddqu_si256((__m256i*) piOrg), _mm256_lddqu_si256((__m256i*) piCur));
+    m1[k + 8] = _mm256_sub_epi32(_mm256_lddqu_si256((__m256i*)(piOrg + 8)), _mm256_lddqu_si256((__m256i*)(piCur + 8)));
+    piCur += iStrideCur;
+    piOrg += iStrideOrg;
+  }
+
+  // vertical, first 8x8
+  m2[0] = _mm256_add_epi32(m1[0], m1[4]);
+  m2[1] = _mm256_add_epi32(m1[1], m1[5]);
+  m2[2] = _mm256_add_epi32(m1[2], m1[6]);
+  m2[3] = _mm256_add_epi32(m1[3], m1[7]);
+  m2[4] = _mm256_sub_epi32(m1[0], m1[4]);
+  m2[5] = _mm256_sub_epi32(m1[1], m1[5]);
+  m2[6] = _mm256_sub_epi32(m1[2], m1[6]);
+  m2[7] = _mm256_sub_epi32(m1[3], m1[7]);
+
+  m1[0] = _mm256_add_epi32(m2[0], m2[2]);
+  m1[1] = _mm256_add_epi32(m2[1], m2[3]);
+  m1[2] = _mm256_sub_epi32(m2[0], m2[2]);
+  m1[3] = _mm256_sub_epi32(m2[1], m2[3]);
+  m1[4] = _mm256_add_epi32(m2[4], m2[6]);
+  m1[5] = _mm256_add_epi32(m2[5], m2[7]);
+  m1[6] = _mm256_sub_epi32(m2[4], m2[6]);
+  m1[7] = _mm256_sub_epi32(m2[5], m2[7]);
+
+  m2[0] = _mm256_add_epi32(m1[0], m1[1]);
+  m2[1] = _mm256_sub_epi32(m1[0], m1[1]);
+  m2[2] = _mm256_add_epi32(m1[2], m1[3]);
+  m2[3] = _mm256_sub_epi32(m1[2], m1[3]);
+  m2[4] = _mm256_add_epi32(m1[4], m1[5]);
+  m2[5] = _mm256_sub_epi32(m1[4], m1[5]);
+  m2[6] = _mm256_add_epi32(m1[6], m1[7]);
+  m2[7] = _mm256_sub_epi32(m1[6], m1[7]);
+
+  // vertical, second 8x8
+  m2[8 + 0] = _mm256_add_epi32(m1[8 + 0], m1[8 + 4]);
+  m2[8 + 1] = _mm256_add_epi32(m1[8 + 1], m1[8 + 5]);
+  m2[8 + 2] = _mm256_add_epi32(m1[8 + 2], m1[8 + 6]);
+  m2[8 + 3] = _mm256_add_epi32(m1[8 + 3], m1[8 + 7]);
+  m2[8 + 4] = _mm256_sub_epi32(m1[8 + 0], m1[8 + 4]);
+  m2[8 + 5] = _mm256_sub_epi32(m1[8 + 1], m1[8 + 5]);
+  m2[8 + 6] = _mm256_sub_epi32(m1[8 + 2], m1[8 + 6]);
+  m2[8 + 7] = _mm256_sub_epi32(m1[8 + 3], m1[8 + 7]);
+
+  m1[8 + 0] = _mm256_add_epi32(m2[8 + 0], m2[8 + 2]);
+  m1[8 + 1] = _mm256_add_epi32(m2[8 + 1], m2[8 + 3]);
+  m1[8 + 2] = _mm256_sub_epi32(m2[8 + 0], m2[8 + 2]);
+  m1[8 + 3] = _mm256_sub_epi32(m2[8 + 1], m2[8 + 3]);
+  m1[8 + 4] = _mm256_add_epi32(m2[8 + 4], m2[8 + 6]);
+  m1[8 + 5] = _mm256_add_epi32(m2[8 + 5], m2[8 + 7]);
+  m1[8 + 6] = _mm256_sub_epi32(m2[8 + 4], m2[8 + 6]);
+  m1[8 + 7] = _mm256_sub_epi32(m2[8 + 5], m2[8 + 7]);
+
+  m2[8 + 0] = _mm256_add_epi32(m1[8 + 0], m1[8 + 1]);
+  m2[8 + 1] = _mm256_sub_epi32(m1[8 + 0], m1[8 + 1]);
+  m2[8 + 2] = _mm256_add_epi32(m1[8 + 2], m1[8 + 3]);
+  m2[8 + 3] = _mm256_sub_epi32(m1[8 + 2], m1[8 + 3]);
+  m2[8 + 4] = _mm256_add_epi32(m1[8 + 4], m1[8 + 5]);
+  m2[8 + 5] = _mm256_sub_epi32(m1[8 + 4], m1[8 + 5]);
+  m2[8 + 6] = _mm256_add_epi32(m1[8 + 6], m1[8 + 7]);
+  m2[8 + 7] = _mm256_sub_epi32(m1[8 + 6], m1[8 + 7]);
+
+  // transpose
+  constexpr int perm_unpacklo_epi128 = (0 << 0) + (2 << 4);
+  constexpr int perm_unpackhi_epi128 = (1 << 0) + (3 << 4);
+
+  m1[0] = _mm256_unpacklo_epi32(m2[0], m2[1]);
+  m1[1] = _mm256_unpacklo_epi32(m2[2], m2[3]);
+  m1[2] = _mm256_unpacklo_epi32(m2[4], m2[5]);
+  m1[3] = _mm256_unpacklo_epi32(m2[6], m2[7]);
+  m1[4] = _mm256_unpackhi_epi32(m2[0], m2[1]);
+  m1[5] = _mm256_unpackhi_epi32(m2[2], m2[3]);
+  m1[6] = _mm256_unpackhi_epi32(m2[4], m2[5]);
+  m1[7] = _mm256_unpackhi_epi32(m2[6], m2[7]);
+
+  m2[0] = _mm256_unpacklo_epi64(m1[0], m1[1]);
+  m2[1] = _mm256_unpackhi_epi64(m1[0], m1[1]);
+  m2[2] = _mm256_unpacklo_epi64(m1[2], m1[3]);
+  m2[3] = _mm256_unpackhi_epi64(m1[2], m1[3]);
+  m2[4] = _mm256_unpacklo_epi64(m1[4], m1[5]);
+  m2[5] = _mm256_unpackhi_epi64(m1[4], m1[5]);
+  m2[6] = _mm256_unpacklo_epi64(m1[6], m1[7]);
+  m2[7] = _mm256_unpackhi_epi64(m1[6], m1[7]);
+
+  m1[0] = _mm256_permute2x128_si256(m2[0], m2[2], perm_unpacklo_epi128);
+  m1[1] = _mm256_permute2x128_si256(m2[0], m2[2], perm_unpackhi_epi128);
+  m1[2] = _mm256_permute2x128_si256(m2[1], m2[3], perm_unpacklo_epi128);
+  m1[3] = _mm256_permute2x128_si256(m2[1], m2[3], perm_unpackhi_epi128);
+  m1[4] = _mm256_permute2x128_si256(m2[4], m2[6], perm_unpacklo_epi128);
+  m1[5] = _mm256_permute2x128_si256(m2[4], m2[6], perm_unpackhi_epi128);
+  m1[6] = _mm256_permute2x128_si256(m2[5], m2[7], perm_unpacklo_epi128);
+  m1[7] = _mm256_permute2x128_si256(m2[5], m2[7], perm_unpackhi_epi128);
+
+  m1[8 + 0] = _mm256_unpacklo_epi32(m2[8 + 0], m2[8 + 1]);
+  m1[8 + 1] = _mm256_unpacklo_epi32(m2[8 + 2], m2[8 + 3]);
+  m1[8 + 2] = _mm256_unpacklo_epi32(m2[8 + 4], m2[8 + 5]);
+  m1[8 + 3] = _mm256_unpacklo_epi32(m2[8 + 6], m2[8 + 7]);
+  m1[8 + 4] = _mm256_unpackhi_epi32(m2[8 + 0], m2[8 + 1]);
+  m1[8 + 5] = _mm256_unpackhi_epi32(m2[8 + 2], m2[8 + 3]);
+  m1[8 + 6] = _mm256_unpackhi_epi32(m2[8 + 4], m2[8 + 5]);
+  m1[8 + 7] = _mm256_unpackhi_epi32(m2[8 + 6], m2[8 + 7]);
+
+  m2[8 + 0] = _mm256_unpacklo_epi64(m1[8 + 0], m1[8 + 1]);
+  m2[8 + 1] = _mm256_unpackhi_epi64(m1[8 + 0], m1[8 + 1]);
+  m2[8 + 2] = _mm256_unpacklo_epi64(m1[8 + 2], m1[8 + 3]);
+  m2[8 + 3] = _mm256_unpackhi_epi64(m1[8 + 2], m1[8 + 3]);
+  m2[8 + 4] = _mm256_unpacklo_epi64(m1[8 + 4], m1[8 + 5]);
+  m2[8 + 5] = _mm256_unpackhi_epi64(m1[8 + 4], m1[8 + 5]);
+  m2[8 + 6] = _mm256_unpacklo_epi64(m1[8 + 6], m1[8 + 7]);
+  m2[8 + 7] = _mm256_unpackhi_epi64(m1[8 + 6], m1[8 + 7]);
+
+  m1[8 + 0] = _mm256_permute2x128_si256(m2[8 + 0], m2[8 + 2], perm_unpacklo_epi128);
+  m1[8 + 1] = _mm256_permute2x128_si256(m2[8 + 0], m2[8 + 2], perm_unpackhi_epi128);
+  m1[8 + 2] = _mm256_permute2x128_si256(m2[8 + 1], m2[8 + 3], perm_unpacklo_epi128);
+  m1[8 + 3] = _mm256_permute2x128_si256(m2[8 + 1], m2[8 + 3], perm_unpackhi_epi128);
+  m1[8 + 4] = _mm256_permute2x128_si256(m2[8 + 4], m2[8 + 6], perm_unpacklo_epi128);
+  m1[8 + 5] = _mm256_permute2x128_si256(m2[8 + 4], m2[8 + 6], perm_unpackhi_epi128);
+  m1[8 + 6] = _mm256_permute2x128_si256(m2[8 + 5], m2[8 + 7], perm_unpacklo_epi128);
+  m1[8 + 7] = _mm256_permute2x128_si256(m2[8 + 5], m2[8 + 7], perm_unpackhi_epi128);
+
+  // horizontal
+  m2[0] = _mm256_add_epi32(m1[0], m1[8]);
+  m2[1] = _mm256_add_epi32(m1[1], m1[9]);
+  m2[2] = _mm256_add_epi32(m1[2], m1[10]);
+  m2[3] = _mm256_add_epi32(m1[3], m1[11]);
+  m2[4] = _mm256_add_epi32(m1[4], m1[12]);
+  m2[5] = _mm256_add_epi32(m1[5], m1[13]);
+  m2[6] = _mm256_add_epi32(m1[6], m1[14]);
+  m2[7] = _mm256_add_epi32(m1[7], m1[15]);
+  m2[8] = _mm256_sub_epi32(m1[0], m1[8]);
+  m2[9] = _mm256_sub_epi32(m1[1], m1[9]);
+  m2[10] = _mm256_sub_epi32(m1[2], m1[10]);
+  m2[11] = _mm256_sub_epi32(m1[3], m1[11]);
+  m2[12] = _mm256_sub_epi32(m1[4], m1[12]);
+  m2[13] = _mm256_sub_epi32(m1[5], m1[13]);
+  m2[14] = _mm256_sub_epi32(m1[6], m1[14]);
+  m2[15] = _mm256_sub_epi32(m1[7], m1[15]);
+
+  m1[0] = _mm256_add_epi32(m2[0], m2[4]);
+  m1[1] = _mm256_add_epi32(m2[1], m2[5]);
+  m1[2] = _mm256_add_epi32(m2[2], m2[6]);
+  m1[3] = _mm256_add_epi32(m2[3], m2[7]);
+  m1[4] = _mm256_sub_epi32(m2[0], m2[4]);
+  m1[5] = _mm256_sub_epi32(m2[1], m2[5]);
+  m1[6] = _mm256_sub_epi32(m2[2], m2[6]);
+  m1[7] = _mm256_sub_epi32(m2[3], m2[7]);
+  m1[8] = _mm256_add_epi32(m2[8], m2[12]);
+  m1[9] = _mm256_add_epi32(m2[9], m2[13]);
+  m1[10] = _mm256_add_epi32(m2[10], m2[14]);
+  m1[11] = _mm256_add_epi32(m2[11], m2[15]);
+  m1[12] = _mm256_sub_epi32(m2[8], m2[12]);
+  m1[13] = _mm256_sub_epi32(m2[9], m2[13]);
+  m1[14] = _mm256_sub_epi32(m2[10], m2[14]);
+  m1[15] = _mm256_sub_epi32(m2[11], m2[15]);
+
+  m2[0] = _mm256_add_epi32(m1[0], m1[2]);
+  m2[1] = _mm256_add_epi32(m1[1], m1[3]);
+  m2[2] = _mm256_sub_epi32(m1[0], m1[2]);
+  m2[3] = _mm256_sub_epi32(m1[1], m1[3]);
+  m2[4] = _mm256_add_epi32(m1[4], m1[6]);
+  m2[5] = _mm256_add_epi32(m1[5], m1[7]);
+  m2[6] = _mm256_sub_epi32(m1[4], m1[6]);
+  m2[7] = _mm256_sub_epi32(m1[5], m1[7]);
+  m2[8] = _mm256_add_epi32(m1[8], m1[10]);
+  m2[9] = _mm256_add_epi32(m1[9], m1[11]);
+  m2[10] = _mm256_sub_epi32(m1[8], m1[10]);
+  m2[11] = _mm256_sub_epi32(m1[9], m1[11]);
+  m2[12] = _mm256_add_epi32(m1[12], m1[14]);
+  m2[13] = _mm256_add_epi32(m1[13], m1[15]);
+  m2[14] = _mm256_sub_epi32(m1[12], m1[14]);
+  m2[15] = _mm256_sub_epi32(m1[13], m1[15]);
+
+  m1[0] = _mm256_abs_epi32(_mm256_add_epi32(m2[0], m2[1]));
+  m1[1] = _mm256_abs_epi32(_mm256_sub_epi32(m2[0], m2[1]));
+  m1[2] = _mm256_abs_epi32(_mm256_add_epi32(m2[2], m2[3]));
+  m1[3] = _mm256_abs_epi32(_mm256_sub_epi32(m2[2], m2[3]));
+  m1[4] = _mm256_abs_epi32(_mm256_add_epi32(m2[4], m2[5]));
+  m1[5] = _mm256_abs_epi32(_mm256_sub_epi32(m2[4], m2[5]));
+  m1[6] = _mm256_abs_epi32(_mm256_add_epi32(m2[6], m2[7]));
+  m1[7] = _mm256_abs_epi32(_mm256_sub_epi32(m2[6], m2[7]));
+  m1[8] = _mm256_abs_epi32(_mm256_add_epi32(m2[8], m2[9]));
+  m1[9] = _mm256_abs_epi32(_mm256_sub_epi32(m2[8], m2[9]));
+  m1[10] = _mm256_abs_epi32(_mm256_add_epi32(m2[10], m2[11]));
+  m1[11] = _mm256_abs_epi32(_mm256_sub_epi32(m2[10], m2[11]));
+  m1[12] = _mm256_abs_epi32(_mm256_add_epi32(m2[12], m2[13]));
+  m1[13] = _mm256_abs_epi32(_mm256_sub_epi32(m2[12], m2[13]));
+  m1[14] = _mm256_abs_epi32(_mm256_add_epi32(m2[14], m2[15]));
+  m1[15] = _mm256_abs_epi32(_mm256_sub_epi32(m2[14], m2[15]));
+
+#if JVET_R0164_MEAN_SCALED_SATD
+  Distortion absDc = _mm_cvtsi128_si32(_mm256_castsi256_si128(m1[0]));
+#endif
+
+  // sum up
+  m1[0] = _mm256_add_epi32(m1[0], m1[1]);
+  m1[2] = _mm256_add_epi32(m1[2], m1[3]);
+  m1[4] = _mm256_add_epi32(m1[4], m1[5]);
+  m1[6] = _mm256_add_epi32(m1[6], m1[7]);
+  m1[8] = _mm256_add_epi32(m1[8], m1[9]);
+  m1[10] = _mm256_add_epi32(m1[10], m1[11]);
+  m1[12] = _mm256_add_epi32(m1[12], m1[13]);
+  m1[14] = _mm256_add_epi32(m1[14], m1[15]);
+
+  m1[0] = _mm256_add_epi32(m1[0], m1[2]);
+  m1[4] = _mm256_add_epi32(m1[4], m1[6]);
+  m1[8] = _mm256_add_epi32(m1[8], m1[10]);
+  m1[12] = _mm256_add_epi32(m1[12], m1[14]);
+
+  m1[0] = _mm256_add_epi32(m1[0], m1[4]);
+  m1[8] = _mm256_add_epi32(m1[8], m1[12]);
+
+  __m256i iSum = _mm256_add_epi32(m1[0], m1[8]);
+  iSum = _mm256_hadd_epi32(iSum, iSum);
+  iSum = _mm256_hadd_epi32(iSum, iSum);
+  iSum = _mm256_add_epi32(iSum, _mm256_permute2x128_si256(iSum, iSum, 0x11));
+
+  Distortion sad = _mm_cvtsi128_si32(_mm256_castsi256_si128(iSum));
+#if JVET_R0164_MEAN_SCALED_SATD
+  sad -= absDc;
+  sad += absDc >> 2;
+#endif
+  sad = (uint32_t)(sad / sqrt(16.0 * 8) * 2);
+
+  return (sad);
+}
+
+static Distortion xCalcHAD8x16_HBD_AVX2(const Pel* piOrg, const Pel* piCur, const int iStrideOrg, const int iStrideCur)
+{
+  __m256i m1[16], m2[16];
+
+  for (int k = 0; k < 16; k++)
+  {
+    m1[k] = _mm256_sub_epi32(_mm256_lddqu_si256((__m256i*)piOrg), _mm256_lddqu_si256((__m256i*)piCur));
+    piCur += iStrideCur;
+    piOrg += iStrideOrg;
+  }
+
+  // vertical
+  m2[0] = _mm256_add_epi32(m1[0], m1[8]);
+  m2[1] = _mm256_add_epi32(m1[1], m1[9]);
+  m2[2] = _mm256_add_epi32(m1[2], m1[10]);
+  m2[3] = _mm256_add_epi32(m1[3], m1[11]);
+  m2[4] = _mm256_add_epi32(m1[4], m1[12]);
+  m2[5] = _mm256_add_epi32(m1[5], m1[13]);
+  m2[6] = _mm256_add_epi32(m1[6], m1[14]);
+  m2[7] = _mm256_add_epi32(m1[7], m1[15]);
+  m2[8] = _mm256_sub_epi32(m1[0], m1[8]);
+  m2[9] = _mm256_sub_epi32(m1[1], m1[9]);
+  m2[10] = _mm256_sub_epi32(m1[2], m1[10]);
+  m2[11] = _mm256_sub_epi32(m1[3], m1[11]);
+  m2[12] = _mm256_sub_epi32(m1[4], m1[12]);
+  m2[13] = _mm256_sub_epi32(m1[5], m1[13]);
+  m2[14] = _mm256_sub_epi32(m1[6], m1[14]);
+  m2[15] = _mm256_sub_epi32(m1[7], m1[15]);
+
+  m1[0] = _mm256_add_epi32(m2[0], m2[4]);
+  m1[1] = _mm256_add_epi32(m2[1], m2[5]);
+  m1[2] = _mm256_add_epi32(m2[2], m2[6]);
+  m1[3] = _mm256_add_epi32(m2[3], m2[7]);
+  m1[4] = _mm256_sub_epi32(m2[0], m2[4]);
+  m1[5] = _mm256_sub_epi32(m2[1], m2[5]);
+  m1[6] = _mm256_sub_epi32(m2[2], m2[6]);
+  m1[7] = _mm256_sub_epi32(m2[3], m2[7]);
+  m1[8] = _mm256_add_epi32(m2[8], m2[12]);
+  m1[9] = _mm256_add_epi32(m2[9], m2[13]);
+  m1[10] = _mm256_add_epi32(m2[10], m2[14]);
+  m1[11] = _mm256_add_epi32(m2[11], m2[15]);
+  m1[12] = _mm256_sub_epi32(m2[8], m2[12]);
+  m1[13] = _mm256_sub_epi32(m2[9], m2[13]);
+  m1[14] = _mm256_sub_epi32(m2[10], m2[14]);
+  m1[15] = _mm256_sub_epi32(m2[11], m2[15]);
+
+  m2[0] = _mm256_add_epi32(m1[0], m1[2]);
+  m2[1] = _mm256_add_epi32(m1[1], m1[3]);
+  m2[2] = _mm256_sub_epi32(m1[0], m1[2]);
+  m2[3] = _mm256_sub_epi32(m1[1], m1[3]);
+  m2[4] = _mm256_add_epi32(m1[4], m1[6]);
+  m2[5] = _mm256_add_epi32(m1[5], m1[7]);
+  m2[6] = _mm256_sub_epi32(m1[4], m1[6]);
+  m2[7] = _mm256_sub_epi32(m1[5], m1[7]);
+  m2[8] = _mm256_add_epi32(m1[8], m1[10]);
+  m2[9] = _mm256_add_epi32(m1[9], m1[11]);
+  m2[10] = _mm256_sub_epi32(m1[8], m1[10]);
+  m2[11] = _mm256_sub_epi32(m1[9], m1[11]);
+  m2[12] = _mm256_add_epi32(m1[12], m1[14]);
+  m2[13] = _mm256_add_epi32(m1[13], m1[15]);
+  m2[14] = _mm256_sub_epi32(m1[12], m1[14]);
+  m2[15] = _mm256_sub_epi32(m1[13], m1[15]);
+
+  m1[0] = _mm256_add_epi32(m2[0], m2[1]);
+  m1[1] = _mm256_sub_epi32(m2[0], m2[1]);
+  m1[2] = _mm256_add_epi32(m2[2], m2[3]);
+  m1[3] = _mm256_sub_epi32(m2[2], m2[3]);
+  m1[4] = _mm256_add_epi32(m2[4], m2[5]);
+  m1[5] = _mm256_sub_epi32(m2[4], m2[5]);
+  m1[6] = _mm256_add_epi32(m2[6], m2[7]);
+  m1[7] = _mm256_sub_epi32(m2[6], m2[7]);
+  m1[8] = _mm256_add_epi32(m2[8], m2[9]);
+  m1[9] = _mm256_sub_epi32(m2[8], m2[9]);
+  m1[10] = _mm256_add_epi32(m2[10], m2[11]);
+  m1[11] = _mm256_sub_epi32(m2[10], m2[11]);
+  m1[12] = _mm256_add_epi32(m2[12], m2[13]);
+  m1[13] = _mm256_sub_epi32(m2[12], m2[13]);
+  m1[14] = _mm256_add_epi32(m2[14], m2[15]);
+  m1[15] = _mm256_sub_epi32(m2[14], m2[15]);
+
+  // transpose
+  constexpr int perm_unpacklo_epi128 = (0 << 0) + (2 << 4);
+  constexpr int perm_unpackhi_epi128 = (1 << 0) + (3 << 4);
+
+  // 1. 8x8
+  m2[0] = _mm256_unpacklo_epi32(m1[0], m1[1]);
+  m2[1] = _mm256_unpacklo_epi32(m1[2], m1[3]);
+  m2[2] = _mm256_unpacklo_epi32(m1[4], m1[5]);
+  m2[3] = _mm256_unpacklo_epi32(m1[6], m1[7]);
+  m2[4] = _mm256_unpackhi_epi32(m1[0], m1[1]);
+  m2[5] = _mm256_unpackhi_epi32(m1[2], m1[3]);
+  m2[6] = _mm256_unpackhi_epi32(m1[4], m1[5]);
+  m2[7] = _mm256_unpackhi_epi32(m1[6], m1[7]);
+
+  m1[0] = _mm256_unpacklo_epi64(m2[0], m2[1]);
+  m1[1] = _mm256_unpackhi_epi64(m2[0], m2[1]);
+  m1[2] = _mm256_unpacklo_epi64(m2[2], m2[3]);
+  m1[3] = _mm256_unpackhi_epi64(m2[2], m2[3]);
+  m1[4] = _mm256_unpacklo_epi64(m2[4], m2[5]);
+  m1[5] = _mm256_unpackhi_epi64(m2[4], m2[5]);
+  m1[6] = _mm256_unpacklo_epi64(m2[6], m2[7]);
+  m1[7] = _mm256_unpackhi_epi64(m2[6], m2[7]);
+
+  m2[0] = _mm256_permute2x128_si256(m1[0], m1[2], perm_unpacklo_epi128);
+  m2[1] = _mm256_permute2x128_si256(m1[0], m1[2], perm_unpackhi_epi128);
+  m2[2] = _mm256_permute2x128_si256(m1[1], m1[3], perm_unpacklo_epi128);
+  m2[3] = _mm256_permute2x128_si256(m1[1], m1[3], perm_unpackhi_epi128);
+  m2[4] = _mm256_permute2x128_si256(m1[4], m1[6], perm_unpacklo_epi128);
+  m2[5] = _mm256_permute2x128_si256(m1[4], m1[6], perm_unpackhi_epi128);
+  m2[6] = _mm256_permute2x128_si256(m1[5], m1[7], perm_unpacklo_epi128);
+  m2[7] = _mm256_permute2x128_si256(m1[5], m1[7], perm_unpackhi_epi128);
+
+  // 2. 8x8
+  m2[0 + 8] = _mm256_unpacklo_epi32(m1[0 + 8], m1[1 + 8]);
+  m2[1 + 8] = _mm256_unpacklo_epi32(m1[2 + 8], m1[3 + 8]);
+  m2[2 + 8] = _mm256_unpacklo_epi32(m1[4 + 8], m1[5 + 8]);
+  m2[3 + 8] = _mm256_unpacklo_epi32(m1[6 + 8], m1[7 + 8]);
+  m2[4 + 8] = _mm256_unpackhi_epi32(m1[0 + 8], m1[1 + 8]);
+  m2[5 + 8] = _mm256_unpackhi_epi32(m1[2 + 8], m1[3 + 8]);
+  m2[6 + 8] = _mm256_unpackhi_epi32(m1[4 + 8], m1[5 + 8]);
+  m2[7 + 8] = _mm256_unpackhi_epi32(m1[6 + 8], m1[7 + 8]);
+
+  m1[0 + 8] = _mm256_unpacklo_epi64(m2[0 + 8], m2[1 + 8]);
+  m1[1 + 8] = _mm256_unpackhi_epi64(m2[0 + 8], m2[1 + 8]);
+  m1[2 + 8] = _mm256_unpacklo_epi64(m2[2 + 8], m2[3 + 8]);
+  m1[3 + 8] = _mm256_unpackhi_epi64(m2[2 + 8], m2[3 + 8]);
+  m1[4 + 8] = _mm256_unpacklo_epi64(m2[4 + 8], m2[5 + 8]);
+  m1[5 + 8] = _mm256_unpackhi_epi64(m2[4 + 8], m2[5 + 8]);
+  m1[6 + 8] = _mm256_unpacklo_epi64(m2[6 + 8], m2[7 + 8]);
+  m1[7 + 8] = _mm256_unpackhi_epi64(m2[6 + 8], m2[7 + 8]);
+
+  m2[0 + 8] = _mm256_permute2x128_si256(m1[0 + 8], m1[2 + 8], perm_unpacklo_epi128);
+  m2[1 + 8] = _mm256_permute2x128_si256(m1[0 + 8], m1[2 + 8], perm_unpackhi_epi128);
+  m2[2 + 8] = _mm256_permute2x128_si256(m1[1 + 8], m1[3 + 8], perm_unpacklo_epi128);
+  m2[3 + 8] = _mm256_permute2x128_si256(m1[1 + 8], m1[3 + 8], perm_unpackhi_epi128);
+  m2[4 + 8] = _mm256_permute2x128_si256(m1[4 + 8], m1[6 + 8], perm_unpacklo_epi128);
+  m2[5 + 8] = _mm256_permute2x128_si256(m1[4 + 8], m1[6 + 8], perm_unpackhi_epi128);
+  m2[6 + 8] = _mm256_permute2x128_si256(m1[5 + 8], m1[7 + 8], perm_unpacklo_epi128);
+  m2[7 + 8] = _mm256_permute2x128_si256(m1[5 + 8], m1[7 + 8], perm_unpackhi_epi128);
+
+  // horizontal
+  m1[0] = _mm256_add_epi32(m2[0], m2[4]);
+  m1[1] = _mm256_add_epi32(m2[1], m2[5]);
+  m1[2] = _mm256_add_epi32(m2[2], m2[6]);
+  m1[3] = _mm256_add_epi32(m2[3], m2[7]);
+  m1[4] = _mm256_sub_epi32(m2[0], m2[4]);
+  m1[5] = _mm256_sub_epi32(m2[1], m2[5]);
+  m1[6] = _mm256_sub_epi32(m2[2], m2[6]);
+  m1[7] = _mm256_sub_epi32(m2[3], m2[7]);
+
+  m2[0] = _mm256_add_epi32(m1[0], m1[2]);
+  m2[1] = _mm256_add_epi32(m1[1], m1[3]);
+  m2[2] = _mm256_sub_epi32(m1[0], m1[2]);
+  m2[3] = _mm256_sub_epi32(m1[1], m1[3]);
+  m2[4] = _mm256_add_epi32(m1[4], m1[6]);
+  m2[5] = _mm256_add_epi32(m1[5], m1[7]);
+  m2[6] = _mm256_sub_epi32(m1[4], m1[6]);
+  m2[7] = _mm256_sub_epi32(m1[5], m1[7]);
+
+  m1[0] = _mm256_abs_epi32(_mm256_add_epi32(m2[0], m2[1]));
+  m1[1] = _mm256_abs_epi32(_mm256_sub_epi32(m2[0], m2[1]));
+  m1[2] = _mm256_abs_epi32(_mm256_add_epi32(m2[2], m2[3]));
+  m1[3] = _mm256_abs_epi32(_mm256_sub_epi32(m2[2], m2[3]));
+  m1[4] = _mm256_abs_epi32(_mm256_add_epi32(m2[4], m2[5]));
+  m1[5] = _mm256_abs_epi32(_mm256_sub_epi32(m2[4], m2[5]));
+  m1[6] = _mm256_abs_epi32(_mm256_add_epi32(m2[6], m2[7]));
+  m1[7] = _mm256_abs_epi32(_mm256_sub_epi32(m2[6], m2[7]));
+
+#if JVET_R0164_MEAN_SCALED_SATD
+  int absDc = _mm_cvtsi128_si32(_mm256_castsi256_si128(m1[0]));
+#endif
+
+  m1[0 + 8] = _mm256_add_epi32(m2[0 + 8], m2[4 + 8]);
+  m1[1 + 8] = _mm256_add_epi32(m2[1 + 8], m2[5 + 8]);
+  m1[2 + 8] = _mm256_add_epi32(m2[2 + 8], m2[6 + 8]);
+  m1[3 + 8] = _mm256_add_epi32(m2[3 + 8], m2[7 + 8]);
+  m1[4 + 8] = _mm256_sub_epi32(m2[0 + 8], m2[4 + 8]);
+  m1[5 + 8] = _mm256_sub_epi32(m2[1 + 8], m2[5 + 8]);
+  m1[6 + 8] = _mm256_sub_epi32(m2[2 + 8], m2[6 + 8]);
+  m1[7 + 8] = _mm256_sub_epi32(m2[3 + 8], m2[7 + 8]);
+
+  m2[0 + 8] = _mm256_add_epi32(m1[0 + 8], m1[2 + 8]);
+  m2[1 + 8] = _mm256_add_epi32(m1[1 + 8], m1[3 + 8]);
+  m2[2 + 8] = _mm256_sub_epi32(m1[0 + 8], m1[2 + 8]);
+  m2[3 + 8] = _mm256_sub_epi32(m1[1 + 8], m1[3 + 8]);
+  m2[4 + 8] = _mm256_add_epi32(m1[4 + 8], m1[6 + 8]);
+  m2[5 + 8] = _mm256_add_epi32(m1[5 + 8], m1[7 + 8]);
+  m2[6 + 8] = _mm256_sub_epi32(m1[4 + 8], m1[6 + 8]);
+  m2[7 + 8] = _mm256_sub_epi32(m1[5 + 8], m1[7 + 8]);
+
+  m1[0 + 8] = _mm256_abs_epi32(_mm256_add_epi32(m2[0 + 8], m2[1 + 8]));
+  m1[1 + 8] = _mm256_abs_epi32(_mm256_sub_epi32(m2[0 + 8], m2[1 + 8]));
+  m1[2 + 8] = _mm256_abs_epi32(_mm256_add_epi32(m2[2 + 8], m2[3 + 8]));
+  m1[3 + 8] = _mm256_abs_epi32(_mm256_sub_epi32(m2[2 + 8], m2[3 + 8]));
+  m1[4 + 8] = _mm256_abs_epi32(_mm256_add_epi32(m2[4 + 8], m2[5 + 8]));
+  m1[5 + 8] = _mm256_abs_epi32(_mm256_sub_epi32(m2[4 + 8], m2[5 + 8]));
+  m1[6 + 8] = _mm256_abs_epi32(_mm256_add_epi32(m2[6 + 8], m2[7 + 8]));
+  m1[7 + 8] = _mm256_abs_epi32(_mm256_sub_epi32(m2[6 + 8], m2[7 + 8]));
+
+  // sum up
+  m1[0] = _mm256_add_epi32(m1[0], m1[1]);
+  m1[1] = _mm256_add_epi32(m1[2], m1[3]);
+  m1[2] = _mm256_add_epi32(m1[4], m1[5]);
+  m1[3] = _mm256_add_epi32(m1[6], m1[7]);
+  m1[4] = _mm256_add_epi32(m1[8], m1[9]);
+  m1[5] = _mm256_add_epi32(m1[10], m1[11]);
+  m1[6] = _mm256_add_epi32(m1[12], m1[13]);
+  m1[7] = _mm256_add_epi32(m1[14], m1[15]);
+
+  // sum up
+  m1[0] = _mm256_add_epi32(m1[0], m1[1]);
+  m1[1] = _mm256_add_epi32(m1[2], m1[3]);
+  m1[2] = _mm256_add_epi32(m1[4], m1[5]);
+  m1[3] = _mm256_add_epi32(m1[6], m1[7]);
+
+  m1[0] = _mm256_add_epi32(m1[0], m1[1]);
+  m1[1] = _mm256_add_epi32(m1[2], m1[3]);
+
+  __m256i iSum = _mm256_add_epi32(m1[0], m1[1]);
+  iSum = _mm256_hadd_epi32(iSum, iSum);
+  iSum = _mm256_hadd_epi32(iSum, iSum);
+  iSum = _mm256_add_epi32(iSum, _mm256_permute2x128_si256(iSum, iSum, 0x11));
+
+  Distortion sad2 = _mm_cvtsi128_si32(_mm256_castsi256_si128(iSum));
+#if JVET_R0164_MEAN_SCALED_SATD
+  sad2 -= absDc;
+  sad2 += absDc >> 2;
+#endif
+  Distortion sad = (uint32_t)(sad2 / sqrt(16.0 * 8) * 2);
 
+  return (sad);
+}
+#endif
+#else
 static uint32_t xCalcHAD4x4_SSE( const Torg *piOrg, const Tcur *piCur, const int iStrideOrg, const int iStrideCur )
 {
   __m128i r0 = ( sizeof( Torg ) > 1 ) ? ( _mm_loadl_epi64( ( const __m128i* )&piOrg[0] ) ) : ( _mm_unpacklo_epi8( _mm_cvtsi32_si128( *(const int*)&piOrg[0] ), _mm_setzero_si128() ) );
@@ -1995,162 +3702,628 @@ static uint32_t xCalcHAD8x16_AVX2( const Pel* piOrg, const Pel* piCur, const int
     int absDc = _mm_cvtsi128_si32( _mm256_castsi256_si128( m1[0] ) );
 #endif
 
-    m1[0 + 8] = _mm256_add_epi32( m2[0 + 8], m2[4 + 8] );
-    m1[1 + 8] = _mm256_add_epi32( m2[1 + 8], m2[5 + 8] );
-    m1[2 + 8] = _mm256_add_epi32( m2[2 + 8], m2[6 + 8] );
-    m1[3 + 8] = _mm256_add_epi32( m2[3 + 8], m2[7 + 8] );
-    m1[4 + 8] = _mm256_sub_epi32( m2[0 + 8], m2[4 + 8] );
-    m1[5 + 8] = _mm256_sub_epi32( m2[1 + 8], m2[5 + 8] );
-    m1[6 + 8] = _mm256_sub_epi32( m2[2 + 8], m2[6 + 8] );
-    m1[7 + 8] = _mm256_sub_epi32( m2[3 + 8], m2[7 + 8] );
-
-    m2[0 + 8] = _mm256_add_epi32( m1[0 + 8], m1[2 + 8] );
-    m2[1 + 8] = _mm256_add_epi32( m1[1 + 8], m1[3 + 8] );
-    m2[2 + 8] = _mm256_sub_epi32( m1[0 + 8], m1[2 + 8] );
-    m2[3 + 8] = _mm256_sub_epi32( m1[1 + 8], m1[3 + 8] );
-    m2[4 + 8] = _mm256_add_epi32( m1[4 + 8], m1[6 + 8] );
-    m2[5 + 8] = _mm256_add_epi32( m1[5 + 8], m1[7 + 8] );
-    m2[6 + 8] = _mm256_sub_epi32( m1[4 + 8], m1[6 + 8] );
-    m2[7 + 8] = _mm256_sub_epi32( m1[5 + 8], m1[7 + 8] );
+    m1[0 + 8] = _mm256_add_epi32( m2[0 + 8], m2[4 + 8] );
+    m1[1 + 8] = _mm256_add_epi32( m2[1 + 8], m2[5 + 8] );
+    m1[2 + 8] = _mm256_add_epi32( m2[2 + 8], m2[6 + 8] );
+    m1[3 + 8] = _mm256_add_epi32( m2[3 + 8], m2[7 + 8] );
+    m1[4 + 8] = _mm256_sub_epi32( m2[0 + 8], m2[4 + 8] );
+    m1[5 + 8] = _mm256_sub_epi32( m2[1 + 8], m2[5 + 8] );
+    m1[6 + 8] = _mm256_sub_epi32( m2[2 + 8], m2[6 + 8] );
+    m1[7 + 8] = _mm256_sub_epi32( m2[3 + 8], m2[7 + 8] );
+
+    m2[0 + 8] = _mm256_add_epi32( m1[0 + 8], m1[2 + 8] );
+    m2[1 + 8] = _mm256_add_epi32( m1[1 + 8], m1[3 + 8] );
+    m2[2 + 8] = _mm256_sub_epi32( m1[0 + 8], m1[2 + 8] );
+    m2[3 + 8] = _mm256_sub_epi32( m1[1 + 8], m1[3 + 8] );
+    m2[4 + 8] = _mm256_add_epi32( m1[4 + 8], m1[6 + 8] );
+    m2[5 + 8] = _mm256_add_epi32( m1[5 + 8], m1[7 + 8] );
+    m2[6 + 8] = _mm256_sub_epi32( m1[4 + 8], m1[6 + 8] );
+    m2[7 + 8] = _mm256_sub_epi32( m1[5 + 8], m1[7 + 8] );
+
+    m1[0 + 8] = _mm256_abs_epi32( _mm256_add_epi32( m2[0 + 8], m2[1 + 8] ) );
+    m1[1 + 8] = _mm256_abs_epi32( _mm256_sub_epi32( m2[0 + 8], m2[1 + 8] ) );
+    m1[2 + 8] = _mm256_abs_epi32( _mm256_add_epi32( m2[2 + 8], m2[3 + 8] ) );
+    m1[3 + 8] = _mm256_abs_epi32( _mm256_sub_epi32( m2[2 + 8], m2[3 + 8] ) );
+    m1[4 + 8] = _mm256_abs_epi32( _mm256_add_epi32( m2[4 + 8], m2[5 + 8] ) );
+    m1[5 + 8] = _mm256_abs_epi32( _mm256_sub_epi32( m2[4 + 8], m2[5 + 8] ) );
+    m1[6 + 8] = _mm256_abs_epi32( _mm256_add_epi32( m2[6 + 8], m2[7 + 8] ) );
+    m1[7 + 8] = _mm256_abs_epi32( _mm256_sub_epi32( m2[6 + 8], m2[7 + 8] ) );
+
+    // sum up
+    m1[0] = _mm256_add_epi32( m1[0], m1[1] );
+    m1[1] = _mm256_add_epi32( m1[2], m1[3] );
+    m1[2] = _mm256_add_epi32( m1[4], m1[5] );
+    m1[3] = _mm256_add_epi32( m1[6], m1[7] );
+    m1[4] = _mm256_add_epi32( m1[8], m1[9] );
+    m1[5] = _mm256_add_epi32( m1[10], m1[11] );
+    m1[6] = _mm256_add_epi32( m1[12], m1[13] );
+    m1[7] = _mm256_add_epi32( m1[14], m1[15] );
+
+    // sum up
+    m1[ 0] = _mm256_add_epi32( m1[ 0], m1[ 1] );
+    m1[ 1] = _mm256_add_epi32( m1[ 2], m1[ 3] );
+    m1[ 2] = _mm256_add_epi32( m1[ 4], m1[ 5] );
+    m1[ 3] = _mm256_add_epi32( m1[ 6], m1[ 7] );
+
+    m1[ 0] = _mm256_add_epi32( m1[ 0], m1[ 1] );
+    m1[ 1] = _mm256_add_epi32( m1[ 2], m1[ 3] );
+
+    __m256i iSum = _mm256_add_epi32( m1[0], m1[1] );
+
+    iSum = _mm256_hadd_epi32( iSum, iSum );
+    iSum = _mm256_hadd_epi32( iSum, iSum );
+    iSum = _mm256_add_epi32( iSum, _mm256_permute2x128_si256( iSum, iSum, 0x11 ) );
+
+    int sad2 = _mm_cvtsi128_si32( _mm256_castsi256_si128( iSum ) );
+
+#if JVET_R0164_MEAN_SCALED_SATD
+    sad2 -= absDc;
+    sad2 += absDc >> 2;
+#endif
+    sad   = (uint32_t)(sad2 / sqrt(16.0 * 8) * 2);
+  }
+
+#endif //USE_AVX2
+
+  return (sad);
+}
+#endif
+template< X86_VEXT vext >
+Distortion RdCost::xGetSADwMask_SIMD( const DistParam &rcDtParam )
+{
+  if (rcDtParam.org.width < 4  || rcDtParam.bitDepth > 10 || rcDtParam.applyWeight)
+    return RdCost::xGetSADwMask( rcDtParam );
+
+  const short* src1   = (const short*)rcDtParam.org.buf;
+  const short* src2   = (const short*)rcDtParam.cur.buf;
+  const short* weightMask   = (const short*)rcDtParam.mask;
+  int  rows           = rcDtParam.org.height;
+  int  cols           = rcDtParam.org.width;
+  int  subShift       = rcDtParam.subShift;
+  int  subStep        = ( 1 << subShift);
+  const int strideSrc1 = rcDtParam.org.stride * subStep;
+  const int strideSrc2 = rcDtParam.cur.stride * subStep;
+  const int strideMask = rcDtParam.maskStride * subStep;
+
+  Distortion sum = 0;
+  if( vext >= AVX2 && (cols & 15 ) == 0 )
+  {
+#ifdef USE_AVX2
+    // Do for width that multiple of 16
+    __m256i vzero = _mm256_setzero_si256();
+    __m256i vsum32 = vzero;
+    for( int y = 0; y < rows; y+= subStep)
+    {
+      for( int x = 0; x < cols; x+=16 )
+      {
+        __m256i vsrc1 = _mm256_lddqu_si256( ( __m256i* )( &src1[x] ) );
+        __m256i vsrc2 = _mm256_lddqu_si256( ( __m256i* )( &src2[x] ) );
+        __m256i vmask;
+        if (rcDtParam.stepX == -1)
+        {
+          vmask = _mm256_lddqu_si256((__m256i*)((&weightMask[x]) - (x << 1) - (16 - 1)));
+          const __m256i shuffle_mask = _mm256_set_epi8(1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14, 1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14);
+          vmask = _mm256_shuffle_epi8(vmask, shuffle_mask);
+          vmask = _mm256_permute4x64_epi64(vmask, _MM_SHUFFLE(1, 0, 3, 2));
+        }
+        else
+        {
+          vmask = _mm256_lddqu_si256((__m256i*)(&weightMask[x]));
+        }
+        vsum32 = _mm256_add_epi32( vsum32, _mm256_madd_epi16( vmask, _mm256_abs_epi16( _mm256_sub_epi16( vsrc1, vsrc2 ) ) ) );
+      }
+      src1 += strideSrc1;
+      src2 += strideSrc2;
+      weightMask += strideMask;
+    }
+    vsum32 = _mm256_hadd_epi32( vsum32, vzero );
+    vsum32 = _mm256_hadd_epi32( vsum32, vzero );
+    sum =  _mm_cvtsi128_si32( _mm256_castsi256_si128( vsum32 ) ) + _mm_cvtsi128_si32( _mm256_castsi256_si128( _mm256_permute2x128_si256( vsum32, vsum32, 0x11 ) ) );
+#endif
+  }
+  else
+  {
+    // Do with step of 8
+    __m128i vzero = _mm_setzero_si128();
+    __m128i vsum32 = vzero;
+    for( int y = 0; y < rows; y+= subStep)
+    {
+      for( int x = 0; x < cols; x+=8 )
+      {
+        __m128i vsrc1 = _mm_loadu_si128( ( const __m128i* )( &src1[x] ) );
+        __m128i vsrc2 = _mm_lddqu_si128( ( const __m128i* )( &src2[x] ) );
+        __m128i vmask;
+        if (rcDtParam.stepX == -1)
+        {
+          vmask = _mm_lddqu_si128((__m128i*)((&weightMask[x]) - (x << 1) - (8 - 1)));
+          const __m128i shuffle_mask = _mm_set_epi8(1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14);
+          vmask = _mm_shuffle_epi8(vmask, shuffle_mask);
+        }
+        else
+        {
+          vmask = _mm_lddqu_si128((const __m128i*)(&weightMask[x]));
+        }
+        vsum32 = _mm_add_epi32( vsum32, _mm_madd_epi16( vmask, _mm_abs_epi16( _mm_sub_epi16( vsrc1, vsrc2 ) ) ) );
+      }
+      src1 += strideSrc1;
+      src2 += strideSrc2;
+      weightMask += strideMask;
+    }
+    vsum32 = _mm_hadd_epi32( vsum32, vzero );
+    vsum32 = _mm_hadd_epi32( vsum32, vzero );
+    sum =  _mm_cvtsi128_si32( vsum32 );
+  }
+  sum <<= subShift;
+
+  return sum >> DISTORTION_PRECISION_ADJUSTMENT(rcDtParam.bitDepth);
+}
+#if RExt__HIGH_BIT_DEPTH_SUPPORT
+template<X86_VEXT vext>
+Distortion RdCost::xGetHADs_HBD_SIMD(const DistParam &rcDtParam)
+{
+  if (rcDtParam.applyWeight)
+  {
+    return RdCostWeightPrediction::xGetHADsw(rcDtParam);
+  }
+
+  const Pel* piOrg = rcDtParam.org.buf;
+  const Pel* piCur = rcDtParam.cur.buf;
+  const int  iRows = rcDtParam.org.height;
+  const int  iCols = rcDtParam.org.width;
+  const int  iStrideCur = rcDtParam.cur.stride;
+  const int  iStrideOrg = rcDtParam.org.stride;
+  const int  iStep = rcDtParam.step;
+
+  CHECK(iStep != 1, "the function only supports of iStep equal to 1");
+
+  int  x = 0, y = 0;
+  Distortion uiSum = 0;
+
+  if (iCols > iRows && (iRows & 7) == 0 && (iCols & 15) == 0)
+  {
+    for (y = 0; y < iRows; y += 8)
+    {
+      for (x = 0; x < iCols; x += 16)
+      {
+#ifdef USE_AVX2
+        if (vext >= AVX2)
+        {
+          uiSum += xCalcHAD16x8_HBD_AVX2(&piOrg[x], &piCur[x], iStrideOrg, iStrideCur);
+        }
+        else
+#endif
+          uiSum += xCalcHAD16x8_HBD_SSE(&piOrg[x], &piCur[x], iStrideOrg, iStrideCur);
+      }
+      piOrg += iStrideOrg * 8;
+      piCur += iStrideCur * 8;
+    }
+  }
+  else if (iCols < iRows && (iCols & 7) == 0 && (iRows & 15) == 0)
+  {
+    for (y = 0; y < iRows; y += 16)
+    {
+      for (x = 0; x < iCols; x += 8)
+      {
+#ifdef USE_AVX2
+        if (vext >= AVX2)
+        {
+          uiSum += xCalcHAD8x16_HBD_AVX2(&piOrg[x], &piCur[x], iStrideOrg, iStrideCur);
+        }
+        else
+#endif
+          uiSum += xCalcHAD8x16_HBD_SSE(&piOrg[x], &piCur[x], iStrideOrg, iStrideCur);
+      }
+      piOrg += iStrideOrg * 16;
+      piCur += iStrideCur * 16;
+    }
+  }
+  else if (iCols > iRows && (iRows & 3) == 0 && (iCols & 7) == 0)
+  {
+    for (y = 0; y < iRows; y += 4)
+    {
+      for (x = 0; x < iCols; x += 8)
+      {
+#ifdef USE_AVX2
+        if (vext >= AVX2)
+        {
+          uiSum += xCalcHAD8x4_HBD_AVX2(&piOrg[x], &piCur[x], iStrideOrg, iStrideCur);
+        }
+        else
+#endif
+          uiSum += xCalcHAD8x4_HBD_SSE(&piOrg[x], &piCur[x], iStrideOrg, iStrideCur);
+      }
+      piOrg += iStrideOrg * 4;
+      piCur += iStrideCur * 4;
+    }
+  }
+  else if (iCols < iRows && (iCols & 3) == 0 && (iRows & 7) == 0)
+  {
+    for (y = 0; y < iRows; y += 8)
+    {
+      for (x = 0; x < iCols; x += 4)
+      {
+#ifdef USE_AVX2
+        if (vext >= AVX2)
+        {
+          uiSum += xCalcHAD4x8_HBD_AVX2(&piOrg[x], &piCur[x], iStrideOrg, iStrideCur);
+        }
+        else
+#endif
+          uiSum += xCalcHAD4x8_HBD_SSE(&piOrg[x], &piCur[x], iStrideOrg, iStrideCur);
+      }
+      piOrg += iStrideOrg * 8;
+      piCur += iStrideCur * 8;
+    }
+  }
+  else if ((iRows % 8 == 0) && (iCols % 8 == 0))
+  {
+    int  iOffsetOrg = iStrideOrg << 3;
+    int  iOffsetCur = iStrideCur << 3;
+    for (y = 0; y < iRows; y += 8)
+    {
+      for (x = 0; x < iCols; x += 8)
+      {
+#ifdef USE_AVX2
+        if (vext >= AVX2)
+        {
+          uiSum += xCalcHAD8x8_HBD_AVX2(&piOrg[x], &piCur[x], iStrideOrg, iStrideCur);
+        }
+        else
+#endif
+          uiSum += xCalcHAD8x8_HBD_SSE(&piOrg[x], &piCur[x], iStrideOrg, iStrideCur);
+      }
+      piOrg += iOffsetOrg;
+      piCur += iOffsetCur;
+    }
+  }
+  else if ((iRows % 4 == 0) && (iCols % 4 == 0))
+  {
+    int  iOffsetOrg = iStrideOrg << 2;
+    int  iOffsetCur = iStrideCur << 2;
+
+    for (y = 0; y < iRows; y += 4)
+    {
+      for (x = 0; x < iCols; x += 4)
+      {
+#ifdef USE_AVX2
+        if (vext >= AVX2)
+        {
+          uiSum += xCalcHAD4x4_HBD_AVX2(&piOrg[x], &piCur[x], iStrideOrg, iStrideCur);
+        }
+        else
+#endif
+          uiSum += xCalcHAD4x4_HBD_SSE(&piOrg[x], &piCur[x], iStrideOrg, iStrideCur);
+      }
+      piOrg += iOffsetOrg;
+      piCur += iOffsetCur;
+    }
+  }
+  else if ((iRows % 2 == 0) && (iCols % 2 == 0))
+  {
+    int  iOffsetOrg = iStrideOrg << 1;
+    int  iOffsetCur = iStrideCur << 1;
+    for (y = 0; y < iRows; y += 2)
+    {
+      for (x = 0; x < iCols; x += 2)
+      {
+        uiSum += xCalcHAD2x2_HBD_SSE(&piOrg[x], &piCur[x], iStrideOrg, iStrideCur);
+      }
+      piOrg += iOffsetOrg;
+      piCur += iOffsetCur;
+    }
+  }
+  else
+  {
+    THROW("Invalid size");
+  }
 
-    m1[0 + 8] = _mm256_abs_epi32( _mm256_add_epi32( m2[0 + 8], m2[1 + 8] ) );
-    m1[1 + 8] = _mm256_abs_epi32( _mm256_sub_epi32( m2[0 + 8], m2[1 + 8] ) );
-    m1[2 + 8] = _mm256_abs_epi32( _mm256_add_epi32( m2[2 + 8], m2[3 + 8] ) );
-    m1[3 + 8] = _mm256_abs_epi32( _mm256_sub_epi32( m2[2 + 8], m2[3 + 8] ) );
-    m1[4 + 8] = _mm256_abs_epi32( _mm256_add_epi32( m2[4 + 8], m2[5 + 8] ) );
-    m1[5 + 8] = _mm256_abs_epi32( _mm256_sub_epi32( m2[4 + 8], m2[5 + 8] ) );
-    m1[6 + 8] = _mm256_abs_epi32( _mm256_add_epi32( m2[6 + 8], m2[7 + 8] ) );
-    m1[7 + 8] = _mm256_abs_epi32( _mm256_sub_epi32( m2[6 + 8], m2[7 + 8] ) );
+  return (uiSum >> DISTORTION_PRECISION_ADJUSTMENT(rcDtParam.bitDepth));
+}
 
-    // sum up
-    m1[0] = _mm256_add_epi32( m1[0], m1[1] );
-    m1[1] = _mm256_add_epi32( m1[2], m1[3] );
-    m1[2] = _mm256_add_epi32( m1[4], m1[5] );
-    m1[3] = _mm256_add_epi32( m1[6], m1[7] );
-    m1[4] = _mm256_add_epi32( m1[8], m1[9] );
-    m1[5] = _mm256_add_epi32( m1[10], m1[11] );
-    m1[6] = _mm256_add_epi32( m1[12], m1[13] );
-    m1[7] = _mm256_add_epi32( m1[14], m1[15] );
+template< X86_VEXT vext >
+Distortion RdCost::xGetSAD_HBD_SIMD(const DistParam &rcDtParam)
+{
+  if (rcDtParam.applyWeight)
+  {
+    return RdCost::xGetSAD(rcDtParam);
+  }
 
-    // sum up
-    m1[ 0] = _mm256_add_epi32( m1[ 0], m1[ 1] );
-    m1[ 1] = _mm256_add_epi32( m1[ 2], m1[ 3] );
-    m1[ 2] = _mm256_add_epi32( m1[ 4], m1[ 5] );
-    m1[ 3] = _mm256_add_epi32( m1[ 6], m1[ 7] );
+  const Pel* pSrc1 = (const Pel*)rcDtParam.org.buf;
+  const Pel* pSrc2 = (const Pel*)rcDtParam.cur.buf;
+  int  iRows = rcDtParam.org.height;
+  int  iCols = rcDtParam.org.width;
+  int  iSubShift = rcDtParam.subShift;
+  int  iSubStep = (1 << iSubShift);
+  const int iStrideSrc1 = rcDtParam.org.stride * iSubStep;
+  const int iStrideSrc2 = rcDtParam.cur.stride * iSubStep;
 
-    m1[ 0] = _mm256_add_epi32( m1[ 0], m1[ 1] );
-    m1[ 1] = _mm256_add_epi32( m1[ 2], m1[ 3] );
+  if ((iCols < 4) && (iRows < (iSubStep << 1)))
+  {
+    return RdCost::xGetSAD(rcDtParam);
+  }
 
-    __m256i iSum = _mm256_add_epi32( m1[0], m1[1] );
+  uint32_t uiSum = 0;
+#ifdef USE_AVX2
+  if ((vext >= AVX2) && ((iCols & 7) == 0))
+  {
+    __m256i vzero = _mm256_setzero_si256();
+    __m256i vsum32 = vzero;
+    __m256i vsrc1, vsrc2, vsum;
+    for (int iY = 0; iY < iRows; iY += iSubStep)
+    {
+      for (int iX = 0; iX < iCols; iX += 8)
+      {
+        vsrc1 = _mm256_lddqu_si256((__m256i*)(&pSrc1[iX]));
+        vsrc2 = _mm256_lddqu_si256((__m256i*)(&pSrc2[iX]));
+        vsum = _mm256_abs_epi32(_mm256_sub_epi32(vsrc1, vsrc2));
+        vsum32 = _mm256_add_epi32(vsum32, vsum);
+      }
+      pSrc1 += iStrideSrc1;
+      pSrc2 += iStrideSrc2;
+    }
+    vsum32 = _mm256_hadd_epi32(vsum32, vzero);
+    vsum32 = _mm256_hadd_epi32(vsum32, vzero);
+    uiSum = _mm_cvtsi128_si32(_mm256_castsi256_si128(vsum32)) + _mm_cvtsi128_si32(_mm256_castsi256_si128(_mm256_permute2x128_si256(vsum32, vsum32, 0x11)));
+  }
+  else
+#endif
+    if ((iCols & 3) == 0)
+    {
+      __m128i vzero = _mm_setzero_si128();
+      __m128i vsum32 = vzero;
+      __m128i vsrc1, vsrc2, vsum;
+      for (int iY = 0; iY < iRows; iY += iSubStep)
+      {
+        for (int iX = 0; iX < iCols; iX += 4)
+        {
+          vsrc1 = _mm_lddqu_si128((const __m128i*)(&pSrc1[iX]));
+          vsrc2 = _mm_lddqu_si128((const __m128i*)(&pSrc2[iX]));
+          vsum = _mm_abs_epi32(_mm_sub_epi32(vsrc1, vsrc2));
+          vsum32 = _mm_add_epi32(vsum32, vsum);
+        }
+        pSrc1 += iStrideSrc1;
+        pSrc2 += iStrideSrc2;
+      }
+      vsum32 = _mm_hadd_epi32(vsum32, vzero);
+      vsum32 = _mm_hadd_epi32(vsum32, vzero);
+      uiSum = _mm_cvtsi128_si32(vsum32);
+    }
+    else
+    {
+      __m128i vzero = _mm_setzero_si128();
+      __m128i vsum32 = vzero;
+      __m128i vsrc10, vsrc20, vsrc11, vsrc21, vsum0, vsum1, vsum;
 
-    iSum = _mm256_hadd_epi32( iSum, iSum );
-    iSum = _mm256_hadd_epi32( iSum, iSum );
-    iSum = _mm256_add_epi32( iSum, _mm256_permute2x128_si256( iSum, iSum, 0x11 ) );
+      int i2StrideSrc1 = (iStrideSrc1 << 1);
+      int i2StrideSrc2 = (iStrideSrc2 << 1);
 
-    int sad2 = _mm_cvtsi128_si32( _mm256_castsi256_si128( iSum ) );
+      for (int iY = 0; iY < iRows; iY += (iSubStep << 1))
+      {
+        for (int iX = 0; iX < iCols; iX += 2)
+        {
+          vsrc10 = _mm_loadl_epi64((const __m128i*)(&pSrc1[iX]));
+          vsrc20 = _mm_loadl_epi64((const __m128i*)(&pSrc2[iX]));
+          vsum0 = _mm_abs_epi32(_mm_sub_epi32(vsrc10, vsrc20));
 
-#if JVET_R0164_MEAN_SCALED_SATD
-    sad2 -= absDc;
-    sad2 += absDc >> 2;
-#endif
-    sad   = (uint32_t)(sad2 / sqrt(16.0 * 8) * 2);
-  }
+          vsrc11 = _mm_loadl_epi64((const __m128i*)(&pSrc1[iX + iStrideSrc1]));
+          vsrc21 = _mm_loadl_epi64((const __m128i*)(&pSrc2[iX + iStrideSrc2]));
+          vsum1 = _mm_abs_epi32(_mm_sub_epi32(vsrc11, vsrc21));
 
-#endif //USE_AVX2
+          vsum = _mm_unpacklo_epi32(vsum0, vsum1);
+          vsum32 = _mm_add_epi32(vsum32, vsum);
+        }
+        pSrc1 += i2StrideSrc1;
+        pSrc2 += i2StrideSrc2;
+      }
+      vsum32 = _mm_hadd_epi32(vsum32, vzero);
+      vsum32 = _mm_hadd_epi32(vsum32, vzero);
+      uiSum = _mm_cvtsi128_si32(vsum32);
+    }
 
-  return (sad);
+  uiSum <<= iSubShift;
+  return uiSum >> DISTORTION_PRECISION_ADJUSTMENT(rcDtParam.bitDepth);
 }
 
 template< X86_VEXT vext >
-Distortion RdCost::xGetSADwMask_SIMD( const DistParam &rcDtParam )
+Distortion RdCost::xGetSADwMask_HBD_SIMD(const DistParam &rcDtParam)
 {
-  if (rcDtParam.org.width < 4  || rcDtParam.bitDepth > 10 || rcDtParam.applyWeight)
-    return RdCost::xGetSADwMask( rcDtParam );
-
-  const short* src1   = (const short*)rcDtParam.org.buf;
-  const short* src2   = (const short*)rcDtParam.cur.buf;
-  const short* weightMask   = (const short*)rcDtParam.mask;
-  int  rows           = rcDtParam.org.height;
-  int  cols           = rcDtParam.org.width;
-  int  subShift       = rcDtParam.subShift;
-  int  subStep        = ( 1 << subShift);
+  CHECK((rcDtParam.org.width & 7), "the function only support width multiple of 8");
+  CHECK(rcDtParam.applyWeight, "the function does not support weighted distortion");
+
+  const Pel* src1 = rcDtParam.org.buf;
+  const Pel* src2 = rcDtParam.cur.buf;
+  const Pel* weightMask = rcDtParam.mask;
+  int  rows = rcDtParam.org.height;
+  int  cols = rcDtParam.org.width;
+  int  subShift = rcDtParam.subShift;
+  int  subStep = (1 << subShift);
   const int strideSrc1 = rcDtParam.org.stride * subStep;
   const int strideSrc2 = rcDtParam.cur.stride * subStep;
   const int strideMask = rcDtParam.maskStride * subStep;
 
   Distortion sum = 0;
-  if( vext >= AVX2 && (cols & 15 ) == 0 )
-  {
+
 #ifdef USE_AVX2
-    // Do for width that multiple of 16
+  if (vext >= AVX2)
+  {
     __m256i vzero = _mm256_setzero_si256();
     __m256i vsum32 = vzero;
-    for( int y = 0; y < rows; y+= subStep)
+    for (int y = 0; y < rows; y += subStep)
     {
-      for( int x = 0; x < cols; x+=16 )
+      for (int x = 0; x < cols; x += 8)
       {
-        __m256i vsrc1 = _mm256_lddqu_si256( ( __m256i* )( &src1[x] ) );
-        __m256i vsrc2 = _mm256_lddqu_si256( ( __m256i* )( &src2[x] ) );
-        __m256i vmask;
+        __m256i vsrc1 = _mm256_lddqu_si256((const __m256i*)(&src1[x]));
+        __m256i vsrc2 = _mm256_lddqu_si256((const __m256i*)(&src2[x]));
+        __m256i vmask, vsum;
         if (rcDtParam.stepX == -1)
         {
-          vmask = _mm256_lddqu_si256((__m256i*)((&weightMask[x]) - (x << 1) - (16 - 1)));
-          const __m256i shuffle_mask = _mm256_set_epi8(1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14, 1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14);
-          vmask = _mm256_shuffle_epi8(vmask, shuffle_mask);
-          vmask = _mm256_permute4x64_epi64(vmask, _MM_SHUFFLE(1, 0, 3, 2));
+          vmask = _mm256_lddqu_si256((__m256i*)((&weightMask[x]) - (x << 1) - (8 - 1)));
+          vmask = _mm256_permute4x64_epi64(_mm256_shuffle_epi32(vmask, 0x1b), 0x4e);
         }
         else
         {
-          vmask = _mm256_lddqu_si256((__m256i*)(&weightMask[x]));
+          vmask = _mm256_lddqu_si256((const __m256i*)(&weightMask[x]));
         }
-        vsum32 = _mm256_add_epi32( vsum32, _mm256_madd_epi16( vmask, _mm256_abs_epi16( _mm256_sub_epi16( vsrc1, vsrc2 ) ) ) );
+
+        vsum = _mm256_mullo_epi32(vmask, _mm256_abs_epi32(_mm256_sub_epi32(vsrc1, vsrc2)));
+        vsum32 = _mm256_add_epi32(vsum32, vsum);
       }
       src1 += strideSrc1;
       src2 += strideSrc2;
       weightMask += strideMask;
     }
-    vsum32 = _mm256_hadd_epi32( vsum32, vzero );
-    vsum32 = _mm256_hadd_epi32( vsum32, vzero );
-    sum =  _mm_cvtsi128_si32( _mm256_castsi256_si128( vsum32 ) ) + _mm_cvtsi128_si32( _mm256_castsi256_si128( _mm256_permute2x128_si256( vsum32, vsum32, 0x11 ) ) );
-#endif
+
+    vsum32 = _mm256_add_epi32(vsum32, _mm256_permute4x64_epi64(vsum32, 0x4e));
+    vsum32 = _mm256_add_epi32(vsum32, _mm256_permute4x64_epi64(vsum32, 0xb1));
+    vsum32 = _mm256_add_epi32(vsum32, _mm256_shuffle_epi32(vsum32, 0x1b));
+    sum = _mm_cvtsi128_si32(_mm256_castsi256_si128(vsum32));
   }
   else
+#endif
   {
-    // Do with step of 8
     __m128i vzero = _mm_setzero_si128();
     __m128i vsum32 = vzero;
-    for( int y = 0; y < rows; y+= subStep)
+    for (int y = 0; y < rows; y += subStep)
     {
-      for( int x = 0; x < cols; x+=8 )
+      for (int x = 0; x < cols; x += 8)
       {
-        __m128i vsrc1 = _mm_loadu_si128( ( const __m128i* )( &src1[x] ) );
-        __m128i vsrc2 = _mm_lddqu_si128( ( const __m128i* )( &src2[x] ) );
-        __m128i vmask;
+        __m128i vsrc11 = _mm_lddqu_si128((const __m128i*)(&src1[x]));
+        __m128i vsrc12 = _mm_lddqu_si128((const __m128i*)(&src1[x + 4]));
+        __m128i vsrc21 = _mm_lddqu_si128((const __m128i*)(&src2[x]));
+        __m128i vsrc22 = _mm_lddqu_si128((const __m128i*)(&src2[x + 4]));
+
+        __m128i vmask1, vmask2, vsum1, vsum2;
         if (rcDtParam.stepX == -1)
         {
-          vmask = _mm_lddqu_si128((__m128i*)((&weightMask[x]) - (x << 1) - (8 - 1)));
-          const __m128i shuffle_mask = _mm_set_epi8(1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14);
-          vmask = _mm_shuffle_epi8(vmask, shuffle_mask);
+          vmask1 = _mm_lddqu_si128((__m128i*)((&weightMask[x]) - (x << 1) - (8 - 1) + 4));
+          vmask1 = _mm_shuffle_epi32(vmask1, 0x1b);
+          vmask2 = _mm_lddqu_si128((__m128i*)((&weightMask[x]) - (x << 1) - (8 - 1)));
+          vmask2 = _mm_shuffle_epi32(vmask2, 0x1b);
         }
         else
         {
-          vmask = _mm_lddqu_si128((const __m128i*)(&weightMask[x]));
+          vmask1 = _mm_lddqu_si128((const __m128i*)(&weightMask[x]));
+          vmask2 = _mm_lddqu_si128((const __m128i*)(&weightMask[x + 4]));
         }
-        vsum32 = _mm_add_epi32( vsum32, _mm_madd_epi16( vmask, _mm_abs_epi16( _mm_sub_epi16( vsrc1, vsrc2 ) ) ) );
+
+        vsum1 = _mm_mullo_epi32(vmask1, _mm_abs_epi32(_mm_sub_epi32(vsrc11, vsrc21)));
+        vsum2 = _mm_mullo_epi32(vmask2, _mm_abs_epi32(_mm_sub_epi32(vsrc12, vsrc22)));
+        vsum32 = _mm_add_epi32(vsum32, vsum1);
+        vsum32 = _mm_add_epi32(vsum32, vsum2);
       }
       src1 += strideSrc1;
       src2 += strideSrc2;
       weightMask += strideMask;
     }
-    vsum32 = _mm_hadd_epi32( vsum32, vzero );
-    vsum32 = _mm_hadd_epi32( vsum32, vzero );
-    sum =  _mm_cvtsi128_si32( vsum32 );
+    vsum32 = _mm_hadd_epi32(vsum32, vzero);
+    vsum32 = _mm_hadd_epi32(vsum32, vzero);
+    sum = _mm_cvtsi128_si32(vsum32);
   }
-  sum <<= subShift;
 
+  sum <<= subShift;
   return sum >> DISTORTION_PRECISION_ADJUSTMENT(rcDtParam.bitDepth);
 }
 
+template< X86_VEXT vext >
+Distortion RdCost::xGetSSE_HBD_SIMD(const DistParam& pcDtParam)
+{
+#ifndef FULL_NBIT
+#error the function only supports full bit-depth
+#endif
+  CHECK(pcDtParam.applyWeight, "the function does not support weighted SSE");
+
+  const Pel* piOrg = pcDtParam.org.buf;
+  const Pel* piCur = pcDtParam.cur.buf;
+  int  iRows = pcDtParam.org.height;
+  int  iCols = pcDtParam.org.width;
+  int  iStrideCur = pcDtParam.cur.stride;
+  int  iStrideOrg = pcDtParam.org.stride;
+
+  Distortion uiSum = 0;
+#ifdef USE_AVX2
+  if ((vext >= AVX2) && ((iCols & 7) == 0))
+  {
+    __m256i vsum = _mm256_setzero_si256();
+    for (int iY = 0; iY < iRows; iY++)
+    {
+      for (int iX = 0; iX < iCols; iX += 8)
+      {
+        __m256i vorg = _mm256_lddqu_si256((const __m256i*)(&piOrg[iX]));
+        __m256i vcur = _mm256_lddqu_si256((const __m256i*)(&piCur[iX]));
+        __m256i vtemp = _mm256_sub_epi32(vorg, vcur);
+        vsum = _mm256_add_epi64(vsum, _mm256_mul_epi32(vtemp, vtemp));
+
+        vorg = _mm256_srli_si256(vorg, 4);
+        vcur = _mm256_srli_si256(vcur, 4);
+        vtemp = _mm256_sub_epi32(vorg, vcur);
+        vsum = _mm256_add_epi64(vsum, _mm256_mul_epi32(vtemp, vtemp));
+      }
+      piOrg += iStrideOrg;
+      piCur += iStrideCur;
+    }
+    uiSum += _mm256_extract_epi64(vsum, 0) + _mm256_extract_epi64(vsum, 1) + _mm256_extract_epi64(vsum, 2) + _mm256_extract_epi64(vsum, 3);
+  }
+  else
+#endif
+    if ((iCols & 3) == 0)
+    {
+      __m128i vsum = _mm_setzero_si128();
+      for (int iY = 0; iY < iRows; iY++)
+      {
+        for (int iX = 0; iX < iCols; iX += 4)
+        {
+          __m128i vorg = _mm_lddqu_si128((const __m128i*)(&piOrg[iX]));
+          __m128i vcur = _mm_lddqu_si128((const __m128i*)(&piCur[iX]));
+          __m128i vtemp = _mm_sub_epi32(vorg, vcur);
+          vsum = _mm_add_epi64(vsum, _mm_mul_epi32(vtemp, vtemp));
+
+          vorg = _mm_srli_si128(vorg, 4);
+          vcur = _mm_srli_si128(vcur, 4);
+          vtemp = _mm_sub_epi32(vorg, vcur);
+          vsum = _mm_add_epi64(vsum, _mm_mul_epi32(vtemp, vtemp));
+        }
+        piOrg += iStrideOrg;
+        piCur += iStrideCur;
+      }
+      uiSum += _mm_extract_epi64(vsum, 0) + _mm_extract_epi64(vsum, 1);
+    }
+    else if ((iCols & 1) == 0)
+    {
+      __m128i vsum = _mm_setzero_si128();
+      for (int iY = 0; iY < iRows; iY++)
+      {
+        for (int iX = 0; iX < iCols; iX += 2)
+        {
+          __m128i vorg = _mm_loadl_epi64((const __m128i*)(&piOrg[iX]));
+          __m128i vcur = _mm_loadl_epi64((const __m128i*)(&piCur[iX]));
+          vorg = _mm_shuffle_epi32(vorg, 0xd8);
+          vcur = _mm_shuffle_epi32(vcur, 0xd8);
+          __m128i vtemp = _mm_sub_epi32(vorg, vcur);
+          vsum = _mm_add_epi64(vsum, _mm_mul_epi32(vtemp, vtemp));
+        }
+        piOrg += iStrideOrg;
+        piCur += iStrideCur;
+      }
+      uiSum += _mm_extract_epi64(vsum, 0) + _mm_extract_epi64(vsum, 1);
+    }
+    else
+    {
+      Intermediate_Int iTemp;
+      for (int iY = 0; iY < iRows; iY++)
+      {
+        for (int iX = 0; iX < iCols; iX++)
+        {
+          iTemp = piOrg[iX] - piCur[iX];
+          uiSum += Distortion(iTemp * iTemp);
+        }
+        piOrg += iStrideOrg;
+        piCur += iStrideCur;
+      }
+    }
+
+  return uiSum;
+}
+#else
 template<X86_VEXT vext>
 Distortion RdCost::xGetHADs_SIMD( const DistParam &rcDtParam )
 {
@@ -2289,7 +4462,7 @@ Distortion RdCost::xGetHADs_SIMD( const DistParam &rcDtParam )
 
   return uiSum >> DISTORTION_PRECISION_ADJUSTMENT(rcDtParam.bitDepth);
 }
-
+#endif
 template <X86_VEXT vext>
 void RdCost::_initRdCostX86()
 {
@@ -2303,7 +4476,41 @@ void RdCost::_initRdCostX86()
   //m_afpDistortFunc[DF_SSE32  ] = xGetSSE_NxN_SIMD<Pel, Pel, 32, vext>;
   //m_afpDistortFunc[DF_SSE64  ] = xGetSSE_NxN_SIMD<Pel, Pel, 64, vext>;
   //m_afpDistortFunc[DF_SSE16N ] = xGetSSE_SIMD<Pel, Pel, vext>;
-
+#if RExt__HIGH_BIT_DEPTH_SUPPORT
+  m_afpDistortFunc[DF_SAD] = xGetSAD_HBD_SIMD<vext>;
+  m_afpDistortFunc[DF_SAD2] = xGetSAD_HBD_SIMD<vext>;
+  m_afpDistortFunc[DF_SAD4] = xGetSAD_HBD_SIMD<vext>;
+  m_afpDistortFunc[DF_SAD8] = xGetSAD_HBD_SIMD<vext>;
+  m_afpDistortFunc[DF_SAD16] = xGetSAD_HBD_SIMD<vext>;
+  m_afpDistortFunc[DF_SAD32] = xGetSAD_HBD_SIMD<vext>;
+  m_afpDistortFunc[DF_SAD64] = xGetSAD_HBD_SIMD<vext>;
+  m_afpDistortFunc[DF_SAD16N] = xGetSAD_HBD_SIMD<vext>;
+  m_afpDistortFunc[DF_SAD12] = xGetSAD_HBD_SIMD<vext>;
+  m_afpDistortFunc[DF_SAD24] = xGetSAD_HBD_SIMD<vext>;
+  m_afpDistortFunc[DF_SAD48] = xGetSAD_HBD_SIMD<vext>;
+  m_afpDistortFunc[DF_SAD_INTERMEDIATE_BITDEPTH] = xGetSAD_HBD_SIMD<vext>;
+  m_afpDistortFunc[DF_SAD_WITH_MASK] = xGetSADwMask_HBD_SIMD<vext>;
+
+  m_afpDistortFunc[DF_HAD] = xGetHADs_HBD_SIMD<vext>;
+  m_afpDistortFunc[DF_HAD2] = xGetHADs_HBD_SIMD<vext>;
+  m_afpDistortFunc[DF_HAD4] = xGetHADs_HBD_SIMD<vext>;
+  m_afpDistortFunc[DF_HAD8] = xGetHADs_HBD_SIMD<vext>;
+  m_afpDistortFunc[DF_HAD16] = xGetHADs_HBD_SIMD<vext>;
+  m_afpDistortFunc[DF_HAD32] = xGetHADs_HBD_SIMD<vext>;
+  m_afpDistortFunc[DF_HAD64] = xGetHADs_HBD_SIMD<vext>;
+  m_afpDistortFunc[DF_HAD16N] = xGetHADs_HBD_SIMD<vext>;
+
+#if FULL_NBIT
+  m_afpDistortFunc[DF_SSE] = xGetSSE_HBD_SIMD<vext>;
+  m_afpDistortFunc[DF_SSE2] = xGetSSE_HBD_SIMD<vext>;
+  m_afpDistortFunc[DF_SSE4] = xGetSSE_HBD_SIMD<vext>;
+  m_afpDistortFunc[DF_SSE8] = xGetSSE_HBD_SIMD<vext>;
+  m_afpDistortFunc[DF_SSE16] = xGetSSE_HBD_SIMD<vext>;
+  m_afpDistortFunc[DF_SSE32] = xGetSSE_HBD_SIMD<vext>;
+  m_afpDistortFunc[DF_SSE64] = xGetSSE_HBD_SIMD<vext>;
+  m_afpDistortFunc[DF_SSE16N] = xGetSSE_HBD_SIMD<vext>;
+#endif
+#else
   m_afpDistortFunc[DF_SAD    ] = xGetSAD_SIMD<vext>;
   m_afpDistortFunc[DF_SAD2   ] = xGetSAD_SIMD<vext>;
   m_afpDistortFunc[DF_SAD4   ] = xGetSAD_NxN_SIMD<4,  vext>;
@@ -2329,6 +4536,7 @@ void RdCost::_initRdCostX86()
   m_afpDistortFunc[DF_SAD_INTERMEDIATE_BITDEPTH] = RdCost::xGetSAD_IBD_SIMD<vext>;
 
   m_afpDistortFunc[DF_SAD_WITH_MASK] = xGetSADwMask_SIMD<vext>;
+#endif
 }
 
 template void RdCost::_initRdCostX86<SIMDX86>();
diff --git a/source/Lib/DecoderAnalyserLib/CMakeLists.txt b/source/Lib/DecoderAnalyserLib/CMakeLists.txt
index 4fbd3463e..d91d1d50a 100644
--- a/source/Lib/DecoderAnalyserLib/CMakeLists.txt
+++ b/source/Lib/DecoderAnalyserLib/CMakeLists.txt
@@ -29,28 +29,8 @@ if( SET_ENABLE_TRACING )
   endif()
 endif()
 
-if( OpenMP_FOUND )
-  if( SET_ENABLE_SPLIT_PARALLELISM )
-    if( ENABLE_SPLIT_PARALLELISM )
-      target_compile_definitions( ${LIB_NAME} PUBLIC ENABLE_SPLIT_PARALLELISM=1 )
-    else()
-      target_compile_definitions( ${LIB_NAME} PUBLIC ENABLE_SPLIT_PARALLELISM=0 )
-    endif()
-  endif()
-  if( SET_ENABLE_WPP_PARALLELISM )
-    if( ENABLE_WPP_PARALLELISM )
-      target_compile_definitions( ${LIB_NAME} PUBLIC ENABLE_WPP_PARALLELISM=1 )
-    else()
-      target_compile_definitions( ${LIB_NAME} PUBLIC ENABLE_WPP_PARALLELISM=0 )
-    endif()
-  endif()
-else()
-  target_compile_definitions( ${LIB_NAME} PUBLIC ENABLE_SPLIT_PARALLELISM=0 )
-  target_compile_definitions( ${LIB_NAME} PUBLIC ENABLE_WPP_PARALLELISM=0 )
-endif()
-
 target_include_directories( ${LIB_NAME} PUBLIC ../DecoderLib )
-target_link_libraries( ${LIB_NAME} CommonAnalyserLib Threads::Threads )
+target_link_libraries( ${LIB_NAME} CommonAnalyserLib )
 
 # example: place header files in different folders
 source_group( "Natvis Files" FILES ${NATVIS_FILES} )
diff --git a/source/Lib/DecoderLib/AnnexBread.cpp b/source/Lib/DecoderLib/AnnexBread.cpp
index 7058de923..3d488d9fe 100644
--- a/source/Lib/DecoderLib/AnnexBread.cpp
+++ b/source/Lib/DecoderLib/AnnexBread.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -125,7 +125,10 @@ _byteStreamNALUnit(
   statBits.bits+=24; statBits.count+=3;
 #endif
 #endif
-  if(start_code_prefix_one_3bytes != 0x000001) { THROW( "Invalid code prefix" );}
+  if (start_code_prefix_one_3bytes != 0x000001)
+  {
+    THROW("Invalid code prefix");
+  }
   stats.m_numStartCodePrefixBytes += 3;
 
   /* 3. NumBytesInNALunit is set equal to the number of bytes starting with
diff --git a/source/Lib/DecoderLib/AnnexBread.h b/source/Lib/DecoderLib/AnnexBread.h
index 6f9c7334d..a5f322c40 100644
--- a/source/Lib/DecoderLib/AnnexBread.h
+++ b/source/Lib/DecoderLib/AnnexBread.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/DecoderLib/BinDecoder.cpp b/source/Lib/DecoderLib/BinDecoder.cpp
index 81d4783ba..df6084512 100644
--- a/source/Lib/DecoderLib/BinDecoder.cpp
+++ b/source/Lib/DecoderLib/BinDecoder.cpp
@@ -3,7 +3,7 @@
 * and contributor rights, including patent rights, and no such rights are
 * granted under this license.
 *
-* Copyright (c) 2010-2020, ITU/ISO/IEC
+* Copyright (c) 2010-2021, ITU/ISO/IEC
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
@@ -97,6 +97,18 @@ void BinDecoderBase::reset( int qp, int initId )
   start();
 }
 
+#if JVET_W0178_CONSTRAINTS_ON_REXT_TOOLS
+void BinDecoderBase::riceStatReset(int bitDepth, bool persistentRiceAdaptationEnabledFlag)
+#else
+void BinDecoderBase::riceStatReset(int bitDepth)
+#endif
+{
+#if JVET_W0178_CONSTRAINTS_ON_REXT_TOOLS
+  Ctx::riceStatReset(bitDepth, persistentRiceAdaptationEnabledFlag);
+#else
+  Ctx::riceStatReset(bitDepth);
+#endif
+}
 
 unsigned BinDecoderBase::decodeBinEP()
 {
diff --git a/source/Lib/DecoderLib/BinDecoder.h b/source/Lib/DecoderLib/BinDecoder.h
index 11a426097..15b6f0ce4 100644
--- a/source/Lib/DecoderLib/BinDecoder.h
+++ b/source/Lib/DecoderLib/BinDecoder.h
@@ -3,7 +3,7 @@
 * and contributor rights, including patent rights, and no such rights are
 * granted under this license.
 *
-* Copyright (c) 2010-2020, ITU/ISO/IEC
+* Copyright (c) 2010-2021, ITU/ISO/IEC
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
@@ -61,6 +61,11 @@ public:
   void      start   ();
   void      finish  ();
   void      reset   ( int qp, int initId );
+#if JVET_W0178_CONSTRAINTS_ON_REXT_TOOLS
+  void      riceStatReset(int bitDepth, bool persistentRiceAdaptationEnabledFlag);
+#else
+  void      riceStatReset(int bitDepth);
+#endif
 #if RExt__DECODER_DEBUG_BIT_STATISTICS
   void      set     ( const CodingStatisticsClassType& type) { ptype = &type; }
 #endif
diff --git a/source/Lib/DecoderLib/CABACReader.cpp b/source/Lib/DecoderLib/CABACReader.cpp
index 2980b49c3..d5c5d364b 100644
--- a/source/Lib/DecoderLib/CABACReader.cpp
+++ b/source/Lib/DecoderLib/CABACReader.cpp
@@ -3,7 +3,7 @@
 * and contributor rights, including patent rights, and no such rights are
 * granted under this license.
 *
-* Copyright (c) 2010-2020, ITU/ISO/IEC
+* Copyright (c) 2010-2021, ITU/ISO/IEC
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
@@ -83,6 +83,12 @@ void CABACReader::initCtxModels( Slice& slice )
     }
   }
   m_BinDecoder.reset( qp, (int)sliceType );
+  m_BinDecoder.setBaseLevel(slice.getRiceBaseLevel());
+#if JVET_W0178_CONSTRAINTS_ON_REXT_TOOLS
+  m_BinDecoder.riceStatReset(slice.getSPS()->getBitDepth(CHANNEL_TYPE_LUMA), slice.getSPS()->getSpsRangeExtension().getPersistentRiceAdaptationEnabledFlag());
+#else
+  m_BinDecoder.riceStatReset(slice.getSPS()->getBitDepth(CHANNEL_TYPE_LUMA));
+#endif
 }
 
 
@@ -144,7 +150,7 @@ void CABACReader::coding_tree_unit( CodingStructure& cs, const UnitArea& area, i
 
 
   sao( cs, ctuRsAddr );
-  if (cs.sps->getALFEnabledFlag() && (cs.slice->getTileGroupAlfEnabledFlag(COMPONENT_Y)))
+  if (cs.sps->getALFEnabledFlag() && (cs.slice->getAlfEnabledFlag(COMPONENT_Y)))
   {
     const PreCalcValues& pcv = *cs.pcv;
     int                 frame_width_in_ctus = pcv.widthInCtus;
@@ -161,7 +167,7 @@ void CABACReader::coding_tree_unit( CodingStructure& cs, const UnitArea& area, i
 
     for( int compIdx = 0; compIdx < MAX_NUM_COMPONENT; compIdx++ )
     {
-      if (cs.slice->getTileGroupAlfEnabledFlag((ComponentID)compIdx))
+      if (cs.slice->getAlfEnabledFlag((ComponentID)compIdx))
       {
         uint8_t* ctbAlfFlag = cs.slice->getPic()->getAlfCtuEnableFlag( compIdx );
         int ctx = 0;
@@ -177,7 +183,7 @@ void CABACReader::coding_tree_unit( CodingStructure& cs, const UnitArea& area, i
         }
         if( isChroma( (ComponentID)compIdx ) )
         {
-          int apsIdx = cs.slice->getTileGroupApsIdChroma();
+          int apsIdx = cs.slice->getAlfApsIdChroma();
           CHECK(cs.slice->getAlfAPSs()[apsIdx] == nullptr, "APS not initialized");
           const AlfParam& alfParam = cs.slice->getAlfAPSs()[apsIdx]->getAlfAPSParam();
           const int numAlts = alfParam.numAlternativesChroma;
@@ -243,7 +249,7 @@ void CABACReader::coding_tree_unit( CodingStructure& cs, const UnitArea& area, i
 void CABACReader::readAlfCtuFilterIndex(CodingStructure& cs, unsigned ctuRsAddr)
 {
   short* alfCtbFilterSetIndex = cs.slice->getPic()->getAlfCtbFilterIndex();
-  unsigned numAps = cs.slice->getTileGroupNumAps();
+  unsigned numAps = cs.slice->getNumAlfApsIdsLuma();
   unsigned numAvailableFiltSets = numAps + NUM_FIXED_FILTER_SETS;
   uint32_t filtIndex = 0;
   if (numAvailableFiltSets > NUM_FIXED_FILTER_SETS)
@@ -1140,7 +1146,7 @@ void CABACReader::pred_mode( CodingUnit& cu )
     else
     {
       cu.predMode = m_BinDecoder.decodeBin(Ctx::PredMode(DeriveCtx::CtxPredModeFlag(cu))) ? MODE_INTRA : MODE_INTER;
-      if (CU::isIntra(cu) && cu.cs->slice->getSPS()->getPLTMode() && cu.lwidth() <= 64 && ( ( (!isLuma(cu.chType)) && (cu.chromaSize().width * cu.chromaSize().height > 16) ) || ((isLuma(cu.chType)) && ((cu.lumaSize().width * cu.lumaSize().height) > 16 ) )  ) && (!cu.isLocalSepTree() || isLuma(cu.chType)  )  )
+      if (CU::isIntra(cu) && cu.cs->slice->getSPS()->getPLTMode() && cu.lwidth() <= 64 &&  cu.lheight() <= 64 && ( ( (!isLuma(cu.chType)) && (cu.chromaSize().width * cu.chromaSize().height > 16) ) || ((isLuma(cu.chType)) && ((cu.lumaSize().width * cu.lumaSize().height) > 16 ) )  ) && (!cu.isLocalSepTree() || isLuma(cu.chType)  )  )
       {
         if (m_BinDecoder.decodeBin(Ctx::PLTFlag(0)))
         {
@@ -2961,6 +2967,15 @@ void CABACReader::residual_coding( TransformUnit& tu, ComponentID compID, CUCtx&
   int ctxBinSampleRatio = (compID == COMPONENT_Y) ? MAX_TU_LEVEL_CTX_CODED_BIN_CONSTRAINT_LUMA : MAX_TU_LEVEL_CTX_CODED_BIN_CONSTRAINT_CHROMA;
   cctx.regBinLimit = (tu.getTbAreaAfterCoefZeroOut(compID) * ctxBinSampleRatio) >> 4;
 
+  int baseLevel = m_BinDecoder.getCtx().getBaseLevel();
+  cctx.setBaseLevel(baseLevel);
+  if (tu.cs->slice->getSPS()->getSpsRangeExtension().getPersistentRiceAdaptationEnabledFlag())
+  {
+    cctx.setUpdateHist(1);
+    unsigned riceStats = m_BinDecoder.getCtx().getGRAdaptStats((unsigned)compID);
+    TCoeff historyValue = (TCoeff)1 << riceStats;
+    cctx.setHistValue(historyValue);
+  }
   for (int subSetId = (cctx.scanPosLast() >> cctx.log2CGSize()); subSetId >= 0; subSetId--)
   {
     cctx.initSubblock(subSetId);
@@ -3117,11 +3132,19 @@ int CABACReader::last_sig_coeff( CoeffCodingContext& cctx, TransformUnit& tu, Co
   unsigned PosLastX = 0, PosLastY = 0;
   unsigned maxLastPosX = cctx.maxLastPosX();
   unsigned maxLastPosY = cctx.maxLastPosY();
+#if JVET_W0046_RLSCP
+  unsigned zoTbWdith  = std::min<unsigned>(JVET_C0024_ZERO_OUT_TH, cctx.width());
+  unsigned zoTbHeight = std::min<unsigned>(JVET_C0024_ZERO_OUT_TH, cctx.height());
+#endif
 
   if( tu.cs->sps->getUseMTS() && tu.cu->sbtInfo != 0 && tu.blocks[ compID ].width <= 32 && tu.blocks[ compID ].height <= 32 && compID == COMPONENT_Y )
   {
-    maxLastPosX = ( tu.blocks[ compID ].width  == 32 ) ? g_uiGroupIdx[ 15 ] : maxLastPosX;
-    maxLastPosY = ( tu.blocks[ compID ].height == 32 ) ? g_uiGroupIdx[ 15 ] : maxLastPosY;
+    maxLastPosX = (tu.blocks[compID].width == 32) ? g_groupIdx[15] : maxLastPosX;
+    maxLastPosY = (tu.blocks[compID].height == 32) ? g_groupIdx[15] : maxLastPosY;
+#if JVET_W0046_RLSCP
+    zoTbWdith  = (tu.blocks[compID].width == 32) ? 16 : zoTbWdith;
+    zoTbHeight = (tu.blocks[compID].height == 32) ? 16 : zoTbHeight;
+#endif
   }
 
   for( ; PosLastX < maxLastPosX; PosLastX++ )
@@ -3140,25 +3163,32 @@ int CABACReader::last_sig_coeff( CoeffCodingContext& cctx, TransformUnit& tu, Co
   }
   if( PosLastX > 3 )
   {
-    uint32_t uiTemp  = 0;
+    uint32_t temp    = 0;
     uint32_t uiCount = ( PosLastX - 2 ) >> 1;
     for ( int i = uiCount - 1; i >= 0; i-- )
     {
-      uiTemp += m_BinDecoder.decodeBinEP( ) << i;
+      temp += m_BinDecoder.decodeBinEP() << i;
     }
-    PosLastX = g_uiMinInGroup[ PosLastX ] + uiTemp;
+    PosLastX = g_minInGroup[PosLastX] + temp;
   }
   if( PosLastY > 3 )
   {
-    uint32_t uiTemp  = 0;
+    uint32_t temp    = 0;
     uint32_t uiCount = ( PosLastY - 2 ) >> 1;
     for ( int i = uiCount - 1; i >= 0; i-- )
     {
-      uiTemp += m_BinDecoder.decodeBinEP( ) << i;
+      temp += m_BinDecoder.decodeBinEP() << i;
     }
-    PosLastY = g_uiMinInGroup[ PosLastY ] + uiTemp;
+    PosLastY = g_minInGroup[PosLastY] + temp;
   }
 
+#if JVET_W0046_RLSCP
+  if (tu.cu->slice->getReverseLastSigCoeffFlag())
+  {
+    PosLastX = zoTbWdith - 1 - PosLastX;
+    PosLastY = zoTbHeight - 1 - PosLastY;
+  }
+#endif
   int blkPos;
   blkPos = PosLastX + (PosLastY * cctx.width());
 
@@ -3196,6 +3226,8 @@ void CABACReader::residual_coding_subblock( CoeffCodingContext& cctx, TCoeff* co
   const bool  isLast      = cctx.isLast();
   int         firstSigPos = ( isLast ? cctx.scanPosLast() : cctx.maxSubPos() );
   int         nextSigPos  = firstSigPos;
+  int baseLevel = cctx.getBaseLevel();
+  bool updateHistory = cctx.getUpdateHist();
 
   //===== decode significant_coeffgroup_flag =====
   RExt__DECODER_DEBUG_BIT_STATISTICS_SET( ctype_group );
@@ -3281,8 +3313,8 @@ void CABACReader::residual_coding_subblock( CoeffCodingContext& cctx, TCoeff* co
   unsigned ricePar = 0;
   for( int scanPos = firstSigPos; scanPos > firstPosMode2; scanPos-- )
   {
-    int       sumAll = cctx.templateAbsSum(scanPos, coeff, 4);
-    ricePar = g_auiGoRiceParsCoeff[sumAll];
+    ricePar = (cctx.*(cctx.deriveRiceRRC))(scanPos, coeff, baseLevel);
+
     TCoeff& tcoeff = coeff[ cctx.blockPos( scanPos ) ];
     if( tcoeff >= 4 )
     {
@@ -3290,20 +3322,33 @@ void CABACReader::residual_coding_subblock( CoeffCodingContext& cctx, TCoeff* co
       int       rem     = m_BinDecoder.decodeRemAbsEP( ricePar, COEF_REMAIN_BIN_REDUCTION, cctx.maxLog2TrDRange() );
       DTRACE( g_trace_ctx, D_SYNTAX_RESI, "rem_val() bin=%d ctx=%d\n", rem, ricePar );
       tcoeff += (rem<<1);
+      if ((updateHistory) && (rem > 0))
+      {
+        unsigned &riceStats = m_BinDecoder.getCtx().getGRAdaptStats((unsigned)(cctx.compID()));
+        cctx.updateRiceStat(riceStats, rem, 1);
+        cctx.setUpdateHist(0);
+        updateHistory = 0;
+      }
     }
   }
 
   //===== coeff bypass ====
   for( int scanPos = firstPosMode2; scanPos >= minSubPos; scanPos-- )
   {
-    int       sumAll = cctx.templateAbsSum(scanPos, coeff, 0);
-    int       rice      = g_auiGoRiceParsCoeff                        [sumAll];
-    int       pos0      = g_auiGoRicePosCoeff0(state, rice);
+    int rice = (cctx.*(cctx.deriveRiceRRC))(scanPos, coeff, 0);
+    int       pos0   = g_goRicePosCoeff0(state, rice);
     RExt__DECODER_DEBUG_BIT_STATISTICS_SET(ctype_escs);
     int       rem       = m_BinDecoder.decodeRemAbsEP( rice, COEF_REMAIN_BIN_REDUCTION, cctx.maxLog2TrDRange() );
     DTRACE( g_trace_ctx, D_SYNTAX_RESI, "rem_val() bin=%d ctx=%d\n", rem, rice );
     TCoeff    tcoeff  = ( rem == pos0 ? 0 : rem < pos0 ? rem+1 : rem );
     state = ( stateTransTable >> ((state<<2)+((tcoeff&1)<<1)) ) & 3;
+    if ((updateHistory) && (rem > 0))
+    {
+      unsigned &riceStats = m_BinDecoder.getCtx().getGRAdaptStats((unsigned)(cctx.compID()));
+      cctx.updateRiceStat(riceStats, rem, 0);
+      cctx.setUpdateHist(0);
+      updateHistory = 0;
+    }
     if( tcoeff )
     {
       int        blkPos         = cctx.blockPos( scanPos );
@@ -3352,11 +3397,16 @@ void CABACReader::residual_codingTS( TransformUnit& tu, ComponentID compID )
   for( int subSetId = 0; subSetId <= ( cctx.maxNumCoeff() - 1 ) >> cctx.log2CGSize(); subSetId++ )
   {
     cctx.initSubblock         ( subSetId );
-    residual_coding_subblockTS( cctx, coeff );
+    int goRiceParam = 1;
+    if (tu.cu->slice->getSPS()->getSpsRangeExtension().getTSRCRicePresentFlag() && tu.mtsIdx[compID] == MTS_SKIP)
+    {
+      goRiceParam = goRiceParam + tu.cu->slice->get_tsrc_index();
+    }
+    residual_coding_subblockTS( cctx, coeff, goRiceParam);
   }
 }
 
-void CABACReader::residual_coding_subblockTS( CoeffCodingContext& cctx, TCoeff* coeff )
+void CABACReader::residual_coding_subblockTS( CoeffCodingContext& cctx, TCoeff* coeff, int riceParam)
 {
   // NOTE: All coefficients of the subblock must be set to zero before calling this function
 #if RExt__DECODER_DEBUG_BIT_STATISTICS
@@ -3498,7 +3548,7 @@ void CABACReader::residual_coding_subblockTS( CoeffCodingContext& cctx, TCoeff*
     }
     if( tcoeff >= cutoffVal )
     {
-      int       rice = cctx.templateAbsSumTS( scanPos, coeff );
+      int       rice = riceParam;
       int       rem  = m_BinDecoder.decodeRemAbsEP( rice, COEF_REMAIN_BIN_REDUCTION, cctx.maxLog2TrDRange() );
       DTRACE( g_trace_ctx, D_SYNTAX_RESI, "ts_rem_val() bin=%d ctx=%d sp=%d\n", rem, rice, scanPos );
       tcoeff += (scanPos <= lastScanPosPass1) ? (rem << 1) : rem;
diff --git a/source/Lib/DecoderLib/CABACReader.h b/source/Lib/DecoderLib/CABACReader.h
index 85869f9d5..92e81dea1 100644
--- a/source/Lib/DecoderLib/CABACReader.h
+++ b/source/Lib/DecoderLib/CABACReader.h
@@ -3,7 +3,7 @@
 * and contributor rights, including patent rights, and no such rights are
 * granted under this license.
 *
-* Copyright (c) 2010-2020, ITU/ISO/IEC
+* Copyright (c) 2010-2021, ITU/ISO/IEC
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
@@ -138,7 +138,7 @@ public:
   int         last_sig_coeff            ( CoeffCodingContext&           cctx,   TransformUnit& tu, ComponentID   compID );
   void        residual_coding_subblock  ( CoeffCodingContext&           cctx,   TCoeff*         coeff, const int stateTransTable, int& state );
   void        residual_codingTS         ( TransformUnit&                tu,     ComponentID     compID );
-  void        residual_coding_subblockTS( CoeffCodingContext&           cctx,   TCoeff*         coeff  );
+  void        residual_coding_subblockTS( CoeffCodingContext&           cctx,   TCoeff*         coeff, int riceParam);
   void        joint_cb_cr               ( TransformUnit&                tu,     const int cbfMask );
 
 
diff --git a/source/Lib/DecoderLib/CMakeLists.txt b/source/Lib/DecoderLib/CMakeLists.txt
index 23a3659a1..9fdcfb250 100644
--- a/source/Lib/DecoderLib/CMakeLists.txt
+++ b/source/Lib/DecoderLib/CMakeLists.txt
@@ -28,28 +28,8 @@ if( SET_ENABLE_TRACING )
   endif()
 endif()
 
-if( OpenMP_FOUND )
-  if( SET_ENABLE_SPLIT_PARALLELISM )
-    if( ENABLE_SPLIT_PARALLELISM )
-      target_compile_definitions( ${LIB_NAME} PUBLIC ENABLE_SPLIT_PARALLELISM=1 )
-    else()
-      target_compile_definitions( ${LIB_NAME} PUBLIC ENABLE_SPLIT_PARALLELISM=0 )
-    endif()
-  endif()
-  if( SET_ENABLE_WPP_PARALLELISM )
-    if( ENABLE_WPP_PARALLELISM )
-      target_compile_definitions( ${LIB_NAME} PUBLIC ENABLE_WPP_PARALLELISM=1 )
-    else()
-      target_compile_definitions( ${LIB_NAME} PUBLIC ENABLE_WPP_PARALLELISM=0 )
-    endif()
-  endif()
-else()
-  target_compile_definitions( ${LIB_NAME} PUBLIC ENABLE_SPLIT_PARALLELISM=0 )
-  target_compile_definitions( ${LIB_NAME} PUBLIC ENABLE_WPP_PARALLELISM=0 )
-endif()
-
 target_include_directories( ${LIB_NAME} PUBLIC . )
-target_link_libraries( ${LIB_NAME} CommonLib Threads::Threads )
+target_link_libraries( ${LIB_NAME} CommonLib )
 
 # example: place header files in different folders
 source_group( "Natvis Files" FILES ${NATVIS_FILES} )
diff --git a/source/Lib/DecoderLib/DecCu.cpp b/source/Lib/DecoderLib/DecCu.cpp
index eeec34743..096e02e42 100644
--- a/source/Lib/DecoderLib/DecCu.cpp
+++ b/source/Lib/DecoderLib/DecCu.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -612,26 +612,6 @@ void DecCu::xIntraRecACTQT(CodingUnit &cu)
   }
 }
 
-/** Function for filling the PCM buffer of a CU using its reconstructed sample array
-* \param pCU   pointer to current CU
-* \param depth CU Depth
-*/
-void DecCu::xFillPCMBuffer(CodingUnit &cu)
-{
-  for( auto &currTU : CU::traverseTUs( cu ) )
-  {
-    for (const CompArea &area : currTU.blocks)
-    {
-      if( !area.valid() ) continue;;
-
-      CPelBuf source      = cu.cs->getRecoBuf(area);
-       PelBuf destination = currTU.getPcmbuf(area.compID);
-
-      destination.copyFrom(source);
-    }
-  }
-}
-
 #include "CommonLib/dtrace_buffer.h"
 
 void DecCu::xReconInter(CodingUnit &cu)
diff --git a/source/Lib/DecoderLib/DecCu.h b/source/Lib/DecoderLib/DecCu.h
index 8789afadb..4b8ce5b49 100644
--- a/source/Lib/DecoderLib/DecCu.h
+++ b/source/Lib/DecoderLib/DecCu.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -81,7 +81,6 @@ protected:
   void xReconInter        ( CodingUnit&      cu );
   void xDecodeInterTexture( CodingUnit&      cu );
   void xReconIntraQT      ( CodingUnit&      cu );
-  void xFillPCMBuffer     ( CodingUnit&      cu );
 
   void xIntraRecBlk       ( TransformUnit&   tu, const ComponentID compID );
   void xIntraRecACTBlk(TransformUnit&   tu);
diff --git a/source/Lib/DecoderLib/DecLib.cpp b/source/Lib/DecoderLib/DecLib.cpp
index 17ebf60e2..1347b946c 100644
--- a/source/Lib/DecoderLib/DecLib.cpp
+++ b/source/Lib/DecoderLib/DecLib.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -212,17 +212,17 @@ bool tryDecodePicture( Picture* pcEncPic, const int expectedPoc, const std::stri
 
                   for( int i = 0; i < pic->slices.size(); i++ )
                   {
-                    pcEncPic->slices[i]->setTileGroupNumAps(pic->slices[i]->getTileGroupNumAps());
-                    pcEncPic->slices[i]->setAlfAPSs(pic->slices[i]->getTileGroupApsIdLuma());
+                    pcEncPic->slices[i]->setNumAlfApsIdsLuma(pic->slices[i]->getNumAlfApsIdsLuma());
+                    pcEncPic->slices[i]->setAlfApsIdsLuma(pic->slices[i]->getAlfApsIdsLuma());
                     pcEncPic->slices[i]->setAlfAPSs(pic->slices[i]->getAlfAPSs());
-                    pcEncPic->slices[i]->setTileGroupApsIdChroma(pic->slices[i]->getTileGroupApsIdChroma());
-                    pcEncPic->slices[i]->setTileGroupAlfEnabledFlag(COMPONENT_Y,  pic->slices[i]->getTileGroupAlfEnabledFlag(COMPONENT_Y));
-                    pcEncPic->slices[i]->setTileGroupAlfEnabledFlag(COMPONENT_Cb, pic->slices[i]->getTileGroupAlfEnabledFlag(COMPONENT_Cb));
-                    pcEncPic->slices[i]->setTileGroupAlfEnabledFlag(COMPONENT_Cr, pic->slices[i]->getTileGroupAlfEnabledFlag(COMPONENT_Cr));
-                    pcEncPic->slices[i]->setTileGroupCcAlfCbApsId(pic->slices[i]->getTileGroupCcAlfCbApsId());
-                    pcEncPic->slices[i]->setTileGroupCcAlfCbEnabledFlag(pic->slices[i]->getTileGroupCcAlfCbEnabledFlag());
-                    pcEncPic->slices[i]->setTileGroupCcAlfCrApsId(pic->slices[i]->getTileGroupCcAlfCrApsId());
-                    pcEncPic->slices[i]->setTileGroupCcAlfCrEnabledFlag(pic->slices[i]->getTileGroupCcAlfCrEnabledFlag());
+                    pcEncPic->slices[i]->setAlfApsIdChroma(pic->slices[i]->getAlfApsIdChroma());
+                    pcEncPic->slices[i]->setAlfEnabledFlag(COMPONENT_Y,  pic->slices[i]->getAlfEnabledFlag(COMPONENT_Y));
+                    pcEncPic->slices[i]->setAlfEnabledFlag(COMPONENT_Cb, pic->slices[i]->getAlfEnabledFlag(COMPONENT_Cb));
+                    pcEncPic->slices[i]->setAlfEnabledFlag(COMPONENT_Cr, pic->slices[i]->getAlfEnabledFlag(COMPONENT_Cr));
+                    pcEncPic->slices[i]->setCcAlfCbApsId(pic->slices[i]->getCcAlfCbApsId());
+                    pcEncPic->slices[i]->setCcAlfCbEnabledFlag(pic->slices[i]->getCcAlfCbEnabledFlag());
+                    pcEncPic->slices[i]->setCcAlfCrApsId(pic->slices[i]->getCcAlfCrApsId());
+                    pcEncPic->slices[i]->setCcAlfCrEnabledFlag(pic->slices[i]->getCcAlfCrEnabledFlag());
                   }
                 }
 
@@ -331,6 +331,8 @@ bool tryDecodePicture( Picture* pcEncPic, const int expectedPoc, const std::stri
           }
 
           pcDecLib->updateAssociatedIRAP();
+          pcDecLib->updatePrevGDRInSameLayer();
+          pcDecLib->updatePrevIRAPAndGDRSubpic();
           // LMCS APS will be assigned later in LMCS initialization step
           pcEncPic->cs->picHeader->setLmcsAPS( nullptr );
           if( bitstreamFile )
@@ -404,6 +406,11 @@ DecLib::DecLib()
   , m_parameterSetManager()
   , m_apcSlicePilot(NULL)
   , m_SEIs()
+  , m_sdiSEIInFirstAU(NULL)
+  , m_maiSEIInFirstAU(NULL)
+#if JVET_W0078_MVP_SEI 
+  , m_mvpSEIInFirstAU(NULL)
+#endif
   , m_cIntraPred()
   , m_cInterPred()
   , m_cTrQuant()
@@ -412,7 +419,7 @@ DecLib::DecLib()
   , m_cCuDecoder()
   , m_HLSReader()
   , m_seiReader()
-  , m_cLoopFilter()
+  , m_deblockingFilter()
   , m_cSAO()
   , m_cReshaper()
 #if JVET_J0090_MEMORY_BANDWITH_MEASURE
@@ -424,11 +431,13 @@ DecLib::DecLib()
   , m_prevPicPOC(MAX_INT)
   , m_prevTid0POC(0)
   , m_bFirstSliceInPicture(true)
-  , m_firstSliceInSequence{ true }
+  , m_firstPictureInSequence(true)
+  , m_colourTranfParams()
   , m_firstSliceInBitstream(true)
   , m_isFirstAuInCvs( true )
   , m_prevSliceSkipped(false)
-  , m_skippedPOC(0)
+  , m_skippedPOC(MAX_INT)
+  , m_skippedLayerID(MAX_INT)
   , m_lastPOCNoOutputPriorPics(-1)
   , m_isNoOutputPriorPics(false)
   , m_lastNoOutputBeforeRecoveryFlag{ false }
@@ -444,13 +453,11 @@ DecLib::DecLib()
   , m_prefixSEINALUs()
   , m_debugPOC( -1 )
   , m_debugCTU( -1 )
-#if JVET_S0163_ON_TARGETOLS_SUBLAYERS
   , m_opi( nullptr )
   , m_mTidExternalSet(false)
   , m_mTidOpiSet(false)
   , m_tOlsIdxTidExternalSet(false)
   , m_tOlsIdxTidOpiSet(false)
-#endif
   , m_vps( nullptr )
   , m_maxDecSubPicIdx(0)
   , m_maxDecSliceAddrInSubPic(-1)
@@ -465,6 +472,8 @@ DecLib::DecLib()
   memset(m_prevEOS, false, sizeof(m_prevEOS));
   memset(m_accessUnitEos, false, sizeof(m_accessUnitEos));
   std::fill_n(m_prevGDRInSameLayerPOC, MAX_VPS_LAYERS, -MAX_INT);
+  std::fill_n(m_prevGDRInSameLayerRecoveryPOC, MAX_VPS_LAYERS, -MAX_INT);
+  std::fill_n(m_firstSliceInSequence, MAX_VPS_LAYERS, true);
   std::fill_n(m_pocCRA, MAX_VPS_LAYERS, -MAX_INT);
 #if JVET_S0176_ITEM5
   std::fill_n(m_accessUnitSpsNumSubpic, MAX_VPS_LAYERS, 1);
@@ -486,7 +495,23 @@ DecLib::~DecLib()
     delete m_prefixSEINALUs.front();
     m_prefixSEINALUs.pop_front();
   }
-
+  if (m_sdiSEIInFirstAU != NULL)
+  {
+    delete m_sdiSEIInFirstAU;
+  }
+  m_sdiSEIInFirstAU = NULL;
+  if (m_maiSEIInFirstAU != NULL)
+  {
+    delete m_maiSEIInFirstAU;
+  }
+  m_maiSEIInFirstAU = NULL;
+#if JVET_W0078_MVP_SEI 
+  if (m_mvpSEIInFirstAU != NULL)
+  {
+    delete m_mvpSEIInFirstAU;
+  }
+  m_mvpSEIInFirstAU = NULL;
+#endif
 }
 
 void DecLib::create()
@@ -539,7 +564,7 @@ void DecLib::deletePicBuffer ( )
   }
   m_cALF.destroy();
   m_cSAO.destroy();
-  m_cLoopFilter.destroy();
+  m_deblockingFilter.destroy();
 #if JVET_J0090_MEMORY_BANDWITH_MEASURE
   m_cacheModel.reportSequence( );
   m_cacheModel.destroy( );
@@ -601,6 +626,13 @@ Picture* DecLib::xGetNewPicBuffer( const SPS &sps, const PPS &pps, const uint32_
       pcPic->destroy();
       pcPic->create( sps.getChromaFormatIdc(), Size( pps.getPicWidthInLumaSamples(), pps.getPicHeightInLumaSamples() ), sps.getMaxCUWidth(), sps.getMaxCUWidth() + 16, true, layerId );
     }
+#if GDR_ENABLED // picHeader should be deleted in case pcPic slot gets reused
+    if (pcPic && pcPic->cs && pcPic->cs->picHeader)
+    {          
+      delete pcPic->cs->picHeader;
+      pcPic->cs->picHeader = nullptr;    
+    }
+#endif
   }
 
   pcPic->setBorderExtension( false );
@@ -643,7 +675,7 @@ void DecLib::executeLoopFilters()
       m_cSAO.setReshaper(&m_cReshaper);
   }
   // deblocking filter
-  m_cLoopFilter.loopFilterPic( cs );
+  m_deblockingFilter.deblockingFilterPic( cs );
   CS::setRefinedMotionField(cs);
   if( cs.sps->getSAOEnabledFlag() )
   {
@@ -691,6 +723,34 @@ void DecLib::finishPictureLight(int& poc, PicList*& rpcListPic )
   Slice*  pcSlice = m_pcPic->cs->slice;
 
   m_pcPic->neededForOutput = (pcSlice->getPicHeader()->getPicOutputFlag() ? true : false);
+
+  const VPS *vps = pcSlice->getVPS();
+  if (vps != nullptr)
+  {
+    if (!vps->getEachLayerIsAnOlsFlag())
+    {
+      const int layerId        = pcSlice->getNalUnitLayerId();
+      const int generalLayerId = vps->getGeneralLayerIdx(layerId);
+      bool      layerIsOutput  = true;
+
+      if (vps->getOlsModeIdc() == 0)
+      {
+        layerIsOutput = generalLayerId == vps->m_targetOlsIdx;
+      }
+      else if (vps->getOlsModeIdc() == 1)
+      {
+        layerIsOutput = generalLayerId <= vps->m_targetOlsIdx;
+      }
+      else if (vps->getOlsModeIdc() == 2)
+      {
+        layerIsOutput = vps->getOlsOutputLayerFlag(vps->m_targetOlsIdx, generalLayerId);
+      }
+      if (!layerIsOutput)
+      {
+        m_pcPic->neededForOutput = false;
+      }
+    }
+  }
   m_pcPic->reconstructed = true;
 
   Slice::sortPicList( m_cListPic ); // sorting for application output
@@ -717,6 +777,7 @@ void DecLib::finishPicture(int &poc, PicList *&rpcListPic, MsgLevel msgl, bool a
   }
 
   if (pcSlice->isDRAP()) c = 'D';
+  if (pcSlice->getEdrapRapId() > 0) c = 'E';
 
   //-- For time output for each slice
   msg( msgl, "POC %4d LId: %2d TId: %1d ( %s, %c-SLICE, QP%3d ) ", pcSlice->getPOC(), pcSlice->getPic()->layerId,
@@ -772,6 +833,24 @@ void DecLib::finishPicture(int &poc, PicList *&rpcListPic, MsgLevel msgl, bool a
       msg( WARNING, "Warning: Got multiple decoded picture hash SEI messages. Using first.");
     }
     m_numberOfChecksumErrorsDetected += calcAndPrintHashStatus(((const Picture*) m_pcPic)->getRecoBuf(), hash, pcSlice->getSPS()->getBitDepths(), msgl);
+
+    SEIMessages scalableNestingSeis = getSeisByType(m_pcPic->SEIs, SEI::SCALABLE_NESTING );
+    for (auto seiIt : scalableNestingSeis)
+    {
+      SEIScalableNesting *nestingSei = dynamic_cast<SEIScalableNesting*>(seiIt);
+      if (nestingSei->m_snSubpicFlag)
+      {
+        uint32_t subpicId = nestingSei->m_snSubpicId.front();
+        SEIMessages nestedPictureHashes = getSeisByType(nestingSei->m_nestedSEIs, SEI::DECODED_PICTURE_HASH);
+        for (auto decPicHash : nestedPictureHashes)
+        {
+          const SubPic& subpic = pcSlice->getPPS()->getSubPic(subpicId);
+          const UnitArea area = UnitArea(pcSlice->getSPS()->getChromaFormatIdc(), Area(subpic.getSubPicLeft(), subpic.getSubPicTop(), subpic.getSubPicWidthInLumaSample(), subpic.getSubPicHeightInLumaSample()));
+          PelUnitBuf recoBuf = m_pcPic->cs->getRecoBuf(area);
+          m_numberOfChecksumErrorsDetected += calcAndPrintHashStatus(recoBuf, dynamic_cast<SEIDecodedPictureHash*>(decPicHash), pcSlice->getSPS()->getBitDepths(), msgl);
+        }
+      }
+    }
   }
 
   msg( msgl, "\n");
@@ -792,7 +871,7 @@ void DecLib::finishPicture(int &poc, PicList *&rpcListPic, MsgLevel msgl, bool a
     else if (pcSlice->getPPS()->getMixedNaluTypesInPicFlag())
     {
       bool isRaslPic = true;
-      for (int i = 0; isRaslPic && i < m_pcPic->numSlices; i++) 
+      for (int i = 0; isRaslPic && i < m_pcPic->numSlices; i++)
       {
         if (!(pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RASL || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RADL))
         {
@@ -805,8 +884,38 @@ void DecLib::finishPicture(int &poc, PicList *&rpcListPic, MsgLevel msgl, bool a
       }
     }
   }
+
+  const VPS *vps = pcSlice->getVPS();
+  if (vps != nullptr)
+  {
+    if (!vps->getEachLayerIsAnOlsFlag())
+    {
+      const int layerId        = pcSlice->getNalUnitLayerId();
+      const int generalLayerId = vps->getGeneralLayerIdx(layerId);
+      bool      layerIsOutput  = true;
+
+      if (vps->getOlsModeIdc() == 0)
+      {
+        layerIsOutput = generalLayerId == vps->m_targetOlsIdx;
+      }
+      else if (vps->getOlsModeIdc() == 1)
+      {
+        layerIsOutput = generalLayerId <= vps->m_targetOlsIdx;
+      }
+      else if (vps->getOlsModeIdc() == 2)
+      {
+        layerIsOutput = vps->getOlsOutputLayerFlag(vps->m_targetOlsIdx, generalLayerId);
+      }
+      if (!layerIsOutput)
+      {
+        m_pcPic->neededForOutput = false;
+      }
+    }
+  }
   m_pcPic->reconstructed = true;
 
+  // process buffered suffix APS NALUs
+  processSuffixApsNalus();
 
   Slice::sortPicList( m_cListPic ); // sorting for application output
   poc                 = pcSlice->getPOC();
@@ -901,15 +1010,25 @@ void DecLib::xCreateLostPicture( int iLostPoc, const int layerId )
 
 void  DecLib::xCreateUnavailablePicture( const PPS *pps, const int iUnavailablePoc, const bool longTermFlag, const int temporalId, const int layerId, const bool interLayerRefPicFlag )
 {
-  msg(INFO, "\ninserting unavailable poc : %d\n", iUnavailablePoc);
-  Picture* cFillPic = xGetNewPicBuffer( *( m_parameterSetManager.getFirstSPS() ), *( m_parameterSetManager.getFirstPPS() ), 0, layerId );
+  msg(INFO, "Note: Inserting unavailable POC : %d\n", iUnavailablePoc);
+  auto const sps = m_parameterSetManager.getSPS(pps->getSPSId());
+  Picture* cFillPic = xGetNewPicBuffer( *sps, *pps, 0, layerId );
 
-  CHECK(!cFillPic->slices.size(), "No slices in picture");
+  cFillPic->cs = new CodingStructure( g_globalUnitCache.cuCache, g_globalUnitCache.puCache, g_globalUnitCache.tuCache );
+  cFillPic->cs->sps = sps;
+  cFillPic->cs->pps = pps;
+  cFillPic->cs->vps = m_parameterSetManager.getVPS(sps->getVPSId());
+  cFillPic->cs->create(cFillPic->cs->sps->getChromaFormatIdc(), Area(0, 0, cFillPic->cs->pps->getPicWidthInLumaSamples(), cFillPic->cs->pps->getPicHeightInLumaSamples()), true, (bool)(cFillPic->cs->sps->getPLTMode()));
+  cFillPic->allocateNewSlice();
 
   cFillPic->slices[0]->initSlice();
 
-  uint32_t yFill = 1 << (m_parameterSetManager.getFirstSPS()->getBitDepth(CHANNEL_TYPE_LUMA) - 1);
-  uint32_t cFill = 1 << (m_parameterSetManager.getFirstSPS()->getBitDepth(CHANNEL_TYPE_CHROMA) - 1);
+  cFillPic->setDecodingOrderNumber(0);
+  cFillPic->subLayerNonReferencePictureDueToSTSA = false;
+  cFillPic->unscaledPic = cFillPic;
+
+  uint32_t yFill = 1 << (sps->getBitDepth(CHANNEL_TYPE_LUMA) - 1);
+  uint32_t cFill = 1 << (sps->getBitDepth(CHANNEL_TYPE_CHROMA) - 1);
   cFillPic->getRecoBuf().Y().fill(yFill);
   cFillPic->getRecoBuf().Cb().fill(cFill);
   cFillPic->getRecoBuf().Cr().fill(cFill);
@@ -919,7 +1038,12 @@ void  DecLib::xCreateUnavailablePicture( const PPS *pps, const int iUnavailableP
   cFillPic->interLayerRefPicFlag = interLayerRefPicFlag;
   cFillPic->longTerm = longTermFlag;
   cFillPic->slices[0]->setPOC(iUnavailablePoc);
-  xUpdatePreviousTid0POC(cFillPic->slices[0]);
+  cFillPic->poc = iUnavailablePoc;
+  if( (cFillPic->slices[0]->getTLayer() == 0) && (cFillPic->slices[0]->getNalUnitType() != NAL_UNIT_CODED_SLICE_RASL) && (cFillPic->slices[0]->getNalUnitType() != NAL_UNIT_CODED_SLICE_RADL) )
+  {
+    m_prevTid0POC = cFillPic->slices[0]->getPOC();
+  }
+
   cFillPic->reconstructed = true;
   cFillPic->neededForOutput = false;
   // picture header is not derived for generated reference picture
@@ -958,6 +1082,11 @@ void DecLib::checkLayerIdIncludedInCvss()
     for (auto pic = m_accessUnitPicInfo.begin(); pic != m_accessUnitPicInfo.end(); pic++)
     {
       bool layerIdFind;
+      if ( m_firstAccessUnitPicInfo.size() == 0 )
+      {
+        msg( NOTICE, "Note: checkIncludedInFirstAu(), m_firstAccessUnitPicInfo.size() is 0.\n");
+        continue;
+      }
       for (auto picFirst = m_firstAccessUnitPicInfo.begin(); picFirst != m_firstAccessUnitPicInfo.end(); picFirst++)
       {
         layerIdFind = pic->m_nuhLayerId == picFirst->m_nuhLayerId ? true : false;
@@ -1085,6 +1214,13 @@ void DecLib::checkSEIInAccessUnit()
   int olsIdxIncludeAllLayes = -1;
   bool isNonNestedSliFound = false;
 #endif
+
+  bool bSdiPresentInAu = false;
+#if JVET_W0078_MVP_SEI 
+  bool bAuxSEIsBeforeSdiSEIPresent[4] = { false, false, false, false };
+#else
+  bool bAuxSEIsBeforeSdiSEIPresent[3] = { false, false, false };
+#endif
   for (auto &sei : m_accessUnitSeiPayLoadTypes)
   {
     enum NalUnitType         naluType = std::get<0>(sei);
@@ -1124,7 +1260,34 @@ void DecLib::checkSEIInAccessUnit()
       }
       CHECK(!olsIncludeAllLayersFind, "When there is no OLS that includes all layers in the current CVS in the entire bitstream, there shall be no non-scalable-nested SEI message with payloadType equal to 0 (BP), 1 (PT), 130 (DUI), or 203 (SLI)");
     }
+    if (payloadType == SEI::SCALABILITY_DIMENSION_INFO)
+    {
+      bSdiPresentInAu = true;
+    }
+    else if (payloadType == SEI::MULTIVIEW_ACQUISITION_INFO && !bSdiPresentInAu)
+    {
+      bAuxSEIsBeforeSdiSEIPresent[0] = true;
+    }
+    else if (payloadType == SEI::ALPHA_CHANNEL_INFO && !bSdiPresentInAu)
+    {
+      bAuxSEIsBeforeSdiSEIPresent[1] = true;
+    }
+    else if (payloadType == SEI::DEPTH_REPRESENTATION_INFO && !bSdiPresentInAu)
+    {
+      bAuxSEIsBeforeSdiSEIPresent[2] = true;
+    }
+#if JVET_W0078_MVP_SEI 
+    else if (payloadType == SEI::MULTIVIEW_VIEW_POSITION && !bSdiPresentInAu)
+    {
+      bAuxSEIsBeforeSdiSEIPresent[3] = true;
+    }
+#endif
   }
+
+  CHECK(bSdiPresentInAu && bAuxSEIsBeforeSdiSEIPresent[0], "When an AU contains both an SDI SEI message and an MAI SEI message, the SDI SEI message shall precede the MAI SEI message in decoding order.");
+  CHECK(bSdiPresentInAu && bAuxSEIsBeforeSdiSEIPresent[1], "When an AU contains both an SDI SEI message with sdi_aux_id[i] equal to 1 for at least one value of i and an ACI SEI message, the SDI SEI message shall precede the ACI SEI message in decoding order.");
+  CHECK(bSdiPresentInAu && bAuxSEIsBeforeSdiSEIPresent[2], "When an AU contains both an SDI SEI message with sdi_aux_id[i] equal to 2 for at least one value of i and a DRI SEI message, the SDI SEI message shall precede the DRI SEI message in decoding order.");
+
 #if JVET_S0176_ITEM5
   if (m_isFirstAuInCvs)
   {
@@ -1175,7 +1338,7 @@ void DecLib::checkMultiSubpicNum(int olsIdx)
  - Count the number of identical SEI messages in the current picture
  */
 void DecLib::checkSeiInPictureUnit()
-{  
+{
   std::vector<std::tuple<int, uint32_t, uint8_t*>> seiList;
 
   // payload types subject to constrained SEI repetition
@@ -1187,7 +1350,7 @@ void DecLib::checkSeiInPictureUnit()
     InputBitstream bs = sei->getBitstream();
 
     do
-    {  
+    {
       int payloadType = 0;
       uint32_t val = 0;
 
@@ -1203,7 +1366,7 @@ void DecLib::checkSeiInPictureUnit()
         bs.readByte(val);
         payloadSize += val;
       } while (val==0xFF);
-    
+
       uint8_t *payload = new uint8_t[payloadSize];
       for (uint32_t i = 0; i < payloadSize; i++)
       {
@@ -1218,7 +1381,7 @@ void DecLib::checkSeiInPictureUnit()
   // count repeated messages in list
   for (uint32_t i = 0; i < seiList.size(); i++)
   {
-    int      k, count = 1;      
+    int      k, count = 1;
     int      payloadType1 = std::get<0>(seiList[i]);
     uint32_t payloadSize1 = std::get<1>(seiList[i]);
     uint8_t  *payload1    = std::get<2>(seiList[i]);
@@ -1242,7 +1405,7 @@ void DecLib::checkSeiInPictureUnit()
       int      payloadType2 = std::get<0>(seiList[j]);
       uint32_t payloadSize2 = std::get<1>(seiList[j]);
       uint8_t  *payload2    = std::get<2>(seiList[j]);
-      
+
       // check for identical SEI type, size, and payload
       if(payloadType1 == payloadType2 && payloadSize1 == payloadSize2)
       {
@@ -1251,7 +1414,7 @@ void DecLib::checkSeiInPictureUnit()
           count++;
         }
       }
-    }    
+    }
     CHECK(count > 4, "There shall be less than or equal to 4 identical sei_payload( ) syntax structures within a picture unit.");
   }
 
@@ -1267,7 +1430,7 @@ void DecLib::checkSeiInPictureUnit()
 /**
  - Reset list of SEI NAL units from the current picture
  */
-void DecLib::resetPictureSeiNalus()   
+void DecLib::resetPictureSeiNalus()
 {
   while (!m_pictureSeiNalus.empty())
   {
@@ -1276,6 +1439,19 @@ void DecLib::resetPictureSeiNalus()
   }
 }
 
+/**
+ - Process buffered list of suffix APS NALUs
+ */
+void DecLib::processSuffixApsNalus()
+{
+  while (!m_suffixApsNalus.empty())
+  {
+    xDecodeAPS(*m_suffixApsNalus.front());
+    delete m_suffixApsNalus.front();
+    m_suffixApsNalus.pop_front();
+  }
+}
+
 /**
  - Determine if the first VCL NAL unit of a picture is also the first VCL NAL of an Access Unit
  */
@@ -1343,11 +1519,11 @@ void activateAPS(PicHeader* picHeader, Slice* pSlice, ParameterSetManager& param
 {
   const SPS *sps = parameterSetManager.getSPS(picHeader->getSPSId());
   //luma APSs
-  if (pSlice->getTileGroupAlfEnabledFlag(COMPONENT_Y))
+  if (pSlice->getAlfEnabledFlag(COMPONENT_Y))
   {
-    for (int i = 0; i < pSlice->getTileGroupApsIdLuma().size(); i++)
+    for (int i = 0; i < pSlice->getAlfApsIdsLuma().size(); i++)
     {
-      int apsId = pSlice->getTileGroupApsIdLuma()[i];
+      int apsId = pSlice->getAlfApsIdsLuma()[i];
       APS* aps = parameterSetManager.getAPS(apsId, ALF_APS);
 
       if (aps)
@@ -1367,10 +1543,10 @@ void activateAPS(PicHeader* picHeader, Slice* pSlice, ParameterSetManager& param
       }
     }
   }
-  if (pSlice->getTileGroupAlfEnabledFlag(COMPONENT_Cb)||pSlice->getTileGroupAlfEnabledFlag(COMPONENT_Cr) )
+  if (pSlice->getAlfEnabledFlag(COMPONENT_Cb)||pSlice->getAlfEnabledFlag(COMPONENT_Cr) )
   {
     //chroma APS
-    int apsId = pSlice->getTileGroupApsIdChroma();
+    int apsId = pSlice->getAlfApsIdChroma();
     APS* aps = parameterSetManager.getAPS(apsId, ALF_APS);
     if (aps)
     {
@@ -1397,9 +1573,9 @@ void activateAPS(PicHeader* picHeader, Slice* pSlice, ParameterSetManager& param
   memset( filterParam.ccAlfFilterIdxEnabled[COMPONENT_Cb - 1], false, sizeof(filterParam.ccAlfFilterIdxEnabled[COMPONENT_Cb - 1]) );
   memset( filterParam.ccAlfFilterIdxEnabled[COMPONENT_Cr - 1], false, sizeof(filterParam.ccAlfFilterIdxEnabled[COMPONENT_Cr - 1]) );
 
-  if(pSlice->getTileGroupCcAlfCbEnabledFlag())
+  if(pSlice->getCcAlfCbEnabledFlag())
   {
-    int apsId = pSlice->getTileGroupCcAlfCbApsId();
+    int apsId = pSlice->getCcAlfCbApsId();
     APS *aps = parameterSetManager.getAPS(apsId, ALF_APS);
     if(aps)
     {
@@ -1425,9 +1601,9 @@ void activateAPS(PicHeader* picHeader, Slice* pSlice, ParameterSetManager& param
     }
   }
 
-  if(pSlice->getTileGroupCcAlfCrEnabledFlag())
+  if(pSlice->getCcAlfCrEnabledFlag())
   {
-    int apsId = pSlice->getTileGroupCcAlfCrApsId();
+    int apsId = pSlice->getCcAlfCrApsId();
     APS *aps = parameterSetManager.getAPS(apsId, ALF_APS);
     if(aps)
     {
@@ -1567,7 +1743,7 @@ void DecLib::xActivateParameterSets( const InputNALUnit nalu )
       //No VPS in bitstream: set defaults values of variables in VPS to the ones signalled in SPS
       m_vps->setMaxSubLayers( sps->getMaxTLayers() );
       m_vps->setLayerId( 0, sps->getLayerId() );
-      m_vps->deriveOutputLayerSets(); 
+      m_vps->deriveOutputLayerSets();
     }
     else
     {
@@ -1597,11 +1773,21 @@ void DecLib::xActivateParameterSets( const InputNALUnit nalu )
     }
 #endif
 
+    m_apcSlicePilot->applyReferencePictureListBasedMarking( m_cListPic, m_apcSlicePilot->getRPL0(), m_apcSlicePilot->getRPL1(), layerId, *pps);
+
     //  Get a new picture buffer. This will also set up m_pcPic, and therefore give us a SPS and PPS pointer that we can use.
     m_pcPic = xGetNewPicBuffer( *sps, *pps, m_apcSlicePilot->getTLayer(), layerId );
 
-    m_apcSlicePilot->applyReferencePictureListBasedMarking( m_cListPic, m_apcSlicePilot->getRPL0(), m_apcSlicePilot->getRPL1(), layerId, *pps);
+#if GDR_ENABLED
+    PicHeader *picHeader = new PicHeader;
+    *picHeader = m_picHeader;
+    m_apcSlicePilot->setPicHeader(picHeader);
+    m_pcPic->finalInit(vps, *sps, *pps, picHeader, apss, lmcsAPS, scalinglistAPS);
+#else
     m_pcPic->finalInit( vps, *sps, *pps, &m_picHeader, apss, lmcsAPS, scalinglistAPS );
+#endif
+    m_pcPic->createColourTransfProcessor(m_firstPictureInSequence, &m_colourTranfParams, &m_invColourTransfBuf, pps->getPicWidthInLumaSamples(), pps->getPicHeightInLumaSamples(), sps->getChromaFormatIdc(), sps->getBitDepth(CHANNEL_TYPE_LUMA));
+    m_firstPictureInSequence = false;
     m_pcPic->createTempBuffers( m_pcPic->cs->pps->pcv->maxCUWidth );
     m_pcPic->cs->createCoeffs((bool)m_pcPic->cs->sps->getPLTMode());
 
@@ -1638,7 +1824,7 @@ void DecLib::xActivateParameterSets( const InputNALUnit nalu )
                    sps->getMaxCUWidth(), sps->getMaxCUHeight(),
                    maxDepth,
                    log2SaoOffsetScaleLuma, log2SaoOffsetScaleChroma );
-    m_cLoopFilter.create(maxDepth);
+    m_deblockingFilter.create(maxDepth);
     m_cIntraPred.init( sps->getChromaFormatIdc(), sps->getBitDepth( CHANNEL_TYPE_LUMA ) );
     m_cInterPred.init( &m_cRdCost, sps->getChromaFormatIdc(), sps->getMaxCUHeight() );
     if (sps->getUseLmcs())
@@ -1782,7 +1968,7 @@ void DecLib::xCheckParameterSetConstraints(const int layerId)
   const SPS *sps = slice->getSPS();
   const PPS *pps = slice->getPPS();
   const VPS *vps = slice->getVPS();
-  
+
   if (sps->getVPSId() && (vps != nullptr))
   {
     if ((layerId == vps->getLayerId(0)) && m_firstSliceInSequence[layerId])
@@ -1837,7 +2023,7 @@ void DecLib::xCheckParameterSetConstraints(const int layerId)
   {
     CHECK(sps->getSubPicInfoPresentFlag() != 0, "When sps_res_change_in_clvs_allowed_flag is equal to 1, the value of sps_subpic_info_present_flag shall be equal to 0.");
   }
-  CHECK(sps->getResChangeInClvsEnabledFlag() && sps->getVirtualBoundariesEnabledFlag(), "when the value of sps_res_change_in_clvs_allowed_flag is equal to 1, the value of sps_virtual_boundaries_present_flag shall be equal to 0");
+  CHECK(sps->getResChangeInClvsEnabledFlag() && sps->getVirtualBoundariesPresentFlag(), "when the value of sps_res_change_in_clvs_allowed_flag is equal to 1, the value of sps_virtual_boundaries_present_flag shall be equal to 0");
 
   if( sps->getCTUSize() + 2 * ( 1 << sps->getLog2MinCodingBlockSize() ) > pps->getPicWidthInLumaSamples() )
   {
@@ -1881,6 +2067,14 @@ void DecLib::xCheckParameterSetConstraints(const int layerId)
         CHECK(curLayerChromaFormat != refLayerChromaFormat, "The chroma formats of the current layer and the reference layer are different");
         int refLayerBitDepth = m_layerBitDepth[i];
         CHECK(curLayerBitDepth != refLayerBitDepth, "The bit-depth of the current layer and the reference layer are different");
+        if (vps->getMaxTidIlRefPicsPlus1(curLayerIdx, i) == 0 && pps->getMixedNaluTypesInPicFlag())
+        {
+          for (int j = 0; j < m_uiSliceSegmentIdx; j++)
+          {
+            Slice* preSlice = m_pcPic->slices[j];
+            CHECK( (preSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL || preSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP || preSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA), "mixed IRAP and non-IRAP NAL units in the picture when sps_video_parameter_set_id is greater than 0 and vps_max_tid_il_ref_pics_plus1[i][j] is equal to 0");
+          }
+        }
       }
     }
   }
@@ -1914,12 +2108,10 @@ void DecLib::xCheckParameterSetConstraints(const int layerId)
     CHECK(pps->getMixedNaluTypesInPicFlag(), "When gci_no_mixed_nalu_types_in_pic_constraint_flag equal to 1, the value of pps_mixed_nalu_types_in_pic_flag shall be equal to 0")
   }
 
-#if JVET_R0266_GCI
   if (sps->getProfileTierLevel()->getConstraintInfo()->getNoGdrConstraintFlag())
   {
     CHECK(sps->getGDREnabledFlag(), "gci_no_gdr_constraint_flag equal to 1 specifies that sps_gdr_enabled_flag for all pictures in OlsInScope shall be equal to 0");
   }
-#endif
 
   if (sps->getProfileTierLevel()->getConstraintInfo()->getNoRectSliceConstraintFlag())
   {
@@ -1988,7 +2180,7 @@ void DecLib::xCheckParameterSetConstraints(const int layerId)
   }
 
   if( sps->getVPSId() && vps->m_numLayersInOls[vps->m_targetOlsIdx] == 1 )
-  {    
+  {
     CHECK( !sps->getPtlDpbHrdParamsPresentFlag(), "When sps_video_parameter_set_id is greater than 0 and there is an OLS that contains only one layer with nuh_layer_id equal to the nuh_layer_id of the SPS, the value of sps_ptl_dpb_hrd_params_present_flag shall be equal to 1" );
   }
 
@@ -2069,6 +2261,7 @@ void DecLib::xParsePrefixSEImessages()
     }
   }
 #endif
+  xCheckDUISEIMessages(m_SEIs);
 }
 
 void DecLib::xCheckPrefixSEIMessages( SEIMessages& prefixSEIs )
@@ -2085,8 +2278,164 @@ void DecLib::xCheckPrefixSEIMessages( SEIMessages& prefixSEIs )
       msg( WARNING, "Warning: ffi_display_elemental_periods_minus1 is different in picture timing and frame field information SEI messages!");
     }
   }
+  if ((getVPS()->getMaxLayers() == 1 || m_audIrapOrGdrAuFlag) && (m_isFirstAuInCvs || m_accessUnitPicInfo.begin()->m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_N_LP || m_accessUnitPicInfo.begin()->m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_W_RADL || ((m_accessUnitPicInfo.begin()->m_nalUnitType == NAL_UNIT_CODED_SLICE_CRA || m_accessUnitPicInfo.begin()->m_nalUnitType == NAL_UNIT_CODED_SLICE_GDR) && m_lastNoOutputBeforeRecoveryFlag[m_accessUnitPicInfo.begin()->m_nuhLayerId])) && m_accessUnitPicInfo.size() == 1)
+  {
+    if (m_sdiSEIInFirstAU != NULL)
+    {
+      delete m_sdiSEIInFirstAU;
+    }
+    m_sdiSEIInFirstAU = NULL;
+    if (m_maiSEIInFirstAU != NULL)
+    {
+      delete m_maiSEIInFirstAU;
+    }
+    m_maiSEIInFirstAU = NULL;
+#if JVET_W0078_MVP_SEI 
+    if (m_mvpSEIInFirstAU != NULL) 
+    {
+      delete m_mvpSEIInFirstAU;
+    }
+    m_mvpSEIInFirstAU = NULL;
+#endif
+    SEIMessages sdiSEIs  = getSeisByType(prefixSEIs, SEI::SCALABILITY_DIMENSION_INFO);
+    if (!sdiSEIs.empty())
+    {
+      SEIScalabilityDimensionInfo *sdi = (SEIScalabilityDimensionInfo*)sdiSEIs.front();
+      m_sdiSEIInFirstAU = new SEIScalabilityDimensionInfo(*sdi);
+      if (sdiSEIs.size() > 1)
+      {
+        for (SEIMessages::const_iterator it=sdiSEIs.begin(); it!=sdiSEIs.end(); it++)
+        {
+          CHECK(!m_sdiSEIInFirstAU->isSDISameContent((SEIScalabilityDimensionInfo*)*it), "All SDI SEI messages in a CVS shall have the same content.")
+        }
+      }
+    }
+    SEIMessages maiSEIs  = getSeisByType(prefixSEIs, SEI::MULTIVIEW_ACQUISITION_INFO);
+    if (!maiSEIs.empty())
+    {
+      SEIMultiviewAcquisitionInfo *mai = (SEIMultiviewAcquisitionInfo*)maiSEIs.front();
+      m_maiSEIInFirstAU = new SEIMultiviewAcquisitionInfo(*mai);
+      if (maiSEIs.size() > 1)
+      {
+        for (SEIMessages::const_iterator it=maiSEIs.begin(); it!=maiSEIs.end(); it++)
+        {
+          CHECK(!m_maiSEIInFirstAU->isMAISameContent((SEIMultiviewAcquisitionInfo*)*it), "All MAI SEI messages in a CVS shall have the same content.")
+        }
+      }
+    }
+#if JVET_W0078_MVP_SEI 
+    SEIMessages mvpSEIs = getSeisByType(prefixSEIs, SEI::MULTIVIEW_VIEW_POSITION);
+    if (!mvpSEIs.empty())
+    {
+      SEIMultiviewViewPosition *mvp = (SEIMultiviewViewPosition*)mvpSEIs.front();
+      m_mvpSEIInFirstAU = new SEIMultiviewViewPosition(*mvp);
+      if (mvpSEIs.size() > 1)
+      {
+        for (SEIMessages::const_iterator it = mvpSEIs.begin(); it != mvpSEIs.end(); it++)
+        {
+          CHECK(!m_mvpSEIInFirstAU->isMVPSameContent((SEIMultiviewViewPosition*)*it), "All MVP SEI messages in a CVS shall have the same content.")
+        }
+      }
+    }
+#endif
+  }
+  else
+  {
+    SEIMessages sdiSEIs  = getSeisByType(prefixSEIs, SEI::SCALABILITY_DIMENSION_INFO);
+    CHECK(!m_sdiSEIInFirstAU && !sdiSEIs.empty(), "When an SDI SEI message is present in any AU of a CVS, an SDI SEI message shall be present for the first AU of the CVS.");
+    if (!sdiSEIs.empty())
+    {
+      for (SEIMessages::const_iterator it=sdiSEIs.begin(); it!=sdiSEIs.end(); it++)
+      {
+        CHECK(!m_sdiSEIInFirstAU->isSDISameContent((SEIScalabilityDimensionInfo*)*it), "All SDI SEI messages in a CVS shall have the same content.")
+      }
+    }
+    SEIMessages maiSEIs  = getSeisByType(prefixSEIs, SEI::MULTIVIEW_ACQUISITION_INFO);
+    CHECK(!m_maiSEIInFirstAU && !maiSEIs.empty(), "When an MAI SEI message is present in any AU of a CVS, an MAI SEI message shall be present for the first AU of the CVS.");
+    if (!maiSEIs.empty())
+    {
+      for (SEIMessages::const_iterator it=maiSEIs.begin(); it!=maiSEIs.end(); it++)
+      {
+        CHECK(!m_maiSEIInFirstAU->isMAISameContent((SEIMultiviewAcquisitionInfo*)*it), "All MAI SEI messages in a CVS shall have the same content.")
+      }
+    }
+#if JVET_W0078_MVP_SEI 
+    SEIMessages mvpSEIs = getSeisByType(prefixSEIs, SEI::MULTIVIEW_VIEW_POSITION);
+    CHECK(!m_mvpSEIInFirstAU && !mvpSEIs.empty(), "When an MVP SEI message is present in any AU of a CVS, an MVP SEI message shall be present for the first AU of the CVS.");
+    if (!mvpSEIs.empty())
+    {
+      for (SEIMessages::const_iterator it = mvpSEIs.begin(); it != mvpSEIs.end(); it++)
+      {
+        CHECK(!m_mvpSEIInFirstAU->isMVPSameContent((SEIMultiviewViewPosition*)*it), "All MVP SEI messages in a CVS shall have the same content.")
+      }
+    }
+#endif
+  }
+
+  for (SEIMessages::const_iterator it=prefixSEIs.begin(); it!=prefixSEIs.end(); it++)
+  {
+    if ((*it)->payloadType() == SEI::MULTIVIEW_ACQUISITION_INFO)
+    {
+      CHECK(!m_sdiSEIInFirstAU, "When a CVS does not contain an SDI SEI message, the CVS shall not contain an MAI SEI message.");
+      SEIMultiviewAcquisitionInfo *maiSei = (SEIMultiviewAcquisitionInfo*)*it;
+      CHECK(m_sdiSEIInFirstAU->m_sdiNumViews - 1 != maiSei->m_maiNumViewsMinus1, "The value of num_views_minus1 shall be equal to NumViews - 1");
+    }
+    else if ((*it)->payloadType() == SEI::ALPHA_CHANNEL_INFO)
+    {
+      CHECK(!m_sdiSEIInFirstAU, "When a CVS does not contain an SDI SEI message with sdi_aux_id[i] equal to 1 for at least one value of i, no picture in the CVS shall be associated with an ACI SEI message.");
+    }
+    else if ((*it)->payloadType() == SEI::DEPTH_REPRESENTATION_INFO)
+    {
+      CHECK(!m_sdiSEIInFirstAU, "When a CVS does not contain an SDI SEI message with sdi_aux_id[i] equal to 2 for at least one value of i, no picture in the CVS shall be associated with a DRI SEI message.");
+    }
+#if JVET_W0078_MVP_SEI
+    else if ((*it)->payloadType() == SEI::MULTIVIEW_VIEW_POSITION)
+    {
+      CHECK(!m_sdiSEIInFirstAU, "When a CVS does not contain an SDI SEI message, the CVS shall not contain an MVP SEI message.");
+      SEIMultiviewViewPosition *mvpSei = (SEIMultiviewViewPosition*)*it;
+      CHECK(m_sdiSEIInFirstAU->m_sdiNumViews - 1 != mvpSei->m_mvpNumViewsMinus1, "The value of num_views_minus1 shall be equal to NumViews - 1");
+    }
+#endif
+  }
 }
 
+void DecLib::xCheckDUISEIMessages(SEIMessages &prefixSEIs)
+{
+  SEIMessages BPSEIs  = getSeisByType(prefixSEIs, SEI::BUFFERING_PERIOD);
+  SEIMessages DUISEIs = getSeisByType(prefixSEIs, SEI::DECODING_UNIT_INFO);
+  if (BPSEIs.empty())
+  {
+    return;
+  }
+  else
+  {
+    bool duDelayFlag = false;
+
+    SEIBufferingPeriod *bp = (SEIBufferingPeriod *) BPSEIs.front();
+    if (bp->m_bpDecodingUnitHrdParamsPresentFlag)
+    {
+      if (!bp->m_decodingUnitDpbDuParamsInPicTimingSeiFlag)
+      {
+        if (DUISEIs.empty())
+        {
+          return;
+        }
+        for (auto it = DUISEIs.cbegin(); it != DUISEIs.cend(); ++it)
+        {
+          const SEIDecodingUnitInfo *dui = (const SEIDecodingUnitInfo *) *it;
+          if (dui->m_picSptDpbOutputDuDelay != -1)
+          {
+            duDelayFlag = true;
+            break;
+          }
+        }
+        CHECK(duDelayFlag == false, "At least one DUI SEI should have dui->m_picSptDpbOutputDuDelay not equal to -1")
+      }
+    }
+  }
+}
+
+
 void DecLib::xDecodePicHeader( InputNALUnit& nalu )
 {
   m_HLSReader.setBitstream( &nalu.getBitstream() );
@@ -2094,6 +2443,19 @@ void DecLib::xDecodePicHeader( InputNALUnit& nalu )
   m_picHeader.setValid();
 }
 
+bool DecLib::getMixedNaluTypesInPicFlag()
+{
+  if (!m_picHeader.isValid())
+  {
+    return false;
+  }
+
+  PPS *pps = m_parameterSetManager.getPPS(m_picHeader.getPPSId());
+  CHECK(pps == 0, "No PPS present");
+
+  return pps->getMixedNaluTypesInPicFlag();
+}
+
 bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDisplay )
 {
   m_apcSlicePilot->setPicHeader( &m_picHeader );
@@ -2119,9 +2481,7 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl
   for( auto& naluTemporalId : m_accessUnitNals )
   {
     if (
-#if JVET_S0163_ON_TARGETOLS_SUBLAYERS
       naluTemporalId.m_nalUnitType != NAL_UNIT_OPI &&
-#endif
       naluTemporalId.m_nalUnitType != NAL_UNIT_DCI
       && naluTemporalId.m_nalUnitType != NAL_UNIT_VPS
       && naluTemporalId.m_nalUnitType != NAL_UNIT_SPS
@@ -2147,6 +2507,11 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl
     m_accessUnitNoOutputPriorPicFlags.push_back(m_apcSlicePilot->getNoOutputOfPriorPicsFlag());
   }
 
+  if (m_picHeader.getGdrPicFlag() && m_prevGDRInSameLayerPOC[nalu.m_nuhLayerId] == -MAX_INT ) // Only care about recovery POC if it is the first coded GDR picture in the layer
+  {
+    m_prevGDRInSameLayerRecoveryPOC[nalu.m_nuhLayerId] = m_apcSlicePilot->getPOC() + m_picHeader.getRecoveryPocCnt();
+  }
+
   PPS *pps = m_parameterSetManager.getPPS(m_picHeader.getPPSId());
   CHECK(pps == 0, "No PPS present");
   SPS *sps = m_parameterSetManager.getSPS(pps->getSPSId());
@@ -2264,6 +2629,10 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl
         m_picHeader.setNoOutputBeforeRecoveryFlag( m_picHeader.getHandleGdrAsCvsStartFlag() );
       }
     }
+    else
+    {
+      m_picHeader.setNoOutputBeforeRecoveryFlag( false );
+    }
 
     //the inference for NoOutputOfPriorPicsFlag
     if( !m_firstSliceInBitstream && m_picHeader.getNoOutputBeforeRecoveryFlag() )
@@ -2343,14 +2712,17 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl
 
   // Skip pictures due to random access
 
-  if (isRandomAccessSkipPicture(iSkipFrame, iPOCLastDisplay))
+  if (isRandomAccessSkipPicture(iSkipFrame, iPOCLastDisplay, pps->getMixedNaluTypesInPicFlag(), nalu.m_nuhLayerId))
   {
     m_prevSliceSkipped = true;
     m_skippedPOC = m_apcSlicePilot->getPOC();
+    m_skippedLayerID = nalu.m_nuhLayerId;
+
     // reset variables for bitstream conformance tests
     resetAccessUnitNals();
     resetAccessUnitApsNals();
     resetAccessUnitPicInfo();
+    resetPictureUnitNals();
     m_maxDecSubPicIdx = 0;
     m_maxDecSliceAddrInSubPic = -1;
     return false;
@@ -2389,13 +2761,13 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl
     int refPicIndex;
     while ((lostPoc = m_apcSlicePilot->checkThatAllRefPicsAreAvailable(m_cListPic, m_apcSlicePilot->getRPL0(), 0, true, &refPicIndex, m_apcSlicePilot->getNumRefIdx(REF_PIC_LIST_0))) > 0)
     {
-      if( !pps->getMixedNaluTypesInPicFlag() && ( 
+      if( !pps->getMixedNaluTypesInPicFlag() && (
       ( ( m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL || m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP ) && ( sps->getIDRRefParamListPresent() || pps->getRplInfoInPhFlag() ) ) ||
-        ( ( m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR || m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA ) && m_picHeader.getNoOutputBeforeRecoveryFlag() ) ) ) 
+        ( ( m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR || m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA ) && m_picHeader.getNoOutputBeforeRecoveryFlag() ) ) )
       {
         if (m_apcSlicePilot->getRPL0()->isInterLayerRefPic(refPicIndex) == 0)
         {
-          xCreateUnavailablePicture( m_apcSlicePilot->getPPS(), lostPoc - 1, m_apcSlicePilot->getRPL0()->isRefPicLongterm( refPicIndex ), m_apcSlicePilot->getPic()->temporalId, m_apcSlicePilot->getPic()->layerId, m_apcSlicePilot->getRPL0()->isInterLayerRefPic( refPicIndex ) );
+          xCreateUnavailablePicture( pps, lostPoc, m_apcSlicePilot->getRPL0()->isRefPicLongterm( refPicIndex ), m_apcSlicePilot->getTLayer(), m_apcSlicePilot->getNalUnitLayerId(), m_apcSlicePilot->getRPL0()->isInterLayerRefPic( refPicIndex ) );
         }
       }
       else
@@ -2405,13 +2777,13 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl
     }
     while ((lostPoc = m_apcSlicePilot->checkThatAllRefPicsAreAvailable(m_cListPic, m_apcSlicePilot->getRPL1(), 0, true, &refPicIndex, m_apcSlicePilot->getNumRefIdx(REF_PIC_LIST_1))) > 0)
     {
-      if( !pps->getMixedNaluTypesInPicFlag() && ( 
+      if( !pps->getMixedNaluTypesInPicFlag() && (
         ( ( m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL || m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP ) && ( sps->getIDRRefParamListPresent() || pps->getRplInfoInPhFlag() ) ) ||
         ( ( m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR || m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA ) && m_picHeader.getNoOutputBeforeRecoveryFlag() ) ) )
       {
         if (m_apcSlicePilot->getRPL1()->isInterLayerRefPic(refPicIndex) == 0)
         {
-          xCreateUnavailablePicture( m_apcSlicePilot->getPPS(), lostPoc - 1, m_apcSlicePilot->getRPL1()->isRefPicLongterm( refPicIndex ), m_apcSlicePilot->getPic()->temporalId, m_apcSlicePilot->getPic()->layerId, m_apcSlicePilot->getRPL1()->isInterLayerRefPic( refPicIndex ) );
+          xCreateUnavailablePicture( pps, lostPoc, m_apcSlicePilot->getRPL1()->isRefPicLongterm( refPicIndex ), m_apcSlicePilot->getTLayer(), m_apcSlicePilot->getNalUnitLayerId(), m_apcSlicePilot->getRPL1()->isInterLayerRefPic( refPicIndex ) );
         }
       }
       else
@@ -2443,9 +2815,20 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl
   m_pcPic->layerId     = nalu.m_nuhLayerId;
   m_pcPic->subLayerNonReferencePictureDueToSTSA = false;
 
+  if (pcSlice->getSPS()->getSpsRangeExtension().getRrcRiceExtensionEnableFlag())
+  {
+    int bitDepth = pcSlice->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA);
+    int baseLevel = (bitDepth > 12) ? (pcSlice->isIntra() ? 5 : 2 * 5 ) : (pcSlice->isIntra() ? 2 * 5 : 3 * 5);
+    pcSlice->setRiceBaseLevel(baseLevel);
+  }
+  else
+  {
+    pcSlice->setRiceBaseLevel(4);
+  }
+
   if (pcSlice->getSPS()->getProfileTierLevel()->getConstraintInfo()->getNoApsConstraintFlag())
   {
-    bool flag = pcSlice->getSPS()->getCCALFEnabledFlag() || pcSlice->getPicHeader()->getNumAlfAps() || pcSlice->getPicHeader()->getAlfEnabledFlag(COMPONENT_Cb) || pcSlice->getPicHeader()->getAlfEnabledFlag(COMPONENT_Cr);
+    bool flag = pcSlice->getSPS()->getCCALFEnabledFlag() || pcSlice->getPicHeader()->getNumAlfApsIdsLuma() || pcSlice->getPicHeader()->getAlfEnabledFlag(COMPONENT_Cb) || pcSlice->getPicHeader()->getAlfEnabledFlag(COMPONENT_Cr);
     CHECK(flag, "When no_aps_constraint_flag is equal to 1, the values of ph_num_alf_aps_ids_luma, sh_num_alf_aps_ids_luma, ph_alf_cb_flag, ph_alf_cr_flag, sh_alf_cb_flag, sh_alf_cr_flag, and sps_ccalf_enabled_flag shall all be equal to 0")
   }
   if( pcSlice->getNalUnitLayerId() != pcSlice->getSPS()->getLayerId() )
@@ -2525,8 +2908,12 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl
     CU::checkConformanceILRP(pcSlice);
   }
 
+#if GDR_ENABLED
+  PicHeader *picHeader = nullptr; // picHeader is not necessary for scaledReference picture at decoder but should not share picHeader with non-scaled picture
+  pcSlice->scaleRefPicList(scaledRefPic, picHeader, m_parameterSetManager.getAPSs(), m_picHeader.getLmcsAPS(), m_picHeader.getScalingListAPS(), true);
+#else
   pcSlice->scaleRefPicList( scaledRefPic, m_pcPic->cs->picHeader, m_parameterSetManager.getAPSs(), m_picHeader.getLmcsAPS(), m_picHeader.getScalingListAPS(), true );
-
+#endif
 
     if (!pcSlice->isIntra())
     {
@@ -2655,6 +3042,23 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl
       pcSlice->setLatestDRAPPOC(pcSlice->getPOC());
     }
     pcSlice->checkConformanceForDRAP(nalu.m_temporalId);
+    if (pcSlice->isIntra())
+      pcSlice->getPic()->setEdrapRapId(0);
+    SEIMessages edrapSEIs = getSeisByType(m_pcPic->SEIs, SEI::EXTENDED_DRAP_INDICATION );
+    if (!edrapSEIs.empty())
+    {
+      msg( NOTICE, "Extended DRAP indication SEI decoded\n");
+      SEIExtendedDrapIndication *seiEdrap = (SEIExtendedDrapIndication *)edrapSEIs.front();
+      pcSlice->setEdrapRapId(seiEdrap->m_edrapIndicationRapIdMinus1 + 1);
+      pcSlice->getPic()->setEdrapRapId(seiEdrap->m_edrapIndicationRapIdMinus1 + 1);
+      pcSlice->setEdrapNumRefRapPics(seiEdrap->m_edrapIndicationNumRefRapPicsMinus1 + 1);
+      for (int i = 0; i < pcSlice->getEdrapNumRefRapPics(); i++)
+      {
+        pcSlice->addEdrapRefRapIds(seiEdrap->m_edrapIndicationRefRapId[i]);
+      }
+      pcSlice->setLatestEDRAPPOC(pcSlice->getPOC());
+    }
+    pcSlice->checkConformanceForEDRAP(nalu.m_temporalId);
 
   Quant *quant = m_cTrQuant.getQuant();
 
@@ -2781,6 +3185,26 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl
     m_cReshaper.setRecReshaped(false);
   }
 
+#if GDR_LEAK_TEST
+  if (m_gdrPocRandomAccess == pcSlice->getPOC())
+  {
+    for (int e = 0; e < 2; e++)
+    {
+      for (int ridx = 0; ridx < pcSlice->getNumRefIdx((RefPicList)e); ridx++)
+      {
+        Picture *pic = pcSlice->getRefPic((RefPicList)e, ridx);
+        if (pic)
+        {
+          CodingStructure& cs = *pic->cs;
+          cs.getRecoBuf().Y().fill(0 * 4); // for 8-bit sequence
+          cs.getRecoBuf().Cb().fill(0 * 4);
+          cs.getRecoBuf().Cr().fill(0 * 4);
+          cs.getMotionBuf().memset(0);    // clear MV storage
+        }
+      }
+    }
+  }
+#endif // GDR_LEAK_TEST
   //  Decode a picture
   m_cSliceDecoder.decompressSlice( pcSlice, &( nalu.getBitstream() ), ( m_pcPic->poc == getDebugPOC() ? getDebugCTU() : -1 ) );
 
@@ -2837,7 +3261,6 @@ void DecLib::updatePrevIRAPAndGDRSubpic()
   }
 }
 
-#if JVET_S0163_ON_TARGETOLS_SUBLAYERS
 void DecLib::xDecodeOPI( InputNALUnit& nalu )
 {
   m_opi = new OPI();
@@ -2847,7 +3270,6 @@ void DecLib::xDecodeOPI( InputNALUnit& nalu )
 
   m_HLSReader.parseOPI( m_opi );
 }
-#endif
 
 void DecLib::xDecodeVPS( InputNALUnit& nalu )
 {
@@ -2929,7 +3351,12 @@ void DecLib::xDecodeAPS(InputNALUnit& nalu)
   {
     APS* apsEnc = new APS();
     *apsEnc = *aps;
-    m_apsMapEnc->storePS( ( apsEnc->getAPSId() << NUM_APS_TYPE_LEN ) + apsEnc->getAPSType(), apsEnc ); 
+    m_apsMapEnc->storePS( ( apsEnc->getAPSId() << NUM_APS_TYPE_LEN ) + apsEnc->getAPSType(), apsEnc );
+  }
+
+  if( nalu.m_nalUnitType == NAL_UNIT_SUFFIX_APS && m_prevSliceSkipped )
+  {
+    m_accessUnitApsNals.pop_back();
   }
 
   // aps will be deleted if it was already stored (and did not changed),
@@ -2940,18 +3367,27 @@ bool DecLib::decode(InputNALUnit& nalu, int& iSkipFrame, int& iPOCLastDisplay, i
 {
   bool ret;
   // ignore all NAL units of layers > 0
-
-  AccessUnitInfo auInfo;
-  auInfo.m_nalUnitType = nalu.m_nalUnitType;
-  auInfo.m_nuhLayerId = nalu.m_nuhLayerId;
-  auInfo.m_temporalId = nalu.m_temporalId;
-  m_accessUnitNals.push_back(auInfo);
-  m_pictureUnitNals.push_back( nalu.m_nalUnitType );
+  if( (nalu.m_nalUnitType != NAL_UNIT_SUFFIX_APS       &&
+       nalu.m_nalUnitType != NAL_UNIT_EOS              &&
+       nalu.m_nalUnitType != NAL_UNIT_EOB              &&
+       nalu.m_nalUnitType != NAL_UNIT_SUFFIX_SEI       &&
+       nalu.m_nalUnitType != NAL_UNIT_FD               &&
+       nalu.m_nalUnitType != NAL_UNIT_RESERVED_NVCL_27 &&
+       nalu.m_nalUnitType != NAL_UNIT_UNSPECIFIED_30   &&
+       nalu.m_nalUnitType != NAL_UNIT_UNSPECIFIED_31)  ||
+       !m_prevSliceSkipped )
+  {
+    AccessUnitInfo auInfo;
+    auInfo.m_nalUnitType = nalu.m_nalUnitType;
+    auInfo.m_nuhLayerId = nalu.m_nuhLayerId;
+    auInfo.m_temporalId = nalu.m_temporalId;
+    m_accessUnitNals.push_back(auInfo);
+    m_pictureUnitNals.push_back( nalu.m_nalUnitType );
+  }
   switch (nalu.m_nalUnitType)
   {
     case NAL_UNIT_VPS:
       xDecodeVPS( nalu );
-#if JVET_S0163_ON_TARGETOLS_SUBLAYERS
       if (getTOlsIdxExternalFlag())
       {
         m_vps->m_targetOlsIdx = iTargetOlsIdx;
@@ -2964,15 +3400,10 @@ bool DecLib::decode(InputNALUnit& nalu, int& iSkipFrame, int& iPOCLastDisplay, i
       {
         m_vps->m_targetOlsIdx = m_vps->deriveTargetOLSIdx();
       }
-#else
-      m_vps->m_targetOlsIdx = iTargetOlsIdx;
-#endif
       return false;
-#if JVET_S0163_ON_TARGETOLS_SUBLAYERS
     case NAL_UNIT_OPI:
       xDecodeOPI( nalu );
       return false;
-#endif
     case NAL_UNIT_DCI:
       xDecodeDCI( nalu );
       return false;
@@ -2989,10 +3420,20 @@ bool DecLib::decode(InputNALUnit& nalu, int& iSkipFrame, int& iPOCLastDisplay, i
       return !m_bFirstSliceInPicture;
 
     case NAL_UNIT_PREFIX_APS:
-    case NAL_UNIT_SUFFIX_APS:
       xDecodeAPS(nalu);
       return false;
 
+    case NAL_UNIT_SUFFIX_APS:
+      if( m_prevSliceSkipped )
+      {
+        xDecodeAPS(nalu);
+      }
+      else
+      {
+        m_suffixApsNalus.push_back(new InputNALUnit(nalu));
+      }
+      return false;
+
     case NAL_UNIT_PREFIX_SEI:
       // Buffer up prefix SEI messages until SPS of associated VCL is known.
       m_prefixSEINALUs.push_back(new InputNALUnit(nalu));
@@ -3002,6 +3443,11 @@ bool DecLib::decode(InputNALUnit& nalu, int& iSkipFrame, int& iPOCLastDisplay, i
     case NAL_UNIT_SUFFIX_SEI:
       if (m_pcPic)
       {
+        if ( m_prevSliceSkipped )
+        {
+          msg( NOTICE, "Note: received suffix SEI but current picture is skipped.\n");
+          return false;
+        }
         m_pictureSeiNalus.push_back(new InputNALUnit(nalu));
         m_accessUnitSeiTids.push_back(nalu.m_temporalId);
         const SPS *sps = m_parameterSetManager.getActiveSPS();
@@ -3033,6 +3479,7 @@ bool DecLib::decode(InputNALUnit& nalu, int& iSkipFrame, int& iPOCLastDisplay, i
       m_associatedIRAPType[nalu.m_nuhLayerId] = NAL_UNIT_INVALID;
       m_pocCRA[nalu.m_nuhLayerId] = -MAX_INT;
       m_prevGDRInSameLayerPOC[nalu.m_nuhLayerId] = -MAX_INT;
+      m_prevGDRInSameLayerRecoveryPOC[nalu.m_nuhLayerId] = -MAX_INT;
       std::fill_n(m_prevGDRSubpicPOC[nalu.m_nuhLayerId], MAX_NUM_SUB_PICS, -MAX_INT);
       std::fill_n(m_prevIRAPSubpicPOC[nalu.m_nuhLayerId], MAX_NUM_SUB_PICS, -MAX_INT);
       memset(m_prevIRAPSubpicDecOrderNo[nalu.m_nuhLayerId], 0, sizeof(int)*MAX_NUM_SUB_PICS);
@@ -3067,9 +3514,6 @@ bool DecLib::decode(InputNALUnit& nalu, int& iSkipFrame, int& iPOCLastDisplay, i
     }
 
     case NAL_UNIT_RESERVED_IRAP_VCL_11:
-#if !JVET_S0163_ON_TARGETOLS_SUBLAYERS
-    case NAL_UNIT_RESERVED_IRAP_VCL_12:
-#endif
       msg( NOTICE, "Note: found reserved VCL NAL unit.\n");
       xParsePrefixSEIsForUnknownVCLNal();
       return false;
@@ -3104,11 +3548,22 @@ bool DecLib::decode(InputNALUnit& nalu, int& iSkipFrame, int& iPOCLastDisplay, i
  *  equal to or greater than the random access point POC is attempted. For non IDR/CRA/BLA random
  *  access point there is no guarantee that the decoder will not crash.
  */
-bool DecLib::isRandomAccessSkipPicture( int& iSkipFrame, int& iPOCLastDisplay )
+bool DecLib::isRandomAccessSkipPicture( int& iSkipFrame, int& iPOCLastDisplay, bool mixedNaluInPicFlag, uint32_t layerId )
 {
+  if( (iSkipFrame > 0) &&
+      (m_apcSlicePilot->getFirstCtuRsAddrInSlice() == 0 && layerId == 0) &&
+      (m_skippedPOC != MAX_INT) && (m_skippedLayerID != MAX_INT))
+  {
+    // When skipFrame count greater than 0, and current frame is not the first frame of sequence, decrement skipFrame count.
+    // If skipFrame count is still greater than 0, the current frame will be skipped.
+    iSkipFrame--;
+  }
+
   if (iSkipFrame)
   {
     iSkipFrame--;   // decrement the counter
+    m_maxDecSubPicIdx = 0;
+    m_maxDecSliceAddrInSubPic = -1;
     return true;
   }
   else if ( m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL || m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP )
@@ -3117,7 +3572,7 @@ bool DecLib::isRandomAccessSkipPicture( int& iSkipFrame, int& iPOCLastDisplay )
   }
   else if (m_pocRandomAccess == MAX_INT) // start of random access point, m_pocRandomAccess has not been set yet.
   {
-    if (m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA )
+    if (m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA || m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR )
     {
       // set the POC random access since we need to skip the reordered pictures in the case of CRA/CRANT/BLA/BLANT.
       m_pocRandomAccess = m_apcSlicePilot->getPOC();
@@ -3126,16 +3581,24 @@ bool DecLib::isRandomAccessSkipPicture( int& iSkipFrame, int& iPOCLastDisplay )
     {
       if(!m_warningMessageSkipPicture)
       {
-        msg( WARNING, "\nWarning: this is not a valid random access point and the data is discarded until the first CRA picture");
+        msg( WARNING, "Warning: This is not a valid random access point and the data is discarded until the first CRA or GDR picture\n");
         m_warningMessageSkipPicture = true;
       }
+      iSkipFrame--;
+      m_maxDecSubPicIdx = 0;
+      m_maxDecSliceAddrInSubPic = -1;
       return true;
     }
   }
   // skip the reordered pictures, if necessary
-  else if (m_apcSlicePilot->getPOC() < m_pocRandomAccess && (m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_RASL))
+  else if (m_apcSlicePilot->getPOC() < m_pocRandomAccess &&
+      (m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_RASL ||
+       mixedNaluInPicFlag))
   {
     iPOCLastDisplay++;
+    iSkipFrame--;
+    m_maxDecSubPicIdx = 0;
+    m_maxDecSliceAddrInSubPic = -1;
     return true;
   }
   // if we reach here, then the picture is not skipped.
@@ -3149,7 +3612,6 @@ void DecLib::checkNalUnitConstraints( uint32_t naluType )
     const ConstraintInfo *cInfo = m_parameterSetManager.getActiveSPS()->getProfileTierLevel()->getConstraintInfo();
     xCheckNalUnitConstraintFlags( cInfo, naluType );
   }
-
 }
 void DecLib::xCheckNalUnitConstraintFlags( const ConstraintInfo *cInfo, uint32_t naluType )
 {
@@ -3264,9 +3726,7 @@ bool DecLib::isNewPicture(std::ifstream *bitstreamFile, class InputByteStream *b
 
       // NUT that indicate the start of a new picture
       case NAL_UNIT_ACCESS_UNIT_DELIMITER:
-#if JVET_S0163_ON_TARGETOLS_SUBLAYERS
       case NAL_UNIT_OPI:
-#endif
       case NAL_UNIT_DCI:
       case NAL_UNIT_VPS:
       case NAL_UNIT_SPS:
@@ -3289,9 +3749,6 @@ bool DecLib::isNewPicture(std::ifstream *bitstreamFile, class InputByteStream *b
       case NAL_UNIT_CODED_SLICE_CRA:
       case NAL_UNIT_CODED_SLICE_GDR:
       case NAL_UNIT_RESERVED_IRAP_VCL_11:
-#if !JVET_S0163_ON_TARGETOLS_SUBLAYERS
-      case NAL_UNIT_RESERVED_IRAP_VCL_12:
-#endif
         ret = checkPictureHeaderInSliceHeaderFlag(nalu);
         finished = true;
         break;
diff --git a/source/Lib/DecoderLib/DecLib.h b/source/Lib/DecoderLib/DecLib.h
index 6b89a8f4c..5e6192754 100644
--- a/source/Lib/DecoderLib/DecLib.h
+++ b/source/Lib/DecoderLib/DecLib.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -49,7 +49,7 @@
 #include "CommonLib/TrQuant.h"
 #include "CommonLib/InterPrediction.h"
 #include "CommonLib/IntraPrediction.h"
-#include "CommonLib/LoopFilter.h"
+#include "CommonLib/DeblockingFilter.h"
 #include "CommonLib/AdaptiveLoopFilter.h"
 #include "CommonLib/SEI.h"
 #include "CommonLib/Unit.h"
@@ -73,6 +73,7 @@ private:
   GeneralHrdParams        m_prevGeneralHrdParams;
 
   int                     m_prevGDRInSameLayerPOC[MAX_VPS_LAYERS]; ///< POC number of the latest GDR picture
+  int                     m_prevGDRInSameLayerRecoveryPOC[MAX_VPS_LAYERS]; ///< Recovery POC number of the latest GDR picture
   NalUnitType             m_associatedIRAPType[MAX_VPS_LAYERS]; ///< NAL unit type of the previous IRAP picture
   int                     m_pocCRA[MAX_VPS_LAYERS];            ///< POC number of the previous CRA picture
   int                     m_associatedIRAPDecodingOrderNumber[MAX_VPS_LAYERS]; ///< Decoding order number of the previous IRAP picture
@@ -94,7 +95,11 @@ private:
 
 
   SEIMessages             m_SEIs; ///< List of SEI messages that have been received before the first slice and between slices, excluding prefix SEIs...
-
+  SEIScalabilityDimensionInfo* m_sdiSEIInFirstAU;
+  SEIMultiviewAcquisitionInfo* m_maiSEIInFirstAU;
+#if JVET_W0078_MVP_SEI 
+  SEIMultiviewViewPosition*    m_mvpSEIInFirstAU;
+#endif
 
   // functional classes
   IntraPrediction         m_cIntraPred;
@@ -109,7 +114,7 @@ private:
 #if JVET_S0257_DUMP_360SEI_MESSAGE
   SeiCfgFileDump          m_seiCfgDump;
 #endif
-  LoopFilter              m_cLoopFilter;
+  DeblockingFilter        m_deblockingFilter;
   SampleAdaptiveOffset    m_cSAO;
   AdaptiveLoopFilter      m_cALF;
   Reshape                 m_cReshaper;                        ///< reshaper class
@@ -119,7 +124,7 @@ private:
 #if JVET_J0090_MEMORY_BANDWITH_MEASURE
   CacheModel              m_cacheModel;
 #endif
-  bool isRandomAccessSkipPicture(int& iSkipFrame,  int& iPOCLastDisplay);
+  bool isRandomAccessSkipPicture(int& iSkipFrame, int& iPOCLastDisplay, bool mixedNaluInPicFlag, uint32_t layerId);
   Picture*                m_pcPic;
   uint32_t                m_uiSliceSegmentIdx;
   uint32_t                m_prevLayerID;
@@ -127,12 +132,16 @@ private:
   int                     m_prevPicPOC;
   int                     m_prevTid0POC;
   bool                    m_bFirstSliceInPicture;
+  bool                    m_firstPictureInSequence;
+  SEIColourTransformApply m_colourTranfParams;
+  PelStorage              m_invColourTransfBuf;
   bool                    m_firstSliceInSequence[MAX_VPS_LAYERS];
   bool                    m_firstSliceInBitstream;
   bool                    m_isFirstAuInCvs;
   bool                    m_accessUnitEos[MAX_VPS_LAYERS];
   bool                    m_prevSliceSkipped;
   int                     m_skippedPOC;
+  uint32_t                m_skippedLayerID;
   int                     m_lastPOCNoOutputPriorPics;
   bool                    m_isNoOutputPriorPics;
   bool                    m_lastNoOutputBeforeRecoveryFlag[MAX_VPS_LAYERS];    //value of variable NoOutputBeforeRecoveryFlag of the assocated CRA/GDR pic
@@ -195,14 +204,13 @@ private:
 
   std::vector<NalUnitType> m_pictureUnitNals;
   std::list<InputNALUnit*> m_pictureSeiNalus; 
+  std::list<InputNALUnit*> m_suffixApsNalus; 
 
-#if JVET_S0163_ON_TARGETOLS_SUBLAYERS
   OPI*                    m_opi;
   bool                    m_mTidExternalSet;
   bool                    m_mTidOpiSet;
   bool                    m_tOlsIdxTidExternalSet;
   bool                    m_tOlsIdxTidOpiSet;
-#endif
   VPS*                    m_vps;
   int                     m_maxDecSubPicIdx;
   int                     m_maxDecSliceAddrInSubPic;
@@ -213,6 +221,11 @@ public:
 
   DCI*                    m_dci;
   ParameterSetMap<APS>*   m_apsMapEnc;
+#if GDR_LEAK_TEST
+public:
+  int                     m_gdrPocRandomAccess;
+#endif // GDR_LEAK_TEST
+
 public:
   DecLib();
   virtual ~DecLib();
@@ -239,10 +252,8 @@ public:
   void  updateAssociatedIRAP();
   void  updatePrevGDRInSameLayer();
   void  updatePrevIRAPAndGDRSubpic();
+  bool  getGDRRecoveryPocReached()          { return ( m_pcPic->getPOC() >= m_prevGDRInSameLayerRecoveryPOC[m_pcPic->layerId] ); }
 
-#if JVET_S0078_NOOUTPUTPRIORPICFLAG
-  bool  getAudIrapOrGdrAuFlag() const       { return m_audIrapOrGdrAuFlag;  }
-#endif
   bool  getNoOutputPriorPicsFlag () const   { return m_isNoOutputPriorPics; }
   void  setNoOutputPriorPicsFlag (bool val) { m_isNoOutputPriorPics = val; }
   void  setFirstSliceInPicture (bool val)  { m_bFirstSliceInPicture = val; }
@@ -279,6 +290,7 @@ public:
   void checkSeiInPictureUnit();
   void resetPictureSeiNalus();
   bool isSliceNaluFirstInAU( bool newPicture, InputNALUnit &nalu );
+  void processSuffixApsNalus();
 
   void checkAPSInPictureUnit();
   void resetPictureUnitNals() { m_pictureUnitNals.clear(); }
@@ -295,7 +307,6 @@ public:
   bool  isNewPicture( std::ifstream *bitstreamFile, class InputByteStream *bytestream );
   bool  isNewAccessUnit( bool newPicture, std::ifstream *bitstreamFile, class InputByteStream *bytestream );
 
-#if JVET_S0163_ON_TARGETOLS_SUBLAYERS
   bool      getHTidExternalSetFlag()               const { return m_mTidExternalSet; }
   void      setHTidExternalSetFlag(bool mTidExternalSet)  { m_mTidExternalSet = mTidExternalSet; }
   bool      getHTidOpiSetFlag()               const { return m_mTidOpiSet; }
@@ -305,7 +316,8 @@ public:
   bool      getTOlsIdxOpiFlag()               const { return m_tOlsIdxTidOpiSet; }
   void      setTOlsIdxOpiFlag(bool tOlsIdxOpiSet)  { m_tOlsIdxTidOpiSet = tOlsIdxOpiSet; }
   const OPI* getOPI()                     { return m_opi; }
-#endif
+
+  bool      getMixedNaluTypesInPicFlag();
 
 protected:
   void  xUpdateRasInit(Slice* slice);
@@ -318,9 +330,7 @@ protected:
   void  xCheckParameterSetConstraints( const int layerId );
   void      xDecodePicHeader( InputNALUnit& nalu );
   bool      xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDisplay);
-#if JVET_S0163_ON_TARGETOLS_SUBLAYERS
   void      xDecodeOPI( InputNALUnit& nalu );
-#endif
   void      xDecodeVPS( InputNALUnit& nalu );
   void      xDecodeDCI( InputNALUnit& nalu );
   void      xDecodeSPS( InputNALUnit& nalu );
@@ -336,6 +346,8 @@ protected:
   void      xParsePrefixSEImessages();
   void      xParsePrefixSEIsForUnknownVCLNal();
   void      xCheckPrefixSEIMessages( SEIMessages& prefixSEIs );
+  void      xCheckDUISEIMessages(SEIMessages &prefixSEIs);
+
 
   void  xCheckNalUnitConstraintFlags( const ConstraintInfo *cInfo, uint32_t naluType );
   void     xCheckMixedNalUnit(Slice* pcSlice, SPS *sps, InputNALUnit &nalu);
diff --git a/source/Lib/DecoderLib/DecSlice.cpp b/source/Lib/DecoderLib/DecSlice.cpp
index 57c1c92c4..df27bae1c 100644
--- a/source/Lib/DecoderLib/DecSlice.cpp
+++ b/source/Lib/DecoderLib/DecSlice.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/DecoderLib/DecSlice.h b/source/Lib/DecoderLib/DecSlice.h
index 56cc1da07..365c6a3a3 100644
--- a/source/Lib/DecoderLib/DecSlice.h
+++ b/source/Lib/DecoderLib/DecSlice.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/DecoderLib/NALread.cpp b/source/Lib/DecoderLib/NALread.cpp
index a1cbcf760..ccda00687 100644
--- a/source/Lib/DecoderLib/NALread.cpp
+++ b/source/Lib/DecoderLib/NALread.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -111,7 +111,8 @@ static void xTraceNalUnitHeader(InputNALUnit& nalu)
 {
   DTRACE( g_trace_ctx, D_NALUNITHEADER, "*********** NAL UNIT (%s) ***********\n", nalUnitTypeToString(nalu.m_nalUnitType) );
   bool zeroTidRequiredFlag = 0;
-  if((nalu.m_nalUnitType >= 16) && (nalu.m_nalUnitType <= 31)) {
+  if ((nalu.m_nalUnitType >= 16) && (nalu.m_nalUnitType <= 31))
+  {
     zeroTidRequiredFlag = 1;
   }
   DTRACE( g_trace_ctx, D_NALUNITHEADER, "%-50s u(%d)  : %u\n", "zero_tid_required_flag", 1, zeroTidRequiredFlag );
@@ -163,10 +164,12 @@ void read(InputNALUnit& nalu)
   InputBitstream &bitstream = nalu.getBitstream();
   vector<uint8_t>& nalUnitBuf=bitstream.getFifo();
   // perform anti-emulation prevention
-  convertPayloadToRBSP(nalUnitBuf, &bitstream, (nalUnitBuf[0] & 64) == 0);
+  const NalUnitType nut = (NalUnitType)(nalUnitBuf[1] >> 3);
+  convertPayloadToRBSP(nalUnitBuf, &bitstream, nut <= NAL_UNIT_RESERVED_IRAP_VCL_11);
   bitstream.resetToStart();
   readNalUnitHeader(nalu);
 }
+
 bool checkPictureHeaderInSliceHeaderFlag(InputNALUnit& nalu)
 {
   InputBitstream& bitstream = nalu.getBitstream();
diff --git a/source/Lib/DecoderLib/NALread.h b/source/Lib/DecoderLib/NALread.h
index 4cf7bac93..e543b2f9d 100644
--- a/source/Lib/DecoderLib/NALread.h
+++ b/source/Lib/DecoderLib/NALread.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/DecoderLib/SEIread.cpp b/source/Lib/DecoderLib/SEIread.cpp
index d5c993102..d6dd927c0 100644
--- a/source/Lib/DecoderLib/SEIread.cpp
+++ b/source/Lib/DecoderLib/SEIread.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -230,10 +230,22 @@ void SEIReader::xReadSEImessage(SEIMessages& seis, const NalUnitType nalUnitType
       sei = new SEIDependentRAPIndication;
       xParseSEIDependentRAPIndication((SEIDependentRAPIndication&) *sei, payloadSize, pDecodedMessageOutputStream);
       break;
+    case SEI::EXTENDED_DRAP_INDICATION:
+      sei = new SEIExtendedDrapIndication;
+      xParseSEIExtendedDrapIndication((SEIExtendedDrapIndication&) *sei, payloadSize, pDecodedMessageOutputStream);
+      break;
     case SEI::FRAME_PACKING:
       sei = new SEIFramePacking;
       xParseSEIFramePacking((SEIFramePacking&) *sei, payloadSize, pDecodedMessageOutputStream);
       break;
+    case SEI::DISPLAY_ORIENTATION:
+      sei = new SEIDisplayOrientation;
+      xParseSEIDisplayOrientation((SEIDisplayOrientation&)*sei, payloadSize, pDecodedMessageOutputStream);
+      break;
+    case SEI::ANNOTATED_REGIONS:
+      sei = new SEIAnnotatedRegions;
+      xParseSEIAnnotatedRegions((SEIAnnotatedRegions&)*sei, payloadSize, pDecodedMessageOutputStream);
+      break;
     case SEI::PARAMETER_SETS_INCLUSION_INDICATION:
       sei = new SEIParameterSetsInclusionIndication;
       xParseSEIParameterSetsInclusionIndication((SEIParameterSetsInclusionIndication&)*sei, payloadSize, pDecodedMessageOutputStream);
@@ -268,6 +280,28 @@ void SEIReader::xReadSEImessage(SEIMessages& seis, const NalUnitType nalUnitType
       sei = new SEIGeneralizedCubemapProjection;
       xParseSEIGeneralizedCubemapProjection((SEIGeneralizedCubemapProjection&) *sei, payloadSize, pDecodedMessageOutputStream);
       break;
+    case SEI::SCALABILITY_DIMENSION_INFO:
+      sei = new SEIScalabilityDimensionInfo;
+      xParseSEIScalabilityDimensionInfo((SEIScalabilityDimensionInfo&) *sei, payloadSize, pDecodedMessageOutputStream );
+      break;
+    case SEI::MULTIVIEW_ACQUISITION_INFO:
+      sei = new SEIMultiviewAcquisitionInfo;
+      xParseSEIMultiviewAcquisitionInfo((SEIMultiviewAcquisitionInfo&) *sei, payloadSize, pDecodedMessageOutputStream );
+      break;
+#if JVET_W0078_MVP_SEI 
+    case SEI::MULTIVIEW_VIEW_POSITION:
+      sei = new SEIMultiviewViewPosition;
+      xParseSEIMultiviewViewPosition((SEIMultiviewViewPosition&)*sei, payloadSize, pDecodedMessageOutputStream);
+      break;
+#endif
+    case SEI::ALPHA_CHANNEL_INFO:
+      sei = new SEIAlphaChannelInfo;
+      xParseSEIAlphaChannelInfo((SEIAlphaChannelInfo&) *sei, payloadSize, pDecodedMessageOutputStream );
+      break;
+    case SEI::DEPTH_REPRESENTATION_INFO:
+      sei = new SEIDepthRepresentationInfo;
+      xParseSEIDepthRepresentationInfo((SEIDepthRepresentationInfo&) *sei, payloadSize, pDecodedMessageOutputStream );
+      break;
     case SEI::SUBPICTURE_LEVEL_INFO:
       sei = new SEISubpicureLevelInfo;
       xParseSEISubpictureLevelInfo((SEISubpicureLevelInfo&) *sei, payloadSize, pDecodedMessageOutputStream);
@@ -296,6 +330,16 @@ void SEIReader::xReadSEImessage(SEIMessages& seis, const NalUnitType nalUnitType
       sei = new SEIContentColourVolume;
       xParseSEIContentColourVolume((SEIContentColourVolume&)*sei, payloadSize, pDecodedMessageOutputStream);
       break;
+    case SEI::COLOUR_TRANSFORM_INFO:
+      sei = new SEIColourTransformInfo;
+      xParseSEIColourTransformInfo((SEIColourTransformInfo&)*sei, payloadSize, pDecodedMessageOutputStream);
+      break;
+#if JVET_W0133_CONSTRAINED_RASL_ENCODING
+    case SEI::CONSTRAINED_RASL_ENCODING:
+      sei = new SEIConstrainedRaslIndication;
+      xParseSEIConstrainedRaslIndication((SEIConstrainedRaslIndication&) *sei, payloadSize, pDecodedMessageOutputStream);
+      break;
+#endif
     default:
       for (uint32_t i = 0; i < payloadSize; i++)
       {
@@ -438,14 +482,12 @@ void SEIReader::xParseSEIDecodedPictureHash(SEIDecodedPictureHash& sei, uint32_t
   uint32_t val;
   sei_read_code( pDecodedMessageOutputStream, 8, val, "dph_sei_hash_type");
   sei.method = static_cast<HashType>(val); bytesRead++;
-#if FIX_TICKET_1405
   sei_read_code( pDecodedMessageOutputStream, 1, val, "dph_sei_single_component_flag");
   sei.singleCompFlag = val;
   sei_read_code( pDecodedMessageOutputStream, 7, val, "dph_sei_reserved_zero_7bits");
   bytesRead++;
   uint32_t expectedSize = ( sei.singleCompFlag ? 1 : 3 ) * (sei.method == 0 ? 16 : (sei.method == 1 ? 2 : 4));
   CHECK ((payloadSize - bytesRead) != expectedSize, "The size of the decoded picture hash does not match the expected size.");
-#endif
 
   const char *traceString="\0";
   switch (sei.method)
@@ -591,6 +633,9 @@ void SEIReader::xCheckScalableNestingConstraints(const SEIScalableNesting& sei,
   for (auto nestedsei : sei.m_nestedSEIs)
   {
     CHECK(nestedsei->payloadType() == SEI::FILLER_PAYLOAD || nestedsei->payloadType() == SEI::SCALABLE_NESTING, "An SEI message that has payloadType equal to filler payload or scalable nesting shall not be contained in a scalable nesting SEI message");
+    
+    CHECK(nestedsei->payloadType() == SEI::SCALABILITY_DIMENSION_INFO, "A scalability dimension information SEI message shall not be contained in a scalable nesting SEI message");
+    CHECK(nestedsei->payloadType() == SEI::MULTIVIEW_ACQUISITION_INFO, "A multiview acquisition information SEI message shall not be contained in a scalable nesting SEI message");
 
     CHECK(nestedsei->payloadType() != SEI::FILLER_PAYLOAD && nestedsei->payloadType() != SEI::DECODED_PICTURE_HASH && nalUnitType != NAL_UNIT_PREFIX_SEI, "When a scalable nesting SEI message contains an SEI message that has payloadType not equal to filler payload or decoded picture hash, the SEI NAL unit containing the scalable nesting SEI message shall have nal_unit_type equal to PREFIX_SEI_NUT");
 
@@ -658,7 +703,8 @@ void SEIReader::xParseSEIDecodingUnitInfo(SEIDecodingUnitInfo& sei, uint32_t pay
       sei.m_duSptCpbRemovalDelayIncrement[i] = 0;
     }
   }
-  if (bp.m_decodingUnitDpbDuParamsInPicTimingSeiFlag)
+  if (!bp.m_decodingUnitDpbDuParamsInPicTimingSeiFlag)
+
   {
     sei_read_flag(pDecodedMessageOutputStream, val, "dpb_output_du_delay_present_flag"); sei.m_dpbOutputDuDelayPresentFlag = (val != 0);
   }
@@ -669,6 +715,8 @@ void SEIReader::xParseSEIDecodingUnitInfo(SEIDecodingUnitInfo& sei, uint32_t pay
   if(sei.m_dpbOutputDuDelayPresentFlag)
   {
     sei_read_code( pDecodedMessageOutputStream, bp.getDpbOutputDelayDuLength(), val, "pic_spt_dpb_output_du_delay");
+    if (sei.m_picSptDpbOutputDuDelay != -1)
+       CHECK(sei.m_picSptDpbOutputDuDelay!=val,"When signaled m_picSptDpbOutputDuDelay value must be same for DUs");
     sei.m_picSptDpbOutputDuDelay = val;
   }
 }
@@ -758,15 +806,15 @@ void SEIReader::xParseSEIBufferingPeriod(SEIBufferingPeriod& sei, uint32_t paylo
           sei_read_code( pDecodedMessageOutputStream, sei.m_initialCpbRemovalDelayLength, code, nalOrVcl ? "vcl_initial_cpb_removal_delay[i][j]" : "nal_initial_cpb_removal_delay[i][j]" );
           sei.m_initialCpbRemovalDelay[i][j][nalOrVcl] = code;
           sei_read_code( pDecodedMessageOutputStream, sei.m_initialCpbRemovalDelayLength, code, nalOrVcl ? "vcl_initial_cpb_removal_offset[i][j]" : "nal_initial_cpb_removal_offset[i][j]" );
-          sei.m_initialCpbRemovalDelay[i][j][nalOrVcl] = code;
+          sei.m_initialCpbRemovalOffset[i][j][nalOrVcl] = code;
         }
       }
     }
   }
-  if (sei.m_bpMaxSubLayers-1 > 0) 
+  if (sei.m_bpMaxSubLayers-1 > 0)
   {
     sei_read_flag(pDecodedMessageOutputStream, code, "bp_sublayer_dpb_output_offsets_present_flag");
-    sei.m_sublayerDpbOutputOffsetsPresentFlag = code; 
+    sei.m_sublayerDpbOutputOffsetsPresentFlag = code;
   }
   else
   {
@@ -980,14 +1028,130 @@ void SEIReader::xParseSEIPictureTiming(SEIPictureTiming& sei, uint32_t payloadSi
       sei.m_duCommonCpbRemovalDelayFlag = 0;
     }
   }
-#if JVET_S0175_ASPECT5
   sei_read_code( pDecodedMessageOutputStream, 8, symbol,    "pt_display_elemental_periods_minus1" );
-#else
-  sei_read_uvlc( pDecodedMessageOutputStream, symbol,    "pt_display_elemental_periods_minus1" );
-#endif
   sei.m_ptDisplayElementalPeriodsMinus1 = symbol;
 }
 
+void SEIReader::xParseSEIAnnotatedRegions(SEIAnnotatedRegions& sei, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream)
+{
+  output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize);
+  uint32_t val;
+
+  sei_read_flag(pDecodedMessageOutputStream, val, "ar_cancel_flag");                                   sei.m_hdr.m_cancelFlag = val;
+  if (!sei.m_hdr.m_cancelFlag)
+  {
+    sei_read_flag(pDecodedMessageOutputStream, val, "ar_not_optimized_for_viewing_flag");              sei.m_hdr.m_notOptimizedForViewingFlag = val;
+    sei_read_flag(pDecodedMessageOutputStream, val, "ar_true_motion_flag");                            sei.m_hdr.m_trueMotionFlag = val;
+    sei_read_flag(pDecodedMessageOutputStream, val, "ar_occluded_object_flag");                        sei.m_hdr.m_occludedObjectFlag = val; // must be constant
+    sei_read_flag(pDecodedMessageOutputStream, val, "ar_partial_object_flag_present_flag");            sei.m_hdr.m_partialObjectFlagPresentFlag = val; // must be constant
+    sei_read_flag(pDecodedMessageOutputStream, val, "ar_object_label_present_flag");                   sei.m_hdr.m_objectLabelPresentFlag = val;
+    sei_read_flag(pDecodedMessageOutputStream, val, "ar_object_confidence_info_present_flag");         sei.m_hdr.m_objectConfidenceInfoPresentFlag = val; // must be constant
+    if (sei.m_hdr.m_objectConfidenceInfoPresentFlag)
+    {
+      sei_read_code(pDecodedMessageOutputStream, 4, val, "ar_object_confidence_length_minus_1"); sei.m_hdr.m_objectConfidenceLength = (val + 1); // must be constant
+    }
+    if (sei.m_hdr.m_objectLabelPresentFlag)
+    {
+      sei_read_flag(pDecodedMessageOutputStream, val, "ar_object_label_language_present_flag");      sei.m_hdr.m_objectLabelLanguagePresentFlag = val;
+      if (sei.m_hdr.m_objectLabelLanguagePresentFlag)
+      {
+        // byte alignment
+        while (m_pcBitstream->getNumBitsRead() % 8 != 0)
+        {
+          uint32_t code;
+          sei_read_flag(pDecodedMessageOutputStream, code, "ar_bit_equal_to_zero");
+        }
+        sei.m_hdr.m_annotatedRegionsObjectLabelLang.clear();
+        do
+        {
+          sei_read_code(pDecodedMessageOutputStream, 8, val, "ar_label_language");
+          if (val)
+          {
+            assert(sei.m_hdr.m_annotatedRegionsObjectLabelLang.size()<256);
+            sei.m_hdr.m_annotatedRegionsObjectLabelLang.push_back((char)val);
+          }
+        } while (val != '\0');
+      }
+    }
+
+    uint32_t numLabelUpdates;
+    sei_read_uvlc(pDecodedMessageOutputStream, numLabelUpdates, "ar_num_label_updates");
+    assert(numLabelUpdates<256);
+
+    sei.m_annotatedLabels.clear();
+    sei.m_annotatedLabels.resize(numLabelUpdates);
+    for (auto it=sei.m_annotatedLabels.begin(); it!=sei.m_annotatedLabels.end(); it++)
+    {
+      SEIAnnotatedRegions::AnnotatedRegionLabel &ar = it->second;
+      sei_read_uvlc(pDecodedMessageOutputStream, val, "ar_label_idx[]");             it->first = val;
+      assert(val<256);
+      sei_read_flag(pDecodedMessageOutputStream, val, "ar_label_cancel_flag");       ar.labelValid = !val;
+      if (ar.labelValid)
+      {
+        ar.label.clear();
+        // byte alignment
+        while (m_pcBitstream->getNumBitsRead() % 8 != 0)
+        {
+          uint32_t code;
+          sei_read_flag(pDecodedMessageOutputStream, code, "ar_bit_equal_to_zero");
+        }
+        do
+        {
+          sei_read_code(pDecodedMessageOutputStream, 8, val, "ar_label[]");
+          if (val)
+          {
+            assert(ar.label.size()<256);
+            ar.label.push_back((char)val);
+          }
+        } while (val != '\0');
+      }
+    }
+
+    uint32_t numObjUpdates;
+    sei_read_uvlc(pDecodedMessageOutputStream, numObjUpdates, "ar_num_object_updates");
+    assert(numObjUpdates<256);
+    sei.m_annotatedRegions.clear();
+    sei.m_annotatedRegions.resize(numObjUpdates);
+    for (auto it=sei.m_annotatedRegions.begin(); it!=sei.m_annotatedRegions.end(); it++)
+    {
+      sei_read_uvlc(pDecodedMessageOutputStream, val, "ar_object_idx"); it->first=val;
+      assert(val<256);
+      SEIAnnotatedRegions::AnnotatedRegionObject &ar = it->second;
+      sei_read_flag(pDecodedMessageOutputStream, val, "ar_object_cancel_flag");                           ar.objectCancelFlag = val;
+      ar.objectLabelValid=false;
+      ar.boundingBoxValid=false;
+
+      if (!ar.objectCancelFlag)
+      {
+        if (sei.m_hdr.m_objectLabelPresentFlag)
+        {
+          sei_read_flag(pDecodedMessageOutputStream, val, "ar_object_label_update_flag");             ar.objectLabelValid = val;
+          if (ar.objectLabelValid)
+          {
+            sei_read_uvlc(pDecodedMessageOutputStream, val, "ar_object_label_idx");                      ar.objLabelIdx = val;
+            assert(val<256);
+          }
+        }
+        sei_read_flag(pDecodedMessageOutputStream, val, "ar_bounding_box_update_flag");              ar.boundingBoxValid = val;
+        if (ar.boundingBoxValid)
+        {
+          sei_read_code(pDecodedMessageOutputStream, 16, val, "ar_bounding_box_top");                      ar.boundingBoxTop = val;
+          sei_read_code(pDecodedMessageOutputStream, 16, val, "ar_bounding_box_left");                     ar.boundingBoxLeft = val;
+          sei_read_code(pDecodedMessageOutputStream, 16, val, "ar_bounding_box_width");                    ar.boundingBoxWidth = val;
+          sei_read_code(pDecodedMessageOutputStream, 16, val, "ar_bounding_box_height");                   ar.boundingBoxHeight = val;
+          if (sei.m_hdr.m_partialObjectFlagPresentFlag)
+          {
+            sei_read_flag(pDecodedMessageOutputStream, val, "ar_partial_object_flag");                ar.partialObjectFlag = val;
+          }
+          if (sei.m_hdr.m_objectConfidenceInfoPresentFlag)
+          {
+            sei_read_code(pDecodedMessageOutputStream, sei.m_hdr.m_objectConfidenceLength, val, "ar_object_confidence"); ar.objectConfidence = val;
+          }
+        }
+      }
+    }
+  }
+}
 void SEIReader::xParseSEIFrameFieldinfo(SEIFrameFieldInfo& sei, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream)
 {
   output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize);
@@ -1016,11 +1180,7 @@ void SEIReader::xParseSEIFrameFieldinfo(SEIFrameFieldInfo& sei, uint32_t payload
       sei_read_flag( pDecodedMessageOutputStream, symbol,  "ffi_top_field_first_flag" );
       sei.m_topFieldFirstFlag = symbol;
     }
-#if JVET_S0175_ASPECT5
     sei_read_code( pDecodedMessageOutputStream, 8, symbol, "ffi_display_elemental_periods_minus1" );
-#else
-    sei_read_uvlc( pDecodedMessageOutputStream, symbol,    "ffi_display_elemental_periods_minus1" );
-#endif
     sei.m_displayElementalPeriodsMinus1 = symbol;
   }
   sei_read_code( pDecodedMessageOutputStream, 2, symbol,   "ffi_source_scan_type" );
@@ -1072,6 +1232,20 @@ void SEIReader::xParseSEIFramePacking(SEIFramePacking& sei, uint32_t payloadSize
   sei_read_flag( pDecodedMessageOutputStream, val, "fp_upsampled_aspect_ratio_flag" );       sei.m_upsampledAspectRatio = val;
 }
 
+void SEIReader::xParseSEIDisplayOrientation(SEIDisplayOrientation& sei, uint32_t payloadSize, std::ostream* pDecodedMessageOutputStream)
+{
+  uint32_t val;
+  output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize);
+
+  sei_read_flag(pDecodedMessageOutputStream, val, "display_orientation_cancel_flag");           sei.m_doCancelFlag = val;
+  if (!sei.m_doCancelFlag)
+  {
+    sei_read_flag(pDecodedMessageOutputStream, val, "display_orientation_persistence_flag");    sei.m_doPersistenceFlag = val;
+    sei_read_code(pDecodedMessageOutputStream, 3, val, "display_orientation_transform_type");   sei.m_doTransformType = val;
+    CHECK((sei.m_doTransformType < 0) || (sei.m_doTransformType > 7), "Invalid transform type");
+  }
+}
+
 void SEIReader::xParseSEIParameterSetsInclusionIndication(SEIParameterSetsInclusionIndication& sei, uint32_t payloadSize, std::ostream* pDecodedMessageOutputStream)
 {
   uint32_t val;
@@ -1208,6 +1382,84 @@ void SEIReader::xParseSEIAmbientViewingEnvironment(SEIAmbientViewingEnvironment&
   sei_read_code(pDecodedMessageOutputStream, 16, code, "ambient_light_y");     sei.m_ambientLightY = (uint16_t)code;
 }
 
+void SEIReader::xParseSEIColourTransformInfo(SEIColourTransformInfo& sei, uint32_t payloadSize, std::ostream* pDecodedMessageOutputStream)
+{
+  uint32_t code;
+
+  output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize);
+
+  sei_read_uvlc(pDecodedMessageOutputStream, code, "colour_transform_id");               sei.m_id = code;
+  sei_read_flag(pDecodedMessageOutputStream, code, "colour_transform_cancel_flag");      bool colourTransformCancelFlag = code;
+
+  if (colourTransformCancelFlag == 0)
+  {
+    sei_read_flag(pDecodedMessageOutputStream, code, "colour_transform_persistence_flag");
+    sei_read_flag(pDecodedMessageOutputStream, code, "colour_transform_video_signal_info_present_flag"); sei.m_signalInfoFlag = code;
+
+    if (sei.m_signalInfoFlag)
+    {
+      sei_read_flag(pDecodedMessageOutputStream, code, "colour_transform_full_range_flag");        sei.m_fullRangeFlag = code;
+      sei_read_code(pDecodedMessageOutputStream, 8, code, "colour_transform_primaries");           sei.m_primaries = code;
+      sei_read_code(pDecodedMessageOutputStream, 8, code, "colour_transform_transfer_function");   sei.m_transferFunction = code;
+      sei_read_code(pDecodedMessageOutputStream, 8, code, "colour_transform_matrix_coefficients"); sei.m_matrixCoefs = code;
+    }
+    else
+    {
+      sei.m_fullRangeFlag = 0;
+      sei.m_primaries = 0;
+      sei.m_transferFunction = 0;
+      sei.m_matrixCoefs = 0;
+    }
+    sei_read_code(pDecodedMessageOutputStream, 4, code, "colour_transform_bit_depth_minus8");                       sei.m_bitdepth = 8+code;
+    sei_read_code(pDecodedMessageOutputStream, 3, code, "colour_transform_log2_number_of_points_per_lut_minus1");   sei.m_log2NumberOfPointsPerLut = code + 1;
+    int numLutValues = (1 << sei.m_log2NumberOfPointsPerLut) + 1;
+    sei_read_flag(pDecodedMessageOutputStream, code, "colour_transform_cross_comp_flag");                sei.m_crossComponentFlag = code;
+    sei.m_crossComponentInferred = 0;
+    if (sei.m_crossComponentFlag == true)
+    {
+      sei_read_flag(pDecodedMessageOutputStream, code, "colour_transform_cross_comp_inferred");          sei.m_crossComponentInferred = code;
+    }
+    for (int i = 0; i < MAX_NUM_COMPONENT; i++) {
+      sei.m_lut[i].lutValues.resize(numLutValues);
+    }
+
+    uint16_t lutCodingLength = 2 + sei.m_bitdepth - sei.m_log2NumberOfPointsPerLut;
+    for (uint32_t j = 0; j < numLutValues; j++)
+    {
+      sei_read_code(pDecodedMessageOutputStream, lutCodingLength, code, "colour_transform_lut[0][i]");
+      sei.m_lut[0].lutValues[j] = code;
+    }
+    sei.m_lut[0].numLutValues = numLutValues;
+    sei.m_lut[0].presentFlag = true;
+    if (sei.m_crossComponentFlag == 0 || sei.m_crossComponentInferred == 0)
+    {
+      sei_read_flag(pDecodedMessageOutputStream, code, "colour_transform_number_chroma_lut_minus1");      sei.m_numberChromaLutMinus1 = code;
+      for (uint32_t j = 0; j < numLutValues; j++)
+      {
+        sei_read_code(pDecodedMessageOutputStream, lutCodingLength, code, "colour_transform_lut[1][i]");
+        sei.m_lut[1].lutValues[j] = code;
+        sei.m_lut[2].lutValues[j] = code;
+      }
+      if (sei.m_numberChromaLutMinus1 == 1)
+      {
+        for (uint32_t j = 0; j < numLutValues; j++)
+        {
+          sei_read_code(pDecodedMessageOutputStream, lutCodingLength, code, "colour_transform_lut[2][i]");
+          sei.m_lut[2].lutValues[j] = code;
+        }
+      }
+      sei.m_lut[1].numLutValues = numLutValues;
+      sei.m_lut[2].numLutValues = numLutValues;
+      sei.m_lut[1].presentFlag = true;
+      sei.m_lut[2].presentFlag = true;
+    }
+    else
+    {
+      sei_read_code(pDecodedMessageOutputStream, lutCodingLength, code, "colour_transform_chroma_offset");
+      sei.m_chromaOffset = code;
+    }
+  }
+}
 void SEIReader::xParseSEIContentColourVolume(SEIContentColourVolume& sei, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream)
 {
   int i;
@@ -1421,6 +1673,246 @@ void SEIReader::xParseSEIGeneralizedCubemapProjection(SEIGeneralizedCubemapProje
   }
 }
 
+void SEIReader::xParseSEIScalabilityDimensionInfo(SEIScalabilityDimensionInfo& sei, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream)
+{
+  output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize);
+  uint32_t val;
+  sei_read_code( pDecodedMessageOutputStream,   6,  val,    "sdi_max_layers_minus1" );            sei.m_sdiMaxLayersMinus1 = val;
+  sei_read_flag( pDecodedMessageOutputStream,       val,    "sdi_multiview_info_flag" );          sei.m_sdiMultiviewInfoFlag = val;
+  sei_read_flag( pDecodedMessageOutputStream,       val,    "sdi_auxiliary_info_flag" );          sei.m_sdiAuxiliaryInfoFlag = val;
+  if (sei.m_sdiMultiviewInfoFlag || sei.m_sdiAuxiliaryInfoFlag)
+  {
+    if (sei.m_sdiMultiviewInfoFlag)
+    {
+      sei_read_code( pDecodedMessageOutputStream, 4, val, "sdi_view_id_len_minus1" ); sei.m_sdiViewIdLenMinus1 = val;
+    }
+    for (int i = 0; i <= sei.m_sdiMaxLayersMinus1; i++)
+    {
+      sei.m_sdiLayerId.resize(sei.m_sdiViewIdLenMinus1 + 1);
+      sei_read_code( pDecodedMessageOutputStream, 6, val, "sdi_layer_id" ); sei.m_sdiLayerId[i] = val;
+      if (sei.m_sdiMultiviewInfoFlag)
+      {
+        sei.m_sdiViewIdVal.resize(sei.m_sdiViewIdLenMinus1 + 1);
+        sei_read_code( pDecodedMessageOutputStream, sei.m_sdiViewIdLenMinus1 + 1, val, "sdi_view_id_val" ); sei.m_sdiViewIdVal[i] = val;
+      }
+      if (sei.m_sdiAuxiliaryInfoFlag)
+      {
+        sei.m_sdiAuxId.resize(sei.m_sdiViewIdLenMinus1 + 1);
+        sei.m_sdiNumAssociatedPrimaryLayersMinus1.resize(sei.m_sdiViewIdLenMinus1 + 1);
+        sei.m_sdiAssociatedPrimaryLayerIdx.resize(sei.m_sdiViewIdLenMinus1 + 1);
+        sei_read_code( pDecodedMessageOutputStream, 8, val, "sdi_aux_id" ); sei.m_sdiAuxId[i] = val;
+        if (sei.m_sdiAuxId[i] > 0)
+        {
+          sei_read_code( pDecodedMessageOutputStream, 6, val, "sdi_num_associated_primary_layers_minus1" ); sei.m_sdiNumAssociatedPrimaryLayersMinus1[i] = val;
+          sei.m_sdiAssociatedPrimaryLayerIdx[i].resize(sei.m_sdiNumAssociatedPrimaryLayersMinus1[i] + 1);
+          for (int j = 0; j <= sei.m_sdiNumAssociatedPrimaryLayersMinus1[i]; j++)
+          {
+            sei_read_code( pDecodedMessageOutputStream, 6, val, "sdi_associated_primary_layer_idx" );
+            sei.m_sdiAssociatedPrimaryLayerIdx[i][j] = val;
+          }
+        }
+      }
+    }
+    sei.m_sdiNumViews = 1;
+    if (sei.m_sdiMultiviewInfoFlag)
+    {
+      for (int i = 1; i <= sei.m_sdiMaxLayersMinus1; i++)
+      {
+        bool newViewFlag = true;
+        for (int j = 0; j < i; j++)
+        {
+          if (sei.m_sdiViewIdVal[i] == sei.m_sdiViewIdVal[j])
+            newViewFlag = false;
+        }
+        if (newViewFlag)
+          sei.m_sdiNumViews++;
+      }
+    }
+  }
+}
+
+void SEIReader::xParseSEIMultiviewAcquisitionInfo(SEIMultiviewAcquisitionInfo& sei, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream)
+{
+  output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize);
+  uint32_t val;
+
+  sei_read_flag( pDecodedMessageOutputStream, val, "intrinsic_param_flag" ); sei.m_maiIntrinsicParamFlag = (val == 1);
+  sei_read_flag( pDecodedMessageOutputStream, val, "extrinsic_param_flag" ); sei.m_maiExtrinsicParamFlag = (val == 1);
+  sei_read_uvlc( pDecodedMessageOutputStream, val, "num_views_minus1"     ); sei.m_maiNumViewsMinus1     =  val      ;
+  sei.resizeArrays( );
+  if( sei.m_maiIntrinsicParamFlag )
+  {
+    sei_read_flag( pDecodedMessageOutputStream, val, "intrinsic_params_equal_flag" ); sei.m_maiIntrinsicParamsEqualFlag = (val == 1);
+    sei_read_uvlc( pDecodedMessageOutputStream, val, "prec_focal_length"           ); sei.m_maiPrecFocalLength          =  val      ;
+    sei_read_uvlc( pDecodedMessageOutputStream, val, "prec_principal_point"        ); sei.m_maiPrecPrincipalPoint       =  val      ;
+    sei_read_uvlc( pDecodedMessageOutputStream, val, "prec_skew_factor"            ); sei.m_maiPrecSkewFactor           =  val      ;
+
+    for( int i = 0; i  <=  ( sei.m_maiIntrinsicParamsEqualFlag ? 0 : sei.m_maiNumViewsMinus1 ); i++ )
+    {
+      sei_read_flag( pDecodedMessageOutputStream,                                         val, "sign_focal_length_x"        ); sei.m_maiSignFocalLengthX       [i] = (val == 1);
+      sei_read_code( pDecodedMessageOutputStream, 6,                                      val, "exponent_focal_length_x"    ); sei.m_maiExponentFocalLengthX   [i] =  val      ;
+      sei_read_code( pDecodedMessageOutputStream, sei.getMantissaFocalLengthXLen   ( i ), val, "mantissa_focal_length_x"    ); sei.m_maiMantissaFocalLengthX   [i] =  val      ;
+      sei_read_flag( pDecodedMessageOutputStream,                                         val, "sign_focal_length_y"        ); sei.m_maiSignFocalLengthY       [i] = (val == 1);
+      sei_read_code( pDecodedMessageOutputStream, 6,                                      val, "exponent_focal_length_y"    ); sei.m_maiExponentFocalLengthY   [i] =  val      ;
+      sei_read_code( pDecodedMessageOutputStream, sei.getMantissaFocalLengthYLen   ( i ), val, "mantissa_focal_length_y"    ); sei.m_maiMantissaFocalLengthY   [i] =  val      ;
+      sei_read_flag( pDecodedMessageOutputStream,                                         val, "sign_principal_point_x"     ); sei.m_maiSignPrincipalPointX    [i] = (val == 1);
+      sei_read_code( pDecodedMessageOutputStream, 6,                                      val, "exponent_principal_point_x" ); sei.m_maiExponentPrincipalPointX[i] =  val      ;
+      sei_read_code( pDecodedMessageOutputStream, sei.getMantissaPrincipalPointXLen( i ), val, "mantissa_principal_point_x" ); sei.m_maiMantissaPrincipalPointX[i] =  val      ;
+      sei_read_flag( pDecodedMessageOutputStream,                                         val, "sign_principal_point_y"     ); sei.m_maiSignPrincipalPointY    [i] = (val == 1);
+      sei_read_code( pDecodedMessageOutputStream, 6,                                      val, "exponent_principal_point_y" ); sei.m_maiExponentPrincipalPointY[i] =  val      ;
+      sei_read_code( pDecodedMessageOutputStream, sei.getMantissaPrincipalPointYLen( i ), val, "mantissa_principal_point_y" ); sei.m_maiMantissaPrincipalPointY[i] =  val      ;
+      sei_read_flag( pDecodedMessageOutputStream,                                         val, "sign_skew_factor"           ); sei.m_maiSignSkewFactor         [i] = (val == 1);
+      sei_read_code( pDecodedMessageOutputStream, 6,                                      val, "exponent_skew_factor"       ); sei.m_maiExponentSkewFactor     [i] =  val      ;
+      sei_read_code( pDecodedMessageOutputStream, sei.getMantissaSkewFactorLen     ( i ), val, "mantissa_skew_factor"       ); sei.m_maiMantissaSkewFactor     [i] =  val      ;
+    }
+  }
+  if( sei.m_maiExtrinsicParamFlag )
+  {
+    sei_read_uvlc( pDecodedMessageOutputStream, val, "prec_rotation_param"    ); sei.m_maiPrecRotationParam    = val;
+    sei_read_uvlc( pDecodedMessageOutputStream, val, "prec_translation_param" ); sei.m_maiPrecTranslationParam = val;
+
+    for( int i = 0; i  <=  sei.m_maiNumViewsMinus1; i++ )
+    {
+      for( int j = 0; j  <=  2; j++ )  /* row */
+      {
+        for( int k = 0; k  <=  2; k++ )  /* column */
+        {
+          sei_read_flag( pDecodedMessageOutputStream,                                 val, "sign_r"     ); sei.m_maiSignR    [i][j][k] = (val == 1);
+          sei_read_code( pDecodedMessageOutputStream, 6,                              val, "exponent_r" ); sei.m_maiExponentR[i][j][k] =  val      ;
+          sei_read_code( pDecodedMessageOutputStream, sei.getMantissaRLen( i, j, k ), val, "mantissa_r" ); sei.m_maiMantissaR[i][j][k] =  val      ;
+        }
+        sei_read_flag( pDecodedMessageOutputStream,                              val, "sign_t"     ); sei.m_maiSignT    [i][j] = (val == 1);
+        sei_read_code( pDecodedMessageOutputStream, 6,                           val, "exponent_t" ); sei.m_maiExponentT[i][j] =  val      ;
+        sei_read_code( pDecodedMessageOutputStream, sei.getMantissaTLen( i, j ), val, "mantissa_t" ); sei.m_maiMantissaT[i][j] =  val      ;
+      }
+    }
+  }
+};
+
+#if JVET_W0078_MVP_SEI
+void SEIReader::xParseSEIMultiviewViewPosition(SEIMultiviewViewPosition& sei, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream)
+{
+  uint32_t val;
+  output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize);
+
+  sei_read_uvlc(pDecodedMessageOutputStream, val, "num_views_minus1"); sei.m_mvpNumViewsMinus1 = val;
+  sei.m_mvpViewPosition.resize(sei.m_mvpNumViewsMinus1 + 1);
+  for (int i = 0; i <= sei.m_mvpNumViewsMinus1; i++)
+  {
+    sei_read_uvlc(pDecodedMessageOutputStream, val, "view_position"); sei.m_mvpViewPosition[i] = val;
+  }
+};
+#endif
+
+void SEIReader::xParseSEIAlphaChannelInfo(SEIAlphaChannelInfo& sei, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream)
+{
+  uint32_t val;
+  output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize);
+
+  sei_read_flag( pDecodedMessageOutputStream, val, "alpha_channel_cancel_flag" ); sei.m_aciCancelFlag = (val == 1);
+  if( !sei.m_aciCancelFlag )
+  {
+    sei_read_code( pDecodedMessageOutputStream, 3, val, "alpha_channel_use_idc" ); sei.m_aciUseIdc = val;
+    sei_read_code( pDecodedMessageOutputStream, 3, val, "alpha_channel_bit_depth_minus8" ); sei.m_aciBitDepthMinus8 = val;
+    sei_read_code( pDecodedMessageOutputStream, sei.m_aciBitDepthMinus8 + 9, val, "alpha_transparent_value" ); sei.m_aciTransparentValue = val;
+    sei_read_code( pDecodedMessageOutputStream, sei.m_aciBitDepthMinus8 + 9, val, "alpha_opaque_value" ); sei.m_aciOpaqueValue = val;
+    sei_read_flag( pDecodedMessageOutputStream, val, "alpha_channel_incr_flag" ); sei.m_aciIncrFlag = (val == 1);
+    sei_read_flag( pDecodedMessageOutputStream, val, "alpha_channel_clip_flag" ); sei.m_aciClipFlag = (val == 1);
+    if( sei.m_aciClipFlag )
+    {
+      sei_read_flag( pDecodedMessageOutputStream, val, "alpha_channel_clip_type_flag" ); sei.m_aciClipTypeFlag = (val == 1);
+    }
+  }
+};
+
+void SEIReader::xParseSEIDepthRepresentationInfo(SEIDepthRepresentationInfo& sei, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream)
+{
+  uint32_t val;
+  double zNear,zFar,dMin,dMax;
+  std::vector<int> DepthNonlinearRepresentationModel;
+
+  output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize);
+
+  sei_read_flag( pDecodedMessageOutputStream, val, "z_near_flag" );    sei.m_driZNearFlag  = (val == 1);
+  sei_read_flag( pDecodedMessageOutputStream, val, "z_far_flag" );     sei.m_driZFarFlag = (val == 1);
+  sei_read_flag( pDecodedMessageOutputStream, val, "d_min_flag" );     sei.m_driDMinFlag = (val == 1);
+  sei_read_flag( pDecodedMessageOutputStream, val, "d_max_flag" );     sei.m_driDMaxFlag = (val == 1);
+  sei_read_uvlc( pDecodedMessageOutputStream, val, "depth_representation_type" ); sei.m_driDepthRepresentationType = val;
+  if( sei.m_driDMinFlag  ||  sei.m_driDMaxFlag )
+  {
+    sei_read_uvlc( pDecodedMessageOutputStream, val, "disparity_ref_view_id" ); sei.m_driDisparityRefViewId = val;
+  }
+  if( sei.m_driZNearFlag )
+  {
+    xParseSEIDepthRepInfoElement(zNear, pDecodedMessageOutputStream);
+    sei.m_driZNear = zNear;
+  }
+  if( sei.m_driZFarFlag )
+  {
+    xParseSEIDepthRepInfoElement(zFar, pDecodedMessageOutputStream);
+    sei.m_driZFar = zFar;
+  }
+  if( sei.m_driDMinFlag )
+  {
+    xParseSEIDepthRepInfoElement(dMin, pDecodedMessageOutputStream);
+    sei.m_driDMin = dMin;
+  }
+  if( sei.m_driDMaxFlag )
+  {
+    xParseSEIDepthRepInfoElement(dMax, pDecodedMessageOutputStream);
+    sei.m_driDMax = dMax;
+  }
+
+  if( sei.m_driDepthRepresentationType == 3 )
+  {
+    sei_read_uvlc( pDecodedMessageOutputStream, val, "depth_nonlinear_representation_num_minus1" ); sei.m_driDepthNonlinearRepresentationNumMinus1 = val;
+    for( int i = 1; i <= sei.m_driDepthNonlinearRepresentationNumMinus1 + 1; i++ )
+    {
+      sei_read_uvlc(pDecodedMessageOutputStream,val,"DepthNonlinearRepresentationModel" ) ;
+      sei.m_driDepthNonlinearRepresentationModel.push_back(val);
+    }
+  }
+}
+
+void SEIReader::xParseSEIDepthRepInfoElement(double& f,std::ostream *pDecodedMessageOutputStream)
+{
+  uint32_t val;
+  uint32_t x_sign,x_mantissa_len,x_mantissa;
+  int x_exp;
+  
+  sei_read_flag(pDecodedMessageOutputStream,     val,"da_sign_flag");  x_sign = val ? 1 : 0 ;
+  sei_read_code(pDecodedMessageOutputStream,  7, val, "da_exponent" );         x_exp = val-31;
+  sei_read_code(pDecodedMessageOutputStream,  5, val, "da_mantissa_len_minus1" );         x_mantissa_len = val+1;
+  sei_read_code(pDecodedMessageOutputStream,  x_mantissa_len, val, "da_mantissa" );         x_mantissa = val;
+  if (x_mantissa_len>=16)
+  {
+    f =1.0 +  (x_mantissa*1.0)/(1u<<(x_mantissa_len-16))/(256.0*256.0 );
+  }else
+  {
+    f =1.0 +  (x_mantissa*1.0)/(1u<<x_mantissa_len);
+  }
+  double m=1.0;
+  int i;
+  if (x_exp<0)
+  {
+    for(i=0;i<-x_exp;i++)
+    m = m * 2;
+    
+    f = f/m;
+  }
+  else
+  {
+    for(i=0;i<x_exp;i++)
+    m = m * 2;
+    
+    f= f * m;
+  }
+  if (x_sign==1)
+  {
+    f= -f;
+  }
+};
+
 void SEIReader::xParseSEISubpictureLevelInfo(SEISubpicureLevelInfo& sei, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream)
 {
   output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize);
@@ -1525,6 +2017,29 @@ void SEIReader::xParseSEISampleAspectRatioInfo(SEISampleAspectRatioInfo& sei, ui
   }
 }
 
+void SEIReader::xParseSEIExtendedDrapIndication(SEIExtendedDrapIndication& sei, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream)
+{
+  uint32_t val;
+  output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize);
+  sei_read_code( pDecodedMessageOutputStream, 16, val,        "edrap_rap_id_minus1"          );   sei.m_edrapIndicationRapIdMinus1         = val;
+  sei_read_flag( pDecodedMessageOutputStream,     val,        "edrap_leading_pictures_decodable_flag" );       sei.m_edrapIndicationLeadingPicturesDecodableFlag = val;
+  sei_read_code( pDecodedMessageOutputStream, 12, val,        "edrap_reserved_zero_12bits"          );   sei.m_edrapIndicationReservedZero12Bits = val;
+  sei_read_code( pDecodedMessageOutputStream, 3, val,         "edrap_num_ref_rap_pics_minus1"          );   sei.m_edrapIndicationNumRefRapPicsMinus1 = val;
+  sei.m_edrapIndicationRefRapId.resize(sei.m_edrapIndicationNumRefRapPicsMinus1 + 1);
+  for (int i = 0; i <= sei.m_edrapIndicationNumRefRapPicsMinus1; i++)
+  {
+    sei_read_code( pDecodedMessageOutputStream, 16, val,       "edrap_ref_rap_id[i]"          );
+    sei.m_edrapIndicationRefRapId[i] = val;
+  }
+}
+
+#if JVET_W0133_CONSTRAINED_RASL_ENCODING
+void SEIReader::xParseSEIConstrainedRaslIndication( SEIConstrainedRaslIndication& sei, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream )
+{
+  output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize);
+}
+#endif
+
 #if JVET_S0257_DUMP_360SEI_MESSAGE
 void SeiCfgFileDump::write360SeiDump (std::string decoded360MessageFileName, SEIMessages& seis, const SPS* sps)
 {
@@ -1547,7 +2062,7 @@ void SeiCfgFileDump::write360SeiDump (std::string decoded360MessageFileName, SEI
     {
       SEIGeneralizedCubemapProjection* sei = (SEIGeneralizedCubemapProjection*)generalizedCubemapProjectionSEIs.front();
       xDumpSEIGeneralizedCubemapProjection(*sei, sps, decoded360MessageFileName);
-      m_360SEIMessageDumped = true; 
+      m_360SEIMessageDumped = true;
     }
   }
 }
diff --git a/source/Lib/DecoderLib/SEIread.h b/source/Lib/DecoderLib/SEIread.h
index 996f6e1f3..8a9f0aea7 100644
--- a/source/Lib/DecoderLib/SEIread.h
+++ b/source/Lib/DecoderLib/SEIread.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -69,8 +69,10 @@ protected:
   void xParseSEIFrameFieldinfo                (SEIFrameFieldInfo& sei,                uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream);
   void xParseSEIDependentRAPIndication        (SEIDependentRAPIndication& sei,        uint32_t payLoadSize,                     std::ostream *pDecodedMessageOutputStream);
   void xParseSEIFramePacking                  (SEIFramePacking& sei,                  uint32_t payloadSize,                     std::ostream *pDecodedMessageOutputStream);
+  void xParseSEIDisplayOrientation            (SEIDisplayOrientation& sei,            uint32_t payloadSize,                     std::ostream* pDecodedMessageOutputStream);
   void xParseSEIParameterSetsInclusionIndication(SEIParameterSetsInclusionIndication& sei, uint32_t payloadSize,                std::ostream* pDecodedMessageOutputStream);
   void xParseSEIMasteringDisplayColourVolume  (SEIMasteringDisplayColourVolume& sei,  uint32_t payloadSize,                     std::ostream *pDecodedMessageOutputStream);
+  void xParseSEIAnnotatedRegions              (SEIAnnotatedRegions& sei,              uint32_t payloadSize,                     std::ostream *pDecodedMessageOutputStream);
 #if U0033_ALTERNATIVE_TRANSFER_CHARACTERISTICS_SEI
   void xParseSEIAlternativeTransferCharacteristics(SEIAlternativeTransferCharacteristics& sei,              uint32_t payLoadSize,                     std::ostream *pDecodedMessageOutputStream);
 #endif
@@ -79,6 +81,14 @@ protected:
   void xParseSEIOmniViewport                  (SEIOmniViewport& sei,                  uint32_t payloadSize,                     std::ostream *pDecodedMessageOutputStream);
   void xParseSEIRegionWisePacking             (SEIRegionWisePacking& sei,             uint32_t payloadSize,                     std::ostream *pDecodedMessageOutputStream);
   void xParseSEIGeneralizedCubemapProjection  (SEIGeneralizedCubemapProjection &sei,  uint32_t payloadSize,                     std::ostream *pDecodedMessageOutputStream);
+  void xParseSEIScalabilityDimensionInfo      (SEIScalabilityDimensionInfo& sei,      uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream);
+  void xParseSEIMultiviewAcquisitionInfo      (SEIMultiviewAcquisitionInfo& sei,      uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream);
+#if JVET_W0078_MVP_SEI 
+  void xParseSEIMultiviewViewPosition         (SEIMultiviewViewPosition& sei,         uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream);
+#endif
+  void xParseSEIAlphaChannelInfo              (SEIAlphaChannelInfo& sei,              uint32_t payloadSize,                     std::ostream *pDecodedMessageOutputStream);
+  void xParseSEIDepthRepresentationInfo       (SEIDepthRepresentationInfo& sei,       uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream);
+  void xParseSEIDepthRepInfoElement           (double &f,std::ostream *pDecodedMessageOutputStream);
   void xParseSEISubpictureLevelInfo           (SEISubpicureLevelInfo& sei,            uint32_t payloadSize,                     std::ostream *pDecodedMessageOutputStream);
   void xParseSEISampleAspectRatioInfo         (SEISampleAspectRatioInfo& sei,         uint32_t payloadSize,                     std::ostream *pDecodedMessageOutputStream);
   void xParseSEIUserDataRegistered            (SEIUserDataRegistered& sei,            uint32_t payloadSize,                     std::ostream *pDecodedMessageOutputStream);
@@ -86,6 +96,11 @@ protected:
   void xParseSEIContentLightLevelInfo         (SEIContentLightLevelInfo& sei,         uint32_t payloadSize,                     std::ostream *pDecodedMessageOutputStream);
   void xParseSEIAmbientViewingEnvironment     (SEIAmbientViewingEnvironment& sei,     uint32_t payloadSize,                     std::ostream *pDecodedMessageOutputStream);
   void xParseSEIContentColourVolume           (SEIContentColourVolume& sei,           uint32_t payloadSize,                     std::ostream *pDecodedMessageOutputStream);
+  void xParseSEIExtendedDrapIndication        (SEIExtendedDrapIndication& sei,        uint32_t payloadSize,                     std::ostream *pDecodedMessageOutputStream);
+  void xParseSEIColourTransformInfo           (SEIColourTransformInfo& sei, uint32_t payloadSize, std::ostream* pDecodedMessageOutputStream);
+#if JVET_W0133_CONSTRAINED_RASL_ENCODING
+  void xParseSEIConstrainedRaslIndication     (SEIConstrainedRaslIndication& sei,     uint32_t payLoadSize,                     std::ostream *pDecodedMessageOutputStream);
+#endif
 
   void sei_read_scode(std::ostream *pOS, uint32_t length, int& code, const char *pSymbolName);
   void sei_read_code(std::ostream *pOS, uint32_t uiLength, uint32_t& ruiCode, const char *pSymbolName);
diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp
index 97651347a..83ccbe070 100644
--- a/source/Lib/DecoderLib/VLCReader.cpp
+++ b/source/Lib/DecoderLib/VLCReader.cpp
@@ -3,7 +3,7 @@
 * and contributor rights, including patent rights, and no such rights are
 * granted under this license.
 *
-* Copyright (c) 2010-2020, ITU/ISO/IEC
+* Copyright (c) 2010-2021, ITU/ISO/IEC
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
@@ -280,6 +280,9 @@ void FDReader::parseFillerData(InputBitstream* bs, uint32_t &fdSize)
 
 HLSyntaxReader::HLSyntaxReader()
 {
+#if GDR_ENABLED
+  m_lastGdrPoc = -1;
+#endif
 }
 
 HLSyntaxReader::~HLSyntaxReader()
@@ -440,6 +443,7 @@ void HLSyntaxReader::parsePPS( PPS* pcPPS )
     READ_UVLC(uiCode, "pps_conf_win_bottom_offset");             conf.setWindowBottomOffset(uiCode);
   }
   READ_FLAG( uiCode, "pps_scaling_window_explicit_signalling_flag" );
+  pcPPS->setExplicitScalingWindowFlag( uiCode );
   if( uiCode != 0 )
   {
     Window &scalingWindow = pcPPS->getScalingWindow();
@@ -563,7 +567,7 @@ void HLSyntaxReader::parsePPS( PPS* pcPPS )
         }
 
         if( tileIdx / pcPPS->getNumTileColumns() != pcPPS->getNumTileRows() - 1  &&
-         ( pcPPS->getTileIdxDeltaPresentFlag() || tileIdx % pcPPS->getNumTileColumns() == 0 ) ) 
+         ( pcPPS->getTileIdxDeltaPresentFlag() || tileIdx % pcPPS->getNumTileColumns() == 0 ) )
         {
           READ_UVLC( uiCode, "pps_slice_height_in_tiles_minus1[i]" );
           pcPPS->setSliceHeightInTiles( i, uiCode + 1 );
@@ -689,7 +693,7 @@ void HLSyntaxReader::parsePPS( PPS* pcPPS )
   READ_FLAG(uiCode, "pps_ref_wraparound_enabled_flag");           pcPPS->setWrapAroundEnabledFlag( uiCode ? true : false );
   if (pcPPS->getWrapAroundEnabledFlag())
   {
-    READ_UVLC(uiCode, "pps_ref_wraparound_offset");               
+    READ_UVLC(uiCode, "pps_ref_wraparound_offset");
     pcPPS->setPicWidthMinusWrapAroundOffset(uiCode);
   }
   else
@@ -1194,12 +1198,8 @@ void HLSyntaxReader::parseGeneralHrdParameters(GeneralHrdParams *hrd)
   READ_CODE(32, symbol, "time_scale");                       hrd->setTimeScale(symbol);
   READ_FLAG(symbol, "general_nal_hrd_parameters_present_flag");           hrd->setGeneralNalHrdParametersPresentFlag(symbol == 1 ? true : false);
   READ_FLAG(symbol, "general_vcl_hrd_parameters_present_flag");           hrd->setGeneralVclHrdParametersPresentFlag(symbol == 1 ? true : false);
-#if JVET_S0175_ASPECT6
   if(  hrd->getGeneralNalHrdParametersPresentFlag() || hrd->getGeneralVclHrdParametersPresentFlag() )
   {
-#else
-  CHECK((hrd->getGeneralNalHrdParametersPresentFlag() == 0) && (hrd->getGeneralVclHrdParametersPresentFlag() == 0), "general_nal_hrd_params_present_flag and general_vcl_hrd_params_present_flag in each general_hrd_parameters( ) syntax structure shall not be both equal to 0.");
-#endif
     READ_FLAG(symbol, "general_same_pic_timing_in_all_ols_flag");           hrd->setGeneralSamePicTimingInAllOlsFlag(symbol == 1 ? true : false);
     READ_FLAG(symbol, "general_decoding_unit_hrd_params_present_flag");     hrd->setGeneralDecodingUnitHrdParamsPresentFlag(symbol == 1 ? true : false);
     if (hrd->getGeneralDecodingUnitHrdParamsPresentFlag())
@@ -1214,9 +1214,7 @@ void HLSyntaxReader::parseGeneralHrdParameters(GeneralHrdParams *hrd)
     }
     READ_UVLC(symbol, "hrd_cpb_cnt_minus1");                      hrd->setHrdCpbCntMinus1(symbol);
     CHECK(symbol > 31,"The value of hrd_cpb_cnt_minus1 shall be in the range of 0 to 31, inclusive");
-#if JVET_S0175_ASPECT6
   }
-#endif
 }
 void HLSyntaxReader::parseOlsHrdParameters(GeneralHrdParams * generalHrd, OlsHrdParams *olsHrd, uint32_t firstSubLayer, uint32_t maxNumSubLayersMinus1)
 {
@@ -1241,11 +1239,7 @@ void HLSyntaxReader::parseOlsHrdParameters(GeneralHrdParams * generalHrd, OlsHrd
     {
       READ_UVLC(symbol, "elemental_duration_in_tc_minus1");             hrd->setElementDurationInTcMinus1(symbol);
     }
-#if JVET_S0175_ASPECT6
     else if((generalHrd->getGeneralNalHrdParametersPresentFlag() || generalHrd->getGeneralVclHrdParametersPresentFlag()) && generalHrd->getHrdCpbCntMinus1() == 0)
-#else
-    else if(generalHrd->getHrdCpbCntMinus1() == 0)
-#endif
     {
       READ_FLAG(symbol, "low_delay_hrd_flag");                      hrd->setLowDelayHrdFlag(symbol == 1 ? true : false);
     }
@@ -1316,6 +1310,16 @@ void HLSyntaxReader::dpb_parameters(int maxSubLayersMinus1, bool subLayerInfoFla
     READ_UVLC(code, "dpb_max_latency_increase_plus1[i]");
     pcSPS->setMaxLatencyIncreasePlus1(code, i);
   }
+
+  if (!subLayerInfoFlag)
+  {
+    for(int i = 0; i < maxSubLayersMinus1; ++i)
+    {
+      pcSPS->setMaxDecPicBuffering(pcSPS->getMaxDecPicBuffering(maxSubLayersMinus1), i);
+      pcSPS->setMaxNumReorderPics(pcSPS->getMaxNumReorderPics(maxSubLayersMinus1), i);
+      pcSPS->setMaxLatencyIncreasePlus1(pcSPS->getMaxLatencyIncreasePlus1(maxSubLayersMinus1), i);
+    }
+  }
 }
 
 
@@ -1357,12 +1361,10 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS)
   READ_FLAG(uiCode, "sps_gdr_enabled_flag");
   pcSPS->setGDREnabledFlag(uiCode);
 
-#if JVET_R0266_GCI
   if (pcSPS->getProfileTierLevel()->getConstraintInfo()->getNoGdrConstraintFlag())
   {
     CHECK(uiCode != 0, "When gci_no_gdr_constraint_flag equal to 1 , the value of sps_gdr_enabled_flag shall be equal to 0");
   }
-#endif
 
   READ_FLAG(uiCode, "sps_ref_pic_resampling_enabled_flag");          pcSPS->setRprEnabledFlag(uiCode);
   if (pcSPS->getProfileTierLevel()->getConstraintInfo()->getNoRprConstraintFlag())
@@ -1546,7 +1548,7 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS)
   READ_FLAG( uiCode, "sps_entry_point_offsets_present_flag");   pcSPS->setEntryPointsPresentFlag(uiCode == 1);
   READ_CODE(4, uiCode, "sps_log2_max_pic_order_cnt_lsb_minus4");     pcSPS->setBitsForPOC( 4 + uiCode );
   CHECK(uiCode > 12, "sps_log2_max_pic_order_cnt_lsb_minus4 shall be in the range of 0 to 12");
-  
+
   READ_FLAG(uiCode, "sps_poc_msb_cycle_flag");                    pcSPS->setPocMsbCycleFlag(uiCode ? true : false);
   if (pcSPS->getPocMsbCycleFlag())
   {
@@ -1786,7 +1788,7 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS)
     for (uint32_t ii = 0; ii < numberOfRPL; ii++)
       copyRefPicList(pcSPS, rplListSource->getReferencePictureList(ii), rplListDest->getReferencePictureList(ii));
   }
-  
+
 
   READ_FLAG(uiCode, "sps_ref_wraparound_enabled_flag");                  pcSPS->setWrapAroundEnabledFlag( uiCode ? true : false );
 
@@ -1922,6 +1924,10 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS)
     pcSPS->setVerCollocatedChromaFlag(true);
   }
   READ_FLAG( uiCode,  "sps_palette_enabled_flag");                                pcSPS->setPLTMode                ( uiCode != 0 );
+#if JVET_W2005_RANGE_EXTENSION_PROFILES
+  CHECK((profile == Profile::MAIN_12 || profile == Profile::MAIN_12_INTRA || profile == Profile::MAIN_12_STILL_PICTURE)
+    && uiCode != 0, "sps_palette_enabled_flag shall be equal to 0 for Main 12 (420) profiles");
+#endif
   if (pcSPS->getChromaFormatIdc() == CHROMA_444 && pcSPS->getLog2MaxTbSize() != 6)
   {
     READ_FLAG(uiCode, "sps_act_enabled_flag");                                pcSPS->setUseColorTrans(uiCode != 0);
@@ -2076,6 +2082,7 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS)
   // KJS: no SPS extensions defined yet
 
   READ_FLAG( uiCode, "sps_extension_present_flag");
+
   if (uiCode)
   {
 #if ENABLE_TRACING || RExt__DECODER_DEBUG_BIT_STATISTICS
@@ -2096,6 +2103,12 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS)
       sps_extension_flags[i] = uiCode!=0;
     }
 
+#if JVET_W0178_CONSTRAINTS_ON_REXT_TOOLS
+    if (pcSPS->getBitDepth(CHANNEL_TYPE_LUMA) <= 10)
+      CHECK(sps_extension_flags[SPS_EXT__REXT] == 1,
+            "The value of sps_range_extension_flag shall be 0 when BitDepth is less than or equal to 10.");
+#endif
+
     bool bSkipTrailingExtensionBits=false;
     for(int i=0; i<NUM_SPS_EXTENSION_FLAGS; i++) // loop used so that the order is determined by the enum.
     {
@@ -2107,13 +2120,31 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS)
           CHECK(bSkipTrailingExtensionBits, "Skipping trailing extension bits not supported");
           {
             SPSRExt &spsRangeExtension = pcSPS->getSpsRangeExtension();
+#if !JVET_W2005_RANGE_EXTENSION_PROFILES
             READ_FLAG( uiCode, "transform_skip_rotation_enabled_flag");     spsRangeExtension.setTransformSkipRotationEnabledFlag(uiCode != 0);
             READ_FLAG( uiCode, "transform_skip_context_enabled_flag");      spsRangeExtension.setTransformSkipContextEnabledFlag (uiCode != 0);
+#endif
             READ_FLAG( uiCode, "extended_precision_processing_flag");       spsRangeExtension.setExtendedPrecisionProcessingFlag (uiCode != 0);
+#if JVET_W0070_W0121_SPSRE_CLEANUP
+            if (pcSPS->getTransformSkipEnabledFlag()) 
+            {
+              READ_FLAG( uiCode, "sps_ts_residual_coding_rice_present_in_sh_flag"); spsRangeExtension.setTSRCRicePresentFlag(uiCode != 0);
+            }
+#else
+            READ_FLAG( uiCode, "sps_ts_residual_coding_rice_present_in_sh_flag"); spsRangeExtension.setTSRCRicePresentFlag(uiCode != 0);
+#endif
+#if !JVET_W2005_RANGE_EXTENSION_PROFILES
             READ_FLAG( uiCode, "intra_smoothing_disabled_flag");            spsRangeExtension.setIntraSmoothingDisabledFlag      (uiCode != 0);
             READ_FLAG( uiCode, "high_precision_offsets_enabled_flag");      spsRangeExtension.setHighPrecisionOffsetsEnabledFlag (uiCode != 0);
+#endif
+            READ_FLAG(uiCode,  "rrc_rice_extension_flag");                  spsRangeExtension.setRrcRiceExtensionEnableFlag      (uiCode != 0);
             READ_FLAG( uiCode, "persistent_rice_adaptation_enabled_flag");  spsRangeExtension.setPersistentRiceAdaptationEnabledFlag (uiCode != 0);
+#if JVET_W0046_RLSCP
+            READ_FLAG( uiCode, "reverse_last_position_enabled_flag");       spsRangeExtension.setReverseLastSigCoeffEnabledFlag(uiCode != 0);
+#endif
+#if !JVET_W2005_RANGE_EXTENSION_PROFILES
             READ_FLAG( uiCode, "cabac_bypass_alignment_enabled_flag");      spsRangeExtension.setCabacBypassAlignmentEnabledFlag  (uiCode != 0);
+#endif
           }
           break;
         default:
@@ -2133,7 +2164,6 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS)
   xReadRbspTrailingBits();
 }
 
-#if JVET_S0163_ON_TARGETOLS_SUBLAYERS
 void HLSyntaxReader::parseOPI(OPI* opi)
 {
 #if ENABLE_TRACING
@@ -2146,13 +2176,13 @@ void HLSyntaxReader::parseOPI(OPI* opi)
   READ_FLAG(symbol, "opi_htid_info_present_flag");
   opi->setHtidInfoPresentFlag(symbol);
 
-  if (opi->getOlsInfoPresentFlag()) 
+  if (opi->getOlsInfoPresentFlag())
   {
-    READ_UVLC(symbol, "opi_ols_idx");  
+    READ_UVLC(symbol, "opi_ols_idx");
     opi->setOpiOlsIdx(symbol);
   }
 
-  if (opi->getHtidInfoPresentFlag()) 
+  if (opi->getHtidInfoPresentFlag())
   {
     READ_CODE(3, symbol, "opi_htid_plus1");
     opi->setOpiHtidPlus1(symbol);
@@ -2168,7 +2198,6 @@ void HLSyntaxReader::parseOPI(OPI* opi)
   }
   xReadRbspTrailingBits();
 }
-#endif
 
 
 void HLSyntaxReader::parseDCI(DCI* dci)
@@ -2236,11 +2265,9 @@ void HLSyntaxReader::parseVPS(VPS* pcVPS)
       pcVPS->setEachLayerIsAnOlsFlag(0);
     }
   }
-#if JVET_R0193
   std::vector<std::vector<uint32_t>> maxTidilRefPicsPlus1;
   maxTidilRefPicsPlus1.resize(pcVPS->getMaxLayers(), std::vector<uint32_t>(pcVPS->getMaxLayers(), NOT_VALID));
   pcVPS->setMaxTidIlRefPicsPlus1(maxTidilRefPicsPlus1);
-#endif
   for (uint32_t i = 0; i < pcVPS->getMaxLayers(); i++)
   {
     READ_CODE(6, uiCode, "vps_layer_id");                     pcVPS->setLayerId(i, uiCode);
@@ -2251,7 +2278,6 @@ void HLSyntaxReader::parseVPS(VPS* pcVPS)
       READ_FLAG(uiCode, "vps_independent_layer_flag");     pcVPS->setIndependentLayerFlag(i, uiCode);
       if (!pcVPS->getIndependentLayerFlag(i))
       {
-#if JVET_R0193
         READ_FLAG(uiCode, "max_tid_ref_present_flag[ i ]");
         bool presentFlag = uiCode;
         uint16_t sumUiCode = 0;
@@ -2275,30 +2301,6 @@ void HLSyntaxReader::parseVPS(VPS* pcVPS)
           }
         }
         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 ");
-#else
-        uint16_t sumUiCode = 0;
-        for (int j = 0, k = 0; j < i; j++)
-        {
-          READ_FLAG(uiCode, "vps_direct_dependency_flag"); pcVPS->setDirectRefLayerFlag(i, j, uiCode);
-          if( uiCode )
-          {
-            pcVPS->setInterLayerRefIdc( i, j, k );
-            pcVPS->setDirectRefLayerIdx( i, k++, j );
-            sumUiCode++;
-          }
-        }
-        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 ");
-        READ_FLAG(uiCode, "vps_max_tid_ref_present_flag[ i ]");
-        if (uiCode)
-        {
-          READ_CODE(3, uiCode, "vps_max_tid_il_ref_pics_plus1[ i ]");
-          pcVPS->setMaxTidIlRefPicsPlus1(i, uiCode);
-        }
-        else
-        {
-          pcVPS->setMaxTidIlRefPicsPlus1(i, 7);
-        }
-#endif
       }
     }
   }
@@ -2372,7 +2374,7 @@ void HLSyntaxReader::parseVPS(VPS* pcVPS)
   ptls.resize(pcVPS->getNumPtls());
   for (int i = 0; i < pcVPS->getNumPtls(); i++)
   {
-    parseProfileTierLevel(&ptls[i], pcVPS->getPtPresentFlag(i), pcVPS->getPtlMaxTemporalId(i) - 1);
+    parseProfileTierLevel(&ptls[i], pcVPS->getPtPresentFlag(i), pcVPS->getPtlMaxTemporalId(i));
   }
   pcVPS->setProfileTierLevel(ptls);
   for (int i = 0; i < pcVPS->getTotalNumOLSs(); i++)
@@ -2647,7 +2649,7 @@ void HLSyntaxReader::parsePictureHeader( PicHeader* picHeader, ParameterSetManag
       {
         READ_CODE(3, uiCode, "ph_num_alf_aps_ids_luma");
         int numAps = uiCode;
-        picHeader->setNumAlfAps(numAps);
+        picHeader->setNumAlfApsIdsLuma(numAps);
 
         std::vector<int> apsId(numAps, -1);
         for (int i = 0; i < numAps; i++)
@@ -2655,7 +2657,7 @@ void HLSyntaxReader::parsePictureHeader( PicHeader* picHeader, ParameterSetManag
           READ_CODE(3, uiCode, "ph_alf_aps_id_luma");
           apsId[i] = uiCode;
         }
-        picHeader->setAlfAPSs(apsId);
+        picHeader->setAlfApsIdsLuma(apsId);
 
         if (sps->getChromaFormatIdc() != CHROMA_400)
         {
@@ -2697,7 +2699,7 @@ void HLSyntaxReader::parsePictureHeader( PicHeader* picHeader, ParameterSetManag
       }
       else
       {
-        picHeader->setNumAlfAps(0);
+        picHeader->setNumAlfApsIdsLuma(0);
       }
       picHeader->setAlfEnabledFlag(COMPONENT_Cb, alfCbEnabledFlag);
       picHeader->setAlfEnabledFlag(COMPONENT_Cr, alfCrEnabledFlag);
@@ -2764,7 +2766,12 @@ void HLSyntaxReader::parsePictureHeader( PicHeader* picHeader, ParameterSetManag
     pps->getConformanceWindow().setWindowRightOffset(sps->getConformanceWindow().getWindowRightOffset());
     pps->getConformanceWindow().setWindowTopOffset(sps->getConformanceWindow().getWindowTopOffset());
     pps->getConformanceWindow().setWindowBottomOffset(sps->getConformanceWindow().getWindowBottomOffset());
+    if (!pps->getExplicitScalingWindowFlag())
+    {
+      pps->setScalingWindow(pps->getConformanceWindow());
+    }
   }
+  CHECK(!sps->getRprEnabledFlag() && pps->getExplicitScalingWindowFlag(), "When sps_ref_pic_resampling_enabled_flag is equal to 0, the value of pps_scaling_window_explicit_signalling_flag shall be equal to 0");
 
   // initialize tile/slice info for no partitioning case
 
@@ -2832,6 +2839,11 @@ void HLSyntaxReader::parsePictureHeader( PicHeader* picHeader, ParameterSetManag
         READ_UVLC(uiCode, "ph_virtual_boundary_pos_x_minus1[i]");        picHeader->setVirtualBoundariesPosX((uiCode + 1) << 3, i);
         CHECK(uiCode > (((pps->getPicWidthInLumaSamples() + 7) >> 3) - 2), "The value of ph_virtual_boundary_pos_x_minus1[ i ] shall be in the range of 0 to Ceil( pps_pic_width_in_luma_samples / 8 ) - 2, inclusive.");
       }
+#if GDR_DEC_TRACE
+      printf("\n");
+      printf("-num_ver_boundary :%d\n", picHeader->getNumVerVirtualBoundaries());
+      printf("-vir_boundary_pos :%d\n", picHeader->getVirtualBoundariesPosX(0));
+#endif
       READ_UVLC(uiCode, "ph_num_hor_virtual_boundaries");        picHeader->setNumHorVirtualBoundaries( uiCode );
       if (pps->getPicHeightInLumaSamples() <= 8)
       {
@@ -2937,12 +2949,10 @@ void HLSyntaxReader::parsePictureHeader( PicHeader* picHeader, ParameterSetManag
           *rpl = *sps->getRPLList( listIdx )->getReferencePictureList(picHeader->getRPLIdx( listIdx ));
         }
       }
-#if JVET_S0096_RPL_CONSTRAINT
       if (picHeader->getPicInterSliceAllowedFlag() && listIdx == 0)
       {
           CHECK(picHeader->getRPL(0)->getNumRefEntries() <= 0, "When pps_rpl_info_in_ph_flag is equal to 1 and ph_inter_slice_allowed_flag is equal to 1, the value of num_ref_entries[ 0 ][ RplsIdx[ 0 ] ] shall be greater than 0");
       }
-#endif
       // POC MSB cycle signalling for LTRP
       for (int i = 0; i < rpl->getNumberOfLongtermPictures() + rpl->getNumberOfShorttermPictures(); i++)
       {
@@ -3404,12 +3414,12 @@ void  HLSyntaxReader::checkAlfNaluTidAndPicTid(Slice* pcSlice, PicHeader* picHea
   PPS* pps = parameterSetManager->getPPS(picHeader->getPPSId());
   int curPicTid = pcSlice->getTLayer();
   APS* aps;
-  const std::vector<int>&   apsId = picHeader->getAlfAPSs();
+  const std::vector<int>&   apsId = picHeader->getAlfApsIdsLuma();
 
   if (sps->getALFEnabledFlag() && pps->getAlfInfoInPhFlag() && picHeader->getAlfEnabledFlag(COMPONENT_Y))
   {
     //luma
-    for (int i = 0; i < picHeader->getNumAlfAps(); i++)
+    for (int i = 0; i < picHeader->getNumAlfApsIdsLuma(); i++)
     {
       aps = parameterSetManager->getAPS(apsId[i], ALF_APS);
       CHECK(aps->getTemporalId() > curPicTid, "The TemporalId of the APS NAL unit having aps_params_type equal to ALF_APS and adaptation_parameter_set_id equal to ph_alf_aps_id_luma[ i ] shall be less than or equal to the TemporalId of the picture associated with the PH.");
@@ -3665,7 +3675,7 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, PicHeader* picHeader, Par
   if (sps->getALFEnabledFlag() && !pps->getAlfInfoInPhFlag())
   {
     READ_FLAG(uiCode, "sh_alf_enabled_flag");
-    pcSlice->setTileGroupAlfEnabledFlag(COMPONENT_Y, uiCode);
+    pcSlice->setAlfEnabledFlag(COMPONENT_Y, uiCode);
     int alfCbEnabledFlag = 0;
     int alfCrEnabledFlag = 0;
 
@@ -3673,7 +3683,7 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, PicHeader* picHeader, Par
     {
       READ_CODE(3, uiCode, "sh_num_alf_aps_ids_luma");
       int numAps = uiCode;
-      pcSlice->setTileGroupNumAps(numAps);
+      pcSlice->setNumAlfApsIdsLuma(numAps);
       std::vector<int> apsId(numAps, -1);
       for (int i = 0; i < numAps; i++)
       {
@@ -3685,7 +3695,7 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, PicHeader* picHeader, Par
       }
 
 
-      pcSlice->setAlfAPSs(apsId);
+      pcSlice->setAlfApsIdsLuma(apsId);
       if (bChroma)
       {
         READ_CODE(1, uiCode, "sh_alf_cb_enabled_flag");   alfCbEnabledFlag = uiCode;
@@ -3699,7 +3709,7 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, PicHeader* picHeader, Par
       if (alfCbEnabledFlag || alfCrEnabledFlag)
       {
         READ_CODE(3, uiCode, "sh_alf_aps_id_chroma");
-        pcSlice->setTileGroupApsIdChroma(uiCode);
+        pcSlice->setAlfApsIdChroma(uiCode);
         APS* APStoCheckChroma = parameterSetManager->getAPS(uiCode, ALF_APS);
         CHECK(APStoCheckChroma == nullptr, "referenced APS not found");
         CHECK(APStoCheckChroma->getAlfAPSParam().newFilterFlag[CHANNEL_TYPE_CHROMA] != 1, "bitstream conformance error, alf_chroma_filter_signal_flag shall be equal to 1");
@@ -3707,42 +3717,42 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, PicHeader* picHeader, Par
     }
     else
     {
-      pcSlice->setTileGroupNumAps(0);
+      pcSlice->setNumAlfApsIdsLuma(0);
     }
-    pcSlice->setTileGroupAlfEnabledFlag(COMPONENT_Cb, alfCbEnabledFlag);
-    pcSlice->setTileGroupAlfEnabledFlag(COMPONENT_Cr, alfCrEnabledFlag);
+    pcSlice->setAlfEnabledFlag(COMPONENT_Cb, alfCbEnabledFlag);
+    pcSlice->setAlfEnabledFlag(COMPONENT_Cr, alfCrEnabledFlag);
 
     CcAlfFilterParam &filterParam = pcSlice->m_ccAlfFilterParam;
-    if (sps->getCCALFEnabledFlag() && pcSlice->getTileGroupAlfEnabledFlag(COMPONENT_Y))
+    if (sps->getCCALFEnabledFlag() && pcSlice->getAlfEnabledFlag(COMPONENT_Y))
     {
       READ_FLAG(uiCode, "sh_alf_cc_cb_enabled_flag");
-      pcSlice->setTileGroupCcAlfCbEnabledFlag(uiCode);
+      pcSlice->setCcAlfCbEnabledFlag(uiCode);
       filterParam.ccAlfFilterEnabled[COMPONENT_Cb - 1] = (uiCode == 1) ? true : false;
-      pcSlice->setTileGroupCcAlfCbApsId(-1);
+      pcSlice->setCcAlfCbApsId(-1);
       if (filterParam.ccAlfFilterEnabled[COMPONENT_Cb - 1])
       {
         // parse APS ID
         READ_CODE(3, uiCode, "sh_alf_cc_cb_aps_id");
-        pcSlice->setTileGroupCcAlfCbApsId(uiCode);
+        pcSlice->setCcAlfCbApsId(uiCode);
       }
       // Cr
       READ_FLAG(uiCode, "sh_alf_cc_cr_enabled_flag");
-      pcSlice->setTileGroupCcAlfCrEnabledFlag(uiCode);
+      pcSlice->setCcAlfCrEnabledFlag(uiCode);
       filterParam.ccAlfFilterEnabled[COMPONENT_Cr - 1] = (uiCode == 1) ? true : false;
-      pcSlice->setTileGroupCcAlfCrApsId(-1);
+      pcSlice->setCcAlfCrApsId(-1);
       if (filterParam.ccAlfFilterEnabled[COMPONENT_Cr - 1])
       {
         // parse APS ID
         READ_CODE(3, uiCode, "sh_alf_cc_cr_aps_id");
-        pcSlice->setTileGroupCcAlfCrApsId(uiCode);
+        pcSlice->setCcAlfCrApsId(uiCode);
       }
     }
     else
     {
       filterParam.ccAlfFilterEnabled[COMPONENT_Cb - 1] = false;
       filterParam.ccAlfFilterEnabled[COMPONENT_Cr - 1] = false;
-      pcSlice->setTileGroupCcAlfCbApsId(-1);
-      pcSlice->setTileGroupCcAlfCrApsId(-1);
+      pcSlice->setCcAlfCbApsId(-1);
+      pcSlice->setCcAlfCrApsId(-1);
     }
   }
   if (picHeader->getLmcsEnabledFlag() && !pcSlice->getPictureHeaderInSliceHeader())
@@ -3883,10 +3893,12 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, PicHeader* picHeader, Par
         {
           int numBits = ceilLog2(sps->getNumRPL1());
           READ_CODE(numBits, uiCode, "ref_pic_list_idx[1]");
+          pcSlice->setRPL1idx(uiCode);
           *rpl1 = *sps->getRPLList1()->getReferencePictureList(uiCode);
         }
         else if (sps->getNumRPL(1) == 1)
         {
+          pcSlice->setRPL1idx(0);
           *rpl1 = *sps->getRPLList1()->getReferencePictureList(0);
         }
         else
@@ -4282,6 +4294,22 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, PicHeader* picHeader, Par
     pcSlice->setTSResidualCodingDisabledFlag( false );
   }
 
+  if ((!pcSlice->getTSResidualCodingDisabledFlag()) && sps->getSpsRangeExtension().getTSRCRicePresentFlag())
+  {
+    READ_CODE(3, uiCode, "sh_ts_residual_coding_rice_idx_minus1");
+    pcSlice->set_tsrc_index(uiCode);
+  }
+#if JVET_W0046_RLSCP
+  if (sps->getSpsRangeExtension().getReverseLastSigCoeffEnabledFlag())
+  {
+    READ_FLAG(uiCode, "sh_reverse_last_sig_coeff_flag");
+    pcSlice->setReverseLastSigCoeffFlag(uiCode != 0);
+  }
+  else {
+    pcSlice->setReverseLastSigCoeffFlag(false);
+  }
+#endif
+
   if( pcSlice->getFirstCtuRsAddrInSlice() == 0 )
   {
     pcSlice->setDefaultClpRng( *sps );
@@ -4358,6 +4386,37 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, PicHeader* picHeader, Par
       pcSlice->addSubstreamSize(entryPointOffset [ idx ] );
     }
   }
+#if GDR_ENABLED
+  int curPoc = pcSlice->getPOC();
+
+  if (picHeader->getGdrPicFlag())
+  {
+    setLastGdrPoc(curPoc);
+    setLastGdrRecoveryPocCnt(pcSlice->getPicHeader()->getRecoveryPocCnt());
+  }
+
+  int recoveryPocCnt = getLastGdrRecoveryPocCnt();
+
+  if (getLastGdrPoc() > 0 && (getLastGdrPoc() <= curPoc) && (curPoc < (getLastGdrPoc() + recoveryPocCnt)))
+  {
+    picHeader->setInGdrInterval(true);
+  }
+  else
+  {
+    picHeader->setInGdrInterval(false);
+  }
+#endif
+
+#if GDR_DEC_TRACE
+  printf("-gdr_pic_flag:%d\n", picHeader->getGdrPicFlag() ? 1 : 0);
+  printf("-recovery_poc_cnt:%d\n", picHeader->getRecoveryPocCnt());
+#if GDR_ENABLED
+  printf("-inGdrInterval:%d\n", picHeader->getInGdrInterval());
+#endif
+
+  printf("-lmcs_enable : %d\n", picHeader->getLmcsEnabledFlag() ? 1 : 0);
+  printf("-lmcs_chroma : %d\n", picHeader->getLmcsChromaResidualScaleFlag() ? 1 : 0);
+#endif
   return;
 }
 
@@ -4446,7 +4505,11 @@ void HLSyntaxReader::getSlicePoc(Slice* pcSlice, PicHeader* picHeader, Parameter
   DTRACE_UPDATE( g_trace_ctx, std::make_pair( "final", 1 ) );
 }
 
+#if JVET_W2005_RANGE_EXTENSION_PROFILES
+void HLSyntaxReader::parseConstraintInfo(ConstraintInfo *cinfo, const ProfileTierLevel* ptl )
+#else
 void HLSyntaxReader::parseConstraintInfo(ConstraintInfo *cinfo)
+#endif
 {
   uint32_t symbol;
   READ_FLAG(symbol, "gci_present_flag"); cinfo->setGciPresentFlag(symbol ? true : false);
@@ -4455,7 +4518,7 @@ void HLSyntaxReader::parseConstraintInfo(ConstraintInfo *cinfo)
     /* general */
     READ_FLAG(symbol, "gci_intra_only_constraint_flag");                 cinfo->setIntraOnlyConstraintFlag(symbol ? true : false);
     READ_FLAG(symbol, "gci_all_layers_independent_constraint_flag");     cinfo->setAllLayersIndependentConstraintFlag(symbol ? true : false);
-    READ_FLAG(symbol, "gci_one_au_only_constraint_flag");                cinfo->setOnePictureOnlyConstraintFlag(symbol ? true : false); 
+    READ_FLAG(symbol, "gci_one_au_only_constraint_flag");                cinfo->setOnePictureOnlyConstraintFlag(symbol ? true : false);
 
     /* picture format */
     READ_CODE(4, symbol, "gci_sixteen_minus_max_bitdepth_constraint_idc"); cinfo->setMaxBitDepthConstraintIdc(symbol>8 ? 16 : (16 - symbol));
@@ -4538,7 +4601,24 @@ void HLSyntaxReader::parseConstraintInfo(ConstraintInfo *cinfo)
     READ_FLAG(symbol, "gci_no_virtual_boundaries_constraint_flag");      cinfo->setNoVirtualBoundaryConstraintFlag(symbol > 0 ? true : false);
     READ_CODE(8, symbol, "gci_num_reserved_bits");
     uint32_t const numReservedBits = symbol;
+#if JVET_W2005_RANGE_EXTENSION_PROFILES
+    int numReservedBitsUsed;
+    if (numReservedBits > 0)
+    {
+      READ_FLAG(symbol, "general_lower_bit_rate_constraint_flag");       cinfo->setLowerBitRateConstraintFlag(symbol > 0 ? true : false);
+      numReservedBitsUsed = 1;
+      Profile::Name profile = ptl->getProfileIdc();
+      CHECK((profile == Profile::MAIN_12 || profile == Profile::MAIN_12_444 || profile == Profile::MAIN_16_444) &&
+        symbol == 0, "general_lower_bitrate_constraint_flag shall be equal to 1 for non-Intra/Still Picture operation range extension profiles.");
+    }
+    else
+    {
+      numReservedBitsUsed = 0;
+    }
+    for (int i = 0; i < numReservedBits - numReservedBitsUsed; i++)
+#else
     for (int i = 0; i < numReservedBits; i++)
+#endif
     {
       READ_FLAG(symbol, "gci_reserved_zero_bit");                    CHECK(symbol != 0, "gci_reserved_zero_bit not equal to zero");
     }
@@ -4571,7 +4651,11 @@ void HLSyntaxReader::parseProfileTierLevel(ProfileTierLevel *ptl, bool profileTi
 
   if(profileTierPresentFlag)
   {
+#if JVET_W2005_RANGE_EXTENSION_PROFILES
+    parseConstraintInfo(ptl->getConstraintInfo(), ptl);
+#else
     parseConstraintInfo(ptl->getConstraintInfo());
+#endif
   }
 
   for (int i = maxNumSubLayersMinus1 - 1; i >= 0; i--)
diff --git a/source/Lib/DecoderLib/VLCReader.h b/source/Lib/DecoderLib/VLCReader.h
index dfd0b53ad..ae4370199 100644
--- a/source/Lib/DecoderLib/VLCReader.h
+++ b/source/Lib/DecoderLib/VLCReader.h
@@ -3,7 +3,7 @@
 * and contributor rights, including patent rights, and no such rights are
 * granted under this license.
 *
-* Copyright (c) 2010-2020, ITU/ISO/IEC
+* Copyright (c) 2010-2021, ITU/ISO/IEC
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
@@ -146,6 +146,11 @@ public:
 
 class HLSyntaxReader : public VLCReader
 {
+#if GDR_ENABLED
+  int m_lastGdrPoc;
+  int m_lastGdrRecoveryPocCnt;
+#endif
+
 public:
   HLSyntaxReader();
   virtual ~HLSyntaxReader();
@@ -155,10 +160,14 @@ protected:
   void  parseRefPicList(SPS* pcSPS, ReferencePictureList* rpl, int rplIdx);
 
 public:
+#if GDR_ENABLED
+  void setLastGdrPoc(int poc) { m_lastGdrPoc = poc;  }
+  int  getLastGdrPoc()        { return m_lastGdrPoc; }
+  void setLastGdrRecoveryPocCnt(int recoveryPocCnt) { m_lastGdrRecoveryPocCnt = recoveryPocCnt; }
+  int  getLastGdrRecoveryPocCnt()                     { return m_lastGdrRecoveryPocCnt; }
+#endif
   void  setBitstream        ( InputBitstream* p )   { m_pcBitstream = p; }
-#if JVET_S0163_ON_TARGETOLS_SUBLAYERS
   void  parseOPI            ( OPI* opi );
-#endif
   void  parseVPS            ( VPS* pcVPS );
   void  parseDCI            ( DCI* dci );
   void  parseSPS            ( SPS* pcSPS );
@@ -168,7 +177,11 @@ public:
   void  parseLmcsAps        ( APS* pcAPS );
   void  parseScalingListAps ( APS* pcAPS );
   void  parseVUI            ( VUI* pcVUI, SPS* pcSPS );
+#if JVET_W2005_RANGE_EXTENSION_PROFILES
+  void  parseConstraintInfo (ConstraintInfo *cinfo, const ProfileTierLevel* ptl );
+#else
   void  parseConstraintInfo   (ConstraintInfo *cinfo);
+#endif
   void  parseProfileTierLevel(ProfileTierLevel *ptl, bool profileTierPresentFlag, int maxNumSubLayersMinus1);
   void  parseOlsHrdParameters(GeneralHrdParams* generalHrd, OlsHrdParams *olsHrd, uint32_t firstSubLayer, uint32_t tempLevelHigh);
   void parseGeneralHrdParameters(GeneralHrdParams *generalHrd);
diff --git a/source/Lib/EncoderLib/AQp.cpp b/source/Lib/EncoderLib/AQp.cpp
index a157e1c85..6f7150380 100644
--- a/source/Lib/EncoderLib/AQp.cpp
+++ b/source/Lib/EncoderLib/AQp.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/EncoderLib/AQp.h b/source/Lib/EncoderLib/AQp.h
index 4e62ed1ee..b6f7f60a6 100644
--- a/source/Lib/EncoderLib/AQp.h
+++ b/source/Lib/EncoderLib/AQp.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/EncoderLib/Analyze.h b/source/Lib/EncoderLib/Analyze.h
index d17b9fa09..9ef8471aa 100644
--- a/source/Lib/EncoderLib/Analyze.h
+++ b/source/Lib/EncoderLib/Analyze.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -99,8 +99,8 @@ public:
 
     m_uiNumPic++;
   }
-#if ENABLE_QPA
-  double  getWPSNR      (const ComponentID compID) const { return m_dPSNRSum[compID] / (double)m_uiNumPic; }
+#if ENABLE_QPA || JVET_W0134_UNIFORM_METRICS_LOG
+  double  getWPSNR(const ComponentID compID) const { return m_dPSNRSum[compID] / (double)m_uiNumPic; }
 #endif
   double  getPsnr(ComponentID compID) const { return  m_dPSNRSum[compID];  }
   double  getMsssim(ComponentID compID) const { return  m_msssim[compID];  }
@@ -189,8 +189,156 @@ public:
     PSNRyuv = (MSEyuv == 0) ? 999.99 : 10.0 * log10((maxval * maxval) / MSEyuv);
   }
 
-#if ENABLE_QPA || WCG_WPSNR
-  void    printOut( char cDelim, const ChromaFormat chFmt, const bool printMSEBasedSNR, const bool printSequenceMSE, const bool printMSSSIM, 
+#if JVET_W0134_UNIFORM_METRICS_LOG
+  void printOut(std::string &header, std::string &metrics, const std::string &delim, ChromaFormat chFmt,
+                bool printMSEBasedSNR, bool printSequenceMSE, bool printMSSSIM,
+                bool printHexPsnr, bool printRprPSNR, const BitDepths &bitDepths,
+                bool useWPSNR = false, bool printHdrMetrics = false)
+  {
+
+    std::ostringstream headeross,metricoss;
+    // no generic lambda in C++11...
+    auto addFieldD=[&](const std::string &header,const char *fmt,double x, bool withchroma=true) {
+      if (!withchroma) return;
+      char buffer[512];
+      headeross<<header;
+      snprintf(buffer,512,fmt,x);
+      metricoss<<buffer;
+    };
+    auto addFieldL=[&](const std::string &header,const char *fmt,uint64_t x, bool withchroma=true) {
+      if (!withchroma) return;
+      char buffer[512];
+      headeross<<header;
+      snprintf(buffer,512,fmt,x);
+      metricoss<<buffer;
+    };
+    auto addFieldS=[&](const std::string &header,const char *fmt,const char *s) {
+      char buffer[512];
+      headeross<<header;
+      snprintf(buffer,512,fmt,s);
+      metricoss<<buffer;
+    };
+
+    auto hexValue=[](double x) {
+      uint64_t ui;
+      copy(reinterpret_cast<uint8_t *>(&x),
+           reinterpret_cast<uint8_t *>(&x) + sizeof(x),
+           reinterpret_cast<uint8_t *>(&ui));
+      return ui;
+    };
+    //
+    double fps     =   m_dFrmRate; //--CFG_KDY
+    double scale   = fps / 1000 / (double)m_uiNumPic;
+
+    double mseBasedSNR[MAX_NUM_COMPONENT];
+    if (printMSEBasedSNR||printRprPSNR)
+    {
+      for (uint32_t componentIndex = 0; componentIndex < MAX_NUM_COMPONENT; componentIndex++)
+      {
+        const ComponentID compID = ComponentID(componentIndex);
+        if (getNumPic() == 0) mseBasedSNR[compID] = 0 * scale; // this is the same calculation that will be evaluated for any other statistic when there are no frames (it should result in NaN). We use it here so all the output is consistent.
+        else
+        {
+          const uint32_t maxval = /*useWPSNR ? (1 << bitDepths.recon[toChannelType(compID)]) - 1 :*/ 255 << (bitDepths.recon[toChannelType(compID)] - 8);
+          const double MSE  = m_MSEyuvframe[compID];
+          mseBasedSNR[compID] = (MSE == 0) ? 999.99 : 10.0 * log10((maxval * maxval) / (MSE / (double)getNumPic()));
+        }
+      }
+    }
+
+
+
+    addFieldL("\tTotal Frames","\t%-8d    ",getNumPic());
+    addFieldS(" |  ",                  " %s ",delim.c_str());
+    addFieldD("Bitrate      ", "%-12.4lf ",getBits() * scale);
+
+    const bool withchroma=(chFmt != CHROMA_400);
+    double psnrYUV = MAX_DOUBLE;
+    double mseYUV  = MAX_DOUBLE;
+    if (withchroma)  calculateCombinedValues(chFmt, psnrYUV, mseYUV, bitDepths);
+
+    if (useWPSNR)
+    {
+      addFieldD("Y-WPSNR   ", "%-8.4lf  ", getWPSNR(COMPONENT_Y));
+      addFieldD("U-WPSNR   ", "%-8.4lf  ", getWPSNR(COMPONENT_Cb), withchroma);
+      addFieldD("V-WPSNR   ", "%-8.4lf  ", getWPSNR(COMPONENT_Cr), withchroma);
+      addFieldD("YUV-WPSNR ", "%-8.4lf  ", psnrYUV, withchroma);
+    }
+    else
+    {
+      addFieldD("Y-PSNR   ", "%-8.4lf ", getPsnr(COMPONENT_Y) / (double) getNumPic());
+      addFieldD("U-PSNR   ", "%-8.4lf ", getPsnr(COMPONENT_Cb) / (double) getNumPic(), withchroma);
+      addFieldD("V-PSNR   ", "%-8.4lf ", getPsnr(COMPONENT_Cr) / (double) getNumPic(), withchroma);
+      addFieldD("YUV-PSNR ", "%-8.4lf ", psnrYUV, withchroma);
+    }
+#if JVET_O0756_CALCULATE_HDRMETRICS
+    if (printHdrMetrics && withchroma)
+    {
+      addFieldD("DeltaE   ", "%-8.4lf ", getDeltaE() / (double) getNumPic());
+      addFieldD("PSNRL    ", "%-8.4lf ", getPsnrL() / (double) getNumPic());
+    }
+#endif
+#if EXTENSION_360_VIDEO
+    m_ext360.printInfos(headeross,metricoss,getNumPic());
+#endif
+    if (printHexPsnr)
+    {
+      if (useWPSNR) {
+        addFieldL("xY-WPSNR         ", "%-16" PRIx64 " ", hexValue(getWPSNR(COMPONENT_Y) ));
+        addFieldL("xU-WPSNR         ", "%-16" PRIx64 " ", hexValue(getWPSNR(COMPONENT_Cb)), withchroma);
+        addFieldL("xV-WPSNR         ", "%-16" PRIx64 " ", hexValue(getWPSNR(COMPONENT_Cr)), withchroma);
+
+      } else {
+      addFieldL("xY-PSNR          ", "%-16" PRIx64 " ", hexValue(getPsnr(COMPONENT_Y) / (double) getNumPic()));
+      addFieldL("xU-PSNR          ", "%-16" PRIx64 " ", hexValue(getPsnr(COMPONENT_Cb) / (double) getNumPic()), withchroma);
+      addFieldL("xV-PSNR          ", "%-16" PRIx64 " ", hexValue(getPsnr(COMPONENT_Cr) / (double) getNumPic()), withchroma);
+      }
+    }
+#if JVET_O0756_CALCULATE_HDRMETRICS
+    if (printHdrMetrics && printHexPsnr && withchroma)
+    {
+      addFieldL("xDeltaE          ", "%-16" PRIx64 " ", hexValue(getDeltaE() / (double) getNumPic()));
+      addFieldL("xPSNRL           ", "%-16" PRIx64 " " , hexValue(getPsnrL() / (double) getNumPic()));
+    }
+#endif
+    if (printMSSSIM)
+    {
+      addFieldD("Y-MS-SSIM  ", "%-9.7lf  ", getMsssim(COMPONENT_Y) / (double) getNumPic());
+      addFieldD("U-MS-SSIM  ", "%-9.7lf  ", getMsssim(COMPONENT_Cb) / (double) getNumPic(), withchroma);
+      addFieldD("V-MS-SSIM  ", "%-9.7lf  ", getMsssim(COMPONENT_Cr) / (double) getNumPic(), withchroma);
+    }
+    if (printSequenceMSE)
+    {
+      addFieldD("Y-MSE      ", "%-10.4lf ", m_MSEyuvframe[COMPONENT_Y] / (double) getNumPic());
+      addFieldD("U-MSE      ", "%-10.4lf ", m_MSEyuvframe[COMPONENT_Cb] / (double) getNumPic(), withchroma);
+      addFieldD("V-MSE      ", "%-10.4lf ", m_MSEyuvframe[COMPONENT_Cr] / (double) getNumPic(), withchroma);
+      addFieldD("YUV-MSE    ", "%-10.4lf ",mseYUV, withchroma);
+    }
+
+    if (printMSEBasedSNR&&!printRprPSNR) {
+      addFieldD("MSE-Y-PSNR   ", "%-8.4lf     ", mseBasedSNR[COMPONENT_Y]);
+      addFieldD("MSE-U-PSNR   ", "%-8.4lf     ", mseBasedSNR[COMPONENT_Cb], withchroma);
+      addFieldD("MSE-V-PSNR   ", "%-8.4lf     ", mseBasedSNR[COMPONENT_Cr], withchroma);
+      addFieldD("MSE-YUV-PSNR ", "%-8.4lf     ", psnrYUV, withchroma);
+    }
+    if (printRprPSNR) {
+      addFieldD("Y-PSNR1  ", "%-8.4lf ", mseBasedSNR[COMPONENT_Y]);
+      addFieldD("U-PSNR1  ", "%-8.4lf ", mseBasedSNR[COMPONENT_Cb], withchroma);
+      addFieldD("V-PSNR1  ", "%-8.4lf ", mseBasedSNR[COMPONENT_Cr], withchroma);
+      addFieldD("Y-PSNR2  ", "%-8.4lf ", m_upscaledPSNR[COMPONENT_Y]/ (double)getNumPic());
+      addFieldD("U-PSNR2  ", "%-8.4lf ", m_upscaledPSNR[COMPONENT_Cb]/ (double)getNumPic(), withchroma);
+      addFieldD("V-PSNR2  ", "%-8.4lf ", m_upscaledPSNR[COMPONENT_Cr]/ (double)getNumPic(), withchroma);
+    }
+    header=headeross.str();
+    metrics=metricoss.str();
+  }
+
+#endif
+
+#if !JVET_W0134_UNIFORM_METRICS_LOG
+#if (ENABLE_QPA || WCG_WPSNR)
+  void    printOut(
+      char cDelim, const ChromaFormat chFmt, const bool printMSEBasedSNR, const bool printSequenceMSE, const bool printMSSSIM,
     const bool printHexPsnr, const bool printRprPSNR, const BitDepths &bitDepths, const bool useWPSNR = false
 #if JVET_O0756_CALCULATE_HDRMETRICS
       , const bool printHdrMetrics = false
@@ -635,7 +783,7 @@ public:
         break;
     }
   }
-
+#endif
 
   void    printSummary(const ChromaFormat chFmt, const bool printSequenceMSE, const bool printHexPsnr, const BitDepths &bitDepths, const std::string &sFilename)
   {
diff --git a/source/Lib/EncoderLib/AnnexBwrite.h b/source/Lib/EncoderLib/AnnexBwrite.h
index d9007085f..0fb5115cc 100644
--- a/source/Lib/EncoderLib/AnnexBwrite.h
+++ b/source/Lib/EncoderLib/AnnexBwrite.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -78,13 +78,8 @@ std::vector<uint32_t> writeAnnexBAccessUnit(std::ostream& out, const AccessUnit&
   for (AccessUnit::const_iterator it = au.begin(); it != au.end(); it++)
   {
     const NALUnitEBSP& nalu = **it;
-#if JVET_S0163_ON_TARGETOLS_SUBLAYERS
     const bool useLongStartCode = (it == au.begin() || nalu.m_nalUnitType == NAL_UNIT_OPI || nalu.m_nalUnitType == NAL_UNIT_DCI || nalu.m_nalUnitType == NAL_UNIT_VPS || nalu.m_nalUnitType == NAL_UNIT_SPS
                                    || nalu.m_nalUnitType == NAL_UNIT_PPS || nalu.m_nalUnitType == NAL_UNIT_PREFIX_APS || nalu.m_nalUnitType == NAL_UNIT_SUFFIX_APS);
-#else
-    const bool useLongStartCode = (it == au.begin() || nalu.m_nalUnitType == NAL_UNIT_DCI || nalu.m_nalUnitType == NAL_UNIT_VPS || nalu.m_nalUnitType == NAL_UNIT_SPS
-                                   || nalu.m_nalUnitType == NAL_UNIT_PPS || nalu.m_nalUnitType == NAL_UNIT_PREFIX_APS || nalu.m_nalUnitType == NAL_UNIT_SUFFIX_APS);
-#endif
 
     const uint32_t size = writeAnnexBNalUnit(out, nalu, useLongStartCode);
 
diff --git a/source/Lib/EncoderLib/BinEncoder.cpp b/source/Lib/EncoderLib/BinEncoder.cpp
index 9636d2f78..9f4f7e91a 100644
--- a/source/Lib/EncoderLib/BinEncoder.cpp
+++ b/source/Lib/EncoderLib/BinEncoder.cpp
@@ -3,7 +3,7 @@
 * and contributor rights, including patent rights, and no such rights are
 * granted under this license.
 *
-* Copyright (c) 2010-2020, ITU/ISO/IEC
+* Copyright (c) 2010-2021, ITU/ISO/IEC
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/EncoderLib/BinEncoder.h b/source/Lib/EncoderLib/BinEncoder.h
index 67500723e..ddd5d878f 100644
--- a/source/Lib/EncoderLib/BinEncoder.h
+++ b/source/Lib/EncoderLib/BinEncoder.h
@@ -3,7 +3,7 @@
 * and contributor rights, including patent rights, and no such rights are
 * granted under this license.
 *
-* Copyright (c) 2010-2020, ITU/ISO/IEC
+* Copyright (c) 2010-2021, ITU/ISO/IEC
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
@@ -172,6 +172,11 @@ public:
   void      finish  ();
   void      restart ();
   void      reset   ( int qp, int initId );
+#if JVET_W0178_CONSTRAINTS_ON_REXT_TOOLS
+  void      riceStatReset(int bitDepth, bool persistentRiceAdaptationEnabledFlag);
+#else
+  void      riceStatReset(int bitDepth);
+#endif
 public:
   void      resetBits           ();
   uint64_t  getEstFracBits      ()                    const { THROW( "not supported" ); return 0; }
diff --git a/source/Lib/EncoderLib/CABACWriter.cpp b/source/Lib/EncoderLib/CABACWriter.cpp
index 087cb0c17..40a1dd263 100644
--- a/source/Lib/EncoderLib/CABACWriter.cpp
+++ b/source/Lib/EncoderLib/CABACWriter.cpp
@@ -3,7 +3,7 @@
 * and contributor rights, including patent rights, and no such rights are
 * granted under this license.
 *
-* Copyright (c) 2010-2020, ITU/ISO/IEC
+* Copyright (c) 2010-2021, ITU/ISO/IEC
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
@@ -61,6 +61,12 @@ void CABACWriter::initCtxModels( const Slice& slice )
     sliceType = encCABACTableIdx;
   }
   m_BinEncoder.reset( qp, (int)sliceType );
+  m_BinEncoder.setBaseLevel(slice.getRiceBaseLevel());
+#if JVET_W0178_CONSTRAINTS_ON_REXT_TOOLS
+  m_BinEncoder.riceStatReset(slice.getSPS()->getBitDepth(CHANNEL_TYPE_LUMA), slice.getSPS()->getSpsRangeExtension().getPersistentRiceAdaptationEnabledFlag()); // provide bit depth for derivation (CE14_C method)
+#else
+  m_BinEncoder.riceStatReset(slice.getSPS()->getBitDepth(CHANNEL_TYPE_LUMA)); // provide bit depth for derivation (CE14_C method)
+#endif
 }
 
 
@@ -174,11 +180,11 @@ void CABACWriter::coding_tree_unit( CodingStructure& cs, const UnitArea& area, i
       codeAlfCtuEnableFlag(cs, ctuRsAddr, compIdx, NULL);
       if (isLuma(ComponentID(compIdx)))
       {
-        codeAlfCtuFilterIndex(cs, ctuRsAddr, cs.slice->getTileGroupAlfEnabledFlag(COMPONENT_Y));
+        codeAlfCtuFilterIndex(cs, ctuRsAddr, cs.slice->getAlfEnabledFlag(COMPONENT_Y));
       }
       if (isChroma(ComponentID(compIdx)))
       {
-        uint8_t* ctbAlfFlag = cs.slice->getTileGroupAlfEnabledFlag((ComponentID)compIdx) ? cs.slice->getPic()->getAlfCtuEnableFlag( compIdx ) : nullptr;
+        uint8_t* ctbAlfFlag = cs.slice->getAlfEnabledFlag((ComponentID)compIdx) ? cs.slice->getPic()->getAlfCtuEnableFlag( compIdx ) : nullptr;
         if( ctbAlfFlag && ctbAlfFlag[ctuRsAddr] )
         {
           codeAlfCtuAlternative( cs, ctuRsAddr, compIdx );
@@ -430,61 +436,62 @@ void CABACWriter::coding_tree(const CodingStructure& cs, Partitioner& partitione
 
   if( splitMode != CU_DONT_SPLIT )
   {
-      if (CS::isDualITree(cs) && pPartitionerChroma != nullptr && (partitioner.currArea().lwidth() >= 64 || partitioner.currArea().lheight() >= 64))
-      {
-        partitioner.splitCurrArea(CU_QUAD_SPLIT, cs);
-        pPartitionerChroma->splitCurrArea(CU_QUAD_SPLIT, cs);
-        bool beContinue = true;
-        bool lumaContinue = true;
-        bool chromaContinue = true;
+    if (CS::isDualITree(cs) && pPartitionerChroma != nullptr
+        && (partitioner.currArea().lwidth() >= 64 || partitioner.currArea().lheight() >= 64))
+    {
+      partitioner.splitCurrArea(CU_QUAD_SPLIT, cs);
+      pPartitionerChroma->splitCurrArea(CU_QUAD_SPLIT, cs);
+      bool beContinue     = true;
+      bool lumaContinue   = true;
+      bool chromaContinue = true;
 
-        while (beContinue)
+      while (beContinue)
+      {
+        if (partitioner.currArea().lwidth() > 64 || partitioner.currArea().lheight() > 64)
         {
-          if (partitioner.currArea().lwidth() > 64 || partitioner.currArea().lheight() > 64)
+          if (cs.picture->blocks[partitioner.chType].contains(partitioner.currArea().blocks[partitioner.chType].pos()))
           {
-            if (cs.picture->blocks[partitioner.chType].contains(partitioner.currArea().blocks[partitioner.chType].pos()))
-            {
-              coding_tree(cs, partitioner, cuCtx, pPartitionerChroma, pCuCtxChroma);
-            }
-            lumaContinue = partitioner.nextPart(cs);
-            chromaContinue = pPartitionerChroma->nextPart(cs);
-            CHECK(lumaContinue != chromaContinue, "luma chroma partition should be matched");
-            beContinue = lumaContinue;
+            coding_tree(cs, partitioner, cuCtx, pPartitionerChroma, pCuCtxChroma);
           }
-          else
+          lumaContinue   = partitioner.nextPart(cs);
+          chromaContinue = pPartitionerChroma->nextPart(cs);
+          CHECK(lumaContinue != chromaContinue, "luma chroma partition should be matched");
+          beContinue = lumaContinue;
+        }
+        else
+        {
+          // dual tree coding under 64x64 block
+          if (cs.picture->blocks[partitioner.chType].contains(partitioner.currArea().blocks[partitioner.chType].pos()))
           {
-            //dual tree coding under 64x64 block
-            if (cs.picture->blocks[partitioner.chType].contains(partitioner.currArea().blocks[partitioner.chType].pos()))
-            {
-              coding_tree(cs, partitioner, cuCtx);
-            }
-            lumaContinue = partitioner.nextPart(cs);
-            if (cs.picture->blocks[pPartitionerChroma->chType].contains(pPartitionerChroma->currArea().blocks[pPartitionerChroma->chType].pos()))
-            {
-              coding_tree(cs, *pPartitionerChroma, *pCuCtxChroma);
-            }
-            chromaContinue = pPartitionerChroma->nextPart(cs);
-            CHECK(lumaContinue != chromaContinue, "luma chroma partition should be matched");
-            beContinue = lumaContinue;
+            coding_tree(cs, partitioner, cuCtx);
           }
+          lumaContinue = partitioner.nextPart(cs);
+          if (cs.picture->blocks[pPartitionerChroma->chType].contains(
+                pPartitionerChroma->currArea().blocks[pPartitionerChroma->chType].pos()))
+          {
+            coding_tree(cs, *pPartitionerChroma, *pCuCtxChroma);
+          }
+          chromaContinue = pPartitionerChroma->nextPart(cs);
+          CHECK(lumaContinue != chromaContinue, "luma chroma partition should be matched");
+          beContinue = lumaContinue;
         }
-        partitioner.exitCurrSplit();
-        pPartitionerChroma->exitCurrSplit();
-
       }
-      else
-      {
-        const ModeType modeTypeParent = partitioner.modeType;
-        const ModeType modeTypeChild = CU::getModeTypeAtDepth( cu, partitioner.currDepth );
-        mode_constraint( splitMode, cs, partitioner, modeTypeChild );
-        partitioner.modeType = modeTypeChild;
+      partitioner.exitCurrSplit();
+      pPartitionerChroma->exitCurrSplit();
+    }
+    else
+    {
+      const ModeType modeTypeParent = partitioner.modeType;
+      const ModeType modeTypeChild  = CU::getModeTypeAtDepth(cu, partitioner.currDepth);
+      mode_constraint(splitMode, cs, partitioner, modeTypeChild);
+      partitioner.modeType = modeTypeChild;
 
-        bool chromaNotSplit = modeTypeParent == MODE_TYPE_ALL && modeTypeChild == MODE_TYPE_INTRA ? true : false;
-        CHECK( chromaNotSplit && partitioner.chType != CHANNEL_TYPE_LUMA, "chType must be luma" );
-        if( partitioner.treeType == TREE_D )
-        {
-          partitioner.treeType = chromaNotSplit ? TREE_L : TREE_D;
-        }
+      bool chromaNotSplit = modeTypeParent == MODE_TYPE_ALL && modeTypeChild == MODE_TYPE_INTRA ? true : false;
+      CHECK(chromaNotSplit && partitioner.chType != CHANNEL_TYPE_LUMA, "chType must be luma");
+      if (partitioner.treeType == TREE_D)
+      {
+        partitioner.treeType = chromaNotSplit ? TREE_L : TREE_D;
+      }
       partitioner.splitCurrArea( splitMode, cs );
 
       do
@@ -500,14 +507,14 @@ void CABACWriter::coding_tree(const CodingStructure& cs, Partitioner& partitione
       {
         if (isChromaEnabled(cs.pcv->chrFormat))
         {
-        CHECK( partitioner.chType != CHANNEL_TYPE_LUMA, "must be luma status" );
-        partitioner.chType = CHANNEL_TYPE_CHROMA;
-        partitioner.treeType = TREE_C;
+          CHECK(partitioner.chType != CHANNEL_TYPE_LUMA, "must be luma status");
+          partitioner.chType   = CHANNEL_TYPE_CHROMA;
+          partitioner.treeType = TREE_C;
 
-        if( cs.picture->blocks[partitioner.chType].contains( partitioner.currArea().blocks[partitioner.chType].pos() ) )
-        {
-          coding_tree( cs, partitioner, cuCtx );
-        }
+          if (cs.picture->blocks[partitioner.chType].contains(partitioner.currArea().blocks[partitioner.chType].pos()))
+          {
+            coding_tree(cs, partitioner, cuCtx);
+          }
         }
 
         //recover
@@ -515,8 +522,8 @@ void CABACWriter::coding_tree(const CodingStructure& cs, Partitioner& partitione
         partitioner.treeType = TREE_D;
       }
       partitioner.modeType = modeTypeParent;
-      }
-      return;
+    }
+    return;
   }
 
   // Predict QP on start of quantization group
@@ -743,9 +750,9 @@ void CABACWriter::cu_skip_flag( const CodingUnit& cu )
       {
         return;
       }
-    unsigned ctxidx = DeriveCtx::CtxIBCFlag(cu);
-    m_BinEncoder.encodeBin(CU::isIBC(cu) ? 1 : 0, Ctx::IBCFlag(ctxidx));
-    DTRACE(g_trace_ctx, D_SYNTAX, "ibc() ctx=%d cu.predMode=%d\n", ctxidx, cu.predMode);
+      unsigned ctxidx = DeriveCtx::CtxIBCFlag(cu);
+      m_BinEncoder.encodeBin(CU::isIBC(cu) ? 1 : 0, Ctx::IBCFlag(ctxidx));
+      DTRACE(g_trace_ctx, D_SYNTAX, "ibc() ctx=%d cu.predMode=%d\n", ctxidx, cu.predMode);
     }
   }
 }
@@ -765,8 +772,8 @@ void CABACWriter::pred_mode( const CodingUnit& cu )
     {
       if (cu.lwidth() < 128 && cu.lheight() < 128) // disable IBC mode larger than 64x64
       {
-      unsigned ctxidx = DeriveCtx::CtxIBCFlag(cu);
-      m_BinEncoder.encodeBin(CU::isIBC(cu), Ctx::IBCFlag(ctxidx));
+        unsigned ctxidx = DeriveCtx::CtxIBCFlag(cu);
+        m_BinEncoder.encodeBin(CU::isIBC(cu), Ctx::IBCFlag(ctxidx));
       }
       if (!CU::isIBC(cu) && cu.cs->slice->getSPS()->getPLTMode() && cu.lwidth() <= 64 && cu.lheight() <= 64 && (cu.lumaSize().width * cu.lumaSize().height > 16) )
       {
@@ -783,14 +790,16 @@ void CABACWriter::pred_mode( const CodingUnit& cu )
       if (CU::isIntra(cu) || CU::isPLT(cu))
       {
         if (cu.cs->slice->getSPS()->getPLTMode() && cu.lwidth() <= 64 && cu.lheight() <= 64 && (cu.lumaSize().width * cu.lumaSize().height > 16) )
+        {
           m_BinEncoder.encodeBin(CU::isPLT(cu), Ctx::PLTFlag(0));
+        }
       }
       else
       {
         if (cu.lwidth() < 128 && cu.lheight() < 128) // disable IBC mode larger than 64x64
         {
-        unsigned ctxidx = DeriveCtx::CtxIBCFlag(cu);
-        m_BinEncoder.encodeBin(CU::isIBC(cu), Ctx::IBCFlag(ctxidx));
+          unsigned ctxidx = DeriveCtx::CtxIBCFlag(cu);
+          m_BinEncoder.encodeBin(CU::isIBC(cu), Ctx::IBCFlag(ctxidx));
         }
       }
     }
@@ -806,7 +815,9 @@ void CABACWriter::pred_mode( const CodingUnit& cu )
     if ( cu.cs->slice->isIntra() || ( cu.lwidth() == 4 && cu.lheight() == 4 ) || cu.isConsIntra() )
     {
       if (cu.cs->slice->getSPS()->getPLTMode() && cu.lwidth() <= 64 && cu.lheight() <= 64 && ( ( (!isLuma(cu.chType)) && (cu.chromaSize().width * cu.chromaSize().height > 16) ) || ((isLuma(cu.chType)) && ((cu.lumaSize().width * cu.lumaSize().height) > 16 ) )  ) && (!cu.isLocalSepTree() || isLuma(cu.chType)  ) )
+      {
         m_BinEncoder.encodeBin((CU::isPLT(cu)), Ctx::PLTFlag(0));
+      }
       return;
     }
     m_BinEncoder.encodeBin((CU::isIntra(cu) || CU::isPLT(cu)), Ctx::PredMode(DeriveCtx::CtxPredModeFlag(cu)));
@@ -818,8 +829,14 @@ void CABACWriter::pred_mode( const CodingUnit& cu )
 }
 void CABACWriter::bdpcm_mode( const CodingUnit& cu, const ComponentID compID )
 {
-  if( !cu.cs->sps->getBDPCMEnabledFlag() ) return;
-  if( !CU::bdpcmAllowed( cu, compID ) ) return;
+  if (!cu.cs->sps->getBDPCMEnabledFlag())
+  {
+    return;
+  }
+  if (!CU::bdpcmAllowed(cu, compID))
+  {
+    return;
+  }
 
   int bdpcmMode = isLuma(compID) ? cu.bdpcmMode : cu.bdpcmModeChroma;
 
@@ -871,7 +888,6 @@ void CABACWriter::cu_pred_data( const CodingUnit& cu )
   affine_amvr_mode( cu );
 
   cu_bcw_flag( cu );
-
 }
 
 void CABACWriter::cu_bcw_flag(const CodingUnit& cu)
@@ -978,7 +994,6 @@ void CABACWriter::extend_ref_line(const PredictionUnit& pu)
 
 void CABACWriter::extend_ref_line(const CodingUnit& cu)
 {
-
   if ( !cu.Y().valid() || cu.predMode != MODE_INTRA || !isLuma(cu.chType) || cu.bdpcmMode )
   {
     return;
@@ -1006,7 +1021,6 @@ void CABACWriter::extend_ref_line(const CodingUnit& cu)
       {
         m_BinEncoder.encodeBin(multiRefIdx != MULTI_REF_LINE_IDX[1], Ctx::MultiRefLineIdx(1));
       }
-
     }
     pu = pu->next;
   }
@@ -1082,26 +1096,26 @@ void CABACWriter::intra_luma_pred_modes( const CodingUnit& cu )
     const unsigned& mpm_idx = mpm_idxs[k];
     if( mpm_idx < numMPMs )
     {
+      unsigned ctx = (pu->cu->ispMode == NOT_INTRA_SUBPARTITIONS ? 1 : 0);
+      if (pu->multiRefIdx == 0)
       {
-        unsigned ctx = (pu->cu->ispMode == NOT_INTRA_SUBPARTITIONS ? 1 : 0);
-        if (pu->multiRefIdx == 0)
-          m_BinEncoder.encodeBin(mpm_idx > 0, Ctx::IntraLumaPlanarFlag(ctx));
-        if( mpm_idx )
-        {
-          m_BinEncoder.encodeBinEP( mpm_idx > 1 );
-        }
-        if (mpm_idx > 1)
-        {
-          m_BinEncoder.encodeBinEP(mpm_idx > 2);
-        }
-        if (mpm_idx > 2)
-        {
-          m_BinEncoder.encodeBinEP(mpm_idx > 3);
-        }
-        if (mpm_idx > 3)
-        {
-          m_BinEncoder.encodeBinEP(mpm_idx > 4);
-        }
+        m_BinEncoder.encodeBin(mpm_idx > 0, Ctx::IntraLumaPlanarFlag(ctx));
+      }
+      if (mpm_idx)
+      {
+        m_BinEncoder.encodeBinEP(mpm_idx > 1);
+      }
+      if (mpm_idx > 1)
+      {
+        m_BinEncoder.encodeBinEP(mpm_idx > 2);
+      }
+      if (mpm_idx > 2)
+      {
+        m_BinEncoder.encodeBinEP(mpm_idx > 3);
+      }
+      if (mpm_idx > 3)
+      {
+        m_BinEncoder.encodeBinEP(mpm_idx > 4);
       }
     }
     else
@@ -1112,17 +1126,16 @@ void CABACWriter::intra_luma_pred_modes( const CodingUnit& cu )
       // sorting of MPMs
       std::sort( mpm_pred, mpm_pred + numMPMs );
 
+      for (int idx = numMPMs - 1; idx >= 0; idx--)
       {
-        for (int idx = numMPMs - 1; idx >= 0; idx--)
+        if (ipred_mode > mpm_pred[idx])
         {
-          if (ipred_mode > mpm_pred[idx])
-          {
-            ipred_mode--;
-          }
+          ipred_mode--;
         }
-        CHECK(ipred_mode >= 64, "Incorrect mode");
-        xWriteTruncBinCode(ipred_mode, NUM_LUMA_MODE - NUM_MOST_PROBABLE_MODES);  // Remaining mode is truncated binary coded
       }
+      CHECK(ipred_mode >= 64, "Incorrect mode");
+      xWriteTruncBinCode(ipred_mode,
+                         NUM_LUMA_MODE - NUM_MOST_PROBABLE_MODES);   // Remaining mode is truncated binary coded
     }
 
     DTRACE( g_trace_ctx, D_SYNTAX, "intra_luma_pred_modes() idx=%d pos=(%d,%d) mode=%d\n", k, pu->lumaPos().x, pu->lumaPos().y, pu->intraDir[0] );
@@ -1133,8 +1146,10 @@ void CABACWriter::intra_luma_pred_modes( const CodingUnit& cu )
 
 void CABACWriter::intra_luma_pred_mode( const PredictionUnit& pu )
 {
-
-  if( pu.cu->bdpcmMode ) return;
+  if (pu.cu->bdpcmMode)
+  {
+    return;
+  }
   mip_flag(*pu.cu);
   if (pu.cu->mipFlag)
   {
@@ -1173,41 +1188,40 @@ void CABACWriter::intra_luma_pred_mode( const PredictionUnit& pu )
   // mpm_idx / rem_intra_luma_pred_mode
   if( mpm_idx < numMPMs )
   {
+    unsigned ctx = (pu.cu->ispMode == NOT_INTRA_SUBPARTITIONS ? 1 : 0);
+    if (pu.multiRefIdx == 0)
     {
-      unsigned ctx = (pu.cu->ispMode == NOT_INTRA_SUBPARTITIONS ? 1 : 0);
-      if (pu.multiRefIdx == 0)
-        m_BinEncoder.encodeBin( mpm_idx > 0, Ctx::IntraLumaPlanarFlag(ctx) );
-      if( mpm_idx )
-      {
-        m_BinEncoder.encodeBinEP( mpm_idx > 1 );
-      }
-      if (mpm_idx > 1)
-      {
-        m_BinEncoder.encodeBinEP(mpm_idx > 2);
-      }
-      if (mpm_idx > 2)
-      {
-        m_BinEncoder.encodeBinEP(mpm_idx > 3);
-      }
-      if (mpm_idx > 3)
-      {
-        m_BinEncoder.encodeBinEP(mpm_idx > 4);
-      }
+      m_BinEncoder.encodeBin(mpm_idx > 0, Ctx::IntraLumaPlanarFlag(ctx));
+    }
+    if (mpm_idx)
+    {
+      m_BinEncoder.encodeBinEP(mpm_idx > 1);
+    }
+    if (mpm_idx > 1)
+    {
+      m_BinEncoder.encodeBinEP(mpm_idx > 2);
+    }
+    if (mpm_idx > 2)
+    {
+      m_BinEncoder.encodeBinEP(mpm_idx > 3);
+    }
+    if (mpm_idx > 3)
+    {
+      m_BinEncoder.encodeBinEP(mpm_idx > 4);
     }
   }
   else
   {
     std::sort( mpm_pred, mpm_pred + numMPMs );
+    for (int idx = numMPMs - 1; idx >= 0; idx--)
     {
-      for (int idx = numMPMs - 1; idx >= 0; idx--)
+      if (ipred_mode > mpm_pred[idx])
       {
-        if (ipred_mode > mpm_pred[idx])
-        {
-          ipred_mode--;
-        }
+        ipred_mode--;
       }
-      xWriteTruncBinCode(ipred_mode, NUM_LUMA_MODE - NUM_MOST_PROBABLE_MODES);  // Remaining mode is truncated binary coded
     }
+    xWriteTruncBinCode(ipred_mode,
+                       NUM_LUMA_MODE - NUM_MOST_PROBABLE_MODES);   // Remaining mode is truncated binary coded
   }
 }
 
@@ -1439,7 +1453,6 @@ void CABACWriter::end_of_ctu( const CodingUnit& cu, CUCtx& cuCtx )
       )
   {
     cuCtx.isDQPCoded = ( cu.cs->pps->getUseDQP() && !cuCtx.isDQPCoded );
-
   }
 }
 
@@ -1453,7 +1466,6 @@ void CABACWriter::cu_palette_info(const CodingUnit& cu, ComponentID compBegin, u
 
   if (cu.lastPLTSize[compBegin])
   {
-
     xEncodePLTPredIndicator(cu, maxPltSize, compBegin);
   }
 
@@ -1489,9 +1501,13 @@ void CABACWriter::cu_palette_info(const CodingUnit& cu, ComponentID compBegin, u
   m_scanOrder = g_scanOrder[SCAN_UNGROUPED][(cu.useRotation[compBegin]) ? SCAN_TRAV_VER : SCAN_TRAV_HOR][gp_sizeIdxInfo->idxFrom(width)][gp_sizeIdxInfo->idxFrom(height)];
   uint32_t total = height * width;
   if (indexMaxSize > 1)
+  {
     codeScanRotationModeFlag(cu, compBegin);
+  }
   else
+  {
     assert(!cu.useRotation[compBegin]);
+  }
 
   if (cu.useEscape[compBegin] && cu.cs->pps->getUseDQP() && !cuCtx.isDQPCoded)
   {
@@ -1519,6 +1535,7 @@ void CABACWriter::cu_palette_info(const CodingUnit& cu, ComponentID compBegin, u
   }
   CHECK(cu.curPLTSize[compBegin] > maxPltSize, " Current palette size is larger than maximum palette size");
 }
+
 void CABACWriter::cuPaletteSubblockInfo(const CodingUnit& cu, ComponentID compBegin, uint32_t numComp, int subSetId, uint32_t& prevRunPos, unsigned& prevRunType)
 {
   const SPS&      sps = *(cu.cs->sps);
@@ -1534,10 +1551,14 @@ void CABACWriter::cuPaletteSubblockInfo(const CodingUnit& cu, ComponentID compBe
 
   unsigned runCopyFlag[(1 << LOG2_PALETTE_CG_SIZE)];
   for (int i = 0; i < (1 << LOG2_PALETTE_CG_SIZE); i++)
+  {
     runCopyFlag[i] = MAX_INT;
+  }
 
   if (minSubPos == 0)
+  {
     runCopyFlag[0] = 0;
+  }
 
 // PLT runCopy flag and runType - context coded
   int curPos = minSubPos;
@@ -1609,19 +1630,21 @@ void CABACWriter::cuPaletteSubblockInfo(const CodingUnit& cu, ComponentID compBe
       uint32_t posx = m_scanOrder[curPos].x;
       if (curPLTIdx.at(posx, posy) == cu.curPLTSize[compBegin])
       {
-          PLTescapeBuf    escapeValue = tu.getescapeValue((ComponentID)comp);
-          if (compID == COMPONENT_Y || compBegin != COMPONENT_Y)
-          {
-            exp_golomb_eqprob((unsigned)escapeValue.at(posx, posy), 5);
-            DTRACE(g_trace_ctx, D_SYNTAX, "plt_escape_val() value=%d etype=%d sp=%d\n", escapeValue.at(posx, posy), comp, curPos);
-          }
-          if (compBegin == COMPONENT_Y && compID != COMPONENT_Y && posy % (1 << scaleY) == 0 && posx % (1 << scaleX) == 0)
-          {
-            uint32_t posxC = posx >> scaleX;
-            uint32_t posyC = posy >> scaleY;
-            exp_golomb_eqprob((unsigned)escapeValue.at(posxC, posyC), 5);
-            DTRACE(g_trace_ctx, D_SYNTAX, "plt_escape_val() value=%d etype=%d sp=%d\n", escapeValue.at(posx, posy), comp, curPos);
-          }
+        PLTescapeBuf escapeValue = tu.getescapeValue((ComponentID) comp);
+        if (compID == COMPONENT_Y || compBegin != COMPONENT_Y)
+        {
+          exp_golomb_eqprob((unsigned) escapeValue.at(posx, posy), 5);
+          DTRACE(g_trace_ctx, D_SYNTAX, "plt_escape_val() value=%d etype=%d sp=%d\n", escapeValue.at(posx, posy), comp,
+                 curPos);
+        }
+        if (compBegin == COMPONENT_Y && compID != COMPONENT_Y && posy % (1 << scaleY) == 0 && posx % (1 << scaleX) == 0)
+        {
+          uint32_t posxC = posx >> scaleX;
+          uint32_t posyC = posy >> scaleY;
+          exp_golomb_eqprob((unsigned) escapeValue.at(posxC, posyC), 5);
+          DTRACE(g_trace_ctx, D_SYNTAX, "plt_escape_val() value=%d etype=%d sp=%d\n", escapeValue.at(posx, posy), comp,
+                 curPos);
+        }
       }
     }
   }
@@ -1663,6 +1686,7 @@ void CABACWriter::xEncodePLTPredIndicator(const CodingUnit& cu, uint32_t maxPLTS
     exp_golomb_eqprob(1, 0);
   }
 }
+
 Pel CABACWriter::writePLTIndex(const CodingUnit& cu, uint32_t idx, PelBuf& paletteIdx, PLTtypeBuf& paletteRunType, int maxSymbol, ComponentID compBegin)
 {
   uint32_t posy = m_scanOrder[idx].y;
@@ -1739,11 +1763,7 @@ Pel CABACWriter::writePLTIndex(const CodingUnit& cu, uint32_t idx, PelBuf& palet
 void CABACWriter::prediction_unit( const PredictionUnit& pu )
 {
   CHECK( pu.cu->treeType == TREE_C, "cannot be chroma CU" );
-#if ENABLE_SPLIT_PARALLELISM
-  CHECK( pu.cacheUsed, "Processing a PU that should be in cache!" );
-  CHECK( pu.cu->cacheUsed, "Processing a CU that should be in cache!" );
 
-#endif
   if( pu.cu->skip )
   {
     CHECK( !pu.mergeFlag, "merge_flag must be true for skipped CUs" );
@@ -1767,7 +1787,9 @@ void CABACWriter::prediction_unit( const PredictionUnit& pu )
       CHECK( pu.mvpIdx[REF_PIC_LIST_0], "mvpIdx for IBC mode should be 0" );
     }
     else
-    mvp_flag(pu, REF_PIC_LIST_0);
+    {
+      mvp_flag(pu, REF_PIC_LIST_0);
+    }
   }
   else
   {
@@ -1804,31 +1826,31 @@ void CABACWriter::prediction_unit( const PredictionUnit& pu )
     {
       if ( pu.cu->smvdMode != 1 )
       {
-      ref_idx     ( pu, REF_PIC_LIST_1 );
-      if( !pu.cs->picHeader->getMvdL1ZeroFlag() || pu.interDir != 3 /* PRED_BI */ )
-      {
-        if ( pu.cu->affine )
+        ref_idx(pu, REF_PIC_LIST_1);
+        if (!pu.cs->picHeader->getMvdL1ZeroFlag() || pu.interDir != 3 /* PRED_BI */)
         {
-          Mv mvd = pu.mvdAffi[REF_PIC_LIST_1][0];
-          mvd.changeAffinePrecInternal2Amvr(pu.cu->imv);
-          mvd_coding(mvd, 0); // already changed to signaling precision
-          mvd = pu.mvdAffi[REF_PIC_LIST_1][1];
-          mvd.changeAffinePrecInternal2Amvr(pu.cu->imv);
-          mvd_coding(mvd, 0); // already changed to signaling precision
-          if ( pu.cu->affineType == AFFINEMODEL_6PARAM )
+          if (pu.cu->affine)
           {
-            mvd = pu.mvdAffi[REF_PIC_LIST_1][2];
+            Mv mvd = pu.mvdAffi[REF_PIC_LIST_1][0];
             mvd.changeAffinePrecInternal2Amvr(pu.cu->imv);
             mvd_coding(mvd, 0); // already changed to signaling precision
+            mvd = pu.mvdAffi[REF_PIC_LIST_1][1];
+            mvd.changeAffinePrecInternal2Amvr(pu.cu->imv);
+            mvd_coding(mvd, 0);   // already changed to signaling precision
+            if (pu.cu->affineType == AFFINEMODEL_6PARAM)
+            {
+              mvd = pu.mvdAffi[REF_PIC_LIST_1][2];
+              mvd.changeAffinePrecInternal2Amvr(pu.cu->imv);
+              mvd_coding(mvd, 0);   // already changed to signaling precision
+            }
+          }
+          else
+          {
+            Mv mvd = pu.mvd[REF_PIC_LIST_1];
+            mvd.changeTransPrecInternal2Amvr(pu.cu->imv);
+            mvd_coding(mvd, 0);   // already changed to signaling precision
           }
         }
-        else
-        {
-          Mv mvd = pu.mvd[REF_PIC_LIST_1];
-          mvd.changeTransPrecInternal2Amvr(pu.cu->imv);
-          mvd_coding(mvd, 0); // already changed to signaling precision
-        }
-      }
       }
       mvp_flag    ( pu, REF_PIC_LIST_1 );
     }
@@ -1969,8 +1991,8 @@ void CABACWriter::imv_mode( const CodingUnit& cu )
     }
     if (cu.imv < IMV_HPEL)
     {
-    m_BinEncoder.encodeBin( (cu.imv > 1), Ctx::ImvFlag( 1 ) );
-    DTRACE( g_trace_ctx, D_SYNTAX, "imv_mode() value=%d ctx=%d\n", (cu.imv > 1), 1 );
+      m_BinEncoder.encodeBin((cu.imv > 1), Ctx::ImvFlag(1));
+      DTRACE(g_trace_ctx, D_SYNTAX, "imv_mode() value=%d ctx=%d\n", (cu.imv > 1), 1);
     }
   }
 
@@ -2021,7 +2043,7 @@ void CABACWriter::merge_idx( const PredictionUnit& pu )
         m_BinEncoder.encodeBin( 1, Ctx::AffMergeIdx() );
         for ( unsigned idx = 1; idx < numCandminus1; idx++ )
         {
-            m_BinEncoder.encodeBinEP( pu.mergeIdx == idx ? 0 : 1 );
+          m_BinEncoder.encodeBinEP(pu.mergeIdx == idx ? 0 : 1);
           if ( pu.mergeIdx == idx )
           {
             break;
@@ -2065,31 +2087,35 @@ void CABACWriter::merge_idx( const PredictionUnit& pu )
     }
     int numCandminus1;
     if (pu.cu->predMode == MODE_IBC)
+    {
       numCandminus1 = int(pu.cs->sps->getMaxNumIBCMergeCand()) - 1;
+    }
     else
-      numCandminus1 = int(pu.cs->sps->getMaxNumMergeCand()) - 1;
-  if( numCandminus1 > 0 )
-  {
-    if( pu.mergeIdx == 0 )
     {
-      m_BinEncoder.encodeBin( 0, Ctx::MergeIdx() );
-      DTRACE( g_trace_ctx, D_SYNTAX, "merge_idx() merge_idx=%d\n", pu.mergeIdx );
-      return;
+      numCandminus1 = int(pu.cs->sps->getMaxNumMergeCand()) - 1;
     }
-    else
+    if (numCandminus1 > 0)
     {
-      m_BinEncoder.encodeBin( 1, Ctx::MergeIdx() );
-      for( unsigned idx = 1; idx < numCandminus1; idx++ )
+      if (pu.mergeIdx == 0)
+      {
+        m_BinEncoder.encodeBin(0, Ctx::MergeIdx());
+        DTRACE(g_trace_ctx, D_SYNTAX, "merge_idx() merge_idx=%d\n", pu.mergeIdx);
+        return;
+      }
+      else
       {
-          m_BinEncoder.encodeBinEP( pu.mergeIdx == idx ? 0 : 1 );
-        if( pu.mergeIdx == idx )
+        m_BinEncoder.encodeBin(1, Ctx::MergeIdx());
+        for (unsigned idx = 1; idx < numCandminus1; idx++)
         {
-          break;
+          m_BinEncoder.encodeBinEP(pu.mergeIdx == idx ? 0 : 1);
+          if (pu.mergeIdx == idx)
+          {
+            break;
+          }
         }
       }
     }
-  }
-  DTRACE( g_trace_ctx, D_SYNTAX, "merge_idx() merge_idx=%d\n", pu.mergeIdx );
+    DTRACE(g_trace_ctx, D_SYNTAX, "merge_idx() merge_idx=%d\n", pu.mergeIdx);
   }
 }
 void CABACWriter::mmvd_merge_idx(const PredictionUnit& pu)
@@ -2134,6 +2160,7 @@ void CABACWriter::mmvd_merge_idx(const PredictionUnit& pu)
   DTRACE(g_trace_ctx, D_SYNTAX, "pos() pos=%d\n", var2);
   DTRACE(g_trace_ctx, D_SYNTAX, "mmvd_merge_idx() mmvd_merge_idx=%d\n", pu.mmvdMergeIdx);
 }
+
 void CABACWriter::inter_pred_idc( const PredictionUnit& pu )
 {
   if( !pu.cs->slice->isInterB() )
@@ -2172,7 +2199,9 @@ void CABACWriter::ref_idx( const PredictionUnit& pu, RefPicList eRefList )
   if (eRefList == REF_PIC_LIST_0 && pu.cs->sps->getIBCFlag())
   {
     if (CU::isIBC(*pu.cu))
+    {
       return;
+    }
   }
 
   if( numRef <= 1 )
@@ -2260,8 +2289,9 @@ void CABACWriter::transform_tree( const CodingStructure& cs, Partitioner& partit
     CHECK( !split, "transform split implied - sbt" );
   }
   else
-  CHECK( split && !cu.ispMode, "transform split not allowed with QTBT" );
-
+  {
+    CHECK(split && !cu.ispMode, "transform split not allowed with QTBT");
+  }
 
   if( split )
   {
@@ -2284,7 +2314,9 @@ void CABACWriter::transform_tree( const CodingStructure& cs, Partitioner& partit
       partitioner.splitCurrArea( PartSplit( cu.getSbtTuSplit() ), cs );
     }
     else
+    {
       THROW( "Implicit TU split not available" );
+    }
 
     do
     {
@@ -2311,24 +2343,26 @@ void CABACWriter::cbf_comp( const CodingStructure& cs, bool cbf, const CompArea&
    || (area.compID != COMPONENT_Y && cs.getCU(area.pos(), toChannelType(area.compID)) != NULL && cs.getCU(area.pos(), toChannelType(area.compID))->bdpcmModeChroma))
   {
     if (area.compID == COMPONENT_Y)
+    {
       ctxId = 1;
+    }
     else if (area.compID == COMPONENT_Cb)
+    {
       ctxId = 1;
+    }
     else
+    {
       ctxId = 2;
+    }
     m_BinEncoder.encodeBin(cbf, ctxSet(ctxId));
   }
   else
   {
-  m_BinEncoder.encodeBin( cbf, ctxSet( ctxId ) );
+    m_BinEncoder.encodeBin(cbf, ctxSet(ctxId));
   }
   DTRACE( g_trace_ctx, D_SYNTAX, "cbf_comp() etype=%d pos=(%d,%d) ctx=%d cbf=%d\n", area.compID, area.x, area.y, ctxId, cbf );
 }
 
-
-
-
-
 //================================================================================
 //  clause 7.3.8.9
 //--------------------------------------------------------------------------------
@@ -2393,9 +2427,6 @@ void CABACWriter::mvd_coding( const Mv &rMvd, int8_t imv )
   }
 }
 
-
-
-
 //================================================================================
 //  clause 7.3.8.10
 //--------------------------------------------------------------------------------
@@ -2417,28 +2448,24 @@ void CABACWriter::transform_unit( const TransformUnit& tu, CUCtx& cuCtx, Partiti
   {
     const bool              chromaCbfISP = area.blocks[COMPONENT_Cb].valid() && cu.ispMode;
     if (area.blocks[COMPONENT_Cb].valid() && (!cu.isSepTree() || partitioner.chType == CHANNEL_TYPE_CHROMA) && (!cu.ispMode || chromaCbfISP))
-  {
     {
       unsigned cbfDepth = chromaCbfISP ? trDepth - 1 : trDepth;
+      chromaCbfs.Cb     = TU::getCbfAtDepth(tu, COMPONENT_Cb, trDepth);
+      if (!(cu.sbtInfo && tu.noResidual))
       {
-        chromaCbfs.Cb = TU::getCbfAtDepth(tu, COMPONENT_Cb, trDepth);
-        //if (!(cu.sbtInfo && trDepth == 1))
-        if (!(cu.sbtInfo && tu.noResidual))
-          cbf_comp(cs, chromaCbfs.Cb, area.blocks[COMPONENT_Cb], cbfDepth);
+        cbf_comp(cs, chromaCbfs.Cb, area.blocks[COMPONENT_Cb], cbfDepth);
       }
 
+      chromaCbfs.Cr = TU::getCbfAtDepth(tu, COMPONENT_Cr, trDepth);
+      if (!(cu.sbtInfo && tu.noResidual))
       {
-        chromaCbfs.Cr = TU::getCbfAtDepth(tu, COMPONENT_Cr, trDepth);
-        //if (!(cu.sbtInfo && trDepth == 1))
-        if (!(cu.sbtInfo && tu.noResidual))
-          cbf_comp(cs, chromaCbfs.Cr, area.blocks[COMPONENT_Cr], cbfDepth, chromaCbfs.Cb);
+        cbf_comp(cs, chromaCbfs.Cr, area.blocks[COMPONENT_Cr], cbfDepth, chromaCbfs.Cb);
       }
     }
-  }
-  else if (cu.isSepTree())
-  {
-    chromaCbfs = ChromaCbfs(false);
-  }
+    else if (cu.isSepTree())
+    {
+      chromaCbfs = ChromaCbfs(false);
+    }
   }
   else if (cu.isSepTree())
   {
@@ -2536,20 +2563,22 @@ void CABACWriter::transform_unit( const TransformUnit& tu, CUCtx& cuCtx, Partiti
     joint_cb_cr( tu, ( cbf[COMPONENT_Cb] ? 2 : 0 ) + ( cbf[COMPONENT_Cr] ? 1 : 0 ) );
   }
 
-    if( cbfLuma )
-    {
-      residual_coding( tu, COMPONENT_Y, &cuCtx );
-    }
-    if( !lumaOnly )
+  if (cbfLuma)
+  {
+    residual_coding(tu, COMPONENT_Y, &cuCtx);
+  }
+  if (!lumaOnly)
+  {
+    for (ComponentID compID = COMPONENT_Cb; compID <= COMPONENT_Cr; compID = ComponentID(compID + 1))
     {
-      for( ComponentID compID = COMPONENT_Cb; compID <= COMPONENT_Cr; compID = ComponentID( compID + 1 ) )
+      if (cbf[compID])
       {
-        if( cbf[ compID ] )
-        {
-          residual_coding( tu, compID, &cuCtx );
+        residual_coding(tu, compID, &cuCtx);
       }
     }
   }
+
+  DTRACE_COND( ( isEncoding() ), g_trace_ctx, D_DQP, "x=%d, y=%d, d=%d, qpAdj=%d\n", cu.blocks[cu.chType].lumaPos().x, cu.blocks[cu.chType].lumaPos().y, cu.qtDepth, cu.chromaQpAdj );
 }
 
 void CABACWriter::cu_qp_delta( const CodingUnit& cu, int predQP, const int8_t qp )
@@ -2594,10 +2623,6 @@ void CABACWriter::cu_chroma_qp_offset( const CodingUnit& cu )
   }
 }
 
-
-
-
-
 //================================================================================
 //  clause 7.3.8.11
 //--------------------------------------------------------------------------------
@@ -2627,7 +2652,9 @@ void CABACWriter::residual_coding( const TransformUnit& tu, ComponentID compID,
   DTRACE( g_trace_ctx, D_SYNTAX, "residual_coding() etype=%d pos=(%d,%d) size=%dx%d predMode=%d\n", tu.blocks[compID].compID, tu.blocks[compID].x, tu.blocks[compID].y, tu.blocks[compID].width, tu.blocks[compID].height, cu.predMode );
 
   if( compID == COMPONENT_Cr && tu.jointCbCr == 3 )
+  {
     return;
+  }
 
   ts_flag            ( tu, compID );
 
@@ -2685,6 +2712,15 @@ void CABACWriter::residual_coding( const TransformUnit& tu, ComponentID compID,
   int ctxBinSampleRatio = (compID == COMPONENT_Y) ? MAX_TU_LEVEL_CTX_CODED_BIN_CONSTRAINT_LUMA : MAX_TU_LEVEL_CTX_CODED_BIN_CONSTRAINT_CHROMA;
   cctx.regBinLimit = (tu.getTbAreaAfterCoefZeroOut(compID) * ctxBinSampleRatio) >> 4;
 
+  int baseLevel = m_BinEncoder.getCtx().getBaseLevel();
+  cctx.setBaseLevel(baseLevel);
+  if (tu.cs->slice->getSPS()->getSpsRangeExtension().getPersistentRiceAdaptationEnabledFlag())
+  {
+    cctx.setUpdateHist(1);
+    unsigned riceStats = m_BinEncoder.getCtx().getGRAdaptStats((unsigned)compID);
+    TCoeff historyValue = (TCoeff)1 << riceStats;
+    cctx.setHistValue(historyValue);
+  }
   for( int subSetId = ( cctx.scanPosLast() >> cctx.log2CGSize() ); subSetId >= 0; subSetId--)
   {
     cctx.initSubblock       ( subSetId, sigGroupFlags[subSetId] );
@@ -2834,17 +2870,47 @@ void CABACWriter::last_sig_coeff( CoeffCodingContext& cctx, const TransformUnit&
   }
 
   unsigned CtxLast;
-  unsigned GroupIdxX = g_uiGroupIdx[ posX ];
-  unsigned GroupIdxY = g_uiGroupIdx[ posY ];
+  unsigned GroupIdxX = g_groupIdx[posX];
+  unsigned GroupIdxY = g_groupIdx[posY];
 
   unsigned maxLastPosX = cctx.maxLastPosX();
   unsigned maxLastPosY = cctx.maxLastPosY();
 
+#if JVET_W0046_RLSCP
+  unsigned zoTbWdith  = std::min<unsigned>(JVET_C0024_ZERO_OUT_TH, cctx.width());
+  unsigned zoTbHeight = std::min<unsigned>(JVET_C0024_ZERO_OUT_TH, cctx.height());
+#endif
+
   if( tu.cs->sps->getUseMTS() && tu.cu->sbtInfo != 0 && tu.blocks[ compID ].width <= 32 && tu.blocks[ compID ].height <= 32 && compID == COMPONENT_Y )
   {
-    maxLastPosX = ( tu.blocks[compID].width  == 32 ) ? g_uiGroupIdx[ 15 ] : maxLastPosX;
-    maxLastPosY = ( tu.blocks[compID].height == 32 ) ? g_uiGroupIdx[ 15 ] : maxLastPosY;
+    maxLastPosX = (tu.blocks[compID].width == 32) ? g_groupIdx[15] : maxLastPosX;
+    maxLastPosY = (tu.blocks[compID].height == 32) ? g_groupIdx[15] : maxLastPosY;
+#if JVET_W0046_RLSCP
+    zoTbWdith = (tu.blocks[compID].width == 32) ? 16 : zoTbWdith;
+    zoTbHeight = (tu.blocks[compID].height == 32) ? 16 : zoTbHeight;
+#endif
+  }
+#if JVET_W0046_RLSCP
+  if (isEncoding())
+  {
+    if ((posX + posY) > ((zoTbWdith + zoTbHeight + 2) / 2))
+    {
+      tu.cu->slice->updateCntRightBottom(1);
+    }
+    else
+    {
+      tu.cu->slice->updateCntRightBottom(-1);
+    }
+  }
+  if (tu.cu->slice->getReverseLastSigCoeffFlag())
+  {
+    posX = zoTbWdith - 1 - posX;
+    posY = zoTbHeight - 1 - posY;
+
+    GroupIdxX = g_groupIdx[posX];
+    GroupIdxY = g_groupIdx[posY];
   }
+#endif
 
   for( CtxLast = 0; CtxLast < GroupIdxX; CtxLast++ )
   {
@@ -2864,7 +2930,7 @@ void CABACWriter::last_sig_coeff( CoeffCodingContext& cctx, const TransformUnit&
   }
   if( GroupIdxX > 3 )
   {
-    posX -= g_uiMinInGroup[ GroupIdxX ];
+    posX -= g_minInGroup[GroupIdxX];
     for (int i = ( ( GroupIdxX - 2 ) >> 1 ) - 1 ; i >= 0; i-- )
     {
       m_BinEncoder.encodeBinEP( ( posX >> i ) & 1 );
@@ -2872,7 +2938,7 @@ void CABACWriter::last_sig_coeff( CoeffCodingContext& cctx, const TransformUnit&
   }
   if( GroupIdxY > 3 )
   {
-    posY -= g_uiMinInGroup[ GroupIdxY ];
+    posY -= g_minInGroup[GroupIdxY];
     for ( int i = ( ( GroupIdxY - 2 ) >> 1 ) - 1 ; i >= 0; i-- )
     {
       m_BinEncoder.encodeBinEP( ( posY >> i ) & 1 );
@@ -2880,8 +2946,6 @@ void CABACWriter::last_sig_coeff( CoeffCodingContext& cctx, const TransformUnit&
   }
 }
 
-
-
 void CABACWriter::residual_coding_subblock( CoeffCodingContext& cctx, const TCoeff* coeff, const int stateTransTable, int& state )
 {
   //===== init =====
@@ -2889,6 +2953,8 @@ void CABACWriter::residual_coding_subblock( CoeffCodingContext& cctx, const TCoe
   const bool  isLast      = cctx.isLast();
   int         firstSigPos = ( isLast ? cctx.scanPosLast() : cctx.maxSubPos() );
   int         nextSigPos  = firstSigPos;
+  int baseLevel = cctx.getBaseLevel();
+  bool updateHistory = cctx.getUpdateHist();
 
   //===== encode significant_coeffgroup_flag =====
   if( !isLast && cctx.isNotFirst() )
@@ -2974,14 +3040,21 @@ void CABACWriter::residual_coding_subblock( CoeffCodingContext& cctx, const TCoe
   unsigned ricePar = 0;
   for( int scanPos = firstSigPos; scanPos > firstPosMode2; scanPos-- )
   {
-    int       sumAll = cctx.templateAbsSum(scanPos, coeff, 4);
-    ricePar = g_auiGoRiceParsCoeff[sumAll];
+     ricePar = (cctx.*(cctx.deriveRiceRRC))(scanPos, coeff, baseLevel);
+
     unsigned absLevel = (unsigned) abs( coeff[ cctx.blockPos( scanPos ) ] );
     if( absLevel >= 4 )
     {
       unsigned rem      = ( absLevel - 4 ) >> 1;
       m_BinEncoder.encodeRemAbsEP( rem, ricePar, COEF_REMAIN_BIN_REDUCTION, cctx.maxLog2TrDRange() );
       DTRACE( g_trace_ctx, D_SYNTAX_RESI, "rem_val() bin=%d ctx=%d\n", rem, ricePar );
+      if ((updateHistory) && (rem > 0))
+      {
+        unsigned &riceStats = m_BinEncoder.getCtx().getGRAdaptStats((unsigned)(cctx.compID()));
+        cctx.updateRiceStat(riceStats, rem, 1);
+        cctx.setUpdateHist(0);
+        updateHistory = 0;
+      }
     }
   }
 
@@ -2990,13 +3063,19 @@ void CABACWriter::residual_coding_subblock( CoeffCodingContext& cctx, const TCoe
   {
     TCoeff    Coeff     = coeff[ cctx.blockPos( scanPos ) ];
     unsigned    absLevel  = (unsigned) abs( Coeff );
-    int       sumAll = cctx.templateAbsSum(scanPos, coeff, 0);
-    int       rice      = g_auiGoRiceParsCoeff                        [sumAll];
-    int       pos0      = g_auiGoRicePosCoeff0(state, rice);
+    int rice = (cctx.*(cctx.deriveRiceRRC))(scanPos, coeff, 0);
+    int         pos0      = g_goRicePosCoeff0(state, rice);
     unsigned  rem       = ( absLevel == 0 ? pos0 : absLevel <= pos0 ? absLevel-1 : absLevel );
     m_BinEncoder.encodeRemAbsEP( rem, rice, COEF_REMAIN_BIN_REDUCTION, cctx.maxLog2TrDRange() );
     DTRACE( g_trace_ctx, D_SYNTAX_RESI, "rem_val() bin=%d ctx=%d\n", rem, rice );
     state = ( stateTransTable >> ((state<<2)+((absLevel&1)<<1)) ) & 3;
+    if ((updateHistory) && (rem > 0))
+    {
+      unsigned &riceStats = m_BinEncoder.getCtx().getGRAdaptStats((unsigned)cctx.compID());
+      cctx.updateRiceStat(riceStats, rem, 0);
+      cctx.setUpdateHist(0);
+      updateHistory = 0;
+    }
     if( absLevel )
     {
       numNonZero++;
@@ -3042,11 +3121,33 @@ void CABACWriter::residual_codingTS( const TransformUnit& tu, ComponentID compID
   for( int subSetId = 0; subSetId <= ( cctx.maxNumCoeff() - 1 ) >> cctx.log2CGSize(); subSetId++ )
   {
     cctx.initSubblock         ( subSetId, sigGroupFlags[subSetId] );
-    residual_coding_subblockTS( cctx, coeff );
+    int goRiceParam = 1;
+    bool ricePresentFlag = false;
+    unsigned RiceBit[8]   = { 0, 0, 0, 0, 0, 0, 0, 0 };
+    if (tu.cu->slice->getSPS()->getSpsRangeExtension().getTSRCRicePresentFlag() && tu.mtsIdx[compID] == MTS_SKIP)
+    {
+      goRiceParam = goRiceParam + tu.cu->slice->get_tsrc_index();
+      if (isEncoding())
+      {
+        ricePresentFlag = true;
+        for (int i = 0; i < MAX_TSRC_RICE; i++)
+        {
+          RiceBit[i] = tu.cu->slice->getRiceBit(i);
+        }
+      }
+    }
+    residual_coding_subblockTS( cctx, coeff, RiceBit, goRiceParam, ricePresentFlag);
+    if (tu.cu->slice->getSPS()->getSpsRangeExtension().getTSRCRicePresentFlag() && tu.mtsIdx[compID] == MTS_SKIP && isEncoding())
+    {
+      for (int i = 0; i < MAX_TSRC_RICE; i++)
+      {
+        tu.cu->slice->setRiceBit(i, RiceBit[i]);
+      }
+    }
   }
 }
 
-void CABACWriter::residual_coding_subblockTS( CoeffCodingContext& cctx, const TCoeff* coeff )
+void CABACWriter::residual_coding_subblockTS( CoeffCodingContext& cctx, const TCoeff* coeff, unsigned (&RiceBit)[8], int riceParam, bool ricePresentFlag)
 {
   //===== init =====
   const int   minSubPos   = cctx.maxSubPos();
@@ -3058,13 +3159,13 @@ void CABACWriter::residual_coding_subblockTS( CoeffCodingContext& cctx, const TC
   {
     if( cctx.isSigGroup() )
     {
-        m_BinEncoder.encodeBin( 1, cctx.sigGroupCtxId( true ) );
-        DTRACE( g_trace_ctx, D_SYNTAX_RESI, "ts_sigGroup() bin=%d ctx=%d\n", 1, cctx.sigGroupCtxId() );
+      m_BinEncoder.encodeBin(1, cctx.sigGroupCtxId(true));
+      DTRACE(g_trace_ctx, D_SYNTAX_RESI, "ts_sigGroup() bin=%d ctx=%d\n", 1, cctx.sigGroupCtxId());
     }
     else
     {
-        m_BinEncoder.encodeBin( 0, cctx.sigGroupCtxId( true ) );
-        DTRACE( g_trace_ctx, D_SYNTAX_RESI, "ts_sigGroup() bin=%d ctx=%d\n", 0, cctx.sigGroupCtxId() );
+      m_BinEncoder.encodeBin(0, cctx.sigGroupCtxId(true));
+      DTRACE(g_trace_ctx, D_SYNTAX_RESI, "ts_sigGroup() bin=%d ctx=%d\n", 0, cctx.sigGroupCtxId());
       return;
     }
   }
@@ -3084,19 +3185,19 @@ void CABACWriter::residual_coding_subblockTS( CoeffCodingContext& cctx, const TC
     unsigned  sigFlag    = ( Coeff != 0 );
     if( numNonZero || nextSigPos != inferSigPos )
     {
-        const unsigned sigCtxId = cctx.sigCtxIdAbsTS( nextSigPos, coeff );
-        m_BinEncoder.encodeBin( sigFlag, sigCtxId );
-        DTRACE( g_trace_ctx, D_SYNTAX_RESI, "ts_sig_bin() bin=%d ctx=%d\n", sigFlag, sigCtxId );
-        cctx.decimateNumCtxBins(1);
+      const unsigned sigCtxId = cctx.sigCtxIdAbsTS(nextSigPos, coeff);
+      m_BinEncoder.encodeBin(sigFlag, sigCtxId);
+      DTRACE(g_trace_ctx, D_SYNTAX_RESI, "ts_sig_bin() bin=%d ctx=%d\n", sigFlag, sigCtxId);
+      cctx.decimateNumCtxBins(1);
     }
 
     if( sigFlag )
     {
       //===== encode sign's =====
       int sign = Coeff < 0;
-        const unsigned signCtxId = cctx.signCtxIdAbsTS(nextSigPos, coeff, cctx.bdpcm());
-        m_BinEncoder.encodeBin(sign, signCtxId);
-        cctx.decimateNumCtxBins(1);
+      const unsigned signCtxId = cctx.signCtxIdAbsTS(nextSigPos, coeff, cctx.bdpcm());
+      m_BinEncoder.encodeBin(sign, signCtxId);
+      cctx.decimateNumCtxBins(1);
       numNonZero++;
       cctx.neighTS(rightPixel, belowPixel, nextSigPos, coeff);
       modAbsCoeff = cctx.deriveModCoeff(rightPixel, belowPixel, abs(Coeff), cctx.bdpcm());
@@ -3104,9 +3205,9 @@ void CABACWriter::residual_coding_subblockTS( CoeffCodingContext& cctx, const TC
 
       unsigned gt1 = !!remAbsLevel;
       const unsigned gt1CtxId = cctx.lrg1CtxIdAbsTS(nextSigPos, coeff, cctx.bdpcm());
-        m_BinEncoder.encodeBin(gt1, gt1CtxId);
-        DTRACE(g_trace_ctx, D_SYNTAX_RESI, "ts_gt1_flag() bin=%d ctx=%d\n", gt1, gt1CtxId);
-        cctx.decimateNumCtxBins(1);
+      m_BinEncoder.encodeBin(gt1, gt1CtxId);
+      DTRACE(g_trace_ctx, D_SYNTAX_RESI, "ts_gt1_flag() bin=%d ctx=%d\n", gt1, gt1CtxId);
+      cctx.decimateNumCtxBins(1);
 
       if( gt1 )
       {
@@ -3151,10 +3252,33 @@ void CABACWriter::residual_coding_subblockTS( CoeffCodingContext& cctx, const TC
 
     if( absLevel >= cutoffVal )
     {
-      int       rice = cctx.templateAbsSumTS( scanPos, coeff );
+      int       rice = riceParam;
       unsigned  rem = scanPos <= lastScanPosPass1 ? (absLevel - cutoffVal) >> 1 : absLevel;
       m_BinEncoder.encodeRemAbsEP( rem, rice, COEF_REMAIN_BIN_REDUCTION, cctx.maxLog2TrDRange() );
       DTRACE( g_trace_ctx, D_SYNTAX_RESI, "ts_rem_val() bin=%d ctx=%d sp=%d\n", rem, rice, scanPos );
+      if ( ricePresentFlag && (isEncoding()) && (cctx.compID() == COMPONENT_Y))
+      {
+        for (int idx = 1; idx < 9; idx++)
+        {
+          uint32_t length;
+          uint32_t symbol = rem;
+          if (rem < (5 << idx))
+          {
+            length = rem >> idx;
+            RiceBit[idx - 1] += (length + 1 + idx);
+          }
+          else
+          {
+            length = idx;
+            symbol = symbol - (5 << idx);
+            while (symbol >= (1 << length))
+            {
+              symbol -= (1 << (length++));
+            }
+            RiceBit[idx - 1] += (5 + length + 1 - idx + length);
+          }
+        }
+      }
 
       if (absLevel && scanPos > lastScanPosPass1)
       {
@@ -3165,12 +3289,6 @@ void CABACWriter::residual_coding_subblockTS( CoeffCodingContext& cctx, const TC
   }
 }
 
-
-
-
-
-
-
 //================================================================================
 //  helper functions
 //--------------------------------------------------------------------------------
@@ -3240,14 +3358,20 @@ void CABACWriter::codeAlfCtuEnableFlags( CodingStructure& cs, ChannelType channe
   if( isLuma( channel ) )
   {
     if (alfParam->enabledFlag[COMPONENT_Y])
+    {
       codeAlfCtuEnableFlags( cs, COMPONENT_Y, alfParam );
+    }
   }
   else
   {
     if (alfParam->enabledFlag[COMPONENT_Cb])
+    {
       codeAlfCtuEnableFlags( cs, COMPONENT_Cb, alfParam );
+    }
     if (alfParam->enabledFlag[COMPONENT_Cr])
+    {
       codeAlfCtuEnableFlags( cs, COMPONENT_Cr, alfParam );
+    }
   }
 }
 void CABACWriter::codeAlfCtuEnableFlags( CodingStructure& cs, ComponentID compID, AlfParam* alfParam)
@@ -3262,7 +3386,7 @@ void CABACWriter::codeAlfCtuEnableFlags( CodingStructure& cs, ComponentID compID
 
 void CABACWriter::codeAlfCtuEnableFlag( CodingStructure& cs, uint32_t ctuRsAddr, const int compIdx, AlfParam* alfParam)
 {
-  const bool alfComponentEnabled = (alfParam != NULL) ? alfParam->enabledFlag[compIdx] : cs.slice->getTileGroupAlfEnabledFlag((ComponentID)compIdx);
+  const bool alfComponentEnabled = (alfParam != NULL) ? alfParam->enabledFlag[compIdx] : cs.slice->getAlfEnabledFlag((ComponentID)compIdx);
 
   if( cs.sps->getALFEnabledFlag() && alfComponentEnabled )
   {
@@ -3396,7 +3520,7 @@ void CABACWriter::codeAlfCtuFilterIndex(CodingStructure& cs, uint32_t ctuRsAddr,
 
   short* alfCtbFilterIndex = cs.slice->getPic()->getAlfCtbFilterIndex();
   const unsigned filterSetIdx = alfCtbFilterIndex[ctuRsAddr];
-  unsigned numAps = cs.slice->getTileGroupNumAps();
+  unsigned numAps = cs.slice->getNumAlfApsIdsLuma();
   unsigned numAvailableFiltSets = numAps + NUM_FIXED_FILTER_SETS;
   if (numAvailableFiltSets > NUM_FIXED_FILTER_SETS)
   {
@@ -3422,20 +3546,28 @@ void CABACWriter::codeAlfCtuFilterIndex(CodingStructure& cs, uint32_t ctuRsAddr,
     xWriteTruncBinCode(filterSetIdx, NUM_FIXED_FILTER_SETS);
   }
 }
+
 void CABACWriter::codeAlfCtuAlternatives( CodingStructure& cs, ChannelType channel, AlfParam* alfParam)
 {
   if( isChroma( channel ) )
   {
     if (alfParam->enabledFlag[COMPONENT_Cb])
+    {
       codeAlfCtuAlternatives( cs, COMPONENT_Cb, alfParam );
+    }
     if (alfParam->enabledFlag[COMPONENT_Cr])
+    {
       codeAlfCtuAlternatives( cs, COMPONENT_Cr, alfParam );
+    }
   }
 }
+
 void CABACWriter::codeAlfCtuAlternatives( CodingStructure& cs, ComponentID compID, AlfParam* alfParam)
 {
   if( compID == COMPONENT_Y )
+  {
     return;
+  }
   uint32_t numCTUs = cs.pcv->sizeInCtus;
   uint8_t* ctbAlfFlag = cs.slice->getPic()->getAlfCtuEnableFlag( compID );
 
@@ -3451,11 +3583,13 @@ void CABACWriter::codeAlfCtuAlternatives( CodingStructure& cs, ComponentID compI
 void CABACWriter::codeAlfCtuAlternative( CodingStructure& cs, uint32_t ctuRsAddr, const int compIdx, const AlfParam* alfParam)
 {
   if( compIdx == COMPONENT_Y )
+  {
     return;
-  int apsIdx = alfParam ? 0 : cs.slice->getTileGroupApsIdChroma();
+  }
+  int apsIdx = alfParam ? 0 : cs.slice->getAlfApsIdChroma();
   const AlfParam& alfParamRef = alfParam ? (*alfParam) : cs.slice->getAlfAPSs()[apsIdx]->getAlfAPSParam();
 
-  if( alfParam || (cs.sps->getALFEnabledFlag() && cs.slice->getTileGroupAlfEnabledFlag( (ComponentID)compIdx )) )
+  if( alfParam || (cs.sps->getALFEnabledFlag() && cs.slice->getAlfEnabledFlag( (ComponentID)compIdx )) )
   {
     uint8_t* ctbAlfFlag = cs.slice->getPic()->getAlfCtuEnableFlag( compIdx );
 
@@ -3466,9 +3600,13 @@ void CABACWriter::codeAlfCtuAlternative( CodingStructure& cs, uint32_t ctuRsAddr
       unsigned numOnes = ctbAlfAlternative[ctuRsAddr];
       assert( ctbAlfAlternative[ctuRsAddr] < numAlts );
       for( int i = 0; i < numOnes; ++i )
+      {
         m_BinEncoder.encodeBin( 1, Ctx::ctbAlfAlternative( compIdx-1 ) );
+      }
       if( numOnes < numAlts-1 )
+      {
         m_BinEncoder.encodeBin( 0, Ctx::ctbAlfAlternative( compIdx-1 ) );
+      }
     }
   }
 }
diff --git a/source/Lib/EncoderLib/CABACWriter.h b/source/Lib/EncoderLib/CABACWriter.h
index 62a39d7a6..a230571fd 100644
--- a/source/Lib/EncoderLib/CABACWriter.h
+++ b/source/Lib/EncoderLib/CABACWriter.h
@@ -3,7 +3,7 @@
 * and contributor rights, including patent rights, and no such rights are
 * granted under this license.
 *
-* Copyright (c) 2010-2020, ITU/ISO/IEC
+* Copyright (c) 2010-2021, ITU/ISO/IEC
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
@@ -149,7 +149,7 @@ public:
   void        last_sig_coeff            ( CoeffCodingContext&           cctx,     const TransformUnit& tu, ComponentID       compID );
   void        residual_coding_subblock  ( CoeffCodingContext&           cctx,     const TCoeff*     coeff, const int stateTransTable, int& state );
   void        residual_codingTS         ( const TransformUnit&          tu,       ComponentID       compID );
-  void        residual_coding_subblockTS( CoeffCodingContext&           cctx,     const TCoeff*     coeff  );
+  void        residual_coding_subblockTS( CoeffCodingContext&           cctx,     const TCoeff*     coeff, unsigned (&RiceBit)[8], int riceParam, bool ricePresentFlag);
   void        joint_cb_cr               ( const TransformUnit&          tu,       const int cbfMask );
 
 
diff --git a/source/Lib/EncoderLib/CMakeLists.txt b/source/Lib/EncoderLib/CMakeLists.txt
index 2a50346f2..9585d923b 100644
--- a/source/Lib/EncoderLib/CMakeLists.txt
+++ b/source/Lib/EncoderLib/CMakeLists.txt
@@ -32,28 +32,8 @@ if( SET_ENABLE_TRACING )
   endif()
 endif()
 
-if( OpenMP_FOUND )
-  if( SET_ENABLE_SPLIT_PARALLELISM )
-    if( ENABLE_SPLIT_PARALLELISM )
-      target_compile_definitions( ${LIB_NAME} PUBLIC ENABLE_SPLIT_PARALLELISM=1 )
-    else()
-      target_compile_definitions( ${LIB_NAME} PUBLIC ENABLE_SPLIT_PARALLELISM=0 )
-    endif()
-  endif()
-  if( SET_ENABLE_WPP_PARALLELISM )
-    if( ENABLE_WPP_PARALLELISM )
-      target_compile_definitions( ${LIB_NAME} PUBLIC ENABLE_WPP_PARALLELISM=1 )
-    else()
-      target_compile_definitions( ${LIB_NAME} PUBLIC ENABLE_WPP_PARALLELISM=0 )
-    endif()
-  endif()
-else()
-  target_compile_definitions( ${LIB_NAME} PUBLIC ENABLE_SPLIT_PARALLELISM=0 )
-  target_compile_definitions( ${LIB_NAME} PUBLIC ENABLE_WPP_PARALLELISM=0 )
-endif()
-
 target_include_directories( ${LIB_NAME} PUBLIC . )
-target_link_libraries( ${LIB_NAME} CommonLib Threads::Threads )
+target_link_libraries( ${LIB_NAME} CommonLib )
 
 if( CMAKE_COMPILER_IS_GNUCC )
   # this is quite certainly a compiler problem
diff --git a/source/Lib/EncoderLib/EncAdaptiveLoopFilter.cpp b/source/Lib/EncoderLib/EncAdaptiveLoopFilter.cpp
index c4f260b2e..60cfb552c 100644
--- a/source/Lib/EncoderLib/EncAdaptiveLoopFilter.cpp
+++ b/source/Lib/EncoderLib/EncAdaptiveLoopFilter.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -807,8 +807,8 @@ void EncAdaptiveLoopFilter::xSetupCcAlfAPS( CodingStructure &cs )
 {
   if (m_ccAlfFilterParam.ccAlfFilterEnabled[COMPONENT_Cb - 1])
   {
-    int  ccAlfCbApsId = cs.slice->getTileGroupCcAlfCbApsId();
-    APS* aps = m_apsMap->getPS((cs.slice->getTileGroupCcAlfCbApsId() << NUM_APS_TYPE_LEN) + ALF_APS);
+    int  ccAlfCbApsId = cs.slice->getCcAlfCbApsId();
+    APS* aps = m_apsMap->getPS((cs.slice->getCcAlfCbApsId() << NUM_APS_TYPE_LEN) + ALF_APS);
     if (aps == NULL)
     {
       aps = m_apsMap->allocatePS((ccAlfCbApsId << NUM_APS_TYPE_LEN) + ALF_APS);
@@ -831,16 +831,16 @@ void EncAdaptiveLoopFilter::xSetupCcAlfAPS( CodingStructure &cs )
       m_apsMap->setChangedFlag((ccAlfCbApsId << NUM_APS_TYPE_LEN) + ALF_APS, true);
       aps->setTemporalId(cs.slice->getTLayer());
     }
-    cs.slice->setTileGroupCcAlfCbEnabledFlag(true);
+    cs.slice->setCcAlfCbEnabledFlag(true);
   }
   else
   {
-    cs.slice->setTileGroupCcAlfCbEnabledFlag(false);
+    cs.slice->setCcAlfCbEnabledFlag(false);
   }
   if (m_ccAlfFilterParam.ccAlfFilterEnabled[COMPONENT_Cr - 1])
   {
-    int  ccAlfCrApsId = cs.slice->getTileGroupCcAlfCrApsId();
-    APS* aps = m_apsMap->getPS((cs.slice->getTileGroupCcAlfCrApsId() << NUM_APS_TYPE_LEN) + ALF_APS);
+    int  ccAlfCrApsId = cs.slice->getCcAlfCrApsId();
+    APS* aps = m_apsMap->getPS((cs.slice->getCcAlfCrApsId() << NUM_APS_TYPE_LEN) + ALF_APS);
     if (aps == NULL)
     {
       aps = m_apsMap->allocatePS((ccAlfCrApsId << NUM_APS_TYPE_LEN) + ALF_APS);
@@ -863,11 +863,11 @@ void EncAdaptiveLoopFilter::xSetupCcAlfAPS( CodingStructure &cs )
       aps->setTemporalId(cs.slice->getTLayer());
     }
     aps->setAPSType(ALF_APS);
-    cs.slice->setTileGroupCcAlfCrEnabledFlag(true);
+    cs.slice->setCcAlfCrEnabledFlag(true);
   }
   else
   {
-    cs.slice->setTileGroupCcAlfCrEnabledFlag(false);
+    cs.slice->setCcAlfCrEnabledFlag(false);
   }
 }
 
@@ -881,7 +881,11 @@ void EncAdaptiveLoopFilter::ALFProcess(CodingStructure& cs, const double *lambda
   int layerIdx = cs.vps == nullptr ? 0 : cs.vps->getGeneralLayerIdx( cs.slice->getPic()->layerId );
 
    // IRAP AU is assumed
+#if JVET_W0133_CONSTRAINED_RASL_ENCODING
+  if( !layerIdx && ( cs.slice->getPendingRasInit() || cs.slice->isIDRorBLA() || ( cs.slice->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA && m_encCfg->getCraAPSreset() ) ) )
+#else
   if( !layerIdx && ( cs.slice->getPendingRasInit() || cs.slice->isIDRorBLA() ) )
+#endif
   {
     memset(cs.slice->getAlfAPSs(), 0, sizeof(*cs.slice->getAlfAPSs())*ALF_CTB_MAX_NUM_APS);
     m_apsIdStart = ALF_CTB_MAX_NUM_APS;
@@ -925,8 +929,11 @@ void EncAdaptiveLoopFilter::ALFProcess(CodingStructure& cs, const double *lambda
   m_lambda[COMPONENT_Y] = lambdas[COMPONENT_Y] * double(1 << shiftLuma);
   m_lambda[COMPONENT_Cb] = lambdas[COMPONENT_Cb] * double(1 << shiftChroma);
   m_lambda[COMPONENT_Cr] = lambdas[COMPONENT_Cr] * double(1 << shiftChroma);
-
-  PelUnitBuf orgYuv = cs.getOrgBuf();
+#if JVET_W0129_ENABLE_ALF_TRUEORG
+  PelUnitBuf orgYuv = m_encCfg->getAlfTrueOrg() ? cs.getTrueOrgBuf() : cs.getOrgBuf();
+#else
+  PelUnitBuf orgYuv = m_encCfg->getAlfSaoTrueOrg() ? cs.getTrueOrgBuf() : cs.getOrgBuf();
+#endif
 
   m_tempBuf.copyFrom( cs.getRecoBuf() );
   PelUnitBuf recYuv = m_tempBuf.getBuf( cs.area );
@@ -1009,7 +1016,7 @@ void EncAdaptiveLoopFilter::ALFProcess(CodingStructure& cs, const double *lambda
   // consider using new filter (only)
   alfParam.newFilterFlag[CHANNEL_TYPE_LUMA] = true;
   alfParam.newFilterFlag[CHANNEL_TYPE_CHROMA] = true;
-  cs.slice->setTileGroupNumAps(1); // Only new filter for RD cost optimization
+  cs.slice->setNumAlfApsIdsLuma(1); // Only new filter for RD cost optimization
   // derive filter (luma)
   alfEncoder( cs, alfParam, orgYuv, recYuv, cs.getRecoBuf(), CHANNEL_TYPE_LUMA
 #if ENABLE_QPA
@@ -1030,7 +1037,7 @@ void EncAdaptiveLoopFilter::ALFProcess(CodingStructure& cs, const double *lambda
   // let alfEncoderCtb decide now
   alfParam.newFilterFlag[CHANNEL_TYPE_LUMA] = false;
   alfParam.newFilterFlag[CHANNEL_TYPE_CHROMA] = false;
-  cs.slice->setTileGroupNumAps(0);
+  cs.slice->setNumAlfApsIdsLuma(0);
   m_CABACEstimator->getCtx() = AlfCtx(ctxStart);
   alfEncoderCtb(cs, alfParam
 #if ENABLE_QPA
@@ -1055,9 +1062,9 @@ void EncAdaptiveLoopFilter::ALFProcess(CodingStructure& cs, const double *lambda
   alfReconstructor(cs, recYuv);
 
   // Do not transmit CC ALF if it is unchanged
-  if (cs.slice->getTileGroupAlfEnabledFlag(COMPONENT_Y))
+  if (cs.slice->getAlfEnabledFlag(COMPONENT_Y))
   {
-    for (int32_t lumaAlfApsId : cs.slice->getTileGroupApsIdLuma())
+    for (int32_t lumaAlfApsId : cs.slice->getAlfApsIdsLuma())
     {
       APS* aps = (lumaAlfApsId >= 0) ? m_apsMap->getPS((lumaAlfApsId << NUM_APS_TYPE_LEN) + ALF_APS) : nullptr;
       if (aps && m_apsMap->getChangedFlag((lumaAlfApsId << NUM_APS_TYPE_LEN) + ALF_APS))
@@ -1067,7 +1074,7 @@ void EncAdaptiveLoopFilter::ALFProcess(CodingStructure& cs, const double *lambda
       }
     }
   }
-  int chromaAlfApsId = ( cs.slice->getTileGroupAlfEnabledFlag(COMPONENT_Cb) || cs.slice->getTileGroupAlfEnabledFlag(COMPONENT_Cr) ) ? cs.slice->getTileGroupApsIdChroma() : -1;
+  int chromaAlfApsId = ( cs.slice->getAlfEnabledFlag(COMPONENT_Cb) || cs.slice->getAlfEnabledFlag(COMPONENT_Cr) ) ? cs.slice->getAlfApsIdChroma() : -1;
   APS* aps = (chromaAlfApsId >= 0) ? m_apsMap->getPS((chromaAlfApsId << NUM_APS_TYPE_LEN) + ALF_APS) : nullptr;
   if (aps && m_apsMap->getChangedFlag((chromaAlfApsId << NUM_APS_TYPE_LEN) + ALF_APS))
   {
@@ -1084,7 +1091,7 @@ void EncAdaptiveLoopFilter::ALFProcess(CodingStructure& cs, const double *lambda
   m_tempBuf.get(COMPONENT_Cr).copyFrom(cs.getRecoBuf().get(COMPONENT_Cr));
   recYuv = m_tempBuf.getBuf(cs.area);
   recYuv.extendBorderPel(MAX_ALF_FILTER_LENGTH >> 1);
-  
+
   deriveStatsForCcAlfFiltering(orgYuv, recYuv, COMPONENT_Cb, m_numCTUsInWidth, (0 + 1), cs);
   deriveStatsForCcAlfFiltering(orgYuv, recYuv, COMPONENT_Cr, m_numCTUsInWidth, (0 + 1), cs);
   initDistortionCcalf();
@@ -1162,7 +1169,7 @@ double EncAdaptiveLoopFilter::deriveCtbAlfEnableFlags( CodingStructure& cs, cons
       {
         // Evaluate cost of signaling filter set index for convergence of filters enabled flag / filter derivation
         assert( cs.slice->getPic()->getAlfCtbFilterIndex()[ctuIdx] == NUM_FIXED_FILTER_SETS );
-        assert( cs.slice->getTileGroupNumAps() == 1 );
+        assert( cs.slice->getNumAlfApsIdsLuma() == 1 );
         m_CABACEstimator->codeAlfCtuFilterIndex(cs, ctuIdx, &m_alfParamTemp.enabledFlag[COMPONENT_Y]);
       }
       double costOn = distUnfilterCtu + ctuLambda * FRAC_BITS_SCALE * m_CABACEstimator->getEstFracBits();
@@ -1459,7 +1466,7 @@ double EncAdaptiveLoopFilter::getFilterCoeffAndCost( CodingStructure& cs, double
     {
       // Evaluate cost of signaling filter set index for convergence of filters enabled flag / filter derivation
       assert( cs.slice->getPic()->getAlfCtbFilterIndex()[ctuIdx] == NUM_FIXED_FILTER_SETS );
-      assert( cs.slice->getTileGroupNumAps() == 1 );
+      assert( cs.slice->getNumAlfApsIdsLuma() == 1 );
       m_CABACEstimator->codeAlfCtuFilterIndex(cs, ctuIdx, &m_alfParamTemp.enabledFlag[COMPONENT_Y]);
     }
   }
@@ -1707,7 +1714,9 @@ int EncAdaptiveLoopFilter::lengthFilterCoeffs( AlfFilterShape& alfShape, const i
     {
       bitCnt += lengthUvlc( abs( FilterCoeff[ ind ][ i ] ) );
       if( abs( FilterCoeff[ ind ][ i ] ) != 0 )
+      {
         bitCnt += 1;
+      }
     }
   }
   return bitCnt;
@@ -1767,23 +1776,23 @@ double EncAdaptiveLoopFilter::getDistCoeffForce0( bool* codedVarBins, double err
   return distForce0;
 }
 
-int EncAdaptiveLoopFilter::lengthUvlc( int uiCode )
+int EncAdaptiveLoopFilter::lengthUvlc(int code)
 {
-  int uiLength = 1;
-  int uiTemp = ++uiCode;
+  CHECK(code < 0,        "Unsigned VLC cannot be negative");
+  CHECK(code == MAX_INT, "Maximum supported UVLC code is MAX_INT-1");
 
-  CHECK( !uiTemp, "Integer overflow" );
+  int length = 1;
+  int temp = ++code;
 
-  while( 1 != uiTemp )
+  while (1 != temp)
   {
-    uiTemp >>= 1;
-    uiLength += 2;
+    temp >>= 1;
+    length += 2;
   }
-  // Take care of cases where uiLength > 32
-  return ( uiLength >> 1 ) + ( ( uiLength + 1 ) >> 1 );
+  // Take care of cases where length > 32
+  return (length >> 1) + ((length + 1) >> 1);
 }
 
-
 double EncAdaptiveLoopFilter::deriveFilterCoeffs( AlfCovariance* cov, AlfCovariance* covMerged, int clipMerged[MAX_NUM_ALF_CLASSES][MAX_NUM_ALF_CLASSES][MAX_NUM_ALF_LUMA_COEFF], AlfFilterShape& alfShape, short* filterIndices, int numFilters, double errorTabForce0Coeff[MAX_NUM_ALF_CLASSES][2], AlfParam& alfParam )
 {
   double error = 0.0;
@@ -1834,12 +1843,11 @@ double EncAdaptiveLoopFilter::deriveCoeffQuant( int *filterClipp, int *filterCoe
   filterCoeffQuant[numCoeff - 1] = 0;
 
   int modified=1;
-#if JVET_T0064
-  if( m_encCfg->getALFStrength() != 1.0 )
+  bool isLumaFilter = numCoeff > 7 ? 1 : 0;
+  if ((isLumaFilter && m_encCfg->getALFStrengthLuma() != 1.0) || (!isLumaFilter && m_encCfg->getALFStrengthChroma() != 1.0))
   {
     modified = 0;
   }
-#endif
   double errRef=cov.calcErrorForCoeffs( filterClipp, filterCoeffQuant, numCoeff, bitDepth );
   while( modified )
   {
@@ -1880,14 +1888,12 @@ double EncAdaptiveLoopFilter::deriveCoeffQuant( int *filterClipp, int *filterCoe
 
 void EncAdaptiveLoopFilter::roundFiltCoeff( int *filterCoeffQuant, double *filterCoeff, const int numCoeff, const int factor )
 {
+  bool isLumaFilter = numCoeff > 7 ? 1 : 0;
+  double alfStrength = isLumaFilter ? m_encCfg->getALFStrengthLuma() : m_encCfg->getALFStrengthChroma();
   for( int i = 0; i < numCoeff; i++ )
   {
     int sign = filterCoeff[i] > 0 ? 1 : -1;
-#if JVET_T0064
-    filterCoeffQuant[i] = int((filterCoeff[i] * m_encCfg->getALFStrength()) * sign * factor + 0.5) * sign;
-#else
-    filterCoeffQuant[i] = int( filterCoeff[i] * sign * factor + 0.5 ) * sign;
-#endif
+    filterCoeffQuant[i] = int((filterCoeff[i] * alfStrength) * sign * factor + 0.5) * sign;
   }
 }
 
@@ -1901,11 +1907,7 @@ void EncAdaptiveLoopFilter::roundFiltCoeffCCALF(int16_t *filterCoeffQuant, doubl
     int best_index = 0;
     for(int k = 0; k < CCALF_CANDS_COEFF_NR; k++)
     {
-#if JVET_T0064
       double err = ((filterCoeff[i] * m_encCfg->getCCALFStrength()) * sign * factor - CCALF_SMALL_TAB[k]);
-#else
-      double err = (filterCoeff[i] * sign * factor - CCALF_SMALL_TAB[k]);
-#endif
       err = err*err;
       if(err < best_err)
       {
@@ -2273,7 +2275,19 @@ void EncAdaptiveLoopFilter::getBlkStats(AlfCovariance* alfCovariance, const AlfF
   const int numBins = AlfNumClippingValues[channel];
   int transposeIdx = 0;
   int classIdx = 0;
-
+  bool isLumaFilter = shape.numCoeff > 7 ? 1 : 0;
+  double filterStrengthTarget = isLumaFilter ? m_encCfg->getALFStrengthTargetLuma() : m_encCfg->getALFStrengthTargetChroma();
+  double filterStrengthTargetE = 1.0;
+  double filterStrengthTargetY = 1.0;
+  if (filterStrengthTarget != 0.0)
+  {
+    filterStrengthTargetY = 1 / filterStrengthTarget;
+    filterStrengthTargetE = filterStrengthTargetY * filterStrengthTargetY;
+  }
+  else
+  {
+    filterStrengthTargetY = 0.0;
+  }
   for( int i = 0; i < area.height; i++ )
   {
     int vbDistance = ((areaDst.y + i) % vbCTUHeight) - vbPos;
@@ -2308,11 +2322,11 @@ void EncAdaptiveLoopFilter::getBlkStats(AlfCovariance* alfCovariance, const AlfF
             {
               if (m_alfWSSD)
               {
-                alfCovariance[classIdx].E[b0][b1][k][l] += weight * (ELocal[k][b0] * (double)ELocal[l][b1]);
+                alfCovariance[classIdx].E[b0][b1][k][l] += filterStrengthTargetE * weight * (ELocal[k][b0] * (double)ELocal[l][b1]);
               }
               else
               {
-                alfCovariance[classIdx].E[b0][b1][k][l] += ELocal[k][b0] * (double)ELocal[l][b1];
+                alfCovariance[classIdx].E[b0][b1][k][l] += filterStrengthTargetE * ELocal[k][b0] * (double)ELocal[l][b1];
               }
             }
           }
@@ -2321,11 +2335,11 @@ void EncAdaptiveLoopFilter::getBlkStats(AlfCovariance* alfCovariance, const AlfF
         {
           if (m_alfWSSD)
           {
-            alfCovariance[classIdx].y[b][k] += weight * (ELocal[k][b] * (double)yLocal);
+            alfCovariance[classIdx].y[b][k] += filterStrengthTargetY * weight * (ELocal[k][b] * (double)yLocal);
           }
           else
           {
-            alfCovariance[classIdx].y[b][k] += ELocal[k][b] * (double)yLocal;
+            alfCovariance[classIdx].y[b][k] += filterStrengthTargetY * ELocal[k][b] * (double)yLocal;
           }
         }
       }
@@ -2563,8 +2577,8 @@ std::vector<int> EncAdaptiveLoopFilter::getAvaiApsIdsLuma(CodingStructure& cs, i
       curApsId = (curApsId + 1) % ALF_CTB_MAX_NUM_APS;
     }
   }
-  cs.slice->setTileGroupNumAps((int)result.size());
-  cs.slice->setAlfAPSs(result);
+  cs.slice->setNumAlfApsIdsLuma((int)result.size());
+  cs.slice->setAlfApsIdsLuma(result);
   newApsId = m_apsIdStart - 1;
   if (newApsId < 0)
   {
@@ -2649,7 +2663,7 @@ void  EncAdaptiveLoopFilter::alfEncoderCtb(CodingStructure& cs, AlfParam& alfPar
       {
         continue;
       }
-      cs.slice->setTileGroupNumAps(numTemporalAps + useNewFilter);
+      cs.slice->setNumAlfApsIdsLuma(numTemporalAps + useNewFilter);
       int numFilterSet = NUM_FIXED_FILTER_SETS + numTemporalAps + useNewFilter;
       if (numTemporalAps == apsIds.size() && numTemporalAps > 0 && useNewFilter && newApsId == apsIds.back()) //last temporalAPS is occupied by new filter set and this temporal APS becomes unavailable
       {
@@ -2734,16 +2748,12 @@ void  EncAdaptiveLoopFilter::alfEncoderCtb(CodingStructure& cs, AlfParam& alfPar
           double         costOn = MAX_DOUBLE;
           ctxTempStart = AlfCtx(m_CABACEstimator->getCtx());
           int iBestFilterSetIdx = 0;
-#if JVET_T0064
           int firstFilterSetIdx = 0;
           if (!m_encCfg->getALFAllowPredefinedFilters())
           {
             firstFilterSetIdx = NUM_FIXED_FILTER_SETS;
           }
           for (int filterSetIdx = firstFilterSetIdx; filterSetIdx < numFilterSet; filterSetIdx++)
-#else
-          for (int filterSetIdx = 0; filterSetIdx < numFilterSet; filterSetIdx++)
-#endif
           {
             //rate
             m_CABACEstimator->getCtx() = AlfCtx(ctxTempStart);
@@ -2849,22 +2859,22 @@ void  EncAdaptiveLoopFilter::alfEncoderCtb(CodingStructure& cs, AlfParam& alfPar
     }// for (int numTemporalAps = 0; numTemporalAps < apsIds.size(); numTemporalAps++)
   }//for (int useNewFilter = 0; useNewFilter <= 1; useNewFilter++)
 
-  cs.slice->setTileGroupCcAlfCbApsId(newApsId);
-  cs.slice->setTileGroupCcAlfCrApsId(newApsId);
+  cs.slice->setCcAlfCbApsId(newApsId);
+  cs.slice->setCcAlfCrApsId(newApsId);
 
   if (costOff <= costMin)
   {
-    cs.slice->resetTileGroupAlfEnabledFlag();
-    cs.slice->setTileGroupNumAps(0);
+    cs.slice->resetAlfEnabledFlag();
+    cs.slice->setNumAlfApsIdsLuma(0);
     setCtuEnableFlag(m_ctuEnableFlag, CHANNEL_TYPE_LUMA, 0);
     setCtuEnableFlag(m_ctuEnableFlag, CHANNEL_TYPE_CHROMA, 0);
     return;
   }
   else
   {
-    cs.slice->setTileGroupAlfEnabledFlag(COMPONENT_Y, true);
-    cs.slice->setTileGroupNumAps((int)bestApsIds.size());
-    cs.slice->setAlfAPSs(bestApsIds);
+    cs.slice->setAlfEnabledFlag(COMPONENT_Y, true);
+    cs.slice->setNumAlfApsIdsLuma((int)bestApsIds.size());
+    cs.slice->setAlfApsIdsLuma(bestApsIds);
     copyCtuEnableFlag(m_ctuEnableFlag, m_ctuEnableFlagTmp, CHANNEL_TYPE_LUMA);
     for (int ctuIdx = 0; ctuIdx < m_numCTUsInPic; ctuIdx++)
     {
@@ -2886,8 +2896,8 @@ void  EncAdaptiveLoopFilter::alfEncoderCtb(CodingStructure& cs, AlfParam& alfPar
       m_apsIdStart = newApsId;
     }
 
-    std::vector<int> apsIds = cs.slice->getTileGroupApsIdLuma();
-    for (int i = 0; i < (int)cs.slice->getTileGroupNumAps(); i++)
+    std::vector<int> apsIds = cs.slice->getAlfApsIdsLuma();
+    for (int i = 0; i < (int)cs.slice->getNumAlfApsIdsLuma(); i++)
     {
       apss[apsIds[i]] = m_apsMap->getPS((apsIds[i] << NUM_APS_TYPE_LEN) + ALF_APS);
     }
@@ -3048,9 +3058,9 @@ void  EncAdaptiveLoopFilter::alfEncoderCtb(CodingStructure& cs, AlfParam& alfPar
       if (curCost < costMin)
       {
         costMin = curCost;
-        cs.slice->setTileGroupApsIdChroma(curApsId);
-        cs.slice->setTileGroupAlfEnabledFlag(COMPONENT_Cb, m_alfParamTemp.enabledFlag[COMPONENT_Cb]);
-        cs.slice->setTileGroupAlfEnabledFlag(COMPONENT_Cr, m_alfParamTemp.enabledFlag[COMPONENT_Cr]);
+        cs.slice->setAlfApsIdChroma(curApsId);
+        cs.slice->setAlfEnabledFlag(COMPONENT_Cb, m_alfParamTemp.enabledFlag[COMPONENT_Cb]);
+        cs.slice->setAlfEnabledFlag(COMPONENT_Cr, m_alfParamTemp.enabledFlag[COMPONENT_Cr]);
         copyCtuEnableFlag(m_ctuEnableFlagTmp, m_ctuEnableFlag, CHANNEL_TYPE_CHROMA);
         copyCtuAlternativeChroma(m_ctuAlternativeTmp, m_ctuAlternative);
       }
@@ -3058,20 +3068,20 @@ void  EncAdaptiveLoopFilter::alfEncoderCtb(CodingStructure& cs, AlfParam& alfPar
 
     if (newApsIdChroma >= 0)
     {
-      cs.slice->setTileGroupCcAlfCbApsId(newApsIdChroma);
-      cs.slice->setTileGroupCcAlfCrApsId(newApsIdChroma);
+      cs.slice->setCcAlfCbApsId(newApsIdChroma);
+      cs.slice->setCcAlfCrApsId(newApsIdChroma);
     }
     if (costOff < costMin)
     {
-      cs.slice->setTileGroupAlfEnabledFlag(COMPONENT_Cb, false);
-      cs.slice->setTileGroupAlfEnabledFlag(COMPONENT_Cr, false);
+      cs.slice->setAlfEnabledFlag(COMPONENT_Cb, false);
+      cs.slice->setAlfEnabledFlag(COMPONENT_Cr, false);
       setCtuEnableFlag(m_ctuEnableFlag, CHANNEL_TYPE_CHROMA, 0);
     }
     else
     {
       copyCtuEnableFlag(m_ctuEnableFlag, m_ctuEnableFlagTmp, CHANNEL_TYPE_CHROMA);
       copyCtuAlternativeChroma(m_ctuAlternative, m_ctuAlternativeTmp);
-      if (cs.slice->getTileGroupApsIdChroma() == newApsIdChroma)   // new filter
+      if (cs.slice->getAlfApsIdChroma() == newApsIdChroma)   // new filter
       {
         APS *newAPS = m_apsMap->getPS((newApsIdChroma << NUM_APS_TYPE_LEN) + ALF_APS);
         if (newAPS == NULL)
@@ -3101,19 +3111,19 @@ void  EncAdaptiveLoopFilter::alfEncoderCtb(CodingStructure& cs, AlfParam& alfPar
         m_apsMap->setChangedFlag((newApsIdChroma << NUM_APS_TYPE_LEN) + ALF_APS);
         m_apsIdStart = newApsIdChroma;
       }
-      apss[cs.slice->getTileGroupApsIdChroma()] =
-        m_apsMap->getPS((cs.slice->getTileGroupApsIdChroma() << NUM_APS_TYPE_LEN) + ALF_APS);
+      apss[cs.slice->getAlfApsIdChroma()] =
+        m_apsMap->getPS((cs.slice->getAlfApsIdChroma() << NUM_APS_TYPE_LEN) + ALF_APS);
     }
   }
 }
 
 void EncAdaptiveLoopFilter::alfReconstructor(CodingStructure& cs, const PelUnitBuf& recExtBuf)
 {
-  if (!cs.slice->getTileGroupAlfEnabledFlag(COMPONENT_Y))
+  if (!cs.slice->getAlfEnabledFlag(COMPONENT_Y))
   {
     return;
   }
-  reconstructCoeffAPSs(cs, true, cs.slice->getTileGroupAlfEnabledFlag(COMPONENT_Cb) || cs.slice->getTileGroupAlfEnabledFlag(COMPONENT_Cr), false);
+  reconstructCoeffAPSs(cs, true, cs.slice->getAlfEnabledFlag(COMPONENT_Cb) || cs.slice->getAlfEnabledFlag(COMPONENT_Cr), false);
   short* alfCtuFilterIndex = cs.slice->getPic()->getAlfCtbFilterIndex();
   PelUnitBuf& recBuf = cs.getRecoBufRef();
   const PreCalcValues& pcv = *cs.pcv;
@@ -3359,12 +3369,10 @@ void EncAdaptiveLoopFilter::deriveCcAlfFilterCoeff( ComponentID compID, const Pe
 
   // Refine quanitzation
   int modified       = 1;
-#if JVET_T0064
   if (m_encCfg->getCCALFStrength() != 1.0)
   {
     modified = 0;
   }
-#endif
   double errRef      = m_alfCovarianceFrameCcAlf[compID - 1][0][filterIdx].calcErrorForCcAlfCoeffs(filterCoeffInt, size, (m_scaleBits+1));
   while (modified)
   {
@@ -3535,7 +3543,7 @@ void EncAdaptiveLoopFilter::determineControlIdcValues(CodingStructure &cs, const
   {
     std::copy_n(curFilterEnabled, MAX_NUM_CC_ALF_FILTERS, filterEnabled);
 
-    std::sort(filterIdxCount, filterIdxCount + MAX_NUM_CC_ALF_FILTERS, compareCounts);
+    std::stable_sort(filterIdxCount, filterIdxCount + MAX_NUM_CC_ALF_FILTERS, compareCounts);
 
     int filterIdc = 1;
     ccAlfFilterCount = 0;
@@ -3636,7 +3644,7 @@ void EncAdaptiveLoopFilter::getFrameStatsCcalf(ComponentID compIdx, int filterId
 
 void EncAdaptiveLoopFilter::deriveCcAlfFilter( CodingStructure& cs, ComponentID compID, const PelUnitBuf& orgYuv, const PelUnitBuf& tempDecYuvBuf, const PelUnitBuf& dstYuv )
 {
-  if (!cs.slice->getTileGroupAlfEnabledFlag(COMPONENT_Y))
+  if (!cs.slice->getAlfEnabledFlag(COMPONENT_Y))
   {
     m_ccAlfFilterParam.ccAlfFilterEnabled[compID - 1] = false;
     return;
@@ -3927,11 +3935,11 @@ void EncAdaptiveLoopFilter::deriveCcAlfFilter( CodingStructure& cs, ComponentID
       m_reuseApsId[compID - 1] = ccalfReuseApsId;
       if (compID == COMPONENT_Cb)
       {
-        cs.slice->setTileGroupCcAlfCbApsId(ccalfReuseApsId);
+        cs.slice->setCcAlfCbApsId(ccalfReuseApsId);
       }
       else
       {
-        cs.slice->setTileGroupCcAlfCrApsId(ccalfReuseApsId);
+        cs.slice->setCcAlfCrApsId(ccalfReuseApsId);
       }
     }
   }
@@ -4076,7 +4084,18 @@ void EncAdaptiveLoopFilter::getBlkStatsCcAlf(AlfCovariance &alfCovariance, const
   }
 
   Pel ELocal[MAX_NUM_CC_ALF_CHROMA_COEFF][1];
-
+  double filterStrengthTarget = m_encCfg->getCCALFStrengthTarget();
+  double filterStrengthTargetE = 1.0;
+  double filterStrengthTargetY = 1.0;
+  if (filterStrengthTarget != 0.0)
+  {
+    filterStrengthTargetY = 1 / filterStrengthTarget;
+    filterStrengthTargetE = filterStrengthTargetY * filterStrengthTargetY;
+  }
+  else
+  {
+    filterStrengthTargetY = 0.0;
+  }
   for (int i = 0; i < compArea.height; i++)
   {
     int vbDistance = ((i << getComponentScaleY(compID, m_chromaFormat)) % vbCTUHeight) - vbPos;
@@ -4105,11 +4124,11 @@ void EncAdaptiveLoopFilter::getBlkStatsCcAlf(AlfCovariance &alfCovariance, const
             {
               if (m_alfWSSD)
               {
-                alfCovariance.E[b0][b1][k][l] += weight * (ELocal[k][b0] * (double)ELocal[l][b1]);
+                alfCovariance.E[b0][b1][k][l] += filterStrengthTargetE * weight * (ELocal[k][b0] * (double)ELocal[l][b1]);
               }
               else
               {
-                alfCovariance.E[b0][b1][k][l] += ELocal[k][b0] * (double)ELocal[l][b1];
+                alfCovariance.E[b0][b1][k][l] += filterStrengthTargetE * ELocal[k][b0] * (double)ELocal[l][b1];
               }
             }
           }
@@ -4118,11 +4137,11 @@ void EncAdaptiveLoopFilter::getBlkStatsCcAlf(AlfCovariance &alfCovariance, const
         {
           if (m_alfWSSD)
           {
-            alfCovariance.y[b][k] += weight * (ELocal[k][b] * (double)yLocal);
+            alfCovariance.y[b][k] += filterStrengthTargetY * weight * (ELocal[k][b] * (double)yLocal);
           }
           else
           {
-            alfCovariance.y[b][k] += ELocal[k][b] * (double)yLocal;
+            alfCovariance.y[b][k] += filterStrengthTargetY * ELocal[k][b] * (double)yLocal;
           }
         }
       }
diff --git a/source/Lib/EncoderLib/EncAdaptiveLoopFilter.h b/source/Lib/EncoderLib/EncAdaptiveLoopFilter.h
index 12dbc00c2..6e3f25d9f 100644
--- a/source/Lib/EncoderLib/EncAdaptiveLoopFilter.h
+++ b/source/Lib/EncoderLib/EncAdaptiveLoopFilter.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/EncoderLib/EncCfg.h b/source/Lib/EncoderLib/EncCfg.h
index fa16f2895..2fdec7f1d 100644
--- a/source/Lib/EncoderLib/EncCfg.h
+++ b/source/Lib/EncoderLib/EncCfg.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -161,9 +161,10 @@ protected:
   int       m_iFrameRate;
   int       m_FrameSkip;
   uint32_t      m_temporalSubsampleRatio;
-  int       m_iSourceWidth;
-  int       m_iSourceHeight;
+  int       m_sourceWidth;
+  int       m_sourceHeight;
   Window    m_conformanceWindow;
+  int       m_sourcePadding[2];
   int       m_framesToBeEncoded;
   double    m_adLambdaModifier[ MAX_TLAYER ];
   std::vector<double> m_adIntraLambdaModifier;
@@ -174,6 +175,7 @@ protected:
   bool      m_printFrameMSE;
   bool      m_printSequenceMSE;
   bool      m_printMSSSIM;
+  bool      m_printWPSNR;
   bool      m_cabacZeroWordPaddingEnabled;
 
   bool      m_gciPresentFlag;
@@ -233,6 +235,9 @@ protected:
   bool      m_noCraConstraintFlag;
   bool      m_noGdrConstraintFlag;
   bool      m_noApsConstraintFlag;
+#if JVET_W2005_RANGE_EXTENSION_PROFILES
+  bool      m_generalLowerBitRateConstraintFlag;
+#endif
 
   /* profile & level */
   Profile::Name m_profile;
@@ -269,6 +274,7 @@ protected:
   int       m_maxDecPicBuffering[MAX_TLAYER];
   int       m_maxNumReorderPics[MAX_TLAYER];
   int       m_drapPeriod;
+  int       m_edrapPeriod;
 
   int       m_iQP;                              //  if (AdaptiveQP == OFF)
   ChromaQpMappingTableParams m_chromaQpMappingTableParams;
@@ -276,7 +282,6 @@ protected:
   int       m_intraQPOffset;                    ///< QP offset for intra slice (integer)
   int       m_lambdaFromQPEnable;               ///< enable lambda derivation from QP
 #endif
-  int       m_aiPad[2];
 
   bool      m_AccessUnitDelimiter;               ///< add Access Unit Delimiter NAL units
   bool      m_enablePictureHeaderInSliceHeader;  ///< Enable Picture Header in Slice Header
@@ -299,6 +304,13 @@ protected:
   bool                  m_subPicIdMappingInSpsFlag;
   unsigned              m_subPicIdLen;
   std::vector<uint16_t> m_subPicId;
+#if GDR_ENABLED
+  bool      m_gdrEnabled;  
+  unsigned  m_gdrPocStart;
+  unsigned  m_gdrPeriod;
+  int       m_gdrInterval;  
+  bool      m_gdrNoHash;  
+#endif
   bool      m_useSplitConsOverride;
   unsigned  m_uiMinQT[3]; //0: I slice; 1: P/B slice, 2: I slice chroma
   unsigned  m_uiMaxBT[3]; //0: I slice; 1: P/B slice, 2: I slice chroma
@@ -394,20 +406,23 @@ protected:
   uint32_t  m_log2MaxTbSize;
 
   //====== Loop/Deblock Filter ========
-  bool      m_bLoopFilterDisable;
-  bool      m_loopFilterOffsetInPPS;
-  int       m_loopFilterBetaOffsetDiv2;
-  int       m_loopFilterTcOffsetDiv2;
-  int       m_loopFilterCbBetaOffsetDiv2;
-  int       m_loopFilterCbTcOffsetDiv2;
-  int       m_loopFilterCrBetaOffsetDiv2;
-  int       m_loopFilterCrTcOffsetDiv2;
+  bool      m_deblockingFilterDisable;
+  bool      m_deblockingFilterOffsetInPPS;
+  int       m_deblockingFilterBetaOffsetDiv2;
+  int       m_deblockingFilterTcOffsetDiv2;
+  int       m_deblockingFilterCbBetaOffsetDiv2;
+  int       m_deblockingFilterCbTcOffsetDiv2;
+  int       m_deblockingFilterCrBetaOffsetDiv2;
+  int       m_deblockingFilterCrTcOffsetDiv2;
 #if W0038_DB_OPT
   int       m_deblockingFilterMetric;
 #else
   bool      m_DeblockingFilterMetric;
 #endif
   bool      m_bUseSAO;
+#if JVET_W0129_ENABLE_ALF_TRUEORG
+  bool      m_saoTrueOrg;
+#endif
   bool      m_bTestSAODisableAtPictureLevel;
   double    m_saoEncodingRate;       // When non-0 SAO early picture termination is enabled for luma and chroma
   double    m_saoEncodingRateChroma; // The SAO early picture termination rate to use for chroma (when m_SaoEncodingRate is >0). If <=0, use results for luma.
@@ -428,7 +443,9 @@ protected:
   //====== Quality control ========
   int       m_iMaxDeltaQP;                      //  Max. absolute delta QP (1:default)
   int       m_cuQpDeltaSubdiv;                  //  Max. subdivision level for a CuDQP (0:default)
-  int       m_cuChromaQpOffsetSubdiv;           ///< If negative, then do not apply chroma qp offsets.
+  unsigned  m_cuChromaQpOffsetSubdiv;           ///< Max. subdivision level for a chroma QP adjustment (0:default)
+  bool      m_cuChromaQpOffsetEnabled;          ///< Local chroma QP offset enable flag
+  std::vector<ChromaQpAdj> m_cuChromaQpOffsetList; ///< Local chroma QP offsets list (to be signalled in PPS)
 
   int       m_chromaCbQpOffset;                 //  Chroma Cb QP Offset (0:default)
   int       m_chromaCrQpOffset;                 //  Chroma Cr Qp Offset (0:default)
@@ -447,6 +464,10 @@ protected:
   ChromaFormat m_chromaFormatIDC;
 
   bool      m_extendedPrecisionProcessingFlag;
+  bool      m_tsrcRicePresentFlag;
+#if JVET_W0046_RLSCP
+  bool      m_reverseLastSigCoeffEnabledFlag;
+#endif
   bool      m_highPrecisionOffsetsEnabledFlag;
   bool      m_bUseAdaptiveQP;
   int       m_iQPAdaptationRange;
@@ -478,10 +499,29 @@ protected:
   uint32_t      m_log2MaxTransformSkipBlockSize;
   bool      m_transformSkipRotationEnabledFlag;
   bool      m_transformSkipContextEnabledFlag;
+  bool      m_rrcRiceExtensionEnableFlag;
   bool      m_persistentRiceAdaptationEnabledFlag;
   bool      m_cabacBypassAlignmentEnabledFlag;
 #if SHARP_LUMA_DELTA_QP
   LumaLevelToDeltaQPMapping m_lumaLevelToDeltaQPMapping; ///< mapping from luma level to delta QP.
+#endif
+  bool      m_smoothQPReductionEnable;
+#if JVET_W0043
+  int       m_smoothQPReductionPeriodicity;
+  double    m_smoothQPReductionThresholdIntra;
+  double    m_smoothQPReductionModelScaleIntra;
+  double    m_smoothQPReductionModelOffsetIntra;
+  int       m_smoothQPReductionLimitIntra;
+  double    m_smoothQPReductionThresholdInter;
+  double    m_smoothQPReductionModelScaleInter;
+  double    m_smoothQPReductionModelOffsetInter;
+  int       m_smoothQPReductionLimitInter;
+#else
+  double    m_smoothQPReductionThreshold;
+  double    m_smoothQPReductionModelScale;
+  double    m_smoothQPReductionModelOffset;
+  int       m_smoothQPReductionPeriodicity;
+  int       m_smoothQPReductionLimit;
 #endif
   int*      m_aidQP;
   uint32_t      m_uiDeltaQpRD;
@@ -518,11 +558,16 @@ protected:
   bool      m_pictureTimingSEIEnabled;
   bool      m_frameFieldInfoSEIEnabled;
   bool      m_dependentRAPIndicationSEIEnabled;
+  bool      m_edrapIndicationSEIEnabled;
   bool      m_framePackingSEIEnabled;
   int       m_framePackingSEIType;
   int       m_framePackingSEIId;
   int       m_framePackingSEIQuincunx;
   int       m_framePackingSEIInterpretation;
+  bool      m_doSEIEnabled;
+  bool      m_doSEICancelFlag;
+  bool      m_doSEIPersistenceFlag;
+  int       m_doSEITransformType;
   bool      m_parameterSetsInclusionIndicationSEIEnabled;
   bool      m_selfContainedClvsFlag;
   bool      m_bpDeltasGOPStructure;
@@ -624,6 +669,19 @@ protected:
   uint32_t  m_aveSEIAmbientIlluminance;
   uint16_t  m_aveSEIAmbientLightX;
   uint16_t  m_aveSEIAmbientLightY;
+  // colour tranform information sei
+  bool      m_ctiSEIEnabled;
+  uint32_t  m_ctiSEIId;
+  bool      m_ctiSEISignalInfoFlag;
+  bool      m_ctiSEIFullRangeFlag;
+  uint32_t  m_ctiSEIPrimaries;
+  uint32_t  m_ctiSEITransferFunction;
+  uint32_t  m_ctiSEIMatrixCoefs;
+  bool      m_ctiSEICrossComponentFlag;
+  bool      m_ctiSEICrossComponentInferred;
+  uint32_t  m_ctiSEINumberChromaLut;
+  int       m_ctiSEIChromaOffset;
+  LutModel  m_ctiSEILut[MAX_NUM_COMPONENT];
 // ccv sei
   bool      m_ccvSEIEnabled;
   bool      m_ccvSEICancelFlag;
@@ -637,6 +695,77 @@ protected:
   double    m_ccvSEIMinLuminanceValue;
   double    m_ccvSEIMaxLuminanceValue;
   double    m_ccvSEIAvgLuminanceValue;
+  // sdi sei
+  bool              m_sdiSEIEnabled;
+  int               m_sdiSEIMaxLayersMinus1;
+  bool              m_sdiSEIMultiviewInfoFlag;
+  bool              m_sdiSEIAuxiliaryInfoFlag;
+  int               m_sdiSEIViewIdLenMinus1;
+  std::vector<uint32_t>  m_sdiSEILayerId;
+  std::vector<uint32_t>  m_sdiSEIViewIdVal;
+  std::vector<uint32_t>  m_sdiSEIAuxId;
+  std::vector<uint32_t>  m_sdiSEINumAssociatedPrimaryLayersMinus1;
+  // mai sei
+  bool              m_maiSEIEnabled;
+  bool              m_maiSEIIntrinsicParamFlag;
+  bool              m_maiSEIExtrinsicParamFlag;
+  int               m_maiSEINumViewsMinus1;
+  bool              m_maiSEIIntrinsicParamsEqualFlag;
+  int               m_maiSEIPrecFocalLength;
+  int               m_maiSEIPrecPrincipalPoint;
+  int               m_maiSEIPrecSkewFactor;
+  std::vector<bool> m_maiSEISignFocalLengthX;
+  std::vector<uint32_t>  m_maiSEIExponentFocalLengthX;
+  std::vector<uint32_t>  m_maiSEIMantissaFocalLengthX;
+  std::vector<bool> m_maiSEISignFocalLengthY;
+  std::vector<uint32_t>  m_maiSEIExponentFocalLengthY;
+  std::vector<uint32_t>  m_maiSEIMantissaFocalLengthY;
+  std::vector<bool> m_maiSEISignPrincipalPointX;
+  std::vector<uint32_t>  m_maiSEIExponentPrincipalPointX;
+  std::vector<uint32_t>  m_maiSEIMantissaPrincipalPointX;
+  std::vector<bool> m_maiSEISignPrincipalPointY;
+  std::vector<uint32_t>  m_maiSEIExponentPrincipalPointY;
+  std::vector<uint32_t>  m_maiSEIMantissaPrincipalPointY;
+  std::vector<bool> m_maiSEISignSkewFactor;
+  std::vector<uint32_t>  m_maiSEIExponentSkewFactor;
+  std::vector<uint32_t>  m_maiSEIMantissaSkewFactor;
+  int               m_maiSEIPrecRotationParam;
+  int               m_maiSEIPrecTranslationParam;
+#if JVET_W0078_MVP_SEI 
+  // mvp sei
+  bool              m_mvpSEIEnabled;
+  int               m_mvpSEINumViewsMinus1;
+  std::vector<uint32_t>  m_mvpSEIViewPosition;
+#endif
+  // aci sei
+  bool      m_aciSEIEnabled;
+  bool      m_aciSEICancelFlag;
+  int       m_aciSEIUseIdc;
+  int       m_aciSEIBitDepthMinus8;
+  int       m_aciSEITransparentValue;
+  int       m_aciSEIOpaqueValue;
+  bool      m_aciSEIIncrFlag;
+  bool      m_aciSEIClipFlag;
+  bool      m_aciSEIClipTypeFlag;
+  // dri sei
+  bool      m_driSEIEnabled;
+  bool      m_driSEIZNearFlag;
+  bool      m_driSEIZFarFlag;
+  bool      m_driSEIDMinFlag;
+  bool      m_driSEIDMaxFlag;
+  double    m_driSEIZNear;
+  double    m_driSEIZFar;
+  double    m_driSEIDMin;
+  double    m_driSEIDMax;
+  int       m_driSEIDepthRepresentationType;
+  int       m_driSEIDisparityRefViewId;
+  int       m_driSEINonlinearNumMinus1;
+  std::vector<uint32_t> m_driSEINonlinearModel;
+  std::string           m_arSEIFileRoot;  // Annotated region SEI - initialized from external file
+#if JVET_W0133_CONSTRAINED_RASL_ENCODING
+  bool      m_constrainedRaslEncoding;
+#endif
+
   //====== Weighted Prediction ========
   bool      m_useWeightedPred;       //< Use of Weighting Prediction (P_SLICE)
   bool      m_useWeightedBiPred;    //< Use of Bi-directional Weighting Prediction (B_SLICE)
@@ -683,10 +812,8 @@ protected:
   CostMode  m_costMode;                                       ///< The cost function to use, primarily when considering lossless coding.
   bool      m_TSRCdisableLL;                                  ///< Disable TSRC for lossless
 
-#if JVET_S0163_ON_TARGETOLS_SUBLAYERS
   OPI       m_opi;
   bool      m_OPIEnabled;                                     ///< enable Operating Point Information (OPI)
-#endif
 
   DCI       m_dci;
   bool      m_DCIEnabled;                                     ///< enable Decoding Capability Information (DCI)
@@ -713,8 +840,9 @@ protected:
   bool      m_overscanAppropriateFlag;                        ///< Indicates whether conformant decoded pictures are suitable for display using overscan
   bool      m_videoFullRangeFlag;                             ///< Indicates the black level and range of luma and chroma signals
 
-  bool      m_bEfficientFieldIRAPEnabled;                     ///< enable to code fields in a specific, potentially more efficient, order.
-  bool      m_bHarmonizeGopFirstFieldCoupleEnabled;
+  bool m_fieldSeqFlag;
+  bool m_efficientFieldIRAPEnabled;   /// enable to code fields in a specific, potentially more efficient, order.
+  bool m_harmonizeGopFirstFieldCoupleEnabled;
 
   std::string m_summaryOutFilename;                           ///< filename to use for producing summary output file.
   std::string m_summaryPicFilenameBase;                       ///< Base filename to use for producing summary picture output files. The actual filenames used will have I.txt, P.txt and B.txt appended.
@@ -732,17 +860,19 @@ protected:
 
   CfgVPSParameters m_cfgVPSParameters;
 
-#if ENABLE_SPLIT_PARALLELISM
-  int         m_numSplitThreads;
-  bool        m_forceSingleSplitThread;
-#endif
-
   bool        m_alf;                                          ///< Adaptive Loop Filter
-#if JVET_T0064
-  double      m_alfStrength;
+#if JVET_W0129_ENABLE_ALF_TRUEORG
+  bool        m_alfTrueOrg;
+#else
+  bool        m_alfSaoTrueOrg;
+#endif
+  double      m_alfStrengthLuma;
   bool        m_alfAllowPredefinedFilters;
   double      m_ccalfStrength;
-#endif
+  double      m_alfStrengthChroma;
+  double      m_alfStrengthTargetLuma;
+  double      m_alfStrengthTargetChroma;
+  double      m_ccalfStrengthTarget;
   bool        m_ccalf;
   int         m_ccalfQpThreshold;
 #if JVET_O0756_CALCULATE_HDRMETRICS
@@ -767,6 +897,10 @@ protected:
   int         m_upscaledOutput;
   int         m_numRefLayers[MAX_VPS_LAYERS];
   bool        m_avoidIntraInDepLayer;
+#if JVET_W0133_CONSTRAINED_RASL_ENCODING
+  bool        m_craAPSreset;
+  bool        m_rprRASLtoolSwitch;
+#endif
 
 public:
   EncCfg()
@@ -775,7 +909,7 @@ public:
 
   virtual ~EncCfg()
   {}
-
+  std::map<uint32_t, SEIAnnotatedRegions::AnnotatedRegionObject> m_arObjects;
   void setProfile(Profile::Name profile) { m_profile = profile; }
   void setLevel(Level::Tier tier, Level::Name level) { m_levelTier = tier; m_level = level; }
   bool      getFrameOnlyConstraintFlag() const { return m_frameOnlyConstraintFlag; }
@@ -900,13 +1034,16 @@ public:
   void      setNoGdrConstraintFlag(bool val) { m_noGdrConstraintFlag = val; }
   bool      getNoApsConstraintFlag() const { return m_noApsConstraintFlag; }
   void      setNoApsConstraintFlag(bool val) { m_noApsConstraintFlag = val; }
-
+#if JVET_W2005_RANGE_EXTENSION_PROFILES
+  bool      getGeneralLowerBitRateConstraintFlag() const { return m_generalLowerBitRateConstraintFlag; }
+  void      setGeneralLowerBitRateConstraintFlag(bool val) { m_generalLowerBitRateConstraintFlag = val; }
+#endif
 
   void      setFrameRate                    ( int   i )      { m_iFrameRate = i; }
   void      setFrameSkip                    ( uint32_t  i )      { m_FrameSkip = i; }
   void      setTemporalSubsampleRatio       ( uint32_t  i )      { m_temporalSubsampleRatio = i; }
-  void      setSourceWidth                  ( int   i )      { m_iSourceWidth = i; }
-  void      setSourceHeight                 ( int   i )      { m_iSourceHeight = i; }
+  void      setSourceWidth                  ( int   i )      { m_sourceWidth = i; }
+  void      setSourceHeight                 ( int   i )      { m_sourceHeight = i; }
 
   Window   &getConformanceWindow()                           { return m_conformanceWindow; }
   void      setConformanceWindow (int confLeft, int confRight, int confTop, int confBottom ) { m_conformanceWindow.setWindow (confLeft, confRight, confTop, confBottom); }
@@ -928,6 +1065,9 @@ public:
   bool      getPrintMSSSIM                  ()         const { return m_printMSSSIM;               }
   void      setPrintMSSSIM                  (bool value)     { m_printMSSSIM = value;              }
 
+  bool      getPrintWPSNR                   ()         const { return m_printWPSNR;               }
+  void      setPrintWPSNR                   (bool value)     { m_printWPSNR = value;              }
+
   bool      getCabacZeroWordPaddingEnabled()           const { return m_cabacZeroWordPaddingEnabled;  }
   void      setCabacZeroWordPaddingEnabled(bool value)       { m_cabacZeroWordPaddingEnabled = value; }
 
@@ -964,6 +1104,7 @@ public:
   void      setMaxDecPicBuffering           ( uint32_t u, uint32_t tlayer ) { m_maxDecPicBuffering[tlayer] = u;    }
   void      setMaxNumReorderPics            ( int  i, uint32_t tlayer ) { m_maxNumReorderPics[tlayer] = i;    }
   void      setDrapPeriod                   (int drapPeriod) { m_drapPeriod = drapPeriod; }
+  void      setEdrapPeriod                  (int edrapPeriod) { m_edrapPeriod = edrapPeriod; }
 
   void      setBaseQP                       ( int   i )      { m_iQP = i; }
 #if X0038_LAMBDA_FROM_QP_CAPABILITY
@@ -972,7 +1113,7 @@ public:
 #endif
   void      setChromaQpMappingTableParams   (const ChromaQpMappingTableParams &params) { m_chromaQpMappingTableParams = params; }
 
-  void      setPad                          ( int*  iPad                   )      { for ( int i = 0; i < 2; i++ ) m_aiPad[i] = iPad[i]; }
+  void      setSourcePadding                ( int*  padding)                { for ( int i = 0; i < 2; i++ ) m_sourcePadding[i] = padding[i]; }
 
   int       getMaxRefPicNum                 ()                              { return m_iMaxRefPicNum;           }
   void      setMaxRefPicNum                 ( int iMaxRefPicNum )           { m_iMaxRefPicNum = iMaxRefPicNum;  }
@@ -984,6 +1125,19 @@ public:
   void      setMinQTSizes                   ( unsigned* minQT)   { m_uiMinQT[0] = minQT[0]; m_uiMinQT[1] = minQT[1]; m_uiMinQT[2] = minQT[2]; }
   void      setMaxBTSizes                   ( unsigned* maxBT)   { m_uiMaxBT[0] = maxBT[0]; m_uiMaxBT[1] = maxBT[1]; m_uiMaxBT[2] = maxBT[2]; }
   void      setMaxTTSizes                   ( unsigned* maxTT)   { m_uiMaxTT[0] = maxTT[0]; m_uiMaxTT[1] = maxTT[1]; m_uiMaxTT[2] = maxTT[2]; }
+#if GDR_ENABLED
+  void      setGdrEnabled(bool b)       { m_gdrEnabled  = b; }
+  void      setGdrPeriod(unsigned u)    { m_gdrPeriod   = u; }
+  void      setGdrPocStart(unsigned u)  { m_gdrPocStart = u; }
+  void      setGdrInterval(int i)       { m_gdrInterval = i; }  
+  void      setGdrNoHash(bool b)        { m_gdrNoHash   = b; }    
+
+  bool      getGdrEnabled()             { return m_gdrEnabled;  }
+  unsigned  getGdrPeriod()              { return m_gdrPeriod;   }
+  unsigned  getGdrPocStart()            { return m_gdrPocStart; }
+  int       getGdrInterval()            { return m_gdrInterval; }  
+  bool      getGdrNoHash()              { return m_gdrNoHash;   }  
+#endif
   void      setMaxMTTHierarchyDepth         ( unsigned uiMaxMTTHierarchyDepth, unsigned uiMaxMTTHierarchyDepthI, unsigned uiMaxMTTHierarchyDepthIChroma )
                                                              { m_uiMaxMTTHierarchyDepth = uiMaxMTTHierarchyDepth; m_uiMaxMTTHierarchyDepthI = uiMaxMTTHierarchyDepthI; m_uiMaxMTTHierarchyDepthIChroma = uiMaxMTTHierarchyDepthIChroma; }
   unsigned  getMaxMTTHierarchyDepth         ()         const { return m_uiMaxMTTHierarchyDepth; }
@@ -1209,14 +1363,14 @@ public:
   void      setLog2MaxTbSize                ( uint32_t  u )   { m_log2MaxTbSize = u; }
 
   //====== Loop/Deblock Filter ========
-  void      setLoopFilterDisable            ( bool  b )      { m_bLoopFilterDisable       = b; }
-  void      setLoopFilterOffsetInPPS        ( bool  b )      { m_loopFilterOffsetInPPS      = b; }
-  void      setLoopFilterBetaOffset         ( int   i )      { m_loopFilterBetaOffsetDiv2  = i; }
-  void      setLoopFilterTcOffset           ( int   i )      { m_loopFilterTcOffsetDiv2    = i; }
-  void      setLoopFilterCbBetaOffset       ( int   i )      { m_loopFilterCbBetaOffsetDiv2  = i; }
-  void      setLoopFilterCbTcOffset         ( int   i )      { m_loopFilterCbTcOffsetDiv2    = i; }
-  void      setLoopFilterCrBetaOffset       ( int   i )      { m_loopFilterCrBetaOffsetDiv2  = i; }
-  void      setLoopFilterCrTcOffset         ( int   i )      { m_loopFilterCrTcOffsetDiv2    = i; }
+  void      setDeblockingFilterDisable      ( bool  b )      { m_deblockingFilterDisable           = b; }
+  void      setDeblockingFilterOffsetInPPS  ( bool  b )      { m_deblockingFilterOffsetInPPS       = b; }
+  void      setDeblockingFilterBetaOffset   ( int   i )      { m_deblockingFilterBetaOffsetDiv2    = i; }
+  void      setDeblockingFilterTcOffset     ( int   i )      { m_deblockingFilterTcOffsetDiv2      = i; }
+  void      setDeblockingFilterCbBetaOffset ( int   i )      { m_deblockingFilterCbBetaOffsetDiv2  = i; }
+  void      setDeblockingFilterCbTcOffset   ( int   i )      { m_deblockingFilterCbTcOffsetDiv2    = i; }
+  void      setDeblockingFilterCrBetaOffset ( int   i )      { m_deblockingFilterCrBetaOffsetDiv2  = i; }
+  void      setDeblockingFilterCrTcOffset   ( int   i )      { m_deblockingFilterCrTcOffsetDiv2    = i; }
 #if W0038_DB_OPT
   void      setDeblockingFilterMetric       ( int   i )      { m_deblockingFilterMetric = i; }
 #else
@@ -1235,8 +1389,11 @@ public:
   //====== Quality control ========
   void      setMaxDeltaQP                   ( int   i )      { m_iMaxDeltaQP = i; }
   void      setCuQpDeltaSubdiv              ( int   i )      { m_cuQpDeltaSubdiv = i; }
-  int       getCuChromaQpOffsetSubdiv       ()         const { return m_cuChromaQpOffsetSubdiv;  }
-  void      setCuChromaQpOffsetSubdiv       (int value)      { m_cuChromaQpOffsetSubdiv = value; }
+  unsigned  getCuChromaQpOffsetSubdiv       ()         const { return m_cuChromaQpOffsetSubdiv;  }
+  void      setCuChromaQpOffsetSubdiv       ( unsigned value ) { m_cuChromaQpOffsetSubdiv = value; }
+  bool      getCuChromaQpOffsetEnabled      ()         const { return m_cuChromaQpOffsetEnabled;  }
+  void      setCuChromaQpOffsetEnabled      ( bool value )   { m_cuChromaQpOffsetEnabled = value; }
+  void      setCuChromaQpOffsetList         (const std::vector<ChromaQpAdj> &list) { m_cuChromaQpOffsetList = list; }
 
   void      setChromaCbQpOffset             ( int   i )      { m_chromaCbQpOffset = i; }
   void      setChromaCrQpOffset             ( int   i )      { m_chromaCrQpOffset = i; }
@@ -1268,10 +1425,47 @@ public:
   void      setLumaLevelToDeltaQPControls( const LumaLevelToDeltaQPMapping &lumaLevelToDeltaQPMapping ) { m_lumaLevelToDeltaQPMapping=lumaLevelToDeltaQPMapping; }
   const LumaLevelToDeltaQPMapping& getLumaLevelToDeltaQPMapping() const { return m_lumaLevelToDeltaQPMapping; }
 #endif
-
+  bool      getSmoothQPReductionEnable()                  const { return m_smoothQPReductionEnable; }
+  void      setSmoothQPReductionEnable(bool value)        { m_smoothQPReductionEnable = value; }
+#if JVET_W0043
+  int       getSmoothQPReductionPeriodicity()                 const { return m_smoothQPReductionPeriodicity; }
+  void      setSmoothQPReductionPeriodicity(int value)        { m_smoothQPReductionPeriodicity = value; }
+  double    getSmoothQPReductionThresholdIntra()              const { return m_smoothQPReductionThresholdIntra; }
+  void      setSmoothQPReductionThresholdIntra(double value)  { m_smoothQPReductionThresholdIntra = value; }
+  double    getSmoothQPReductionModelScaleIntra()              const { return m_smoothQPReductionModelScaleIntra; }
+  void      setSmoothQPReductionModelScaleIntra(double value) { m_smoothQPReductionModelScaleIntra = value; }
+  double    getSmoothQPReductionModelOffsetIntra()             const { return m_smoothQPReductionModelOffsetIntra; }
+  void      setSmoothQPReductionModelOffsetIntra(double value) { m_smoothQPReductionModelOffsetIntra = value; }
+  int       getSmoothQPReductionLimitIntra()                   const { return m_smoothQPReductionLimitIntra; }
+  void      setSmoothQPReductionLimitIntra(int value)          { m_smoothQPReductionLimitIntra = value; }
+  double    getSmoothQPReductionThresholdInter()               const { return m_smoothQPReductionThresholdInter; }
+  void      setSmoothQPReductionThresholdInter(double value)   { m_smoothQPReductionThresholdInter = value; }
+  double    getSmoothQPReductionModelScaleInter()              const { return m_smoothQPReductionModelScaleInter; }
+  void      setSmoothQPReductionModelScaleInter(double value) { m_smoothQPReductionModelScaleInter = value; }
+  double    getSmoothQPReductionModelOffsetInter()             const { return m_smoothQPReductionModelOffsetInter; }
+  void      setSmoothQPReductionModelOffsetInter(double value) { m_smoothQPReductionModelOffsetInter = value; }
+  int       getSmoothQPReductionLimitInter()                   const { return m_smoothQPReductionLimitInter; }
+  void      setSmoothQPReductionLimitInter(int value)          { m_smoothQPReductionLimitInter = value; }
+#else
+  double    getSmoothQPReductionThreshold()               const { return m_smoothQPReductionThreshold; }
+  void      setSmoothQPReductionThreshold(double value)   { m_smoothQPReductionThreshold = value; }
+  double    getSmoothQPReductionModelScale()              const { return m_smoothQPReductionModelScale; }
+  void      setSmoothQPReductionModelScale(double value)  { m_smoothQPReductionModelScale = value; }
+  double    getSmoothQPReductionModelOffset()             const { return m_smoothQPReductionModelOffset; }
+  void      setSmoothQPReductionModelOffset(double value) { m_smoothQPReductionModelOffset = value; }
+  int       getSmoothQPReductionPeriodicity()             const { return m_smoothQPReductionPeriodicity; }
+  void      setSmoothQPReductionPeriodicity(int value)    { m_smoothQPReductionPeriodicity = value; }
+  int       getSmoothQPReductionLimit()                   const { return m_smoothQPReductionLimit; }
+  void      setSmoothQPReductionLimit(int value)          { m_smoothQPReductionLimit = value; }
+#endif
   bool      getExtendedPrecisionProcessingFlag         ()         const { return m_extendedPrecisionProcessingFlag;  }
   void      setExtendedPrecisionProcessingFlag         (bool value)     { m_extendedPrecisionProcessingFlag = value; }
-
+  bool      getTSRCRicePresentFlag         ()         const { return m_tsrcRicePresentFlag;  }
+  void      setTSRCRicePresentFlag         (bool value)     { m_tsrcRicePresentFlag = value; }
+#if JVET_W0046_RLSCP
+  bool      getReverseLastSigCoeffEnabledFlag         ()         const { return m_reverseLastSigCoeffEnabledFlag;  }
+  void      setReverseLastSigCoeffEnabledFlag         (bool value)     { m_reverseLastSigCoeffEnabledFlag = value; }
+#endif
   bool      getHighPrecisionOffsetsEnabledFlag() const { return m_highPrecisionOffsetsEnabledFlag; }
   void      setHighPrecisionOffsetsEnabledFlag(bool value) { m_highPrecisionOffsetsEnabledFlag = value; }
 
@@ -1286,8 +1480,8 @@ public:
   int       getFrameRate                    () const     { return  m_iFrameRate; }
   uint32_t      getFrameSkip                    () const     { return  m_FrameSkip; }
   uint32_t      getTemporalSubsampleRatio       () const     { return  m_temporalSubsampleRatio; }
-  int       getSourceWidth                  () const     { return  m_iSourceWidth; }
-  int       getSourceHeight                 () const     { return  m_iSourceHeight; }
+  int       getSourceWidth                  () const     { return  m_sourceWidth; }
+  int       getSourceHeight                 () const     { return  m_sourceHeight; }
   int       getFramesToBeEncoded            () const     { return  m_framesToBeEncoded; }
 
   //====== Lambda Modifiers ========
@@ -1306,6 +1500,7 @@ public:
   int       getMaxDecPicBuffering           (uint32_t tlayer) { return m_maxDecPicBuffering[tlayer]; }
   int       getMaxNumReorderPics            (uint32_t tlayer) { return m_maxNumReorderPics[tlayer]; }
   int       getDrapPeriod                   ()     { return m_drapPeriod; }
+  int       getEdrapPeriod                  ()     { return m_edrapPeriod; }
 #if X0038_LAMBDA_FROM_QP_CAPABILITY
   int       getIntraQPOffset                () const    { return  m_intraQPOffset; }
   int       getLambdaFromQPEnable           () const    { return  m_lambdaFromQPEnable; }
@@ -1315,7 +1510,7 @@ public:
 #else
   int       getBaseQP                       ()       { return  m_iQP; }
 #endif
-  int       getPad                          ( int i )      { CHECK(i >= 2, "Invalid index");                      return  m_aiPad[i]; }
+  int       getSourcePadding                ( int i ) { CHECK(i >= 2, "Invalid index"); return  m_sourcePadding[i]; }
 
   bool      getAccessUnitDelimiter() const  { return m_AccessUnitDelimiter; }
   void      setAccessUnitDelimiter(bool val){ m_AccessUnitDelimiter = val; }
@@ -1323,14 +1518,14 @@ public:
   void      setEnablePictureHeaderInSliceHeader(bool val) { m_enablePictureHeaderInSliceHeader = val; }
 
   //==== Loop/Deblock Filter ========
-  bool      getLoopFilterDisable            ()      { return  m_bLoopFilterDisable;       }
-  bool      getLoopFilterOffsetInPPS        ()      { return m_loopFilterOffsetInPPS; }
-  int       getLoopFilterBetaOffset         ()      { return m_loopFilterBetaOffsetDiv2; }
-  int       getLoopFilterTcOffset           ()      { return m_loopFilterTcOffsetDiv2; }
-  int       getLoopFilterCbBetaOffset       ()      { return m_loopFilterCbBetaOffsetDiv2; }
-  int       getLoopFilterCbTcOffset         ()      { return m_loopFilterCbTcOffsetDiv2;   }
-  int       getLoopFilterCrBetaOffset       ()      { return m_loopFilterCrBetaOffsetDiv2; }
-  int       getLoopFilterCrTcOffset         ()      { return m_loopFilterCrTcOffsetDiv2;   }
+  bool      getDeblockingFilterDisable            ()      { return m_deblockingFilterDisable;          }
+  bool      getDeblockingFilterOffsetInPPS        ()      { return m_deblockingFilterOffsetInPPS;      }
+  int       getDeblockingFilterBetaOffset         ()      { return m_deblockingFilterBetaOffsetDiv2;   }
+  int       getDeblockingFilterTcOffset           ()      { return m_deblockingFilterTcOffsetDiv2;     }
+  int       getDeblockingFilterCbBetaOffset       ()      { return m_deblockingFilterCbBetaOffsetDiv2; }
+  int       getDeblockingFilterCbTcOffset         ()      { return m_deblockingFilterCbTcOffsetDiv2;   }
+  int       getDeblockingFilterCrBetaOffset       ()      { return m_deblockingFilterCrBetaOffsetDiv2; }
+  int       getDeblockingFilterCrTcOffset         ()      { return m_deblockingFilterCrTcOffsetDiv2;   }
 #if W0038_DB_OPT
   int       getDeblockingFilterMetric       ()      { return m_deblockingFilterMetric; }
 #else
@@ -1414,6 +1609,8 @@ public:
   void setUseBDPCM                                     ( bool b ) { m_useBDPCM  = b;   }
   bool getUseJointCbCr                                 ()         { return m_JointCbCrMode; }
   void setUseJointCbCr                                 (bool b)   { m_JointCbCrMode = b; }
+  bool getRrcRiceExtensionEnableFlag()                 const { return m_rrcRiceExtensionEnableFlag; }
+  void setRrcRiceExtensionEnableFlag(const bool value) { m_rrcRiceExtensionEnableFlag = value; }
   bool getPersistentRiceAdaptationEnabledFlag          ()                 const { return m_persistentRiceAdaptationEnabledFlag;  }
   void setPersistentRiceAdaptationEnabledFlag          (const bool value)       { m_persistentRiceAdaptationEnabledFlag = value; }
   bool getCabacBypassAlignmentEnabledFlag              ()       const      { return m_cabacBypassAlignmentEnabledFlag;  }
@@ -1460,6 +1657,10 @@ public:
   bool      getSingleSlicePerSubPicFlagFlag( )                       { return m_singleSlicePerSubPicFlag;    }
   void      setUseSAO                  (bool bVal)                   { m_bUseSAO = bVal; }
   bool      getUseSAO                  ()                            { return m_bUseSAO; }
+#if JVET_W0129_ENABLE_ALF_TRUEORG
+  void      setSaoTrueOrg              (bool b)                      { m_saoTrueOrg = b; }
+  bool      getSaoTrueOrg              () const                      { return m_saoTrueOrg; }
+#endif
   void  setTestSAODisableAtPictureLevel (bool bVal)                  { m_bTestSAODisableAtPictureLevel = bVal; }
   bool  getTestSAODisableAtPictureLevel ( ) const                    { return m_bTestSAODisableAtPictureLevel; }
 
@@ -1490,6 +1691,8 @@ public:
   bool  getFrameFieldInfoSEIEnabled() const                           { return m_frameFieldInfoSEIEnabled; }
   void  setDependentRAPIndicationSEIEnabled(bool b)                  { m_dependentRAPIndicationSEIEnabled = b; }
   int   getDependentRAPIndicationSEIEnabled() const                  { return m_dependentRAPIndicationSEIEnabled; }
+  void  setEdrapIndicationSEIEnabled(bool b)                         { m_edrapIndicationSEIEnabled = b; }
+  int   getEdrapIndicationSEIEnabled() const                         { return m_edrapIndicationSEIEnabled; }
   void  setFramePackingArrangementSEIEnabled(bool b)                 { m_framePackingSEIEnabled = b; }
   bool  getFramePackingArrangementSEIEnabled() const                 { return m_framePackingSEIEnabled; }
   void  setFramePackingArrangementSEIType(int b)                     { m_framePackingSEIType = b; }
@@ -1500,6 +1703,14 @@ public:
   int   getFramePackingArrangementSEIQuincunx()                      { return m_framePackingSEIQuincunx; }
   void  setFramePackingArrangementSEIInterpretation(int b)           { m_framePackingSEIInterpretation = b; }
   int   getFramePackingArrangementSEIInterpretation()                { return m_framePackingSEIInterpretation; }
+  void  setDoSEIEnabled(bool b)                                      { m_doSEIEnabled = b; }
+  bool  getDoSEIEnabled() const                                      { return m_doSEIEnabled; }
+  void  setDoSEICancelFlag(bool b)                                   { m_doSEICancelFlag = b; }
+  bool  getDoSEICancelFlag()                                         { return m_doSEICancelFlag; }
+  void  setDoSEIPersistenceFlag(bool b)                              { m_doSEIPersistenceFlag = b; }
+  bool  getDoSEIPersistenceFlag()                                    { return m_doSEIPersistenceFlag; }
+  void  setDoSEITransformType(const int type)                        { m_doSEITransformType = type; }
+  int   getDOSEITransformType() const                                { return m_doSEITransformType; }
   void  setParameterSetsInclusionIndicationSEIEnabled(bool b)        { m_parameterSetsInclusionIndicationSEIEnabled = b; }
   bool  getParameterSetsInclusionIndicationSEIEnabled() const        { return m_parameterSetsInclusionIndicationSEIEnabled; }
   void  setSelfContainedClvsFlag(bool b)                             { m_selfContainedClvsFlag = b; }
@@ -1557,6 +1768,8 @@ public:
   uint32_t  getOmniViewportSEIHorRange(int idx)                      { return m_omniViewportSEIHorRange[idx]; }
   void  setOmniViewportSEIVerRange(const std::vector<uint32_t>& vi)  { m_omniViewportSEIVerRange = vi; }
   uint32_t  getOmniViewportSEIVerRange(int idx)                      { return m_omniViewportSEIVerRange[idx]; }
+  void  setAnnotatedRegionSEIFileRoot(const std::string &s)          { m_arSEIFileRoot = s; m_arObjects.clear();}
+  const std::string &getAnnotatedRegionSEIFileRoot() const           { return m_arSEIFileRoot; }
   void     setRwpSEIEnabled(bool b)                                                                     { m_rwpSEIEnabled = b; }
   bool     getRwpSEIEnabled()                                                                           { return m_rwpSEIEnabled; }
   void     setRwpSEIRwpCancelFlag(bool b)                                                               { m_rwpSEIRwpCancelFlag = b; }
@@ -1694,6 +1907,31 @@ public:
   uint16_t getAmbientViewingEnvironmentSEIAmbientLightX()            { return m_aveSEIAmbientLightX; }
   void  setAmbientViewingEnvironmentSEIAmbientLightY( uint16_t v )   { m_aveSEIAmbientLightY = v; }
   uint16_t getAmbientViewingEnvironmentSEIAmbientLightY()            { return m_aveSEIAmbientLightY; }
+  // colour tranform information sei
+  void      setCtiSEIEnabled(bool b) { m_ctiSEIEnabled = b; }
+  bool      getCtiSEIEnabled() { return m_ctiSEIEnabled; }
+  void      setCtiSEIId(uint32_t b) { m_ctiSEIId = b; }
+  uint32_t  getCtiSEIId() { return m_ctiSEIId; }
+  void      setCtiSEISignalInfoFlag(bool b) { m_ctiSEISignalInfoFlag = b; }
+  bool      getCtiSEISignalInfoFlag() { return m_ctiSEISignalInfoFlag; }
+  void      setCtiSEIFullRangeFlag(bool b) { m_ctiSEIFullRangeFlag = b; }
+  bool      getCtiSEIFullRangeFlag() { return m_ctiSEIFullRangeFlag; }
+  uint32_t  getCtiSEIPrimaries() { return m_ctiSEIPrimaries; }
+  void      setCtiSEIPrimaries(uint32_t v) { m_ctiSEIPrimaries = v; }
+  uint32_t  getCtiSEITransferFunction() { return m_ctiSEITransferFunction; }
+  void      setCtiSEITransferFunction(uint32_t v) { m_ctiSEITransferFunction = v; }
+  uint32_t  getCtiSEIMatrixCoefs() { return m_ctiSEIMatrixCoefs; }
+  void      setCtiSEIMatrixCoefs(uint32_t v) { m_ctiSEIMatrixCoefs = v; }
+  void      setCtiSEICrossComponentFlag(bool b) { m_ctiSEICrossComponentFlag = b; }
+  bool      getCtiSEICrossComponentFlag() { return m_ctiSEICrossComponentFlag; }
+  void      setCtiSEICrossComponentInferred(bool b) { m_ctiSEICrossComponentInferred = b; }
+  bool      getCtiSEICrossComponentInferred() { return m_ctiSEICrossComponentInferred; }
+  uint32_t  getCtiSEINbChromaLut() { return m_ctiSEINumberChromaLut; }
+  void      setCtiSEINbChromaLut(uint32_t v) { m_ctiSEINumberChromaLut = v; }
+  int       getCtiSEIChromaOffset() { return m_ctiSEIChromaOffset; }
+  void      setCtiSEIChromaOffset(int v) { m_ctiSEIChromaOffset = v; }
+  const LutModel&  getCtiSEILut(int idx) const { return m_ctiSEILut[idx]; }
+  void      setCtiSEILut(LutModel& cmp, int idx) { m_ctiSEILut[idx] = cmp; }
   // ccv SEI
   void     setCcvSEIEnabled(bool b)                                  { m_ccvSEIEnabled = b; }
   bool     getCcvSEIEnabled()                                        { return m_ccvSEIEnabled; }
@@ -1719,6 +1957,140 @@ public:
   double   getCcvSEIMaxLuminanceValue  ()                            { return m_ccvSEIMaxLuminanceValue;  }
   void     setCcvSEIAvgLuminanceValue  (double dValue)               { m_ccvSEIAvgLuminanceValue = dValue; }
   double   getCcvSEIAvgLuminanceValue  ()                            { return m_ccvSEIAvgLuminanceValue;  }
+  // scalability dimension information SEI
+  void     setSdiSEIEnabled(bool b)                                  { m_sdiSEIEnabled = b; }
+  bool     getSdiSEIEnabled() const                                  { return m_sdiSEIEnabled; }
+  void     setSdiSEIMaxLayersMinus1(int i)                           { m_sdiSEIMaxLayersMinus1 = i; }
+  int      getSdiSEIMaxLayersMinus1() const                          { return m_sdiSEIMaxLayersMinus1; }
+  void     setSdiSEIMultiviewInfoFlag(bool b)                        { m_sdiSEIMultiviewInfoFlag = b; }
+  bool     getSdiSEIMultiviewInfoFlag() const                        { return m_sdiSEIMultiviewInfoFlag; }
+  void     setSdiSEIAuxiliaryInfoFlag(bool b)                        { m_sdiSEIAuxiliaryInfoFlag = b; }
+  bool     getSdiSEIAuxiliaryInfoFlag() const                        { return m_sdiSEIAuxiliaryInfoFlag; }
+  void     setSdiSEIViewIdLenMinus1(int i)                           { m_sdiSEIViewIdLenMinus1 = i; }
+  int      getSdiSEIViewIdLenMinus1() const                          { return m_sdiSEIViewIdLenMinus1; }
+  void     setSdiSEILayerId(const std::vector<uint32_t>& sdiSEILayerId)   { m_sdiSEILayerId = sdiSEILayerId; }
+  uint32_t getSdiSEILayerId(int idx) const                           { return m_sdiSEILayerId[idx]; }
+  void     setSdiSEIViewIdVal(const std::vector<uint32_t>& sdiSEIViewIdVal)   { m_sdiSEIViewIdVal = sdiSEIViewIdVal; }
+  uint32_t getSdiSEIViewIdVal(int idx) const                         { return m_sdiSEIViewIdVal[idx]; }
+  void     setSdiSEIAuxId(const std::vector<uint32_t>& sdiSEIAuxId)       { m_sdiSEIAuxId = sdiSEIAuxId; }
+  uint32_t getSdiSEIAuxId(int idx) const                             { return m_sdiSEIAuxId[idx]; }
+  void     setSdiSEINumAssociatedPrimaryLayersMinus1(const std::vector<uint32_t>& sdiSEINumAssociatedPrimaryLayersMinus1)   { m_sdiSEINumAssociatedPrimaryLayersMinus1 = sdiSEINumAssociatedPrimaryLayersMinus1; }
+  uint32_t getSdiSEINumAssociatedPrimaryLayersMinus1(int idx) const  { return m_sdiSEINumAssociatedPrimaryLayersMinus1[idx]; }
+  // multiview acquisition information SEI
+  void     setMaiSEIEnabled(bool b)                                  { m_maiSEIEnabled = b; }
+  bool     getMaiSEIEnabled() const                                  { return m_maiSEIEnabled; }
+  void     setMaiSEIIntrinsicParamFlag(bool b)                       { m_maiSEIIntrinsicParamFlag = b; }
+  bool     getMaiSEIIntrinsicParamFlag() const                       { return m_maiSEIIntrinsicParamFlag; }
+  void     setMaiSEIExtrinsicParamFlag(bool b)                       { m_maiSEIExtrinsicParamFlag = b; }
+  bool     getMaiSEIExtrinsicParamFlag() const                       { return m_maiSEIExtrinsicParamFlag; }
+  void     setMaiSEINumViewsMinus1(int i)                            { m_maiSEINumViewsMinus1 = i; }
+  int      getMaiSEINumViewsMinus1() const                           { return m_maiSEINumViewsMinus1; }
+  void     setMaiSEIIntrinsicParamsEqualFlag(bool b)                 { m_maiSEIIntrinsicParamsEqualFlag = b; }
+  bool     getMaiSEIIntrinsicParamsEqualFlag() const                 { return m_maiSEIIntrinsicParamsEqualFlag; }
+  void     setMaiSEIPrecFocalLength(int i)                           { m_maiSEIPrecFocalLength= i; }
+  int      getMaiSEIPrecFocalLength() const                          { return m_maiSEIPrecFocalLength; }
+  void     setMaiSEIPrecPrincipalPoint(int i)                        { m_maiSEIPrecPrincipalPoint = i; }
+  int      getMaiSEIPrecPrincipalPoint() const                       { return m_maiSEIPrecPrincipalPoint; }
+  void     setMaiSEIPrecSkewFactor(int i)                            { m_maiSEIPrecSkewFactor = i; }
+  int      getMaiSEIPrecSkewFactor() const                           { return m_maiSEIPrecSkewFactor; }
+  void     setMaiSEISignFocalLengthX(const std::vector<bool>& maiSEISignFocalLengthX) { m_maiSEISignFocalLengthX = maiSEISignFocalLengthX; }
+  bool     getMaiSEISignFocalLengthX(int idx) const                  { return m_maiSEISignFocalLengthX[idx]; }
+  void     setMaiSEIExponentFocalLengthX(const std::vector<uint32_t>& maiSEIExponentFocalLengthX) { m_maiSEIExponentFocalLengthX = maiSEIExponentFocalLengthX; }
+  uint32_t      getMaiSEIExponentFocalLengthX(int idx) const              { return m_maiSEIExponentFocalLengthX[idx]; }
+  void     setMaiSEIMantissaFocalLengthX(const std::vector<uint32_t>& maiSEIMantissaFocalLengthX) { m_maiSEIMantissaFocalLengthX = maiSEIMantissaFocalLengthX; }
+  uint32_t      getMaiSEIMantissaFocalLengthX(int idx) const              { return m_maiSEIMantissaFocalLengthX[idx]; }
+  void     setMaiSEISignFocalLengthY(const std::vector<bool>& maiSEISignFocalLengthY) { m_maiSEISignFocalLengthY = maiSEISignFocalLengthY; }
+  bool     getMaiSEISignFocalLengthY(int idx) const                  { return m_maiSEISignFocalLengthY[idx]; }
+  void     setMaiSEIExponentFocalLengthY(const std::vector<uint32_t>& maiSEIExponentFocalLengthY) { m_maiSEIExponentFocalLengthY = maiSEIExponentFocalLengthY; }
+  uint32_t      getMaiSEIExponentFocalLengthY(int idx) const              { return m_maiSEIExponentFocalLengthY[idx]; }
+  void     setMaiSEIMantissaFocalLengthY(const std::vector<uint32_t>& maiSEIMantissaFocalLengthY) { m_maiSEIMantissaFocalLengthY = maiSEIMantissaFocalLengthY; }
+  uint32_t      getMaiSEIMantissaFocalLengthY(int idx) const              { return m_maiSEIMantissaFocalLengthY[idx]; }
+  void     setMaiSEISignPrincipalPointX(const std::vector<bool>& maiSEISignPrincipalPointX) { m_maiSEISignPrincipalPointX = maiSEISignPrincipalPointX; }
+  bool     getMaiSEISignPrincipalPointX(int idx) const               { return m_maiSEISignPrincipalPointX[idx]; }
+  void     setMaiSEIExponentPrincipalPointX(const std::vector<uint32_t>& maiSEIExponentPrincipalPointX) { m_maiSEIExponentPrincipalPointX = maiSEIExponentPrincipalPointX; }
+  uint32_t      getMaiSEIExponentPrincipalPointX(int idx) const           { return m_maiSEIExponentPrincipalPointX[idx]; }
+  void     setMaiSEIMantissaPrincipalPointX(const std::vector<uint32_t>& maiSEIMantissaPrincipalPointX) { m_maiSEIMantissaPrincipalPointX = maiSEIMantissaPrincipalPointX; }
+  uint32_t      getMaiSEIMantissaPrincipalPointX(int idx) const           { return m_maiSEIMantissaPrincipalPointX[idx]; }
+  void     setMaiSEISignPrincipalPointY(const std::vector<bool>& maiSEISignPrincipalPointY) { m_maiSEISignPrincipalPointY = maiSEISignPrincipalPointY; }
+  bool     getMaiSEISignPrincipalPointY(int idx) const               { return m_maiSEISignPrincipalPointY[idx]; }
+  void     setMaiSEIExponentPrincipalPointY(const std::vector<uint32_t>& maiSEIExponentPrincipalPointY) { m_maiSEIExponentPrincipalPointY = maiSEIExponentPrincipalPointY; }
+  uint32_t      getMaiSEIExponentPrincipalPointY(int idx) const           { return m_maiSEIExponentPrincipalPointY[idx]; }
+  void     setMaiSEIMantissaPrincipalPointY(const std::vector<uint32_t>& maiSEIMantissaPrincipalPointY) { m_maiSEIMantissaPrincipalPointY = maiSEIMantissaPrincipalPointY; }
+  uint32_t      getMaiSEIMantissaPrincipalPointY(int idx) const           { return m_maiSEIMantissaPrincipalPointY[idx]; }
+  void     setMaiSEISignSkewFactor(const std::vector<bool>& maiSEISignSkewFactor) { m_maiSEISignSkewFactor = maiSEISignSkewFactor; }
+  bool     getMaiSEISignSkewFactor(int idx) const                    { return m_maiSEISignSkewFactor[idx]; }
+  void     setMaiSEIExponentSkewFactor(const std::vector<uint32_t>& maiSEIExponentSkewFactor) { m_maiSEIExponentSkewFactor = maiSEIExponentSkewFactor; }
+  uint32_t      getMaiSEIExponentSkewFactor(int idx) const                { return m_maiSEIExponentSkewFactor[idx]; }
+  void     setMaiSEIMantissaSkewFactor(const std::vector<uint32_t>& maiSEIMantissaSkewFactor) { m_maiSEIMantissaSkewFactor = maiSEIMantissaSkewFactor; }
+  uint32_t      getMaiSEIMantissaSkewFactor(int idx) const                { return m_maiSEIMantissaSkewFactor[idx]; }
+  void     setMaiSEIPrecRotationParam(int i)                         { m_maiSEIPrecRotationParam = i; }
+  int      getMaiSEIPrecRotationParam() const                        { return m_maiSEIPrecRotationParam; }
+  void     setMaiSEIPrecTranslationParam(int i)                      { m_maiSEIPrecTranslationParam = i; }
+  int      getMaiSEIPrecTranslationParam() const                     { return m_maiSEIPrecTranslationParam; }
+#if JVET_W0078_MVP_SEI 
+  // multiview view position SEI
+  void     setMvpSEIEnabled(bool b) { m_mvpSEIEnabled = b; }
+  bool     getMvpSEIEnabled() const { return m_mvpSEIEnabled; }
+  void     setMvpSEINumViewsMinus1(int i) { m_mvpSEINumViewsMinus1 = i; }
+  int      getMvpSEINumViewsMinus1() const { return m_mvpSEINumViewsMinus1; }
+  void     setMvpSEIViewPosition(const std::vector<uint32_t>& mvpSEIViewPosition) { m_mvpSEIViewPosition = mvpSEIViewPosition; }
+  uint32_t      getMvpSEIViewPosition(int idx) const { return m_mvpSEIViewPosition[idx]; }
+#endif
+  // alpha channel information SEI
+  void     setAciSEIEnabled(bool b)                                  { m_aciSEIEnabled = b; }
+  bool     getAciSEIEnabled() const                                  { return m_aciSEIEnabled; }
+  void     setAciSEICancelFlag(bool b)                               { m_aciSEICancelFlag = b; }
+  bool     getAciSEICancelFlag() const                               { return m_aciSEICancelFlag; }
+  void     setAciSEIUseIdc(int value)                                { m_aciSEIUseIdc = value; }
+  int      getAciSEIUseIdc() const                                   { return m_aciSEIUseIdc; }
+  void     setAciSEIBitDepthMinus8(int value)                        { m_aciSEIBitDepthMinus8 = value; }
+  int      getAciSEIBitDepthMinus8() const                           { return m_aciSEIBitDepthMinus8; }
+  void     setAciSEITransparentValue(int value)                      { m_aciSEITransparentValue = value; }
+  int      getAciSEITransparentValue() const                         { return m_aciSEITransparentValue; }
+  void     setAciSEIOpaqueValue(int value)                           { m_aciSEIOpaqueValue = value; }
+  int      getAciSEIOpaqueValue() const                              { return m_aciSEIOpaqueValue; }
+  void     setAciSEIIncrFlag(bool b)                                 { m_aciSEIIncrFlag = b; }
+  bool     getAciSEIIncrFlag() const                                 { return m_aciSEIIncrFlag; }
+  void     setAciSEIClipFlag(bool b)                                 { m_aciSEIClipFlag = b; }
+  bool     getAciSEIClipFlag() const                                 { return m_aciSEIClipFlag; }
+  void     setAciSEIClipTypeFlag(bool b)                             { m_aciSEIClipTypeFlag = b; }
+  bool     getAciSEIClipTypeFlag() const                             { return m_aciSEIClipTypeFlag; }
+  // depth representation information SEI
+  void     setDriSEIEnabled(bool b)                                  { m_driSEIEnabled = b; }
+  bool     getDriSEIEnabled() const                                  { return m_driSEIEnabled; }
+  void     setDriSEIZNearFlag(bool b)                                { m_driSEIZNearFlag = b; }
+  bool     getDriSEIZNearFlag() const                                { return m_driSEIZNearFlag; }
+  void     setDriSEIZFarFlag(bool b)                                 { m_driSEIZFarFlag = b; }
+  bool     getDriSEIZFarFlag() const                                 { return m_driSEIZFarFlag; }
+  void     setDriSEIDMinFlag(bool b)                                 { m_driSEIDMinFlag = b; }
+  bool     getDriSEIDMinFlag() const                                 { return m_driSEIDMinFlag; }
+  void     setDriSEIDMaxFlag(bool b)                                 { m_driSEIDMaxFlag = b; }
+  bool     getDriSEIDMaxFlag() const                                 { return m_driSEIDMaxFlag; }
+  void     setDriSEIZNear(double d)                                  { m_driSEIZNear = d; }
+  double   getDriSEIZNear() const                                    { return m_driSEIZNear; }
+  void     setDriSEIZFar(double d)                                   { m_driSEIZFar = d; }
+  double   getDriSEIZFar() const                                     { return m_driSEIZFar; }
+  void     setDriSEIDMin(double d)                                   { m_driSEIDMin = d; }
+  double   getDriSEIDMin() const                                     { return m_driSEIDMin; }
+  void     setDriSEIDMax(double d)                                   { m_driSEIDMax = d; }
+  double   getDriSEIDMax() const                                     { return m_driSEIDMax; }
+  void     setDriSEIDepthRepresentationType(int i)                   { m_driSEIDepthRepresentationType = i; }
+  int      getDriSEIDepthRepresentationType() const                  { return m_driSEIDepthRepresentationType; }
+  void     setDriSEIDisparityRefViewId(int i)                        { m_driSEIDisparityRefViewId = i; }
+  int      getDriSEIDisparityRefViewId() const                       { return m_driSEIDisparityRefViewId; }
+  void     setDriSEINonlinearNumMinus1(int i)                        { m_driSEINonlinearNumMinus1 = i; }
+  int      getDriSEINonlinearNumMinus1() const                       { return m_driSEINonlinearNumMinus1; }
+  void     setDriSEINonlinearModel(const std::vector<uint32_t>& driSEINonLinearModel) { m_driSEINonlinearModel = driSEINonLinearModel; }
+  uint32_t getDriSEINonlinearModel(int idx) const                                                    { return m_driSEINonlinearModel[idx]; }
+#if JVET_W0133_CONSTRAINED_RASL_ENCODING
+  void     setConstrainedRaslencoding(bool b)                        { m_constrainedRaslEncoding = b; }
+  bool     getConstrainedRaslencoding()                              { return m_constrainedRaslEncoding; }
+  void     setCraAPSreset(bool b)                                    { m_craAPSreset = b; }
+  bool     getCraAPSreset()                                    const { return m_craAPSreset; }
+  void     setRprRASLtoolSwitch(bool b)                              { m_rprRASLtoolSwitch = b; }
+  bool     getRprRASLtoolSwitch()                                    { return m_rprRASLtoolSwitch; }
+#endif
+
   void         setUseWP               ( bool b )                     { m_useWeightedPred   = b;    }
   void         setWPBiPred            ( bool b )                     { m_useWeightedBiPred = b;    }
   bool         getUseWP               ()                             { return m_useWeightedPred;   }
@@ -1790,28 +2162,27 @@ public:
   bool         getTSRCdisableLL       ()                             { return m_TSRCdisableLL;         }
   void         setTSRCdisableLL       ( bool b )                     { m_TSRCdisableLL = b;            }
 
-#if JVET_S0163_ON_TARGETOLS_SUBLAYERS
   void         setOPI(OPI *p)                                        { m_opi = *p; }
   OPI*         getOPI()                                              { return &m_opi; }
-#endif
 
   void         setDCI(DCI *p)                                        { m_dci = *p; }
   DCI*         getDCI()                                              { return &m_dci; }
   void         setUseRecalculateQPAccordingToLambda (bool b)         { m_recalculateQPAccordingToLambda = b;    }
   bool         getUseRecalculateQPAccordingToLambda ()               { return m_recalculateQPAccordingToLambda; }
 
-  void         setEfficientFieldIRAPEnabled( bool b )                { m_bEfficientFieldIRAPEnabled = b; }
-  bool         getEfficientFieldIRAPEnabled( ) const                 { return m_bEfficientFieldIRAPEnabled; }
+  void setFieldSeqFlag(const bool b) { m_fieldSeqFlag = b; }
+  bool getFieldSeqFlag() const { return m_fieldSeqFlag; }
 
-  void         setHarmonizeGopFirstFieldCoupleEnabled( bool b )      { m_bHarmonizeGopFirstFieldCoupleEnabled = b; }
-  bool         getHarmonizeGopFirstFieldCoupleEnabled( ) const       { return m_bHarmonizeGopFirstFieldCoupleEnabled; }
+  void setEfficientFieldIRAPEnabled(const bool b) { m_efficientFieldIRAPEnabled = b; }
+  bool getEfficientFieldIRAPEnabled() const { return m_efficientFieldIRAPEnabled; }
+
+  void setHarmonizeGopFirstFieldCoupleEnabled(const bool b) { m_harmonizeGopFirstFieldCoupleEnabled = b; }
+  bool getHarmonizeGopFirstFieldCoupleEnabled() const { return m_harmonizeGopFirstFieldCoupleEnabled; }
 
-#if JVET_S0163_ON_TARGETOLS_SUBLAYERS
   bool         getOPIEnabled()                      { return m_OPIEnabled; }
   void         setOPIEnabled(bool i)                { m_OPIEnabled = i; }
   void         setHtidPlus1(int HTid)               { m_opi.setHtidInfoPresentFlag(true); m_opi.setOpiHtidPlus1(HTid); }
   void         setTargetOlsIdx(int TOlsIdx)         { m_opi.setOlsInfoPresentFlag(true); m_opi.setOpiOlsIdx(TOlsIdx); }
-#endif
 
   bool         getDCIEnabled()                      { return m_DCIEnabled; }
   void         setDCIEnabled(bool i)                { m_DCIEnabled = i; }
@@ -1920,22 +2291,29 @@ public:
   void         setDebugCTU( int i )                                  { m_debugCTU = i; }
   int          getDebugCTU()                                   const { return m_debugCTU; }
 
-#if ENABLE_SPLIT_PARALLELISM
-  void         setNumSplitThreads( int n )                           { m_numSplitThreads = n; }
-  int          getNumSplitThreads()                            const { return m_numSplitThreads; }
-  void         setForceSingleSplitThread( bool b )                   { m_forceSingleSplitThread = b; }
-  int          getForceSingleSplitThread()                     const { return m_forceSingleSplitThread; }
-#endif
   void         setUseALF( bool b ) { m_alf = b; }
   bool         getUseALF()                                      const { return m_alf; }
-#if JVET_T0064
-  void         setALFStrength( double s)                        { m_alfStrength = s; }
-  double       getALFStrength()                                 const { return m_alfStrength; }
+#if JVET_W0129_ENABLE_ALF_TRUEORG
+  void         setAlfTrueOrg( bool b )                                { m_alfTrueOrg = b; }
+  bool         getAlfTrueOrg()                                  const { return m_alfTrueOrg; }
+#else
+  void         setAlfSaoTrueOrg( bool b )                             { m_alfSaoTrueOrg = b; }
+  bool         getAlfSaoTrueOrg()                               const { return m_alfSaoTrueOrg; }
+#endif
+  void         setALFStrengthLuma(double s)                     { m_alfStrengthLuma = s; }
+  double       getALFStrengthLuma()                             const { return m_alfStrengthLuma; }
   void         setALFAllowPredefinedFilters(bool b)             { m_alfAllowPredefinedFilters = b; }
   bool         getALFAllowPredefinedFilters()                   const { return m_alfAllowPredefinedFilters; }
   void         setCCALFStrength(double s)                       { m_ccalfStrength = s; }
   double       getCCALFStrength()                               const { return m_ccalfStrength; }
-#endif
+  void         setALFStrengthChroma(double s)                  { m_alfStrengthChroma = s; }
+  double       getALFStrengthChroma()                          const { return m_alfStrengthChroma; }
+  void         setALFStrengthTargetLuma(double s)              { m_alfStrengthTargetLuma = s; }
+  double       getALFStrengthTargetLuma()                      const { return m_alfStrengthTargetLuma; }
+  void         setALFStrengthTargetChroma(double s)            { m_alfStrengthTargetChroma = s; }
+  double       getALFStrengthTargetChroma()                    const { return m_alfStrengthTargetChroma; }
+  void         setCCALFStrengthTarget(double s)                { m_ccalfStrengthTarget = s; }
+  double       getCCALFStrengthTarget()                        const { return m_ccalfStrengthTarget; }
   void         setUseCCALF( bool b )                                  { m_ccalf = b; }
   bool         getUseCCALF()                                    const { return m_ccalf; }
   void         setCCALFQpThreshold( int b )                           { m_ccalfQpThreshold = b; }
diff --git a/source/Lib/EncoderLib/EncCfgParam.h b/source/Lib/EncoderLib/EncCfgParam.h
index f15644b04..f83a651f2 100644
--- a/source/Lib/EncoderLib/EncCfgParam.h
+++ b/source/Lib/EncoderLib/EncCfgParam.h
@@ -4,7 +4,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -48,18 +48,11 @@ class CfgVPSParameters
 {
 public:
   CfgVPSParameters()
-#if !JVET_R0193
-  : m_maxTidILRefPicsPlus1(-1)
-#endif
   {}
 
   virtual ~CfgVPSParameters(){}
 
-#if JVET_R0193
   std::vector<std::vector<uint32_t>> m_maxTidILRefPicsPlus1;
-#else
-  int m_maxTidILRefPicsPlus1;
-#endif
 };
 
 class CfgSEISubpictureLevel
diff --git a/source/Lib/EncoderLib/EncCu.cpp b/source/Lib/EncoderLib/EncCu.cpp
index b875909a9..43a65f84b 100644
--- a/source/Lib/EncoderLib/EncCu.cpp
+++ b/source/Lib/EncoderLib/EncCu.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -155,14 +155,26 @@ void EncCu::destroy()
   {
     for( unsigned h = 0; h < numHeights; h++ )
     {
-      if( m_pBestCS[w][h] ) m_pBestCS[w][h]->destroy();
-      if( m_pTempCS[w][h] ) m_pTempCS[w][h]->destroy();
+      if (m_pBestCS[w][h])
+      {
+        m_pBestCS[w][h]->destroy();
+      }
+      if (m_pTempCS[w][h])
+      {
+        m_pTempCS[w][h]->destroy();
+      }
 
       delete m_pBestCS[w][h];
       delete m_pTempCS[w][h];
 
-      if( m_pBestCS2[w][h] ) m_pBestCS2[w][h]->destroy();
-      if( m_pTempCS2[w][h] ) m_pTempCS2[w][h]->destroy();
+      if (m_pBestCS2[w][h])
+      {
+        m_pBestCS2[w][h]->destroy();
+      }
+      if (m_pTempCS2[w][h])
+      {
+        m_pTempCS2[w][h]->destroy();
+      }
 
       delete m_pBestCS2[w][h];
       delete m_pTempCS2[w][h];
@@ -209,33 +221,25 @@ void EncCu::destroy()
   }
 }
 
-
-
 EncCu::~EncCu()
 {
 }
 
-
-
 /** \param    pcEncLib      pointer of encoder class
  */
-void EncCu::init( EncLib* pcEncLib, const SPS& sps PARL_PARAM( const int tId ) )
+void EncCu::init( EncLib* pcEncLib, const SPS& sps )
 {
   m_pcEncCfg           = pcEncLib;
-  m_pcIntraSearch      = pcEncLib->getIntraSearch( PARL_PARAM0( tId ) );
-  m_pcInterSearch      = pcEncLib->getInterSearch( PARL_PARAM0( tId ) );
-  m_pcTrQuant          = pcEncLib->getTrQuant( PARL_PARAM0( tId ) );
-  m_pcRdCost           = pcEncLib->getRdCost ( PARL_PARAM0( tId ) );
-  m_CABACEstimator     = pcEncLib->getCABACEncoder( PARL_PARAM0( tId ) )->getCABACEstimator( &sps );
+  m_pcIntraSearch      = pcEncLib->getIntraSearch();
+  m_pcInterSearch      = pcEncLib->getInterSearch();
+  m_pcTrQuant          = pcEncLib->getTrQuant();
+  m_pcRdCost           = pcEncLib->getRdCost ();
+  m_CABACEstimator     = pcEncLib->getCABACEncoder()->getCABACEstimator( &sps );
   m_CABACEstimator->setEncCu(this);
-  m_CtxCache           = pcEncLib->getCtxCache( PARL_PARAM0( tId ) );
+  m_CtxCache           = pcEncLib->getCtxCache();
   m_pcRateCtrl         = pcEncLib->getRateCtrl();
   m_pcSliceEncoder     = pcEncLib->getSliceEncoder();
-#if ENABLE_SPLIT_PARALLELISM
-  m_pcEncLib           = pcEncLib;
-  m_dataId             = tId;
-#endif
-  m_pcLoopFilter       = pcEncLib->getLoopFilter();
+  m_deblockingFilter   = pcEncLib->getDeblockingFilter();
   m_GeoCostList.init(GEO_NUM_PARTITION_MODE, m_pcEncCfg->getMaxNumGeoCand());
   m_AFFBestSATDCost = MAX_DOUBLE;
 
@@ -246,7 +250,6 @@ void EncCu::init( EncLib* pcEncLib, const SPS& sps PARL_PARAM( const int tId ) )
   m_pcInterSearch->setModeCtrl( m_modeCtrl );
   m_modeCtrl->setInterSearch(m_pcInterSearch);
   m_pcIntraSearch->setModeCtrl( m_modeCtrl );
-
 }
 
 // ====================================================================================================================
@@ -260,39 +263,6 @@ void EncCu::compressCtu( CodingStructure& cs, const UnitArea& area, const unsign
 
   cs.slice->m_mapPltCost[0].clear();
   cs.slice->m_mapPltCost[1].clear();
-#if ENABLE_SPLIT_PARALLELISM
-  if( m_pcEncCfg->getNumSplitThreads() > 1 )
-  {
-    for( int jId = 1; jId < NUM_RESERVERD_SPLIT_JOBS; jId++ )
-    {
-      EncCu*            jobEncCu  = m_pcEncLib->getCuEncoder( cs.picture->scheduler.getSplitDataId( jId ) );
-      CacheBlkInfoCtrl* cacheCtrl = dynamic_cast< CacheBlkInfoCtrl* >( jobEncCu->m_modeCtrl );
-#if REUSE_CU_RESULTS
-      BestEncInfoCache* bestCache = dynamic_cast< BestEncInfoCache* >( jobEncCu->m_modeCtrl );
-#endif
-      SaveLoadEncInfoSbt *sbtCache = dynamic_cast< SaveLoadEncInfoSbt* >( jobEncCu->m_modeCtrl );
-      if( cacheCtrl )
-      {
-        cacheCtrl->init( *cs.slice );
-      }
-#if REUSE_CU_RESULTS
-      if (bestCache)
-      {
-        bestCache->init(*cs.slice);
-      }
-#endif
-      if (sbtCache)
-      {
-        sbtCache->init(*cs.slice);
-      }
-    }
-  }
-
-#if REUSE_CU_RESULTS
-  if( auto* cacheCtrl = dynamic_cast<BestEncInfoCache*>( m_modeCtrl ) ) { cacheCtrl->tick(); }
-#endif
-  if( auto* cacheCtrl = dynamic_cast<CacheBlkInfoCtrl*>( m_modeCtrl ) ) { cacheCtrl->tick(); }
-#endif
   // init the partitioning manager
   QTBTPartitioner partitioner;
   partitioner.initCtu(area, CH_L, *cs.slice);
@@ -512,7 +482,6 @@ bool EncCu::xCheckBestMode( CodingStructure *&tempCS, CodingStructure *&bestCS,
 
     if( m_modeCtrl->useModeResult( encTestMode, tempCS, partitioner ) )
     {
-
       std::swap( tempCS, bestCS );
       // store temp best CI for next CU coding
       m_CurrCtx->best = m_CABACEstimator->getCtx();
@@ -524,26 +493,12 @@ bool EncCu::xCheckBestMode( CodingStructure *&tempCS, CodingStructure *&bestCS,
   // reset context states
   m_CABACEstimator->getCtx() = m_CurrCtx->start;
   return bestCSUpdated;
-
 }
 
 void EncCu::xCompressCU( CodingStructure*& tempCS, CodingStructure*& bestCS, Partitioner& partitioner, double maxCostAllowed )
 {
   CHECK(maxCostAllowed < 0, "Wrong value of maxCostAllowed!");
-#if ENABLE_SPLIT_PARALLELISM
-  CHECK( m_dataId != tempCS->picture->scheduler.getDataId(), "Working in the wrong dataId!" );
-
-  if( m_pcEncCfg->getNumSplitThreads() != 1 && tempCS->picture->scheduler.getSplitJobId() == 0 )
-  {
-    if( m_modeCtrl->isParallelSplit( *tempCS, partitioner ) )
-    {
-      m_modeCtrl->setParallelSplit( true );
-      xCompressCUParallel( tempCS, bestCS, partitioner );
-      return;
-    }
-  }
 
-#endif
   uint32_t compBegin;
   uint32_t numComp;
   bool jointPLT = false;
@@ -557,16 +512,16 @@ void EncCu::xCompressCU( CodingStructure*& tempCS, CodingStructure*& bestCS, Par
     }
     else
     {
-    if (isLuma(partitioner.chType))
-    {
-      compBegin = COMPONENT_Y;
-      numComp = 1;
-    }
-    else
-    {
-      compBegin = COMPONENT_Cb;
-      numComp = 2;
-    }
+      if (isLuma(partitioner.chType))
+      {
+        compBegin = COMPONENT_Y;
+        numComp   = 1;
+      }
+      else
+      {
+        compBegin = COMPONENT_Cb;
+        numComp   = 2;
+      }
     }
   }
   else
@@ -600,39 +555,115 @@ void EncCu::xCompressCU( CodingStructure*& tempCS, CodingStructure*& bestCS, Par
   const UnitArea currCsArea = clipArea( CS::getArea( *bestCS, bestCS->area, partitioner.chType ), *tempCS->picture );
 
   m_modeCtrl->initCULevel( partitioner, *tempCS );
-  if( partitioner.currQtDepth == 0 && partitioner.currMtDepth == 0 && !tempCS->slice->isIntra() && ( sps.getUseSBT() || sps.getUseInterMTS() ) )
+#if GDR_ENABLED
+  if (m_pcEncCfg->getGdrEnabled())
   {
-    auto slsSbt = dynamic_cast<SaveLoadEncInfoSbt*>( m_modeCtrl );
-    int maxSLSize = sps.getUseSBT() ? tempCS->slice->getSPS()->getMaxTbSize() : MTS_INTER_MAX_CU_SIZE;
-    slsSbt->resetSaveloadSbt( maxSLSize );
-#if ENABLE_SPLIT_PARALLELISM
-    CHECK( tempCS->picture->scheduler.getSplitJobId() != 0, "The SBT search reset need to happen in sequential region." );
-    if (m_pcEncCfg->getNumSplitThreads() > 1)
+    bool isInGdrInterval = slice.getPicHeader()->getInGdrInterval();
+
+    // 1.0 applicable to inter picture only
+    if (isInGdrInterval)
     {
-      for (int jId = 1; jId < NUM_RESERVERD_SPLIT_JOBS; jId++)
+      int gdrPocStart = m_pcEncCfg->getGdrPocStart();
+      int gdrInterval = m_pcEncCfg->getGdrInterval();
+
+      int picWidth = slice.getPPS()->getPicWidthInLumaSamples();
+      int m1, m2, n1;
+
+      int curPoc = slice.getPOC();
+      int gdrPoc = (curPoc - gdrPocStart) % gdrInterval;
+
+      int begGdrX = 0;
+      int endGdrX = 0;
+
+      double dd = (picWidth / (double)gdrInterval);
+      int mm = (int)((picWidth / (double)gdrInterval) + 0.49999);
+      m1 = ((mm + 7) >> 3) << 3;
+      m2 = ((mm + 0) >> 3) << 3;
+
+      if (dd > mm && m1 == m2)
+      {
+        m1 = m1 + 8;
+      }
+
+      n1 = (picWidth - m2 * gdrInterval) / 8;
+
+      if (gdrPoc < n1)
+      {
+        begGdrX = m1 * gdrPoc;
+        endGdrX = begGdrX + m1;
+      }
+      else
+      {
+        begGdrX = m1 * n1 + m2 * (gdrPoc - n1);
+        endGdrX = begGdrX + m2;
+        if (picWidth <= endGdrX)
+        {
+          begGdrX = picWidth;
+          endGdrX = picWidth;
+        }
+      }
+
+      bool isInRefreshArea = tempCS->withinRefresh(begGdrX, endGdrX);
+
+      if (isInRefreshArea)
+      {
+        m_modeCtrl->forceIntraMode();
+      }
+      else if (tempCS->containRefresh(begGdrX, endGdrX) || tempCS->overlapRefresh(begGdrX, endGdrX))
+      {
+        // 1.3.1 enable only vertical splits (QT, BT_V, TT_V)
+        m_modeCtrl->forceVerSplitOnly();
+
+        // 1.3.2 remove TT_V if it does not satisfy the condition
+        if (tempCS->refreshCrossTTV(begGdrX, endGdrX))
+        {
+          m_modeCtrl->forceRemoveTTV();
+        }
+      }
+
+      if (tempCS->area.lwidth() != tempCS->area.lheight())
+      {
+        m_modeCtrl->forceRemoveQT();
+      }
+
+      if (!m_modeCtrl->anyPredModeLeft())
+      {
+        m_modeCtrl->forceRemoveDontSplit();
+      }
+
+      if (isInRefreshArea && !m_modeCtrl->anyIntraIBCMode() && (tempCS->area.lwidth() == 4 || tempCS->area.lheight() == 4))
       {
-        auto slsSbt = dynamic_cast<SaveLoadEncInfoSbt *>(m_pcEncLib->getCuEncoder(jId)->m_modeCtrl);
-        slsSbt->resetSaveloadSbt(maxSLSize);
+        m_modeCtrl->finishCULevel(partitioner);
+        return;
       }
     }
+  }
 #endif
+
+  if( partitioner.currQtDepth == 0 && partitioner.currMtDepth == 0 && !tempCS->slice->isIntra() && ( sps.getUseSBT() || sps.getUseInterMTS() ) )
+  {
+    auto slsSbt = dynamic_cast<SaveLoadEncInfoSbt*>( m_modeCtrl );
+    int maxSLSize = sps.getUseSBT() ? tempCS->slice->getSPS()->getMaxTbSize() : MTS_INTER_MAX_CU_SIZE;
+    slsSbt->resetSaveloadSbt( maxSLSize );
   }
   m_sbtCostSave[0] = m_sbtCostSave[1] = MAX_DOUBLE;
 
   m_CurrCtx->start = m_CABACEstimator->getCtx();
 
-  m_cuChromaQpOffsetIdxPlus1 = 0;
-
   if( slice.getUseChromaQpAdj() )
   {
     // TODO M0133 : double check encoder decisions with respect to chroma QG detection and actual encode
     int lgMinCuSize = sps.getLog2MinCodingBlockSize() +
-      std::max<int>(0, floorLog2(sps.getCTUSize()) - sps.getLog2MinCodingBlockSize() - int(slice.getCuChromaQpOffsetSubdiv() / 2));
+      std::max<int>(0, floorLog2(sps.getCTUSize()) - sps.getLog2MinCodingBlockSize() - int((slice.getCuChromaQpOffsetSubdiv()+1) / 2));
     if( partitioner.currQgChromaEnable() )
     {
       m_cuChromaQpOffsetIdxPlus1 = ( ( uiLPelX >> lgMinCuSize ) + ( uiTPelY >> lgMinCuSize ) ) % ( pps.getChromaQpOffsetListLen() + 1 );
     }
   }
+  else
+  {
+    m_cuChromaQpOffsetIdxPlus1 = 0;
+  }
 
   if( !m_modeCtrl->anyMode() )
   {
@@ -708,6 +739,7 @@ void EncCu::xCompressCU( CodingStructure*& tempCS, CodingStructure*& bestCS, Par
 #if SHARP_LUMA_DELTA_QP
         (m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled()) ||
 #endif
+        (m_pcEncCfg->getSmoothQPReductionEnable()) ||
 #if ENABLE_QPA_SUB_CTU
         (m_pcEncCfg->getUsePerceptQPA() && !m_pcEncCfg->getUseRateCtrl() && pps.getUseDQP())
 #else
@@ -715,9 +747,6 @@ void EncCu::xCompressCU( CodingStructure*& tempCS, CodingStructure*& bestCS, Par
 #endif
       ))
     {
-#if ENABLE_SPLIT_PARALLELISM
-      CHECK( tempCS->picture->scheduler.getSplitJobId() > 0, "Changing lambda is only allowed in the master thread!" );
-#endif
       if (currTestMode.qp >= 0)
       {
         updateLambda (&slice, currTestMode.qp,
@@ -768,7 +797,9 @@ void EncCu::xCompressCU( CodingStructure*& tempCS, CodingStructure*& bestCS, Par
       xCheckRDCostMerge2Nx2N( tempCS, bestCS, partitioner, currTestMode );
       CodingUnit* cu = bestCS->getCU(partitioner.chType);
       if (cu)
-      cu->mmvdSkip = cu->skip == false ? false : cu->mmvdSkip;
+      {
+        cu->mmvdSkip = cu->skip == false ? false : cu->mmvdSkip;
+      }
     }
     else if( currTestMode.type == ETM_MERGE_GEO )
     {
@@ -884,7 +915,11 @@ void EncCu::xCompressCU( CodingStructure*& tempCS, CodingStructure*& bestCS, Par
           break;
         }
       }
+#if GDR_ENABLED
+      if (bestCS->cus.size() > 0 && splitmode != bestCS->cus[0]->splitSeries)
+#else
       if (splitmode != bestCS->cus[0]->splitSeries)
+#endif
       {
         splitmode = bestCS->cus[0]->splitSeries;
         const CodingUnit&     cu = *bestCS->cus.front();
@@ -906,17 +941,6 @@ void EncCu::xCompressCU( CodingStructure*& tempCS, CodingStructure*& bestCS, Par
 
   //////////////////////////////////////////////////////////////////////////
   // Finishing CU
-#if ENABLE_SPLIT_PARALLELISM
-  if( bestCS->cus.empty() )
-  {
-    CHECK( bestCS->cost != MAX_DOUBLE, "Cost should be maximal if no encoding found" );
-    CHECK( bestCS->picture->scheduler.getSplitJobId() == 0, "Should always get a result in serial case" );
-
-    m_modeCtrl->finishCULevel( partitioner );
-    return;
-  }
-
-#endif
   if( tempCS->cost == MAX_DOUBLE && bestCS->cost == MAX_DOUBLE )
   {
     //although some coding modes were planned to be tried in RDO, no coding mode actually finished encoding due to early termination
@@ -959,13 +983,6 @@ void EncCu::xCompressCU( CodingStructure*& tempCS, CodingStructure*& bestCS, Par
     m_pcIntraSearch->saveCuAreaCostInSCIPU( Area( partitioner.currArea().lumaPos(), partitioner.currArea().lumaSize() ), bestCS->cost );
   }
 
-#if ENABLE_SPLIT_PARALLELISM
-  if( tempCS->picture->scheduler.getSplitJobId() == 0 && m_pcEncCfg->getNumSplitThreads() != 1 )
-  {
-    tempCS->picture->finishParallelPart( currCsArea );
-  }
-
-#endif
   if (bestCS->cus.size() == 1) // no partition
   {
     CHECK(bestCS->cus[0]->tileIdx != bestCS->pps->getTileIdx(bestCS->area.lumaPos()), "Wrong tile index!");
@@ -1045,7 +1062,11 @@ void EncCu::updateLambda (Slice* slice, const int dQP,
   {
     m_pcRdCost->setLambda (newLambda, slice->getSPS()->getBitDepths());
 #if WCG_EXT
+#if !JVET_W0043
+    if (!(m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled() || m_pcEncCfg->getSmoothQPReductionEnable()))
+#else
     if (!m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled())
+#endif
     {
       m_pcRdCost->saveUnadjustedLambda();
     }
@@ -1054,164 +1075,6 @@ void EncCu::updateLambda (Slice* slice, const int dQP,
 }
 #endif // SHARP_LUMA_DELTA_QP || ENABLE_QPA_SUB_CTU
 
-#if ENABLE_SPLIT_PARALLELISM
-//#undef DEBUG_PARALLEL_TIMINGS
-//#define DEBUG_PARALLEL_TIMINGS 1
-void EncCu::xCompressCUParallel( CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &partitioner )
-{
-  const unsigned wIdx = gp_sizeIdxInfo->idxFrom( partitioner.currArea().lwidth() );
-  const unsigned hIdx = gp_sizeIdxInfo->idxFrom( partitioner.currArea().lheight() );
-
-  Picture* picture = tempCS->picture;
-
-  int numJobs = m_modeCtrl->getNumParallelJobs( *bestCS, partitioner );
-
-  bool    jobUsed                            [NUM_RESERVERD_SPLIT_JOBS];
-  std::fill( jobUsed, jobUsed + NUM_RESERVERD_SPLIT_JOBS, false );
-
-  const UnitArea currArea = CS::getArea( *tempCS, partitioner.currArea(), partitioner.chType );
-  const bool doParallel   = !m_pcEncCfg->getForceSingleSplitThread();
-  omp_set_num_threads( m_pcEncCfg->getNumSplitThreads() );
-
-#pragma omp parallel for schedule(dynamic,1) if(doParallel)
-  for( int jId = 1; jId <= numJobs; jId++ )
-  {
-    // thread start
-    picture->scheduler.setSplitThreadId();
-    picture->scheduler.setSplitJobId( jId );
-
-    QTBTPartitioner jobPartitioner;
-    EncCu*       jobCuEnc       = m_pcEncLib->getCuEncoder( picture->scheduler.getSplitDataId( jId ) );
-    auto*        jobBlkCache    = dynamic_cast<CacheBlkInfoCtrl*>( jobCuEnc->m_modeCtrl );
-#if REUSE_CU_RESULTS
-    auto*        jobBestCache   = dynamic_cast<BestEncInfoCache*>( jobCuEnc->m_modeCtrl );
-#endif
-
-    jobPartitioner.copyState( partitioner );
-    jobCuEnc      ->copyState( this, jobPartitioner, currArea, true );
-
-    if( jobBlkCache  ) { jobBlkCache ->tick(); }
-#if REUSE_CU_RESULTS
-    if( jobBestCache ) { jobBestCache->tick(); }
-
-#endif
-    CodingStructure *&jobBest = jobCuEnc->m_pBestCS[wIdx][hIdx];
-    CodingStructure *&jobTemp = jobCuEnc->m_pTempCS[wIdx][hIdx];
-
-    jobUsed[jId] = true;
-
-    jobCuEnc->xCompressCU( jobTemp, jobBest, jobPartitioner );
-
-    picture->scheduler.setSplitJobId( 0 );
-    // thread stop
-  }
-  picture->scheduler.setSplitThreadId( 0 );
-
-  int    bestJId  = 0;
-  double bestCost = bestCS->cost;
-  for( int jId = 1; jId <= numJobs; jId++ )
-  {
-    EncCu* jobCuEnc = m_pcEncLib->getCuEncoder( picture->scheduler.getSplitDataId( jId ) );
-
-    if( jobUsed[jId] && jobCuEnc->m_pBestCS[wIdx][hIdx]->cost < bestCost )
-    {
-      bestCost = jobCuEnc->m_pBestCS[wIdx][hIdx]->cost;
-      bestJId  = jId;
-    }
-  }
-
-  if( bestJId > 0 )
-  {
-    copyState( m_pcEncLib->getCuEncoder( picture->scheduler.getSplitDataId( bestJId ) ), partitioner, currArea, false );
-    m_CurrCtx->best = m_CABACEstimator->getCtx();
-
-    tempCS = m_pTempCS[wIdx][hIdx];
-    bestCS = m_pBestCS[wIdx][hIdx];
-  }
-
-  const int      bitDepthY = tempCS->sps->getBitDepth( CH_L );
-  const UnitArea clipdArea = clipArea( currArea, *picture );
-
-  CHECK( calcCheckSum( picture->getRecoBuf( clipdArea.Y() ), bitDepthY ) != calcCheckSum( bestCS->getRecoBuf( clipdArea.Y() ), bitDepthY ), "Data copied incorrectly!" );
-
-  picture->finishParallelPart( currArea );
-
-  if( auto *blkCache = dynamic_cast<CacheBlkInfoCtrl*>( m_modeCtrl ) )
-  {
-    for( int jId = 1; jId <= numJobs; jId++ )
-    {
-      if( !jobUsed[jId] || jId == bestJId ) continue;
-
-      auto *jobBlkCache = dynamic_cast<CacheBlkInfoCtrl*>( m_pcEncLib->getCuEncoder( picture->scheduler.getSplitDataId( jId ) )->m_modeCtrl );
-      CHECK( !jobBlkCache, "If own mode controller has blk info cache capability so should all other mode controllers!" );
-      blkCache->CacheBlkInfoCtrl::copyState( *jobBlkCache, partitioner.currArea() );
-    }
-
-    blkCache->tick();
-  }
-#if REUSE_CU_RESULTS
-
-  if( auto *blkCache = dynamic_cast<BestEncInfoCache*>( m_modeCtrl ) )
-  {
-    for( int jId = 1; jId <= numJobs; jId++ )
-    {
-      if( !jobUsed[jId] || jId == bestJId ) continue;
-
-      auto *jobBlkCache = dynamic_cast<BestEncInfoCache*>( m_pcEncLib->getCuEncoder( picture->scheduler.getSplitDataId( jId ) )->m_modeCtrl );
-      CHECK( !jobBlkCache, "If own mode controller has blk info cache capability so should all other mode controllers!" );
-      blkCache->BestEncInfoCache::copyState( *jobBlkCache, partitioner.currArea() );
-    }
-
-    blkCache->tick();
-  }
-#endif
-}
-
-void EncCu::copyState( EncCu* other, Partitioner& partitioner, const UnitArea& currArea, const bool isDist )
-{
-  const unsigned wIdx = gp_sizeIdxInfo->idxFrom( partitioner.currArea().lwidth () );
-  const unsigned hIdx = gp_sizeIdxInfo->idxFrom( partitioner.currArea().lheight() );
-
-  if( isDist )
-  {
-    other->m_pBestCS[wIdx][hIdx]->initSubStructure( *m_pBestCS[wIdx][hIdx], partitioner.chType, partitioner.currArea(), false );
-    other->m_pTempCS[wIdx][hIdx]->initSubStructure( *m_pTempCS[wIdx][hIdx], partitioner.chType, partitioner.currArea(), false );
-  }
-  else
-  {
-          CodingStructure* dst =        m_pBestCS[wIdx][hIdx];
-    const CodingStructure* src = other->m_pBestCS[wIdx][hIdx];
-    bool keepResi = KEEP_PRED_AND_RESI_SIGNALS;
-    bool keepPred = true;
-
-    dst->useSubStructure( *src, partitioner.chType, currArea, keepPred, true, keepResi, keepResi, true );
-
-    dst->cost           =  src->cost;
-    dst->dist           =  src->dist;
-    dst->fracBits       =  src->fracBits;
-    dst->features       =  src->features;
-  }
-
-  if( isDist )
-  {
-    m_CurrCtx = m_CtxBuffer.data();
-  }
-
-  m_pcInterSearch->copyState( *other->m_pcInterSearch );
-  m_modeCtrl     ->copyState( *other->m_modeCtrl, partitioner.currArea() );
-  m_pcRdCost     ->copyState( *other->m_pcRdCost );
-  m_pcTrQuant    ->copyState( *other->m_pcTrQuant );
-  if( m_pcEncCfg->getLmcs() )
-  {
-    EncReshape *encReshapeThis  = dynamic_cast<EncReshape*>(       m_pcReshape);
-    EncReshape *encReshapeOther = dynamic_cast<EncReshape*>(other->m_pcReshape);
-    encReshapeThis->copyState( *encReshapeOther );
-  }
-
-  m_CABACEstimator->getCtx() = other->m_CABACEstimator->getCtx();
-}
-#endif
-
 void EncCu::xCheckModeSplit(CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &partitioner, const EncTestMode& encTestMode, const ModeType modeTypeParent, bool &skipInterPass )
 {
   const int qp                = encTestMode.qp;
@@ -1286,6 +1149,7 @@ void EncCu::xCheckModeSplit(CodingStructure *&tempCS, CodingStructure *&bestCS,
 
   partitioner.splitCurrArea( split, *tempCS );
   bool qgEnableChildren = partitioner.currQgEnable(); // QG possible at children level
+  bool qgChromaEnableChildren = partitioner.currQgChromaEnable(); // Chroma QG possible at children level
 
   m_CurrCtx++;
 
@@ -1294,7 +1158,12 @@ void EncCu::xCheckModeSplit(CodingStructure *&tempCS, CodingStructure *&bestCS,
   tempCS->getPredBuf().fill(0);
   AffineMVInfo tmpMVInfo;
   bool isAffMVInfoSaved;
+#if GDR_ENABLED
+  AffineMVInfoSolid tmpMVInfoSolid;
+  m_pcInterSearch->savePrevAffMVInfo(0, tmpMVInfo, tmpMVInfoSolid, isAffMVInfoSaved);
+#else
   m_pcInterSearch->savePrevAffMVInfo(0, tmpMVInfo, isAffMVInfoSaved);
+#endif
   BlkUniMvInfo tmpUniMvInfo;
   bool         isUniMvInfoSaved = false;
   if (!tempCS->slice->isIntra())
@@ -1457,30 +1326,32 @@ void EncCu::xCheckModeSplit(CodingStructure *&tempCS, CodingStructure *&bestCS,
 
     if (isChromaEnabled(tempCS->pcv->chrFormat))
     {
-    partitioner.chType = CHANNEL_TYPE_CHROMA;
-    tempCS->treeType = partitioner.treeType = TREE_C;
-
-    m_CurrCtx++;
-
-    const unsigned wIdx = gp_sizeIdxInfo->idxFrom( partitioner.currArea().lwidth() );
-    const unsigned hIdx = gp_sizeIdxInfo->idxFrom( partitioner.currArea().lheight() );
-    CodingStructure *tempCSChroma = m_pTempCS2[wIdx][hIdx];
-    CodingStructure *bestCSChroma = m_pBestCS2[wIdx][hIdx];
-    tempCS->initSubStructure( *tempCSChroma, partitioner.chType, partitioner.currArea(), false );
-    tempCS->initSubStructure( *bestCSChroma, partitioner.chType, partitioner.currArea(), false );
-    tempCS->treeType = TREE_D;
-    xCompressCU( tempCSChroma, bestCSChroma, partitioner );
-
-    //attach chromaCS to luma CS and update cost
-    bool keepResi = KEEP_PRED_AND_RESI_SIGNALS;
-    //bestCSChroma->treeType = tempCSChroma->treeType = TREE_C;
-    CHECK( bestCSChroma->treeType != TREE_C || tempCSChroma->treeType != TREE_C, "wrong treeType for chroma CS" );
-    tempCS->useSubStructure( *bestCSChroma, partitioner.chType, CS::getArea( *bestCSChroma, partitioner.currArea(), partitioner.chType ), KEEP_PRED_AND_RESI_SIGNALS, true, keepResi, true, true );
-
-    //release tmp resource
-    tempCSChroma->releaseIntermediateData();
-    bestCSChroma->releaseIntermediateData();
-    //tempCS->picture->cs->releaseIntermediateData();
+      partitioner.chType = CHANNEL_TYPE_CHROMA;
+      tempCS->treeType = partitioner.treeType = TREE_C;
+
+      m_CurrCtx++;
+
+      const unsigned   wIdx         = gp_sizeIdxInfo->idxFrom(partitioner.currArea().lwidth());
+      const unsigned   hIdx         = gp_sizeIdxInfo->idxFrom(partitioner.currArea().lheight());
+      CodingStructure *tempCSChroma = m_pTempCS2[wIdx][hIdx];
+      CodingStructure *bestCSChroma = m_pBestCS2[wIdx][hIdx];
+      tempCS->initSubStructure(*tempCSChroma, partitioner.chType, partitioner.currArea(), false);
+      tempCS->initSubStructure(*bestCSChroma, partitioner.chType, partitioner.currArea(), false);
+      tempCS->treeType = TREE_D;
+      xCompressCU(tempCSChroma, bestCSChroma, partitioner);
+
+      // attach chromaCS to luma CS and update cost
+      bool keepResi = KEEP_PRED_AND_RESI_SIGNALS;
+      // bestCSChroma->treeType = tempCSChroma->treeType = TREE_C;
+      CHECK(bestCSChroma->treeType != TREE_C || tempCSChroma->treeType != TREE_C, "wrong treeType for chroma CS");
+      tempCS->useSubStructure(*bestCSChroma, partitioner.chType,
+                              CS::getArea(*bestCSChroma, partitioner.currArea(), partitioner.chType),
+                              KEEP_PRED_AND_RESI_SIGNALS, true, keepResi, true, true);
+
+      // release tmp resource
+      tempCSChroma->releaseIntermediateData();
+      bestCSChroma->releaseIntermediateData();
+      // tempCS->picture->cs->releaseIntermediateData();
       m_CurrCtx--;
     }
     tempCS->picture->cs->clearCuPuTuIdxMap( partitioner.currArea(), numCuPuTu[0], numCuPuTu[1], numCuPuTu[2], numCuPuTu + 3 );
@@ -1491,6 +1362,13 @@ void EncCu::xCheckModeSplit(CodingStructure *&tempCS, CodingStructure *&bestCS,
     partitioner.treeType = TREE_D;
     partitioner.modeType = MODE_TYPE_ALL;
   }
+  else
+  {
+    if (!qgChromaEnableChildren) // check at deepest cQG level only
+    {
+      xCheckChromaQPOffset( *tempCS, partitioner );
+    }
+  }
 
   // Finally, generate split-signaling bits for RD-cost check
   const PartSplit implicitSplit = partitioner.getImplicitSplit( *tempCS );
@@ -1531,7 +1409,9 @@ void EncCu::xCheckModeSplit(CodingStructure *&tempCS, CodingStructure *&bestCS,
 
   // Check Delta QP bits for splitted structure
   if( !qgEnableChildren ) // check at deepest QG level only
-  xCheckDQP( *tempCS, partitioner, true );
+  {
+    xCheckDQP(*tempCS, partitioner, true);
+  }
 
   // If the configuration being tested exceeds the maximum number of bytes for a slice / slice-segment, then
   // a proper RD evaluation cannot be performed. Therefore, termination of the
@@ -1562,8 +1442,18 @@ void EncCu::xCheckModeSplit(CodingStructure *&tempCS, CodingStructure *&bestCS,
   // RD check for sub partitioned coding structure.
   xCheckBestMode( tempCS, bestCS, partitioner, encTestMode );
 
+#if GDR_ENABLED
+  if (isAffMVInfoSaved)
+  {
+    m_pcInterSearch->addAffMVInfo(tmpMVInfo, tmpMVInfoSolid);
+  }
+#else
   if (isAffMVInfoSaved)
+  {
     m_pcInterSearch->addAffMVInfo(tmpMVInfo);
+  }
+#endif
+
   if (!tempCS->slice->isIntra() && isUniMvInfoSaved)
   {
     m_pcInterSearch->addUniMvInfo(tmpUniMvInfo);
@@ -1832,7 +1722,10 @@ bool EncCu::xCheckRDCostIntra(CodingStructure *&tempCS, CodingStructure *&bestCS
             m_modeCtrl->setBestCostWithoutSplitFlags( tmpCostWithoutSplitFlags );
           }
 
-          if( !mtsFlag ) static_cast< double& >( costSize2Nx2NmtsFirstPass ) = tempCS->cost;
+          if (!mtsFlag)
+          {
+            static_cast<double &>(costSize2Nx2NmtsFirstPass) = tempCS->cost;
+          }
 
           if( sps.getUseLFNST() && !tempCS->cus.empty() )
           {
@@ -1938,7 +1831,9 @@ bool EncCu::xCheckRDCostIntra(CodingStructure *&tempCS, CodingStructure *&bestCS
     }
   } //trGrpIdx
   if(!adaptiveColorTrans)
-  m_modeCtrl->setBestNonDCT2Cost(bestNonDCT2Cost);
+  {
+    m_modeCtrl->setBestNonDCT2Cost(bestNonDCT2Cost);
+  }
   return foundZeroRootCbf;
 }
 
@@ -1946,7 +1841,7 @@ bool EncCu::xCheckRDCostIntra(CodingStructure *&tempCS, CodingStructure *&bestCS
 void EncCu::xCheckPLT(CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &partitioner, const EncTestMode& encTestMode)
 {
   if (((partitioner.currArea().lumaSize().width * partitioner.currArea().lumaSize().height <= 16) && (isLuma(partitioner.chType)) )
-        || ((partitioner.currArea().chromaSize().width * partitioner.currArea().chromaSize().height <= 16) && (!isLuma(partitioner.chType)) && partitioner.isSepTree(*tempCS) ) 
+        || ((partitioner.currArea().chromaSize().width * partitioner.currArea().chromaSize().height <= 16) && (!isLuma(partitioner.chType)) && partitioner.isSepTree(*tempCS) )
       || (partitioner.isLocalSepTree(*tempCS)  && (!isLuma(partitioner.chType))  )  )
   {
     return;
@@ -2087,7 +1982,10 @@ void EncCu::xCheckDQP( CodingStructure& cs, Partitioner& partitioner, bool bKeep
   if( hasResidual )
   {
     TempCtx ctxTemp( m_CtxCache );
-    if( !bKeepCtx ) ctxTemp = SubCtx( Ctx::DeltaQP, m_CABACEstimator->getCtx() );
+    if (!bKeepCtx)
+    {
+      ctxTemp = SubCtx(Ctx::DeltaQP, m_CABACEstimator->getCtx());
+    }
 
     m_CABACEstimator->resetBits();
     m_CABACEstimator->cu_qp_delta( *cuFirst, predQP, cuFirst->qp );
@@ -2095,8 +1993,10 @@ void EncCu::xCheckDQP( CodingStructure& cs, Partitioner& partitioner, bool bKeep
     cs.fracBits += m_CABACEstimator->getEstFracBits(); // dQP bits
     cs.cost      = m_pcRdCost->calcRdCost(cs.fracBits, cs.dist);
 
-
-    if( !bKeepCtx ) m_CABACEstimator->getCtx() = SubCtx( Ctx::DeltaQP, ctxTemp );
+    if (!bKeepCtx)
+    {
+      m_CABACEstimator->getCtx() = SubCtx(Ctx::DeltaQP, ctxTemp);
+    }
 
     // NOTE: reset QPs for CUs without residuals up to first coded CU
     for( const auto &cu : cs.cus )
@@ -2133,74 +2033,50 @@ void EncCu::xCheckChromaQPOffset( CodingStructure& cs, Partitioner& partitioner
     return;
   }
 
-  // not needed after the first coded TU in the chroma QG
+  // check cost only at cQG top-level (everything below shall not be influenced by adj coding: it occurs only once)
   if( !partitioner.currQgChromaEnable() )
   {
     return;
   }
 
-  CodingUnit& cu = *cs.getCU( partitioner.chType );
-
   // check if chroma is coded or not
-  bool hasResidual = false;
-  for( const TransformUnit &tu : CU::traverseTUs(cu) )
-  {
-    if( tu.cbf[COMPONENT_Cb] || tu.cbf[COMPONENT_Cr] )
-    {
-      hasResidual = true;
-      break;
-    }
-  }
-
-  if( hasResidual )
-  {
-    // estimate cost for coding cu_chroma_qp_offset
-    TempCtx ctxTempAdjFlag( m_CtxCache );
-    TempCtx ctxTempAdjIdc( m_CtxCache );
-    ctxTempAdjFlag = SubCtx( Ctx::ChromaQpAdjFlag, m_CABACEstimator->getCtx() );
-    ctxTempAdjIdc = SubCtx( Ctx::ChromaQpAdjIdc,   m_CABACEstimator->getCtx() );
-    m_CABACEstimator->resetBits();
-    m_CABACEstimator->cu_chroma_qp_offset( cu );
-    cs.fracBits += m_CABACEstimator->getEstFracBits();
-    cs.cost      = m_pcRdCost->calcRdCost(cs.fracBits, cs.dist);
-    m_CABACEstimator->getCtx() = SubCtx( Ctx::ChromaQpAdjFlag, ctxTempAdjFlag );
-    m_CABACEstimator->getCtx() = SubCtx( Ctx::ChromaQpAdjIdc,  ctxTempAdjIdc  );
-  }
-  else
+  bool isCoded = false;
+  for( auto &cu : cs.cus )
   {
-    // reset chroma QP offset to 0 if it will not be coded
-    cu.chromaQpAdj = 0;
-  }
-}
-
-void EncCu::xFillPCMBuffer( CodingUnit &cu )
-{
-  const ChromaFormat format        = cu.chromaFormat;
-  const uint32_t numberValidComponents = getNumberValidComponents(format);
+    SizeType channelWidth = !cu->isSepTree() ? cu->lwidth() : cu->chromaSize().width;
+    SizeType channelHeight = !cu->isSepTree() ? cu->lheight() : cu->chromaSize().height;
 
-  for( auto &tu : CU::traverseTUs( cu ) )
-  {
-    for( uint32_t ch = 0; ch < numberValidComponents; ch++ )
+    for( const TransformUnit &tu : CU::traverseTUs(*cu) )
     {
-      const ComponentID compID = ComponentID( ch );
-
-      const CompArea &compArea = tu.blocks[ compID ];
-
-      const CPelBuf source      = tu.cs->getOrgBuf( compArea );
-             PelBuf destination = tu.getPcmbuf( compID );
-      if (tu.cs->slice->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag() && compID == COMPONENT_Y)
+      if( tu.cbf[COMPONENT_Cb] || tu.cbf[COMPONENT_Cr] || channelWidth > 64 || channelHeight > 64)
       {
-        CompArea    tmpArea(COMPONENT_Y, compArea.chromaFormat, Position(0, 0), compArea.size());
-        PelBuf tempOrgBuf = m_tmpStorageLCU->getBuf(tmpArea);
-        tempOrgBuf.copyFrom(source);
-        tempOrgBuf.rspSignal(m_pcReshape->getFwdLUT());
-        destination.copyFrom(tempOrgBuf);
+        isCoded = true;
+        break;
       }
-      else
-        destination.copyFrom( source );
+    }
+    if (isCoded)
+    {
+      // estimate cost for coding cu_chroma_qp_offset
+      TempCtx ctxTempAdjFlag( m_CtxCache );
+      TempCtx ctxTempAdjIdc( m_CtxCache );
+      ctxTempAdjFlag = SubCtx( Ctx::ChromaQpAdjFlag, m_CABACEstimator->getCtx() );
+      ctxTempAdjIdc = SubCtx( Ctx::ChromaQpAdjIdc,   m_CABACEstimator->getCtx() );
+      m_CABACEstimator->resetBits();
+      m_CABACEstimator->cu_chroma_qp_offset( *cu );
+      cs.fracBits += m_CABACEstimator->getEstFracBits();
+      cs.cost      = m_pcRdCost->calcRdCost(cs.fracBits, cs.dist);
+      m_CABACEstimator->getCtx() = SubCtx( Ctx::ChromaQpAdjFlag, ctxTempAdjFlag );
+      m_CABACEstimator->getCtx() = SubCtx( Ctx::ChromaQpAdjIdc,  ctxTempAdjIdc  );
+      break;
+    }
+    else
+    {
+      // chroma QP adj is forced to 0 for leading uncoded CUs
+      cu->chromaQpAdj = 0;
     }
   }
 }
+
 void EncCu::xCheckRDCostHashInter( CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &partitioner, const EncTestMode& encTestMode )
 {
   bool isPerfectMatch = false;
@@ -2227,10 +2103,7 @@ void EncCu::xCheckRDCostHashInter( CodingStructure *&tempCS, CodingStructure *&b
 
     m_bestModeUpdated = tempCS->useDbCost = bestCS->useDbCost = false;
 
-    xEncodeInterResidual(tempCS, bestCS, partitioner, encTestMode, 0
-      , 0
-      , &equBcwCost
-    );
+    xEncodeInterResidual(tempCS, bestCS, partitioner, encTestMode, 0, 0, &equBcwCost);
 
     if ( m_bestModeUpdated && bestCS->cost != MAX_DOUBLE )
     {
@@ -2257,6 +2130,10 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *&
   MergeCtx mergeCtx;
   const SPS &sps = *tempCS->sps;
 
+#if GDR_ENABLED
+  bool isEncodeGdrClean = false;
+  CodingStructure *cs;
+#endif
   if (sps.getSbTMVPEnabledFlag())
   {
     Size bufSize = g_miScaling.scale( tempCS->area.lumaSize() );
@@ -2277,11 +2154,13 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *&
     PredictionUnit pu( tempCS->area );
     pu.cu = &cu;
     pu.cs = tempCS;
-    PU::getInterMergeCandidates(pu, mergeCtx
-      , 0
-    );
+    PU::getInterMergeCandidates(pu, mergeCtx, 0);
     PU::getInterMMVDMergeCandidates(pu, mergeCtx);
     pu.regularMergeFlag = true;
+#if GDR_ENABLED
+    cs = pu.cs;
+    isEncodeGdrClean = cs->sps->getGDREnabledFlag() && cs->pcv->isEncoder && ((cs->picHeader->getInGdrInterval() && cs->isClean(pu.Y().topRight(), CHANNEL_TYPE_LUMA)) || (cs->picHeader->getNumVerVirtualBoundaries() == 0));
+#endif
   }
   bool candHasNoResidual[MRG_MAX_NUM_CANDS + MMVD_ADD_NUM];
   for (uint32_t ui = 0; ui < MRG_MAX_NUM_CANDS + MMVD_ADD_NUM; ui++)
@@ -2289,15 +2168,15 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *&
     candHasNoResidual[ui] = false;
   }
 
-  bool                                        bestIsSkip = false;
-  bool                                        bestIsMMVDSkip = true;
-  PelUnitBuf                                  acMergeBuffer[MRG_MAX_NUM_CANDS];
-  PelUnitBuf                                  acMergeTmpBuffer[MRG_MAX_NUM_CANDS];
-  PelUnitBuf                                  acMergeRealBuffer[MMVD_MRG_MAX_RD_BUF_NUM];
-  PelUnitBuf *                                acMergeTempBuffer[MMVD_MRG_MAX_RD_NUM];
-  PelUnitBuf *                                singleMergeTempBuffer;
-  int                                         insertPos;
-  unsigned                                    uiNumMrgSATDCand = mergeCtx.numValidMergeCand + MMVD_ADD_NUM;
+  bool        bestIsSkip     = false;
+  bool        bestIsMMVDSkip = true;
+  PelUnitBuf  acMergeBuffer[MRG_MAX_NUM_CANDS];
+  PelUnitBuf  acMergeTmpBuffer[MRG_MAX_NUM_CANDS];
+  PelUnitBuf  acMergeRealBuffer[MMVD_MRG_MAX_RD_BUF_NUM];
+  PelUnitBuf *acMergeTempBuffer[MMVD_MRG_MAX_RD_NUM];
+  PelUnitBuf *singleMergeTempBuffer;
+  int         insertPos;
+  unsigned    uiNumMrgSATDCand = mergeCtx.numValidMergeCand + MMVD_ADD_NUM;
 
   struct ModeInfo
   {
@@ -2446,6 +2325,42 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *&
         uint64_t fracBits = m_pcInterSearch->xCalcPuMeBits(pu);
         double cost = (double)uiSad + (double)fracBits * sqrtLambdaForFirstPassIntra;
         insertPos = -1;
+
+#if GDR_ENABLED
+        // Non-RD cost for regular merge
+        if (isEncodeGdrClean)
+        {
+          bool isSolid = true;
+          bool isValid = true;
+
+          if (mergeCtx.mvFieldNeighbours[(uiMergeCand << 1) + 0].refIdx >= 0)
+          {
+            Mv mv = mergeCtx.mvFieldNeighbours[(uiMergeCand << 1) + 0].mv;
+            int ridx = mergeCtx.mvFieldNeighbours[(uiMergeCand << 1) + 0].refIdx;
+
+            mergeCtx.mvValid[(uiMergeCand << 1) + 0] = cs->isClean(pu.Y().bottomRight(), mv, REF_PIC_LIST_0, ridx);
+
+            isSolid = isSolid && mergeCtx.mvSolid[(uiMergeCand << 1) + 0];
+            isValid = isValid && mergeCtx.mvValid[(uiMergeCand << 1) + 0];
+          }
+
+          if (mergeCtx.mvFieldNeighbours[(uiMergeCand << 1) + 1].refIdx >= 0) \
+          {
+            Mv mv = mergeCtx.mvFieldNeighbours[(uiMergeCand << 1) + 1].mv;
+            int ridx = mergeCtx.mvFieldNeighbours[(uiMergeCand << 1) + 1].refIdx;
+
+            mergeCtx.mvValid[(uiMergeCand << 1) + 1] = cs->isClean(pu.Y().bottomRight(), mv, REF_PIC_LIST_1, ridx);
+
+            isSolid = isSolid && mergeCtx.mvSolid[(uiMergeCand << 1) + 1];
+            isValid = isValid && mergeCtx.mvValid[(uiMergeCand << 1) + 1];
+          }
+
+          if (!isValid || !isSolid)
+          {
+            cost = MAX_DOUBLE;
+          }
+        }
+#endif
         updateCandList(ModeInfo(uiMergeCand, true, false, false), cost, RdModeList, candCostList, uiNumMrgSATDCand, &insertPos);
         if (insertPos != -1)
         {
@@ -2462,7 +2377,9 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *&
             swap(singleMergeTempBuffer, acMergeTempBuffer[insertPos]);
           }
         }
+#if !GDR_ENABLED
         CHECK(std::min(uiMergeCand + 1, uiNumMrgSATDCand) != RdModeList.size(), "");
+#endif
       }
 
       if (isIntrainterEnabled)
@@ -2516,6 +2433,42 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *&
           pu.regularMergeFlag = false;
           uint64_t fracBits = m_pcInterSearch->xCalcPuMeBits(pu);
           double cost = (double)sadValue + (double)fracBits * sqrtLambdaForFirstPassIntra;
+#if GDR_ENABLED
+          // Non-RD cost for CIIP merge
+          if (isEncodeGdrClean)
+          {
+            bool isSolid = true;
+            bool isValid = true;
+
+            if (mergeCtx.mvFieldNeighbours[(mergeCand << 1) + 0].refIdx >= 0)
+            {
+              Mv mv = mergeCtx.mvFieldNeighbours[(mergeCand << 1) + 0].mv;
+              int ridx = mergeCtx.mvFieldNeighbours[(mergeCand << 1) + 0].refIdx;
+
+              mergeCtx.mvValid[(mergeCand << 1) + 0] = cs->isClean(pu.Y().bottomRight(), mv, REF_PIC_LIST_0, ridx);
+
+              isSolid = isSolid && mergeCtx.mvSolid[(mergeCand << 1) + 0];
+              isValid = isValid && mergeCtx.mvValid[(mergeCand << 1) + 0];
+            }
+
+            if (mergeCtx.mvFieldNeighbours[(mergeCand << 1) + 1].refIdx >= 0)
+            {
+              Mv mv = mergeCtx.mvFieldNeighbours[(mergeCand << 1) + 1].mv;
+              int ridx = mergeCtx.mvFieldNeighbours[(mergeCand << 1) + 1].refIdx;
+
+              mergeCtx.mvValid[(mergeCand << 1) + 1] = cs->isClean(pu.Y().bottomRight(), mv, REF_PIC_LIST_1, ridx);
+
+              isSolid = isSolid && mergeCtx.mvSolid[(mergeCand << 1) + 1];
+              isValid = isValid && mergeCtx.mvValid[(mergeCand << 1) + 1];
+            }
+
+            if (!isValid || !isSolid)
+            {
+              cost = MAX_DOUBLE;
+            }
+          }
+#endif
+
           insertPos = -1;
           updateCandList(ModeInfo(mergeCand, false, false, true), cost, RdModeList, candCostList, uiNumMrgSATDCand, &insertPos);
           if (insertPos != -1)
@@ -2539,7 +2492,19 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *&
           int baseIdx = mmvdMergeCand / MMVD_MAX_REFINE_NUM;
           int refineStep = (mmvdMergeCand - (baseIdx * MMVD_MAX_REFINE_NUM)) / 4;
           if (refineStep >= m_pcEncCfg->getMmvdDisNum())
+          {
             continue;
+          }
+#if GDR_ENABLED
+          if (isEncodeGdrClean)
+          {
+            pu.mvSolid[REF_PIC_LIST_0] = true;
+            pu.mvSolid[REF_PIC_LIST_1] = true;
+
+            pu.mvValid[REF_PIC_LIST_0] = true;
+            pu.mvValid[REF_PIC_LIST_1] = true;
+          }
+#endif
           mergeCtx.setMmvdMergeCandiInfo(pu, mmvdMergeCand);
 
           PU::spanMotionInfo(pu, mergeCtx);
@@ -2557,6 +2522,31 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *&
           uint64_t fracBits = m_pcInterSearch->xCalcPuMeBits(pu);
           double cost = (double)uiSad + (double)fracBits * sqrtLambdaForFirstPassIntra;
           insertPos = -1;
+
+#if GDR_ENABLED
+          if (isEncodeGdrClean)
+          {
+            bool isSolid = true;
+            bool isValid = true;
+
+            if (pu.refIdx[0] >= 0)
+            {
+              isSolid = isSolid && pu.mvSolid[0];
+              isValid = isValid && pu.mvValid[0];
+            }
+
+            if (pu.refIdx[1] >= 0)
+            {
+              isSolid = isSolid && pu.mvSolid[1];
+              isValid = isValid && pu.mvValid[1];
+            }
+
+            if (!isSolid || !isValid)
+            {
+              cost = MAX_DOUBLE;
+            }
+          }
+#endif
           updateCandList(ModeInfo(mmvdMergeCand, false, true, false), cost, RdModeList, candCostList, uiNumMrgSATDCand, &insertPos);
           if (insertPos != -1)
           {
@@ -2590,7 +2580,9 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *&
             pu.intraDir[0] = PLANAR_IDX;
             pu.intraDir[1] = DM_CHROMA_IDX;
             if (pu.chromaSize().width == 2)
+            {
               continue;
+            }
             uint32_t bufIdx = 0;
             m_pcIntraSearch->initIntraPatternChType(*pu.cu, pu.Cb());
             m_pcIntraSearch->predIntraAng(COMPONENT_Cb, pu.cs->getPredBuf(pu).Cb(), pu);
@@ -2723,22 +2715,24 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *&
           m_pcIntraSearch->geneWeightedPred(COMPONENT_Y, tmpBuf, pu, m_pcIntraSearch->getPredictorPtr2(COMPONENT_Y, bufIdx));
           if (isChromaEnabled(pu.chromaFormat))
           {
-          if (pu.chromaSize().width > 2)
-          {
-          tmpBuf = tempCS->getPredBuf(pu).Cb();
-          tmpBuf.copyFrom(acMergeTmpBuffer[uiMergeCand].Cb());
-          m_pcIntraSearch->geneWeightedPred(COMPONENT_Cb, tmpBuf, pu, m_pcIntraSearch->getPredictorPtr2(COMPONENT_Cb, bufIdx));
-          tmpBuf = tempCS->getPredBuf(pu).Cr();
-          tmpBuf.copyFrom(acMergeTmpBuffer[uiMergeCand].Cr());
-          m_pcIntraSearch->geneWeightedPred(COMPONENT_Cr, tmpBuf, pu, m_pcIntraSearch->getPredictorPtr2(COMPONENT_Cr, bufIdx));
-          }
-          else
-          {
-            tmpBuf = tempCS->getPredBuf(pu).Cb();
-            tmpBuf.copyFrom(acMergeTmpBuffer[uiMergeCand].Cb());
-            tmpBuf = tempCS->getPredBuf(pu).Cr();
-            tmpBuf.copyFrom(acMergeTmpBuffer[uiMergeCand].Cr());
-          }
+            if (pu.chromaSize().width > 2)
+            {
+              tmpBuf = tempCS->getPredBuf(pu).Cb();
+              tmpBuf.copyFrom(acMergeTmpBuffer[uiMergeCand].Cb());
+              m_pcIntraSearch->geneWeightedPred(COMPONENT_Cb, tmpBuf, pu,
+                                                m_pcIntraSearch->getPredictorPtr2(COMPONENT_Cb, bufIdx));
+              tmpBuf = tempCS->getPredBuf(pu).Cr();
+              tmpBuf.copyFrom(acMergeTmpBuffer[uiMergeCand].Cr());
+              m_pcIntraSearch->geneWeightedPred(COMPONENT_Cr, tmpBuf, pu,
+                                                m_pcIntraSearch->getPredictorPtr2(COMPONENT_Cr, bufIdx));
+            }
+            else
+            {
+              tmpBuf = tempCS->getPredBuf(pu).Cb();
+              tmpBuf.copyFrom(acMergeTmpBuffer[uiMergeCand].Cb());
+              tmpBuf = tempCS->getPredBuf(pu).Cr();
+              tmpBuf.copyFrom(acMergeTmpBuffer[uiMergeCand].Cr());
+            }
           }
         }
         else
@@ -2770,7 +2764,36 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *&
         isTestSkipMerge[uiMergeCand] = true;
       }
 
+#if GDR_ENABLED
+      if (isEncodeGdrClean)
+      {
+        bool isSolid = true;
+        bool isValid = true;
+
+        if (pu.refIdx[0] >= 0)
+        {
+          isSolid = isSolid && pu.mvSolid[0];
+          isValid = isValid && pu.mvValid[0];
+        }
+
+        if (pu.refIdx[1] >= 0)
+        {
+          isSolid = isSolid && pu.mvSolid[1];
+          isValid = isValid && pu.mvValid[1];
+        }
+
+        if (isSolid && isValid)
+        {
+          xEncodeInterResidual(tempCS, bestCS, partitioner, encTestMode, uiNoResidualPass, uiNoResidualPass == 0 ? &candHasNoResidual[uiMrgHADIdx] : NULL);
+        }
+      }
+      else
+      {
+        xEncodeInterResidual(tempCS, bestCS, partitioner, encTestMode, uiNoResidualPass, uiNoResidualPass == 0 ? &candHasNoResidual[uiMrgHADIdx] : NULL);
+      }
+#else
       xEncodeInterResidual( tempCS, bestCS, partitioner, encTestMode, uiNoResidualPass, uiNoResidualPass == 0 ? &candHasNoResidual[uiMrgHADIdx] : NULL );
+#endif
 
       if( m_pcEncCfg->getUseFastDecisionForMerge() && !bestIsSkip && !pu.ciipFlag)
       {
@@ -2837,6 +2860,7 @@ void EncCu::xCheckRDCostMergeGeo2Nx2N(CodingStructure *&tempCS, CodingStructure
   cu.predMode = MODE_INTER;
   cu.slice = tempCS->slice;
   cu.tileIdx = tempCS->pps->getTileIdx(tempCS->area.lumaPos());
+  cu.chromaQpAdj = m_cuChromaQpOffsetIdxPlus1;
   cu.qp = encTestMode.qp;
   cu.affine = false;
   cu.mtsFlag = false;
@@ -2849,6 +2873,11 @@ void EncCu::xCheckRDCostMergeGeo2Nx2N(CodingStructure *&tempCS, CodingStructure
   cu.bdpcmMode = 0;
 
   PredictionUnit &pu = tempCS->addPU(cu, pm.chType);
+#if GDR_ENABLED
+  CodingStructure &cs = *pu.cs;
+  const bool isEncodeGdrClean = cs.sps->getGDREnabledFlag() && cs.pcv->isEncoder && ((cs.picHeader->getInGdrInterval() && cs.isClean(pu.Y().topRight(), CHANNEL_TYPE_LUMA)) || (cs.picHeader->getNumVerVirtualBoundaries() == 0));
+#endif
+
   pu.mergeFlag = true;
   pu.regularMergeFlag = false;
   PU::getGeoMergeCandidates(pu, mergeCtx);
@@ -2867,16 +2896,27 @@ void EncCu::xCheckRDCostMergeGeo2Nx2N(CodingStructure *&tempCS, CodingStructure
   m_pcRdCost->setDistParam(distParamWholeBlk, tempCS->getOrgBuf().Y(), m_acMergeBuffer[0].Y().buf, m_acMergeBuffer[0].Y().stride, sps.getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y);
   Distortion bestWholeBlkSad = MAX_UINT64;
   double bestWholeBlkCost = MAX_DOUBLE;
-  Distortion *sadWholeBlk;
-  sadWholeBlk = new Distortion[maxNumMergeCandidates];
-  int *pocMrg;
-  Mv *MrgMv;
-  bool *isSkipThisCand;
-  pocMrg = new int[maxNumMergeCandidates];
-  MrgMv = new Mv[maxNumMergeCandidates];
-  isSkipThisCand = new bool[maxNumMergeCandidates];
+  Distortion sadWholeBlk[GEO_MAX_NUM_UNI_CANDS];
+  int        pocMrg[GEO_MAX_NUM_UNI_CANDS];
+  Mv         MrgMv[GEO_MAX_NUM_UNI_CANDS];
+  bool       isSkipThisCand[GEO_MAX_NUM_UNI_CANDS];
+#if GDR_ENABLED
+  bool MrgSolid[GEO_MAX_NUM_UNI_CANDS];
+  bool MrgValid[GEO_MAX_NUM_UNI_CANDS];
+
+  if (isEncodeGdrClean)
+  {
+    for (int i = 0; i < maxNumMergeCandidates; i++)
+    {
+      MrgSolid[i] = true;
+      MrgValid[i] = true;
+    }
+  }
+#endif
   for (int i = 0; i < maxNumMergeCandidates; i++)
+  {
     isSkipThisCand[i] = false;
+  }
   for (uint8_t mergeCand = 0; mergeCand < maxNumMergeCandidates; mergeCand++)
   {
     geoBuffer[mergeCand] = m_acMergeBuffer[mergeCand].getBuf(localUnitArea);
@@ -2886,6 +2926,13 @@ void EncCu::xCheckRDCostMergeGeo2Nx2N(CodingStructure *&tempCS, CodingStructure
     int MrgrefIdx = mergeCtx.mvFieldNeighbours[(mergeCand << 1) + MrgList].refIdx;
     pocMrg[mergeCand] = tempCS->slice->getRefPic(MrgeRefPicList, MrgrefIdx)->getPOC();
     MrgMv[mergeCand] = mergeCtx.mvFieldNeighbours[(mergeCand << 1) + MrgList].mv;
+#if GDR_ENABLED
+    if (isEncodeGdrClean)
+    {
+      MrgSolid[mergeCand] = mergeCtx.mvSolid[(mergeCand << 1) + MrgList];
+      MrgValid[mergeCand] = mergeCtx.mvValid[(mergeCand << 1) + MrgList];
+    }
+#endif
     if (mergeCand)
     {
       for (int i = 0; i < mergeCand; i++)
@@ -2910,7 +2957,20 @@ void EncCu::xCheckRDCostMergeGeo2Nx2N(CodingStructure *&tempCS, CodingStructure
     distParamWholeBlk.cur.buf = geoTempBuf[mergeCand].Y().buf;
     distParamWholeBlk.cur.stride = geoTempBuf[mergeCand].Y().stride;
     sadWholeBlk[mergeCand] = distParamWholeBlk.distFunc(distParamWholeBlk);
+#if GDR_ENABLED
+    bool allOk = (sadWholeBlk[mergeCand] < bestWholeBlkSad);
+    if (isEncodeGdrClean)
+    {
+      bool isSolid = mergeCtx.mvSolid[(mergeCand << 1) + MrgList];
+      bool isValid = mergeCtx.mvValid[(mergeCand << 1) + MrgList];
+      allOk = allOk && isSolid && isValid;
+    }
+#endif
+#if GDR_ENABLED
+    if (allOk)
+#else
     if (sadWholeBlk[mergeCand] < bestWholeBlkSad)
+#endif
     {
       bestWholeBlkSad = sadWholeBlk[mergeCand];
       int bitsCand = mergeCand + 1;
@@ -2958,18 +3018,46 @@ void EncCu::xCheckRDCostMergeGeo2Nx2N(CodingStructure *&tempCS, CodingStructure
     for (uint8_t mergeCand = 0; mergeCand < maxNumMergeCandidates; mergeCand++)
     {
       int bitsCand = mergeCand + 1;
+#if GDR_ENABLED
+      if (isEncodeGdrClean)
+      {
+        double cost0, cost1;
+
+        m_pcRdCost->setDistParam(distParam, tempCS->getOrgBuf().Y(), geoTempBuf[mergeCand].Y().buf, geoTempBuf[mergeCand].Y().stride, SADmask, maskStride, stepX, maskStride2, sps.getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y);
+        sadLarge = distParam.distFunc(distParam);
+        sadSmall = sadWholeBlk[mergeCand] - sadLarge;
 
+        if (MrgSolid[mergeCand] && MrgValid[mergeCand])
+        {
+          cost0 = (double)sadLarge + (double)bitsCand * sqrtLambdaForFirstPass;
+          cost1 = (double)sadSmall + (double)bitsCand * sqrtLambdaForFirstPass;
+        }
+        else
+        {
+          cost0 = MAX_DOUBLE;
+          cost1 = MAX_DOUBLE;
+        }
+
+        m_GeoCostList.insert(splitDir, 0, mergeCand, cost0);
+        m_GeoCostList.insert(splitDir, 1, mergeCand, cost1);
+      }
+      else
+      {
+        m_pcRdCost->setDistParam(distParam, tempCS->getOrgBuf().Y(), geoTempBuf[mergeCand].Y().buf, geoTempBuf[mergeCand].Y().stride, SADmask, maskStride, stepX, maskStride2, sps.getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y);
+        sadLarge = distParam.distFunc(distParam);
+        m_GeoCostList.insert(splitDir, 0, mergeCand, (double)sadLarge + (double)bitsCand * sqrtLambdaForFirstPass);
+        sadSmall = sadWholeBlk[mergeCand] - sadLarge;
+        m_GeoCostList.insert(splitDir, 1, mergeCand, (double)sadSmall + (double)bitsCand * sqrtLambdaForFirstPass);
+      }
+#else
       m_pcRdCost->setDistParam(distParam, tempCS->getOrgBuf().Y(), geoTempBuf[mergeCand].Y().buf, geoTempBuf[mergeCand].Y().stride, SADmask, maskStride, stepX, maskStride2, sps.getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y);
       sadLarge = distParam.distFunc(distParam);
       m_GeoCostList.insert(splitDir, 0, mergeCand, (double)sadLarge + (double)bitsCand * sqrtLambdaForFirstPass);
       sadSmall = sadWholeBlk[mergeCand] - sadLarge;
       m_GeoCostList.insert(splitDir, 1, mergeCand, (double)sadSmall + (double)bitsCand * sqrtLambdaForFirstPass);
+#endif
     }
   }
-  delete[] sadWholeBlk;
-  delete[] pocMrg;
-  delete[] MrgMv;
-  delete[] isSkipThisCand;
 
   for (int splitDir = 0; splitDir < GEO_NUM_PARTITION_MODE; splitDir++)
   {
@@ -2979,13 +3067,33 @@ void EncCu::xCheckRDCostMergeGeo2Nx2N(CodingStructure *&tempCS, CodingStructure
       unsigned int mergeCand1 = m_GeoModeTest[GeoMotionIdx].m_candIdx1;
       double tempCost = m_GeoCostList.singleDistList[0][splitDir][mergeCand0].cost + m_GeoCostList.singleDistList[1][splitDir][mergeCand1].cost;
       if (tempCost > bestWholeBlkCost)
+      {
         continue;
+      }
       tempCost = tempCost + (double)bitsCandTB * sqrtLambdaForFirstPass;
+#if GDR_ENABLED
+      if (isEncodeGdrClean)
+      {
+        int idx0 = mergeCand0;
+        int idx1 = mergeCand1;
+        bool isSolid0 = mergeCtx.mvSolid[(idx0 << 1) + 0] && mergeCtx.mvSolid[(idx0 << 1) + 1];
+        bool isSolid1 = mergeCtx.mvSolid[(idx1 << 1) + 0] && mergeCtx.mvSolid[(idx1 << 1) + 1];
+        bool isValid0 = mergeCtx.mvValid[(idx0 << 1) + 0] && mergeCtx.mvValid[(idx0 << 1) + 1];
+        bool isValid1 = mergeCtx.mvValid[(idx1 << 1) + 0] && mergeCtx.mvValid[(idx1 << 1) + 1];
+
+        if (!isSolid0 || !isSolid1 || !isValid0 || !isValid1)
+        {
+          tempCost = MAX_DOUBLE;
+        }
+      }
+#endif
       comboList.list.push_back(GeoMergeCombo(splitDir, mergeCand0, mergeCand1, tempCost));
     }
   }
   if (comboList.list.empty())
+  {
     return;
+  }
   comboList.sortByCost();
   bool geocandHasNoResidual[GEO_MAX_TRY_WEIGHTED_SAD];
   for (int mergeCand = 0; mergeCand < GEO_MAX_TRY_WEIGHTED_SAD; mergeCand++)
@@ -3017,6 +3125,22 @@ void EncCu::xCheckRDCostMergeGeo2Nx2N(CodingStructure *&tempCS, CodingStructure
     mvBits += mergeCand0;
     mvBits += mergeCand1;
     double updateCost = (double)sad + (double)(bitsCandTB + mvBits) * sqrtLambdaForFirstPass;
+#if GDR_ENABLED
+    if (isEncodeGdrClean)
+    {
+      int idx0 = mergeCand0;
+      int idx1 = mergeCand1;
+      bool isSolid0 = mergeCtx.mvSolid[(idx0 << 1) + 0] && mergeCtx.mvSolid[(idx0 << 1) + 1];
+      bool isSolid1 = mergeCtx.mvSolid[(idx1 << 1) + 0] && mergeCtx.mvSolid[(idx1 << 1) + 1];
+      bool isValid0 = mergeCtx.mvValid[(idx0 << 1) + 0] && mergeCtx.mvValid[(idx0 << 1) + 1];
+      bool isValid1 = mergeCtx.mvValid[(idx1 << 1) + 0] && mergeCtx.mvValid[(idx1 << 1) + 1];
+
+      if (!isSolid0 || !isSolid1 || !isValid0 || !isValid1)
+      {
+        updateCost = MAX_DOUBLE;
+      }
+    }
+#endif
     comboList.list[candidateIdx].cost = updateCost;
     updateCandList(candidateIdx, updateCost, geoRdModeList, geocandCostList, geoNumMrgSATDCand);
   }
@@ -3058,6 +3182,7 @@ void EncCu::xCheckRDCostMergeGeo2Nx2N(CodingStructure *&tempCS, CodingStructure
       cu.predMode = MODE_INTER;
       cu.slice = tempCS->slice;
       cu.tileIdx = tempCS->pps->getTileIdx(tempCS->area.lumaPos());
+      cu.chromaQpAdj = m_cuChromaQpOffsetIdxPlus1;
       cu.qp = encTestMode.qp;
       cu.affine = false;
       cu.mtsFlag = false;
@@ -3080,7 +3205,28 @@ void EncCu::xCheckRDCostMergeGeo2Nx2N(CodingStructure *&tempCS, CodingStructure
       PU::spanGeoMotionInfo(pu, mergeCtx, pu.geoSplitDir, pu.geoMergeIdx0, pu.geoMergeIdx1);
       tempCS->getPredBuf().copyFrom(geoCombinations[candidateIdx]);
 
+#if GDR_ENABLED
+      if (isEncodeGdrClean)
+      {
+        int idx0 = pu.geoMergeIdx0;
+        int idx1 = pu.geoMergeIdx1;
+        bool isSolid0 = mergeCtx.mvSolid[(idx0 << 1) + 0] && mergeCtx.mvSolid[(idx0 << 1) + 1];
+        bool isSolid1 = mergeCtx.mvSolid[(idx1 << 1) + 0] && mergeCtx.mvSolid[(idx1 << 1) + 1];
+        bool isValid0 = mergeCtx.mvValid[(idx0 << 1) + 0] && mergeCtx.mvValid[(idx0 << 1) + 1];
+        bool isValid1 = mergeCtx.mvValid[(idx1 << 1) + 0] && mergeCtx.mvValid[(idx1 << 1) + 1];
+
+        if (isSolid0 && isSolid1 && isValid0 && isValid1)
+        {
+          xEncodeInterResidual(tempCS, bestCS, pm, encTestMode, noResidualPass, (noResidualPass == 0 ? &geocandHasNoResidual[candidateIdx] : NULL));
+        }
+      }
+      else
+      {
+        xEncodeInterResidual(tempCS, bestCS, pm, encTestMode, noResidualPass, (noResidualPass == 0 ? &geocandHasNoResidual[candidateIdx] : NULL));
+      }
+#else
       xEncodeInterResidual(tempCS, bestCS, pm, encTestMode, noResidualPass, (noResidualPass == 0 ? &geocandHasNoResidual[candidateIdx] : NULL));
+#endif
 
       if (m_pcEncCfg->getUseFastDecisionForMerge() && !bestIsSkip)
       {
@@ -3106,6 +3252,10 @@ void EncCu::xCheckRDCostAffineMerge2Nx2N( CodingStructure *&tempCS, CodingStruct
   {
     return;
   }
+#if GDR_ENABLED
+  CodingStructure *cs;
+  bool isEncodeGdrClean = false;
+#endif
   m_bestModeUpdated = tempCS->useDbCost = bestCS->useDbCost = false;
   const Slice &slice = *tempCS->slice;
 
@@ -3143,6 +3293,10 @@ void EncCu::xCheckRDCostAffineMerge2Nx2N( CodingStructure *&tempCS, CodingStruct
     pu.cu = &cu;
     pu.cs = tempCS;
     pu.regularMergeFlag = false;
+#if GDR_ENABLED
+    cs = pu.cs;
+    isEncodeGdrClean = cs->sps->getGDREnabledFlag() && cs->pcv->isEncoder && ((cs->picHeader->getInGdrInterval() && cs->isClean(pu.Y().topRight(), CHANNEL_TYPE_LUMA)) || (cs->picHeader->getNumVerVirtualBoundaries() == 0));
+#endif
     PU::getAffineMergeCand( pu, affineMergeCtx );
 
     if ( affineMergeCtx.numValidMergeCand <= 0 )
@@ -3233,6 +3387,19 @@ void EncCu::xCheckRDCostAffineMerge2Nx2N( CodingStructure *&tempCS, CodingStruct
           PU::spanMotionInfo( pu );
         }
 
+#if GDR_ENABLED
+        if (isEncodeGdrClean)
+        {
+          Mv zero = Mv(0, 0);
+          bool isValid = cs->isSubPuClean(pu, &zero);
+          affineMergeCtx.mvValid[(uiMergeCand << 1) + 0][0] = isValid;
+          affineMergeCtx.mvValid[(uiMergeCand << 1) + 0][1] = isValid;
+          affineMergeCtx.mvValid[(uiMergeCand << 1) + 0][2] = isValid;
+          affineMergeCtx.mvValid[(uiMergeCand << 1) + 1][0] = isValid;
+          affineMergeCtx.mvValid[(uiMergeCand << 1) + 1][1] = isValid;
+          affineMergeCtx.mvValid[(uiMergeCand << 1) + 1][2] = isValid;
+        }
+#endif
         distParam.cur = acMergeBuffer[uiMergeCand].Y();
 
         m_pcInterSearch->motionCompensation( pu, acMergeBuffer[uiMergeCand], REF_PIC_LIST_X, true, false );
@@ -3244,6 +3411,23 @@ void EncCu::xCheckRDCostAffineMerge2Nx2N( CodingStructure *&tempCS, CodingStruct
           uiBitsCand--;
         }
         double cost = (double)uiSad + (double)uiBitsCand * sqrtLambdaForFirstPass;
+#if GDR_ENABLED
+        if (isEncodeGdrClean)
+        {
+          bool isSolid0 = affineMergeCtx.mvSolid[(uiMergeCand << 1) + 0][0] && affineMergeCtx.mvSolid[(uiMergeCand << 1) + 0][1] && affineMergeCtx.mvSolid[(uiMergeCand << 1) + 0][2];
+          bool isSolid1 = affineMergeCtx.mvSolid[(uiMergeCand << 1) + 1][0] && affineMergeCtx.mvSolid[(uiMergeCand << 1) + 1][1] && affineMergeCtx.mvSolid[(uiMergeCand << 1) + 1][2];
+          bool isValid0 = affineMergeCtx.mvValid[(uiMergeCand << 1) + 0][0] && affineMergeCtx.mvValid[(uiMergeCand << 1) + 0][1] && affineMergeCtx.mvValid[(uiMergeCand << 1) + 0][2];
+          bool isValid1 = affineMergeCtx.mvValid[(uiMergeCand << 1) + 1][0] && affineMergeCtx.mvValid[(uiMergeCand << 1) + 1][1] && affineMergeCtx.mvValid[(uiMergeCand << 1) + 1][2];
+
+          bool isSolid = isSolid0 && isSolid1;
+          bool isValid = isValid0 && isValid1;
+
+          if (!isSolid || !isValid)
+          {
+            cost = MAX_DOUBLE;
+          }
+        }
+#endif
         updateCandList( uiMergeCand, cost, RdModeList, candCostList
           , uiNumMrgSATDCand );
 
@@ -3336,11 +3520,59 @@ void EncCu::xCheckRDCostAffineMerge2Nx2N( CodingStructure *&tempCS, CodingStruct
         m_pcInterSearch->motionCompensation( pu );
       }
 
+#if GDR_ENABLED
+      bool isSolid = true;
+      bool isValid = true;
+
+      if (isEncodeGdrClean)
+      {
+        if (bestIsSkip)
+        {
+          Mv zero = Mv(0, 0);
+          bool isValid = cs->isSubPuClean(pu, &zero);
+          affineMergeCtx.mvValid[(uiMergeCand << 1) + 0][0] = isValid;
+          affineMergeCtx.mvValid[(uiMergeCand << 1) + 0][1] = isValid;
+          affineMergeCtx.mvValid[(uiMergeCand << 1) + 0][2] = isValid;
+          affineMergeCtx.mvValid[(uiMergeCand << 1) + 1][0] = isValid;
+          affineMergeCtx.mvValid[(uiMergeCand << 1) + 1][1] = isValid;
+          affineMergeCtx.mvValid[(uiMergeCand << 1) + 1][2] = isValid;
+        }
+
+        bool isSolid0 = affineMergeCtx.mvSolid[(uiMergeCand << 1) + 0][0] && affineMergeCtx.mvSolid[(uiMergeCand << 1) + 0][1] && affineMergeCtx.mvSolid[(uiMergeCand << 1) + 0][2];
+        bool isSolid1 = affineMergeCtx.mvSolid[(uiMergeCand << 1) + 1][0] && affineMergeCtx.mvSolid[(uiMergeCand << 1) + 1][1] && affineMergeCtx.mvSolid[(uiMergeCand << 1) + 1][2];
+        bool isValid0 = affineMergeCtx.mvValid[(uiMergeCand << 1) + 0][0] && affineMergeCtx.mvValid[(uiMergeCand << 1) + 0][1] && affineMergeCtx.mvValid[(uiMergeCand << 1) + 0][2];
+        bool isValid1 = affineMergeCtx.mvValid[(uiMergeCand << 1) + 1][0] && affineMergeCtx.mvValid[(uiMergeCand << 1) + 1][1] && affineMergeCtx.mvValid[(uiMergeCand << 1) + 1][2];
+
+        isSolid = isSolid0 && isSolid1;
+        isValid = isValid0 && isValid1;
+
+        if (isSolid && isValid)
+        {
+          xEncodeInterResidual(tempCS, bestCS, partitioner, encTestMode, uiNoResidualPass, (uiNoResidualPass == 0 ? &candHasNoResidual[uiMergeCand] : NULL));
+        }
+      }
+      else
+      {
+        xEncodeInterResidual(tempCS, bestCS, partitioner, encTestMode, uiNoResidualPass, (uiNoResidualPass == 0 ? &candHasNoResidual[uiMergeCand] : NULL));
+      }
+#else
       xEncodeInterResidual( tempCS, bestCS, partitioner, encTestMode, uiNoResidualPass, ( uiNoResidualPass == 0 ? &candHasNoResidual[uiMergeCand] : NULL ) );
+#endif
 
       if ( m_pcEncCfg->getUseFastDecisionForMerge() && !bestIsSkip )
       {
-        bestIsSkip = bestCS->getCU( partitioner.chType )->rootCbf == 0;
+#if GDR_ENABLED
+        if (bestCS->getCU(partitioner.chType))
+        {
+          bestIsSkip = bestCS->getCU(partitioner.chType)->rootCbf == 0;
+        }
+        else
+        {
+          bestIsSkip = false;
+        }
+#else
+        bestIsSkip = bestCS->getCU(partitioner.chType)->rootCbf == 0;
+#endif
       }
       tempCS->initStructData( encTestMode.qp );
     }// end loop uiMrgHADIdx
@@ -3401,6 +3633,9 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct
     mergeCtx.subPuMvpMiBuf = MotionBuf(m_SubPuMiBuf, bufSize);
   }
 
+#if GDR_ENABLED
+  bool gdrClean = true;
+#endif
   {
     // first get merge candidates
     CodingUnit cu(tempCS->area);
@@ -3416,7 +3651,15 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct
     pu.regularMergeFlag = false;
     cu.geoFlag = false;
     PU::getIBCMergeCandidates(pu, mergeCtx);
+#if GDR_ENABLED
+    gdrClean = tempCS->isClean(pu.Y().topRight(), CHANNEL_TYPE_LUMA) || tempCS->picHeader->getNumVerVirtualBoundaries() == 0;
+#endif
   }
+#if GDR_ENABLED
+  const bool isEncodeGdrClean = tempCS->sps->getGDREnabledFlag() && tempCS->pcv->isEncoder && tempCS->picHeader->getInGdrInterval() && gdrClean;
+  bool *MrgSolid = nullptr;
+  bool *MrgValid = nullptr;
+#endif
 
   int candHasNoResidual[MRG_MAX_NUM_CANDS];
   for (unsigned int ui = 0; ui < mergeCtx.numValidMergeCand; ui++)
@@ -3424,6 +3667,19 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct
     candHasNoResidual[ui] = 0;
   }
 
+#if GDR_ENABLED
+  if (isEncodeGdrClean)
+  {
+    MrgSolid = new bool[MRG_MAX_NUM_CANDS];
+    MrgValid = new bool[MRG_MAX_NUM_CANDS];
+    for (int i = 0; i < MRG_MAX_NUM_CANDS; i++)
+    {
+      MrgSolid[i] = false;
+      MrgValid[i] = false;
+    }
+  }
+#endif
+
   bool                                        bestIsSkip = false;
   unsigned                                    numMrgSATDCand = mergeCtx.numValidMergeCand;
   static_vector<unsigned, MRG_MAX_NUM_CANDS>  RdModeList(MRG_MAX_NUM_CANDS);
@@ -3432,106 +3688,142 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct
     RdModeList[i] = i;
   }
 
-  //{
-    static_vector<double, MRG_MAX_NUM_CANDS>  candCostList(MRG_MAX_NUM_CANDS, MAX_DOUBLE);
-    // 1. Pass: get SATD-cost for selected candidates and reduce their count
+  static_vector<double, MRG_MAX_NUM_CANDS> candCostList(MRG_MAX_NUM_CANDS, MAX_DOUBLE);
+  // 1. Pass: get SATD-cost for selected candidates and reduce their count
+  {
+    const double sqrtLambdaForFirstPass = m_pcRdCost->getMotionLambda();
+
+    CodingUnit &cu = tempCS->addCU(CS::getArea(*tempCS, tempCS->area, (const ChannelType) partitioner.chType),
+                                   (const ChannelType) partitioner.chType);
+
+    partitioner.setCUData(cu);
+    cu.slice       = tempCS->slice;
+    cu.tileIdx     = tempCS->pps->getTileIdx(tempCS->area.lumaPos());
+    cu.skip        = false;
+    cu.predMode    = MODE_IBC;
+    cu.chromaQpAdj = m_cuChromaQpOffsetIdxPlus1;
+    cu.qp          = encTestMode.qp;
+    cu.mmvdSkip    = false;
+    cu.geoFlag     = false;
+    DistParam       distParam;
+    const bool      bUseHadamard = !cu.slice->getDisableSATDForRD();
+    PredictionUnit &pu           = tempCS->addPU(cu, partitioner.chType);   // tempCS->addPU(cu);
+    pu.mmvdMergeFlag             = false;
+    pu.regularMergeFlag          = false;
+    Picture *     refPic         = pu.cu->slice->getPic();
+    const CPelBuf refBuf         = refPic->getRecoBuf(pu.blocks[COMPONENT_Y]);
+    const Pel *   piRefSrch      = refBuf.buf;
+    if (tempCS->slice->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag())
+    {
+      const CompArea &area = cu.blocks[COMPONENT_Y];
+      CompArea        tmpArea(COMPONENT_Y, area.chromaFormat, Position(0, 0), area.size());
+      PelBuf          tmpLuma = m_tmpStorageLCU->getBuf(tmpArea);
+      tmpLuma.copyFrom(tempCS->getOrgBuf().Y());
+      tmpLuma.rspSignal(m_pcReshape->getFwdLUT());
+      m_pcRdCost->setDistParam(distParam, tmpLuma, refBuf, sps.getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y,
+                               bUseHadamard);
+    }
+    else
     {
-      const double sqrtLambdaForFirstPass = m_pcRdCost->getMotionLambda( );
+      m_pcRdCost->setDistParam(distParam, tempCS->getOrgBuf().Y(), refBuf, sps.getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y, bUseHadamard);
+    }
+    int            refStride = refBuf.stride;
+    const UnitArea localUnitArea(tempCS->area.chromaFormat,
+                                 Area(0, 0, tempCS->area.Y().width, tempCS->area.Y().height));
+    int            numValidBv = mergeCtx.numValidMergeCand;
+    for (unsigned int mergeCand = 0; mergeCand < mergeCtx.numValidMergeCand; mergeCand++)
+    {
+      mergeCtx.setMergeInfo(pu, mergeCand);   // set bv info in merge mode
+      const int          cuPelX    = pu.Y().x;
+      const int          cuPelY    = pu.Y().y;
+      int                roiWidth  = pu.lwidth();
+      int                roiHeight = pu.lheight();
+      const int          picWidth  = pu.cs->slice->getPPS()->getPicWidthInLumaSamples();
+      const int          picHeight = pu.cs->slice->getPPS()->getPicHeightInLumaSamples();
+      const unsigned int lcuWidth  = pu.cs->slice->getSPS()->getMaxCUWidth();
+      int                xPred     = pu.bv.getHor();
+      int                yPred     = pu.bv.getVer();
+
+      if (!m_pcInterSearch->searchBv(pu, cuPelX, cuPelY, roiWidth, roiHeight, picWidth, picHeight, xPred, yPred,
+                                     lcuWidth))   // not valid bv derived
+      {
+        numValidBv--;
+        continue;
+      }
+      PU::spanMotionInfo(pu, mergeCtx);
 
-      CodingUnit &cu = tempCS->addCU(CS::getArea(*tempCS, tempCS->area, (const ChannelType)partitioner.chType), (const ChannelType)partitioner.chType);
+      distParam.cur.buf = piRefSrch + refStride * yPred + xPred;
 
-      partitioner.setCUData(cu);
-      cu.slice = tempCS->slice;
-      cu.tileIdx = tempCS->pps->getTileIdx( tempCS->area.lumaPos() );
-      cu.skip = false;
-      cu.predMode = MODE_IBC;
-      cu.chromaQpAdj = m_cuChromaQpOffsetIdxPlus1;
-      cu.qp = encTestMode.qp;
-      cu.mmvdSkip = false;
-      cu.geoFlag = false;
-      DistParam distParam;
-      const bool bUseHadamard = !cu.slice->getDisableSATDForRD();
-      PredictionUnit &pu = tempCS->addPU(cu, partitioner.chType); //tempCS->addPU(cu);
-      pu.mmvdMergeFlag = false;
-      pu.regularMergeFlag = false;
-      Picture* refPic = pu.cu->slice->getPic();
-      const CPelBuf refBuf = refPic->getRecoBuf(pu.blocks[COMPONENT_Y]);
-      const Pel*        piRefSrch = refBuf.buf;
-      if (tempCS->slice->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag())
-      {
-        const CompArea &area = cu.blocks[COMPONENT_Y];
-        CompArea    tmpArea(COMPONENT_Y, area.chromaFormat, Position(0, 0), area.size());
-        PelBuf tmpLuma = m_tmpStorageLCU->getBuf(tmpArea);
-        tmpLuma.copyFrom(tempCS->getOrgBuf().Y());
-        tmpLuma.rspSignal(m_pcReshape->getFwdLUT());
-        m_pcRdCost->setDistParam(distParam, tmpLuma, refBuf, sps.getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y, bUseHadamard);
+      Distortion   sad      = distParam.distFunc(distParam);
+      unsigned int bitsCand = mergeCand + 1;
+      if (mergeCand == tempCS->sps->getMaxNumMergeCand() - 1)
+      {
+        bitsCand--;
       }
-      else
-      m_pcRdCost->setDistParam(distParam, tempCS->getOrgBuf().Y(), refBuf, sps.getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y, bUseHadamard);
-      int refStride = refBuf.stride;
-      const UnitArea localUnitArea(tempCS->area.chromaFormat, Area(0, 0, tempCS->area.Y().width, tempCS->area.Y().height));
-      int numValidBv = mergeCtx.numValidMergeCand;
-      for (unsigned int mergeCand = 0; mergeCand < mergeCtx.numValidMergeCand; mergeCand++)
-      {
-        mergeCtx.setMergeInfo(pu, mergeCand); // set bv info in merge mode
-        const int cuPelX = pu.Y().x;
-        const int cuPelY = pu.Y().y;
-        int roiWidth = pu.lwidth();
-        int roiHeight = pu.lheight();
-        const int picWidth = pu.cs->slice->getPPS()->getPicWidthInLumaSamples();
-        const int picHeight = pu.cs->slice->getPPS()->getPicHeightInLumaSamples();
-        const unsigned int  lcuWidth = pu.cs->slice->getSPS()->getMaxCUWidth();
-        int xPred = pu.bv.getHor();
-        int yPred = pu.bv.getVer();
-
-        if (!m_pcInterSearch->searchBv(pu, cuPelX, cuPelY, roiWidth, roiHeight, picWidth, picHeight, xPred, yPred, lcuWidth)) // not valid bv derived
+      double cost = (double) sad + (double) bitsCand * sqrtLambdaForFirstPass;
+#if GDR_ENABLED
+      if (isEncodeGdrClean)
+      {
+        bool isSolid = true;
+        bool isValid = true;
+
+        if (mergeCtx.mvFieldNeighbours[(mergeCand << 1) + 0].refIdx >= 0)
         {
-          numValidBv--;
-          continue;
-        }
-        PU::spanMotionInfo(pu, mergeCtx);
+          Mv mv = mergeCtx.mvFieldNeighbours[(mergeCand << 1) + 0].mv;
+          int ridx = mergeCtx.mvFieldNeighbours[(mergeCand << 1) + 0].refIdx;
 
-        distParam.cur.buf = piRefSrch + refStride * yPred + xPred;
+          mergeCtx.mvValid[(mergeCand << 1) + 0] = tempCS->isClean(pu.Y().bottomRight(), mv, REF_PIC_LIST_0, ridx, true);
 
-        Distortion sad = distParam.distFunc(distParam);
-        unsigned int bitsCand = mergeCand + 1;
-        if (mergeCand == tempCS->sps->getMaxNumMergeCand() - 1)
+          isSolid = isSolid && mergeCtx.mvSolid[(mergeCand << 1) + 0];
+          isValid = isValid && mergeCtx.mvValid[(mergeCand << 1) + 0];
+        }
+
+        if (mergeCtx.mvFieldNeighbours[(mergeCand << 1) + 1].refIdx >= 0)
         {
-          bitsCand--;
+          Mv mv = mergeCtx.mvFieldNeighbours[(mergeCand << 1) + 1].mv;
+          int ridx = mergeCtx.mvFieldNeighbours[(mergeCand << 1) + 1].refIdx;
+
+          mergeCtx.mvValid[(mergeCand << 1) + 1] = tempCS->isClean(pu.Y().bottomRight(), mv, REF_PIC_LIST_1, ridx, true);
+
+          isSolid = isSolid && mergeCtx.mvSolid[(mergeCand << 1) + 1];
+          isValid = isValid && mergeCtx.mvValid[(mergeCand << 1) + 1];
         }
-        double cost = (double)sad + (double)bitsCand * sqrtLambdaForFirstPass;
 
-        updateCandList(mergeCand, cost, RdModeList, candCostList
-         , numMrgSATDCand);
+        if (!isValid || !isSolid)
+        {
+          cost = MAX_DOUBLE;
+          numValidBv--;
+        }
       }
+#endif
+      updateCandList(mergeCand, cost, RdModeList, candCostList, numMrgSATDCand);
+    }
 
-      // Try to limit number of candidates using SATD-costs
-      if (numValidBv)
+    // Try to limit number of candidates using SATD-costs
+    if (numValidBv)
+    {
+      numMrgSATDCand = numValidBv;
+      for (unsigned int i = 1; i < numValidBv; i++)
       {
-        numMrgSATDCand = numValidBv;
-        for (unsigned int i = 1; i < numValidBv; i++)
+        if (candCostList[i] > MRG_FAST_RATIO * candCostList[0])
         {
-          if (candCostList[i] > MRG_FAST_RATIO*candCostList[0])
-          {
-            numMrgSATDCand = i;
-            break;
-          }
+          numMrgSATDCand = i;
+          break;
         }
       }
-      else
-      {
-        tempCS->dist = 0;
-        tempCS->fracBits = 0;
-        tempCS->cost = MAX_DOUBLE;
-        tempCS->costDbOffset = 0;
-        tempCS->initStructData(encTestMode.qp);
-        return;
-      }
-
+    }
+    else
+    {
+      tempCS->dist         = 0;
+      tempCS->fracBits     = 0;
+      tempCS->cost         = MAX_DOUBLE;
+      tempCS->costDbOffset = 0;
       tempCS->initStructData(encTestMode.qp);
+      return;
     }
-  //}
 
+    tempCS->initStructData(encTestMode.qp);
+  }
 
   const unsigned int iteration = 2;
   m_bestModeUpdated = tempCS->useDbCost = bestCS->useDbCost = false;
@@ -3546,7 +3838,6 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct
         if (!(bestIsSkip && (numResidualPass == 0)))
         {
           {
-
             // first get merge candidates
             CodingUnit &cu = tempCS->addCU(CS::getArea(*tempCS, tempCS->area, (const ChannelType)partitioner.chType), (const ChannelType)partitioner.chType);
 
@@ -3571,12 +3862,62 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct
 
             assert(mergeCtx.mrgTypeNeighbours[mergeCand] == MRG_TYPE_IBC); //  should be IBC candidate at this round
             const bool chroma = !pu.cu->isSepTree();
+#if GDR_ENABLED
+            // redo validation again for Skip
+            {
+              CodingStructure &cs = *pu.cs;
+
+              if (isEncodeGdrClean)
+              {
+                if (mergeCtx.mvFieldNeighbours[(mergeCand << 1) + 0].refIdx >= 0)
+                {
+                  Mv mv = mergeCtx.mvFieldNeighbours[(mergeCand << 1) + 0].mv;
+                  int ridx = mergeCtx.mvFieldNeighbours[(mergeCand << 1) + 0].refIdx;
+
+                  mergeCtx.mvValid[(mergeCand << 1) + 0] = cs.isClean(pu.Y().bottomRight(), mv, REF_PIC_LIST_0, ridx, true);
+                }
 
+                if (mergeCtx.mvFieldNeighbours[(mergeCand << 1) + 1].refIdx >= 0)
+                {
+                  Mv mv = mergeCtx.mvFieldNeighbours[(mergeCand << 1) + 1].mv;
+                  int ridx = mergeCtx.mvFieldNeighbours[(mergeCand << 1) + 1].refIdx;
+                  mergeCtx.mvValid[(mergeCand << 1) + 1] = cs.isClean(pu.Y().bottomRight(), mv, REF_PIC_LIST_1, ridx, true);
+                }
+              }
+            }
+#endif
             //  MC
             m_pcInterSearch->motionCompensation(pu,REF_PIC_LIST_0, true, chroma);
             m_CABACEstimator->getCtx() = m_CurrCtx->start;
 
+#if GDR_ENABLED
+            if (isEncodeGdrClean)
+            {
+              bool mvSolid = true;
+              bool mvValid = true;
+              if (mergeCtx.mvFieldNeighbours[(mergeCand << 1) + 0].refIdx >= 0)
+              {
+                mvSolid = mvSolid && mergeCtx.mvSolid[(mergeCand << 1) + 0];
+                mvValid = mvValid && mergeCtx.mvValid[(mergeCand << 1) + 0];
+              }
+              if (mergeCtx.mvFieldNeighbours[(mergeCand << 1) + 1].refIdx >= 0)
+              {
+                mvSolid = mvSolid && mergeCtx.mvSolid[(mergeCand << 1) + 1];
+                mvValid = mvValid && mergeCtx.mvValid[(mergeCand << 1) + 1];
+              }
+
+              if (mvSolid && mvValid)
+              {
+                m_pcInterSearch->encodeResAndCalcRdInterCU(*tempCS, partitioner, (numResidualPass != 0), true, chroma);
+              }
+            }
+            else
+            {
+              m_pcInterSearch->encodeResAndCalcRdInterCU(*tempCS, partitioner, (numResidualPass != 0), true, chroma);
+            }
+#else
             m_pcInterSearch->encodeResAndCalcRdInterCU(*tempCS, partitioner, (numResidualPass != 0), true, chroma);
+#endif
             if (tempCS->slice->getSPS()->getUseColorTrans())
             {
               bestCS->tmpColorSpaceCost = tempCS->tmpColorSpaceCost;
@@ -3602,13 +3943,17 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct
             tempCS->initStructData(encTestMode.qp);
           }
 
-            if (m_pcEncCfg->getUseFastDecisionForMerge() && !bestIsSkip)
+          if (m_pcEncCfg->getUseFastDecisionForMerge() && !bestIsSkip)
+          {
+            if (bestCS->getCU(partitioner.chType) == NULL)
+            {
+              bestIsSkip = 0;
+            }
+            else
             {
-              if (bestCS->getCU(partitioner.chType) == NULL)
-                bestIsSkip = 0;
-              else
               bestIsSkip = bestCS->getCU(partitioner.chType)->rootCbf == 0;
             }
+          }
         }
       }
     }
@@ -3617,6 +3962,13 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct
   {
     xCalDebCost( *bestCS, partitioner );
   }
+#if GDR_ENABLED
+  if (isEncodeGdrClean)
+  {
+    delete[] MrgSolid;
+    delete[] MrgValid;
+  }
+#endif
 }
 
 void EncCu::xCheckRDCostIBCMode(CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &partitioner, const EncTestMode& encTestMode)
@@ -3626,86 +3978,82 @@ void EncCu::xCheckRDCostIBCMode(CodingStructure *&tempCS, CodingStructure *&best
     return;
   }
 
-    tempCS->initStructData(encTestMode.qp);
-
-    m_bestModeUpdated = tempCS->useDbCost = bestCS->useDbCost = false;
+  tempCS->initStructData(encTestMode.qp);
 
-    CodingUnit &cu = tempCS->addCU(CS::getArea(*tempCS, tempCS->area, partitioner.chType), partitioner.chType);
+  m_bestModeUpdated = tempCS->useDbCost = bestCS->useDbCost = false;
 
-    partitioner.setCUData(cu);
-    cu.slice = tempCS->slice;
-    cu.tileIdx = tempCS->pps->getTileIdx( tempCS->area.lumaPos() );
-    cu.skip = false;
-    cu.predMode = MODE_IBC;
-    cu.chromaQpAdj = m_cuChromaQpOffsetIdxPlus1;
-    cu.qp = encTestMode.qp;
-    cu.imv = 0;
-    cu.sbtInfo = 0;
+  CodingUnit &cu = tempCS->addCU(CS::getArea(*tempCS, tempCS->area, partitioner.chType), partitioner.chType);
 
-    CU::addPUs(cu);
+  partitioner.setCUData(cu);
+  cu.slice       = tempCS->slice;
+  cu.tileIdx     = tempCS->pps->getTileIdx(tempCS->area.lumaPos());
+  cu.skip        = false;
+  cu.predMode    = MODE_IBC;
+  cu.chromaQpAdj = m_cuChromaQpOffsetIdxPlus1;
+  cu.qp          = encTestMode.qp;
+  cu.imv         = 0;
+  cu.sbtInfo     = 0;
 
-    m_bestModeUpdated = tempCS->useDbCost = bestCS->useDbCost = false;
+  CU::addPUs(cu);
 
-    PredictionUnit& pu = *cu.firstPU;
-    cu.mmvdSkip = false;
-    pu.mmvdMergeFlag = false;
-    pu.regularMergeFlag = false;
+  m_bestModeUpdated = tempCS->useDbCost = bestCS->useDbCost = false;
 
-    pu.intraDir[0] = DC_IDX; // set intra pred for ibc block
-    pu.intraDir[1] = PLANAR_IDX; // set intra pred for ibc block
+  PredictionUnit &pu  = *cu.firstPU;
+  cu.mmvdSkip         = false;
+  pu.mmvdMergeFlag    = false;
+  pu.regularMergeFlag = false;
 
-    pu.interDir = 1; // use list 0 for IBC mode
-    pu.refIdx[REF_PIC_LIST_0] = MAX_NUM_REF; // last idx in the list
-      bool bValid = m_pcInterSearch->predIBCSearch(cu, partitioner, m_ctuIbcSearchRangeX, m_ctuIbcSearchRangeY, m_ibcHashMap);
+  pu.intraDir[0] = DC_IDX;       // set intra pred for ibc block
+  pu.intraDir[1] = PLANAR_IDX;   // set intra pred for ibc block
 
-      if (bValid)
-      {
-        PU::spanMotionInfo(pu);
-        const bool chroma = !pu.cu->isSepTree();
-        //  MC
-        m_pcInterSearch->motionCompensation(pu, REF_PIC_LIST_0, true, chroma);
+  pu.interDir               = 1;             // use list 0 for IBC mode
+  pu.refIdx[REF_PIC_LIST_0] = MAX_NUM_REF;   // last idx in the list
+  bool bValid =
+    m_pcInterSearch->predIBCSearch(cu, partitioner, m_ctuIbcSearchRangeX, m_ctuIbcSearchRangeY, m_ibcHashMap);
 
-        {
+  if (bValid)
+  {
+    PU::spanMotionInfo(pu);
+    const bool chroma = !pu.cu->isSepTree();
+    //  MC
+    m_pcInterSearch->motionCompensation(pu, REF_PIC_LIST_0, true, chroma);
 
-          m_pcInterSearch->encodeResAndCalcRdInterCU(*tempCS, partitioner, false, true, chroma);
-          if (tempCS->slice->getSPS()->getUseColorTrans())
-          {
-            bestCS->tmpColorSpaceCost = tempCS->tmpColorSpaceCost;
-            bestCS->firstColorSpaceSelected = tempCS->firstColorSpaceSelected;
-          }
+    m_pcInterSearch->encodeResAndCalcRdInterCU(*tempCS, partitioner, false, true, chroma);
+    if (tempCS->slice->getSPS()->getUseColorTrans())
+    {
+      bestCS->tmpColorSpaceCost       = tempCS->tmpColorSpaceCost;
+      bestCS->firstColorSpaceSelected = tempCS->firstColorSpaceSelected;
+    }
 
-          xEncodeDontSplit(*tempCS, partitioner);
+    xEncodeDontSplit(*tempCS, partitioner);
 
 #if ENABLE_QPA_SUB_CTU
-          xCheckDQP (*tempCS, partitioner);
+    xCheckDQP(*tempCS, partitioner);
 #else
-          // this if-check is redundant
-          if (tempCS->pps->getUseDQP() && partitioner.currQgEnable())
-          {
-            xCheckDQP(*tempCS, partitioner);
-          }
+    // this if-check is redundant
+    if (tempCS->pps->getUseDQP() && partitioner.currQgEnable())
+    {
+      xCheckDQP(*tempCS, partitioner);
+    }
 #endif
-          xCheckChromaQPOffset( *tempCS, partitioner );
+    xCheckChromaQPOffset(*tempCS, partitioner);
 
-          tempCS->useDbCost = m_pcEncCfg->getUseEncDbOpt();
-          if ( m_bestModeUpdated )
-          {
-            xCalDebCost( *tempCS, partitioner );
-          }
-
-          DTRACE_MODE_COST(*tempCS, m_pcRdCost->getLambda());
-          xCheckBestMode(tempCS, bestCS, partitioner, encTestMode);
-
-        }
+    tempCS->useDbCost = m_pcEncCfg->getUseEncDbOpt();
+    if (m_bestModeUpdated)
+    {
+      xCalDebCost(*tempCS, partitioner);
+    }
 
-      } // bValid
-      else
-      {
-        tempCS->dist = 0;
-        tempCS->fracBits = 0;
-        tempCS->cost = MAX_DOUBLE;
-        tempCS->costDbOffset = 0;
-      }
+    DTRACE_MODE_COST(*tempCS, m_pcRdCost->getLambda());
+    xCheckBestMode(tempCS, bestCS, partitioner, encTestMode);
+  }   // bValid
+  else
+  {
+    tempCS->dist         = 0;
+    tempCS->fracBits     = 0;
+    tempCS->cost         = MAX_DOUBLE;
+    tempCS->costDbOffset = 0;
+  }
 }
   // check ibc mode in encoder RD
   //////////////////////////////////////////////////////////////////////////////////////////////
@@ -3756,80 +4104,165 @@ void EncCu::xCheckRDCostInter( CodingStructure *&tempCS, CodingStructure *&bestC
       }
     }
 
-  CodingUnit &cu      = tempCS->addCU( tempCS->area, partitioner.chType );
+    CodingUnit &cu = tempCS->addCU(tempCS->area, partitioner.chType);
 
-  partitioner.setCUData( cu );
-  cu.slice            = tempCS->slice;
-  cu.tileIdx          = tempCS->pps->getTileIdx( tempCS->area.lumaPos() );
-  cu.skip             = false;
-  cu.mmvdSkip = false;
-//cu.affine
-  cu.predMode         = MODE_INTER;
-  cu.chromaQpAdj      = m_cuChromaQpOffsetIdxPlus1;
-  cu.qp               = encTestMode.qp;
-  CU::addPUs( cu );
+    partitioner.setCUData(cu);
+    cu.slice    = tempCS->slice;
+    cu.tileIdx  = tempCS->pps->getTileIdx(tempCS->area.lumaPos());
+    cu.skip     = false;
+    cu.mmvdSkip = false;
+    // cu.affine
+    cu.predMode    = MODE_INTER;
+    cu.chromaQpAdj = m_cuChromaQpOffsetIdxPlus1;
+    cu.qp          = encTestMode.qp;
+    CU::addPUs(cu);
 
-  cu.BcwIdx = g_BcwSearchOrder[bcwLoopIdx];
-  uint8_t bcwIdx = cu.BcwIdx;
-  bool  testBcw = (bcwIdx != BCW_DEFAULT);
+    cu.BcwIdx       = g_BcwSearchOrder[bcwLoopIdx];
+    uint8_t bcwIdx  = cu.BcwIdx;
+    bool    testBcw = (bcwIdx != BCW_DEFAULT);
 
-  m_pcInterSearch->predInterSearch( cu, partitioner );
+#if GDR_ENABLED
+  const bool isEncodeGdrClean = tempCS->sps->getGDREnabledFlag() && tempCS->pcv->isEncoder && ((tempCS->picHeader->getInGdrInterval() && tempCS->isClean(cu.Y().topRight(), CHANNEL_TYPE_LUMA)) || (tempCS->picHeader->getNumVerVirtualBoundaries() == 0));
+#endif
+    m_pcInterSearch->predInterSearch(cu, partitioner);
 
-  bcwIdx = CU::getValidBcwIdx(cu);
-  if( testBcw && bcwIdx == BCW_DEFAULT ) // Enabled Bcw but the search results is uni.
-  {
-    tempCS->initStructData(encTestMode.qp);
-    continue;
-  }
-  CHECK(!(testBcw || (!testBcw && bcwIdx == BCW_DEFAULT)), " !( bTestBcw || (!bTestBcw && bcwIdx == BCW_DEFAULT ) )");
+    bcwIdx = CU::getValidBcwIdx(cu);
+    if (testBcw && bcwIdx == BCW_DEFAULT)   // Enabled Bcw but the search results is uni.
+    {
+      tempCS->initStructData(encTestMode.qp);
+      continue;
+    }
+    CHECK(!(testBcw || (!testBcw && bcwIdx == BCW_DEFAULT)), " !( bTestBcw || (!bTestBcw && bcwIdx == BCW_DEFAULT ) )");
 
-  bool isEqualUni = false;
-  if( m_pcEncCfg->getUseBcwFast() )
-  {
-    if( cu.firstPU->interDir != 3 && testBcw == 0 )
+    bool isEqualUni = false;
+    if (m_pcEncCfg->getUseBcwFast())
     {
-      isEqualUni = true;
+      if (cu.firstPU->interDir != 3 && testBcw == 0)
+      {
+        isEqualUni = true;
+      }
     }
-  }
 
-  xEncodeInterResidual( tempCS, bestCS, partitioner, encTestMode, 0
-                        , 0
-                        , &equBcwCost
-  );
+#if GDR_ENABLED
+    // 2.0 xCheckRDCostInter: check residual (compare with bestCS)
+    if (isEncodeGdrClean)
+    {
+      bool isClean = true;
+
+      if (cu.affine && cu.firstPU)
+      {
+        bool L0ok = true, L1ok = true, L3ok = true;
+
+        L0ok = L0ok && cu.firstPU->mvAffiSolid[0][0] && cu.firstPU->mvAffiSolid[0][1] && cu.firstPU->mvAffiSolid[0][2];
+        L0ok = L0ok && cu.firstPU->mvAffiValid[0][0] && cu.firstPU->mvAffiValid[0][1] && cu.firstPU->mvAffiValid[0][2];
+
+        L1ok = L1ok && cu.firstPU->mvAffiSolid[1][0] && cu.firstPU->mvAffiSolid[1][1] && cu.firstPU->mvAffiSolid[1][2];
+        L1ok = L1ok && cu.firstPU->mvAffiValid[1][0] && cu.firstPU->mvAffiValid[1][1] && cu.firstPU->mvAffiValid[1][2];
 
-  if( g_BcwSearchOrder[bcwLoopIdx] == BCW_DEFAULT )
+        L3ok = L0ok && L1ok;
+
+        if (cu.firstPU->interDir == 1 && !L0ok)
+        {
+          isClean = false;
+        }
+        if (cu.firstPU->interDir == 2 && !L1ok)
+        {
+          isClean = false;
+        }
+        if (cu.firstPU->interDir == 3 && !L3ok)
+        {
+          isClean = false;
+        }
+      }
+      else if (cu.firstPU)
+      {
+        bool L0ok = true;
+        bool L1ok = true;
+        bool L3ok = true;
+
+        L0ok = L0ok && cu.firstPU->mvSolid[0];
+        L0ok = L0ok && cu.firstPU->mvValid[0];
+
+        L1ok = L1ok && cu.firstPU->mvSolid[1];
+        L1ok = L1ok && cu.firstPU->mvValid[1];
+
+        L3ok = L0ok && L1ok;
+
+        if (cu.firstPU->interDir == 1 && !L0ok)
+        {
+          isClean = false;
+        }
+        if (cu.firstPU->interDir == 2 && !L1ok)
+        {
+          isClean = false;
+        }
+        if (cu.firstPU->interDir == 3 && !L3ok)
+        {
+          isClean = false;
+        }
+      }
+      else
+      {
+        isClean = false;
+      }
+
+      if (isClean)
+      {
+        xEncodeInterResidual(tempCS, bestCS, partitioner, encTestMode, 0
+          , 0
+          , &equBcwCost
+        );
+      }
+    }
+    else
+    {
+      xEncodeInterResidual(tempCS, bestCS, partitioner, encTestMode, 0
+        , 0
+        , &equBcwCost
+      );
+    }
+#else
+    xEncodeInterResidual(tempCS, bestCS, partitioner, encTestMode, 0, 0, &equBcwCost);
+#endif
+
+#if GDR_ENABLED
+  if (g_BcwSearchOrder[bcwLoopIdx] == BCW_DEFAULT && bestCS->cus.size() > 0)
     m_pcInterSearch->setAffineModeSelected((bestCS->cus.front()->affine && !(bestCS->cus.front()->firstPU->mergeFlag)));
+#else
+    if (g_BcwSearchOrder[bcwLoopIdx] == BCW_DEFAULT)
+    {
+      m_pcInterSearch->setAffineModeSelected(
+        (bestCS->cus.front()->affine && !(bestCS->cus.front()->firstPU->mergeFlag)));
+    }
+#endif
 
-  tempCS->initStructData(encTestMode.qp);
+    tempCS->initStructData(encTestMode.qp);
 
-  double skipTH = MAX_DOUBLE;
-  skipTH = (m_pcEncCfg->getUseBcwFast() ? 1.05 : MAX_DOUBLE);
-  if( equBcwCost > curBestCost * skipTH )
-  {
-    break;
-  }
+    double skipTH = MAX_DOUBLE;
+    skipTH        = (m_pcEncCfg->getUseBcwFast() ? 1.05 : MAX_DOUBLE);
+    if (equBcwCost > curBestCost * skipTH)
+    {
+      break;
+    }
 
-  if( m_pcEncCfg->getUseBcwFast() )
-  {
-    if( isEqualUni == true && m_pcEncCfg->getIntraPeriod() == -1 )
+    if (m_pcEncCfg->getUseBcwFast())
+    {
+      if (isEqualUni == true && m_pcEncCfg->getIntraPeriod() == -1)
+      {
+        break;
+      }
+    }
+    if (g_BcwSearchOrder[bcwLoopIdx] == BCW_DEFAULT && xIsBcwSkip(cu) && m_pcEncCfg->getUseBcwFast())
     {
       break;
     }
-  }
-  if( g_BcwSearchOrder[bcwLoopIdx] == BCW_DEFAULT && xIsBcwSkip(cu) && m_pcEncCfg->getUseBcwFast() )
-  {
-    break;
-  }
- }  // for( UChar bcwLoopIdx = 0; bcwLoopIdx < bcwLoopNum; bcwLoopIdx++ )
+  }   // for( UChar bcwLoopIdx = 0; bcwLoopIdx < bcwLoopNum; bcwLoopIdx++ )
   if ( m_bestModeUpdated && bestCS->cost != MAX_DOUBLE )
   {
     xCalDebCost( *bestCS, partitioner );
   }
 }
 
-
-
-
 bool EncCu::xCheckRDCostInterIMV(CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &partitioner, const EncTestMode& encTestMode, double &bestIntPelCost)
 {
   int iIMV = int( ( encTestMode.opts & ETO_IMV ) >> ETO_IMV_SHIFT );
@@ -3906,6 +4339,9 @@ bool EncCu::xCheckRDCostInterIMV(CodingStructure *&tempCS, CodingStructure *&bes
 
   CU::addPUs( cu );
 
+#if GDR_ENABLED
+    const bool isEncodeGdrClean = tempCS->sps->getGDREnabledFlag() && tempCS->pcv->isEncoder && ((tempCS->picHeader->getInGdrInterval() && tempCS->isClean(cu.Y().topRight(), CHANNEL_TYPE_LUMA)) || (tempCS->picHeader->getNumVerVirtualBoundaries() == 0));
+#endif
   if (testAltHpelFilter)
   {
     cu.imv = IMV_HPEL;
@@ -3977,10 +4413,79 @@ bool EncCu::xCheckRDCostInterIMV(CodingStructure *&tempCS, CodingStructure *&bes
     }
   }
 
-  xEncodeInterResidual( tempCS, bestCS, partitioner, encTestModeBase, 0
-                        , 0
-                        , &equBcwCost
-  );
+#if GDR_ENABLED
+  // 2.0 xCheckRDCostInter: check residual (compare with bestCS)
+  if (isEncodeGdrClean)
+  {
+    bool isClean = true;
+
+    if (cu.affine && cu.firstPU)
+    {
+      bool L0ok = true, L1ok = true, L3ok = true;
+
+      L0ok = L0ok && cu.firstPU->mvAffiSolid[0][0] && cu.firstPU->mvAffiSolid[0][1] && cu.firstPU->mvAffiSolid[0][2];
+      L0ok = L0ok && cu.firstPU->mvAffiValid[0][0] && cu.firstPU->mvAffiValid[0][1] && cu.firstPU->mvAffiValid[0][2];
+
+      L1ok = L1ok && cu.firstPU->mvAffiSolid[1][0] && cu.firstPU->mvAffiSolid[1][1] && cu.firstPU->mvAffiSolid[1][2];
+      L1ok = L1ok && cu.firstPU->mvAffiValid[1][0] && cu.firstPU->mvAffiValid[1][1] && cu.firstPU->mvAffiValid[1][2];
+
+      L3ok = L0ok && L1ok;
+
+      if (cu.firstPU->interDir == 1 && !L0ok)
+      {
+        isClean = false;
+      }
+      if (cu.firstPU->interDir == 2 && !L1ok)
+      {
+        isClean = false;
+      }
+      if (cu.firstPU->interDir == 3 && !L3ok)
+      {
+        isClean = false;
+      }
+    }
+    else if (cu.firstPU)
+    {
+      bool L0ok = cu.firstPU->mvSolid[0] && cu.firstPU->mvValid[0];
+      bool L1ok = cu.firstPU->mvSolid[1] && cu.firstPU->mvValid[1];
+      bool L3ok = L0ok && L1ok;
+
+      if (cu.firstPU->interDir == 1 && !L0ok)
+      {
+        isClean = false;
+      }
+      if (cu.firstPU->interDir == 2 && !L1ok)
+      {
+        isClean = false;
+      }
+      if (cu.firstPU->interDir == 3 && !L3ok)
+      {
+        isClean = false;
+      }
+    }
+    else
+    {
+      isClean = false;
+    }
+
+    if (isClean)
+    {
+      xEncodeInterResidual(tempCS, bestCS, partitioner, encTestMode, 0
+        , 0
+        , &equBcwCost
+      );
+    }
+  }
+  else
+  {
+    xEncodeInterResidual(tempCS, bestCS, partitioner, encTestMode, 0
+      , 0
+      , &equBcwCost
+    );
+  }
+#else
+  xEncodeInterResidual(tempCS, bestCS, partitioner, encTestModeBase, 0, 0, &equBcwCost);
+#endif
 
   if( cu.imv == IMV_FPEL && tempCS->cost < bestIntPelCost )
   {
@@ -4029,7 +4534,7 @@ void EncCu::xCalDebCost( CodingStructure &cs, Partitioner &partitioner, bool cal
     return;
   }
 
-  m_pcLoopFilter->setEnc(true);
+  m_deblockingFilter->setEnc(true);
   const ChromaFormat format = cs.area.chromaFormat;
   CodingUnit*                cu = cs.getCU(partitioner.chType);
   const Position lumaPos = cu->Y().valid() ? cu->Y().pos() : recalcPosition( format, cu->chType, CHANNEL_TYPE_LUMA, cu->blocks[cu->chType].pos() );
@@ -4040,7 +4545,6 @@ void EncCu::xCalDebCost( CodingStructure &cs, Partitioner &partitioner, bool cal
 
   if ( calDist )
   {
-    const UnitArea currCsArea = clipArea( CS::getArea( cs, cs.area, partitioner.chType ), *cs.picture );
     ComponentID compStr = ( cu->isSepTree() && !isLuma( partitioner.chType ) ) ? COMPONENT_Cb : COMPONENT_Y;
     ComponentID compEnd = ( cu->isSepTree() && isLuma( partitioner.chType ) ) ? COMPONENT_Y : COMPONENT_Cr;
     Distortion finalDistortion = 0;
@@ -4049,7 +4553,7 @@ void EncCu::xCalDebCost( CodingStructure &cs, Partitioner &partitioner, bool cal
       const ComponentID compID = ComponentID( comp );
       CPelBuf org = cs.getOrgBuf( compID );
       CPelBuf reco = cs.getRecoBuf( compID );
-      finalDistortion += getDistortionDb( cs, org, reco, compID, currCsArea.block( compID ), false );
+      finalDistortion += getDistortionDb(cs, org, reco, compID, cs.area.block(COMPONENT_Y), false);
     }
     //updated distortion
     cs.dist = finalDistortion;
@@ -4060,9 +4564,9 @@ void EncCu::xCalDebCost( CodingStructure &cs, Partitioner &partitioner, bool cal
     ComponentID compStr = ( cu->isSepTree() && !isLuma( partitioner.chType ) ) ? COMPONENT_Cb : COMPONENT_Y;
     ComponentID compEnd = ( cu->isSepTree() &&  isLuma( partitioner.chType ) ) ? COMPONENT_Y : COMPONENT_Cr;
 
-    const UnitArea currCsArea = clipArea( CS::getArea( cs, cs.area, partitioner.chType ), *cs.picture );
+    const UnitArea currCsArea = clipArea(cs.area, *cs.picture);
 
-    PelStorage&          picDbBuf = m_pcLoopFilter->getDbEncPicYuvBuffer();
+    PelStorage&          picDbBuf = m_deblockingFilter->getDbEncPicYuvBuffer();
 
     //deblock neighbour pixels
     const Size     lumaSize = cu->Y().valid() ? cu->Y().size() : recalcSize( format, cu->chType, CHANNEL_TYPE_LUMA, cu->blocks[cu->chType].size() );
@@ -4108,14 +4612,14 @@ void EncCu::xCalDebCost( CodingStructure &cs, Partitioner &partitioner, bool cal
     //deblock
     if ( leftEdgeAvai )
     {
-      m_pcLoopFilter->resetFilterLengths();
-      m_pcLoopFilter->xDeblockCU( *cu, EDGE_VER );
+      m_deblockingFilter->resetFilterLengths();
+      m_deblockingFilter->xDeblockCU( *cu, EDGE_VER );
     }
 
     if (topEdgeAvai)
     {
-      m_pcLoopFilter->resetFilterLengths();
-      m_pcLoopFilter->xDeblockCU( *cu, EDGE_HOR );
+      m_deblockingFilter->resetFilterLengths();
+      m_deblockingFilter->xDeblockCU( *cu, EDGE_HOR );
     }
 
     //update current CU SSE
@@ -4125,7 +4629,7 @@ void EncCu::xCalDebCost( CodingStructure &cs, Partitioner &partitioner, bool cal
       ComponentID compId = (ComponentID)compIdx;
       CPelBuf reco = picDbBuf.getBuf( currCsArea.block( compId ) );
       CPelBuf org = cs.getOrgBuf( compId );
-      distCur += getDistortionDb( cs, org, reco, compId, currCsArea.block( compId ), true );
+      distCur += getDistortionDb(cs, org, reco, compId, currCsArea.block(COMPONENT_Y), true);
     }
 
     //calculate difference between DB_before_SSE and DB_after_SSE for neighbouring CUs
@@ -4139,8 +4643,8 @@ void EncCu::xCalDebCost( CodingStructure &cs, Partitioner &partitioner, bool cal
         CPelBuf org = cs.picture->getOrigBuf( compArea );
         CPelBuf reco = cs.picture->getRecoBuf( compArea );
         CPelBuf recoDb = picDbBuf.getBuf( compArea );
-        distBeforeDb += getDistortionDb( cs, org, reco,   compId, compArea, false );
-        distAfterDb  += getDistortionDb( cs, org, recoDb, compId, compArea, true  );
+        distBeforeDb += getDistortionDb(cs, org, reco, compId, areaLeft.block(COMPONENT_Y), false);
+        distAfterDb += getDistortionDb(cs, org, recoDb, compId, areaLeft.block(COMPONENT_Y), true);
       }
       if ( topEdgeAvai )
       {
@@ -4148,8 +4652,8 @@ void EncCu::xCalDebCost( CodingStructure &cs, Partitioner &partitioner, bool cal
         CPelBuf org = cs.picture->getOrigBuf( compArea );
         CPelBuf reco = cs.picture->getRecoBuf( compArea );
         CPelBuf recoDb = picDbBuf.getBuf( compArea );
-        distBeforeDb += getDistortionDb( cs, org, reco,   compId, compArea, false );
-        distAfterDb  += getDistortionDb( cs, org, recoDb, compId, compArea, true  );
+        distBeforeDb += getDistortionDb(cs, org, reco, compId, areaTop.block(COMPONENT_Y), false);
+        distAfterDb += getDistortionDb(cs, org, recoDb, compId, areaTop.block(COMPONENT_Y), true);
       }
     }
 
@@ -4160,7 +4664,7 @@ void EncCu::xCalDebCost( CodingStructure &cs, Partitioner &partitioner, bool cal
     cs.costDbOffset = sign * m_pcRdCost->calcRdCost( 0, distTmp );
   }
 
-  m_pcLoopFilter->setEnc( false );
+  m_deblockingFilter->setEnc( false );
 }
 
 Distortion EncCu::getDistortionDb( CodingStructure &cs, CPelBuf org, CPelBuf reco, ComponentID compID, const CompArea& compArea, bool afterDb )
@@ -4168,7 +4672,7 @@ Distortion EncCu::getDistortionDb( CodingStructure &cs, CPelBuf org, CPelBuf rec
   Distortion dist = 0;
 #if WCG_EXT
   m_pcRdCost->setChromaFormat(cs.sps->getChromaFormatIdc());
-  CPelBuf orgLuma = cs.picture->getOrigBuf( cs.area.blocks[COMPONENT_Y] );
+  CPelBuf orgLuma = cs.picture->getOrigBuf(compArea);
   if (m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled() || (
     m_pcEncCfg->getLmcs() && (cs.slice->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag())))
   {
@@ -4257,7 +4761,9 @@ void EncCu::xEncodeInterResidual(   CodingStructure *&tempCS
         mvShift = normalShiftTab[cu->imv];
         Mv signaledmvd(pu.mvd[refList].getHor() >> mvShift, pu.mvd[refList].getVer() >> mvShift);
         if (!((signaledmvd.getHor() >= MVD_MIN) && (signaledmvd.getHor() <= MVD_MAX)) || !((signaledmvd.getVer() >= MVD_MIN) && (signaledmvd.getVer() <= MVD_MAX)))
+        {
           return;
+        }
       }
       else
       {
@@ -4266,7 +4772,9 @@ void EncCu::xEncodeInterResidual(   CodingStructure *&tempCS
           mvShift = affineShiftTab[cu->imv];
           Mv signaledmvd(pu.mvdAffi[refList][ctrlP].getHor() >> mvShift, pu.mvdAffi[refList][ctrlP].getVer() >> mvShift);
           if (!((signaledmvd.getHor() >= MVD_MIN) && (signaledmvd.getHor() <= MVD_MAX)) || !((signaledmvd.getVer() >= MVD_MIN) && (signaledmvd.getVer() <= MVD_MAX)))
+          {
             return;
+          }
         }
       }
     }
@@ -4617,11 +5125,12 @@ void EncCu::xEncodeDontSplit( CodingStructure &cs, Partitioner &partitioner )
 
   m_CABACEstimator->split_cu_mode( CU_DONT_SPLIT, cs, partitioner );
   if( partitioner.treeType == TREE_C )
+  {
     CHECK( m_CABACEstimator->getEstFracBits() != 0, "must be 0 bit" );
+  }
 
   cs.fracBits += m_CABACEstimator->getEstFracBits(); // split bits
   cs.cost      = m_pcRdCost->calcRdCost( cs.fracBits, cs.dist );
-
 }
 
 #if REUSE_CU_RESULTS
@@ -4637,9 +5146,7 @@ void EncCu::xReuseCachedResult( CodingStructure *&tempCS, CodingStructure *&best
     CodingUnit& cu = *tempCS->cus.front();
     partitioner.setCUData( cu );
 
-    if( CU::isIntra( cu )
-    || CU::isPLT(cu)
-    )
+    if (CU::isIntra(cu) || CU::isPLT(cu))
     {
       xReconIntraQT( cu );
     }
@@ -4658,42 +5165,48 @@ void EncCu::xReuseCachedResult( CodingStructure *&tempCS, CodingStructure *&best
     }
     else
     {
-    const SPS &sps = *tempCS->sps;
-    const int  numValidComponents = getNumberValidComponents( tempCS->area.chromaFormat );
-
-    for( int comp = 0; comp < numValidComponents; comp++ )
-    {
-      const ComponentID compID = ComponentID( comp );
+      const SPS &sps                = *tempCS->sps;
+      const int  numValidComponents = getNumberValidComponents(tempCS->area.chromaFormat);
 
-      if( partitioner.isSepTree( *tempCS ) && toChannelType( compID ) != partitioner.chType )
+      for (int comp = 0; comp < numValidComponents; comp++)
       {
-        continue;
-      }
+        const ComponentID compID = ComponentID(comp);
 
-      CPelBuf reco = tempCS->getRecoBuf( compID );
-      CPelBuf org  = tempCS->getOrgBuf ( compID );
+        if (partitioner.isSepTree(*tempCS) && toChannelType(compID) != partitioner.chType)
+        {
+          continue;
+        }
+
+        CPelBuf reco = tempCS->getRecoBuf(compID);
+        CPelBuf org  = tempCS->getOrgBuf(compID);
 
 #if WCG_EXT
-      if (m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled() || (
-        m_pcEncCfg->getLmcs() && (tempCS->slice->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag())))
-      {
-        const CPelBuf orgLuma = tempCS->getOrgBuf(tempCS->area.blocks[COMPONENT_Y]);
-        if (compID == COMPONENT_Y && !(m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled()))
+        if (m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled()
+            || (m_pcEncCfg->getLmcs() && (tempCS->slice->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag())))
         {
-          const CompArea &area = cu.blocks[COMPONENT_Y];
-          CompArea    tmpArea(COMPONENT_Y, area.chromaFormat, Position(0, 0), area.size());
-          PelBuf tmpRecLuma = m_tmpStorageLCU->getBuf(tmpArea);
-          tmpRecLuma.copyFrom(reco);
-          tmpRecLuma.rspSignal(m_pcReshape->getInvLUT());
-          finalDistortion += m_pcRdCost->getDistPart(org, tmpRecLuma, sps.getBitDepth(toChannelType(compID)), compID, DF_SSE_WTD, &orgLuma);
+          const CPelBuf orgLuma = tempCS->getOrgBuf(tempCS->area.blocks[COMPONENT_Y]);
+          if (compID == COMPONENT_Y && !(m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled()))
+          {
+            const CompArea &area = cu.blocks[COMPONENT_Y];
+            CompArea        tmpArea(COMPONENT_Y, area.chromaFormat, Position(0, 0), area.size());
+            PelBuf          tmpRecLuma = m_tmpStorageLCU->getBuf(tmpArea);
+            tmpRecLuma.copyFrom(reco);
+            tmpRecLuma.rspSignal(m_pcReshape->getInvLUT());
+            finalDistortion += m_pcRdCost->getDistPart(org, tmpRecLuma, sps.getBitDepth(toChannelType(compID)), compID,
+                                                       DF_SSE_WTD, &orgLuma);
+          }
+          else
+          {
+            finalDistortion +=
+              m_pcRdCost->getDistPart(org, reco, sps.getBitDepth(toChannelType(compID)), compID, DF_SSE_WTD, &orgLuma);
+          }
         }
         else
-        finalDistortion += m_pcRdCost->getDistPart( org, reco, sps.getBitDepth( toChannelType( compID ) ), compID, DF_SSE_WTD, &orgLuma );
-      }
-      else
 #endif
-      finalDistortion += m_pcRdCost->getDistPart( org, reco, sps.getBitDepth( toChannelType( compID ) ), compID, DF_SSE );
-    }
+        {
+          finalDistortion += m_pcRdCost->getDistPart(org, reco, sps.getBitDepth(toChannelType(compID)), compID, DF_SSE);
+        }
+      }
     }
 
     m_CABACEstimator->getCtx() = m_CurrCtx->start;
diff --git a/source/Lib/EncoderLib/EncCu.h b/source/Lib/EncoderLib/EncCu.h
index 07d4848fa..612e212ce 100644
--- a/source/Lib/EncoderLib/EncCu.h
+++ b/source/Lib/EncoderLib/EncCu.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -46,7 +46,7 @@
 #include "CommonLib/Unit.h"
 #include "CommonLib/UnitPartitioner.h"
 #include "CommonLib/IbcHashMap.h"
-#include "CommonLib/LoopFilter.h"
+#include "CommonLib/DeblockingFilter.h"
 
 #include "DecoderLib/DecCu.h"
 
@@ -88,16 +88,18 @@ struct SmallerThanComboCost
 {
   inline bool operator() (const GeoMergeCombo& first, const GeoMergeCombo& second)
   {
-      return (first.cost < second.cost);
+    return (first.cost < second.cost);
   }
 };
+
 class GeoComboCostList
 {
 public:
   GeoComboCostList() {};
   ~GeoComboCostList() {};
-  std::vector<GeoMergeCombo> list;
-  void sortByCost() { std::sort(list.begin(), list.end(), SmallerThanComboCost()); };
+  std::vector<GeoMergeCombo> list;  
+  
+  void sortByCost() { std::stable_sort(list.begin(), list.end(), SmallerThanComboCost()); };
 };
 struct SingleGeoMergeEntry
 {
@@ -161,10 +163,6 @@ private:
   CtxPair*              m_CurrCtx;
   CtxCache*             m_CtxCache;
 
-#if ENABLE_SPLIT_PARALLELISM
-  int                   m_dataId;
-#endif
-
   //  Data : encoder control
   int                   m_cuChromaQpOffsetIdxPlus1; // if 0, then cu_chroma_qp_offset_flag will be 0, otherwise cu_chroma_qp_offset_flag will be 1.
 
@@ -181,7 +179,7 @@ private:
   TrQuant*              m_pcTrQuant;
   RdCost*               m_pcRdCost;
   EncSlice*             m_pcSliceEncoder;
-  LoopFilter*           m_pcLoopFilter;
+  DeblockingFilter*     m_deblockingFilter;
 
   CABACWriter*          m_CABACEstimator;
   RateCtrl*             m_pcRateCtrl;
@@ -199,9 +197,6 @@ private:
 
   int                   m_ctuIbcSearchRangeX;
   int                   m_ctuIbcSearchRangeY;
-#if ENABLE_SPLIT_PARALLELISM
-  EncLib*               m_pcEncLib;
-#endif
   int                   m_bestBcwIdx[2];
   double                m_bestBcwCost[2];
   GeoMotionInfo         m_GeoModeTest[GEO_MAX_NUM_CANDS];
@@ -215,7 +210,7 @@ private:
   double                m_sbtCostSave[2];
 public:
   /// copy parameters from encoder class
-  void  init                ( EncLib* pcEncLib, const SPS& sps PARL_PARAM( const int jId = 0 ) );
+  void  init                ( EncLib* pcEncLib, const SPS& sps );
 
   void setDecCuReshaperInEncCU(EncReshape* pcReshape, ChromaFormat chromaFormatIDC) { initDecCuReshaper((Reshape*) pcReshape, chromaFormatIDC); }
   /// create internal buffers
@@ -248,10 +243,6 @@ protected:
   Distortion getDistortionDb  ( CodingStructure &cs, CPelBuf org, CPelBuf reco, ComponentID compID, const CompArea& compArea, bool afterDb );
 
   void xCompressCU            ( CodingStructure*& tempCS, CodingStructure*& bestCS, Partitioner& pm, double maxCostAllowed = MAX_DOUBLE );
-#if ENABLE_SPLIT_PARALLELISM
-  void xCompressCUParallel    ( CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &pm );
-  void copyState              ( EncCu* other, Partitioner& pm, const UnitArea& currArea, const bool isDist );
-#endif
 
   bool
     xCheckBestMode         ( CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &pm, const EncTestMode& encTestmode );
@@ -262,7 +253,6 @@ protected:
 
   void xCheckDQP              ( CodingStructure& cs, Partitioner& partitioner, bool bKeepCtx = false);
   void xCheckChromaQPOffset   ( CodingStructure& cs, Partitioner& partitioner);
-  void xFillPCMBuffer         ( CodingUnit &cu);
 
   void xCheckRDCostHashInter  ( CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &pm, const EncTestMode& encTestMode );
   void xCheckRDCostAffineMerge2Nx2N
diff --git a/source/Lib/EncoderLib/EncGOP.cpp b/source/Lib/EncoderLib/EncGOP.cpp
index 092c2195b..dc9b083f8 100644
--- a/source/Lib/EncoderLib/EncGOP.cpp
+++ b/source/Lib/EncoderLib/EncGOP.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -59,8 +59,6 @@
 
 #include "DecoderLib/DecLib.h"
 
-#define ENCODE_SUB_SET 0
-
 using namespace std;
 
 //! \ingroup EncoderLib
@@ -89,7 +87,12 @@ EncGOP::EncGOP()
   m_bFirst              = true;
   m_iLastRecoveryPicPOC = 0;
   m_latestDRAPPOC       = MAX_INT;
+  m_latestEDRAPPOC      = MAX_INT;
+  m_latestEdrapLeadingPicDecodableFlag = false;
   m_lastRasPoc          = MAX_INT;
+  ::memset(m_riceBit, 0, 8 * 2 * sizeof(unsigned));
+  ::memset(m_preQP, MAX_INT, 2 * sizeof(int));
+  m_preIPOC             = 0;
 
   m_pcCfg               = NULL;
   m_pcSliceEncoder      = NULL;
@@ -139,6 +142,10 @@ EncGOP::EncGOP()
   m_isUseLTRef = false;
   m_isPrepareLTRef = true;
   m_lastLTRefPoc = 0;
+#if JVET_W0046_RLSCP
+  m_cnt_right_bottom = 0;
+  m_cnt_right_bottom_i = 0;
+#endif
 }
 
 EncGOP::~EncGOP()
@@ -212,7 +219,7 @@ void EncGOP::init ( EncLib* pcEncLib )
   m_pcSliceEncoder       = pcEncLib->getSliceEncoder();
   m_pcListPic            = pcEncLib->getListPic();
   m_HLSWriter            = pcEncLib->getHLSWriter();
-  m_pcLoopFilter         = pcEncLib->getLoopFilter();
+  m_pcLoopFilter         = pcEncLib->getDeblockingFilter();
   m_pcSAO                = pcEncLib->getSAO();
   m_pcALF                = pcEncLib->getALF();
   m_pcRateCtrl           = pcEncLib->getRateCtrl();
@@ -233,6 +240,10 @@ void EncGOP::init ( EncLib* pcEncLib )
     pcEncLib->getRdCost()->setReshapeInfo(RESHAPE_SIGNAL_PQ, m_pcCfg->getBitDepth(CHANNEL_TYPE_LUMA));
     pcEncLib->getRdCost()->initLumaLevelToWeightTableReshape();
   }
+  else if (m_pcCfg->getPrintWPSNR())
+  {
+    pcEncLib->getRdCost()->initLumaLevelToWeightTable(m_pcCfg->getBitDepth(CHANNEL_TYPE_LUMA));
+  }
   pcEncLib->getALF()->getLumaLevelWeightTable() = pcEncLib->getRdCost()->getLumaLevelWeightTable();
   int alfWSSD = 0;
   if (m_pcCfg->getLmcs() && m_pcCfg->getReshapeSignalType() == RESHAPE_SIGNAL_PQ )
@@ -308,9 +319,11 @@ void EncGOP::init ( EncLib* pcEncLib )
     m_pcTransferFct       = hdrtoolslib::TransferFunction::create(hdrtoolslib::TF_PQ, true, (float) maxSampleValue, 0, 0.0, 1.0, enableTFunctionLUT);
   }
 #endif
+#if GDR_ENABLED
+  m_lastGdrIntervalPoc = -1;
+#endif
 }
 
-#if JVET_S0163_ON_TARGETOLS_SUBLAYERS
 int EncGOP::xWriteOPI (AccessUnit &accessUnit, const OPI *opi)
 {
   OutputNALUnit nalu(NAL_UNIT_OPI);
@@ -320,7 +333,6 @@ int EncGOP::xWriteOPI (AccessUnit &accessUnit, const OPI *opi)
   accessUnit.push_back(new NALUnitEBSP(nalu));
   return (int)(accessUnit.back()->m_nalUnitData.str().size()) * 8;
 }
-#endif
 
 int EncGOP::xWriteVPS (AccessUnit &accessUnit, const VPS *vps)
 {
@@ -372,6 +384,12 @@ int EncGOP::xWriteAPS( AccessUnit &accessUnit, APS *aps, const int layerId, cons
   nalu.m_temporalId = aps->getTemporalId();
   aps->setLayerId( layerId );
   CHECK( nalu.m_temporalId < accessUnit.temporalId, "TemporalId shall be greater than or equal to the TemporalId of the layer access unit containing the NAL unit" );
+
+#if GDR_ENC_TRACE
+  if (aps)
+    printf("-aps ty:%d id:%d\n", aps->getAPSType(), aps->getAPSId());
+#endif
+
   m_HLSWriter->codeAPS(aps);
   accessUnit.push_back(new NALUnitEBSP(nalu));
   return (int)(accessUnit.back()->m_nalUnitData.str().size()) * 8;
@@ -385,12 +403,10 @@ int EncGOP::xWriteParameterSets(AccessUnit &accessUnit, Slice *slice, const bool
   {
     if (layerIdx == 0)
     {
-#if JVET_S0163_ON_TARGETOLS_SUBLAYERS
       if (m_pcCfg->getOPIEnabled())
       {
         actualTotalBits += xWriteOPI(accessUnit, m_pcEncLib->getOPI());
       }
-#endif
       if (m_pcCfg->getDCIEnabled())
       {
         actualTotalBits += xWriteDCI(accessUnit, m_pcEncLib->getDCI());
@@ -514,7 +530,6 @@ void EncGOP::xWriteLeadingSEIOrdered (SEIMessages& seiMessages, SEIMessages& duI
 {
   AccessUnit::iterator itNalu = accessUnit.begin();
 
-#if JVET_S0163_ON_TARGETOLS_SUBLAYERS
   while ((itNalu != accessUnit.end()) &&
     ((*itNalu)->m_nalUnitType == NAL_UNIT_ACCESS_UNIT_DELIMITER
       || (*itNalu)->m_nalUnitType == NAL_UNIT_OPI
@@ -523,15 +538,6 @@ void EncGOP::xWriteLeadingSEIOrdered (SEIMessages& seiMessages, SEIMessages& duI
       || (*itNalu)->m_nalUnitType == NAL_UNIT_SPS
       || (*itNalu)->m_nalUnitType == NAL_UNIT_PPS
       ))
-#else
-  while ((itNalu != accessUnit.end()) &&
-    ((*itNalu)->m_nalUnitType == NAL_UNIT_ACCESS_UNIT_DELIMITER
-      || (*itNalu)->m_nalUnitType == NAL_UNIT_VPS
-      || (*itNalu)->m_nalUnitType == NAL_UNIT_DCI
-      || (*itNalu)->m_nalUnitType == NAL_UNIT_SPS
-      || (*itNalu)->m_nalUnitType == NAL_UNIT_PPS
-      ))
-#endif
   {
     itNalu++;
   }
@@ -770,6 +776,57 @@ void EncGOP::xCreateIRAPLeadingSEIMessages (SEIMessages& seiMessages, const SPS
     m_seiEncoder.initSEIContentColourVolume(seiContentColourVolume);
     seiMessages.push_back(seiContentColourVolume);
   }
+  
+  if (m_pcCfg->getSdiSEIEnabled())
+  {
+    SEIScalabilityDimensionInfo *seiScalabilityDimensionInfo = new SEIScalabilityDimensionInfo;
+    m_seiEncoder.initSEIScalabilityDimensionInfo(seiScalabilityDimensionInfo);
+    seiMessages.push_back(seiScalabilityDimensionInfo);
+  }
+  // multiview acquisition information
+  if (m_pcCfg->getMaiSEIEnabled())
+  {
+    SEIMultiviewAcquisitionInfo *seiMultiviewAcquisitionInfo = new SEIMultiviewAcquisitionInfo;
+    m_seiEncoder.initSEIMultiviewAcquisitionInfo(seiMultiviewAcquisitionInfo);
+    seiMessages.push_back(seiMultiviewAcquisitionInfo);
+  }
+#if JVET_W0078_MVP_SEI 
+  // multiview view position
+  if (m_pcCfg->getMvpSEIEnabled())
+  {
+    SEIMultiviewViewPosition *seiMultiviewViewPosition = new SEIMultiviewViewPosition;
+    m_seiEncoder.initSEIMultiviewViewPosition(seiMultiviewViewPosition);
+    seiMessages.push_back(seiMultiviewViewPosition);
+  }
+#endif
+  // alpha channel information
+  if (m_pcCfg->getAciSEIEnabled())
+  {
+    SEIAlphaChannelInfo *seiAlphaChannelInfo = new SEIAlphaChannelInfo;
+    m_seiEncoder.initSEIAlphaChannelInfo(seiAlphaChannelInfo);
+    seiMessages.push_back(seiAlphaChannelInfo);
+  }
+  // depth representation information
+  if (m_pcCfg->getDriSEIEnabled())
+  {
+    SEIDepthRepresentationInfo *seiDepthRepresentationInfo = new SEIDepthRepresentationInfo;
+    m_seiEncoder.initSEIDepthRepresentationInfo(seiDepthRepresentationInfo);
+    seiMessages.push_back(seiDepthRepresentationInfo);
+  }
+  // colour transform information
+  if (m_pcCfg->getCtiSEIEnabled())
+  {
+    SEIColourTransformInfo* seiCTI = new SEIColourTransformInfo;
+    m_seiEncoder.initSEIColourTransformInfo(seiCTI);
+    seiMessages.push_back(seiCTI);
+  }
+#if JVET_W0133_CONSTRAINED_RASL_ENCODING
+  if (m_pcCfg->getConstrainedRaslencoding())
+  {
+    SEIConstrainedRaslIndication* seiConstrainedRasl = new SEIConstrainedRaslIndication;
+    seiMessages.push_back(seiConstrainedRasl);
+  }
+#endif
 }
 
 void EncGOP::xCreatePerPictureSEIMessages (int picInGOP, SEIMessages& seiMessages, SEIMessages& nestedSeiMessages, Slice *slice)
@@ -791,7 +848,6 @@ void EncGOP::xCreatePerPictureSEIMessages (int picInGOP, SEIMessages& seiMessage
       bufferingPeriodSEI->copyTo(*bufferingPeriodSEIcopy);
       nestedSeiMessages.push_back(bufferingPeriodSEIcopy);
     }
-
   }
 
   if (m_pcEncLib->getDependentRAPIndicationSEIEnabled() && slice->isDRAP())
@@ -801,9 +857,40 @@ void EncGOP::xCreatePerPictureSEIMessages (int picInGOP, SEIMessages& seiMessage
     seiMessages.push_back(dependentRAPIndicationSEI);
   }
 
+  if (m_pcEncLib->getEdrapIndicationSEIEnabled() && slice->getEdrapRapId() > 0)
+  {
+    SEIExtendedDrapIndication *seiExtendedDrapIndication = new SEIExtendedDrapIndication();
+    m_seiEncoder.initSEIExtendedDrapIndication(seiExtendedDrapIndication);
+    // update EDRAP SEI message according to the reference lists of the slice
+    seiExtendedDrapIndication->m_edrapIndicationRapIdMinus1 = slice->getEdrapRapId() - 1;
+    seiExtendedDrapIndication->m_edrapIndicationLeadingPicturesDecodableFlag = slice->getLatestEdrapLeadingPicDecodableFlag();
+    seiExtendedDrapIndication->m_edrapIndicationNumRefRapPicsMinus1 = slice->getEdrapNumRefRapPics() - 1;
+    seiExtendedDrapIndication->m_edrapIndicationRefRapId.resize(seiExtendedDrapIndication->m_edrapIndicationNumRefRapPicsMinus1 + 1);
+    for (int i = 0; i <= seiExtendedDrapIndication->m_edrapIndicationNumRefRapPicsMinus1; i++)
+    {
+      seiExtendedDrapIndication->m_edrapIndicationRefRapId[i] = slice->getEdrapRefRapId(i);
+    }
+    seiMessages.push_back(seiExtendedDrapIndication);
+  }
+
+  // insert one Annotated Region SEI for the picture (if the file exists)
+  if (!m_pcCfg->getAnnotatedRegionSEIFileRoot().empty())
+  {
+    SEIAnnotatedRegions *seiAnnotatedRegions = new SEIAnnotatedRegions();
+    const bool success = m_seiEncoder.initSEIAnnotatedRegions(seiAnnotatedRegions, slice->getPOC());
+
+    if (success)
+    {
+      seiMessages.push_back(seiAnnotatedRegions);
+    }
+    else
+    {
+      delete seiAnnotatedRegions;
+    }
+  }
 }
 
-void EncGOP::xCreateScalableNestingSEI(SEIMessages& seiMessages, SEIMessages& nestedSeiMessages, const std::vector<int> &targetOLSs, const std::vector<int> &targetLayers, const std::vector<uint16_t>& subpicIDs)
+void EncGOP::xCreateScalableNestingSEI(SEIMessages& seiMessages, SEIMessages& nestedSeiMessages, const std::vector<int> &targetOLSs, const std::vector<int> &targetLayers, const std::vector<uint16_t>& subpicIDs, uint16_t maxSubpicIdInPic)
 {
   SEIMessages tmpMessages;
   while (!nestedSeiMessages.empty())
@@ -812,7 +899,7 @@ void EncGOP::xCreateScalableNestingSEI(SEIMessages& seiMessages, SEIMessages& ne
     nestedSeiMessages.pop_front();
     tmpMessages.push_back(sei);
     SEIScalableNesting *nestingSEI = new SEIScalableNesting();
-    m_seiEncoder.initSEIScalableNesting(nestingSEI, tmpMessages, targetOLSs, targetLayers, subpicIDs);
+    m_seiEncoder.initSEIScalableNesting(nestingSEI, tmpMessages, targetOLSs, targetLayers, subpicIDs, maxSubpicIdInPic);
     seiMessages.push_back(nestingSEI);
     tmpMessages.clear();
   }
@@ -850,7 +937,6 @@ void EncGOP::xCreatePictureTimingSEI  (int IRAPGOPid, SEIMessages& seiMessages,
   // update decoding unit parameters
   if ((m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled()) && slice->getNalUnitLayerId() == slice->getVPS()->getLayerId(0))
   {
-    int picSptDpbOutputDuDelay = 0;
     SEIPictureTiming *pictureTimingSEI = new SEIPictureTiming();
 
     // DU parameters
@@ -1044,10 +1130,6 @@ void EncGOP::xCreatePictureTimingSEI  (int IRAPGOPid, SEIMessages& seiMessages,
     }
     int factor = hrd->getTickDivisorMinus2() + 2;
     pictureTimingSEI->m_picDpbOutputDuDelay = factor * pictureTimingSEI->m_picDpbOutputDelay;
-    if( m_pcCfg->getDecodingUnitInfoSEIEnabled() )
-    {
-      picSptDpbOutputDuDelay = factor * pictureTimingSEI->m_picDpbOutputDelay;
-    }
     if (m_bufferingPeriodSEIPresentInAU)
     {
       for( int i = temporalId ; i < maxNumSubLayers ; i ++ )
@@ -1080,9 +1162,10 @@ void EncGOP::xCreatePictureTimingSEI  (int IRAPGOPid, SEIMessages& seiMessages,
         SEIDecodingUnitInfo *duInfoSEI = new SEIDecodingUnitInfo();
         duInfoSEI->m_decodingUnitIdx = i;
         for( int j = temporalId; j <= maxNumSubLayers; j++ )
+        {
           duInfoSEI->m_duSptCpbRemovalDelayIncrement[j] = pictureTimingSEI->m_duCpbRemovalDelayMinus1[i*maxNumSubLayers+j] + 1;
+        }
         duInfoSEI->m_dpbOutputDuDelayPresentFlag = false;
-        duInfoSEI->m_picSptDpbOutputDuDelay = picSptDpbOutputDuDelay;
 
         duInfoSeiMessages.push_back(duInfoSEI);
       }
@@ -1150,7 +1233,9 @@ void EncGOP::xUpdateTimingSEI(SEIPictureTiming *pictureTimingSEI, std::deque<DUD
 
     int maxNumSubLayers = sps->getMaxTLayers();
     for( int j = 0; j < maxNumSubLayers - 1; j++ )
+    {
       pictureTimingSEI->m_ptSubLayerDelaysPresentFlag[j] = false;
+    }
 
     for( i = 0; i < numDU; i ++ )
     {
@@ -1190,7 +1275,10 @@ void EncGOP::xUpdateTimingSEI(SEIPictureTiming *pictureTimingSEI, std::deque<DUD
             ui64Tmp = uiPrev + 1;
             flag = 1;
           }
-          else                            ui64Tmp = maxDiff - tmp + 1;
+          else
+          {
+            ui64Tmp = maxDiff - tmp + 1;
+          }
         }
         rDuCpbRemovalDelayMinus1[ i * maxNumSubLayers + maxNumSubLayers - 1 ] = (uint32_t)ui64Tmp - uiPrev - 1;
         if( (int)rDuCpbRemovalDelayMinus1[ i * maxNumSubLayers + maxNumSubLayers - 1 ] < 0 )
@@ -1255,6 +1343,40 @@ validateMinCrRequirements(const ProfileLevelTierFeatures &plt, std::size_t numBy
     }
   }
 }
+
+static void
+validateMinCrRequirements(const ProfileLevelTierFeatures &plt, std::size_t numBytesInVclNalUnits, const Slice *pSlice, const EncCfg *pCfg, const SEISubpicureLevelInfo &seiSubpic, const int subPicIdx, const int layerId)
+{
+  if (plt.getLevelTierFeatures() && plt.getProfileFeatures())
+  {
+    if (plt.getTier() == Level::Tier::MAIN)
+    {
+      const uint32_t formatCapabilityFactorx1000 = plt.getProfileFeatures()->formatCapabilityFactorx1000;
+      const uint64_t maxLumaSr = plt.getLevelTierFeatures()->maxLumaSr;
+      const double   denomx1000x256 = (256 * plt.getMinCr() * pCfg->getFrameRate() * 1000 * 256);
+
+      for (int i = 0; i < seiSubpic.m_numRefLevels; i++)
+      {
+        Level::Name level = seiSubpic.m_refLevelIdc[i][layerId];
+        if (level != Level::LEVEL15_5)
+        {
+          const int      nonSubpicLayersFraction = seiSubpic.m_nonSubpicLayersFraction[i][layerId];
+          const int      refLevelFraction = seiSubpic.m_refLevelFraction[i][subPicIdx][layerId] + 1; //m_refLevelFraction is actually sli_ref_level_fraction_minus1
+          const uint32_t olsRefLevelFractionx256 = nonSubpicLayersFraction * 256 + (256 - nonSubpicLayersFraction) * refLevelFraction;
+
+          const double   threshold = formatCapabilityFactorx1000 * maxLumaSr * olsRefLevelFractionx256 / denomx1000x256;
+
+          if (numBytesInVclNalUnits > threshold)
+          {
+            msg( WARNING, "WARNING: Encoded stream for sub-picture %d does not meet MinCr requirements numBytesInVclNalUnits (%.0f) must be <= %.0f. Try increasing Qp, tier or level\n",
+                      subPicIdx, (double) numBytesInVclNalUnits, threshold );
+          }
+        }
+      }
+    }
+  }
+}
+
 static std::size_t
 cabac_zero_word_padding(const Slice *const pcSlice,
                         const Picture *const pcPic,
@@ -1306,7 +1428,7 @@ cabac_zero_word_padding(const Slice *const pcSlice,
       return numberOfAdditionalCabacZeroWords;
     }
   }
-      return 0;
+  return 0;
 }
 
 class EfficientFieldIRAPMapping
@@ -1564,7 +1686,10 @@ void trySkipOrDecodePicture( bool& decPic, bool& encPic, const EncCfg& cfg, Pict
     }
 
     encPic |= cfg.getForceDecodeBitstream1() && !decPic;
-    if( cfg.getForceDecodeBitstream1() ) { return; }
+    if (cfg.getForceDecodeBitstream1())
+    {
+      return;
+    }
   }
 
 
@@ -1892,7 +2017,9 @@ void EncGOP::xPicInitLMCS(Picture *pic, PicHeader *picHeader, Slice *slice)
         m_pcReshaper->setCTUFlag(false);
       }
       else
+      {
         m_pcReshaper->setCTUFlag(true);
+      }
 
       m_pcReshaper->getSliceReshaperInfo().setSliceReshapeModelPresentFlag(false);
 
@@ -1903,6 +2030,12 @@ void EncGOP::xPicInitLMCS(Picture *pic, PicHeader *picHeader, Slice *slice)
       else if (m_pcCfg->getReshapeSignalType() == RESHAPE_SIGNAL_SDR || m_pcCfg->getReshapeSignalType() == RESHAPE_SIGNAL_HLG)
       {
         int modIP = pic->getPOC() - pic->getPOC() / m_pcCfg->getReshapeCW().rspFpsToIp * m_pcCfg->getReshapeCW().rspFpsToIp;
+#if GDR_ENABLED
+        if (slice->getSPS()->getGDREnabledFlag() && slice->isInterGDR())
+        {
+          modIP = 0;
+        }
+#endif
         if (m_pcReshaper->getReshapeFlag() && m_pcCfg->getReshapeCW().updateCtrl == 2 && modIP == 0)
         {
           m_pcReshaper->getSliceReshaperInfo().setSliceReshapeModelPresentFlag(true);
@@ -1917,9 +2050,17 @@ void EncGOP::xPicInitLMCS(Picture *pic, PicHeader *picHeader, Slice *slice)
     }
 
     //set all necessary information in LMCS APS and picture header
-    picHeader->setLmcsEnabledFlag(m_pcReshaper->getSliceReshaperInfo().getUseSliceReshaper());
+    picHeader->setLmcsEnabledFlag(m_pcReshaper->getSliceReshaperInfo().getUseSliceReshaper());    
     slice->setLmcsEnabledFlag(m_pcReshaper->getSliceReshaperInfo().getUseSliceReshaper());
-    picHeader->setLmcsChromaResidualScaleFlag(m_pcReshaper->getSliceReshaperInfo().getSliceReshapeChromaAdj() == 1);
+    picHeader->setLmcsChromaResidualScaleFlag(m_pcReshaper->getSliceReshaperInfo().getSliceReshapeChromaAdj() == 1);    
+
+#if GDR_ENABLED
+    if (slice->getSPS()->getGDREnabledFlag() && picHeader->getInGdrInterval())
+    {
+      picHeader->setLmcsChromaResidualScaleFlag(false);
+    }
+#endif
+
     if (m_pcReshaper->getSliceReshaperInfo().getSliceReshapeModelPresentFlag())
     {
       int apsId = std::min<int>( 3, m_pcEncLib->getVPS() == nullptr ? 0 : m_pcEncLib->getVPS()->getGeneralLayerIdx( m_pcEncLib->getLayerId() ) );
@@ -1966,7 +2107,7 @@ void EncGOP::xPicInitLMCS(Picture *pic, PicHeader *picHeader, Slice *slice)
 // ====================================================================================================================
 void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
                           std::list<PelUnitBuf*>& rcListPicYuvRecOut,
-                          bool isField, bool isTff, const InputColourSpaceConversion snr_conversion, 
+                          bool isField, bool isTff, const InputColourSpaceConversion snr_conversion,
                           const bool printFrameMSE, const bool printMSSSIM, bool isEncodeLtRef, const int picIdInGOP)
 {
   // TODO: Split this function up.
@@ -2094,9 +2235,6 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
 
     m_pcSliceEncoder->create( picWidth, picHeight, chromaFormatIDC, maxCUWidth, maxCUHeight, maxTotalCUDepth );
 
-#if ENABLE_SPLIT_PARALLELISM
-    pcPic->scheduler.init( pcPic->cs->pcv->heightInCtus, pcPic->cs->pcv->widthInCtus, 1                          , 0                             , m_pcCfg->getNumSplitThreads() );
-#endif
     pcPic->createTempBuffers( pcPic->cs->pps->pcv->maxCUWidth );
     pcPic->cs->createCoeffs((bool)pcPic->cs->sps->getPLTMode());
 
@@ -2105,7 +2243,7 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
     pcPic->allocateNewSlice();
     m_pcSliceEncoder->setSliceSegmentIdx(0);
 
-    m_pcSliceEncoder->initEncSlice(pcPic, iPOCLast, pocCurr, iGOPid, pcSlice, isField, isEncodeLtRef, m_pcEncLib->getLayerId() );
+    m_pcSliceEncoder->initEncSlice(pcPic, iPOCLast, pocCurr, iGOPid, pcSlice, isField, isEncodeLtRef, m_pcEncLib->getLayerId(), getNalUnitType(pocCurr, m_iLastIDR, isField) );
 
     DTRACE_UPDATE( g_trace_ctx, ( std::make_pair( "poc", pocCurr ) ) );
     DTRACE_UPDATE( g_trace_ctx, ( std::make_pair( "final", 0 ) ) );
@@ -2127,6 +2265,18 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
       pcSlice->setSliceType(I_SLICE);
     }
     pcSlice->setTLayer(m_pcCfg->getGOPEntry(iGOPid).m_temporalId);
+#if GDR_ENABLED
+    if (m_pcCfg->getGdrEnabled() && pocCurr >= m_pcCfg->getGdrPocStart() && ((pocCurr - m_pcCfg->getGdrPocStart()) % m_pcCfg->getGdrPeriod() == 0))
+    {
+      pcSlice->setSliceType(B_SLICE);
+    }
+
+    // note : first picture is GDR(I_SLICE)
+    if (m_pcCfg->getGdrEnabled() && pocCurr == 0)
+    {
+      pcSlice->setSliceType(I_SLICE);
+    }
+#endif
 
     // Set the nal unit type
     pcSlice->setNalUnitType(getNalUnitType(pocCurr, m_iLastIDR, isField));
@@ -2149,6 +2299,11 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
       {
         m_associatedIRAPType[pcPic->layerId] = pcSlice->getNalUnitType();
         m_associatedIRAPPOC[pcPic->layerId] = pocCurr;
+        if (m_pcEncLib->getEdrapIndicationSEIEnabled())
+        {
+          m_latestEDRAPPOC = MAX_INT;
+          pcPic->setEdrapRapId(0);
+        }
       }
       pcSlice->setAssociatedIRAPType(m_associatedIRAPType[pcPic->layerId]);
       pcSlice->setAssociatedIRAPPOC(m_associatedIRAPPOC[pcPic->layerId]);
@@ -2187,6 +2342,11 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
       {
         m_associatedIRAPType[pcPic->layerId] = pcSlice->getNalUnitType();
         m_associatedIRAPPOC[pcPic->layerId] = pocCurr;
+        if (m_pcEncLib->getEdrapIndicationSEIEnabled())
+        {
+          m_latestEDRAPPOC = MAX_INT;
+          pcPic->setEdrapRapId(0);
+        }
       }
       pcSlice->setAssociatedIRAPType(m_associatedIRAPType[pcPic->layerId]);
       pcSlice->setAssociatedIRAPPOC(m_associatedIRAPPOC[pcPic->layerId]);
@@ -2221,7 +2381,7 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
         rpcPic = *(iterPic++);
         if ( pcSlice->isDRAP() && rpcPic->getPOC() != pocCurr )
         {
-            rpcPic->precedingDRAP = true;
+          rpcPic->precedingDRAP = true;
         }
         else if ( !pcSlice->isDRAP() && rpcPic->getPOC() == pocCurr )
         {
@@ -2230,8 +2390,60 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
       }
     }
 
+    pcSlice->setEnableEdrapSEI(m_pcEncLib->getEdrapIndicationSEIEnabled());
+    if (m_pcEncLib->getEdrapIndicationSEIEnabled())
+    {
+      // Only mark the picture as Extended DRAP if all of the following applies:
+      //  1) Extended DRAP indication SEI messages are enabled
+      //  2) The current picture is not an intra picture
+      //  3) The current picture is in the EDRAP period
+      //  4) The current picture is a trailing picture
+      if (m_pcEncLib->getEdrapIndicationSEIEnabled() && m_pcEncLib->getEdrapPeriod() > 0 && !pcSlice->isIntra() &&
+          pocCurr % m_pcEncLib->getEdrapPeriod() == 0 && pocCurr > pcSlice->getAssociatedIRAPPOC())
+      {
+        pcSlice->setEdrapRapId(pocCurr / m_pcEncLib->getEdrapPeriod());
+        pcSlice->getPic()->setEdrapRapId(pocCurr / m_pcEncLib->getEdrapPeriod());
+      }
+
+      if (pcSlice->getEdrapRapId() > 0)
+      {
+        m_latestEDRAPPOC = pocCurr;
+        m_latestEdrapLeadingPicDecodableFlag = false;
+        pcSlice->setTLayer(0); // Force Extended DRAP picture to have temporal layer 0
+        msg( NOTICE, "Force the temporal sublayer identifier of the EDRAP picture equal to 0.\n");
+      }
+      pcSlice->setLatestEDRAPPOC(m_latestEDRAPPOC);
+      pcSlice->setLatestEdrapLeadingPicDecodableFlag(m_latestEdrapLeadingPicDecodableFlag);
+      pcSlice->setUseLTforEdrap(false); // When set, sets the associated IRAP/EDRAP as long-term in RPL0 at slice level, unless the associated IRAP/EDRAP is already included in RPL0 or RPL1 defined in SPS
+
+      PicList::iterator iterPic = rcListPic.begin();
+      Picture *rpcPic;
+      while (iterPic != rcListPic.end())
+      {
+        rpcPic = *(iterPic++);
+        if ( pcSlice->getEdrapRapId() > 0 && rpcPic->getPOC() != pocCurr && rpcPic->getPOC() >= pcSlice->getAssociatedIRAPPOC() )
+        {
+          if (rpcPic->getEdrapRapId() >= 0 && rpcPic->getPOC() % m_pcEncLib->getEdrapPeriod() == 0)
+          {
+            bool bRefExist = false;
+            for (int i = 0; i < pcSlice->getEdrapNumRefRapPics(); i++)
+            {
+              if (pcSlice->getEdrapRefRapId(i) == rpcPic->getEdrapRapId())
+                bRefExist = true;
+            }
+            if (!bRefExist)
+            {
+              pcSlice->addEdrapRefRapIds(rpcPic->getPOC() / m_pcEncLib->getEdrapPeriod());
+              pcSlice->setEdrapNumRefRapPics(pcSlice->getEdrapNumRefRapPics() + 1);
+            }
+          }
+        }
+      }
+    }
+
     if (pcSlice->checkThatAllRefPicsAreAvailable(rcListPic, pcSlice->getRPL0(), 0, false) != 0 || pcSlice->checkThatAllRefPicsAreAvailable(rcListPic, pcSlice->getRPL1(), 1, false) != 0 ||
-        (m_pcEncLib->getDependentRAPIndicationSEIEnabled() && !pcSlice->isIRAP() && ( pcSlice->isDRAP() || !pcSlice->isPOCInRefPicList(pcSlice->getRPL0(), pcSlice->getAssociatedIRAPPOC())) )
+        (m_pcEncLib->getDependentRAPIndicationSEIEnabled() && !pcSlice->isIRAP() && ( pcSlice->isDRAP() || !pcSlice->isPOCInRefPicList(pcSlice->getRPL0(), pcSlice->getAssociatedIRAPPOC())) ) ||
+        (m_pcEncLib->getEdrapIndicationSEIEnabled() && !pcSlice->isIRAP() && ( pcSlice->getEdrapRapId() > 0 || !pcSlice->isPOCInRefPicList(pcSlice->getRPL0(), pcSlice->getAssociatedIRAPPOC()) ) )
       || ((m_pcEncLib->getAvoidIntraInDepLayer() || !pcSlice->isIRAP()) && pcSlice->getPic()->cs->vps && m_pcEncLib->getNumRefLayers(pcSlice->getPic()->cs->vps->getGeneralLayerIdx(m_pcEncLib->getLayerId())))
       )
     {
@@ -2245,11 +2457,10 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
         || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RASL)
         )
     {
-    if (pcSlice->isStepwiseTemporalLayerSwitchingPointCandidate(rcListPic))
+      if (pcSlice->isStepwiseTemporalLayerSwitchingPointCandidate(rcListPic))
       {
         bool isSTSA=true;
 
-
         for(int ii=0;(ii<m_pcCfg->getGOPSize() && isSTSA==true);ii++)
         {
           int lTid = m_pcCfg->getRPLEntry(0, ii).m_temporalId;
@@ -2313,7 +2524,8 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
       pcSlice->setNumRefIdx(REF_PIC_LIST_0, (pcSlice->isIntra()) ? 0 : pcSlice->getRPL0()->getNumberOfActivePictures());
       pcSlice->setNumRefIdx(REF_PIC_LIST_1, (!pcSlice->isInterB()) ? 0 : pcSlice->getRPL1()->getNumberOfActivePictures());
     }
-    if (m_pcCfg->getUseCompositeRef() && getPrepareLTRef()) {
+    if (m_pcCfg->getUseCompositeRef() && getPrepareLTRef())
+    {
       arrangeCompositeReference(pcSlice, rcListPic, pocCurr);
     }
     //  Set reference list
@@ -2341,7 +2553,10 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
       if (!pcSlice->isIRAP())
       {
         int refLayer = pcSlice->getDepth();
-        if( refLayer > 9 ) refLayer = 9; // Max layer is 10
+        if (refLayer > 9)
+        {
+          refLayer = 9;   // Max layer is 10
+        }
 
         if( m_bInitAMaxBT && pcSlice->getPOC() > m_uiPrevISlicePOC )
         {
@@ -2450,7 +2665,6 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
 
     if (pcSlice->getSliceType() == B_SLICE)
     {
-
       bool bLowDelay = true;
       int  iCurrPOC  = pcSlice->getPOC();
       int iRefIdx = 0;
@@ -2481,7 +2695,6 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
     //-------------------------------------------------------------
     pcSlice->setRefPOCList();
 
-
     pcSlice->setList1IdxToList0Idx();
 
     if (m_pcEncLib->getTMVPModeId() == 2)
@@ -2583,7 +2796,14 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
       }
     }
 
+#if GDR_ENABLED
+    PicHeader *picHeader = new PicHeader;
+    *picHeader = *pcPic->cs->picHeader;
+    pcSlice->scaleRefPicList(scaledRefPic, picHeader, m_pcEncLib->getApss(), picHeader->getLmcsAPS(), picHeader->getScalingListAPS(), false);
+    picHeader = pcPic->cs->picHeader;
+#else
     pcSlice->scaleRefPicList( scaledRefPic, pcPic->cs->picHeader, m_pcEncLib->getApss(), picHeader->getLmcsAPS(), picHeader->getScalingListAPS(), false );
+#endif
 
     // set adaptive search range for non-intra-slices
     if (m_pcCfg->getUseASR() && !pcSlice->isIntra())
@@ -2697,6 +2917,15 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
       pcSlice->setBiDirPred( false, -1, -1 );
     }
 
+#if JVET_W0133_CONSTRAINED_RASL_ENCODING
+    if( pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RASL && m_pcCfg->getRprRASLtoolSwitch() )
+    {
+      pcSlice->setDisableLmChromaCheck( true );
+      picHeader->setDmvrDisabledFlag( true );
+      xUpdateRPRtmvp( picHeader, pcSlice );
+    }
+#endif
+    
     double lambda            = 0.0;
     int actualHeadBits       = 0;
     int actualTotalBits      = 0;
@@ -2707,9 +2936,7 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
 
     uint32_t uiNumSliceSegments = 1;
 
-    {
-      pcSlice->setDefaultClpRng( *pcSlice->getSPS() );
-    }
+    pcSlice->setDefaultClpRng(*pcSlice->getSPS());
 
     // Allocate some coders, now the number of tiles are known.
     const uint32_t numberOfCtusInFrame = pcPic->cs->pcv->sizeInCtus;
@@ -2795,6 +3022,31 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
     {
       m_pcSliceEncoder->setJointCbCrModes(*pcPic->cs, Position(0, 0), pcPic->cs->area.lumaSize());
     }
+
+#if JVET_W0046_RLSCP
+    if (!pcSlice->getSPS()->getSpsRangeExtension().getReverseLastSigCoeffEnabledFlag() || pcSlice->getSliceQp() > 12)
+    {
+      pcSlice->setReverseLastSigCoeffFlag(false);
+    }
+    else
+    {
+      /*for RA serial and parallel alignment start*/
+      if (m_pcCfg->getIntraPeriod() > 1)
+      {
+        if (pcSlice->isIntra())
+        {
+          m_cnt_right_bottom = 0;
+        }
+        if ((pocCurr % m_pcCfg->getIntraPeriod()) <= m_pcCfg->getGOPSize() && iGOPid == 0 && !pcSlice->isIntra())
+        {
+          m_cnt_right_bottom = m_cnt_right_bottom_i;
+        }
+      }
+      /*for RA serial and parallel alignment end*/
+      pcSlice->setReverseLastSigCoeffFlag(m_cnt_right_bottom >= 0);
+    }
+#endif
+
     if( encPic )
     // now compress (trial encode) the various slice segments (slices, and dependent slices)
     {
@@ -2809,6 +3061,57 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
       for(uint32_t sliceIdx = 0; sliceIdx < pcPic->cs->pps->getNumSlicesInPic(); sliceIdx++ )
       {
         pcSlice->setSliceMap( pcPic->cs->pps->getSliceMap( sliceIdx ) );
+        if (pcSlice->getSPS()->getSpsRangeExtension().getTSRCRicePresentFlag() && (pcPic->cs->pps->getNumSlicesInPic() == 1))
+        {
+          if (!pcSlice->isIntra())
+          {
+            int nextRice = 1;
+
+            if (m_preIPOC < pocCurr)
+            {
+              for (int idx = 0; idx < MAX_TSRC_RICE; idx++)
+              {
+                m_riceBit[idx][0] = m_riceBit[idx][1];
+              }
+              m_preQP[0] = m_preQP[1];
+              m_preIPOC = MAX_INT;
+            }
+
+            if (m_preQP[0] != pcSlice->getSliceQp())
+            {
+              m_riceBit[pcSlice->get_tsrc_index()][0] = (int) (m_riceBit[pcSlice->get_tsrc_index()][0] * 9 / 10);
+            }
+
+            for (int idx = 2; idx < 9; idx++)
+            {
+              if (m_riceBit[idx - 2][0] > m_riceBit[idx - 1][0])
+              {
+                nextRice = idx;
+              }
+              else
+              {
+                m_riceBit[idx - 1][0] = m_riceBit[idx - 2][0];
+              }
+              m_riceBit[idx - 2][0] = 0;
+            }
+            m_riceBit[7][0] = 0;
+            pcSlice->set_tsrc_index(nextRice - 1);
+          }
+          else
+          {
+            m_preIPOC = pocCurr;
+            m_preQP[0] = MAX_INT;          
+            m_preQP[1] = pcSlice->getSliceQp();
+            for (int idx = 0; idx < MAX_TSRC_RICE; idx++)
+            {
+              m_riceBit[idx][0] = 0;
+            }
+          }
+          for (int idx = 0; idx < MAX_TSRC_RICE; idx++)
+          {
+             pcSlice->setRiceBit(idx, m_riceBit[idx][0]);
+          }
+        }
         if( pcPic->cs->pps->getRectSliceFlag() )
         {
           Position firstCtu;
@@ -2840,7 +3143,7 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
             else
             {
               pcPic->getOrigBuf().copyFrom(pcPic->getTrueOrigBuf());
-            } 
+            }
 
             if (pcSlice->getLmcsEnabledFlag())
             {
@@ -2901,6 +3204,12 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
       if (cs.sps->getUseLmcs() && m_pcReshaper->getSliceReshaperInfo().getUseSliceReshaper())
       {
         picHeader->setLmcsEnabledFlag(true);
+#if GDR_ENABLED
+        if (cs.sps->getGDREnabledFlag() && picHeader->getInGdrInterval())
+        {
+          picHeader->setLmcsChromaResidualScaleFlag(false);
+        }
+#endif
         int apsId = std::min<int>(3, m_pcEncLib->getVPS() == nullptr ? 0 : m_pcEncLib->getVPS()->getGeneralLayerIdx(m_pcEncLib->getLayerId()));
         picHeader->setLmcsAPSId(apsId);
 
@@ -2928,7 +3237,7 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
         else
         {
           pcPic->getOrigBuf().copyFrom(pcPic->getTrueOrigBuf());
-        } 
+        }
       }
 
       // create SAO object based on the picture size
@@ -2957,7 +3266,11 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
       // SAO parameter estimation using non-deblocked pixels for CTU bottom and right boundary areas
       if( pcSlice->getSPS()->getSAOEnabledFlag() && m_pcCfg->getSaoCtuBoundary() )
       {
-        m_pcSAO->getPreDBFStatistics( cs );
+#if JVET_W0129_ENABLE_ALF_TRUEORG
+        m_pcSAO->getPreDBFStatistics( cs, m_pcCfg->getSaoTrueOrg() );
+#else
+        m_pcSAO->getPreDBFStatistics( cs, m_pcCfg->getAlfSaoTrueOrg() );
+#endif
       }
 
       //-- Loop filter
@@ -2969,14 +3282,12 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
           applyDeblockingFilterParameterSelection(pcPic, uiNumSliceSegments, iGOPid);
         }
         else
-        {
   #endif
+        {
           applyDeblockingFilterMetric(pcPic, uiNumSliceSegments);
-  #if W0038_DB_OPT
         }
-  #endif
       }
-      if (m_pcCfg->getCostMode() == COST_LOSSLESS_CODING) 
+      if (m_pcCfg->getCostMode() == COST_LOSSLESS_CODING)
       {
         for (int s = 0; s < uiNumSliceSegments; s++)
         {
@@ -2986,7 +3297,7 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
           }
         }
       }
-      m_pcLoopFilter->loopFilterPic( cs );
+      m_pcLoopFilter->deblockingFilterPic( cs );
 
       CS::setRefinedMotionField(cs);
 
@@ -2994,16 +3305,22 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
       {
         bool sliceEnabled[MAX_NUM_COMPONENT];
         m_pcSAO->initCABACEstimator( m_pcEncLib->getCABACEncoder(), m_pcEncLib->getCtxCache(), pcSlice );
-
+#if JVET_W0129_ENABLE_ALF_TRUEORG
         m_pcSAO->SAOProcess( cs, sliceEnabled, pcSlice->getLambdas(),
 #if ENABLE_QPA
-                             (m_pcCfg->getUsePerceptQPA() && !m_pcCfg->getUseRateCtrl() && pcSlice->getPPS()->getUseDQP() ? m_pcEncLib->getRdCost (PARL_PARAM0 (0))->getChromaWeight() : 0.0),
+                             (m_pcCfg->getUsePerceptQPA() && !m_pcCfg->getUseRateCtrl() && pcSlice->getPPS()->getUseDQP() ? m_pcEncLib->getRdCost ()->getChromaWeight() : 0.0),
+#endif
+                             m_pcCfg->getTestSAODisableAtPictureLevel(), m_pcCfg->getSaoEncodingRate(), m_pcCfg->getSaoEncodingRateChroma(), m_pcCfg->getSaoCtuBoundary(), m_pcCfg->getSaoGreedyMergeEnc(), m_pcCfg->getSaoTrueOrg() );
+#else
+        m_pcSAO->SAOProcess( cs, sliceEnabled, pcSlice->getLambdas(),
+#if ENABLE_QPA
+                             (m_pcCfg->getUsePerceptQPA() && !m_pcCfg->getUseRateCtrl() && pcSlice->getPPS()->getUseDQP() ? m_pcEncLib->getRdCost ()->getChromaWeight() : 0.0),
+#endif
+                             m_pcCfg->getTestSAODisableAtPictureLevel(), m_pcCfg->getSaoEncodingRate(), m_pcCfg->getSaoEncodingRateChroma(), m_pcCfg->getSaoCtuBoundary(), m_pcCfg->getSaoGreedyMergeEnc(), m_pcCfg->getAlfSaoTrueOrg() );
 #endif
-                             m_pcCfg->getTestSAODisableAtPictureLevel(), m_pcCfg->getSaoEncodingRate(), m_pcCfg->getSaoEncodingRateChroma(), m_pcCfg->getSaoCtuBoundary(), m_pcCfg->getSaoGreedyMergeEnc() );
         //assign SAO slice header
         for (int s = 0; s < uiNumSliceSegments; s++)
         {
-
           if (pcPic->slices[s]->isLossless() && m_pcCfg->getCostMode() == COST_LOSSLESS_CODING)
           {
             pcPic->slices[s]->setSaoEnabledFlag(CHANNEL_TYPE_LUMA, false);
@@ -3014,9 +3331,7 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
             pcPic->slices[s]->setSaoEnabledFlag(CHANNEL_TYPE_LUMA, sliceEnabled[COMPONENT_Y]);
             CHECK(!(sliceEnabled[COMPONENT_Cb] == sliceEnabled[COMPONENT_Cr]), "Unspecified error");
             pcPic->slices[s]->setSaoEnabledFlag(CHANNEL_TYPE_CHROMA, sliceEnabled[COMPONENT_Cb]);
-
-        }
-
+          }
         }
       }
 
@@ -3027,12 +3342,12 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
 
         for (int s = 0; s < uiNumSliceSegments; s++)
         {
-          pcPic->slices[s]->setTileGroupAlfEnabledFlag(COMPONENT_Y, false);
+          pcPic->slices[s]->setAlfEnabledFlag(COMPONENT_Y, false);
         }
         m_pcALF->initCABACEstimator(m_pcEncLib->getCABACEncoder(), m_pcEncLib->getCtxCache(), pcSlice, m_pcEncLib->getApsMap());
         m_pcALF->ALFProcess(cs, pcSlice->getLambdas()
 #if ENABLE_QPA
-          , (m_pcCfg->getUsePerceptQPA() && !m_pcCfg->getUseRateCtrl() && pcSlice->getPPS()->getUseDQP() ? m_pcEncLib->getRdCost(PARL_PARAM0(0))->getChromaWeight() : 0.0)
+          , (m_pcCfg->getUsePerceptQPA() && !m_pcCfg->getUseRateCtrl() && pcSlice->getPPS()->getUseDQP() ? m_pcEncLib->getRdCost()->getChromaWeight() : 0.0)
 #endif
           , pcPic, uiNumSliceSegments
         );
@@ -3040,40 +3355,44 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
         //assign ALF slice header
         for (int s = 0; s < uiNumSliceSegments; s++)
         {
-           //For the first slice, even if it is lossless, slice level ALF is not disabled and ALF-APS is signaled so that the later lossy slices can use APS of the first slice. 
-           //However, if the first slice is lossless, the ALF process is disabled for all of the CTUs ( m_ctuEnableFlag == 0) of that slice which is implemented in the function void EncAdaptiveLoopFilter::ALFProcess.         
-      
+           //For the first slice, even if it is lossless, slice level ALF is not disabled and ALF-APS is signaled so that the later lossy slices can use APS of the first slice.
+           //However, if the first slice is lossless, the ALF process is disabled for all of the CTUs ( m_ctuEnableFlag == 0) of that slice which is implemented in the function void EncAdaptiveLoopFilter::ALFProcess.
+
           if (pcPic->slices[s]->isLossless() && s && m_pcCfg->getCostMode() == COST_LOSSLESS_CODING)
           {
-            pcPic->slices[s]->setTileGroupAlfEnabledFlag(COMPONENT_Y, false);
-            pcPic->slices[s]->setTileGroupAlfEnabledFlag(COMPONENT_Cb, false);
-            pcPic->slices[s]->setTileGroupAlfEnabledFlag(COMPONENT_Cr, false);
+            pcPic->slices[s]->setAlfEnabledFlag(COMPONENT_Y, false);
+            pcPic->slices[s]->setAlfEnabledFlag(COMPONENT_Cb, false);
+            pcPic->slices[s]->setAlfEnabledFlag(COMPONENT_Cr, false);
           }
           else
           {
-            pcPic->slices[s]->setTileGroupAlfEnabledFlag(COMPONENT_Y, cs.slice->getTileGroupAlfEnabledFlag(COMPONENT_Y));
-            pcPic->slices[s]->setTileGroupAlfEnabledFlag(COMPONENT_Cb, cs.slice->getTileGroupAlfEnabledFlag(COMPONENT_Cb));
-            pcPic->slices[s]->setTileGroupAlfEnabledFlag(COMPONENT_Cr, cs.slice->getTileGroupAlfEnabledFlag(COMPONENT_Cr));
+            pcPic->slices[s]->setAlfEnabledFlag(COMPONENT_Y, cs.slice->getAlfEnabledFlag(COMPONENT_Y));
+            pcPic->slices[s]->setAlfEnabledFlag(COMPONENT_Cb, cs.slice->getAlfEnabledFlag(COMPONENT_Cb));
+            pcPic->slices[s]->setAlfEnabledFlag(COMPONENT_Cr, cs.slice->getAlfEnabledFlag(COMPONENT_Cr));
 
           }
-          if (pcPic->slices[s]->getTileGroupAlfEnabledFlag(COMPONENT_Y))
+          if (pcPic->slices[s]->getAlfEnabledFlag(COMPONENT_Y))
           {
-            pcPic->slices[s]->setTileGroupNumAps(cs.slice->getTileGroupNumAps());
-            pcPic->slices[s]->setAlfAPSs(cs.slice->getTileGroupApsIdLuma());
+            pcPic->slices[s]->setNumAlfApsIdsLuma(cs.slice->getNumAlfApsIdsLuma());
+            pcPic->slices[s]->setAlfApsIdsLuma(cs.slice->getAlfApsIdsLuma());
           }
           else
           {
-            pcPic->slices[s]->setTileGroupNumAps(0);
+            pcPic->slices[s]->setNumAlfApsIdsLuma(0);
           }
           pcPic->slices[s]->setAlfAPSs(cs.slice->getAlfAPSs());
-          pcPic->slices[s]->setTileGroupApsIdChroma(cs.slice->getTileGroupApsIdChroma());
-          pcPic->slices[s]->setTileGroupCcAlfCbApsId(cs.slice->getTileGroupCcAlfCbApsId());
-          pcPic->slices[s]->setTileGroupCcAlfCrApsId(cs.slice->getTileGroupCcAlfCrApsId());
+          pcPic->slices[s]->setAlfApsIdChroma(cs.slice->getAlfApsIdChroma());
+          pcPic->slices[s]->setCcAlfCbApsId(cs.slice->getCcAlfCbApsId());
+          pcPic->slices[s]->setCcAlfCrApsId(cs.slice->getCcAlfCrApsId());
           pcPic->slices[s]->m_ccAlfFilterParam      = m_pcALF->getCcAlfFilterParam();
           pcPic->slices[s]->m_ccAlfFilterControl[0] = m_pcALF->getCcAlfControlIdc(COMPONENT_Cb);
           pcPic->slices[s]->m_ccAlfFilterControl[1] = m_pcALF->getCcAlfControlIdc(COMPONENT_Cr);
         }
       }
+      else if (!layerIdx && (cs.slice->getPendingRasInit() || cs.slice->isIDRorBLA()))
+      {
+        m_pcALF->setApsIdStart(ALF_CTB_MAX_NUM_APS);
+      }
       DTRACE_UPDATE( g_trace_ctx, ( std::make_pair( "final", 1 ) ) );
       if (m_pcCfg->getUseCompositeRef() && getPrepareLTRef())
       {
@@ -3099,7 +3418,7 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
       {
         m_pcSAO->disabledRate( *pcPic->cs, pcPic->getSAO(1), m_pcCfg->getSaoEncodingRate(), m_pcCfg->getSaoEncodingRateChroma());
       }
-      if (pcSlice->getSPS()->getALFEnabledFlag() && (pcSlice->getTileGroupAlfEnabledFlag(COMPONENT_Y) || pcSlice->getTileGroupCcAlfCbEnabledFlag() || pcSlice->getTileGroupCcAlfCrEnabledFlag()))
+      if (pcSlice->getSPS()->getALFEnabledFlag() && (pcSlice->getAlfEnabledFlag(COMPONENT_Y) || pcSlice->getCcAlfCbEnabledFlag() || pcSlice->getCcAlfCrEnabledFlag()))
       {
         // IRAP AU: reset APS map
         {
@@ -3108,7 +3427,7 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
           {
             // We have to reset all APS on IRAP, but in not encoding case we have to keep the parsed APS of current slice
             // Get active ALF APSs from picture/slice header
-            const std::vector<int> sliceApsIdsLuma = pcSlice->getTileGroupApsIdLuma();
+            const std::vector<int> sliceApsIdsLuma = pcSlice->getAlfApsIdsLuma();
 
             m_pcALF->setApsIdStart( ALF_CTB_MAX_NUM_APS );
 
@@ -3134,10 +3453,10 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
                   }
                 }
                 // Chroma
-                activeAps |= aps->getAPSId() == pcSlice->getTileGroupApsIdChroma();
+                activeAps |= aps->getAPSId() == pcSlice->getAlfApsIdChroma();
                 // CC-ALF
-                activeApsCcAlf |= pcSlice->getTileGroupCcAlfCbEnabledFlag() && aps->getAPSId() == pcSlice->getTileGroupCcAlfCbApsId();
-                activeApsCcAlf |= pcSlice->getTileGroupCcAlfCrEnabledFlag() && aps->getAPSId() == pcSlice->getTileGroupCcAlfCrApsId();
+                activeApsCcAlf |= pcSlice->getCcAlfCbEnabledFlag() && aps->getAPSId() == pcSlice->getCcAlfCbApsId();
+                activeApsCcAlf |= pcSlice->getCcAlfCrEnabledFlag() && aps->getAPSId() == pcSlice->getCcAlfCrApsId();
                 if( !activeAps && !activeApsCcAlf )
                 {
                   apsMap->clearChangedFlag( psId );
@@ -3170,11 +3489,15 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
               pcSlice->getAlfAPSs()[apsId] = aps;
             }
             if( apsMap->getChangedFlag( psId ) )
+            {
               changedApsId = apsId;
+            }
           }
         }
         if( changedApsId >= 0 )
+        {
           m_pcALF->setApsIdStart( changedApsId );
+        }
       }
     }
 
@@ -3199,7 +3522,11 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
       /////////////////////////////////////////////////////////////////////////////////////////////////// File writing
 
       // write various parameter sets
+#if GDR_ENABLED // Note : insert SPS/PPS at every GDR picture
+      bool writePS = m_bSeqFirst || (m_pcCfg->getReWriteParamSets() && (pcSlice->isIRAP())) || pcSlice->isInterGDR();
+#else
       bool writePS = m_bSeqFirst || (m_pcCfg->getReWriteParamSets() && (pcSlice->isIRAP()));
+#endif
       if (writePS)
       {
         m_pcEncLib->setParamSetChanged(pcSlice->getSPS()->getSPSId(), pcSlice->getPPS()->getPPSId());
@@ -3235,12 +3562,25 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
         ParameterSetMap<APS> *apsMap = m_pcEncLib->getApsMap();
         APS* aps = apsMap->getPS((apsId << NUM_APS_TYPE_LEN) + LMCS_APS);
         bool writeAPS = aps && apsMap->getChangedFlag((apsId << NUM_APS_TYPE_LEN) + LMCS_APS);
+#if GDR_ENABLED // note : insert APS at every GDR picture
+        if (aps && apsId >= 0)
+        {
+          writeAPS |= pcSlice->isInterGDR();
+        }
+#endif
         if (writeAPS)
         {
           aps->chromaPresentFlag = pcSlice->getSPS()->getChromaFormatIdc() != CHROMA_400;
           actualTotalBits += xWriteAPS( accessUnit, aps, m_pcEncLib->getLayerId(), true );
           apsMap->clearChangedFlag((apsId << NUM_APS_TYPE_LEN) + LMCS_APS);
+#if GDR_ENABLED
+          if (!pcSlice->isInterGDR())
+          {
+            CHECK(aps != picHeader->getLmcsAPS(), "Wrong LMCS APS pointer in compressGOP");
+          }
+#else
           CHECK(aps != picHeader->getLmcsAPS(), "Wrong LMCS APS pointer in compressGOP");
+#endif
         }
       }
 
@@ -3251,16 +3591,29 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
         ParameterSetMap<APS> *apsMap = m_pcEncLib->getApsMap();
         APS* aps = apsMap->getPS( ( apsId << NUM_APS_TYPE_LEN ) + SCALING_LIST_APS );
         bool writeAPS = aps && apsMap->getChangedFlag( ( apsId << NUM_APS_TYPE_LEN ) + SCALING_LIST_APS );
+#if GDR_ENABLED // note : insert APS at every GDR picture
+        if (aps && apsId >= 0)
+        {
+          writeAPS |= pcSlice->isInterGDR();
+        }
+#endif
         if( writeAPS )
         {
           aps->chromaPresentFlag = pcSlice->getSPS()->getChromaFormatIdc() != CHROMA_400;
           actualTotalBits += xWriteAPS( accessUnit, aps, m_pcEncLib->getLayerId(), true );
           apsMap->clearChangedFlag( ( apsId << NUM_APS_TYPE_LEN ) + SCALING_LIST_APS );
+#if GDR_ENABLED
+          if (!pcSlice->isInterGDR())
+          {
+            CHECK(aps != picHeader->getScalingListAPS(), "Wrong SCALING LIST APS pointer in compressGOP");
+          }
+#else
           CHECK( aps != picHeader->getScalingListAPS(), "Wrong SCALING LIST APS pointer in compressGOP" );
+#endif
         }
       }
 
-      if (pcSlice->getSPS()->getALFEnabledFlag() && (pcSlice->getTileGroupAlfEnabledFlag(COMPONENT_Y) || pcSlice->getTileGroupCcAlfCbEnabledFlag() || pcSlice->getTileGroupCcAlfCrEnabledFlag()))
+      if (pcSlice->getSPS()->getALFEnabledFlag() && (pcSlice->getAlfEnabledFlag(COMPONENT_Y) || pcSlice->getCcAlfCbEnabledFlag() || pcSlice->getCcAlfCrEnabledFlag()))
       {
         for (int apsId = 0; apsId < ALF_CTB_MAX_NUM_APS; apsId++)
         {
@@ -3275,23 +3628,35 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
             *apsMap->allocatePS((apsId << NUM_APS_TYPE_LEN) + ALF_APS) = *aps; //allocate and cpy
             m_pcALF->setApsIdStart( apsId );
           }
-          else if (pcSlice->getTileGroupCcAlfCbEnabledFlag() && !aps && apsId == pcSlice->getTileGroupCcAlfCbApsId())
+          else if (pcSlice->getCcAlfCbEnabledFlag() && !aps && apsId == pcSlice->getCcAlfCbApsId())
           {
             writeAPS = true;
-            aps = apsMap->getPS((pcSlice->getTileGroupCcAlfCbApsId() << NUM_APS_TYPE_LEN) + ALF_APS);
+            aps = apsMap->getPS((pcSlice->getCcAlfCbApsId() << NUM_APS_TYPE_LEN) + ALF_APS);
           }
-          else if (pcSlice->getTileGroupCcAlfCrEnabledFlag() && !aps && apsId == pcSlice->getTileGroupCcAlfCrApsId())
+          else if (pcSlice->getCcAlfCrEnabledFlag() && !aps && apsId == pcSlice->getCcAlfCrApsId())
           {
             writeAPS = true;
-            aps = apsMap->getPS((pcSlice->getTileGroupCcAlfCrApsId() << NUM_APS_TYPE_LEN) + ALF_APS);
+            aps = apsMap->getPS((pcSlice->getCcAlfCrApsId() << NUM_APS_TYPE_LEN) + ALF_APS);
           }
-
+#if GDR_ENABLED // note : insert APS at every GDR picture
+          if (aps && apsId >= 0)
+          {
+            writeAPS |= (pcSlice->isInterGDR());
+          }
+#endif
           if (writeAPS )
           {
             aps->chromaPresentFlag = pcSlice->getSPS()->getChromaFormatIdc() != CHROMA_400;
             actualTotalBits += xWriteAPS( accessUnit, aps, m_pcEncLib->getLayerId(), true );
             apsMap->clearChangedFlag((apsId << NUM_APS_TYPE_LEN) + ALF_APS);
-            CHECK(aps != pcSlice->getAlfAPSs()[apsId] && apsId != pcSlice->getTileGroupCcAlfCbApsId() && apsId != pcSlice->getTileGroupCcAlfCrApsId(), "Wrong APS pointer in compressGOP");
+#if GDR_ENABLED
+            if (!pcSlice->isInterGDR())
+            {
+              CHECK(aps != pcSlice->getAlfAPSs()[apsId] && apsId != pcSlice->getCcAlfCbApsId() && apsId != pcSlice->getCcAlfCrApsId(), "Wrong APS pointer in compressGOP");
+            }
+#else
+            CHECK(aps != pcSlice->getAlfAPSs()[apsId] && apsId != pcSlice->getCcAlfCbApsId() && apsId != pcSlice->getCcAlfCrApsId(), "Wrong APS pointer in compressGOP");
+#endif
           }
         }
       }
@@ -3379,16 +3744,16 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
           // code ALF parameters in picture header or slice headers
           if( !m_pcCfg->getSliceLevelAlf() )
           {
-            picHeader->setAlfEnabledFlag(COMPONENT_Y,  pcSlice->getTileGroupAlfEnabledFlag(COMPONENT_Y ) );
-            picHeader->setAlfEnabledFlag(COMPONENT_Cb, pcSlice->getTileGroupAlfEnabledFlag(COMPONENT_Cb) );
-            picHeader->setAlfEnabledFlag(COMPONENT_Cr, pcSlice->getTileGroupAlfEnabledFlag(COMPONENT_Cr) );
-            picHeader->setNumAlfAps(pcSlice->getTileGroupNumAps());
-            picHeader->setAlfAPSs(pcSlice->getTileGroupApsIdLuma());
-            picHeader->setAlfApsIdChroma(pcSlice->getTileGroupApsIdChroma());
-            picHeader->setCcAlfEnabledFlag(COMPONENT_Cb, pcSlice->getTileGroupCcAlfCbEnabledFlag());
-            picHeader->setCcAlfEnabledFlag(COMPONENT_Cr, pcSlice->getTileGroupCcAlfCrEnabledFlag());
-            picHeader->setCcAlfCbApsId(pcSlice->getTileGroupCcAlfCbApsId());
-            picHeader->setCcAlfCrApsId(pcSlice->getTileGroupCcAlfCrApsId());
+            picHeader->setAlfEnabledFlag(COMPONENT_Y,  pcSlice->getAlfEnabledFlag(COMPONENT_Y ) );
+            picHeader->setAlfEnabledFlag(COMPONENT_Cb, pcSlice->getAlfEnabledFlag(COMPONENT_Cb) );
+            picHeader->setAlfEnabledFlag(COMPONENT_Cr, pcSlice->getAlfEnabledFlag(COMPONENT_Cr) );
+            picHeader->setNumAlfApsIdsLuma(pcSlice->getNumAlfApsIdsLuma());
+            picHeader->setAlfApsIdsLuma(pcSlice->getAlfApsIdsLuma());
+            picHeader->setAlfApsIdChroma(pcSlice->getAlfApsIdChroma());
+            picHeader->setCcAlfEnabledFlag(COMPONENT_Cb, pcSlice->getCcAlfCbEnabledFlag());
+            picHeader->setCcAlfEnabledFlag(COMPONENT_Cr, pcSlice->getCcAlfCrEnabledFlag());
+            picHeader->setCcAlfCbApsId(pcSlice->getCcAlfCbApsId());
+            picHeader->setCcAlfCrApsId(pcSlice->getCcAlfCrApsId());
           }
 
           // code WP parameters in picture header or slice headers
@@ -3427,7 +3792,6 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
         OutputNALUnit nalu( pcSlice->getNalUnitType(), m_pcEncLib->getLayerId(), pcSlice->getTLayer() );
         m_HLSWriter->setBitstream( &nalu.m_Bitstream );
 
-
         tmpBitsBeforeWriting = m_HLSWriter->getNumberOfWrittenBits();
         m_HLSWriter->codeSliceHeader( pcSlice );
         actualHeadBits += ( m_HLSWriter->getNumberOfWrittenBits() - tmpBitsBeforeWriting );
@@ -3444,6 +3808,21 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
           binCountsInNalUnits+=numBinsCoded;
           subPicStats[subpicIdx].numBinsWritten += numBinsCoded;
         }
+        if (pcSlice->getSPS()->getSpsRangeExtension().getTSRCRicePresentFlag() && (pcPic->cs->pps->getNumSlicesInPic() == 1))
+        {
+          if (pcSlice->getSliceType() == I_SLICE)
+          {
+            for (int idx = 0; idx < MAX_TSRC_RICE; idx++)
+            {
+              m_riceBit[idx][1] = pcSlice->getRiceBit(idx);
+            }
+          }
+          for (int idx = 0; idx < MAX_TSRC_RICE; idx++)
+          {
+            m_riceBit[idx][0] = pcSlice->getRiceBit(idx);
+          }
+          m_preQP[0] = pcSlice->getSliceQp();
+        }
         {
           // Construct the final bitstream by concatenating substreams.
           // The final bitstream is either nalu.m_Bitstream or pcBitstreamRedirect;
@@ -3498,6 +3877,12 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
           // Check picture level encoding constraints/requirements
           ProfileLevelTierFeatures profileLevelTierFeatures;
           profileLevelTierFeatures.extractPTLInformation(*(pcSlice->getSPS()));
+          const SEIMessages& subPictureLevelInfoSEIs = getSeisByType(leadingSeiMessages, SEI::SUBPICTURE_LEVEL_INFO);
+          if (!subPictureLevelInfoSEIs.empty())
+          {
+            const SEISubpicureLevelInfo& seiSubpic = static_cast<const SEISubpicureLevelInfo&>(*subPictureLevelInfoSEIs.front());
+            validateMinCrRequirements(profileLevelTierFeatures, subPicStats[subpicIdx].numBytesInVclNalUnits, pcSlice, m_pcCfg, seiSubpic, subpicIdx, m_pcEncLib->getLayerId());
+          }
           sumZeroWords += cabac_zero_word_padding(pcSlice, pcPic, subPicStats[subpicIdx].numBinsWritten, subPicStats[subpicIdx].numBytesInVclNalUnits, 0,
                                                   accessUnit.back()->m_nalUnitData, m_pcCfg->getCabacZeroWordPaddingEnabled(), profileLevelTierFeatures);
         }
@@ -3517,7 +3902,13 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
       auto encTime = std::chrono::duration_cast<std::chrono::seconds>( elapsed ).count();
 
       std::string digestStr;
+#if GDR_ENABLED
+      // note : generate hash sei only for non-gdr pictures
+      bool genHash = !(m_pcCfg->getGdrNoHash() && pcSlice->getPicHeader()->getInGdrInterval());
+      if (m_pcCfg->getDecodedPictureHashSEIType() != HASHTYPE_NONE && genHash)
+#else
       if (m_pcCfg->getDecodedPictureHashSEIType()!=HASHTYPE_NONE)
+#endif
       {
         SEIDecodedPictureHash *decodedPictureHashSei = new SEIDecodedPictureHash();
         PelUnitBuf recoBuf = pcPic->cs->getRecoBuf();
@@ -3530,6 +3921,9 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
       std::string subPicDigest;
       if (numSubpics > 1 && m_pcCfg->getSubpicDecodedPictureHashType() != HASHTYPE_NONE )
       {
+        std::vector<uint16_t> subPicIdsInPic;
+        xGetSubpicIdsInPic(subPicIdsInPic, pcPic->cs->sps, pps);
+        uint16_t maxSubpicIdInPic = subPicIdsInPic.size() == 0 ? 0 : *std::max_element(subPicIdsInPic.begin(), subPicIdsInPic.end());
         for (int subPicIdx = 0; subPicIdx < numSubpics; subPicIdx++)
         {
           const SubPic& subpic = pps->getSubPic(subPicIdx);
@@ -3542,20 +3936,27 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
           const std::vector<uint16_t> subPicIds = { (uint16_t)subpic.getSubPicID() };
           std::vector<int> targetOLS;
           std::vector<int> targetLayers = {pcPic->layerId};
-          xCreateScalableNestingSEI(trailingSeiMessages, nestedSEI, targetOLS, targetLayers, subPicIds);
+          xCreateScalableNestingSEI(trailingSeiMessages, nestedSEI, targetOLS, targetLayers, subPicIds, maxSubpicIdInPic);
         }
       }
 
       m_pcCfg->setEncodedFlag(iGOPid, true);
 
       double PSNR_Y;
-      xCalculateAddPSNRs(isField, isTff, iGOPid, pcPic, accessUnit, rcListPic, encTime, snr_conversion, 
+      xCalculateAddPSNRs(isField, isTff, iGOPid, pcPic, accessUnit, rcListPic, encTime, snr_conversion,
         printFrameMSE, printMSSSIM, &PSNR_Y, isEncodeLtRef );
 
 
       xWriteTrailingSEIMessages(trailingSeiMessages, accessUnit, pcSlice->getTLayer());
 
+#if GDR_ENABLED
+      if (!(m_pcCfg->getGdrNoHash() && pcSlice->getPicHeader()->getInGdrInterval()))
+      {
+          printHash(m_pcCfg->getDecodedPictureHashSEIType(), digestStr);
+      }
+#else
       printHash(m_pcCfg->getDecodedPictureHashSEIType(), digestStr);
+#endif
 
       if ( m_pcCfg->getUseRateCtrl() )
       {
@@ -3595,34 +3996,13 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
         const PPS* pps = pcSlice->getPPS();
 
         std::vector<uint16_t> subpicIDs;
-        if (sps->getSubPicInfoPresentFlag())
-        {
-          if(sps->getSubPicIdMappingExplicitlySignalledFlag())
-          {
-            if(sps->getSubPicIdMappingPresentFlag())
-            {
-              subpicIDs = sps->getSubPicIds();
-            }
-            else
-            {
-              subpicIDs = pps->getSubPicIds();
-            }
-          }
-          else
-          {
-            const int numSubPics = sps->getNumSubPics();
-            subpicIDs.resize(numSubPics);
-            for (int i = 0 ; i < numSubPics; i++)
-            {
-              subpicIDs[i] = (uint16_t) i;
-            }
-          }
-        }
+        xGetSubpicIdsInPic(subpicIDs, sps, pps);
+        uint16_t maxSubpicIdInPic = subpicIDs.size() == 0 ? 0 : *std::max_element(subpicIDs.begin(), subpicIDs.end());
         // Note (KJS): Using targetOLS = 0, 1 is as random as encapsulating the same SEIs in scalable nesting.
         //             This can just be seen as example regarding how to write scalable nesting, not what to write.
         std::vector<int> targetOLS = {0, 1};
         std::vector<int> targetLayers;
-        xCreateScalableNestingSEI(leadingSeiMessages, nestedSeiMessages, targetOLS, targetLayers, subpicIDs);
+        xCreateScalableNestingSEI(leadingSeiMessages, nestedSeiMessages, targetOLS, targetLayers, subpicIDs, maxSubpicIdInPic);
       }
 
       xWriteLeadingSEIMessages( leadingSeiMessages, duInfoSeiMessages, accessUnit, pcSlice->getTLayer(), pcSlice->getSPS(), duData );
@@ -3634,6 +4014,13 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
       fflush( stdout );
     }
 
+#if JVET_W0046_RLSCP
+    m_cnt_right_bottom = pcSlice->getCntRightBottom();
+    if (m_pcCfg->getIntraPeriod() > 1 && pcSlice->isIntra())
+    {
+      m_cnt_right_bottom_i = m_cnt_right_bottom;
+    }
+#endif
 
     DTRACE_UPDATE( g_trace_ctx, ( std::make_pair( "final", 0 ) ) );
 
@@ -3664,15 +4051,19 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
   CHECK( m_iNumPicCoded > 1, "Unspecified error" );
 }
 
-void EncGOP::printOutSummary( uint32_t uiNumAllPicCoded, bool isField, const bool printMSEBasedSNR, 
-  const bool printSequenceMSE, const bool printMSSSIM, const bool printHexPsnr, const bool printRprPSNR, 
-  const BitDepths &bitDepths )
+void EncGOP::printOutSummary( uint32_t uiNumAllPicCoded, bool isField, const bool printMSEBasedSNR,
+  const bool printSequenceMSE, const bool printMSSSIM, const bool printHexPsnr, const bool printRprPSNR,
+  const BitDepths &bitDepths
+#if JVET_W0134_UNIFORM_METRICS_LOG
+                             , int layerId
+#endif
+                             )
 {
 #if ENABLE_QPA
   const bool    useWPSNR = m_pcEncLib->getUseWPSNR();
 #endif
 #if WCG_WPSNR
-  const bool    useLumaWPSNR = m_pcEncLib->getLumaLevelToDeltaQPMapping().isEnabled() || (m_pcCfg->getLmcs() && m_pcCfg->getReshapeSignalType() == RESHAPE_SIGNAL_PQ);
+  const bool    useLumaWPSNR = m_pcEncLib->getPrintWPSNR();
 #endif
 
   if( m_pcCfg->getDecodeBitstream(0).empty() && m_pcCfg->getDecodeBitstream(1).empty() && !m_pcCfg->useFastForwardToPOC() )
@@ -3701,8 +4092,22 @@ void EncGOP::printOutSummary( uint32_t uiNumAllPicCoded, bool isField, const boo
 #if JVET_O0756_CALCULATE_HDRMETRICS
   const bool calculateHdrMetrics = m_pcEncLib->getCalcluateHdrMetrics();
 #endif
+
+
+#if JVET_W0134_UNIFORM_METRICS_LOG
+  std::string header,metrics;
+  std::string id="a";
+  if (layerId==0) id+=' ';
+  else            id+=std::to_string(layerId);
+  m_gcAnalyzeAll.printOut(header,metrics, id, chFmt, printMSEBasedSNR, printSequenceMSE, printMSSSIM, printHexPsnr, printRprPSNR, bitDepths, useWPSNR
+#if JVET_O0756_CALCULATE_HDRMETRICS
+                          , calculateHdrMetrics
+#endif
+                          );
+  if( g_verbosity >= INFO ) std::cout<<header<<'\n'<<metrics<<std::endl;
+#else
 #if ENABLE_QPA
-  m_gcAnalyzeAll.printOut( 'a', chFmt, printMSEBasedSNR, printSequenceMSE, printMSSSIM, printHexPsnr, 
+  m_gcAnalyzeAll.printOut( 'a', chFmt, printMSEBasedSNR, printSequenceMSE, printMSSSIM, printHexPsnr,
     printRprPSNR, bitDepths, useWPSNR
 #if JVET_O0756_CALCULATE_HDRMETRICS
                           , calculateHdrMetrics
@@ -3715,16 +4120,48 @@ void EncGOP::printOutSummary( uint32_t uiNumAllPicCoded, bool isField, const boo
 #endif
                           );
 #endif
+#endif
+
+#if JVET_W0134_UNIFORM_METRICS_LOG
+  id="i";
+  if (layerId==0) id+=' ';
+  else            id+=std::to_string(layerId);
+  m_gcAnalyzeI.printOut(header,metrics, id, chFmt, printMSEBasedSNR, printSequenceMSE, printMSSSIM, printHexPsnr, printRprPSNR, bitDepths );
+  if( g_verbosity >= DETAILS ) std::cout<< "\n\nI Slices--------------------------------------------------------\n"<<header<<'\n'<<metrics<<std::endl;
+
+  id="p";
+  if (layerId==0) id+=' ';
+  else            id+=std::to_string(layerId);
+  m_gcAnalyzeP.printOut(header,metrics, id, chFmt, printMSEBasedSNR, printSequenceMSE, printMSSSIM, printHexPsnr, printRprPSNR, bitDepths );
+  if( g_verbosity >= DETAILS ) std::cout<<"\n\nP Slices--------------------------------------------------------\n"<<header<<'\n'<<metrics<<std::endl;
+
+  id="b";
+  if (layerId==0) id+=' ';
+  else            id+=std::to_string(layerId);
+  m_gcAnalyzeB.printOut(header,metrics, id, chFmt, printMSEBasedSNR, printSequenceMSE, printMSSSIM, printHexPsnr, printRprPSNR, bitDepths );
+  if( g_verbosity >= DETAILS ) std::cout<<"\n\nB Slices--------------------------------------------------------\n"<<header<<'\n'<<metrics<<std::endl;
+
+#if WCG_WPSNR
+  if (useLumaWPSNR)
+  {
+    id="w";
+    if (layerId==0) id+=' ';
+    else            id+=std::to_string(layerId);
+    m_gcAnalyzeWPSNR.printOut(header,metrics, id, chFmt, printMSEBasedSNR, printSequenceMSE, printMSSSIM, printHexPsnr, printRprPSNR, bitDepths, useLumaWPSNR );
+    if( g_verbosity >= DETAILS ) std::cout<<"\nWPSNR SUMMARY --------------------------------------------------------\n"<<header<<'\n'<<metrics<<std::endl;
+
+  }
+#endif
+#else
   msg( DETAILS, "\n\nI Slices--------------------------------------------------------\n" );
-  m_gcAnalyzeI.printOut( 'i', chFmt, printMSEBasedSNR, printSequenceMSE, printMSSSIM, 
+  m_gcAnalyzeI.printOut( 'i', chFmt, printMSEBasedSNR, printSequenceMSE, printMSSSIM,
     printHexPsnr, printRprPSNR, bitDepths );
-
   msg( DETAILS, "\n\nP Slices--------------------------------------------------------\n" );
   m_gcAnalyzeP.printOut( 'p', chFmt, printMSEBasedSNR, printSequenceMSE, printMSSSIM,
     printHexPsnr, printRprPSNR, bitDepths );
 
   msg( DETAILS, "\n\nB Slices--------------------------------------------------------\n" );
-  m_gcAnalyzeB.printOut( 'b', chFmt, printMSEBasedSNR, printSequenceMSE, printMSSSIM, 
+  m_gcAnalyzeB.printOut( 'b', chFmt, printMSEBasedSNR, printSequenceMSE, printMSSSIM,
     printHexPsnr, printRprPSNR, bitDepths );
 
 #if WCG_WPSNR
@@ -3735,6 +4172,9 @@ void EncGOP::printOutSummary( uint32_t uiNumAllPicCoded, bool isField, const boo
       printHexPsnr, printRprPSNR, bitDepths, useLumaWPSNR );
   }
 #endif
+#endif
+
+
   if (!m_pcCfg->getSummaryOutFilename().empty())
   {
     m_gcAnalyzeAll.printSummary(chFmt, printSequenceMSE, printHexPsnr, bitDepths, m_pcCfg->getSummaryOutFilename());
@@ -3759,7 +4199,13 @@ void EncGOP::printOutSummary( uint32_t uiNumAllPicCoded, bool isField, const boo
     m_gcAnalyzeAll_in.setFrmRate( m_pcCfg->getFrameRate() / (double)m_pcCfg->getTemporalSubsampleRatio());
     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 JVET_W0134_UNIFORM_METRICS_LOG
+    id="a";
+    if (layerId==0) id+=' ';
+    else            id+=std::to_string(layerId);
+    m_gcAnalyzeAll_in.printOut(header,metrics, id, chFmt, printMSEBasedSNR, printSequenceMSE, printMSSSIM, printHexPsnr, printRprPSNR, bitDepths, useWPSNR );
+    if( g_verbosity >= DETAILS ) std::cout<< "\n\nSUMMARY INTERLACED ---------------------------------------------\n"<<header<<'\n'<<metrics<<std::endl;
+#else
     msg( INFO,"\n\nSUMMARY INTERLACED ---------------------------------------------\n" );
 #if ENABLE_QPA
     m_gcAnalyzeAll_in.printOut( 'a', chFmt, printMSEBasedSNR, printSequenceMSE, printMSSSIM,
@@ -3767,6 +4213,7 @@ void EncGOP::printOutSummary( uint32_t uiNumAllPicCoded, bool isField, const boo
 #else
     m_gcAnalyzeAll_in.printOut('a', chFmt, printMSEBasedSNR, printSequenceMSE, printMSSSIM,
       printHexPsnr, bitDepths);
+#endif
 #endif
     if (!m_pcCfg->getSummaryOutFilename().empty())
     {
@@ -3787,7 +4234,7 @@ void EncGOP::printOutSummary( uint32_t uiNumAllPicCoded, bool isField, const boo
 uint64_t EncGOP::preLoopFilterPicAndCalcDist( Picture* pcPic )
 {
   CodingStructure& cs = *pcPic->cs;
-  m_pcLoopFilter->loopFilterPic( cs );
+  m_pcLoopFilter->deblockingFilterPic( cs );
 
   const CPelUnitBuf picOrg = pcPic->getRecoBuf();
   const CPelUnitBuf picRec = cs.getRecoBuf();
@@ -3809,9 +4256,7 @@ uint64_t EncGOP::preLoopFilterPicAndCalcDist( Picture* pcPic )
 // ====================================================================================================================
 // Protected member functions
 // ====================================================================================================================
-void EncGOP::xInitGOP( int iPOCLast, int iNumPicRcvd, bool isField
-  , bool isEncodeLtRef
-)
+void EncGOP::xInitGOP(int iPOCLast, int iNumPicRcvd, bool isField, bool isEncodeLtRef)
 {
   CHECK(!( iNumPicRcvd > 0 ), "Unspecified error");
   //  Exception for the first frames
@@ -3871,6 +4316,35 @@ void EncGOP::xGetBuffer( PicList&                  rcListPic,
   return;
 }
 
+void EncGOP::xGetSubpicIdsInPic(std::vector<uint16_t>& subpicIDs, const SPS* sps, const PPS* pps)
+{
+  subpicIDs.clear();
+
+  if (sps->getSubPicInfoPresentFlag())
+  {
+    if(sps->getSubPicIdMappingExplicitlySignalledFlag())
+    {
+      if(sps->getSubPicIdMappingPresentFlag())
+      {
+        subpicIDs = sps->getSubPicIds();
+      }
+      else
+      {
+        subpicIDs = pps->getSubPicIds();
+      }
+    }
+    else
+    {
+      const int numSubPics = sps->getNumSubPics();
+      subpicIDs.resize(numSubPics);
+      for (int i = 0 ; i < numSubPics; i++)
+      {
+        subpicIDs[i] = (uint16_t) i;
+      }
+    }
+  }
+}
+
 #if ENABLE_QPA
 
 #ifndef BETA
@@ -3909,7 +4383,10 @@ static inline double calcWeightedSquaredError(const CPelBuf& org,        const C
       ssErr += uint64_t(iDiff * iDiff);
     }
   }
-  if (wAct <= xAct || hAct <= yAct) return (double)ssErr;
+  if (wAct <= xAct || hAct <= yAct)
+  {
+    return (double) ssErr;
+  }
 
   for (y = yAct; y < hAct; y++)   // activity
   {
@@ -4031,7 +4508,7 @@ uint64_t EncGOP::xFindDistortionPlane(const CPelBuf& pic0, const CPelBuf& pic1,
 double EncGOP::xFindDistortionPlaneWPSNR(const CPelBuf& pic0, const CPelBuf& pic1, const uint32_t rshift, const CPelBuf& picLuma0,
   ComponentID compID, const ChromaFormat chfmt    )
 {
-  const bool    useLumaWPSNR = m_pcEncLib->getLumaLevelToDeltaQPMapping().isEnabled() || (m_pcCfg->getLmcs() && m_pcCfg->getReshapeSignalType() == RESHAPE_SIGNAL_PQ);
+  const bool    useLumaWPSNR = m_pcEncLib->getPrintWPSNR();
   if (!useLumaWPSNR)
   {
     return 0;
@@ -4081,12 +4558,12 @@ double EncGOP::xFindDistortionPlaneWPSNR(const CPelBuf& pic0, const CPelBuf& pic
 }
 #endif
 
-void EncGOP::xCalculateAddPSNRs( const bool isField, const bool isFieldTopFieldFirst, 
-  const int iGOPid, Picture* pcPic, const AccessUnit&accessUnit, PicList &rcListPic, 
-  const int64_t dEncTime, const InputColourSpaceConversion snr_conversion, 
+void EncGOP::xCalculateAddPSNRs( const bool isField, const bool isFieldTopFieldFirst,
+  const int iGOPid, Picture* pcPic, const AccessUnit&accessUnit, PicList &rcListPic,
+  const int64_t dEncTime, const InputColourSpaceConversion snr_conversion,
   const bool printFrameMSE, const bool printMSSSIM, double* PSNR_Y, bool isEncodeLtRef)
 {
-  xCalculateAddPSNR(pcPic, pcPic->getRecoBuf(), accessUnit, (double)dEncTime, snr_conversion, 
+  xCalculateAddPSNR(pcPic, pcPic->getRecoBuf(), accessUnit, (double)dEncTime, snr_conversion,
     printFrameMSE, printMSSSIM, PSNR_Y, isEncodeLtRef);
 
   //In case of field coding, compute the interlaced PSNR for both fields
@@ -4142,20 +4619,20 @@ void EncGOP::xCalculateAddPSNRs( const bool isField, const bool isFieldTopFieldF
 
       if ((pcPic->topField && isFieldTopFieldFirst) || (!pcPic->topField && !isFieldTopFieldFirst))
       {
-        xCalculateInterlacedAddPSNR(pcPic, correspondingFieldPic, pcPic->getRecoBuf(), 
-          correspondingFieldPic->getRecoBuf(), snr_conversion, printFrameMSE, printMSSSIM, 
+        xCalculateInterlacedAddPSNR(pcPic, correspondingFieldPic, pcPic->getRecoBuf(),
+          correspondingFieldPic->getRecoBuf(), snr_conversion, printFrameMSE, printMSSSIM,
           PSNR_Y, isEncodeLtRef);
       }
       else
       {
-        xCalculateInterlacedAddPSNR(correspondingFieldPic, pcPic, correspondingFieldPic->getRecoBuf(), 
+        xCalculateInterlacedAddPSNR(correspondingFieldPic, pcPic, correspondingFieldPic->getRecoBuf(),
           pcPic->getRecoBuf(), snr_conversion, printFrameMSE, printMSSSIM, PSNR_Y, isEncodeLtRef);
       }
     }
   }
 }
 
-void EncGOP::xCalculateAddPSNR(Picture* pcPic, PelUnitBuf cPicD, const AccessUnit& accessUnit, 
+void EncGOP::xCalculateAddPSNR(Picture* pcPic, PelUnitBuf cPicD, const AccessUnit& accessUnit,
   double dEncTime, const InputColourSpaceConversion conversion, const bool printFrameMSE, const bool printMSSSIM,
   double* PSNR_Y, bool isEncodeLtRef)
 {
@@ -4170,7 +4647,7 @@ void EncGOP::xCalculateAddPSNR(Picture* pcPic, PelUnitBuf cPicD, const AccessUni
   double  dPSNR[MAX_NUM_COMPONENT];
   double msssim[MAX_NUM_COMPONENT] = {0.0};
 #if WCG_WPSNR
-  const bool    useLumaWPSNR = m_pcEncLib->getLumaLevelToDeltaQPMapping().isEnabled() || (m_pcCfg->getLmcs() && m_pcCfg->getReshapeSignalType() == RESHAPE_SIGNAL_PQ);
+  const bool    useLumaWPSNR = m_pcEncLib->getPrintWPSNR();
   double  dPSNRWeighted[MAX_NUM_COMPONENT];
   double  MSEyuvframeWeighted[MAX_NUM_COMPONENT];
 #endif
@@ -4237,8 +4714,8 @@ void EncGOP::xCalculateAddPSNR(Picture* pcPic, PelUnitBuf cPicD, const AccessUni
     CHECK(!( p.width  == o.width), "Unspecified error");
     CHECK(!( p.height == o.height), "Unspecified error");
 
-    int padX = m_pcEncLib->getPad( 0 );
-    int padY = m_pcEncLib->getPad( 1 );
+    int padX = m_pcEncLib->getSourcePadding( 0 );
+    int padY = m_pcEncLib->getSourcePadding( 1 );
 
     // when RPR is enabled, picture padding is picture specific due to possible different picture resoluitons, however only full resolution padding is stored in EncLib
     // get per picture padding from the conformance window, in this case if conformance window is set not equal to the padding then PSNR results may be inaccurate
@@ -4284,8 +4761,8 @@ void EncGOP::xCalculateAddPSNR(Picture* pcPic, PelUnitBuf cPicD, const AccessUni
     {
       const CPelBuf& upscaledOrg = (sps.getUseLmcs() || m_pcCfg->getGopBasedTemporalFilterEnabled()) ? pcPic->M_BUFS( 0, PIC_TRUE_ORIGINAL_INPUT).get( compID ) : pcPic->M_BUFS( 0, PIC_ORIGINAL_INPUT).get( compID );
 
-      const uint32_t upscaledWidth = upscaledOrg.width - ( m_pcEncLib->getPad( 0 ) >> ::getComponentScaleX( compID, format ) );
-      const uint32_t upscaledHeight = upscaledOrg.height - ( m_pcEncLib->getPad( 1 ) >> ( !!bPicIsField + ::getComponentScaleY( compID, format ) ) );
+      const uint32_t upscaledWidth = upscaledOrg.width - ( m_pcEncLib->getSourcePadding( 0 ) >> ::getComponentScaleX( compID, format ) );
+      const uint32_t upscaledHeight = upscaledOrg.height - ( m_pcEncLib->getSourcePadding( 1 ) >> ( !!bPicIsField + ::getComponentScaleY( compID, format ) ) );
 
       // create new buffers with correct dimensions
       const CPelBuf upscaledRecPB( upscaledRec.get( compID ).bufAt( 0, 0 ), upscaledRec.get( compID ).stride, upscaledWidth, upscaledHeight );
@@ -4331,11 +4808,7 @@ void EncGOP::xCalculateAddPSNR(Picture* pcPic, PelUnitBuf cPicD, const AccessUni
     if( ( *it )->m_nalUnitType != NAL_UNIT_PREFIX_SEI && ( *it )->m_nalUnitType != NAL_UNIT_SUFFIX_SEI )
     {
       numRBSPBytes += numRBSPBytes_nal;
-#if JVET_S0163_ON_TARGETOLS_SUBLAYERS
       if (it == accessUnit.begin() || (*it)->m_nalUnitType == NAL_UNIT_OPI || (*it)->m_nalUnitType == NAL_UNIT_VPS || (*it)->m_nalUnitType == NAL_UNIT_DCI || (*it)->m_nalUnitType == NAL_UNIT_SPS || (*it)->m_nalUnitType == NAL_UNIT_PPS || (*it)->m_nalUnitType == NAL_UNIT_PREFIX_APS || (*it)->m_nalUnitType == NAL_UNIT_SUFFIX_APS)
-#else
-      if (it == accessUnit.begin() || (*it)->m_nalUnitType == NAL_UNIT_VPS || (*it)->m_nalUnitType == NAL_UNIT_DCI || (*it)->m_nalUnitType == NAL_UNIT_SPS || (*it)->m_nalUnitType == NAL_UNIT_PPS || (*it)->m_nalUnitType == NAL_UNIT_PREFIX_APS || (*it)->m_nalUnitType == NAL_UNIT_SUFFIX_APS)
-#endif
       {
         numRBSPBytes += 4;
       }
@@ -4414,7 +4887,14 @@ void EncGOP::xCalculateAddPSNR(Picture* pcPic, PelUnitBuf cPicD, const AccessUni
   {
     c += 32;
   }
-  if (m_pcCfg->getDependentRAPIndicationSEIEnabled() && pcSlice->isDRAP()) c = 'D';
+  if (m_pcCfg->getDependentRAPIndicationSEIEnabled() && pcSlice->isDRAP())
+  {
+    c = 'D';
+  }
+  if (m_pcCfg->getEdrapIndicationSEIEnabled() && pcSlice->getEdrapRapId() > 0)
+  {
+    c = 'E';
+  }
 
   if( g_verbosity >= NOTICE )
   {
@@ -4451,7 +4931,7 @@ void EncGOP::xCalculateAddPSNR(Picture* pcPic, PelUnitBuf cPicD, const AccessUni
     if (printMSSSIM)
     {
       msg( NOTICE, " [MS-SSIM Y %1.6lf    U %1.6lf    V %1.6lf]", msssim[COMPONENT_Y], msssim[COMPONENT_Cb], msssim[COMPONENT_Cr] );
-    }  
+    }
 
     if( printFrameMSE )
     {
@@ -4506,8 +4986,8 @@ void EncGOP::xCalculateAddPSNR(Picture* pcPic, PelUnitBuf cPicD, const AccessUni
                  reinterpret_cast<uint8_t *>(&psnrL[i]) + sizeof(psnrL[i]),
                  reinterpret_cast<uint8_t *>(&xpsnrL[i]));
           }
-          msg(NOTICE, " [xPSNRL%d %16" PRIx64 "]", (int)m_pcCfg->getWhitePointDeltaE(i), xpsnrL[0]);
 
+          msg(NOTICE, " [xPSNRL%d %16" PRIx64 "]", (int) m_pcCfg->getWhitePointDeltaE(i), xpsnrL[0]);
         }
       }
     }
@@ -4555,7 +5035,11 @@ void EncGOP::xCalculateAddPSNR(Picture* pcPic, PelUnitBuf cPicD, const AccessUni
     }
     if (m_pcEncLib->isResChangeInClvsEnabled())
     {
+#if JVET_W0134_UNIFORM_METRICS_LOG
+      msg( NOTICE, " [Y2 %6.4lf dB  U2 %6.4lf dB  V2 %6.4lf dB]", upscaledPSNR[COMPONENT_Y], upscaledPSNR[COMPONENT_Cb], upscaledPSNR[COMPONENT_Cr] );
+#else
       msg( NOTICE, "\nPSNR2: [Y %6.4lf dB    U %6.4lf dB    V %6.4lf dB]", upscaledPSNR[COMPONENT_Y], upscaledPSNR[COMPONENT_Cb], upscaledPSNR[COMPONENT_Cr] );
+#endif
     }
   }
   else if( g_verbosity >= INFO )
@@ -4573,22 +5057,22 @@ double EncGOP::xCalculateMSSSIM (const Pel* org, const int orgStride, const Pel*
 
   uint32_t maxScale;
 
-  // For low resolution videos determine number of scales 
+  // For low resolution videos determine number of scales
   if (width < 22 || height < 22)
   {
-    maxScale = 1; 
+    maxScale = 1;
   }
   else if (width < 44 || height < 44)
   {
-    maxScale = 2; 
+    maxScale = 2;
   }
   else if (width < 88 || height < 88)
   {
-    maxScale = 3; 
+    maxScale = 3;
   }
   else if (width < 176 || height < 176)
   {
-    maxScale = 4; 
+    maxScale = 4;
   }
   else
   {
@@ -4604,8 +5088,10 @@ double EncGOP::xCalculateMSSSIM (const Pel* org, const int orgStride, const Pel*
   {
     for(int x=0; x<WEIGHTING_SIZE; x++)
     {
-      weights[y][x]=exp(-((y-WEIGHTING_MID_TAP)*(y-WEIGHTING_MID_TAP)+(x-WEIGHTING_MID_TAP)*(x-WEIGHTING_MID_TAP))/(WEIGHTING_MID_TAP-0.5));
-      coeffSum +=weights[y][x];
+      weights[y][x] =
+        exp(-((y - WEIGHTING_MID_TAP) * (y - WEIGHTING_MID_TAP) + (x - WEIGHTING_MID_TAP) * (x - WEIGHTING_MID_TAP))
+            / (WEIGHTING_MID_TAP - 0.5));
+      coeffSum += weights[y][x];
     }
   }
 
@@ -4666,12 +5152,12 @@ double EncGOP::xCalculateMSSSIM (const Pel* org, const int orgStride, const Pel*
       }
     }
   }
-  
+
   // Calculate MS-SSIM:
   const uint32_t   maxValue  = (1<<bitDepth)-1;
   const double c1        = (0.01*maxValue)*(0.01*maxValue);
   const double c2        = (0.03*maxValue)*(0.03*maxValue);
-  
+
   double finalMSSSIM = 1.0;
 
   for(uint32_t scale=0; scale<maxScale; scale++)
@@ -4760,7 +5246,6 @@ void EncGOP::xCalculateHDRMetrics( Picture* pcPic, double deltaE[hdrtoolslib::NB
 
   *deltaE = m_pcDistortionDeltaE->getDeltaE();
   *psnrL  = m_pcDistortionDeltaE->getPsnrL();
-
 }
 
 void EncGOP::copyBuftoFrame( Picture* pcPic )
@@ -4770,12 +5255,12 @@ void EncGOP::copyBuftoFrame( Picture* pcPic )
   int cropOffsetRight  = m_pcCfg->getCropOffsetRight();
   int cropOffsetBottom = m_pcCfg->getCropOffsetBottom();
 
-  int height = pcPic->getOrigBuf(COMPONENT_Y).height - cropOffsetLeft + cropOffsetRight;
-  int width = pcPic->getOrigBuf(COMPONENT_Y).width - cropOffsetTop + cropOffsetBottom;
+  int height = pcPic->getTrueOrigBuf(COMPONENT_Y).height - cropOffsetLeft + cropOffsetRight;
+  int width  = pcPic->getTrueOrigBuf(COMPONENT_Y).width - cropOffsetTop + cropOffsetBottom;
 
   ChromaFormat chFmt =  pcPic->chromaFormat;
 
-  Pel* pOrg = pcPic->getOrigBuf(COMPONENT_Y).buf;
+  Pel *pOrg = pcPic->getTrueOrigBuf(COMPONENT_Y).buf;
   Pel* pRec = pcPic->getRecoBuf(COMPONENT_Y).buf;
 
   uint16_t* yOrg = m_ppcFrameOrg[0]->m_ui16Comp[hdrtoolslib::Y_COMP];
@@ -4785,7 +5270,8 @@ void EncGOP::copyBuftoFrame( Picture* pcPic )
   uint16_t* vOrg = m_ppcFrameOrg[0]->m_ui16Comp[hdrtoolslib::Cr_COMP];
   uint16_t* vRec = m_ppcFrameRec[0]->m_ui16Comp[hdrtoolslib::Cr_COMP];
 
-  if(chFmt == CHROMA_444){
+  if (chFmt == CHROMA_444)
+  {
     yOrg = m_ppcFrameOrg[1]->m_ui16Comp[hdrtoolslib::Y_COMP];
     yRec = m_ppcFrameRec[1]->m_ui16Comp[hdrtoolslib::Y_COMP];
     uOrg = m_ppcFrameOrg[1]->m_ui16Comp[hdrtoolslib::Cb_COMP];
@@ -4794,36 +5280,43 @@ void EncGOP::copyBuftoFrame( Picture* pcPic )
     vRec = m_ppcFrameRec[1]->m_ui16Comp[hdrtoolslib::Cr_COMP];
   }
 
-  for (int i = 0; i < height; i++) {
-    for (int j = 0; j < width; j++) {
-      yOrg[i*width + j] = static_cast<uint16_t>(pOrg[(i + cropOffsetTop) * pcPic->getOrigBuf(COMPONENT_Y).stride + j + cropOffsetLeft]);
+  for (int i = 0; i < height; i++)
+  {
+    for (int j = 0; j < width; j++)
+    {
+      yOrg[i * width + j] = static_cast<uint16_t>(pOrg[(i + cropOffsetTop) * pcPic->getTrueOrigBuf(COMPONENT_Y).stride + j + cropOffsetLeft]);
       yRec[i*width + j] = static_cast<uint16_t>(pRec[(i + cropOffsetTop) * pcPic->getRecoBuf(COMPONENT_Y).stride + j + cropOffsetLeft]);
     }
   }
 
-  if (chFmt != CHROMA_444) {
+  if (chFmt != CHROMA_444)
+  {
     height >>= 1;
     width  >>= 1;
     cropOffsetLeft >>= 1;
     cropOffsetTop >>= 1;
   }
 
-  pOrg = pcPic->getOrigBuf(COMPONENT_Cb).buf;
+  pOrg = pcPic->getTrueOrigBuf(COMPONENT_Cb).buf;
   pRec = pcPic->getRecoBuf(COMPONENT_Cb).buf;
 
-  for (int i = 0; i < height; i++) {
-    for (int j = 0; j < width; j++) {
-      uOrg[i*width + j] = static_cast<uint16_t>(pOrg[(i + cropOffsetTop) * pcPic->getOrigBuf(COMPONENT_Cb).stride + j + cropOffsetLeft]);
+  for (int i = 0; i < height; i++)
+  {
+    for (int j = 0; j < width; j++)
+    {
+      uOrg[i * width + j] = static_cast<uint16_t>(pOrg[(i + cropOffsetTop) * pcPic->getTrueOrigBuf(COMPONENT_Cb).stride + j + cropOffsetLeft]);
       uRec[i*width + j] = static_cast<uint16_t>(pRec[(i + cropOffsetTop) * pcPic->getRecoBuf(COMPONENT_Cb).stride + j + cropOffsetLeft]);
     }
   }
 
-  pOrg = pcPic->getOrigBuf(COMPONENT_Cr).buf;
+  pOrg = pcPic->getTrueOrigBuf(COMPONENT_Cr).buf;
   pRec = pcPic->getRecoBuf(COMPONENT_Cr).buf;
 
-  for (int i = 0; i < height; i++) {
-    for (int j = 0; j < width; j++) {
-      vOrg[i*width + j] = static_cast<uint16_t>(pOrg[(i + cropOffsetTop) * pcPic->getOrigBuf(COMPONENT_Cr).stride + j + cropOffsetLeft]);
+  for (int i = 0; i < height; i++)
+  {
+    for (int j = 0; j < width; j++)
+    {
+      vOrg[i * width + j] = static_cast<uint16_t>(pOrg[(i + cropOffsetTop) * pcPic->getTrueOrigBuf(COMPONENT_Cr).stride + j + cropOffsetLeft]);
       vRec[i*width + j] = static_cast<uint16_t>(pRec[(i + cropOffsetTop) * pcPic->getRecoBuf(COMPONENT_Cr).stride + j + cropOffsetLeft]);
     }
   }
@@ -4832,7 +5325,7 @@ void EncGOP::copyBuftoFrame( Picture* pcPic )
 
 void EncGOP::xCalculateInterlacedAddPSNR( Picture* pcPicOrgFirstField, Picture* pcPicOrgSecondField,
                                           PelUnitBuf cPicRecFirstField, PelUnitBuf cPicRecSecondField,
-                                          const InputColourSpaceConversion conversion, const bool printFrameMSE, 
+                                          const InputColourSpaceConversion conversion, const bool printFrameMSE,
                                           const bool printMSSSIM, double* PSNR_Y, bool isEncodeLtRef)
 {
   const SPS &sps = *pcPicOrgFirstField->cs->sps;
@@ -4874,8 +5367,8 @@ void EncGOP::xCalculateInterlacedAddPSNR( Picture* pcPicOrgFirstField, Picture*
     CHECK(!(acPicRecFields[0].get(ch).height==acPicRecFields[0].get(ch).height), "Unspecified error");
 
     uint64_t uiSSDtemp=0;
-    const uint32_t width    = acPicRecFields[0].get(ch).width - (m_pcEncLib->getPad(0) >> ::getComponentScaleX(ch, format));
-    const uint32_t height   = acPicRecFields[0].get(ch).height - ((m_pcEncLib->getPad(1) >> 1) >> ::getComponentScaleY(ch, format));
+    const uint32_t width    = acPicRecFields[0].get(ch).width - (m_pcEncLib->getSourcePadding(0) >> ::getComponentScaleX(ch, format));
+    const uint32_t height   = acPicRecFields[0].get(ch).height - ((m_pcEncLib->getSourcePadding(1) >> 1) >> ::getComponentScaleY(ch, format));
     const uint32_t bitDepth = sps.getBitDepth(toChannelType(ch));
 
     double sumOverFieldsMSSSIM = 0;
@@ -4937,6 +5430,18 @@ void EncGOP::xCalculateInterlacedAddPSNR( Picture* pcPicOrgFirstField, Picture*
  */
 NalUnitType EncGOP::getNalUnitType(int pocCurr, int lastIDR, bool isField)
 {
+#if GDR_ENABLED
+  if (m_pcCfg->getGdrEnabled() && m_pcCfg->getDecodingRefreshType() == 3 && (pocCurr >= m_pcCfg->getGdrPocStart()))
+  {
+    int m = pocCurr - m_pcCfg->getGdrPocStart();
+    int n = m_pcCfg->getGdrPeriod();
+    if (m % n == 0)
+    {
+      return NAL_UNIT_CODED_SLICE_GDR;
+    }
+  }
+#endif
+
   if (pocCurr == 0)
   {
     return NAL_UNIT_CODED_SLICE_IDR_N_LP;
@@ -4987,7 +5492,14 @@ NalUnitType EncGOP::getNalUnitType(int pocCurr, int lastIDR, bool isField)
       return NAL_UNIT_CODED_SLICE_RADL;
     }
   }
+#if GDR_ENABLED
+  if (m_pcCfg->getGdrEnabled() && pocCurr >= m_pcCfg->getGdrPocStart() && ((pocCurr - m_pcCfg->getGdrPocStart()) % m_pcCfg->getGdrPeriod() == 0))
+    return NAL_UNIT_CODED_SLICE_GDR;
+  else
+    return NAL_UNIT_CODED_SLICE_TRAIL;
+#else
   return NAL_UNIT_CODED_SLICE_TRAIL;
+#endif
 }
 
 void EncGOP::xUpdateRasInit(Slice* slice)
@@ -5004,6 +5516,69 @@ void EncGOP::xUpdateRasInit(Slice* slice)
   }
 }
 
+#if JVET_W0133_CONSTRAINED_RASL_ENCODING
+void EncGOP::xUpdateRPRtmvp( PicHeader* pcPicHeader, Slice* pcSlice )
+{
+  if( pcPicHeader->getEnableTMVPFlag() )
+  {
+    int colRefIdxL0 = -1, colRefIdxL1 = -1;
+
+    for( int refIdx = 0; refIdx < pcSlice->getNumRefIdx( REF_PIC_LIST_0 ); refIdx++ )
+    {
+      if( !( pcSlice->getRefPic( REF_PIC_LIST_0, refIdx )->slices[0]->getNalUnitType() != NAL_UNIT_CODED_SLICE_RASL &&
+            pcSlice->getRefPic( REF_PIC_LIST_0, refIdx )->poc <= m_pocCRA ) )
+      {
+        colRefIdxL0 = refIdx;
+        break;
+      }
+    }
+
+    for( int refIdx = 0; refIdx < pcSlice->getNumRefIdx( REF_PIC_LIST_1 ); refIdx++ )
+    {
+      if( !( pcSlice->getRefPic( REF_PIC_LIST_1, refIdx )->slices[0]->getNalUnitType() != NAL_UNIT_CODED_SLICE_RASL &&
+            pcSlice->getRefPic( REF_PIC_LIST_1, refIdx )->poc <= m_pocCRA ) )
+      {
+        colRefIdxL1 = refIdx;
+        break;
+      }
+    }
+
+    if( colRefIdxL0 >= 0 && colRefIdxL1 >= 0 )
+    {
+      const Picture *refPicL0 = pcSlice->getRefPic( REF_PIC_LIST_0, colRefIdxL0 );
+      const Picture *refPicL1 = pcSlice->getRefPic( REF_PIC_LIST_1, colRefIdxL1 );
+
+      CHECK( !refPicL0->slices.size(), "Wrong L0 reference picture" );
+      CHECK( !refPicL1->slices.size(), "Wrong L1 reference picture" );
+
+      const uint32_t colFromL0 = refPicL0->slices[0]->getSliceQp() > refPicL1->slices[0]->getSliceQp();
+      pcPicHeader->setPicColFromL0Flag( colFromL0 );
+      pcSlice->setColFromL0Flag(colFromL0);
+      pcSlice->setColRefIdx( colFromL0 ? colRefIdxL0 : colRefIdxL1 );
+      pcPicHeader->setColRefIdx( colFromL0 ? colRefIdxL0 : colRefIdxL1 );
+    }
+    else if( colRefIdxL0 < 0 && colRefIdxL1 >= 0 )
+    {
+      pcPicHeader->setPicColFromL0Flag( false );
+      pcSlice->setColFromL0Flag( false );
+      pcSlice->setColRefIdx( colRefIdxL1 );
+      pcPicHeader->setColRefIdx( colRefIdxL1 );
+    }
+    else if( colRefIdxL0 >= 0 && colRefIdxL1 < 0 )
+    {
+      pcPicHeader->setPicColFromL0Flag( true );
+      pcSlice->setColFromL0Flag( true );
+      pcSlice->setColRefIdx( colRefIdxL0 );
+      pcPicHeader->setColRefIdx( colRefIdxL0 );
+    }
+    else
+    {
+      pcPicHeader->setEnableTMVPFlag( false );
+    }
+  }
+}
+#endif
+
 double EncGOP::xCalculateRVM()
 {
   double dRVM = 0;
@@ -5311,7 +5886,7 @@ void EncGOP::applyDeblockingFilterMetric( Picture* pcPic, uint32_t uiNumSlices )
   int qp = pcSlice->getSliceQp();
   const int bitDepthLuma=pcSlice->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA);
   int bitdepthScale = 1 << (bitDepthLuma-8);
-  int beta = LoopFilter::getBeta( qp ) * bitdepthScale;
+  int beta = DeblockingFilter::getBeta( qp ) * bitdepthScale;
   const int thr2 = (beta>>2);
   const int thr1 = 2*bitdepthScale;
   uint32_t a = 0;
@@ -5560,19 +6135,11 @@ void EncGOP::applyDeblockingFilterParameterSelection( Picture* pcPic, const uint
 }
 #endif
 
-#if JVET_R0193
 bool EncGOP::xCheckMaxTidILRefPics(int layerIdx, Picture* refPic, bool currentPicIsIRAP)
-#else
-bool EncGOP::xCheckMaxTidILRefPics(Picture* refPic, bool currentPicIsIRAP)
-#endif
 {
-#if JVET_R0193
   const VPS* vps = refPic->cs->vps;
   int refLayerIdx = vps == nullptr ? 0 : vps->getGeneralLayerIdx(refPic->layerId);
   const int maxTidILRefPicsPlus1 = vps->getMaxTidIlRefPicsPlus1(layerIdx, refLayerIdx);
-#else
-  const int maxTidILRefPicsPlus1 = m_pcCfg->getVPSParameters().m_maxTidILRefPicsPlus1;
-#endif
 
   // -1 means not set
   if (maxTidILRefPicsPlus1 < 0)
@@ -5613,6 +6180,8 @@ void EncGOP::xCreateExplicitReferencePictureSetFromReference( Slice* slice, PicL
   static_vector<int, MAX_NUM_REF_PICS> higherTLayerRefs;
 
   higherTLayerRefs.resize(0);
+  static_vector<int, MAX_NUM_REF_PICS> inactiveRefs;
+  inactiveRefs.resize(0);
   if (isIntraLayerPredAllowed)
   {
     for (int ii = 0; ii < numOfRefPic; ii++)
@@ -5633,12 +6202,14 @@ void EncGOP::xCreateExplicitReferencePictureSetFromReference( Slice* slice, PicL
           hasHigherTId = rpcPic->temporalId > pic->temporalId;
           if (!rpl0->isRefPicLongterm(ii) && rpcPic->referenced
               && rpcPic->getPOC() == slice->getPOC() + rpl0->getRefPicIdentifier(ii)
-              && !slice->isPocRestrictedByDRAP(rpcPic->getPOC(), rpcPic->precedingDRAP))
+              && !slice->isPocRestrictedByDRAP(rpcPic->getPOC(), rpcPic->precedingDRAP)
+              && !slice->isPocRestrictedByEdrap(rpcPic->getPOC()))
           {
             isAvailable = true;
             break;
           }
-          else if (rpl0->isRefPicLongterm(ii) && rpcPic->referenced && (rpcPic->getPOC() & (pocCycle - 1)) == rpl0->getRefPicIdentifier(ii) && !slice->isPocRestrictedByDRAP(rpcPic->getPOC(), rpcPic->precedingDRAP))
+          else if (rpl0->isRefPicLongterm(ii) && rpcPic->referenced && (rpcPic->getPOC() & (pocCycle - 1)) == rpl0->getRefPicIdentifier(ii) && !slice->isPocRestrictedByDRAP(rpcPic->getPOC(), rpcPic->precedingDRAP)
+              && !slice->isPocRestrictedByEdrap(rpcPic->getPOC()))
           {
             isAvailable = true;
             break;
@@ -5652,6 +6223,10 @@ void EncGOP::xCreateExplicitReferencePictureSetFromReference( Slice* slice, PicL
         {
           higherTLayerRefs.push_back(ii);
         }
+        else if (refPicIdxL0 >= rpl1->getNumberOfActivePictures() && layerIdx && vps && !vps->getAllIndependentLayersFlag() && isInterLayerPredAllowed)
+        {
+          inactiveRefs.push_back(ii);
+        }
         else
         {
           pLocalRPL0->setRefPicIdentifier(refPicIdxL0, rpl0->getRefPicIdentifier(ii), rpl0->isRefPicLongterm(ii), false,
@@ -5679,11 +6254,7 @@ void EncGOP::xCreateExplicitReferencePictureSetFromReference( Slice* slice, PicL
         rpcPic = *( iterPic++ );
         int refLayerIdx = vps->getGeneralLayerIdx( rpcPic->layerId );
         if (rpcPic->referenced && rpcPic->getPOC() == pic->getPOC() && vps->getDirectRefLayerFlag(layerIdx, refLayerIdx)
-#if JVET_R0193
             && xCheckMaxTidILRefPics(layerIdx, rpcPic, slice->isIRAP()))
-#else
-            && xCheckMaxTidILRefPics(rpcPic, slice->isIRAP()) )
-#endif
         {
           pLocalRPL0->setRefPicIdentifier( refPicIdxL0, 0, true, true, vps->getInterLayerRefIdc( layerIdx, refLayerIdx ) );
           refPicIdxL0++;
@@ -5693,6 +6264,16 @@ void EncGOP::xCreateExplicitReferencePictureSetFromReference( Slice* slice, PicL
       }
     }
   }
+  // now add inactive refs
+  for (int i = 0; i < inactiveRefs.size(); i++)
+  {
+    const int ii = inactiveRefs[i];
+    pLocalRPL0->setRefPicIdentifier(refPicIdxL0, rpl0->getRefPicIdentifier(ii), rpl0->isRefPicLongterm(ii), false,
+      NOT_VALID);
+    refPicIdxL0++;
+    numOfSTRPL0 = numOfSTRPL0 + ((rpl0->isRefPicLongterm(ii)) ? 0 : 1);
+    numOfLTRPL0 += (rpl0->isRefPicLongterm(ii) && !rpl0->isInterLayerRefPic(ii)) ? 1 : 0;
+  }
 
   if( slice->getEnableDRAPSEI() )
   {
@@ -5718,6 +6299,35 @@ void EncGOP::xCreateExplicitReferencePictureSetFromReference( Slice* slice, PicL
       }
     }
   }
+  if( slice->getEnableEdrapSEI() )
+  {
+    pLocalRPL0->setNumberOfShorttermPictures( numOfSTRPL0 );
+    pLocalRPL0->setNumberOfLongtermPictures( numOfLTRPL0 );
+    pLocalRPL0->setNumberOfInterLayerPictures( numOfILRPL0 );
+
+    for (int i = 0; i < slice->getEdrapNumRefRapPics(); i++)
+    {
+      int refPoc = slice->getEdrapRefRapId(i) == 0 ? slice->getAssociatedIRAPPOC() : slice->getEdrapRefRapId(i) * m_pcEncLib->getEdrapPeriod();
+      if( slice->isPOCInRefPicList( pLocalRPL0, refPoc ) )
+      {
+        continue;
+      }
+      if( slice->getUseLTforEdrap() && !slice->isPOCInRefPicList( rpl1, refPoc ) )
+      {
+        // Added as longterm picture
+        pLocalRPL0->setRefPicIdentifier( refPicIdxL0, refPoc, true, false, 0 );
+        refPicIdxL0++;
+        numOfLTRPL0++;
+      }
+      else
+      {
+        // Added as shortterm picture
+        pLocalRPL0->setRefPicIdentifier(refPicIdxL0, refPoc - slice->getPOC(), false, false, 0);
+        refPicIdxL0++;
+        numOfSTRPL0++;
+      }
+    }
+  }
 
   // now add higher TId refs
   for (int i = 0; i < higherTLayerRefs.size(); i++)
@@ -5740,6 +6350,7 @@ void EncGOP::xCreateExplicitReferencePictureSetFromReference( Slice* slice, PicL
   uint32_t refPicIdxL1 = 0;
 
   higherTLayerRefs.resize(0);
+  inactiveRefs.resize(0);
   if (isIntraLayerPredAllowed)
   {
     for (int ii = 0; ii < numOfRefPic; ii++)
@@ -5758,12 +6369,13 @@ void EncGOP::xCreateExplicitReferencePictureSetFromReference( Slice* slice, PicL
           hasHigherTId = rpcPic->temporalId > pic->temporalId;
           if (!rpl1->isRefPicLongterm(ii) && rpcPic->referenced
               && rpcPic->getPOC() == slice->getPOC() + rpl1->getRefPicIdentifier(ii)
-              && !slice->isPocRestrictedByDRAP(rpcPic->getPOC(), rpcPic->precedingDRAP))
+              && !slice->isPocRestrictedByDRAP(rpcPic->getPOC(), rpcPic->precedingDRAP)
+              && !slice->isPocRestrictedByEdrap(rpcPic->getPOC()))
           {
             isAvailable = true;
             break;
           }
-          else if (rpl1->isRefPicLongterm(ii) && rpcPic->referenced && (rpcPic->getPOC() & (pocCycle - 1)) == rpl1->getRefPicIdentifier(ii) && !slice->isPocRestrictedByDRAP(rpcPic->getPOC(), rpcPic->precedingDRAP))
+          else if (rpl1->isRefPicLongterm(ii) && rpcPic->referenced && (rpcPic->getPOC() & (pocCycle - 1)) == rpl1->getRefPicIdentifier(ii) && !slice->isPocRestrictedByDRAP(rpcPic->getPOC(), rpcPic->precedingDRAP) && !slice->isPocRestrictedByEdrap(rpcPic->getPOC()))
           {
             isAvailable = true;
             break;
@@ -5777,6 +6389,10 @@ void EncGOP::xCreateExplicitReferencePictureSetFromReference( Slice* slice, PicL
         {
           higherTLayerRefs.push_back(ii);
         }
+        else if (refPicIdxL1 >= rpl1->getNumberOfActivePictures() && layerIdx && vps && !vps->getAllIndependentLayersFlag() && isInterLayerPredAllowed)
+        {
+          inactiveRefs.push_back(ii);
+        }
         else
         {
           pLocalRPL1->setRefPicIdentifier(refPicIdxL1, rpl1->getRefPicIdentifier(ii), rpl1->isRefPicLongterm(ii), false,
@@ -5805,11 +6421,7 @@ void EncGOP::xCreateExplicitReferencePictureSetFromReference( Slice* slice, PicL
         rpcPic = *( iterPic++ );
         int refLayerIdx = vps->getGeneralLayerIdx( rpcPic->layerId );
         if (rpcPic->referenced && rpcPic->getPOC() == pic->getPOC() && vps->getDirectRefLayerFlag(layerIdx, refLayerIdx)
-#if JVET_R0193
             && xCheckMaxTidILRefPics( layerIdx, rpcPic, slice->isIRAP()))
-#else
-            && xCheckMaxTidILRefPics( rpcPic, slice->isIRAP() ) )
-#endif
         {
           pLocalRPL1->setRefPicIdentifier( refPicIdxL1, 0, true, true, vps->getInterLayerRefIdc( layerIdx, refLayerIdx ) );
           refPicIdxL1++;
@@ -5820,6 +6432,15 @@ void EncGOP::xCreateExplicitReferencePictureSetFromReference( Slice* slice, PicL
     }
   }
 
+  for (int i = 0; i < inactiveRefs.size(); i++)
+  {
+    const int ii = inactiveRefs[i];
+    pLocalRPL1->setRefPicIdentifier(refPicIdxL1, rpl1->getRefPicIdentifier(ii), rpl1->isRefPicLongterm(ii), false,
+                                    NOT_VALID);
+    refPicIdxL1++;
+    numOfSTRPL1 = numOfSTRPL1 + ((rpl1->isRefPicLongterm(ii)) ? 0 : 1);
+    numOfLTRPL1 += (rpl1->isRefPicLongterm(ii) && !rpl1->isInterLayerRefPic(ii)) ? 1 : 0;
+  }
   // now add higher TId refs
   for (int i = 0; i < higherTLayerRefs.size(); i++)
   {
@@ -5880,7 +6501,7 @@ void EncGOP::xCreateExplicitReferencePictureSetFromReference( Slice* slice, PicL
   *slice->getRPL0() = localRPL0;
 
   //Copy from L0 if we have less than active ref pic
-  numOfNeedToFill = pLocalRPL0->getNumberOfActivePictures() - ( numOfLTRPL1 + numOfSTRPL1 );
+  numOfNeedToFill = pLocalRPL0->getNumberOfActivePictures() - ( numOfLTRPL1 + numOfSTRPL1 ) - numOfILRPL0;
 
   for( int ii = 0; numOfNeedToFill > 0 && ii < ( pLocalRPL0->getNumberOfLongtermPictures() + pLocalRPL0->getNumberOfShorttermPictures() + pLocalRPL0->getNumberOfInterLayerPictures() ); ii++ )
   {
@@ -5908,7 +6529,7 @@ void EncGOP::xCreateExplicitReferencePictureSetFromReference( Slice* slice, PicL
         refPicIdxL1++;
         numOfSTRPL1 = numOfSTRPL1 + ( ( pLocalRPL0->isRefPicLongterm( ii ) ) ? 0 : 1 );
         numOfLTRPL1 += ( pLocalRPL0->isRefPicLongterm( ii ) && !pLocalRPL0->isInterLayerRefPic( ii ) ) ? 1 : 0;
-        numOfLTRPL1 += pLocalRPL0->isInterLayerRefPic( ii ) ? 1 : 0;
+		numOfILRPL1 += pLocalRPL0->isInterLayerRefPic( ii ) ? 1 : 0;
         numOfNeedToFill--;
       }
     }
@@ -5922,5 +6543,15 @@ void EncGOP::xCreateExplicitReferencePictureSetFromReference( Slice* slice, PicL
   pLocalRPL1->setLtrpInSliceHeaderFlag( 1 );
   slice->setRPL1idx( -1 );
   *slice->getRPL1() = localRPL1;
+  // To ensure that any picture in the RefRapIds has been included in the refrence list.
+  for (int i = 0; i < slice->getEdrapNumRefRapPics(); i++)
+  {
+    int refPoc = slice->getEdrapRefRapId(i) == 0 ? slice->getAssociatedIRAPPOC() : slice->getEdrapRefRapId(i) * m_pcEncLib->getEdrapPeriod();
+    if (!slice->isPOCInRefPicList( pLocalRPL0, refPoc ) && !slice->isPOCInRefPicList( pLocalRPL1, refPoc ))
+    {
+      slice->deleteEdrapRefRapIds(i);
+    }
+  }
+
 }
 //! \}
diff --git a/source/Lib/EncoderLib/EncGOP.h b/source/Lib/EncoderLib/EncGOP.h
index 5a89d4898..bc7d2869a 100644
--- a/source/Lib/EncoderLib/EncGOP.h
+++ b/source/Lib/EncoderLib/EncGOP.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -43,7 +43,7 @@
 #include <stdlib.h>
 
 #include "CommonLib/Picture.h"
-#include "CommonLib/LoopFilter.h"
+#include "CommonLib/DeblockingFilter.h"
 #include "CommonLib/NAL.h"
 #include "EncSampleAdaptiveOffset.h"
 #include "EncAdaptiveLoopFilter.h"
@@ -128,7 +128,16 @@ private:
   bool                    m_bFirst;
   int                     m_iLastRecoveryPicPOC;
   int                     m_latestDRAPPOC;
+  int                     m_latestEDRAPPOC;
+  bool                    m_latestEdrapLeadingPicDecodableFlag;
   int                     m_lastRasPoc;
+  unsigned                m_riceBit[8][2];
+  int                     m_preQP[2];
+  int                     m_preIPOC;
+#if JVET_W0046_RLSCP
+  int                     m_cnt_right_bottom;
+  int                     m_cnt_right_bottom_i;
+#endif
 
   //  Access channel
   EncLib*                 m_pcEncLib;
@@ -137,7 +146,7 @@ private:
   PicList*                m_pcListPic;
 
   HLSWriter*              m_HLSWriter;
-  LoopFilter*             m_pcLoopFilter;
+  DeblockingFilter*             m_pcLoopFilter;
 
   SEIWriter               m_seiWriter;
 
@@ -183,6 +192,9 @@ private:
   bool                    m_bInitAMaxBT;
 
   AUWriterIf*             m_AUWriterIf;
+#if GDR_ENABLED
+  int                     m_lastGdrIntervalPoc;  
+#endif
 
 #if JVET_O0756_CALCULATE_HDRMETRICS
 
@@ -234,8 +246,19 @@ public:
   void      setLastLTRefPoc(int iLastLTRefPoc) { m_lastLTRefPoc = iLastLTRefPoc; }
   int       getLastLTRefPoc() const { return m_lastLTRefPoc; }
 
+#if GDR_ENABLED
+  void      setLastGdrIntervalPoc(int p)  { m_lastGdrIntervalPoc = p; }
+  int       getLastGdrIntervalPoc() const { return m_lastGdrIntervalPoc; }
+#endif
+
+  int       getPreQP() const { return m_preQP[0]; }
+
   void  printOutSummary( uint32_t uiNumAllPicCoded, bool isField, const bool printMSEBasedSNR, const bool printSequenceMSE, 
-    const bool printMSSSIM, const bool printHexPsnr, const bool printRprPSNR, const BitDepths &bitDepths );
+    const bool printMSSSIM, const bool printHexPsnr, const bool printRprPSNR, const BitDepths &bitDepths
+#if JVET_W0134_UNIFORM_METRICS_LOG
+                       , int layerId
+#endif
+                       );
 #if W0038_DB_OPT
   uint64_t  preLoopFilterPicAndCalcDist( Picture* pcPic );
 #endif
@@ -267,6 +290,7 @@ protected:
   void  xPicInitLMCS       (Picture *pic, PicHeader *picHeader, Slice *slice);
   void  xGetBuffer        ( PicList& rcListPic, std::list<PelUnitBuf*>& rcListPicYuvRecOut,
                             int iNumPicRcvd, int iTimeOffset, Picture*& rpcPic, int pocCurr, bool isField );
+  void xGetSubpicIdsInPic(std::vector<uint16_t>& subpicIDs, const SPS* sps, const PPS* pps);
 
 #if JVET_O0756_CALCULATE_HDRMETRICS
   void xCalculateHDRMetrics ( Picture* pcPic, double deltaE[hdrtoolslib::NB_REF_WHITE], double psnrL[hdrtoolslib::NB_REF_WHITE]);
@@ -296,6 +320,10 @@ protected:
 
   void xUpdateRasInit(Slice* slice);
 
+#if JVET_W0133_CONSTRAINED_RASL_ENCODING
+  void xUpdateRPRtmvp    ( PicHeader* pcPicHeader, Slice* pcSlice );
+#endif
+
   void xWriteAccessUnitDelimiter (AccessUnit &accessUnit, Slice *slice);
 
   void xWriteFillerData (AccessUnit &accessUnit, Slice *slice, uint32_t &fdSize);
@@ -307,7 +335,7 @@ protected:
   void xUpdateDuData(AccessUnit &testAU, std::deque<DUData> &duData);
   void xUpdateTimingSEI(SEIPictureTiming *pictureTimingSEI, std::deque<DUData> &duData, const SPS *sps);
   void xUpdateDuInfoSEI(SEIMessages &duInfoSeiMessages, SEIPictureTiming *pictureTimingSEI, int maxSubLayers);
-  void xCreateScalableNestingSEI(SEIMessages& seiMessages, SEIMessages& nestedSeiMessages, const std::vector<int> &targetOLSs, const std::vector<int> &targetLayers, const std::vector<uint16_t>& subpicIDs);
+  void xCreateScalableNestingSEI(SEIMessages& seiMessages, SEIMessages& nestedSeiMessages, const std::vector<int> &targetOLSs, const std::vector<int> &targetLayers, const std::vector<uint16_t>& subpicIDs, uint16_t maxSubpicIdInPic);
   void xWriteSEI (NalUnitType naluType, SEIMessages& seiMessages, AccessUnit &accessUnit, AccessUnit::iterator &auPos, int temporalId);
   void xWriteSEISeparately (NalUnitType naluType, SEIMessages& seiMessages, AccessUnit &accessUnit, AccessUnit::iterator &auPos, int temporalId);
   void xClearSEIs(SEIMessages& seiMessages, bool deleteMessages);
@@ -316,9 +344,7 @@ protected:
   void xWriteTrailingSEIMessages (SEIMessages& seiMessages, AccessUnit &accessUnit, int temporalId);
   void xWriteDuSEIMessages       (SEIMessages& duInfoSeiMessages, AccessUnit &accessUnit, int temporalId, std::deque<DUData> &duData);
 
-#if JVET_S0163_ON_TARGETOLS_SUBLAYERS
   int xWriteOPI (AccessUnit &accessUnit, const OPI *opi);
-#endif
   int xWriteVPS (AccessUnit &accessUnit, const VPS *vps);
   int xWriteDCI (AccessUnit &accessUnit, const DCI *dci);
   int xWriteSPS( AccessUnit &accessUnit, const SPS *sps, const int layerId = 0 );
@@ -332,11 +358,7 @@ protected:
   void applyDeblockingFilterParameterSelection( Picture* pcPic, const uint32_t numSlices, const int gopID );
 #endif
   void xCreateExplicitReferencePictureSetFromReference( Slice* slice, PicList& rcListPic, const ReferencePictureList *rpl0, const ReferencePictureList *rpl1 );
-#if JVET_R0193
   bool xCheckMaxTidILRefPics(int layerIdx, Picture* refPic, bool currentPicIsIRAP);
-#else
-  bool xCheckMaxTidILRefPics(Picture* refPic, bool currentPicIsIRAP);
-#endif
 };// END CLASS DEFINITION EncGOP
 
 //! \}
diff --git a/source/Lib/EncoderLib/EncHRD.cpp b/source/Lib/EncoderLib/EncHRD.cpp
index 1b4d2ce26..481cbf060 100644
--- a/source/Lib/EncoderLib/EncHRD.cpp
+++ b/source/Lib/EncoderLib/EncHRD.cpp
@@ -3,7 +3,7 @@
 * and contributor rights, including patent rights, and no such rights are
 * granted under this license.
 *
-* Copyright (c) 2010-2020, ITU/ISO/IEC
+* Copyright (c) 2010-2021, ITU/ISO/IEC
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/EncoderLib/EncHRD.h b/source/Lib/EncoderLib/EncHRD.h
index 1aa7c695f..c7a0173f7 100644
--- a/source/Lib/EncoderLib/EncHRD.h
+++ b/source/Lib/EncoderLib/EncHRD.h
@@ -3,7 +3,7 @@
 * and contributor rights, including patent rights, and no such rights are
 * granted under this license.
 *
-* Copyright (c) 2010-2020, ITU/ISO/IEC
+* Copyright (c) 2010-2021, ITU/ISO/IEC
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp
index bb5e51f65..b3e46ff29 100644
--- a/source/Lib/EncoderLib/EncLib.cpp
+++ b/source/Lib/EncoderLib/EncLib.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -43,9 +43,6 @@
 #include "CommonLib/Picture.h"
 #include "CommonLib/CommonDef.h"
 #include "CommonLib/ChromaFormat.h"
-#if ENABLE_SPLIT_PARALLELISM
-#include <omp.h>
-#endif
 #include "EncLibCommon.h"
 #include "CommonLib/ProfileLevelTier.h"
 
@@ -102,56 +99,25 @@ void EncLib::create( const int layerId )
   m_iPOCLast = m_compositeRefEnabled ? -2 : -1;
   // create processing unit classes
   m_cGOPEncoder.        create( );
-#if ENABLE_SPLIT_PARALLELISM
-#if ENABLE_SPLIT_PARALLELISM
-  m_numCuEncStacks  = m_numSplitThreads == 1 ? 1 : NUM_RESERVERD_SPLIT_JOBS;
-#else
-  m_numCuEncStacks  = 1;
-#endif
-
-  m_cCuEncoder      = new EncCu              [m_numCuEncStacks];
-  m_cInterSearch    = new InterSearch        [m_numCuEncStacks];
-  m_cIntraSearch    = new IntraSearch        [m_numCuEncStacks];
-  m_cTrQuant        = new TrQuant            [m_numCuEncStacks];
-  m_CABACEncoder    = new CABACEncoder       [m_numCuEncStacks];
-  m_cRdCost         = new RdCost             [m_numCuEncStacks];
-  m_CtxCache        = new CtxCache           [m_numCuEncStacks];
-
-  for( int jId = 0; jId < m_numCuEncStacks; jId++ )
-  {
-    m_cCuEncoder[jId].         create( this );
-  }
-#else
   m_cCuEncoder.         create( this );
-#endif
 #if JVET_J0090_MEMORY_BANDWITH_MEASURE
   m_cInterSearch.cacheAssign( &m_cacheModel );
 #endif
 
-  m_cLoopFilter.create(floorLog2(m_maxCUWidth) - MIN_CU_LOG2);
+  m_deblockingFilter.create(floorLog2(m_maxCUWidth) - MIN_CU_LOG2);
 
-  if (!m_bLoopFilterDisable && m_encDbOpt)
+  if (!m_deblockingFilterDisable && m_encDbOpt)
   {
-    m_cLoopFilter.initEncPicYuvBuffer(m_chromaFormatIDC, Size(getSourceWidth(), getSourceHeight()), getMaxCUWidth());
+    m_deblockingFilter.initEncPicYuvBuffer(m_chromaFormatIDC, Size(getSourceWidth(), getSourceHeight()), getMaxCUWidth());
   }
 
-#if ENABLE_SPLIT_PARALLELISM
-  m_cReshaper = new EncReshape[m_numCuEncStacks];
-#endif
   if (m_lmcsEnabled)
   {
-#if ENABLE_SPLIT_PARALLELISM
-    for (int jId = 0; jId < m_numCuEncStacks; jId++)
-    {
-      m_cReshaper[jId].createEnc(getSourceWidth(), getSourceHeight(), m_maxCUWidth, m_maxCUHeight, m_bitDepth[COMPONENT_Y]);
-    }
-#else
     m_cReshaper.createEnc( getSourceWidth(), getSourceHeight(), m_maxCUWidth, m_maxCUHeight, m_bitDepth[COMPONENT_Y]);
-#endif
   }
   if ( m_RCEnableRateControl )
   {
-    m_cRateCtrl.init(m_framesToBeEncoded, m_RCTargetBitrate, (int)((double)m_iFrameRate / m_temporalSubsampleRatio + 0.5), m_iGOPSize, m_iSourceWidth, m_iSourceHeight,
+    m_cRateCtrl.init(m_framesToBeEncoded, m_RCTargetBitrate, (int)((double)m_iFrameRate / m_temporalSubsampleRatio + 0.5), m_iGOPSize, m_sourceWidth, m_sourceHeight,
       m_maxCUWidth, m_maxCUHeight, getBitDepth(CHANNEL_TYPE_LUMA), m_RCKeepHierarchicalBit, m_RCUseLCUSeparateModel, m_GOPList);
   }
 
@@ -162,55 +128,23 @@ void EncLib::destroy ()
   // destroy processing unit classes
   m_cGOPEncoder.        destroy();
   m_cSliceEncoder.      destroy();
-#if ENABLE_SPLIT_PARALLELISM
-  for( int jId = 0; jId < m_numCuEncStacks; jId++ )
-  {
-    m_cCuEncoder[jId].destroy();
-  }
-#else
   m_cCuEncoder.         destroy();
-#endif
   if( m_alf )
   {
     m_cEncALF.destroy();
   }
   m_cEncSAO.            destroyEncData();
   m_cEncSAO.            destroy();
-  m_cLoopFilter.        destroy();
+  m_deblockingFilter.   destroy();
   m_cRateCtrl.          destroy();
-#if ENABLE_SPLIT_PARALLELISM
-  for (int jId = 0; jId < m_numCuEncStacks; jId++)
-  {
-    m_cReshaper[jId].   destroy();
-  }
-#else
   m_cReshaper.          destroy();
-#endif
-#if ENABLE_SPLIT_PARALLELISM
-  for( int jId = 0; jId < m_numCuEncStacks; jId++ )
-  {
-    m_cInterSearch[jId].   destroy();
-    m_cIntraSearch[jId].   destroy();
-  }
-#else
   m_cInterSearch.       destroy();
   m_cIntraSearch.       destroy();
-#endif
-
-#if ENABLE_SPLIT_PARALLELISM
-  delete[] m_cCuEncoder;
-  delete[] m_cInterSearch;
-  delete[] m_cIntraSearch;
-  delete[] m_cTrQuant;
-  delete[] m_CABACEncoder;
-  delete[] m_cRdCost;
-  delete[] m_CtxCache;
-#endif
 
   return;
 }
 
-void EncLib::init( bool isFieldCoding, AUWriterIf* auWriterIf )
+void EncLib::init(AUWriterIf *auWriterIf)
 {
   m_AUWriterIf = auWriterIf;
 
@@ -233,17 +167,8 @@ void EncLib::init( bool isFieldCoding, AUWriterIf* auWriterIf )
   }
 
   xInitVPS( sps0 );
-#if JVET_S0163_ON_TARGETOLS_SUBLAYERS
   xInitOPI(m_opi);
-#endif
   xInitDCI(m_dci, sps0);
-#if ENABLE_SPLIT_PARALLELISM
-  if( omp_get_dynamic() )
-  {
-    omp_set_dynamic( false );
-  }
-  omp_set_nested( true );
-#endif
 
   if (getUseCompositeRef() || getDependentRAPIndicationSEIEnabled())
   {
@@ -256,18 +181,11 @@ void EncLib::init( bool isFieldCoding, AUWriterIf* auWriterIf )
     m_cRateCtrl.initHrdParam(sps0.getGeneralHrdParameters(), sps0.getOlsHrdParameters(), m_iFrameRate, m_RCInitialCpbFullness);
   }
 #endif
-#if ENABLE_SPLIT_PARALLELISM
-  for( int jId = 0; jId < m_numCuEncStacks; jId++ )
-  {
-    m_cRdCost[jId].setCostMode ( m_costMode );
-  }
-#else
   m_cRdCost.setCostMode ( m_costMode );
-#endif
 
   // initialize PPS
-  pps0.setPicWidthInLumaSamples( m_iSourceWidth );
-  pps0.setPicHeightInLumaSamples( m_iSourceHeight );
+  pps0.setPicWidthInLumaSamples( m_sourceWidth );
+  pps0.setPicHeightInLumaSamples( m_sourceHeight );
   if (pps0.getPicWidthInLumaSamples() == sps0.getMaxPicWidthInLumaSamples() && pps0.getPicHeightInLumaSamples() == sps0.getMaxPicHeightInLumaSamples())
   {
     pps0.setConformanceWindow( sps0.getConformanceWindow() );
@@ -278,9 +196,13 @@ void EncLib::init( bool isFieldCoding, AUWriterIf* auWriterIf )
     pps0.setConformanceWindow( m_conformanceWindow );
     pps0.setConformanceWindowFlag( m_conformanceWindow.getWindowEnabledFlag() );
   }
+  if (!pps0.getExplicitScalingWindowFlag())
+  {
+    pps0.setScalingWindow(pps0.getConformanceWindow());
+  }
   xInitPPS(pps0, sps0);
   // initialize APS
-  xInitRPL(sps0, isFieldCoding);
+  xInitRPL(sps0);
 
   if (m_resChangeInClvsEnabled)
   {
@@ -314,6 +236,7 @@ void EncLib::init( bool isFieldCoding, AUWriterIf* auWriterIf )
     Window scalingWindow;
     scalingWindow.setWindow( 0, ( width - scaledWidth ) / SPS::getWinUnitX( sps0.getChromaFormatIdc() ), 0, ( height - scaledHeight ) / SPS::getWinUnitY( sps0.getChromaFormatIdc() ) );
     pps.setScalingWindow( scalingWindow );
+    pps.setExplicitScalingWindowFlag(scalingWindow.getWindowEnabledFlag());
 
     //register the width/height of the current pic into reference SPS
     if (!sps0.getPPSValidFlag(pps.getPPSId()))
@@ -342,7 +265,7 @@ void EncLib::init( bool isFieldCoding, AUWriterIf* auWriterIf )
     m_noPicPartitionFlag = true;
 
     xInitPPS( pps, sps0 ); // will allocate memory for and initialize pps.pcv inside
-    
+
     if( pps.getWrapAroundEnabledFlag() )
     {
       int minCbSizeY = (1 << sps0.getLog2MinCodingBlockSize());
@@ -350,10 +273,10 @@ void EncLib::init( bool isFieldCoding, AUWriterIf* auWriterIf )
       pps.setWrapAroundOffset                   (minCbSizeY * (pps.getPicWidthInLumaSamples() / minCbSizeY - pps.getPicWidthMinusWrapAroundOffset()));
 
     }
-    else 
+    else
     {
       pps.setPicWidthMinusWrapAroundOffset      (0);
-      pps.setWrapAroundOffset                   ( 0 );       
+      pps.setWrapAroundOffset                   ( 0 );
     }
   }
 
@@ -375,54 +298,6 @@ void EncLib::init( bool isFieldCoding, AUWriterIf* auWriterIf )
   // initialize processing unit classes
   m_cGOPEncoder.  init( this );
   m_cSliceEncoder.init( this, sps0 );
-#if ENABLE_SPLIT_PARALLELISM
-  for( int jId = 0; jId < m_numCuEncStacks; jId++ )
-  {
-    // precache a few objects
-    for( int i = 0; i < 10; i++ )
-    {
-      auto x = m_CtxCache[jId].get();
-      m_CtxCache[jId].cache( x );
-    }
-
-    m_cCuEncoder[jId].init( this, sps0, jId );
-
-    // initialize transform & quantization class
-    m_cTrQuant[jId].init( jId == 0 ? nullptr : m_cTrQuant[0].getQuant(),
-                          1 << m_log2MaxTbSize,
-
-                          m_useRDOQ,
-                          m_useRDOQTS,
-#if T0196_SELECTIVE_RDOQ
-                          m_useSelectiveRDOQ,
-#endif
-                          true
-    );
-
-    // initialize encoder search class
-    CABACWriter* cabacEstimator = m_CABACEncoder[jId].getCABACEstimator( &sps0 );
-    m_cIntraSearch[jId].init( this,
-                              &m_cTrQuant[jId],
-                              &m_cRdCost[jId],
-                              cabacEstimator,
-                              getCtxCache( jId ), m_maxCUWidth, m_maxCUHeight, floorLog2(m_maxCUWidth) - m_log2MinCUSize
-                            , &m_cReshaper[jId]
-                            , sps0.getBitDepth(CHANNEL_TYPE_LUMA)
-    );
-    m_cInterSearch[jId].init( this,
-                              &m_cTrQuant[jId],
-                              m_iSearchRange,
-                              m_bipredSearchRange,
-                              m_motionEstimationSearchMethod,
-                              getUseCompositeRef(),
-                              m_maxCUWidth, m_maxCUHeight, floorLog2(m_maxCUWidth) - m_log2MinCUSize, &m_cRdCost[jId], cabacEstimator, getCtxCache( jId )
-                           , &m_cReshaper[jId]
-    );
-
-    // link temporary buffets from intra search with inter search to avoid unnecessary memory overhead
-    m_cInterSearch[jId].setTempBuffers( m_cIntraSearch[jId].getSplitCSBuf(), m_cIntraSearch[jId].getFullCSBuf(), m_cIntraSearch[jId].getSaveCSBuf() );
-  }
-#else  // ENABLE_SPLIT_PARALLELISM || ENABLE_WPP_PARALLELISM
   m_cCuEncoder.   init( this, sps0 );
 
   // initialize transform & quantization class
@@ -458,7 +333,6 @@ void EncLib::init( bool isFieldCoding, AUWriterIf* auWriterIf )
 
   // link temporary buffets from intra search with inter search to avoid unneccessary memory overhead
   m_cInterSearch.setTempBuffers( m_cIntraSearch.getSplitCSBuf(), m_cIntraSearch.getFullCSBuf(), m_cIntraSearch.getSaveCSBuf() );
-#endif // ENABLE_SPLIT_PARALLELISM || ENABLE_WPP_PARALLELISM
 
   m_iMaxRefPicNum = 0;
 
@@ -482,7 +356,13 @@ void EncLib::init( bool isFieldCoding, AUWriterIf* auWriterIf )
     Picture *picBg = new Picture;
     picBg->create( sps0.getChromaFormatIdc(), Size( pps0.getPicWidthInLumaSamples(), pps0.getPicHeightInLumaSamples() ), sps0.getMaxCUWidth(), sps0.getMaxCUWidth() + 16, false, m_layerId, m_gopBasedTemporalFilterEnabled );
     picBg->getRecoBuf().fill(0);
+#if GDR_ENABLED
+    PicHeader *picHeader = new PicHeader();
+    xInitPicHeader(*picHeader, sps0, pps0);
+    picBg->finalInit( m_vps, sps0, pps0, picHeader, m_apss, m_lmcsAPS, m_scalinglistAPS );
+#else
     picBg->finalInit( m_vps, sps0, pps0, &m_picHeader, m_apss, m_lmcsAPS, m_scalinglistAPS );
+#endif
     picBg->allocateNewSlice();
     picBg->createSpliceIdx(pps0.pcv->sizeInCtus);
     m_cGOPEncoder.setPicBg(picBg);
@@ -509,26 +389,12 @@ void EncLib::xInitScalingLists( SPS &sps, APS &aps )
   {
     quant->setFlatScalingList(maxLog2TrDynamicRange, sps.getBitDepths());
     quant->setUseScalingList(false);
-#if ENABLE_SPLIT_PARALLELISM
-    for( int jId = 1; jId < m_numCuEncStacks; jId++ )
-    {
-      getTrQuant( jId )->getQuant()->setFlatScalingList( maxLog2TrDynamicRange, sps.getBitDepths() );
-      getTrQuant( jId )->getQuant()->setUseScalingList( false );
-    }
-#endif
   }
   else if(getUseScalingListId() == SCALING_LIST_DEFAULT)
   {
     aps.getScalingList().setDefaultScalingList ();
     quant->setScalingList( &( aps.getScalingList() ), maxLog2TrDynamicRange, sps.getBitDepths() );
     quant->setUseScalingList(true);
-#if ENABLE_SPLIT_PARALLELISM
-    for( int jId = 1; jId < m_numCuEncStacks; jId++ )
-    {
-      getTrQuant( jId )->getQuant()->setUseScalingList( true );
-    }
-    sps.setDisableScalingMatrixForLfnstBlks(getDisableScalingMatrixForLfnstBlks());
-#endif
   }
   else if(getUseScalingListId() == SCALING_LIST_FILE_READ)
   {
@@ -542,12 +408,6 @@ void EncLib::xInitScalingLists( SPS &sps, APS &aps )
     aps.getScalingList().setChromaScalingListPresentFlag((sps.getChromaFormatIdc()!=CHROMA_400));
     quant->setScalingList( &( aps.getScalingList() ), maxLog2TrDynamicRange, sps.getBitDepths() );
     quant->setUseScalingList(true);
-#if ENABLE_SPLIT_PARALLELISM
-    for( int jId = 1; jId < m_numCuEncStacks; jId++ )
-    {
-      getTrQuant( jId )->getQuant()->setUseScalingList( true );
-    }
-#endif
 
     sps.setDisableScalingMatrixForLfnstBlks(getDisableScalingMatrixForLfnstBlks());
   }
@@ -614,7 +474,13 @@ bool EncLib::encodePrep( bool flush, PelStorage* pcPicYuvOrg, PelStorage* cPicYu
     const SPS *sps = m_spsMap.getPS( pps->getSPSId() );
 
     picCurr->M_BUFS( 0, PIC_ORIGINAL ).copyFrom( m_cGOPEncoder.getPicBg()->getRecoBuf() );
+#if GDR_ENABLED
+    PicHeader *picHeader = new PicHeader();
+    xInitPicHeader(*picHeader, *sps, *pps);
+    picCurr->finalInit( m_vps, *sps, *pps, picHeader, m_apss, m_lmcsAPS, m_scalinglistAPS );
+#else
     picCurr->finalInit( m_vps, *sps, *pps, &m_picHeader, m_apss, m_lmcsAPS, m_scalinglistAPS );
+#endif
     picCurr->poc = m_iPOCLast - 1;
     m_iPOCLast -= 2;
     if( getUseAdaptiveQP() )
@@ -626,7 +492,7 @@ bool EncLib::encodePrep( bool flush, PelStorage* pcPicYuvOrg, PelStorage* cPicYu
       m_cRateCtrl.initRCGOP( m_iNumPicRcvd );
     }
 
-    m_cGOPEncoder.compressGOP( m_iPOCLast, m_iNumPicRcvd, m_cListPic, rcListPicYuvRecOut, false, false, 
+    m_cGOPEncoder.compressGOP( m_iPOCLast, m_iNumPicRcvd, m_cListPic, rcListPicYuvRecOut, false, false,
       snrCSC, m_printFrameMSE, m_printMSSSIM, true, 0 );
 
 #if JVET_O0756_CALCULATE_HDRMETRICS
@@ -732,8 +598,13 @@ bool EncLib::encodePrep( bool flush, PelStorage* pcPicYuvOrg, PelStorage* cPicYu
         pcPicCurr->M_BUFS( 0, PIC_FILTERED_ORIGINAL ).swap( *pcPicYuvFilteredOrg );
       }
     }
-
+#if GDR_ENABLED
+    PicHeader *picHeader = new PicHeader();
+    xInitPicHeader(*picHeader, *pSPS, *pPPS);
+    pcPicCurr->finalInit( m_vps, *pSPS, *pPPS, picHeader, m_apss, m_lmcsAPS, m_scalinglistAPS );
+#else
     pcPicCurr->finalInit( m_vps, *pSPS, *pPPS, &m_picHeader, m_apss, m_lmcsAPS, m_scalinglistAPS );
+#endif
 
     pcPicCurr->poc = m_iPOCLast;
 
@@ -878,7 +749,13 @@ bool EncLib::encodePrep( bool flush, PelStorage* pcPicYuvOrg, PelStorage* pcPicY
       const PPS *pPPS = ( ppsID < 0 ) ? m_ppsMap.getFirstPS() : m_ppsMap.getPS( ppsID );
       const SPS *pSPS = m_spsMap.getPS( pPPS->getSPSId() );
 
+#if GDR_ENABLED
+      PicHeader *picHeader = new PicHeader();
+      xInitPicHeader(*picHeader, *pSPS, *pPPS);
+      pcField->finalInit( m_vps, *pSPS, *pPPS, picHeader, m_apss, m_lmcsAPS, m_scalinglistAPS );
+#else
       pcField->finalInit( m_vps, *pSPS, *pPPS, &m_picHeader, m_apss, m_lmcsAPS, m_scalinglistAPS );
+#endif
 
       pcField->poc = m_iPOCLast;
       pcField->reconstructed = false;
@@ -914,7 +791,7 @@ bool EncLib::encode( const InputColourSpaceConversion snrCSC, std::list<PelUnitB
     m_iPOCLast = m_iPOCLast < 2 ? fieldNum : m_iPOCLast;
 
     // compress GOP
-    m_cGOPEncoder.compressGOP( m_iPOCLast, m_iPOCLast < 2 ? m_iPOCLast + 1 : m_iNumPicRcvd, m_cListPic, 
+    m_cGOPEncoder.compressGOP( m_iPOCLast, m_iPOCLast < 2 ? m_iPOCLast + 1 : m_iNumPicRcvd, m_cListPic,
       rcListPicYuvRecOut, true, isTff, snrCSC, m_printFrameMSE, m_printMSSSIM, false, m_picIdInGOP );
 #if JVET_O0756_CALCULATE_HDRMETRICS
     m_metricTime = m_cGOPEncoder.getMetricTime();
@@ -1010,7 +887,7 @@ void EncLib::xGetNewPicBuffer ( std::list<PelUnitBuf*>& rcListPicYuvRecOut, Pict
       if(m_gopBasedTemporalFilterEnabled)
       {
         rpcPic->M_BUFS(0, PIC_FILTERED_ORIGINAL_INPUT).create(sps.getChromaFormatIdc(), Area(Position(), Size(pps0.getPicWidthInLumaSamples(), pps0.getPicHeightInLumaSamples())));
-      } 
+      }
     }
     if ( getUseAdaptiveQP() )
     {
@@ -1043,9 +920,7 @@ void EncLib::xInitVPS( const SPS& sps )
   m_vps->m_olsHrdParams.resize(m_vps->getNumOlsTimingHrdParamsMinus1(), std::vector<OlsHrdParams>(m_vps->getMaxSubLayers()));
   ProfileLevelTierFeatures profileLevelTierFeatures;
   profileLevelTierFeatures.extractPTLInformation( sps );
-#if JVET_R0193
   m_vps->setMaxTidIlRefPicsPlus1(m_cfgVPSParameters.m_maxTidILRefPicsPlus1);
-#endif
   m_vps->deriveOutputLayerSets();
   m_vps->deriveTargetOutputLayerSet( m_vps->m_targetOlsIdx );
 
@@ -1069,7 +944,7 @@ void EncLib::xInitVPS( const SPS& sps )
   for( int olsIdx = 0, dpbIdx = 0; olsIdx < m_vps->m_numOutputLayersInOls.size(); olsIdx++ )
   {
     if ( m_vps->getNumLayersInOls(olsIdx) > 1 )
-    { 
+    {
       if( std::find( m_vps->m_layerIdInOls[olsIdx].begin(), m_vps->m_layerIdInOls[olsIdx].end(), m_layerId ) != m_vps->m_layerIdInOls[olsIdx].end() )
       {
         m_vps->setOlsDpbPicWidth( olsIdx, std::max<int>( sps.getMaxPicWidthInLumaSamples(), m_vps->getOlsDpbPicSize( olsIdx ).width ) );
@@ -1087,7 +962,7 @@ void EncLib::xInitVPS( const SPS& sps )
   for( int i = 0; i < m_vps->m_numOutputLayersInOls.size(); i++ )
   {
     if ( m_vps->getNumLayersInOls(i) > 1 )
-    { 
+    {
       int dpbIdx = m_vps->getOlsDpbParamsIdx( i );
 
       if( m_vps->getMaxSubLayers() == 1 )
@@ -1117,7 +992,7 @@ void EncLib::xInitVPS( const SPS& sps )
           decPicBuffering[tId] += m_layerDecPicBuffering[m_vps->getLayerIdInOls( i, lIdx ) * MAX_TLAYER + tId];
         }
       }
-    
+
       for( int j = ( m_vps->m_sublayerDpbParamsPresentFlag ? 0 : m_vps->m_dpbMaxTemporalId[dpbIdx] ); j <= m_vps->m_dpbMaxTemporalId[dpbIdx]; j++ )
       {
         m_vps->m_dpbParameters[dpbIdx].m_maxDecPicBuffering[j] = decPicBuffering[j] > 0 ? decPicBuffering[j] : profileLevelTierFeatures.getMaxDpbSize( m_vps->getOlsDpbPicSize( i ).width * m_vps->getOlsDpbPicSize( i ).height );
@@ -1145,19 +1020,9 @@ void EncLib::xInitVPS( const SPS& sps )
     m_vps->setHrdMaxTid(i, m_vps->getMaxSubLayers() - 1);
   }
 
-#if !JVET_R0193
-  if (m_cfgVPSParameters.m_maxTidILRefPicsPlus1 >= 0)
-  {
-    for (int i = 0; i < m_vps->getMaxLayers(); i++)
-    {
-      m_vps->setMaxTidIlRefPicsPlus1(i, m_cfgVPSParameters.m_maxTidILRefPicsPlus1);
-    }
-  }
-#endif
   m_vps->checkVPS();
 }
 
-#if JVET_S0163_ON_TARGETOLS_SUBLAYERS
 void EncLib::xInitOPI(OPI& opi)
 {
   if (m_OPIEnabled && m_vps)
@@ -1165,7 +1030,7 @@ void EncLib::xInitOPI(OPI& opi)
     if (!opi.getOlsInfoPresentFlag())
     {
       opi.setOpiOlsIdx(m_vps->deriveTargetOLSIdx());
-      opi.setOlsInfoPresentFlag(true);    
+      opi.setOlsInfoPresentFlag(true);
     }
     if (!opi.getHtidInfoPresentFlag())
     {
@@ -1174,7 +1039,6 @@ void EncLib::xInitOPI(OPI& opi)
     }
   }
 }
-#endif
 
 void EncLib::xInitDCI(DCI& dci, const SPS& sps)
 {
@@ -1254,6 +1118,9 @@ void EncLib::xInitSPS( SPS& sps )
   cinfo->setNoCraConstraintFlag(m_noCraConstraintFlag);
   cinfo->setNoGdrConstraintFlag(m_noGdrConstraintFlag);
   cinfo->setNoApsConstraintFlag(m_noApsConstraintFlag);
+#if JVET_W2005_RANGE_EXTENSION_PROFILES
+  cinfo->setLowerBitRateConstraintFlag(m_generalLowerBitRateConstraintFlag);
+#endif
 
   profileTierLevel->setLevelIdc                    (m_level);
   profileTierLevel->setTierFlag                    (m_levelTier);
@@ -1269,12 +1136,26 @@ void EncLib::xInitSPS( SPS& sps )
   /* XXX: may be a good idea to refactor the above into a function
    * that chooses the actual compatibility based upon options */
   sps.setVPSId( m_vps->getVPSId() );
-  sps.setMaxPicWidthInLumaSamples( m_iSourceWidth );
-  sps.setMaxPicHeightInLumaSamples( m_iSourceHeight );
+
+#if GDR_ENABLED
+  if (m_gdrEnabled)
+  {
+    sps.setGDREnabledFlag(true);
+  }
+  else
+  {
+    sps.setGDREnabledFlag(false);
+  }
+#else
+  sps.setGDREnabledFlag(false);
+#endif
+
+  sps.setMaxPicWidthInLumaSamples( m_sourceWidth );
+  sps.setMaxPicHeightInLumaSamples( m_sourceHeight );
   if (m_resChangeInClvsEnabled)
   {
-    int maxPicWidth = std::max(m_iSourceWidth, (int)((double)m_iSourceWidth / m_scalingRatioHor + 0.5));
-    int maxPicHeight = std::max(m_iSourceHeight, (int)((double)m_iSourceHeight / m_scalingRatioVer + 0.5));
+    int maxPicWidth = std::max(m_sourceWidth, (int)((double)m_sourceWidth / m_scalingRatioHor + 0.5));
+    int maxPicHeight = std::max(m_sourceHeight, (int)((double)m_sourceHeight / m_scalingRatioVer + 0.5));
     const int minCuSize = std::max(8, 1 << m_log2MinCUSize);
     if (maxPicWidth % minCuSize)
     {
@@ -1410,7 +1291,7 @@ void EncLib::xInitSPS( SPS& sps )
   }
   sps.setALFEnabledFlag( m_alf );
   sps.setCCALFEnabledFlag( m_ccalf );
-  sps.setFieldSeqFlag(false);
+  sps.setFieldSeqFlag(m_fieldSeqFlag);
   sps.setVuiParametersPresentFlag(getVuiParametersPresentFlag());
 
   if (sps.getVuiParametersPresentFlag())
@@ -1467,9 +1348,14 @@ void EncLib::xInitSPS( SPS& sps )
   sps.getSpsRangeExtension().setTransformSkipRotationEnabledFlag(m_transformSkipRotationEnabledFlag);
   sps.getSpsRangeExtension().setTransformSkipContextEnabledFlag(m_transformSkipContextEnabledFlag);
   sps.getSpsRangeExtension().setExtendedPrecisionProcessingFlag(m_extendedPrecisionProcessingFlag);
+  sps.getSpsRangeExtension().setTSRCRicePresentFlag(m_tsrcRicePresentFlag);
   sps.getSpsRangeExtension().setIntraSmoothingDisabledFlag( m_intraSmoothingDisabledFlag );
   sps.getSpsRangeExtension().setHighPrecisionOffsetsEnabledFlag(m_highPrecisionOffsetsEnabledFlag);
+  sps.getSpsRangeExtension().setRrcRiceExtensionEnableFlag(m_rrcRiceExtensionEnableFlag);
   sps.getSpsRangeExtension().setPersistentRiceAdaptationEnabledFlag(m_persistentRiceAdaptationEnabledFlag);
+#if JVET_W0046_RLSCP
+  sps.getSpsRangeExtension().setReverseLastSigCoeffEnabledFlag(m_reverseLastSigCoeffEnabledFlag);
+#endif
   sps.getSpsRangeExtension().setCabacBypassAlignmentEnabledFlag(m_cabacBypassAlignmentEnabledFlag);
 
   sps.setSubPicInfoPresentFlag(m_subPicInfoPresentFlag);
@@ -1479,7 +1365,7 @@ void EncLib::xInitSPS( SPS& sps )
     sps.setSubPicSameSizeFlag(m_subPicSameSizeFlag);
     if (m_subPicSameSizeFlag)
     {
-      uint32_t numSubpicCols = (m_iSourceWidth + m_CTUSize - 1) / m_CTUSize / m_subPicWidth[0];
+      uint32_t numSubpicCols = (m_sourceWidth + m_CTUSize - 1) / m_CTUSize / m_subPicWidth[0];
       for (unsigned int i = 0; i < m_numSubPics; i++)
       {
         sps.setSubPicCtuTopLeftX(i, (i % numSubpicCols) * m_subPicWidth[0]);
@@ -1513,8 +1399,8 @@ void EncLib::xInitSPS( SPS& sps )
     sps.setNumSubPics(1);
     sps.setSubPicCtuTopLeftX(0, 0);
     sps.setSubPicCtuTopLeftY(0, 0);
-    sps.setSubPicWidth(0, m_iSourceWidth);
-    sps.setSubPicHeight(0, m_iSourceHeight);
+    sps.setSubPicWidth(0, m_sourceWidth);
+    sps.setSubPicHeight(0, m_sourceHeight);
     sps.setSubPicTreatedAsPicFlag(0, 1);
     sps.setLoopFilterAcrossSubpicEnabledFlag(0, 0);
     sps.setSubPicIdLen(0);
@@ -1549,7 +1435,11 @@ void EncLib::xInitSPS( SPS& sps )
   sps.setInterLayerPresentFlag( m_layerId > 0 && m_vps->getMaxLayers() > 1 && !m_vps->getAllIndependentLayersFlag() && !m_vps->getIndependentLayerFlag( m_vps->getGeneralLayerIdx( m_layerId ) ) );
   CHECK( m_vps->getIndependentLayerFlag( m_vps->getGeneralLayerIdx( m_layerId ) ) && sps.getInterLayerPresentFlag(), " 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." );
 
+#if JVET_W0133_CONSTRAINED_RASL_ENCODING
+  sps.setResChangeInClvsEnabledFlag(m_resChangeInClvsEnabled || m_constrainedRaslEncoding);
+#else
   sps.setResChangeInClvsEnabledFlag(m_resChangeInClvsEnabled);
+#endif
   sps.setRprEnabledFlag(m_rprEnabledFlag);
 
   sps.setLog2ParallelMergeLevelMinus2( m_log2ParallelMergeLevelMinus2 );
@@ -1597,6 +1487,10 @@ void EncLib::xInitPPS(PPS &pps, const SPS &sps)
     bUseDQP = true;
   }
 #endif
+  if (getSmoothQPReductionEnable())
+  {
+    bUseDQP = true;
+  }
 #if ENABLE_QPA
   if (getUsePerceptQPA() && !bUseDQP)
   {
@@ -1624,11 +1518,15 @@ void EncLib::xInitPPS(PPS &pps, const SPS &sps)
     pps.setUseDQP(false);
   }
 
-  if ( m_cuChromaQpOffsetSubdiv >= 0 )
+  if ( m_cuChromaQpOffsetList.size() > 0 )
   {
+    /* insert table entries from cfg parameters (NB, 0 should not be touched) */
     pps.clearChromaQpOffsetList();
-    pps.setChromaQpOffsetListEntry(1, 6, 6, 6);
-    /* todo, insert table entries from command line (NB, 0 should not be touched) */
+    for (int i=0; i < m_cuChromaQpOffsetList.size(); i++)
+    {
+      pps.setChromaQpOffsetListEntry(i + 1, m_cuChromaQpOffsetList[i].u.comp.CbOffset,
+        m_cuChromaQpOffsetList[i].u.comp.CrOffset, m_cuChromaQpOffsetList[i].u.comp.JointCbCrOffset);
+    }
   }
   else
   {
@@ -1650,13 +1548,18 @@ void EncLib::xInitPPS(PPS &pps, const SPS &sps)
     pps.setPicInitQPMinus26( std::min( maxDQP, std::max( minDQP, baseQp ) ));
   }
 
-  if( sps.getJointCbCrEnabledFlag() == false || getChromaFormatIdc() == CHROMA_400 || m_chromaCbCrQpOffset == 0 )
+  if (sps.getJointCbCrEnabledFlag() == false || getChromaFormatIdc() == CHROMA_400)
   {
     pps.setJointCbCrQpOffsetPresentFlag(false);
   }
   else
   {
-    pps.setJointCbCrQpOffsetPresentFlag(true);
+    bool enable = (m_chromaCbCrQpOffset != 0);
+    for (int i=0; i < m_cuChromaQpOffsetList.size(); i++)
+    {
+      enable |= (m_cuChromaQpOffsetList[i].u.comp.JointCbCrOffset != 0);
+    }
+    pps.setJointCbCrQpOffsetPresentFlag(enable);
   }
 
 #if ER_CHROMA_QP_WCG_PPS
@@ -1725,10 +1628,10 @@ void EncLib::xInitPPS(PPS &pps, const SPS &sps)
     pps.setPicWidthMinusWrapAroundOffset      ((pps.getPicWidthInLumaSamples()/minCbSizeY) - (m_wrapAroundOffset / minCbSizeY));
     pps.setWrapAroundOffset                   (minCbSizeY *(pps.getPicWidthInLumaSamples() / minCbSizeY- pps.getPicWidthMinusWrapAroundOffset()));
   }
-  else 
+  else
   {
     pps.setPicWidthMinusWrapAroundOffset      ( 0 );
-    pps.setWrapAroundOffset                   ( 0 );       
+    pps.setWrapAroundOffset                   ( 0 );
   }
   CHECK( !sps.getWrapAroundEnabledFlag() && pps.getWrapAroundEnabledFlag(), "When sps_ref_wraparound_enabled_flag is equal to 0, the value of pps_ref_wraparound_enabled_flag shall be equal to 0.");
   CHECK( (((sps.getCTUSize() / minCbSizeY) + 1) > ((pps.getPicWidthInLumaSamples() / minCbSizeY) - 1)) && pps.getWrapAroundEnabledFlag(), "When the value of CtbSizeY / MinCbSizeY + 1 is greater than pps_pic_width_in_luma_samples / MinCbSizeY - 1, the value of pps_ref_wraparound_enabled_flag shall be equal to 0.");
@@ -1780,7 +1683,7 @@ void EncLib::xInitPPS(PPS &pps, const SPS &sps)
 
   pps.setUseWP( m_useWeightedPred );
   pps.setWPBiPred( m_useWeightedBiPred );
-  pps.setOutputFlagPresentFlag( false );
+  pps.setOutputFlagPresentFlag(false);
 
   if ( getDeblockingFilterMetric() )
   {
@@ -1789,18 +1692,18 @@ void EncLib::xInitPPS(PPS &pps, const SPS &sps)
   }
   else
   {
-    pps.setDeblockingFilterOverrideEnabledFlag( !getLoopFilterOffsetInPPS() );
-    pps.setPPSDeblockingFilterDisabledFlag( getLoopFilterDisable() );
+    pps.setDeblockingFilterOverrideEnabledFlag( !getDeblockingFilterOffsetInPPS() );
+    pps.setPPSDeblockingFilterDisabledFlag( getDeblockingFilterDisable() );
   }
 
   if (! pps.getPPSDeblockingFilterDisabledFlag())
   {
-    pps.setDeblockingFilterBetaOffsetDiv2( getLoopFilterBetaOffset() );
-    pps.setDeblockingFilterTcOffsetDiv2( getLoopFilterTcOffset() );
-    pps.setDeblockingFilterCbBetaOffsetDiv2( getLoopFilterCbBetaOffset() );
-    pps.setDeblockingFilterCbTcOffsetDiv2( getLoopFilterCbTcOffset() );
-    pps.setDeblockingFilterCrBetaOffsetDiv2( getLoopFilterCrBetaOffset() );
-    pps.setDeblockingFilterCrTcOffsetDiv2( getLoopFilterCrTcOffset() );
+    pps.setDeblockingFilterBetaOffsetDiv2  ( getDeblockingFilterBetaOffset() );
+    pps.setDeblockingFilterTcOffsetDiv2    ( getDeblockingFilterTcOffset() );
+    pps.setDeblockingFilterCbBetaOffsetDiv2( getDeblockingFilterCbBetaOffset() );
+    pps.setDeblockingFilterCbTcOffsetDiv2  ( getDeblockingFilterCbTcOffset() );
+    pps.setDeblockingFilterCrBetaOffsetDiv2( getDeblockingFilterCrBetaOffset() );
+    pps.setDeblockingFilterCrTcOffsetDiv2  ( getDeblockingFilterCrTcOffset() );
   }
   else
   {
@@ -1915,6 +1818,10 @@ void EncLib::xInitPicHeader(PicHeader &picHeader, const SPS &sps, const PPS &pps
     bUseDQP = true;
   }
 #endif
+  if (getSmoothQPReductionEnable())
+  {
+    bUseDQP = true;
+  }
 #if ENABLE_QPA
   if( getUsePerceptQPA() && !bUseDQP )
   {
@@ -1944,17 +1851,8 @@ void EncLib::xInitPicHeader(PicHeader &picHeader, const SPS &sps, const PPS &pps
     picHeader.setCuQpDeltaSubdivInter( 0 );
   }
 
-  if( m_cuChromaQpOffsetSubdiv >= 0 )
-  {
-    picHeader.setCuChromaQpOffsetSubdivIntra(m_cuChromaQpOffsetSubdiv);
-    picHeader.setCuChromaQpOffsetSubdivInter(m_cuChromaQpOffsetSubdiv);
-  }
-  else
-  {
-    picHeader.setCuChromaQpOffsetSubdivIntra(0);
-    picHeader.setCuChromaQpOffsetSubdivInter(0);
-  }
-
+  picHeader.setCuChromaQpOffsetSubdivIntra(m_cuChromaQpOffsetSubdiv);
+  picHeader.setCuChromaQpOffsetSubdivInter(m_cuChromaQpOffsetSubdiv);
 
   // virtual boundaries
   if( sps.getVirtualBoundariesEnabledFlag() )
@@ -1968,6 +1866,10 @@ void EncLib::xInitPicHeader(PicHeader &picHeader, const SPS &sps, const PPS &pps
     }
   }
 
+#if GDR_ENABLED  
+    picHeader.setGdrOrIrapPicFlag(false);    
+#endif
+
   // gradual decoder refresh flag
   picHeader.setGdrPicFlag(false);
 
@@ -1982,9 +1884,10 @@ void EncLib::xInitAPS(APS &aps)
   //Do nothing now
 }
 
-void EncLib::xInitRPL(SPS &sps, bool isFieldCoding)
+void EncLib::xInitRPL(SPS &sps)
 {
   ReferencePictureList*      rpl;
+  const bool                 isFieldCoding = sps.getFieldSeqFlag();
 
   int numRPLCandidates = getRPLCandidateSize(0);
   // To allocate one additional memory for RPL of POC1 (first bottom field) which is not specified in cfg file
@@ -2348,6 +2251,12 @@ int EncCfg::getQPForPicture(const uint32_t gopIndex, const Slice *pSlice) const
     }
     else
     {
+      if (pSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP || pSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA)
+      {
+        qp += getIntraQPOffset();
+      }
+      else
+      {
         const GOPEntry &gopEntry=getGOPEntry(gopIndex);
         // adjust QP according to the QP offset for the GOP entry.
         qp +=gopEntry.m_QPOffset;
@@ -2357,6 +2266,7 @@ int EncCfg::getQPForPicture(const uint32_t gopIndex, const Slice *pSlice) const
         int qpOffset = (int)floor(Clip3<double>(0.0, 3.0, dqpOffset));
         qp += qpOffset ;
       }
+    }
 
 #if !QP_SWITCHING_FOR_PARALLEL
     // modify QP if a fractional QP was originally specified, cause dQPs to be 0 or 1.
diff --git a/source/Lib/EncoderLib/EncLib.h b/source/Lib/EncoderLib/EncLib.h
index 517c65cbc..94e383d17 100644
--- a/source/Lib/EncoderLib/EncLib.h
+++ b/source/Lib/EncoderLib/EncLib.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -40,7 +40,7 @@
 
 // Include files
 #include "CommonLib/TrQuant.h"
-#include "CommonLib/LoopFilter.h"
+#include "CommonLib/DeblockingFilter.h"
 #include "CommonLib/NAL.h"
 
 #include "Utilities/VideoIOYuv.h"
@@ -79,65 +79,35 @@ private:
   int                       m_layerId;
 
   // encoder search
-#if ENABLE_SPLIT_PARALLELISM
-  InterSearch              *m_cInterSearch;                       ///< encoder search class
-  IntraSearch              *m_cIntraSearch;                       ///< encoder search class
-#else
   InterSearch               m_cInterSearch;                       ///< encoder search class
   IntraSearch               m_cIntraSearch;                       ///< encoder search class
-#endif
   // coding tool
-#if ENABLE_SPLIT_PARALLELISM
-  TrQuant                  *m_cTrQuant;                           ///< transform & quantization class
-#else
   TrQuant                   m_cTrQuant;                           ///< transform & quantization class
-#endif
-  LoopFilter                m_cLoopFilter;                        ///< deblocking filter class
+  DeblockingFilter          m_deblockingFilter;                   ///< deblocking filter class
   EncSampleAdaptiveOffset   m_cEncSAO;                            ///< sample adaptive offset class
   EncAdaptiveLoopFilter     m_cEncALF;
   HLSWriter                 m_HLSWriter;                          ///< CAVLC encoder
-#if ENABLE_SPLIT_PARALLELISM
-  CABACEncoder             *m_CABACEncoder;
-#else
   CABACEncoder              m_CABACEncoder;
-#endif
 
-#if ENABLE_SPLIT_PARALLELISM
-  EncReshape               *m_cReshaper;                        ///< reshaper class
-#else
   EncReshape                m_cReshaper;                        ///< reshaper class
-#endif
 
   // processing unit
   EncGOP                    m_cGOPEncoder;                        ///< GOP encoder
   EncSlice                  m_cSliceEncoder;                      ///< slice encoder
-#if ENABLE_SPLIT_PARALLELISM
-  EncCu                    *m_cCuEncoder;                         ///< CU encoder
-#else
   EncCu                     m_cCuEncoder;                         ///< CU encoder
-#endif
   // SPS
   ParameterSetMap<SPS>&     m_spsMap;                             ///< SPS. This is the base value. This is copied to PicSym
   ParameterSetMap<PPS>&     m_ppsMap;                             ///< PPS. This is the base value. This is copied to PicSym
   ParameterSetMap<APS>&     m_apsMap;                             ///< APS. This is the base value. This is copied to PicSym
   PicHeader                 m_picHeader;                          ///< picture header
   // RD cost computation
-#if ENABLE_SPLIT_PARALLELISM
-  RdCost                   *m_cRdCost;                            ///< RD cost computation class
-  CtxCache                 *m_CtxCache;                           ///< buffer for temporarily stored context models
-#else
   RdCost                    m_cRdCost;                            ///< RD cost computation class
   CtxCache                  m_CtxCache;                           ///< buffer for temporarily stored context models
-#endif
   // quality control
   RateCtrl                  m_cRateCtrl;                          ///< Rate control class
 
   AUWriterIf*               m_AUWriterIf;
 
-#if ENABLE_SPLIT_PARALLELISM
-  int                       m_numCuEncStacks;
-#endif
-
 #if JVET_J0090_MEMORY_BANDWITH_MEASURE
   CacheModel                m_cacheModel;
 #endif
@@ -167,9 +137,7 @@ public:
 
 protected:
   void  xGetNewPicBuffer  ( std::list<PelUnitBuf*>& rcListPicYuvRecOut, Picture*& rpcPic, int ppsId ); ///< get picture buffer which will be processed. If ppsId<0, then the ppsMap will be queried for the first match.
-#if JVET_S0163_ON_TARGETOLS_SUBLAYERS
   void  xInitOPI(OPI& opi); ///< initialize Operating point Information (OPI) from encoder options
-#endif
   void  xInitDCI(DCI& dci, const SPS& sps); ///< initialize Decoding Capability Information (DCI) from encoder options
   void  xInitVPS( const SPS& sps ); ///< initialize VPS from encoder options
   void  xInitSPS( SPS& sps );       ///< initialize SPS from encoder options
@@ -180,7 +148,7 @@ protected:
   void  xInitPPSforLT(PPS& pps);
   void  xInitHrdParameters(SPS &sps);                 ///< initialize HRDParameters parameters
 
-  void  xInitRPL(SPS &sps, bool isFieldCoding);           ///< initialize SPS from encoder options
+  void xInitRPL(SPS &sps);   ///< initialize SPS from encoder options
 
 public:
   EncLib( EncLibCommon* encLibCommon );
@@ -188,7 +156,7 @@ public:
 
   void      create          ( const int layerId );
   void      destroy         ();
-  void      init            ( bool isFieldCoding, AUWriterIf* auWriterIf );
+  void      init(AUWriterIf *auWriterIf);
   void      deletePicBuffer ();
 
   // -------------------------------------------------------------------------------------------------------------------
@@ -197,40 +165,22 @@ public:
 
   AUWriterIf*             getAUWriterIf         ()              { return   m_AUWriterIf;           }
   PicList*                getListPic            ()              { return  &m_cListPic;             }
-#if ENABLE_SPLIT_PARALLELISM
-  InterSearch*            getInterSearch        ( int jId = 0 ) { return  &m_cInterSearch[jId];    }
-  IntraSearch*            getIntraSearch        ( int jId = 0 ) { return  &m_cIntraSearch[jId];    }
-
-  TrQuant*                getTrQuant            ( int jId = 0 ) { return  &m_cTrQuant[jId];        }
-#else
   InterSearch*            getInterSearch        ()              { return  &m_cInterSearch;         }
   IntraSearch*            getIntraSearch        ()              { return  &m_cIntraSearch;         }
 
   TrQuant*                getTrQuant            ()              { return  &m_cTrQuant;             }
-#endif
-  LoopFilter*             getLoopFilter         ()              { return  &m_cLoopFilter;          }
+  DeblockingFilter*       getDeblockingFilter   ()              { return  &m_deblockingFilter;     }
   EncSampleAdaptiveOffset* getSAO               ()              { return  &m_cEncSAO;              }
   EncAdaptiveLoopFilter*  getALF                ()              { return  &m_cEncALF;              }
   EncGOP*                 getGOPEncoder         ()              { return  &m_cGOPEncoder;          }
   EncSlice*               getSliceEncoder       ()              { return  &m_cSliceEncoder;        }
   EncHRD*                 getHRD                ()              { return  &m_encHRD;               }
-#if ENABLE_SPLIT_PARALLELISM
-  EncCu*                  getCuEncoder          ( int jId = 0 ) { return  &m_cCuEncoder[jId];      }
-#else
   EncCu*                  getCuEncoder          ()              { return  &m_cCuEncoder;           }
-#endif
   HLSWriter*              getHLSWriter          ()              { return  &m_HLSWriter;            }
-#if ENABLE_SPLIT_PARALLELISM
-  CABACEncoder*           getCABACEncoder       ( int jId = 0 ) { return  &m_CABACEncoder[jId];    }
-
-  RdCost*                 getRdCost             ( int jId = 0 ) { return  &m_cRdCost[jId];         }
-  CtxCache*               getCtxCache           ( int jId = 0 ) { return  &m_CtxCache[jId];        }
-#else
   CABACEncoder*           getCABACEncoder       ()              { return  &m_CABACEncoder;         }
 
   RdCost*                 getRdCost             ()              { return  &m_cRdCost;              }
   CtxCache*               getCtxCache           ()              { return  &m_CtxCache;             }
-#endif
   RateCtrl*               getRateCtrl           ()              { return  &m_cRateCtrl;            }
 
 
@@ -244,16 +194,7 @@ public:
   const PPS* getPPS( int Id ) { return m_ppsMap.getPS( Id); }
   const APS*             getAPS(int Id) { return m_apsMap.getPS(Id); }
 
-#if ENABLE_SPLIT_PARALLELISM
-  void                   setNumCuEncStacks( int n )             { m_numCuEncStacks = n; }
-  int                    getNumCuEncStacks()              const { return m_numCuEncStacks; }
-#endif
-
-#if ENABLE_SPLIT_PARALLELISM
-  EncReshape*            getReshaper( int jId = 0 )             { return  &m_cReshaper[jId]; }
-#else
   EncReshape*            getReshaper()                          { return  &m_cReshaper; }
-#endif
 
   ParameterSetMap<APS>*  getApsMap() { return &m_apsMap; }
 
@@ -293,7 +234,11 @@ public:
 
 
   void printSummary(bool isField) { m_cGOPEncoder.printOutSummary(m_uiNumAllPicCoded, isField, m_printMSEBasedSequencePSNR, 
-    m_printSequenceMSE, m_printMSSSIM, m_printHexPsnr, m_resChangeInClvsEnabled, m_spsMap.getFirstPS()->getBitDepths()); }
+    m_printSequenceMSE, m_printMSSSIM, m_printHexPsnr, m_resChangeInClvsEnabled, m_spsMap.getFirstPS()->getBitDepths()
+#if JVET_W0134_UNIFORM_METRICS_LOG
+                                  , m_layerId
+#endif
+                                  ); }
 
   int getLayerId() const { return m_layerId; }
   VPS* getVPS()          { return m_vps;     }
diff --git a/source/Lib/EncoderLib/EncLibCommon.cpp b/source/Lib/EncoderLib/EncLibCommon.cpp
index 770eda97e..1b41432fd 100644
--- a/source/Lib/EncoderLib/EncLibCommon.cpp
+++ b/source/Lib/EncoderLib/EncLibCommon.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/EncoderLib/EncLibCommon.h b/source/Lib/EncoderLib/EncLibCommon.h
index f53ae803d..ff3687f4c 100644
--- a/source/Lib/EncoderLib/EncLibCommon.h
+++ b/source/Lib/EncoderLib/EncLibCommon.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/EncoderLib/EncModeCtrl.cpp b/source/Lib/EncoderLib/EncModeCtrl.cpp
index 858500147..778a40393 100644
--- a/source/Lib/EncoderLib/EncModeCtrl.cpp
+++ b/source/Lib/EncoderLib/EncModeCtrl.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -64,15 +64,6 @@ void EncModeCtrl::init( EncCfg *pCfg, RateCtrl *pRateCtrl, RdCost* pRdCost )
 
 bool EncModeCtrl::tryModeMaster( const EncTestMode& encTestmode, const CodingStructure &cs, Partitioner& partitioner )
 {
-#if ENABLE_SPLIT_PARALLELISM
-  if( m_ComprCUCtxList.back().isLevelSplitParallel )
-  {
-    if( !parallelJobSelector( encTestmode, cs, partitioner ) )
-    {
-      return false;
-    }
-  }
-#endif
   return tryMode( encTestmode, cs, partitioner );
 }
 
@@ -248,18 +239,97 @@ int EncModeCtrl::calculateLumaDQP( const CPelBuf& rcOrg )
 }
 #endif
 
-#if ENABLE_SPLIT_PARALLELISM
-void EncModeCtrl::copyState( const EncModeCtrl& other, const UnitArea& area )
+#if JVET_W0043
+int EncModeCtrl::calculateLumaDQPsmooth(const CPelBuf& rcOrg, int baseQP, double threshold, double scale, double offset, int limit)
+#else
+int EncModeCtrl::calculateLumaDQPsmooth(const CPelBuf& rcOrg, int baseQP)
+#endif
 {
-  m_slice          = other.m_slice;
-  m_fastDeltaQP    = other.m_fastDeltaQP;
-  m_lumaQPOffset   = other.m_lumaQPOffset;
-  m_runNextInParallel
-                   = other.m_runNextInParallel;
-  m_ComprCUCtxList = other.m_ComprCUCtxList;
-}
+  double avg = 0;
+  double diff = 0;
+#if JVET_W0043
+  double thr = (double)threshold*rcOrg.height*rcOrg.width;
+#else
+  double thr = (double)m_pcEncCfg->getSmoothQPReductionThreshold()*rcOrg.height*rcOrg.width;
+#endif
+  int qp = 0;
+  if (rcOrg.height >= 64 && rcOrg.width >= 64)
+  {
+    const int numBasis = 6;
+
+    double invb[numBasis][numBasis] = { {0.001*0.244140625000000,                         0,                         0,                        0,                        0,                        0},
+                                      {                      0,   0.001*0.013204564833946,   0.001*0.002080251479290, -0.001*0.000066039729501, -0.001*0.000165220364313,        0.000000000000000},
+                                      {                      0,   0.001*0.002080251479290,   0.001*0.013204564833946, -0.001*0.000066039729501,        0.000000000000000, -0.001*0.000165220364313},
+                                      {                      0,  -0.001*0.000066039729501,  -0.001*0.000066039729501,  0.001*0.000002096499349,        0.000000000000000,        0.000000000000000},
+                                      {                      0,  -0.001*0.000165220364313,         0.000000000000000,        0.000000000000000,  0.001*0.000002622545465,        0.000000000000000},
+                                      {                      0,         0.000000000000000,  -0.001*0.000165220364313,        0.000000000000000,        0.000000000000000,  0.001*0.000002622545465} };
+    double boffset[5] = { -31.5, -31.5, -992.25, -1333.5, -1333.5 };
+
+    int listQuadrantsX[4] = { 0, 64, 0, 64 };
+    int listQuadrantsY[4] = { 0, 0, 64, 64 };
+
+    double b1sum;
+    double b2sum;
+    double b3sum;
+    double b4sum;
+    double b5sum;
+    double b6sum;
+    int numQuadrantsX = (rcOrg.width == 128) ? 2 : 1;
+    int numQuadrantsY = (rcOrg.height == 128) ? 2 : 1;
+    //loop over quadrants
+    for (int posy = 0; posy < numQuadrantsY; posy++)
+    {
+      for (int posx = 0; posx < numQuadrantsX; posx++)
+      {
+        b2sum = 0.0;
+        b3sum = 0.0;
+        b4sum = 0.0;
+        b5sum = 0.0;
+        b6sum = 0.0;
+        avg = 0.0;
+        for (uint32_t y = 0; y < 64; y++)
+        {
+          for (uint32_t x = 0; x < 64; x++)
+          {
+            const Pel& v = rcOrg.at(x + listQuadrantsX[posx + 2 * posy], y + listQuadrantsY[posx + 2 * posy]);
+            b2sum += ((double)v)*((double)x + boffset[0]);
+            b3sum += ((double)v)*((double)y + boffset[1]);
+            b4sum += ((double)v)*((double)x*(double)y + boffset[2]);
+            b5sum += ((double)v)*((double)x*(double)x + boffset[3]);
+            b6sum += ((double)v)*((double)y*(double)y + boffset[4]);
+            avg += (double)v;
+          }
+        }
+        b1sum = avg;
+        double r[numBasis];
+        for (uint32_t b = 0; b < numBasis; b++)
+        {
+          r[b] = invb[b][0] * b1sum + invb[b][1] * b2sum + invb[b][2] * b3sum + invb[b][3] * b4sum + invb[b][4] * b5sum + invb[b][5] * b6sum;
+        }
+        // compute SAD for model
+        for (uint32_t y = 0; y < 64; y++)
+        {
+          for (uint32_t x = 0; x < 64; x++)
+          {
+            const Pel& v = rcOrg.at(x + listQuadrantsX[posx + 2 * posy], y + listQuadrantsY[posx + 2 * posy]);
 
+            diff += abs((int)v - (int)(r[0] + r[1] * ((double)x + boffset[0]) + r[2] * ((double)y + boffset[1]) + r[3] * ((double)x*(double)y + boffset[2]) + r[4] * ((double)x*(double)x + boffset[3]) + r[5] * ((double)y*(double)y + boffset[4])));
+          }
+        }
+      }
+    }
+    if (diff < thr)
+    {
+#if JVET_W0043
+      qp = max(limit, min(0, (int)(scale*(double)baseQP + offset)));
+#else
+      qp = max(m_pcEncCfg->getSmoothQPReductionLimit(), min(0, (int)(m_pcEncCfg->getSmoothQPReductionModelScale()*(double)baseQP + m_pcEncCfg->getSmoothQPReductionModelOffset())));
 #endif
+    }
+  }
+  return qp;
+}
+
 void CacheBlkInfoCtrl::create()
 {
   const unsigned numPos = MAX_CU_SIZE >> MIN_CU_LOG2;
@@ -267,6 +337,8 @@ void CacheBlkInfoCtrl::create()
   m_numWidths  = gp_sizeIdxInfo->numWidths();
   m_numHeights = gp_sizeIdxInfo->numHeights();
 
+  bool isLog2MttPartitioning = !!dynamic_cast<SizeIndexInfoLog2*>( gp_sizeIdxInfo );
+
   for( unsigned x = 0; x < numPos; x++ )
   {
     for( unsigned y = 0; y < numPos; y++ )
@@ -275,25 +347,39 @@ void CacheBlkInfoCtrl::create()
 
       for( int wIdx = 0; wIdx < gp_sizeIdxInfo->numWidths(); wIdx++ )
       {
-        if( gp_sizeIdxInfo->isCuSize( gp_sizeIdxInfo->sizeFrom( wIdx ) ) && x + ( gp_sizeIdxInfo->sizeFrom( wIdx ) >> MIN_CU_LOG2 ) <= ( MAX_CU_SIZE >> MIN_CU_LOG2 ) )
+        if( !( gp_sizeIdxInfo->isCuSize( gp_sizeIdxInfo->sizeFrom( wIdx ) ) && x + ( gp_sizeIdxInfo->sizeFrom( wIdx ) >> MIN_CU_LOG2 ) <= ( MAX_CU_SIZE >> MIN_CU_LOG2 ) ) )
         {
-          m_codedCUInfo[x][y][wIdx] = new CodedCUInfo*[gp_sizeIdxInfo->numHeights()];
-
-          for( int hIdx = 0; hIdx < gp_sizeIdxInfo->numHeights(); hIdx++ )
-          {
-            if( gp_sizeIdxInfo->isCuSize( gp_sizeIdxInfo->sizeFrom( hIdx ) ) && y + ( gp_sizeIdxInfo->sizeFrom( hIdx ) >> MIN_CU_LOG2 ) <= ( MAX_CU_SIZE >> MIN_CU_LOG2 ) )
-            {
-              m_codedCUInfo[x][y][wIdx][hIdx] = new CodedCUInfo;
-            }
-            else
-            {
-              m_codedCUInfo[x][y][wIdx][hIdx] = nullptr;
-            }
-          }
+          m_codedCUInfo[x][y][wIdx] = nullptr;
+          continue;
         }
-        else
+
+        const int wLog2 = floorLog2( gp_sizeIdxInfo->sizeFrom( wIdx ) );
+
+        if( isLog2MttPartitioning && ( ( x << MIN_CU_LOG2 ) & ( ( 1 << ( wLog2 - 1 ) ) - 1 ) ) != 0 )
         {
           m_codedCUInfo[x][y][wIdx] = nullptr;
+          continue;
+        }
+
+        m_codedCUInfo[x][y][wIdx] = new CodedCUInfo*[gp_sizeIdxInfo->numHeights()];
+
+        for( int hIdx = 0; hIdx < gp_sizeIdxInfo->numHeights(); hIdx++ )
+        {
+          if( !( gp_sizeIdxInfo->isCuSize( gp_sizeIdxInfo->sizeFrom( hIdx ) ) && y + ( gp_sizeIdxInfo->sizeFrom( hIdx ) >> MIN_CU_LOG2 ) <= ( MAX_CU_SIZE >> MIN_CU_LOG2 ) ) )
+          {
+            m_codedCUInfo[x][y][wIdx][hIdx] = nullptr;
+            continue;
+          }
+
+          const int hLog2 = floorLog2( gp_sizeIdxInfo->sizeFrom( hIdx ) );
+
+          if( isLog2MttPartitioning && ( ( ( y << MIN_CU_LOG2 ) & ( ( 1 << ( hLog2 - 1 ) ) - 1 ) ) != 0 ) )
+          {
+            m_codedCUInfo[x][y][wIdx][hIdx] = nullptr;
+            continue;
+          }
+
+          m_codedCUInfo[x][y][wIdx][hIdx] = new CodedCUInfo;
         }
       }
     }
@@ -354,72 +440,8 @@ void CacheBlkInfoCtrl::init( const Slice &slice )
   }
 
   m_slice_chblk = &slice;
-#if ENABLE_SPLIT_PARALLELISM
-
-  m_currTemporalId = 0;
-#endif
-}
-#if ENABLE_SPLIT_PARALLELISM
-
-void CacheBlkInfoCtrl::touch( const UnitArea& area )
-{
-  CodedCUInfo& cuInfo = getBlkInfo( area );
-  cuInfo.temporalId = m_currTemporalId;
 }
 
-void CacheBlkInfoCtrl::copyState( const CacheBlkInfoCtrl &other, const UnitArea& area )
-{
-  m_slice_chblk = other.m_slice_chblk;
-
-  m_currTemporalId = other.m_currTemporalId;
-
-  if( m_slice_chblk->isIntra() ) return;
-
-  const int cuSizeMask = m_slice_chblk->getSPS()->getMaxCUWidth() - 1;
-
-  const int minPosX = ( area.lx() & cuSizeMask ) >> MIN_CU_LOG2;
-  const int minPosY = ( area.ly() & cuSizeMask ) >> MIN_CU_LOG2;
-  const int maxPosX = ( area.Y().bottomRight().x & cuSizeMask ) >> MIN_CU_LOG2;
-  const int maxPosY = ( area.Y().bottomRight().y & cuSizeMask ) >> MIN_CU_LOG2;
-
-  for( unsigned x = minPosX; x <= maxPosX; x++ )
-  {
-    for( unsigned y = minPosY; y <= maxPosY; y++ )
-    {
-      for( int wIdx = 0; wIdx < gp_sizeIdxInfo->numWidths(); wIdx++ )
-      {
-        const int width = gp_sizeIdxInfo->sizeFrom( wIdx );
-
-        if( m_codedCUInfo[x][y][wIdx] && width <= area.lwidth() && x + ( width >> MIN_CU_LOG2 ) <= ( maxPosX + 1 ) )
-        {
-          for( int hIdx = 0; hIdx < gp_sizeIdxInfo->numHeights(); hIdx++ )
-          {
-            const int height = gp_sizeIdxInfo->sizeFrom( hIdx );
-
-            if( gp_sizeIdxInfo->isCuSize( height ) && height <= area.lheight() && y + ( height >> MIN_CU_LOG2 ) <= ( maxPosY + 1 ) )
-            {
-              if( other.m_codedCUInfo[x][y][wIdx][hIdx]->temporalId > m_codedCUInfo[x][y][wIdx][hIdx]->temporalId )
-              {
-                *m_codedCUInfo[x][y][wIdx][hIdx] = *other.m_codedCUInfo[x][y][wIdx][hIdx];
-                m_codedCUInfo[x][y][wIdx][hIdx]->temporalId = m_currTemporalId;
-              }
-            }
-            else if( y + ( height >> MIN_CU_LOG2 ) > maxPosY + 1 )
-            {
-              break;;
-            }
-          }
-        }
-        else if( x + ( width >> MIN_CU_LOG2 ) > maxPosX + 1 )
-        {
-          break;
-        }
-      }
-    }
-  }
-}
-#endif
-
 CodedCUInfo& CacheBlkInfoCtrl::getBlkInfo( const UnitArea& area )
 {
   unsigned idx1, idx2, idx3, idx4;
@@ -461,10 +483,6 @@ void CacheBlkInfoCtrl::setMv( const UnitArea& area, const RefPicList refPicList,
 
   m_codedCUInfo[idx1][idx2][idx3][idx4]->saveMv [refPicList][iRefIdx] = rMv;
   m_codedCUInfo[idx1][idx2][idx3][idx4]->validMv[refPicList][iRefIdx] = true;
-#if ENABLE_SPLIT_PARALLELISM
-
-  touch( area );
-#endif
 }
 
 bool CacheBlkInfoCtrl::getMv( const UnitArea& area, const RefPicList refPicList, const int iRefIdx, Mv& rMv ) const
@@ -563,13 +581,6 @@ bool SaveLoadEncInfoSbt::saveBestSbt( const UnitArea& area, const uint32_t curPu
   return true;
 }
 
-#if ENABLE_SPLIT_PARALLELISM
-void SaveLoadEncInfoSbt::copyState(const SaveLoadEncInfoSbt &other)
-{
-  m_sliceSbt = other.m_sliceSbt;
-}
-#endif
-
 void SaveLoadEncInfoSbt::resetSaveloadSbt( int maxSbtSize )
 {
   int numSizeIdx = gp_sizeIdxInfo->idxFrom( maxSbtSize ) - MIN_CU_LOG2 + 1;
@@ -653,6 +664,8 @@ void BestEncInfoCache::create( const ChromaFormat chFmt )
   m_numWidths  = gp_sizeIdxInfo->numWidths();
   m_numHeights = gp_sizeIdxInfo->numHeights();
 
+  bool isLog2MttPartitioning = !!dynamic_cast<SizeIndexInfoLog2*>( gp_sizeIdxInfo );
+
   for( unsigned x = 0; x < numPos; x++ )
   {
     for( unsigned y = 0; y < numPos; y++ )
@@ -661,45 +674,59 @@ void BestEncInfoCache::create( const ChromaFormat chFmt )
 
       for( int wIdx = 0; wIdx < gp_sizeIdxInfo->numWidths(); wIdx++ )
       {
-        if( gp_sizeIdxInfo->isCuSize( gp_sizeIdxInfo->sizeFrom( wIdx ) ) && x + ( gp_sizeIdxInfo->sizeFrom( wIdx ) >> MIN_CU_LOG2 ) <= ( MAX_CU_SIZE >> MIN_CU_LOG2 ) )
+        if( !( gp_sizeIdxInfo->isCuSize( gp_sizeIdxInfo->sizeFrom( wIdx ) ) && x + ( gp_sizeIdxInfo->sizeFrom( wIdx ) >> MIN_CU_LOG2 ) <= ( MAX_CU_SIZE >> MIN_CU_LOG2 ) ) )
         {
-          m_bestEncInfo[x][y][wIdx] = new BestEncodingInfo*[gp_sizeIdxInfo->numHeights()];
+          m_bestEncInfo[x][y][wIdx] = nullptr;
+          continue;
+        }
 
-          for( int hIdx = 0; hIdx < gp_sizeIdxInfo->numHeights(); hIdx++ )
+        const int wLog2 = floorLog2( gp_sizeIdxInfo->sizeFrom( wIdx ) );
+
+        if( isLog2MttPartitioning && ( ( x << MIN_CU_LOG2 ) & ( ( 1 << ( wLog2 - 1 ) ) - 1 ) ) != 0 )
+        {
+          m_bestEncInfo[x][y][wIdx] = nullptr;
+          continue;
+        }
+
+        m_bestEncInfo[x][y][wIdx] = new BestEncodingInfo*[gp_sizeIdxInfo->numHeights()];
+
+        for( int hIdx = 0; hIdx < gp_sizeIdxInfo->numHeights(); hIdx++ )
+        {
+          if( !( gp_sizeIdxInfo->isCuSize( gp_sizeIdxInfo->sizeFrom( hIdx ) ) && y + ( gp_sizeIdxInfo->sizeFrom( hIdx ) >> MIN_CU_LOG2 ) <= ( MAX_CU_SIZE >> MIN_CU_LOG2 ) ) )
           {
-            if( gp_sizeIdxInfo->isCuSize( gp_sizeIdxInfo->sizeFrom( hIdx ) ) && y + ( gp_sizeIdxInfo->sizeFrom( hIdx ) >> MIN_CU_LOG2 ) <= ( MAX_CU_SIZE >> MIN_CU_LOG2 ) )
-            {
-              m_bestEncInfo[x][y][wIdx][hIdx] = new BestEncodingInfo;
+            m_bestEncInfo[x][y][wIdx][hIdx] = nullptr;
+            continue;
+          }
 
-              int w = gp_sizeIdxInfo->sizeFrom( wIdx );
-              int h = gp_sizeIdxInfo->sizeFrom( hIdx );
+          const int hLog2 = floorLog2( gp_sizeIdxInfo->sizeFrom( hIdx ) );
 
-              const UnitArea area( chFmt, Area( 0, 0, w, h ) );
+          if( isLog2MttPartitioning && ( ( ( y << MIN_CU_LOG2 ) & ( ( 1 << ( hLog2 - 1 ) ) - 1 ) ) != 0 ) )
+          {
+            m_bestEncInfo[x][y][wIdx][hIdx] = nullptr;
+            continue;
+          }
 
-              new ( &m_bestEncInfo[x][y][wIdx][hIdx]->cu ) CodingUnit    ( area );
-              new ( &m_bestEncInfo[x][y][wIdx][hIdx]->pu ) PredictionUnit( area );
+          m_bestEncInfo[x][y][wIdx][hIdx] = new BestEncodingInfo;
+
+          int w = gp_sizeIdxInfo->sizeFrom( wIdx );
+          int h = gp_sizeIdxInfo->sizeFrom( hIdx );
+
+          const UnitArea area( chFmt, Area( 0, 0, w, h ) );
+
+          new ( &m_bestEncInfo[x][y][wIdx][hIdx]->cu ) CodingUnit    ( area );
+          new ( &m_bestEncInfo[x][y][wIdx][hIdx]->pu ) PredictionUnit( area );
 #if REUSE_CU_RESULTS_WITH_MULTIPLE_TUS
-              m_bestEncInfo[x][y][wIdx][hIdx]->numTus = 0;
-              for( int i = 0; i < MAX_NUM_TUS; i++ )
-              {
-                new ( &m_bestEncInfo[x][y][wIdx][hIdx]->tus[i] ) TransformUnit( area );
-              }
+          m_bestEncInfo[x][y][wIdx][hIdx]->numTus = 0;
+          for( int i = 0; i < MAX_NUM_TUS; i++ )
+          {
+            new ( &m_bestEncInfo[x][y][wIdx][hIdx]->tus[i] ) TransformUnit( area );
+          }
 #else
-              new ( &m_bestEncInfo[x][y][wIdx][hIdx]->tu ) TransformUnit( area );
+          new ( &m_bestEncInfo[x][y][wIdx][hIdx]->tu ) TransformUnit( area );
 #endif
 
-              m_bestEncInfo[x][y][wIdx][hIdx]->poc      = -1;
-              m_bestEncInfo[x][y][wIdx][hIdx]->testMode = EncTestMode();
-            }
-            else
-            {
-              m_bestEncInfo[x][y][wIdx][hIdx] = nullptr;
-            }
-          }
-        }
-        else
-        {
-          m_bestEncInfo[x][y][wIdx] = nullptr;
+          m_bestEncInfo[x][y][wIdx][hIdx]->poc      = -1;
+          m_bestEncInfo[x][y][wIdx][hIdx]->testMode = EncTestMode();
         }
       }
     }
@@ -852,10 +879,6 @@ void BestEncInfoCache::init( const Slice &slice )
       }
     }
   }
-#if ENABLE_SPLIT_PARALLELISM
-
-  m_currTemporalId = 0;
-#endif
 }
 
 bool BestEncInfoCache::setFromCs( const CodingStructure& cs, const Partitioner& partitioner )
@@ -923,7 +946,7 @@ bool BestEncInfoCache::isValid( const CodingStructure& cs, const Partitioner& pa
   {
     return false;
   }
-  if( encInfo.cu.qp != qp )
+  if( encInfo.cu.qp != qp || cs.slice->getUseChromaQpAdj())
     return false;
   if( cs.picture->poc != encInfo.poc || CS::getArea( cs, cs.area, partitioner.chType ) != CS::getArea( cs, encInfo.cu, partitioner.chType ) || !isTheSameNbHood( encInfo.cu, cs, partitioner
     , encInfo.pu, (cs.picture->Y().width), (cs.picture->Y().height)
@@ -993,75 +1016,6 @@ bool BestEncInfoCache::setCsFrom( CodingStructure& cs, EncTestMode& testMode, co
   return true;
 }
 
-#if ENABLE_SPLIT_PARALLELISM
-void BestEncInfoCache::copyState(const BestEncInfoCache &other, const UnitArea &area)
-{
-  m_slice_bencinf  = other.m_slice_bencinf;
-  m_currTemporalId = other.m_currTemporalId;
-
-  if( m_slice_bencinf->isIntra() ) return;
-
-  const int cuSizeMask = m_slice_bencinf->getSPS()->getMaxCUWidth() - 1;
-
-  const int minPosX = ( area.lx() & cuSizeMask ) >> MIN_CU_LOG2;
-  const int minPosY = ( area.ly() & cuSizeMask ) >> MIN_CU_LOG2;
-  const int maxPosX = ( area.Y().bottomRight().x & cuSizeMask ) >> MIN_CU_LOG2;
-  const int maxPosY = ( area.Y().bottomRight().y & cuSizeMask ) >> MIN_CU_LOG2;
-
-  for( unsigned x = minPosX; x <= maxPosX; x++ )
-  {
-    for( unsigned y = minPosY; y <= maxPosY; y++ )
-    {
-      for( int wIdx = 0; wIdx < gp_sizeIdxInfo->numWidths(); wIdx++ )
-      {
-        const int width = gp_sizeIdxInfo->sizeFrom( wIdx );
-
-        if( m_bestEncInfo[x][y][wIdx] && width <= area.lwidth() && x + ( width >> MIN_CU_LOG2 ) <= ( maxPosX + 1 ) )
-        {
-          for( int hIdx = 0; hIdx < gp_sizeIdxInfo->numHeights(); hIdx++ )
-          {
-            const int height = gp_sizeIdxInfo->sizeFrom( hIdx );
-
-            if( gp_sizeIdxInfo->isCuSize( height ) && height <= area.lheight() && y + ( height >> MIN_CU_LOG2 ) <= ( maxPosY + 1 ) )
-            {
-              if( other.m_bestEncInfo[x][y][wIdx][hIdx]->temporalId > m_bestEncInfo[x][y][wIdx][hIdx]->temporalId )
-              {
-                m_bestEncInfo[x][y][wIdx][hIdx]->cu       = other.m_bestEncInfo[x][y][wIdx][hIdx]->cu;
-                m_bestEncInfo[x][y][wIdx][hIdx]->pu       = other.m_bestEncInfo[x][y][wIdx][hIdx]->pu;
-                m_bestEncInfo[x][y][wIdx][hIdx]->numTus   = other.m_bestEncInfo[x][y][wIdx][hIdx]->numTus;
-                m_bestEncInfo[x][y][wIdx][hIdx]->poc      = other.m_bestEncInfo[x][y][wIdx][hIdx]->poc;
-                m_bestEncInfo[x][y][wIdx][hIdx]->testMode = other.m_bestEncInfo[x][y][wIdx][hIdx]->testMode;
-
-                for( int i = 0; i < m_bestEncInfo[x][y][wIdx][hIdx]->numTus; i++ )
-                  m_bestEncInfo[x][y][wIdx][hIdx]->tus[i] = other.m_bestEncInfo[x][y][wIdx][hIdx]->tus[i];
-              }
-            }
-            else if( y + ( height >> MIN_CU_LOG2 ) > maxPosY + 1 )
-            {
-              break;;
-            }
-          }
-        }
-        else if( x + ( width >> MIN_CU_LOG2 ) > maxPosX + 1 )
-        {
-          break;
-        }
-      }
-    }
-  }
-}
-
-void BestEncInfoCache::touch(const UnitArea &area)
-{
-  unsigned idx1, idx2, idx3, idx4;
-  getAreaIdx(area.Y(), *m_slice_bencinf->getPPS()->pcv, idx1, idx2, idx3, idx4);
-  BestEncodingInfo &encInfo = *m_bestEncInfo[idx1][idx2][idx3][idx4];
-
-  encInfo.temporalId = m_currTemporalId;
-}
-
-#endif
-
 #endif
 
 static bool interHadActive( const ComprCUCtx& ctx )
@@ -1075,6 +1029,9 @@ static bool interHadActive( const ComprCUCtx& ctx )
 
 void EncModeCtrlMTnoRQT::create( const EncCfg& cfg )
 {
+#if GDR_ENABLED
+  m_encCfg = cfg;
+#endif
   CacheBlkInfoCtrl::create();
 #if REUSE_CU_RESULTS
   BestEncInfoCache::create( cfg.getChromaFormatIdc() );
@@ -1102,9 +1059,6 @@ void EncModeCtrlMTnoRQT::initCTUEncoding( const Slice &slice )
   CHECK( !m_ComprCUCtxList.empty(), "Mode list is not empty at the beginning of a CTU" );
 
   m_slice             = &slice;
-#if ENABLE_SPLIT_PARALLELISM
-  m_runNextInParallel      = false;
-#endif
 
   if( m_pcEncCfg->getUseE0023FastEnc() )
   {
@@ -1136,19 +1090,6 @@ void EncModeCtrlMTnoRQT::initCULevel( Partitioner &partitioner, const CodingStru
 
   m_ComprCUCtxList.push_back( ComprCUCtx( cs, minDepth, maxDepth, NUM_EXTRA_FEATURES ) );
 
-#if ENABLE_SPLIT_PARALLELISM
-  if( m_runNextInParallel )
-  {
-    for( auto &level : m_ComprCUCtxList )
-    {
-      CHECK( level.isLevelSplitParallel, "Tring to parallelize a level within parallel execution!" );
-    }
-    CHECK( cs.picture->scheduler.getSplitJobId() == 0, "Trying to run a parallel level although jobId is 0!" );
-    m_runNextInParallel                          = false;
-    m_ComprCUCtxList.back().isLevelSplitParallel = true;
-  }
-
-#endif
   const CodingUnit* cuLeft  = cs.getCU( cs.area.blocks[partitioner.chType].pos().offset( -1, 0 ), partitioner.chType );
   const CodingUnit* cuAbove = cs.getCU( cs.area.blocks[partitioner.chType].pos().offset( 0, -1 ), partitioner.chType );
 
@@ -1207,6 +1148,40 @@ void EncModeCtrlMTnoRQT::initCULevel( Partitioner &partitioner, const CodingStru
       baseQP = Clip3 (-cs.sps->getQpBDOffset (CHANNEL_TYPE_LUMA), MAX_QP, baseQP - m_lumaQPOffset);
     }
 #endif
+    if (m_pcEncCfg->getSmoothQPReductionEnable())
+    {
+      int smoothQPoffset = 0;
+      if (partitioner.currQgEnable())
+      {
+        // enable smooth QP reduction on selected frames
+        bool checkSmoothQP = false;
+        if (m_pcEncCfg->getSmoothQPReductionPeriodicity() != 0)
+        {
+          checkSmoothQP = ((m_pcEncCfg->getSmoothQPReductionPeriodicity() == 0) && cs.slice->isIntra()) || (m_pcEncCfg->getSmoothQPReductionPeriodicity() == 1) || ((cs.slice->getPOC() % m_pcEncCfg->getSmoothQPReductionPeriodicity()) == 0);
+        }
+        else
+        {
+          checkSmoothQP = ((m_pcEncCfg->getSmoothQPReductionPeriodicity() == 0) && cs.slice->isIntra());
+        }
+        if (checkSmoothQP)
+        {
+#if JVET_W0043
+          bool isIntraSlice = cs.slice->isIntra();
+          if (isIntraSlice)
+          {
+            smoothQPoffset = calculateLumaDQPsmooth(cs.getOrgBuf(clipArea(cs.area.Y(), cs.picture->Y())), baseQP, m_pcEncCfg->getSmoothQPReductionThresholdIntra(), m_pcEncCfg->getSmoothQPReductionModelScaleIntra(), m_pcEncCfg->getSmoothQPReductionModelOffsetIntra(), m_pcEncCfg->getSmoothQPReductionLimitIntra());
+          }
+          else
+          {
+            smoothQPoffset = calculateLumaDQPsmooth(cs.getOrgBuf(clipArea(cs.area.Y(), cs.picture->Y())), baseQP, m_pcEncCfg->getSmoothQPReductionThresholdInter(), m_pcEncCfg->getSmoothQPReductionModelScaleInter(), m_pcEncCfg->getSmoothQPReductionModelOffsetInter(), m_pcEncCfg->getSmoothQPReductionLimitInter());
+          }
+#else
+          smoothQPoffset = calculateLumaDQPsmooth(cs.getOrgBuf(clipArea(cs.area.Y(), cs.picture->Y())), baseQP);
+#endif
+        }
+      }
+      baseQP = Clip3(-cs.sps->getQpBDOffset(CHANNEL_TYPE_LUMA), MAX_QP, baseQP + smoothQPoffset);
+    }
   }
   int minQP = baseQP;
   int maxQP = baseQP;
@@ -1369,7 +1344,7 @@ void EncModeCtrlMTnoRQT::initCULevel( Partitioner &partitioner, const CodingStru
           m_ComprCUCtxList.back().testModes.push_back( { ETM_MERGE_GEO, ETO_STANDARD, qp } );
         }
         m_ComprCUCtxList.back().testModes.push_back( { ETM_MERGE_SKIP,  ETO_STANDARD, qp } );
-        if (cs.sps->getUseAffine() || cs.sps->getSbTMVPEnabledFlag())
+        if (cs.sps->getUseAffine() || (cs.sps->getSbTMVPEnabledFlag() && cs.slice->getPicHeader()->getEnableTMVPFlag()))
         {
           m_ComprCUCtxList.back().testModes.push_back( { ETM_AFFINE,    ETO_STANDARD, qp } );
         }
@@ -1383,7 +1358,7 @@ void EncModeCtrlMTnoRQT::initCULevel( Partitioner &partitioner, const CodingStru
           m_ComprCUCtxList.back().testModes.push_back( { ETM_MERGE_GEO, ETO_STANDARD, qp } );
         }
         m_ComprCUCtxList.back().testModes.push_back( { ETM_MERGE_SKIP,  ETO_STANDARD, qp } );
-        if (cs.sps->getUseAffine() || cs.sps->getSbTMVPEnabledFlag())
+        if (cs.sps->getUseAffine() || (cs.sps->getSbTMVPEnabledFlag() && cs.slice->getPicHeader()->getEnableTMVPFlag()))
         {
           m_ComprCUCtxList.back().testModes.push_back( { ETM_AFFINE,    ETO_STANDARD, qp } );
         }
@@ -1421,7 +1396,14 @@ bool EncModeCtrlMTnoRQT::tryMode( const EncTestMode& encTestmode, const CodingSt
   // Fast checks, partitioning depended
   if (cuECtx.isHashPerfectMatch && encTestmode.type != ETM_MERGE_SKIP && encTestmode.type != ETM_INTER_ME && encTestmode.type != ETM_AFFINE && encTestmode.type != ETM_MERGE_GEO)
   {
+#if GDR_ENABLED // disable hash perfect match when GDR is on
+    if (!m_encCfg.getGdrEnabled())
+    {
+      return false;
+    }
+#else
     return false;
+#endif
   }
 
   // if early skip detected, skip all modes checking but the splits
@@ -1570,7 +1552,7 @@ bool EncModeCtrlMTnoRQT::tryMode( const EncTestMode& encTestmode, const CodingSt
   {
     if (partitioner.currArea().lumaSize().width > 64 || partitioner.currArea().lumaSize().height > 64
         || ((partitioner.currArea().lumaSize().width * partitioner.currArea().lumaSize().height <= 16) && (isLuma(partitioner.chType)) )
-        || ((partitioner.currArea().chromaSize().width * partitioner.currArea().chromaSize().height <= 16) && (!isLuma(partitioner.chType)) && partitioner.isSepTree(cs) ) 
+        || ((partitioner.currArea().chromaSize().width * partitioner.currArea().chromaSize().height <= 16) && (!isLuma(partitioner.chType)) && partitioner.isSepTree(cs) )
       || (partitioner.isLocalSepTree(cs)  && (!isLuma(partitioner.chType)) ) )
     {
       return false;
@@ -1746,9 +1728,6 @@ bool EncModeCtrlMTnoRQT::tryMode( const EncTestMode& encTestmode, const CodingSt
     {
       case CU_QUAD_SPLIT:
         {
-#if ENABLE_SPLIT_PARALLELISM
-          if( !cuECtx.isLevelSplitParallel )
-#endif
           if( !cuECtx.get<bool>( QT_BEFORE_BT ) && bestCU )
           {
             unsigned maxBTD        = cs.pcv->getMaxBtDepth( slice, partitioner.chType );
@@ -1971,12 +1950,7 @@ bool EncModeCtrlMTnoRQT::tryMode( const EncTestMode& encTestmode, const CodingSt
             relatedCU.relatedCuIsValid   = true;
           }
         }
-#if ENABLE_SPLIT_PARALLELISM
-#if REUSE_CU_RESULTS
-        BestEncInfoCache::touch(partitioner.currArea());
-#endif
-        CacheBlkInfoCtrl::touch(partitioner.currArea());
-#endif
+
         cuECtx.set( IS_BEST_NOSPLIT_SKIP, bestCU->skip );
       }
     }
@@ -2117,105 +2091,3 @@ bool EncModeCtrlMTnoRQT::useModeResult( const EncTestMode& encTestmode, CodingSt
   }
 }
 
-#if ENABLE_SPLIT_PARALLELISM
-void EncModeCtrlMTnoRQT::copyState( const EncModeCtrl& other, const UnitArea& area )
-{
-  const EncModeCtrlMTnoRQT* pOther = dynamic_cast<const EncModeCtrlMTnoRQT*>( &other );
-
-  CHECK( !pOther, "Trying to copy state from a different type of controller" );
-
-  this->EncModeCtrl        ::copyState( *pOther, area );
-  this->CacheBlkInfoCtrl   ::copyState( *pOther, area );
-#if REUSE_CU_RESULTS
-  this->BestEncInfoCache   ::copyState( *pOther, area );
-#endif
-  this->SaveLoadEncInfoSbt ::copyState( *pOther );
-
-  m_skipThreshold = pOther->m_skipThreshold;
-}
-
-int EncModeCtrlMTnoRQT::getNumParallelJobs( const CodingStructure &cs, Partitioner& partitioner ) const
-{
-  int numJobs = 0;
-
-  if(      partitioner.canSplit( CU_TRIH_SPLIT, cs ) )
-  {
-    numJobs = 6;
-  }
-  else if( partitioner.canSplit( CU_TRIV_SPLIT, cs ) )
-  {
-    numJobs = 5;
-  }
-  else if( partitioner.canSplit( CU_HORZ_SPLIT, cs ) )
-  {
-    numJobs = 4;
-  }
-  else if( partitioner.canSplit( CU_VERT_SPLIT, cs ) )
-  {
-    numJobs = 3;
-  }
-  else if( partitioner.canSplit( CU_QUAD_SPLIT, cs ) )
-  {
-    numJobs = 2;
-  }
-  else if( partitioner.canSplit( CU_DONT_SPLIT, cs ) )
-  {
-    numJobs = 1;
-  }
-
-  CHECK( numJobs >= NUM_RESERVERD_SPLIT_JOBS, "More jobs specified than allowed" );
-
-  return numJobs;
-}
-
-bool EncModeCtrlMTnoRQT::isParallelSplit( const CodingStructure &cs, Partitioner& partitioner ) const
-{
-  if( partitioner.getImplicitSplit( cs ) != CU_DONT_SPLIT || cs.picture->scheduler.getSplitJobId() != 0 ) return false;
-  if( cs.pps->getUseDQP() && partitioner.currQgEnable() ) return false;
-  const int numJobs = getNumParallelJobs( cs, partitioner );
-  const int numPxl  = partitioner.currArea().Y().area();
-  const int parlAt  = m_pcEncCfg->getNumSplitThreads() <= 3 ? 1024 : 256;
-  if(  cs.slice->isIntra() && numJobs > 2 && ( numPxl == parlAt || !partitioner.canSplit( CU_QUAD_SPLIT, cs ) ) ) return true;
-  if( !cs.slice->isIntra() && numJobs > 1 && ( numPxl == parlAt || !partitioner.canSplit( CU_QUAD_SPLIT, cs ) ) ) return true;
-  return false;
-}
-
-bool EncModeCtrlMTnoRQT::parallelJobSelector( const EncTestMode& encTestmode, const CodingStructure &cs, Partitioner& partitioner ) const
-{
-  // Job descriptors
-  //  - 1: all non-split modes
-  //  - 2: QT-split
-  //  - 3: all vertical modes but TT_V
-  //  - 4: all horizontal modes but TT_H
-  //  - 5: TT_V
-  //  - 6: TT_H
-  switch( cs.picture->scheduler.getSplitJobId() )
-  {
-  case 1:
-    // be sure to execute post dont split
-    return !isModeSplit( encTestmode );
-    break;
-  case 2:
-    return encTestmode.type == ETM_SPLIT_QT;
-    break;
-  case 3:
-    return encTestmode.type == ETM_SPLIT_BT_V;
-    break;
-  case 4:
-    return encTestmode.type == ETM_SPLIT_BT_H;
-    break;
-  case 5:
-    return encTestmode.type == ETM_SPLIT_TT_V;
-    break;
-  case 6:
-    return encTestmode.type == ETM_SPLIT_TT_H;
-    break;
-  default:
-    THROW( "Unknown job-ID for parallelization of EncModeCtrlMTnoRQT: " << cs.picture->scheduler.getSplitJobId() );
-    break;
-  }
-}
-
-#endif
-
-
diff --git a/source/Lib/EncoderLib/EncModeCtrl.h b/source/Lib/EncoderLib/EncModeCtrl.h
index 0eb7a3329..d48ac0312 100644
--- a/source/Lib/EncoderLib/EncModeCtrl.h
+++ b/source/Lib/EncoderLib/EncModeCtrl.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -194,10 +194,6 @@ struct ComprCUCtx
     , skipSecondMTSPass
                     ( false )
     , interHad      (std::numeric_limits<Distortion>::max())
-#if ENABLE_SPLIT_PARALLELISM
-    , isLevelSplitParallel
-                    ( false )
-#endif
     , bestCostWithoutSplitFlags( MAX_DOUBLE )
     , bestCostMtsFirstPassNoIsp( MAX_DOUBLE )
     , bestCostIsp   ( MAX_DOUBLE )
@@ -245,9 +241,6 @@ struct ComprCUCtx
   double                            bestMtsSize2Nx2N1stPass;
   bool                              skipSecondMTSPass;
   Distortion                        interHad;
-#if ENABLE_SPLIT_PARALLELISM
-  bool                              isLevelSplitParallel;
-#endif
   double                            bestCostWithoutSplitFlags;
   double                            bestCostMtsFirstPassNoIsp;
   double                            bestCostIsp;
@@ -286,9 +279,6 @@ protected:
 #endif
   bool                  m_fastDeltaQP;
   static_vector<ComprCUCtx, ( MAX_CU_DEPTH << 2 )> m_ComprCUCtxList;
-#if ENABLE_SPLIT_PARALLELISM
-  int                   m_runNextInParallel;
-#endif
   InterSearch*          m_pcInterSearch;
 
   bool                  m_doPlt;
@@ -311,13 +301,6 @@ public:
 
   virtual bool useModeResult        ( const EncTestMode& encTestmode, CodingStructure*& tempCS,  Partitioner& partitioner ) = 0;
   virtual bool checkSkipOtherLfnst  ( const EncTestMode& encTestmode, CodingStructure*& tempCS,  Partitioner& partitioner ) = 0;
-#if ENABLE_SPLIT_PARALLELISM
-  virtual void copyState            ( const EncModeCtrl& other, const UnitArea& area );
-  virtual int  getNumParallelJobs   ( const CodingStructure &cs, Partitioner& partitioner )                                 const { return 1;     }
-  virtual bool isParallelSplit      ( const CodingStructure &cs, Partitioner& partitioner )                                 const { return false; }
-  virtual bool parallelJobSelector  ( const EncTestMode& encTestmode, const CodingStructure &cs, Partitioner& partitioner ) const { return true;  }
-          void setParallelSplit     ( bool val ) { m_runNextInParallel = val; }
-#endif
 
   void         init                 ( EncCfg *pCfg, RateCtrl *pRateCtrl, RdCost *pRdCost );
   bool         tryModeMaster        ( const EncTestMode& encTestmode, const CodingStructure &cs, Partitioner& partitioner );
@@ -335,6 +318,11 @@ public:
 #if SHARP_LUMA_DELTA_QP
   void                  initLumaDeltaQpLUT();
   int                   calculateLumaDQP  ( const CPelBuf& rcOrg );
+#endif
+#if JVET_W0043
+  int                                 calculateLumaDQPsmooth(const CPelBuf& rcOrg, int baseQP, double threshold, double scale, double offset, int limit);
+#else
+  int                                 calculateLumaDQPsmooth(const CPelBuf& rcOrg, int baseQP);
 #endif
   void setFastDeltaQp                 ( bool b )                {        m_fastDeltaQP = b;                               }
   bool getFastDeltaQp                 ()                  const { return m_fastDeltaQP;                                   }
@@ -374,6 +362,393 @@ public:
   void   setPltEnc                    ( bool b )                { m_doPlt = b; }
   bool   getPltEnc()                                      const { return m_doPlt; }
 
+#if GDR_ENABLED
+void forceIntraMode()
+{ 
+  // remove all inter or split to force make intra      
+  int n = (int)m_ComprCUCtxList.back().testModes.size();   
+  for (int j = 0; j < n; j++) 
+  {
+    const EncTestMode etm = m_ComprCUCtxList.back().testModes[j];
+
+    if (isModeInter(etm.type)) 
+    {
+      m_ComprCUCtxList.back().testModes.erase(m_ComprCUCtxList.back().testModes.begin() + j);
+      j--;
+      n--;          
+    }
+  }  
+}
+
+void forceIntraNoSplit()
+{
+  // remove all inter or split to force make intra        
+  int n = (int)m_ComprCUCtxList.back().testModes.size();
+
+  for (int j = 0; j < n; j++) 
+  {
+    const EncTestMode etm = m_ComprCUCtxList.back().testModes[j];
+
+    if (isModeInter(etm.type) || isModeSplit(etm.type)) 
+    {
+      m_ComprCUCtxList.back().testModes.erase(m_ComprCUCtxList.back().testModes.begin() + j);
+      j--;
+      n--;
+    }
+  }  
+}
+
+// Note: ForceInterMode
+void forceInterMode()
+{    
+  int n = (int)m_ComprCUCtxList.back().testModes.size();
+  for (int j = 0; j < n; j++) 
+  {
+    const EncTestMode etm = m_ComprCUCtxList.back().testModes[j];
+    if (etm.type == ETM_INTRA) 
+    {
+      m_ComprCUCtxList.back().testModes.erase(m_ComprCUCtxList.back().testModes.begin() + j);
+      j--;
+      n--;        
+    }
+  }  
+}
+
+void removeHashInter()
+{
+  int n = (int)m_ComprCUCtxList.back().testModes.size();
+  for (int j = 0; j < n; j++) 
+  {
+    const EncTestMode etm = m_ComprCUCtxList.back().testModes[j];
+    if (etm.type == ETM_HASH_INTER) 
+    {
+      m_ComprCUCtxList.back().testModes.erase(m_ComprCUCtxList.back().testModes.begin() + j);
+      j--;
+      n--;
+    }
+  }
+}
+
+void removeMergeSkip()
+{
+  int n = (int)m_ComprCUCtxList.back().testModes.size();
+  for (int j = 0; j < n; j++) 
+  {
+    const EncTestMode etm = m_ComprCUCtxList.back().testModes[j];
+    if (etm.type == ETM_MERGE_SKIP) 
+    {
+      m_ComprCUCtxList.back().testModes.erase(m_ComprCUCtxList.back().testModes.begin() + j);
+      j--;
+      n--;
+    }
+  }
+}
+
+void removeInterME()
+{
+  int n = (int)m_ComprCUCtxList.back().testModes.size();
+  for (int j = 0; j < n; j++) 
+  {
+    const EncTestMode etm = m_ComprCUCtxList.back().testModes[j];
+    if (etm.type == ETM_INTER_ME) 
+    {
+      m_ComprCUCtxList.back().testModes.erase(m_ComprCUCtxList.back().testModes.begin() + j);
+      j--;
+      n--;
+    }
+  }
+}
+
+void removeAffine()
+{
+  int n = (int)m_ComprCUCtxList.back().testModes.size();
+  for (int j = 0; j < n; j++) 
+  {
+    const EncTestMode etm = m_ComprCUCtxList.back().testModes[j];
+    if (etm.type == ETM_AFFINE) 
+    {
+      m_ComprCUCtxList.back().testModes.erase(m_ComprCUCtxList.back().testModes.begin() + j);
+      j--;
+      n--;
+    }
+  }
+}
+
+void removeMergeGeo()
+{
+  int n = (int)m_ComprCUCtxList.back().testModes.size();
+  for (int j = 0; j < n; j++) 
+  {
+    const EncTestMode etm = m_ComprCUCtxList.back().testModes[j];
+    if (etm.type == ETM_MERGE_GEO) 
+    {
+      m_ComprCUCtxList.back().testModes.erase(m_ComprCUCtxList.back().testModes.begin() + j);
+      j--;
+      n--;
+    }
+  }
+}
+
+void removeIntra()
+{
+  int n = (int)m_ComprCUCtxList.back().testModes.size();
+  for (int j = 0; j < n; j++) 
+  {
+    const EncTestMode etm = m_ComprCUCtxList.back().testModes[j];
+    if (etm.type == ETM_INTRA) 
+    {
+      m_ComprCUCtxList.back().testModes.erase(m_ComprCUCtxList.back().testModes.begin() + j);
+      j--;
+      n--;
+    }
+  }
+}
+
+void removeBadMode()
+{  
+  int n = (int)m_ComprCUCtxList.back().testModes.size();
+  for (int j = 0; j < n; j++) 
+  {
+    const EncTestMode etm = m_ComprCUCtxList.back().testModes[j];
+
+    if (etm.type == ETM_INTER_ME && ((etm.opts & ETO_IMV) >> ETO_IMV_SHIFT) > 2) 
+    {  
+      m_ComprCUCtxList.back().testModes.erase(m_ComprCUCtxList.back().testModes.begin() + j);
+      j--;
+      n--;
+      break;
+    }
+  }  
+}
+
+bool anyPredModeLeft()
+{ 
+  int n = (int)m_ComprCUCtxList.back().testModes.size();
+  for (int j = 0; j < n; j++) 
+  {
+    const EncTestMode etm = m_ComprCUCtxList.back().testModes[j];
+
+    if (etm.type == ETM_HASH_INTER ||
+        etm.type == ETM_MERGE_SKIP || 
+        etm.type == ETM_INTER_ME   || 
+        etm.type == ETM_AFFINE     || 
+        etm.type == ETM_MERGE_GEO  || 
+        etm.type == ETM_INTRA      ||
+        etm.type == ETM_PALETTE    || 
+        etm.type == ETM_IBC        ||
+        etm.type == ETM_IBC_MERGE) {
+      return true;
+    }
+  }
+
+  return false;
+}
+
+bool anyIntraIBCMode()
+{
+  int n = (int)m_ComprCUCtxList.back().testModes.size();
+  for (int j = 0; j < n; j++) 
+  {
+    const EncTestMode etm = m_ComprCUCtxList.back().testModes[j];
+
+    if (etm.type == ETM_INTRA || etm.type == ETM_IBC) 
+    {
+      return true;
+    }
+  }
+
+  return false;
+}
+
+void forceRemoveDontSplit()
+{
+  int n = (int)m_ComprCUCtxList.back().testModes.size();
+  for (int j = 0; j < n; j++) 
+  {
+    const EncTestMode etm = m_ComprCUCtxList.back().testModes[j];
+
+    if (etm.type == ETM_POST_DONT_SPLIT) 
+    {
+      m_ComprCUCtxList.back().testModes.erase(m_ComprCUCtxList.back().testModes.begin() + j);
+      j--;
+      n--;
+    }
+  }
+}
+
+void forceVerSplitOnly()
+{
+  int n = (int)m_ComprCUCtxList.back().testModes.size();
+  for (int j = 0; j < n; j++) 
+  {
+    const EncTestMode etm = m_ComprCUCtxList.back().testModes[j];       
+ 
+    if (etm.type != ETM_SPLIT_QT && etm.type != ETM_SPLIT_BT_V && etm.type != ETM_SPLIT_TT_V) 
+    {
+      m_ComprCUCtxList.back().testModes.erase(m_ComprCUCtxList.back().testModes.begin() + j);
+      j--;
+      n--;
+    }
+  }   
+}
+
+void forceRemoveTTV()
+{
+  int n = (int)m_ComprCUCtxList.back().testModes.size();
+  for (int j = 0; j < n; j++) 
+  {
+    const EncTestMode etm = m_ComprCUCtxList.back().testModes[j];
+    
+    if (etm.type == ETM_SPLIT_TT_V) 
+    {
+      m_ComprCUCtxList.back().testModes.erase(m_ComprCUCtxList.back().testModes.begin() + j);
+      j--;
+      n--;
+    }
+  }
+}
+
+void forceRemoveBTV()
+{  
+  int n = (int)m_ComprCUCtxList.back().testModes.size();
+  for (int j = 0; j < n; j++) 
+  {
+    const EncTestMode etm = m_ComprCUCtxList.back().testModes[j];
+
+    if (etm.type == ETM_SPLIT_BT_V) 
+    {
+      m_ComprCUCtxList.back().testModes.erase(m_ComprCUCtxList.back().testModes.begin() + j);
+      j--;
+      n--;
+    }
+  }
+}
+
+void forceRemoveQT()
+{
+  int n = (int)m_ComprCUCtxList.back().testModes.size();
+  for (int j = 0; j < n; j++) 
+  {
+    const EncTestMode etm = m_ComprCUCtxList.back().testModes[j];
+ 
+    if (etm.type == ETM_SPLIT_QT) 
+    {
+      m_ComprCUCtxList.back().testModes.erase(m_ComprCUCtxList.back().testModes.begin() + j);
+      j--;
+      n--;
+    }
+  }  
+}
+
+void forceRemoveHT()
+{
+  int n = (int)m_ComprCUCtxList.back().testModes.size();
+  for (int j = 0; j < n; j++) 
+  {
+    const EncTestMode etm = m_ComprCUCtxList.back().testModes[j];
+
+    if (etm.type == ETM_SPLIT_BT_H || etm.type == ETM_SPLIT_TT_H) 
+    {
+      m_ComprCUCtxList.back().testModes.erase(m_ComprCUCtxList.back().testModes.begin() + j);
+      j--;
+      n--;
+    }
+  }
+}
+
+void forceRemoveQTHT()
+{
+  int n = (int)m_ComprCUCtxList.back().testModes.size();
+  for (int j = 0; j < n; j++) 
+  {
+    const EncTestMode etm = m_ComprCUCtxList.back().testModes[j];
+    
+    if (etm.type == ETM_SPLIT_QT || etm.type == ETM_SPLIT_BT_H || etm.type == ETM_SPLIT_TT_H) 
+    {
+      m_ComprCUCtxList.back().testModes.erase(m_ComprCUCtxList.back().testModes.begin() + j);
+      j--;
+      n--;
+    }
+  }
+}
+
+void forceRemoveAllSplit()
+{
+  int n = (int)m_ComprCUCtxList.back().testModes.size();
+  for (int j = 0; j < n; j++) 
+  {
+    const EncTestMode etm = m_ComprCUCtxList.back().testModes[j];
+
+    if (etm.type == ETM_SPLIT_QT || etm.type == ETM_SPLIT_BT_H || etm.type == ETM_SPLIT_BT_V || etm.type == ETM_SPLIT_TT_H || etm.type == ETM_SPLIT_TT_V) 
+    {
+      m_ComprCUCtxList.back().testModes.erase(m_ComprCUCtxList.back().testModes.begin() + j);
+      j--;
+      n--;
+    }
+  }
+}
+
+void forceQTonlyMode()
+{
+  // remove all split except QT  
+  int n = (int)m_ComprCUCtxList.back().testModes.size();
+  for (int j = 0; j < n; j++) 
+  {
+    const EncTestMode etm = m_ComprCUCtxList.back().testModes[j];
+
+    if (etm.type != ETM_SPLIT_QT) 
+    {
+      m_ComprCUCtxList.back().testModes.erase(m_ComprCUCtxList.back().testModes.begin() + j);
+      j--;
+      n--;        
+    }
+  }    
+}
+
+const char* printType(EncTestModeType type)
+{
+  char *ret;
+
+  switch (type) {
+  case  0: ret = strdup("Hash"); break;
+  case  1: ret = strdup("Mkip"); break;
+  case  2: ret = strdup("Inter"); break;
+  case  3: ret = strdup("Affi"); break;
+  case  4: ret = strdup("Tria"); break;
+  case  5: ret = strdup("Intra"); break;
+  case  6: ret = strdup("Palet"); break;
+
+  case  7: ret = strdup("QT"); break;
+  case  8: ret = strdup("BTH"); break;
+  case  9: ret = strdup("BTV"); break;
+  case 10: ret = strdup("TTH"); break;
+  case 11: ret = strdup("TTV"); break;
+  case 12: ret = strdup("|"); break;
+  case 13: ret = strdup("CACHE"); break;
+  case 14: ret = strdup("IMV"); break;
+  case 15: ret = strdup("IBC"); break;
+  case 16: ret = strdup("IBCM"); break;
+  default:
+    ret = strdup("INVALID");
+  }
+
+  return ret;
+}
+
+void printMode()
+{
+  // remove all inter or split to force make intra          
+  int n = (int)m_ComprCUCtxList.back().testModes.size();
+  printf("-:[");
+  for (int j = 0; j < n; j++) 
+  {
+    const EncTestMode etm = m_ComprCUCtxList.back().testModes[j];      
+    printf(" %s", printType(etm.type));      
+  }
+  printf("]\n");   
+}
+#endif
+
 protected:
   void xExtractFeatures ( const EncTestMode encTestmode, CodingStructure& cs );
   void xGetMinMaxQP     ( int& iMinQP, int& iMaxQP, const CodingStructure& cs, const Partitioner &pm, const int baseQP, const SPS& sps, const PPS& pps, const PartSplit splitMode );
@@ -395,13 +770,7 @@ struct SaveLoadStructSbt
 class SaveLoadEncInfoSbt
 {
 protected:
-#if ENABLE_SPLIT_PARALLELISM
-public:
-#endif
   void init( const Slice &slice );
-#if ENABLE_SPLIT_PARALLELISM
-protected:
-#endif
   void create();
   void destroy();
 
@@ -414,9 +783,6 @@ public:
   void     resetSaveloadSbt( int maxSbtSize );
   uint16_t findBestSbt( const UnitArea& area, const uint32_t curPuSse );
   bool     saveBestSbt( const UnitArea& area, const uint32_t curPuSse, const uint8_t curPuSbt, const uint8_t curPuTrs );
-#if ENABLE_SPLIT_PARALLELISM
-  void     copyState(const SaveLoadEncInfoSbt& other);
-#endif
 };
 
 static const int MAX_STORED_CU_INFO_REFS = 4;
@@ -439,12 +805,6 @@ struct CodedCUInfo
   double   bestNonDCT2Cost;
   bool     relatedCuIsValid;
   uint8_t  bestISPIntraMode;
-
-#if ENABLE_SPLIT_PARALLELISM
-
-  uint64_t
-       temporalId;
-#endif
 };
 
 class CacheBlkInfoCtrl
@@ -460,21 +820,7 @@ protected:
 
   void create   ();
   void destroy  ();
-#if ENABLE_SPLIT_PARALLELISM
-public:
-#endif
   void init     ( const Slice &slice );
-#if ENABLE_SPLIT_PARALLELISM
-private:
-  uint64_t
-       m_currTemporalId;
-public:
-  void tick     () { m_currTemporalId++; CHECK( m_currTemporalId <= 0, "Problem with integer overflow!" ); }
-  // mark the state of the blk as changed within the current temporal id
-  void copyState( const CacheBlkInfoCtrl &other, const UnitArea& area );
-protected:
-  void touch    ( const UnitArea& area );
-#endif
 
   CodedCUInfo& getBlkInfo( const UnitArea& area );
 
@@ -508,10 +854,6 @@ struct BestEncodingInfo
   EncTestMode    testMode;
 
   int            poc;
-
-#if ENABLE_SPLIT_PARALLELISM
-  int64_t        temporalId;
-#endif
 };
 
 class BestEncInfoCache
@@ -526,9 +868,6 @@ private:
   bool               *m_runType;
   CodingStructure     m_dummyCS;
   XUCache             m_dummyCache;
-#if ENABLE_SPLIT_PARALLELISM
-  int64_t m_currTemporalId;
-#endif
 
 protected:
 
@@ -537,19 +876,10 @@ protected:
 
   bool setFromCs( const CodingStructure& cs, const Partitioner& partitioner );
   bool isValid  ( const CodingStructure &cs, const Partitioner &partitioner, int qp );
-
-#if ENABLE_SPLIT_PARALLELISM
-  void touch    ( const UnitArea& area );
-#endif
 public:
 
   BestEncInfoCache() : m_slice_bencinf( nullptr ), m_dummyCS( m_dummyCache.cuCache, m_dummyCache.puCache, m_dummyCache.tuCache ) {}
   virtual ~BestEncInfoCache() {}
-
-#if ENABLE_SPLIT_PARALLELISM
-  void     copyState( const BestEncInfoCache &other, const UnitArea &area );
-  void     tick     () { m_currTemporalId++; CHECK( m_currTemporalId <= 0, "Problem with integer overflow!" ); }
-#endif
   void     init     ( const Slice &slice );
   bool     setCsFrom( CodingStructure& cs, EncTestMode& testMode, const Partitioner& partitioner ) const;
 };
@@ -590,6 +920,9 @@ class EncModeCtrlMTnoRQT : public EncModeCtrl, public CacheBlkInfoCtrl
   };
 
   unsigned m_skipThreshold;
+#if GDR_ENABLED
+  EncCfg m_encCfg;
+#endif
 
 public:
 
@@ -602,13 +935,6 @@ public:
   virtual bool tryMode            ( const EncTestMode& encTestmode, const CodingStructure &cs, Partitioner& partitioner );
   virtual bool useModeResult      ( const EncTestMode& encTestmode, CodingStructure*& tempCS,  Partitioner& partitioner );
 
-#if ENABLE_SPLIT_PARALLELISM
-  virtual void copyState          ( const EncModeCtrl& other, const UnitArea& area );
-
-  virtual int  getNumParallelJobs ( const CodingStructure &cs, Partitioner& partitioner ) const;
-  virtual bool isParallelSplit    ( const CodingStructure &cs, Partitioner& partitioner ) const;
-  virtual bool parallelJobSelector( const EncTestMode& encTestmode, const CodingStructure &cs, Partitioner& partitioner ) const;
-#endif
   virtual bool checkSkipOtherLfnst( const EncTestMode& encTestmode, CodingStructure*& tempCS, Partitioner& partitioner );
 };
 
diff --git a/source/Lib/EncoderLib/EncReshape.cpp b/source/Lib/EncoderLib/EncReshape.cpp
index 0d4731548..1120b4e20 100644
--- a/source/Lib/EncoderLib/EncReshape.cpp
+++ b/source/Lib/EncoderLib/EncReshape.cpp
@@ -3,7 +3,7 @@
 * and contributor rights, including patent rights, and no such rights are
 * granted under this license.
 *
-* Copyright (c) 2010-2020, ITU/ISO/IEC
+* Copyright (c) 2010-2021, ITU/ISO/IEC
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
@@ -228,11 +228,7 @@ void EncReshape::calcSeqStats(Picture *pcPic, SeqInfo &stats)
         {
           for (bx = x1; bx <= x2; bx++)
           {
-#if JVET_T0091_LMCS_ENC_OVERFLOW_FIX
             tempSq = (int64_t)pWinY[bx] * (int64_t)pWinY[bx];
-#else
-            tempSq = pWinY[bx] * pWinY[bx];
-#endif
             leftSum += pWinY[bx];
             leftSumSq += tempSq;
             leftColSum[bx] += pWinY[bx];
@@ -259,11 +255,7 @@ void EncReshape::calcSeqStats(Picture *pcPic, SeqInfo &stats)
           for (bx = x1; bx <= x2; bx++)
           {
             topRowSum[y + winLens] += pWinY[bx];
-#if JVET_T0091_LMCS_ENC_OVERFLOW_FIX
             topRowSumSq[y + winLens] += (int64_t)pWinY[bx] * (int64_t)pWinY[bx];
-#else
-            topRowSumSq[y + winLens] += pWinY[bx] * pWinY[bx];
-#endif
           }
           topSum += topRowSum[y + winLens];
           topSumSq += topRowSumSq[y + winLens];
@@ -282,11 +274,7 @@ void EncReshape::calcSeqStats(Picture *pcPic, SeqInfo &stats)
           for (bx = x1; bx <= x2; bx++)
           {
             leftColSum[bx] += pWinY[bx];
-#if JVET_T0091_LMCS_ENC_OVERFLOW_FIX
             leftColSumSq[bx] += (int64_t)pWinY[bx] * (int64_t)pWinY[bx];
-#else
-            leftColSumSq[bx] += pWinY[bx] * pWinY[bx];
-#endif
           }
           pWinY += stride;
         }
@@ -307,11 +295,7 @@ void EncReshape::calcSeqStats(Picture *pcPic, SeqInfo &stats)
             for (by = y1; by <= y2; by++)
             {
               leftColSum[x + winLens] += pWinY[x + winLens];
-#if JVET_T0091_LMCS_ENC_OVERFLOW_FIX
               leftColSumSq[x + winLens] += (int64_t)pWinY[x + winLens] * (int64_t)pWinY[x + winLens];
-#else
-              leftColSumSq[x + winLens] += pWinY[x + winLens] * pWinY[x + winLens];
-#endif
               pWinY += stride;
             }
           }
@@ -324,22 +308,14 @@ void EncReshape::calcSeqStats(Picture *pcPic, SeqInfo &stats)
               pWinY = &picY.buf[0];
               pWinY += winLens * stride;
               leftColSum[x + winLens] += pWinY[x + winLens];
-#if JVET_T0091_LMCS_ENC_OVERFLOW_FIX
               leftColSumSq[x + winLens] += (int64_t)pWinY[x + winLens] * (int64_t)pWinY[x + winLens];
-#else
-              leftColSumSq[x + winLens] += pWinY[x + winLens] * pWinY[x + winLens];
-#endif
             }
             if (y > winLens)
             {
               pWinY = &picY.buf[0];
               pWinY -= (winLens + 1) * stride;
               leftColSum[x + winLens] -= pWinY[x + winLens];
-#if JVET_T0091_LMCS_ENC_OVERFLOW_FIX
               leftColSumSq[x + winLens] -= (int64_t)pWinY[x + winLens] * (int64_t)pWinY[x + winLens];
-#else
-              leftColSumSq[x + winLens] -= pWinY[x + winLens] * pWinY[x + winLens];
-#endif
             }
           }
           topColSum[x + winLens] = leftColSum[x + winLens];
@@ -423,11 +399,7 @@ void EncReshape::calcSeqStats(Picture *pcPic, SeqInfo &stats)
     for (int x = 0; x < width; x++)
     {
       avgY += picY.buf[x];
-#if JVET_T0091_LMCS_ENC_OVERFLOW_FIX
       varY += (double)picY.buf[x] * (double)picY.buf[x];
-#else
-      varY += picY.buf[x] * picY.buf[x];
-#endif
     }
     picY.buf += stride;
   }
@@ -449,13 +421,8 @@ void EncReshape::calcSeqStats(Picture *pcPic, SeqInfo &stats)
       {
         avgU += picU.buf[x];
         avgV += picV.buf[x];
-#if JVET_T0091_LMCS_ENC_OVERFLOW_FIX
         varU += (int64_t)picU.buf[x] * (int64_t)picU.buf[x];
         varV += (int64_t)picV.buf[x] * (int64_t)picV.buf[x];
-#else
-        varU += picU.buf[x] * picU.buf[x];
-        varV += picV.buf[x] * picV.buf[x];
-#endif
       }
       picU.buf += strideC;
       picV.buf += strideC;
@@ -477,6 +444,9 @@ void EncReshape::preAnalyzerLMCS(Picture *pcPic, const uint32_t signalType, cons
   m_sliceReshapeInfo.sliceReshaperModelPresentFlag = true;
   m_sliceReshapeInfo.sliceReshaperEnableFlag = true;
   int modIP = pcPic->getPOC() - pcPic->getPOC() / reshapeCW.rspFpsToIp * reshapeCW.rspFpsToIp;
+#if GDR_ENABLED
+  if (pcPic->cs->slice->isInterGDR()) modIP = 0;
+#endif
   if (sliceType == I_SLICE || (reshapeCW.updateCtrl == 2 && modIP == 0))
   {
     if (m_sliceReshapeInfo.sliceReshaperModelPresentFlag == true)
@@ -711,6 +681,96 @@ void EncReshape::preAnalyzerLMCS(Picture *pcPic, const uint32_t signalType, cons
       const int cTid = m_reshapeCW.rspTid;
       bool enableRsp = m_tcase == 5 ? false : (m_tcase < 5 ? (cTid < m_tcase + 1 ? false : true) : (cTid <= 10 - m_tcase ? true : false));
       m_sliceReshapeInfo.sliceReshaperEnableFlag = enableRsp;
+
+      if (m_sliceReshapeInfo.sliceReshaperEnableFlag)
+      {
+        m_binNum = PIC_CODE_CW_BINS;
+        PelBuf picY = pcPic->getOrigBuf(COMPONENT_Y);
+        const int width = picY.width;
+        const int height = picY.height;
+        const int stride = picY.stride;
+        uint32_t binCnt[PIC_CODE_CW_BINS];
+        std::fill_n(binCnt, m_binNum, 0);
+
+        initSeqStats(m_srcSeqStats);
+        for (uint32_t y = 0; y < height; y++)
+        {
+          for (uint32_t x = 0; x < width; x++)
+          {
+            const Pel pxlY = picY.buf[x];
+            int binLen = m_reshapeLUTSize / m_binNum;
+            uint32_t binIdx = (uint32_t)(pxlY / binLen);
+            binCnt[binIdx]++;
+          }
+          picY.buf += stride;
+        }
+
+        for (int b = 0; b < m_binNum; b++)
+        {
+          m_srcSeqStats.binHist[b] = (double)binCnt[b] / (double)(m_reshapeCW.rspPicSize);
+        }
+
+        double avgY = 0.0;
+        double varY = 0.0;
+        picY = pcPic->getOrigBuf(COMPONENT_Y);
+        for (int y = 0; y < height; y++)
+        {
+          for (int x = 0; x < width; x++)
+          {
+            avgY += picY.buf[x];
+            varY += (double)picY.buf[x] * (double)picY.buf[x];
+          }
+          picY.buf += stride;
+        }
+        avgY = avgY / (width * height);
+        varY = varY / (width * height) - avgY * avgY;
+
+        if (isChromaEnabled(pcPic->chromaFormat))
+        {
+          PelBuf picU = pcPic->getOrigBuf(COMPONENT_Cb);
+          PelBuf picV = pcPic->getOrigBuf(COMPONENT_Cr);
+          const int widthC = picU.width;
+          const int heightC = picU.height;
+          const int strideC = picU.stride;
+          double avgU = 0.0, avgV = 0.0;
+          double varU = 0.0, varV = 0.0;
+          for (int y = 0; y < heightC; y++)
+          {
+            for (int x = 0; x < widthC; x++)
+            {
+              avgU += picU.buf[x];
+              avgV += picV.buf[x];
+              varU += (int64_t)picU.buf[x] * (int64_t)picU.buf[x];
+              varV += (int64_t)picV.buf[x] * (int64_t)picV.buf[x];
+            }
+            picU.buf += strideC;
+            picV.buf += strideC;
+          }
+          avgU = avgU / (widthC * heightC);
+          avgV = avgV / (widthC * heightC);
+          varU = varU / (widthC * heightC) - avgU * avgU;
+          varV = varV / (widthC * heightC) - avgV * avgV;
+          if (varY > 0)
+          {
+            m_srcSeqStats.ratioStdU = sqrt(varU) / sqrt(varY);
+            m_srcSeqStats.ratioStdV = sqrt(varV) / sqrt(varY);
+          }
+        }
+
+        if (m_srcSeqStats.binHist[m_binNum - 1] > 0.0003)
+        {
+          m_sliceReshapeInfo.sliceReshaperEnableFlag = false;
+        }
+        if (m_srcSeqStats.binHist[0] > 0.03)
+        {
+          m_sliceReshapeInfo.sliceReshaperEnableFlag = false;
+        }
+
+        if ((m_srcSeqStats.ratioStdU + m_srcSeqStats.ratioStdV) > 1.5 && m_srcSeqStats.binHist[1] > 0.5)
+        {
+          m_sliceReshapeInfo.sliceReshaperEnableFlag = false;
+        }
+      }
     }
   }
 }
@@ -1244,6 +1304,8 @@ void EncReshape::initLUTfromdQPModel()
     }
     else
     {
+      CHECK((m_binCW[i] + m_sliceReshapeInfo.chrResScalingOffset) < (m_initCW >> 3) || (m_binCW[i] + m_sliceReshapeInfo.chrResScalingOffset) > ((m_initCW << 3) - 1),
+        "It is a requirement of bitstream conformance that, when lmcsCW[ i ] is not equal to 0, ( lmcsCW[ i ] + lmcsDeltaCrs ) shall be in the range of ( OrgCW >> 3 ) to ( ( OrgCW << 3 ) - 1 ), inclusive.");
       m_invScaleCoef[i] = (int32_t)(m_initCW * (1 << FP_PREC) / m_binCW[i]);
       m_chromaAdjHelpLUT[i] = (int32_t)(m_initCW * (1 << FP_PREC) / (m_binCW[i] + m_sliceReshapeInfo.chrResScalingOffset));
     }
@@ -1339,6 +1401,8 @@ void EncReshape::constructReshaperLMCS()
     }
     else
     {
+      CHECK((m_binCW[i] + m_sliceReshapeInfo.chrResScalingOffset) < (m_initCW >> 3) || (m_binCW[i] + m_sliceReshapeInfo.chrResScalingOffset) > ((m_initCW << 3) - 1),
+        "It is a requirement of bitstream conformance that, when lmcsCW[ i ] is not equal to 0, ( lmcsCW[ i ] + lmcsDeltaCrs ) shall be in the range of ( OrgCW >> 3 ) to ( ( OrgCW << 3 ) - 1 ), inclusive.");
       m_invScaleCoef[i] = (int32_t)(m_initCW * (1 << FP_PREC) / m_binCW[i]);
       m_chromaAdjHelpLUT[i] = (int32_t)(m_initCW * (1 << FP_PREC) / (m_binCW[i] + m_sliceReshapeInfo.chrResScalingOffset));
     }
@@ -1429,45 +1493,5 @@ void EncReshape::adjustLmcsPivot()
     }
   }
 }
-
-#if ENABLE_SPLIT_PARALLELISM
-void EncReshape::copyState(const EncReshape &other)
-{
-  m_srcReshaped     = other.m_srcReshaped;
-  m_picWidth        = other.m_picWidth;
-  m_picHeight       = other.m_picHeight;
-  m_maxCUWidth      = other.m_maxCUWidth;
-  m_maxCUHeight     = other.m_maxCUHeight;
-  m_widthInCtus     = other.m_widthInCtus;
-  m_heightInCtus    = other.m_heightInCtus;
-  m_numCtuInFrame   = other.m_numCtuInFrame;
-  m_exceedSTD       = other.m_exceedSTD;
-  m_binImportance   = other.m_binImportance;
-  m_tcase           = other.m_tcase;
-  m_rateAdpMode     = other.m_rateAdpMode;
-  m_useAdpCW        = other.m_useAdpCW;
-  m_initCWAnalyze   = other.m_initCWAnalyze;
-  m_reshapeCW       = other.m_reshapeCW;
-  memcpy( m_cwLumaWeight, other.m_cwLumaWeight, sizeof( m_cwLumaWeight ) );
-  m_chromaWeight    = other.m_chromaWeight;
-  m_chromaAdj       = other.m_chromaAdj;
-
-  m_sliceReshapeInfo = other.m_sliceReshapeInfo;
-  m_CTUFlag          = other.m_CTUFlag;
-  m_recReshaped      = other.m_recReshaped;
-  m_invLUT           = other.m_invLUT;
-  m_fwdLUT           = other.m_fwdLUT;
-  m_chromaAdjHelpLUT = other.m_chromaAdjHelpLUT;
-  m_binCW            = other.m_binCW;
-  m_initCW           = other.m_initCW;
-  m_reshape          = other.m_reshape;
-  m_reshapePivot     = other.m_reshapePivot;
-  m_inputPivot       = other.m_inputPivot;
-  m_fwdScaleCoef     = other.m_fwdScaleCoef;
-  m_invScaleCoef     = other.m_invScaleCoef;
-  m_lumaBD           = other.m_lumaBD;
-  m_reshapeLUTSize   = other.m_reshapeLUTSize;
-}
-#endif
 //
 //! \}
diff --git a/source/Lib/EncoderLib/EncReshape.h b/source/Lib/EncoderLib/EncReshape.h
index ba9b51950..72efd26fe 100644
--- a/source/Lib/EncoderLib/EncReshape.h
+++ b/source/Lib/EncoderLib/EncReshape.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -115,10 +115,6 @@ public:
   Pel * getWeightTable() { return m_cwLumaWeight; }
   double getCWeight() { return m_chromaWeight; }
   void adjustLmcsPivot();
-
-#if ENABLE_SPLIT_PARALLELISM
-  void copyState(const EncReshape& other);
-#endif
 };// END CLASS DEFINITION EncReshape
 
 //! \}
diff --git a/source/Lib/EncoderLib/EncSampleAdaptiveOffset.cpp b/source/Lib/EncoderLib/EncSampleAdaptiveOffset.cpp
index 90583a5a4..1c0188652 100644
--- a/source/Lib/EncoderLib/EncSampleAdaptiveOffset.cpp
+++ b/source/Lib/EncoderLib/EncSampleAdaptiveOffset.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -211,9 +211,9 @@ void EncSampleAdaptiveOffset::SAOProcess( CodingStructure& cs, bool* sliceEnable
 #if ENABLE_QPA
                                           const double lambdaChromaWeight,
 #endif
-                                          const bool bTestSAODisableAtPictureLevel, const double saoEncodingRate, const double saoEncodingRateChroma, const bool isPreDBFSamplesUsed, bool isGreedyMergeEncoding )
+                                          const bool bTestSAODisableAtPictureLevel, const double saoEncodingRate, const double saoEncodingRateChroma, const bool isPreDBFSamplesUsed, bool isGreedyMergeEncoding, bool usingTrueOrg )
 {
-  PelUnitBuf org = cs.getOrgBuf();
+  PelUnitBuf org = usingTrueOrg ? cs.getTrueOrgBuf() : cs.getOrgBuf();
   PelUnitBuf res = cs.getRecoBuf();
   PelUnitBuf src = m_tempBuf;
   memcpy(m_lambda, lambdas, sizeof(m_lambda));
@@ -248,10 +248,9 @@ void EncSampleAdaptiveOffset::SAOProcess( CodingStructure& cs, bool* sliceEnable
 
 }
 
-
-void EncSampleAdaptiveOffset::getPreDBFStatistics(CodingStructure& cs)
+void EncSampleAdaptiveOffset::getPreDBFStatistics( CodingStructure& cs, bool usingTrueOrg )
 {
-  PelUnitBuf org = cs.getOrgBuf();
+  PelUnitBuf org = usingTrueOrg ? cs.getTrueOrgBuf() : cs.getOrgBuf();
   PelUnitBuf rec = cs.getRecoBuf();
   getStatistics(m_preDBFstatData, org, rec, cs, true);
 }
@@ -825,7 +824,7 @@ void EncSampleAdaptiveOffset::decideBlkParams(CodingStructure& cs, bool* sliceEn
 
   int     mergeCtuAddr = 1; //Ctu to be merged
   int     groupSize = 1;
-  double  Cost[2] = { 0, 0 };
+  double  cost[2]      = { 0, 0 };
   TempCtx ctxBeforeMerge(m_CtxCache);
   TempCtx ctxAfterMerge(m_CtxCache);
 
@@ -920,13 +919,13 @@ void EncSampleAdaptiveOffset::decideBlkParams(CodingStructure& cs, bool* sliceEn
       {
         if (ctuRsAddr == (mergeCtuAddr - 1))
         {
-          Cost[0] = minCost;  //previous
+          cost[0]   = minCost;   // previous
           groupSize = 1;
           getMergeList(cs, ctuRsAddr, reconParams, startingMergeList);
         }
         else if (ctuRsAddr == mergeCtuAddr)
         {
-          Cost[1] = minCost;
+          cost[1]  = minCost;
           minCost2 = MAX_DOUBLE;
           for (int tmp = groupSize; tmp >= 0; tmp--)
           {
@@ -980,13 +979,13 @@ void EncSampleAdaptiveOffset::decideBlkParams(CodingStructure& cs, bool* sliceEn
             ctxAfterMerge = SAOCtx(m_CABACEstimator->getCtx());
           }
 
-          totalCost += Cost[0];
-          totalCost += Cost[1];
+          totalCost += cost[0];
+          totalCost += cost[1];
 
-          if ((Cost[0] + Cost[1]) > minCost2) //merge current CTU
+          if ((cost[0] + cost[1]) > minCost2)   // merge current CTU
           {
             //original merge all
-            totalCost = totalCost - Cost[0] - Cost[1] + minCost2;
+            totalCost                          = totalCost - cost[0] - cost[1] + minCost2;
             codedParams[ctuRsAddr - groupSize] = groupParam;
             for (int compIdx = 0; compIdx < MAX_NUM_COMPONENT; compIdx++)
             {
@@ -1007,7 +1006,7 @@ void EncSampleAdaptiveOffset::decideBlkParams(CodingStructure& cs, bool* sliceEn
             }
             else //next CTU can be merged with current group
             {
-              Cost[0] = minCost2;
+              cost[0] = minCost2;
               groupSize += 1;
             }
             m_CABACEstimator->getCtx() = SAOCtx(ctxAfterMerge);
@@ -1016,7 +1015,7 @@ void EncSampleAdaptiveOffset::decideBlkParams(CodingStructure& cs, bool* sliceEn
           {
             mergeCtuAddr += 1;
             // Current block will be the starting block for successive operations
-            Cost[0] = Cost[1];
+            cost[0] = cost[1];
             getMergeList(cs, ctuRsAddr, reconParams, startingMergeList);
             groupSize = 1;
             m_CABACEstimator->getCtx() = SAOCtx(ctxStart);
@@ -1026,7 +1025,7 @@ void EncSampleAdaptiveOffset::decideBlkParams(CodingStructure& cs, bool* sliceEn
             {
               mergeCtuAddr += 1;
             }
-          } //else, if(Cost[0] + Cost[1] > minCost2)
+          }   // else, if(cost[0] + cost[1] > minCost2)
         }//else if (ctuRsAddr == mergeCtuAddr)
       }
       else
@@ -1083,6 +1082,8 @@ void EncSampleAdaptiveOffset::decideBlkParams(CodingStructure& cs, bool* sliceEn
       sliceEnabled[componentIndex] = false;
     }
     m_CABACEstimator->getCtx() = SAOCtx(ctxPicStart);
+
+    resYuv.copyFrom(srcYuv);
   }
 
   EncSampleAdaptiveOffset::disabledRate( cs, reconParams, saoEncodingRate, saoEncodingRateChroma );
diff --git a/source/Lib/EncoderLib/EncSampleAdaptiveOffset.h b/source/Lib/EncoderLib/EncSampleAdaptiveOffset.h
index 8a0530ec7..0627649a9 100644
--- a/source/Lib/EncoderLib/EncSampleAdaptiveOffset.h
+++ b/source/Lib/EncoderLib/EncSampleAdaptiveOffset.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -93,10 +93,10 @@ public:
 #if ENABLE_QPA
                    const double lambdaChromaWeight,
 #endif
-                   const bool bTestSAODisableAtPictureLevel, const double saoEncodingRate, const double saoEncodingRateChroma, const bool isPreDBFSamplesUsed, bool isGreedyMergeEncoding );
+                   const bool bTestSAODisableAtPictureLevel, const double saoEncodingRate, const double saoEncodingRateChroma, const bool isPreDBFSamplesUsed, bool isGreedyMergeEncoding, bool usingTrueOrg );
 
   void disabledRate( CodingStructure& cs, SAOBlkParam* reconParams, const double saoEncodingRate, const double saoEncodingRateChroma );
-  void getPreDBFStatistics(CodingStructure& cs);
+  void getPreDBFStatistics( CodingStructure& cs, bool usingTrueOrg );
 private: //methods
 
   void deriveLoopFilterBoundaryAvailibility(CodingStructure& cs, const Position &pos, bool& isLeftAvail, bool& isAboveAvail, bool& isAboveLeftAvail) const;
diff --git a/source/Lib/EncoderLib/EncSlice.cpp b/source/Lib/EncoderLib/EncSlice.cpp
index 5ac56442f..7aeb6ba3d 100644
--- a/source/Lib/EncoderLib/EncSlice.cpp
+++ b/source/Lib/EncoderLib/EncSlice.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -175,7 +175,10 @@ static void filterAndCalculateAverageEnergies (const Pel* pSrc, const int  iSrcS
   hpEner = double(saAct) / double((iWidth - 2) * (iHeight - 2));
 
   // lower limit, compensate for highpass amplification
-  if (hpEner < double(1 << (uBitDepth - 4))) hpEner = double(1 << (uBitDepth - 4));
+  if (hpEner < double(1 << (uBitDepth - 4)))
+  {
+    hpEner = double(1 << (uBitDepth - 4));
+  }
 }
 
 #ifndef GLOBAL_AVERAGING
@@ -229,13 +232,19 @@ static int getGlaringColorQPOffset (Picture* const pcPic, const int ctuAddr, Sli
     }
     else avgCompValue = pcPic->getOrigBuf (pcPic->block (compID)).computeAvg();
 
-    if (chrValue > avgCompValue) chrValue = avgCompValue; // minimum of the DC offsets
+    if (chrValue > avgCompValue)
+    {
+      chrValue = avgCompValue;   // minimum of the DC offsets
+    }
   }
   CHECK (chrValue < 0, "DC offset cannot be negative!");
 
   chrValue = (int)avgLumaValue - chrValue;
 
-  if (chrValue > midLevel) return apprI3Log2 (double (chrValue * chrValue) / double (midLevel * midLevel));
+  if (chrValue > midLevel)
+  {
+    return apprI3Log2(double(chrValue * chrValue) / double(midLevel * midLevel));
+  }
 
   return 0;
 }
@@ -279,7 +288,10 @@ static int applyQPAdaptationChroma (Picture* const pcPic, Slice* const pcSlice,
         // change mean picture QP index based on picture's average luma value (Sharp)
         if (pcEncCfg->getLumaLevelToDeltaQPMapping().mode == LUMALVL_TO_DQP_NUM_MODES)
         {
-          if (meanLuma == MAX_UINT) meanLuma = pcPic->getOrigBuf().Y().computeAvg();
+          if (meanLuma == MAX_UINT)
+          {
+            meanLuma = pcPic->getOrigBuf().Y().computeAvg();
+          }
 
           averageAdaptedLumaQP = Clip3 (0, MAX_QP, averageAdaptedLumaQP + lumaDQPOffset (meanLuma, bitDepth));
         }
@@ -316,7 +328,7 @@ static int applyQPAdaptationChroma (Picture* const pcPic, Slice* const pcSlice,
  \param isField       true for field coding
  */
 void EncSlice::initEncSlice(Picture* pcPic, const int pocLast, const int pocCurr, const int iGOPid, Slice*& rpcSlice, const bool isField,
-                            bool isEncodeLtRef, int layerId)
+                            bool isEncodeLtRef, int layerId, NalUnitType nalType)
 {
   double dQP;
   double dLambda;
@@ -347,7 +359,7 @@ void EncSlice::initEncSlice(Picture* pcPic, const int pocLast, const int pocCurr
     rpcSlice->setSignDataHidingEnabledFlag( m_pcCfg->getSignDataHidingEnabledFlag() );
     rpcSlice->setTSResidualCodingDisabledFlag( false );
 
-    CHECK( (m_pcCfg->getDepQuantEnabledFlag() || m_pcCfg->getSignDataHidingEnabledFlag() ) 
+    CHECK( (m_pcCfg->getDepQuantEnabledFlag() || m_pcCfg->getSignDataHidingEnabledFlag() )
            && rpcSlice->getTSResidualCodingDisabledFlag() , "TSRC cannot be bypassed if either DQ or SDH are enabled at slice level.");
   }
   else
@@ -422,10 +434,22 @@ void EncSlice::initEncSlice(Picture* pcPic, const int pocLast, const int pocCurr
       if(m_pcCfg->getDecodingRefreshType() == 3)
       {
         eSliceType = (pocLast == 0 || pocCurr % (m_pcCfg->getIntraPeriod() * multipleFactor) == 0 || m_pcGOPEncoder->getGOPSize() == 0) && (!useIlRef) ? I_SLICE : eSliceType;
+#if GDR_ENABLED
+        if (m_pcCfg->getGdrEnabled() && (pocCurr >= m_pcCfg->getGdrPocStart()) && ((pocCurr - m_pcCfg->getGdrPocStart()) % m_pcCfg->getGdrPeriod() == 0))
+        {
+          eSliceType = B_SLICE;
+        }
+#endif
       }
       else
       {
         eSliceType = (pocLast == 0 || (pocCurr - (isField ? 1 : 0)) % (m_pcCfg->getIntraPeriod() * multipleFactor) == 0 || m_pcGOPEncoder->getGOPSize() == 0) && (!useIlRef) ? I_SLICE : eSliceType;
+#if GDR_ENABLED
+        if (m_pcCfg->getGdrEnabled() && (pocCurr >= m_pcCfg->getGdrPocStart()) && ((pocCurr - m_pcCfg->getGdrPocStart()) % m_pcCfg->getGdrPeriod() == 0))
+        {
+          eSliceType = B_SLICE;
+        }
+#endif
       }
     }
   }
@@ -448,14 +472,13 @@ void EncSlice::initEncSlice(Picture* pcPic, const int pocLast, const int pocCurr
   // ------------------------------------------------------------------------------------------------------------------
 
 #if X0038_LAMBDA_FROM_QP_CAPABILITY
+  rpcSlice->setNalUnitType(nalType);
   dQP = m_pcCfg->getQPForPicture(iGOPid, rpcSlice);
 #else
   dQP = m_pcCfg->getBaseQP();
   if(eSliceType!=I_SLICE)
   {
-    {
-      dQP += m_pcCfg->getGOPEntry(iGOPid).m_QPOffset;
-    }
+    dQP += m_pcCfg->getGOPEntry(iGOPid).m_QPOffset;
   }
 
   // modify QP
@@ -589,10 +612,22 @@ void EncSlice::initEncSlice(Picture* pcPic, const int pocLast, const int pocCurr
         if(m_pcCfg->getDecodingRefreshType() == 3)
         {
           eSliceType = (pocLast == 0 || pocCurr % (m_pcCfg->getIntraPeriod() * multipleFactor) == 0 || m_pcGOPEncoder->getGOPSize() == 0) && (!useIlRef) ? I_SLICE : eSliceType;
+#if GDR_ENABLED
+          if (m_pcCfg->getGdrEnabled() && (pocCurr >= m_pcCfg->getGdrPocStart()) && ((pocCurr - m_pcCfg->getGdrPocStart()) % m_pcCfg->getGdrPeriod() == 0))
+          {
+            eSliceType = B_SLICE;
+          }
+#endif
         }
         else
         {
           eSliceType = (pocLast == 0 || (pocCurr - (isField ? 1 : 0)) % (m_pcCfg->getIntraPeriod() * multipleFactor) == 0 || m_pcGOPEncoder->getGOPSize() == 0) && (!useIlRef) ? I_SLICE : eSliceType;
+#if GDR_ENABLED
+          if (m_pcCfg->getGdrEnabled() && (pocCurr >= m_pcCfg->getGdrPocStart()) && ((pocCurr - m_pcCfg->getGdrPocStart()) % m_pcCfg->getGdrPeriod() == 0))
+          {
+            eSliceType = B_SLICE;
+          }
+#endif
         }
       }
     }
@@ -613,12 +648,16 @@ void EncSlice::initEncSlice(Picture* pcPic, const int pocLast, const int pocCurr
   rpcSlice->setSliceQp           ( iQP );
   rpcSlice->setSliceQpDelta      ( 0 );
   pcPic->setLossyQPValue(iQP);
+  if ((!rpcSlice->getTSResidualCodingDisabledFlag()) && ( rpcSlice->getSPS()->getSpsRangeExtension().getTSRCRicePresentFlag() ))
+  {
+    rpcSlice->set_tsrc_index(Clip3(MIN_TSRC_RICE, MAX_TSRC_RICE, (int) ((19 - iQP) / 6)) - 1);
+  }
 #if !W0038_CQP_ADJ
   rpcSlice->setSliceChromaQpDelta( COMPONENT_Cb, 0 );
   rpcSlice->setSliceChromaQpDelta( COMPONENT_Cr, 0 );
   rpcSlice->setSliceChromaQpDelta( JOINT_CbCr,   0 );
 #endif
-  rpcSlice->setUseChromaQpAdj( rpcSlice->getPPS()->getCuChromaQpOffsetListEnabledFlag() );
+  rpcSlice->setUseChromaQpAdj( rpcSlice->getPPS()->getCuChromaQpOffsetListEnabledFlag() && m_pcCfg->getCuChromaQpOffsetEnabled() );
   rpcSlice->setNumRefIdx(REF_PIC_LIST_0, m_pcCfg->getRPLEntry(0, iGOPid).m_numRefPicsActive);
   rpcSlice->setNumRefIdx(REF_PIC_LIST_1, m_pcCfg->getRPLEntry(1, iGOPid).m_numRefPicsActive);
 
@@ -641,31 +680,31 @@ void EncSlice::initEncSlice(Picture* pcPic, const int pocLast, const int pocCurr
     {
       if ( rpcSlice->getDeblockingFilterOverrideFlag() && eSliceType!=I_SLICE)
       {
-        rpcSlice->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_betaOffsetDiv2 + m_pcCfg->getLoopFilterBetaOffset()  );
-        rpcSlice->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_tcOffsetDiv2 + m_pcCfg->getLoopFilterTcOffset() );
+        rpcSlice->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_betaOffsetDiv2 + m_pcCfg->getDeblockingFilterBetaOffset()  );
+        rpcSlice->setDeblockingFilterTcOffsetDiv2  ( m_pcCfg->getGOPEntry(iGOPid).m_tcOffsetDiv2   + m_pcCfg->getDeblockingFilterTcOffset() );
         if( rpcSlice->getPPS()->getPPSChromaToolFlag() )
         {
-          rpcSlice->setDeblockingFilterCbBetaOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_CbBetaOffsetDiv2 + m_pcCfg->getLoopFilterCbBetaOffset() );
-          rpcSlice->setDeblockingFilterCbTcOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_CbTcOffsetDiv2 + m_pcCfg->getLoopFilterCbTcOffset() );
-          rpcSlice->setDeblockingFilterCrBetaOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_CrBetaOffsetDiv2 + m_pcCfg->getLoopFilterCrBetaOffset() );
-          rpcSlice->setDeblockingFilterCrTcOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_CrTcOffsetDiv2 + m_pcCfg->getLoopFilterCrTcOffset() );
+          rpcSlice->setDeblockingFilterCbBetaOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_CbBetaOffsetDiv2 + m_pcCfg->getDeblockingFilterCbBetaOffset() );
+          rpcSlice->setDeblockingFilterCbTcOffsetDiv2  ( m_pcCfg->getGOPEntry(iGOPid).m_CbTcOffsetDiv2   + m_pcCfg->getDeblockingFilterCbTcOffset() );
+          rpcSlice->setDeblockingFilterCrBetaOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_CrBetaOffsetDiv2 + m_pcCfg->getDeblockingFilterCrBetaOffset() );
+          rpcSlice->setDeblockingFilterCrTcOffsetDiv2  ( m_pcCfg->getGOPEntry(iGOPid).m_CrTcOffsetDiv2   + m_pcCfg->getDeblockingFilterCrTcOffset() );
         }
         else
         {
           rpcSlice->setDeblockingFilterCbBetaOffsetDiv2( rpcSlice->getDeblockingFilterBetaOffsetDiv2() );
-          rpcSlice->setDeblockingFilterCbTcOffsetDiv2( rpcSlice->getDeblockingFilterTcOffsetDiv2() );
+          rpcSlice->setDeblockingFilterCbTcOffsetDiv2  ( rpcSlice->getDeblockingFilterTcOffsetDiv2() );
           rpcSlice->setDeblockingFilterCrBetaOffsetDiv2( rpcSlice->getDeblockingFilterBetaOffsetDiv2() );
-          rpcSlice->setDeblockingFilterCrTcOffsetDiv2( rpcSlice->getDeblockingFilterTcOffsetDiv2() );
+          rpcSlice->setDeblockingFilterCrTcOffsetDiv2  ( rpcSlice->getDeblockingFilterTcOffsetDiv2() );
         }
       }
       else
       {
-        rpcSlice->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getLoopFilterBetaOffset() );
-        rpcSlice->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getLoopFilterTcOffset() );
-        rpcSlice->setDeblockingFilterCbBetaOffsetDiv2( m_pcCfg->getLoopFilterCbBetaOffset() );
-        rpcSlice->setDeblockingFilterCbTcOffsetDiv2( m_pcCfg->getLoopFilterCbTcOffset() );
-        rpcSlice->setDeblockingFilterCrBetaOffsetDiv2( m_pcCfg->getLoopFilterCrBetaOffset() );
-        rpcSlice->setDeblockingFilterCrTcOffsetDiv2( m_pcCfg->getLoopFilterCrTcOffset() );
+        rpcSlice->setDeblockingFilterBetaOffsetDiv2  ( m_pcCfg->getDeblockingFilterBetaOffset() );
+        rpcSlice->setDeblockingFilterTcOffsetDiv2    ( m_pcCfg->getDeblockingFilterTcOffset() );
+        rpcSlice->setDeblockingFilterCbBetaOffsetDiv2( m_pcCfg->getDeblockingFilterCbBetaOffset() );
+        rpcSlice->setDeblockingFilterCbTcOffsetDiv2  ( m_pcCfg->getDeblockingFilterCbTcOffset() );
+        rpcSlice->setDeblockingFilterCrBetaOffsetDiv2( m_pcCfg->getDeblockingFilterCrBetaOffset() );
+        rpcSlice->setDeblockingFilterCrTcOffsetDiv2  ( m_pcCfg->getDeblockingFilterCrTcOffset() );
       }
     }
   }
@@ -695,6 +734,131 @@ void EncSlice::initEncSlice(Picture* pcPic, const int pocLast, const int pocCurr
     m_pcCuEncoder->getIbcHashMap().destroy();
     m_pcCuEncoder->getIbcHashMap().init( pcPic->cs->pps->getPicWidthInLumaSamples(), pcPic->cs->pps->getPicHeightInLumaSamples() );
   }
+#if GDR_ENABLED
+  if (m_pcCfg->getGdrEnabled())
+  {
+    int gdrPocStart = m_pcCuEncoder->getEncCfg()->getGdrPocStart();
+    int gdrPeriod = m_pcCuEncoder->getEncCfg()->getGdrPeriod();
+    int gdrInterval = m_pcCuEncoder->getEncCfg()->getGdrInterval();
+
+    int picWidth = rpcSlice->getPPS()->getPicWidthInLumaSamples();
+
+    int curPoc = rpcSlice->getPOC();
+    int gdrPoc = (curPoc - gdrPocStart) % gdrPeriod;
+
+    pcPic->cs->picHeader->setGdrPicFlag(false);
+    pcPic->cs->picHeader->setRecoveryPocCnt(0);
+    pcPic->cs->picHeader->setInGdrInterval(false);
+
+    pcPic->cs->picHeader->setVirtualBoundariesPresentFlag(false);
+
+    int  offset = (curPoc < gdrPocStart) ? 0 : (((curPoc - gdrPocStart) / gdrPeriod) * gdrPeriod);
+    int  actualGdrStart = gdrPocStart + offset;
+    int  actualGdrInterval = min(gdrInterval, (int)(pcPic->getPicWidthInLumaSamples() / 8));
+    int  recoveryPocCnt = actualGdrInterval - 1;
+    int  recoveryPicPoc = actualGdrStart + recoveryPocCnt;
+
+    bool isInGdrInterval = (curPoc >= actualGdrStart) && (curPoc < recoveryPicPoc);
+    bool isOutGdrInterval = !isInGdrInterval;
+    bool isGdrPic = (actualGdrStart == curPoc);
+
+#if GDR_ENC_TRACE
+    printf("\n");
+    printf("-poc:%d gdrPocStart:%d actualGdrStart:%d actualGdrInterval:%d actualGdrEndPoc:%d\n", rpcSlice->getPOC(), gdrPocStart, actualGdrStart, actualGdrInterval, recoveryPicPoc - 1);
+#endif
+
+    // for none gdr period pictures
+    if ((curPoc < gdrPocStart) || isOutGdrInterval)
+    {
+      pcPic->cs->picHeader->setInGdrInterval(false);
+      pcPic->cs->picHeader->setVirtualBoundariesPresentFlag(false);
+
+      pcPic->cs->picHeader->setNumHorVirtualBoundaries(0);
+      pcPic->cs->picHeader->setNumVerVirtualBoundaries(0);
+
+#if GDR_ENC_TRACE
+      printf("-poc:%d no virtual boundary\n", rpcSlice->getPOC());
+#endif
+    }
+    // for gdr inteval pictures
+    else
+    {
+      if (curPoc == recoveryPicPoc)
+      {
+        pcPic->cs->picHeader->setInGdrInterval(false);
+      }
+      else
+      {
+        pcPic->cs->picHeader->setInGdrInterval(true);
+      }
+
+      pcPic->cs->picHeader->setVirtualBoundariesPresentFlag(true);
+
+      if (isGdrPic)
+      {
+        pcPic->cs->picHeader->setGdrOrIrapPicFlag(true);
+        pcPic->cs->picHeader->setGdrPicFlag(true);
+
+        pcPic->cs->picHeader->setRecoveryPocCnt(recoveryPocCnt);
+        m_pcGOPEncoder->setLastGdrIntervalPoc(recoveryPicPoc - 1);
+      }
+
+      pcPic->cs->picHeader->setNumHorVirtualBoundaries(0);
+      pcPic->cs->picHeader->setNumVerVirtualBoundaries(1);
+
+      int begGdrX;
+      int endGdrX;
+      int m1, m2, n1;
+
+      double dd = (picWidth / (double)gdrInterval);
+      int mm = (int)((picWidth / (double)gdrInterval) + 0.49999);
+      m1 = ((mm + 7) >> 3) << 3;
+      m2 = ((mm + 0) >> 3) << 3;
+
+      if (dd > mm && m1 == m2)
+      {
+        m1 = m1 + 8;
+      }
+
+      n1 = (picWidth - m2 * gdrInterval) / 8;
+
+      if (gdrPoc < n1)
+      {
+        begGdrX = m1 * gdrPoc;
+        endGdrX = begGdrX + m1;
+      }
+      else
+      {
+        begGdrX = m1 * n1 + m2 * (gdrPoc - n1);
+        endGdrX = begGdrX + m2;
+        if (picWidth <= begGdrX)
+        {
+          begGdrX = picWidth;
+          endGdrX = picWidth;
+        }
+      }
+
+      pcPic->cs->picHeader->setVirtualBoundariesPosX(endGdrX, 0);
+
+#if GDR_ENC_TRACE
+      printf("\n");
+      printf("-poc:%d beg:%d end:%d\n", rpcSlice->getPOC(), begGdrX, endGdrX);
+#endif
+    }
+  }
+#endif
+
+  if (rpcSlice->getSPS()->getSpsRangeExtension().getRrcRiceExtensionEnableFlag())
+  {
+    int bitDepth = rpcSlice->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA);
+    int baseLevel = (bitDepth > 12) ? (rpcSlice->isIntra() ? 5 : 2 * 5) : (rpcSlice->isIntra() ? 2 * 5 : 3 * 5);
+    rpcSlice->setRiceBaseLevel(baseLevel);
+  }
+  else
+  {
+    rpcSlice->setRiceBaseLevel(4);
+  }
+
 }
 
 double EncSlice::initializeLambda(const Slice* slice, const int GOPid, const int refQP, const double dQP)
@@ -726,7 +890,10 @@ double EncSlice::initializeLambda(const Slice* slice, const int GOPid, const int
       }
       else
 #endif
-      dQPFactor = 0.57 * (1.0 - Clip3(0.0, 0.5, 0.05 * double (slice->getPic()->fieldPic ? numberBFrames >> 1 : numberBFrames)));
+      {
+        dQPFactor =
+          0.57 * (1.0 - Clip3(0.0, 0.5, 0.05 * double(slice->getPic()->fieldPic ? numberBFrames >> 1 : numberBFrames)));
+      }
     }
   }
 #if X0038_LAMBDA_FROM_QP_CAPABILITY
@@ -797,7 +964,11 @@ void EncSlice::resetQP( Picture* pic, int sliceQP, double lambda )
 #endif
   setUpLambda(slice, lambda, sliceQP);
 #if WCG_EXT
+#if !JVET_W0043
+  if (!(m_pcCfg->getLumaLevelToDeltaQPMapping().isEnabled() || m_pcCfg->getSmoothQPReductionEnable()))
+#else
   if (!m_pcCfg->getLumaLevelToDeltaQPMapping().isEnabled())
+#endif
   {
     m_pcRdCost->saveUnadjustedLambda();
   }
@@ -855,7 +1026,10 @@ static bool applyQPAdaptation (Picture* const pcPic,       Slice* const pcSlice,
 #if SHARP_LUMA_DELTA_QP
           && !useSharpLumaDQP
 #endif
-          ) iQPFixed = MAX_QP;
+      )
+      {
+        iQPFixed = MAX_QP;
+      }
     }
 #if SHARP_LUMA_DELTA_QP
 
@@ -878,9 +1052,11 @@ static bool applyQPAdaptation (Picture* const pcPic,       Slice* const pcSlice,
     }
 #endif
 
-    if (iQPIndex >= MAX_QP) iQPFixed = MAX_QP;
-    else
-    if (iQPFixed != iQPIndex)
+    if (iQPIndex >= MAX_QP)
+    {
+      iQPFixed = MAX_QP;
+    }
+    else if (iQPFixed != iQPIndex)
     {
       const double* oldLambdas = pcSlice->getLambdas();
       const double  corrFactor = pow (2.0, double(iQPFixed - iQPIndex) / 3.0);
@@ -921,7 +1097,10 @@ static bool applyQPAdaptation (Picture* const pcPic,       Slice* const pcSlice,
 #if SHARP_LUMA_DELTA_QP
               && !useSharpLumaDQP
 #endif
-              ) iQPAdapt = MAX_QP;
+          )
+          {
+            iQPAdapt = MAX_QP;
+          }
           CHECK (meanLuma != (uint32_t)pcPic->m_iOffsetCtu[ctuRsAddr], "luma DC offsets don't match");
         }
 #if SHARP_LUMA_DELTA_QP
@@ -961,7 +1140,10 @@ static bool applyQPAdaptation (Picture* const pcPic,       Slice* const pcSlice,
           uAbsDCless = uint32_t((uint64_t(uAbsDCless) * 64*64 + (blockSize >> 1)) / blockSize);
         }
 
-        if (uAbsDCless < 64*64) uAbsDCless = 64*64;  // limit to 1
+        if (uAbsDCless < 64 * 64)
+        {
+          uAbsDCless = 64 * 64;   // limit to 1
+        }
 
         // reduce QP index if CTU would be fully quantized to zero
         if (uAbsDCless < uRefScale)
@@ -1023,7 +1205,10 @@ static int applyQPAdaptationSubCtu (CodingStructure &cs, const UnitArea ctuArea,
   const int       bitDepth = cs.slice->getSPS()->getBitDepth (CHANNEL_TYPE_LUMA); // overall image bit-depth
   const int   adaptedCtuQP = pcPic ? pcPic->m_iOffsetCtu[ctuAddr] : cs.slice->getSliceQpBase();
 
-  if (!pcPic || cs.slice->getCuQpDeltaSubdiv() == 0) return adaptedCtuQP;
+  if (!pcPic || cs.slice->getCuQpDeltaSubdiv() == 0)
+  {
+    return adaptedCtuQP;
+  }
 
   for (unsigned addr = 0; addr < cs.picture->m_subCtuQP.size(); addr++)
   {
@@ -1075,7 +1260,10 @@ static int applyQPAdaptationSubCtu (CodingStructure &cs, const UnitArea ctuArea,
 #endif
       }
     }
-    if (sumAct <= 0.0) return adaptedCtuQP;
+    if (sumAct <= 0.0)
+    {
+      return adaptedCtuQP;
+    }
 
     sumAct = double(numAct) / sumAct; // 1.0 / (average CTU activity)
 
@@ -1133,7 +1321,7 @@ void EncSlice::setSearchRange( Slice* pcSlice )
   }
 }
 
-void EncSlice::setLosslessSlice(Picture* pcPic, bool islossless) 
+void EncSlice::setLosslessSlice(Picture* pcPic, bool islossless)
 {
   Slice* slice = pcPic->slices[getSliceSegmentIdx()];
   slice->setLossless(islossless);
@@ -1145,13 +1333,12 @@ void EncSlice::setLosslessSlice(Picture* pcPic, bool islossless)
       int losslessQp = LOSSLESS_AND_MIXED_LOSSLESS_RD_COST_TEST_QP - ((slice->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA) - 8) * 6);
       slice->setSliceQp(losslessQp); // update the slice/base QPs
 
-     slice->setTSResidualCodingDisabledFlag(m_pcCfg->getTSRCdisableLL() ? true : false);
-
+      slice->setTSResidualCodingDisabledFlag(m_pcCfg->getTSRCdisableLL() ? true : false);
     }
     else
     {
-        slice->setSliceQp(pcPic->getLossyQPValue());
-        slice->setTSResidualCodingDisabledFlag(false);
+      slice->setSliceQp(pcPic->getLossyQPValue());
+      slice->setTSResidualCodingDisabledFlag(false);
     }
   }
 }
@@ -1177,8 +1364,6 @@ void EncSlice::precompressSlice( Picture* pcPic )
 
   Slice* pcSlice        = pcPic->slices[getSliceSegmentIdx()];
 
-
-
   double     dPicRdCostBest = MAX_DOUBLE;
   uint32_t       uiQpIdxBest = 0;
 
@@ -1239,7 +1424,6 @@ void EncSlice::calCostSliceI(Picture* pcPic) // TODO: this only analyses the fir
   const int      shift             = sps.getBitDepth(CHANNEL_TYPE_LUMA)-8;
   const int      offset            = (shift>0)?(1<<(shift-1)):0;
 
-
   for( uint32_t ctuIdx = 0; ctuIdx < pcSlice->getNumCtuInSlice(); ctuIdx++ )
   {
     uint32_t ctuRsAddr = pcSlice->getCtuAddrInSlice( ctuIdx );
@@ -1252,7 +1436,6 @@ void EncSlice::calCostSliceI(Picture* pcPic) // TODO: this only analyses the fir
 
     (m_pcRateCtrl->getRCPic()->getLCU(ctuRsAddr)).m_costIntra=(iSumHad+offset)>>shift;
     iSumHadSlice += (m_pcRateCtrl->getRCPic()->getLCU(ctuRsAddr)).m_costIntra;
-
   }
   m_pcRateCtrl->getRCPic()->setTotalIntraCost(iSumHadSlice);
 }
@@ -1290,6 +1473,17 @@ void EncSlice::compressSlice( Picture* pcPic, const bool bCompressEntireSlice, c
 
   Slice* const pcSlice    = pcPic->slices[getSliceSegmentIdx()];
 
+  if (pcSlice->getSPS()->getSpsRangeExtension().getRrcRiceExtensionEnableFlag())
+  {
+    int bitDepth = pcSlice->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA);
+    int baseLevel = (bitDepth > 12) ? (pcSlice->isIntra() ? 5 : 2 * 5 ) : (pcSlice->isIntra() ? 2 * 5 : 3 * 5);
+    pcSlice->setRiceBaseLevel(baseLevel);
+  }
+  else
+  {
+    pcSlice->setRiceBaseLevel(4);
+  }
+
   // initialize cost values - these are used by precompressSlice (they should be parameters).
   m_uiPicTotalBits  = 0;
   m_uiPicDist       = 0;
@@ -1298,14 +1492,6 @@ void EncSlice::compressSlice( Picture* pcPic, const bool bCompressEntireSlice, c
 
   m_CABACEstimator->initCtxModels( *pcSlice );
 
-#if ENABLE_SPLIT_PARALLELISM
-  for( int jId = 1; jId < m_pcLib->getNumCuEncStacks(); jId++ )
-  {
-    CABACWriter* cw = m_pcLib->getCABACEncoder( jId )->getCABACEstimator( pcSlice->getSPS() );
-    cw->initCtxModels( *pcSlice );
-  }
-
-#endif
   m_pcCuEncoder->getModeCtrl()->setFastDeltaQp(bFastDeltaQP);
 
 
@@ -1330,9 +1516,7 @@ void EncSlice::compressSlice( Picture* pcPic, const bool bCompressEntireSlice, c
     xCheckWPEnable( pcSlice );
   }
 
-
-
-    pcPic->m_prevQP[0] = pcPic->m_prevQP[1] = pcSlice->getSliceQp();
+  pcPic->m_prevQP[0] = pcPic->m_prevQP[1] = pcSlice->getSliceQp();
 
   CHECK( pcPic->m_prevQP[0] == std::numeric_limits<int>::max(), "Invalid previous QP" );
 
@@ -1353,14 +1537,7 @@ void EncSlice::compressSlice( Picture* pcPic, const bool bCompressEntireSlice, c
                            (m_pcCfg->getBaseQP() >= 38) || (m_pcCfg->getSourceWidth() <= 512 && m_pcCfg->getSourceHeight() <= 320), m_adaptedLumaQP))
     {
       m_CABACEstimator->initCtxModels (*pcSlice);
-#if ENABLE_SPLIT_PARALLELISM
-      for (int jId = 1; jId < m_pcLib->getNumCuEncStacks(); jId++)
-      {
-        CABACWriter* cw = m_pcLib->getCABACEncoder (jId)->getCABACEstimator (pcSlice->getSPS());
-        cw->initCtxModels (*pcSlice);
-      }
-#endif
-        pcPic->m_prevQP[0] = pcPic->m_prevQP[1] = pcSlice->getSliceQp();
+      pcPic->m_prevQP[0] = pcPic->m_prevQP[1] = pcSlice->getSliceQp();
       if (pcSlice->getFirstCtuRsAddrInSlice() == 0)
       {
         cs.currQP[0] = cs.currQP[1] = pcSlice->getSliceQp(); // cf code above
@@ -1389,7 +1566,10 @@ void EncSlice::compressSlice( Picture* pcPic, const bool bCompressEntireSlice, c
   m_pcInterSearch->resetUniMvList();
   ::memset(g_isReusedUniMVsFilled, 0, sizeof(g_isReusedUniMVsFilled));
   encodeCtus( pcPic, bCompressEntireSlice, bFastDeltaQP, m_pcLib );
-  if (checkPLTRatio) m_pcLib->checkPltStats( pcPic );
+  if (checkPLTRatio)
+  {
+    m_pcLib->checkPltStats(pcPic);
+  }
 }
 
 void EncSlice::checkDisFracMmvd( Picture* pcPic, uint32_t startCtuTsAddr, uint32_t boundingCtuTsAddr )
@@ -1424,13 +1604,13 @@ void EncSlice::checkDisFracMmvd( Picture* pcPic, uint32_t startCtuTsAddr, uint32
   {
     pcPic->cs->picHeader->setDisFracMMVD( true );
   }
-  if (!pcPic->cs->picHeader->getDisFracMMVD()) {
+  if (!pcPic->cs->picHeader->getDisFracMMVD())
+  {
     bool useIntegerMVD = (pcPic->lwidth()*pcPic->lheight() > 1920 * 1080);
     pcPic->cs->picHeader->setDisFracMMVD( useIntegerMVD );
   }
 }
 
-
 void EncSlice::setJointCbCrModes( CodingStructure& cs, const Position topLeftLuma, const Size sizeLuma )
 {
   bool              sgnFlag = true;
@@ -1479,12 +1659,9 @@ void EncSlice::encodeCtus( Picture* pcPic, const bool bCompressEntireSlice, cons
   const int iQPIndex              = pcSlice->getSliceQpBase();
 #endif
 
-#if ENABLE_SPLIT_PARALLELISM
-  const int       dataId          = 0;
-#endif
-  CABACWriter*    pCABACWriter    = pEncLib->getCABACEncoder( PARL_PARAM0( dataId ) )->getCABACEstimator( pcSlice->getSPS() );
-  TrQuant*        pTrQuant        = pEncLib->getTrQuant( PARL_PARAM0( dataId ) );
-  RdCost*         pRdCost         = pEncLib->getRdCost( PARL_PARAM0( dataId ) );
+  CABACWriter*    pCABACWriter    = pEncLib->getCABACEncoder()->getCABACEstimator( pcSlice->getSPS() );
+  TrQuant*        pTrQuant        = pEncLib->getTrQuant();
+  RdCost*         pRdCost         = pEncLib->getRdCost();
   EncCfg*         pCfg            = pEncLib;
   RateCtrl*       pRateCtrl       = pEncLib->getRateCtrl();
   pRdCost->setLosslessRDCost(pcSlice->isLossless());
@@ -1506,7 +1683,7 @@ void EncSlice::encodeCtus( Picture* pcPic, const bool bCompressEntireSlice, cons
   prevQP[0] = prevQP[1] = pcSlice->getSliceQp();
   currQP[0] = currQP[1] = pcSlice->getSliceQp();
 
-    prevQP[0] = prevQP[1] = pcSlice->getSliceQp();
+  prevQP[0] = prevQP[1] = pcSlice->getSliceQp();
   if ( pcSlice->getSPS()->getFpelMmvdEnabledFlag() ||
       (pcSlice->getSPS()->getIBCFlag() && m_pcCuEncoder->getEncCfg()->getIBCHashSearch()))
   {
@@ -1516,6 +1693,29 @@ void EncSlice::encodeCtus( Picture* pcPic, const bool bCompressEntireSlice, cons
       int hashBlkHitPerc = m_pcCuEncoder->getIbcHashMap().calHashBlkMatchPerc(cs.area.Y());
       cs.slice->setDisableSATDForRD(hashBlkHitPerc > 59);
     }
+    if ((pcSlice->getSPS()->getSpsRangeExtension().getTSRCRicePresentFlag()) && (m_pcGOPEncoder->getPreQP() != pcSlice->getSliceQp()) && (pcPic->cs->pps->getNumSlicesInPic() == 1) && (pcSlice->get_tsrc_index() > 0) && (pcSlice->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA) <= 12))
+    {
+      uint32_t totalCtu  = 0;
+      uint32_t hashRatio = 0;
+      for (uint32_t ctuIdx = 0; ctuIdx < pcSlice->getNumCtuInSlice(); ctuIdx++)
+      {
+        const uint32_t ctuRsAddr     = pcSlice->getCtuAddrInSlice(ctuIdx);
+        const uint32_t ctuXPosInCtus = ctuRsAddr % widthInCtus;
+        const uint32_t ctuYPosInCtus = ctuRsAddr / widthInCtus;
+        const Position pos(ctuXPosInCtus * pcv.maxCUWidth, ctuYPosInCtus * pcv.maxCUHeight);
+        const UnitArea ctuArea(cs.area.chromaFormat, Area(pos.x, pos.y, pcv.maxCUWidth, pcv.maxCUHeight));
+
+        hashRatio += m_pcCuEncoder->getIbcHashMap().calHashBlkMatchPerc(cs.area.Y());
+        totalCtu++;
+      }
+      if (totalCtu > 0)
+      {
+        if ((hashRatio < 4200) || (hashRatio < (41 * totalCtu)))
+        {
+          pcSlice->set_tsrc_index(0);
+        }
+      }
+    }
   }
 
   // for every CTU in the slice
@@ -1676,22 +1876,16 @@ void EncSlice::encodeCtus( Picture* pcPic, const bool bCompressEntireSlice, cons
     if (pcSlice->getSPS()->getUseLmcs())
     {
       m_pcCuEncoder->setDecCuReshaperInEncCU(m_pcLib->getReshaper(), pcSlice->getSPS()->getChromaFormatIdc());
-
-#if ENABLE_SPLIT_PARALLELISM
-      for (int jId = 1; jId < m_pcLib->getNumCuEncStacks(); jId++)
-      {
-        m_pcLib->getCuEncoder(jId)->setDecCuReshaperInEncCU(m_pcLib->getReshaper(jId), pcSlice->getSPS()->getChromaFormatIdc());
-      }
-#endif
     }
     if( !cs.slice->isIntra() && pCfg->getMCTSEncConstraint() )
     {
       pcPic->mctsInfo.init( &cs, ctuRsAddr );
     }
 
-  if (pCfg->getSwitchPOC() != pcPic->poc || ctuRsAddr >= pCfg->getDebugCTU())
-    m_pcCuEncoder->compressCtu( cs, ctuArea, ctuRsAddr, prevQP, currQP );
-
+    if (pCfg->getSwitchPOC() != pcPic->poc || ctuRsAddr >= pCfg->getDebugCTU())
+    {
+      m_pcCuEncoder->compressCtu(cs, ctuArea, ctuRsAddr, prevQP, currQP);
+    }
 #if K0149_BLOCK_STATISTICS
     getAndStoreBlockStatistics(cs, ctuArea);
 #endif
@@ -1700,13 +1894,7 @@ void EncSlice::encodeCtus( Picture* pcPic, const bool bCompressEntireSlice, cons
     pCABACWriter->coding_tree_unit( cs, ctuArea, prevQP, ctuRsAddr, true, true );
     const int numberOfWrittenBits = int( pCABACWriter->getEstFracBits() >> SCALE_BITS );
 
-#if ENABLE_SPLIT_PARALLELISM
-#pragma omp critical
-#endif
     pcSlice->setSliceBits( ( uint32_t ) ( pcSlice->getSliceBits() + numberOfWrittenBits ) );
-#if ENABLE_SPLIT_PARALLELISM
-#pragma omp critical
-#endif
 
     // Store probabilities of first CTU in line into buffer - used only if wavefront-parallel-processing is enabled.
     if( cs.pps->ctuIsTileColBd( ctuXPosInCtus ) && pEncLib->getEntropyCodingSyncEnabledFlag() )
@@ -1782,7 +1970,6 @@ void EncSlice::encodeCtus( Picture* pcPic, const bool bCompressEntireSlice, cons
     // for last Ctu in the slice
     if (pcSlice->getPPS()->getNumSubPics() >= 2 && curSubPic.getTreatedAsPicFlag() && ctuIdx == (pcSlice->getNumCtuInSlice() - 1))
     {
-
       int subPicX = (int)curSubPic.getSubPicLeft();
       int subPicY = (int)curSubPic.getSubPicTop();
       int subPicWidth = (int)curSubPic.getSubPicWidthInLumaSample();
@@ -1926,7 +2113,6 @@ void EncSlice::encodeSlice   ( Picture* pcPic, OutputBitstream* pcSubstreams, ui
     m_encCABACTableIdx = pcSlice->getSliceType();
   }
   numBinsCoded += m_CABACWriter->getNumBins();
-
 }
 
 
diff --git a/source/Lib/EncoderLib/EncSlice.h b/source/Lib/EncoderLib/EncSlice.h
index 9feaffd75..17ec52a6b 100644
--- a/source/Lib/EncoderLib/EncSlice.h
+++ b/source/Lib/EncoderLib/EncSlice.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -118,7 +118,7 @@ public:
 
   /// preparation of slice encoding (reference marking, QP and lambda)
   void    initEncSlice        ( Picture*  pcPic, const int pocLast, const int pocCurr,
-                                const int iGOPid, Slice*& rpcSlice, const bool isField, bool isEncodeLtRef, int layerId );
+                                const int iGOPid, Slice*& rpcSlice, const bool isField, bool isEncodeLtRef, int layerId, NalUnitType nalType );
 
   void    resetQP             ( Picture* pic, int sliceQP, double lambda );
 
diff --git a/source/Lib/EncoderLib/EncTemporalFilter.cpp b/source/Lib/EncoderLib/EncTemporalFilter.cpp
index c9c74336f..867effa41 100644
--- a/source/Lib/EncoderLib/EncTemporalFilter.cpp
+++ b/source/Lib/EncoderLib/EncTemporalFilter.cpp
@@ -3,7 +3,7 @@
 * and contributor rights, including patent rights, and no such rights are
 * granted under this license.
 *
-* Copyright (c) 2010-2020, ITU/ISO/IEC
+* Copyright (c) 2010-2021, ITU/ISO/IEC
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
@@ -43,10 +43,10 @@
 // Constructor / destructor / initialization / destroy
 // ====================================================================================================================
 
-const int EncTemporalFilter::m_range = 2;
-const double EncTemporalFilter::m_chromaFactor = 0.55;
-const double EncTemporalFilter::m_sigmaMultiplier = 9.0;
-const double EncTemporalFilter::m_sigmaZeroPoint = 10.0;
+const int EncTemporalFilter::m_range = 4;
+const double EncTemporalFilter::m_chromaFactor    =  0.55;
+const double EncTemporalFilter::m_sigmaMultiplier =  9.0;
+const double EncTemporalFilter::m_sigmaZeroPoint  = 10.0;
 const int EncTemporalFilter::m_motionVectorFactor = 16;
 const int EncTemporalFilter::m_padding = 128;
 const int EncTemporalFilter::m_interpolationFilter[16][8] =
@@ -69,12 +69,12 @@ const int EncTemporalFilter::m_interpolationFilter[16][8] =
   {   0,   0,  -2,   4,  64,  -3,   1,   0 }    //15-->-->
 };
 
-const double EncTemporalFilter::m_refStrengths[3][2] =
+const double EncTemporalFilter::m_refStrengths[3][4] =
 { // abs(POC offset)
-  //  1,    2
-  {0.85, 0.60},  // m_range * 2
-  {1.20, 1.00},  // m_range
-  {0.30, 0.30}   // otherwise
+  //  1,    2     3     4
+  {0.85, 0.57, 0.41, 0.33},  // m_range * 2
+  {1.13, 0.97, 0.81, 0.57},  // m_range
+  {0.30, 0.30, 0.30, 0.30}   // otherwise
 };
 
 EncTemporalFilter::EncTemporalFilter() :
@@ -105,23 +105,23 @@ void EncTemporalFilter::init(const int frameSkip,
   m_FrameSkip = frameSkip;
   for (int i = 0; i < MAX_NUM_CHANNEL_TYPE; i++)
   {
-    m_inputBitDepth[i] = inputBitDepth[i];
+    m_inputBitDepth[i]       = inputBitDepth[i];
     m_MSBExtendedBitDepth[i] = msbExtendedBitDepth[i];
-    m_internalBitDepth[i] = internalBitDepth[i];
+    m_internalBitDepth[i]    = internalBitDepth[i];
   }
 
-  m_sourceWidth = width;
+  m_sourceWidth  = width;
   m_sourceHeight = height;
   for (int i = 0; i < 2; i++)
   {
     m_pad[i] = pad[i];
   }
   m_clipInputVideoToRec709Range = rec709;
-  m_inputFileName = filename;
+  m_inputFileName   = filename;
   m_chromaFormatIDC = inputChromaFormatIDC;
   m_inputColourSpaceConvert = colorSpaceConv;
   m_area = Area(0, 0, width, height);
-  m_QP = qp;
+  m_QP   = qp;
   m_temporalFilterStrengths = temporalFilterStrengths;
   m_gopBasedTemporalFilterFutureReference = gopBasedTemporalFilterFutureReference;
 }
@@ -153,11 +153,10 @@ bool EncTemporalFilter::filter(PelStorage *orgPic, int receivedPoc)
     yuvFrames.open(m_inputFileName, false, m_inputBitDepth, m_MSBExtendedBitDepth, m_internalBitDepth);
     yuvFrames.skipFrames(std::max(offset + receivedPoc - m_range, 0), m_sourceWidth - m_pad[0], m_sourceHeight - m_pad[1], m_chromaFormatIDC);
 
-
     std::deque<TemporalFilterSourcePicInfo> srcFrameInfo;
 
     int firstFrame = receivedPoc + offset - m_range;
-    int lastFrame = receivedPoc + offset + m_range;
+    int lastFrame  = receivedPoc + offset + m_range;
     if (!m_gopBasedTemporalFilterFutureReference)
     {
       lastFrame = receivedPoc + offset - 1;
@@ -192,7 +191,7 @@ bool EncTemporalFilter::filter(PelStorage *orgPic, int receivedPoc)
         continue;
       }
       srcFrameInfo.push_back(TemporalFilterSourcePicInfo());
-      TemporalFilterSourcePicInfo &srcPic=srcFrameInfo.back();
+      TemporalFilterSourcePicInfo &srcPic = srcFrameInfo.back();
 
       PelStorage dummyPicBufferTO; // Only used temporary in yuvFrames.read
       srcPic.picBuffer.create(m_chromaFormatIDC, m_area, 0, m_padding);
@@ -240,20 +239,20 @@ bool EncTemporalFilter::filter(PelStorage *orgPic, int receivedPoc)
 
 void EncTemporalFilter::subsampleLuma(const PelStorage &input, PelStorage &output, const int factor) const
 {
-  const int newWidth = input.Y().width / factor;
+  const int newWidth  = input.Y().width  / factor;
   const int newHeight = input.Y().height / factor;
   output.create(m_chromaFormatIDC, Area(0, 0, newWidth, newHeight), 0, m_padding);
 
-  const Pel* srcRow = input.Y().buf;
+  const Pel* srcRow   = input.Y().buf;
   const int srcStride = input.Y().stride;
-  Pel *dstRow = output.Y().buf;
+  Pel *dstRow         = output.Y().buf;
   const int dstStride = output.Y().stride;
 
-  for (int y = 0; y < newHeight; y++, srcRow+=factor*srcStride, dstRow+=dstStride)
+  for (int y = 0; y < newHeight; y++, srcRow += factor * srcStride, dstRow += dstStride)
   {
     const Pel *inRow      = srcRow;
-    const Pel *inRowBelow = srcRow+srcStride;
-    Pel *target     = dstRow;
+    const Pel *inRowBelow = srcRow + srcStride;
+    Pel *target           = dstRow;
 
     for (int x = 0; x < newWidth; x++)
     {
@@ -275,19 +274,19 @@ int EncTemporalFilter::motionErrorLuma(const PelStorage &orig,
   const int besterror = 8 * 8 * 1024 * 1024) const
 {
   const Pel* origOrigin = orig.Y().buf;
-  const int origStride  = orig.Y().stride;
-  const Pel *buffOrigin = buffer.Y().buf;
-  const int buffStride  = buffer.Y().stride;
+  const int  origStride = orig.Y().stride;
+  const Pel* buffOrigin = buffer.Y().buf;
+  const int  buffStride = buffer.Y().stride;
 
-  int error = 0;// dx * 10 + dy * 10;
+  int error = 0;
   if (((dx | dy) & 0xF) == 0)
   {
     dx /= m_motionVectorFactor;
     dy /= m_motionVectorFactor;
     for (int y1 = 0; y1 < bs; y1++)
     {
-      const Pel* origRowStart = origOrigin + (y+y1)*origStride + x;
-      const Pel* bufferRowStart = buffOrigin + (y+y1+dy)*buffStride + (x+dx);
+      const Pel* origRowStart   = origOrigin + (y + y1) * origStride + x;
+      const Pel* bufferRowStart = buffOrigin + (y + y1 + dy) * buffStride + (x + dx);
       for (int x1 = 0; x1 < bs; x1 += 2)
       {
         int diff = origRowStart[x1] - bufferRowStart[x1];
@@ -311,7 +310,7 @@ int EncTemporalFilter::motionErrorLuma(const PelStorage &orig,
     for (int y1 = 1; y1 < bs + 7; y1++)
     {
       const int yOffset = y + y1 + (dy >> 4) - 3;
-      const Pel *sourceRow = buffOrigin + (yOffset)*buffStride + 0;
+      const Pel *sourceRow = buffOrigin + yOffset * buffStride + 0;
       for (int x1 = 0; x1 < bs; x1++)
       {
         sum = 0;
@@ -329,10 +328,10 @@ int EncTemporalFilter::motionErrorLuma(const PelStorage &orig,
       }
     }
 
-    const Pel maxSampleValue = (1<<m_internalBitDepth[CHANNEL_TYPE_LUMA])-1;
+    const Pel maxSampleValue = (1 << m_internalBitDepth[CHANNEL_TYPE_LUMA]) - 1;
     for (int y1 = 0; y1 < bs; y1++)
     {
-      const Pel *origRow = origOrigin + (y+y1)*origStride + 0;
+      const Pel *origRow = origOrigin + (y + y1) * origStride;
       for (int x1 = 0; x1 < bs; x1++)
       {
         sum = 0;
@@ -360,15 +359,15 @@ int EncTemporalFilter::motionErrorLuma(const PelStorage &orig,
 void EncTemporalFilter::motionEstimationLuma(Array2D<MotionVector> &mvs, const PelStorage &orig, const PelStorage &buffer, const int blockSize,
   const Array2D<MotionVector> *previous, const int factor, const bool doubleRes) const
 {
-  int range = 5;
+  int range = doubleRes ? 0 : 5;
   const int stepSize = blockSize;
 
   const int origWidth  = orig.Y().width;
   const int origHeight = orig.Y().height;
 
-  for (int blockY = 0; blockY + blockSize < origHeight; blockY += stepSize)
+  for (int blockY = 0; blockY + blockSize <= origHeight; blockY += stepSize)
   {
-    for (int blockX = 0; blockX + blockSize < origWidth; blockX += stepSize)
+    for (int blockX = 0; blockX + blockSize <= origWidth; blockX += stepSize)
     {
       MotionVector best;
 
@@ -378,10 +377,10 @@ void EncTemporalFilter::motionEstimationLuma(Array2D<MotionVector> &mvs, const P
       }
       else
       {
-        for (int py = -2; py <= 2; py++)
+        for (int py = -1; py <= 1; py++)
         {
           int testy = blockY / (2 * blockSize) + py;
-          for (int px = -2; px <= 2; px++)
+          for (int px = -1; px <= 1; px++)
           {
             int testx = blockX / (2 * blockSize) + px;
             if ((testx >= 0) && (testx < origWidth / (2 * blockSize)) && (testy >= 0) && (testy < origHeight / (2 * blockSize)))
@@ -395,6 +394,11 @@ void EncTemporalFilter::motionEstimationLuma(Array2D<MotionVector> &mvs, const P
             }
           }
         }
+        int error = motionErrorLuma(orig, buffer, blockX, blockY, 0, 0, blockSize, best.error);
+        if (error < best.error)
+        {
+          best.set(0, 0, error);
+        }
       }
       MotionVector prevBest = best;
       for (int y2 = prevBest.y / m_motionVectorFactor - range; y2 <= prevBest.y / m_motionVectorFactor + range; y2++)
@@ -409,7 +413,7 @@ void EncTemporalFilter::motionEstimationLuma(Array2D<MotionVector> &mvs, const P
         }
       }
       if (doubleRes)
-      { // merge into one loop, probably with precision array (here [12, 3] or maybe [4, 1]) with setable number of iterations
+      {
         prevBest = best;
         int doubleRange = 3 * 4;
         for (int y2 = prevBest.y - doubleRange; y2 <= prevBest.y + doubleRange; y2 += 4)
@@ -421,7 +425,6 @@ void EncTemporalFilter::motionEstimationLuma(Array2D<MotionVector> &mvs, const P
             {
               best.set(x2, y2, error);
             }
-
           }
         }
 
@@ -436,11 +439,51 @@ void EncTemporalFilter::motionEstimationLuma(Array2D<MotionVector> &mvs, const P
             {
               best.set(x2, y2, error);
             }
-
           }
         }
+      }
+
+      if (blockY > 0)
+      {
+        MotionVector aboveMV = mvs.get(blockX / stepSize, (blockY - stepSize) / stepSize);
+        int error = motionErrorLuma(orig, buffer, blockX, blockY, aboveMV.x, aboveMV.y, blockSize, best.error);
+        if (error < best.error)
+        {
+          best.set(aboveMV.x, aboveMV.y, error);
+        }
+      }
+      if (blockX > 0)
+      {
+        MotionVector leftMV = mvs.get((blockX - stepSize) / stepSize, blockY / stepSize);
+        int error = motionErrorLuma(orig, buffer, blockX, blockY, leftMV.x, leftMV.y, blockSize, best.error);
+        if (error < best.error)
+        {
+          best.set(leftMV.x, leftMV.y, error);
+        }
+      }
+
+      // calculate average
+      double avg = 0.0;
+      for (int x1 = 0; x1 < blockSize; x1++)
+      {
+        for (int y1 = 0; y1 < blockSize; y1++)
+        {
+          avg = avg + orig.Y().at(blockX + x1, blockY + y1);
+        }
+      }
+      avg = avg / (blockSize * blockSize);
 
+      // calculate variance
+      double variance = 0;
+      for (int x1 = 0; x1 < blockSize; x1++)
+      {
+        for (int y1 = 0; y1 < blockSize; y1++)
+        {
+          int pix = orig.Y().at(blockX + x1, blockY + y1);
+          variance = variance + (pix - avg) * (pix - avg);
+        }
       }
+      best.error = (int)(20 * ((best.error + 5.0) / (variance + 5.0)) + (best.error / (blockSize * blockSize)) / 50);
       mvs.get(blockX / stepSize, blockY / stepSize) = best;
     }
   }
@@ -448,7 +491,7 @@ void EncTemporalFilter::motionEstimationLuma(Array2D<MotionVector> &mvs, const P
 
 void EncTemporalFilter::motionEstimation(Array2D<MotionVector> &mv, const PelStorage &orgPic, const PelStorage &buffer, const PelStorage &origSubsampled2, const PelStorage &origSubsampled4) const
 {
-  const int width = m_sourceWidth;
+  const int width  = m_sourceWidth;
   const int height = m_sourceHeight;
   Array2D<MotionVector> mv_0(width / 16, height / 16);
   Array2D<MotionVector> mv_1(width / 16, height / 16);
@@ -469,25 +512,25 @@ void EncTemporalFilter::motionEstimation(Array2D<MotionVector> &mv, const PelSto
 
 void EncTemporalFilter::applyMotion(const Array2D<MotionVector> &mvs, const PelStorage &input, PelStorage &output) const
 {
-  static const int lumaBlockSize=8;
+  static const int lumaBlockSize = 8;
 
-  for(int c=0; c< getNumberValidComponents(m_chromaFormatIDC); c++)
+  for(int c = 0; c < getNumberValidComponents(m_chromaFormatIDC); c++)
   {
-    const ComponentID compID=(ComponentID)c;
-    const int csx=getComponentScaleX(compID, m_chromaFormatIDC);
-    const int csy=getComponentScaleY(compID, m_chromaFormatIDC);
-    const int blockSizeX = lumaBlockSize>>csx;
-    const int blockSizeY = lumaBlockSize>>csy;
+    const ComponentID compID = (ComponentID)c;
+    const int csx = getComponentScaleX(compID, m_chromaFormatIDC);
+    const int csy = getComponentScaleY(compID, m_chromaFormatIDC);
+    const int blockSizeX = lumaBlockSize >> csx;
+    const int blockSizeY = lumaBlockSize >> csy;
     const int height = input.bufs[c].height;
     const int width  = input.bufs[c].width;
 
-    const Pel maxValue = (1<<m_internalBitDepth[toChannelType(compID)])-1;
+    const Pel maxValue = (1 << m_internalBitDepth[toChannelType(compID)]) - 1;
 
     const Pel *srcImage = input.bufs[c].buf;
-    const int srcStride  = input.bufs[c].stride;
+    const int srcStride = input.bufs[c].stride;
 
     Pel *dstImage = output.bufs[c].buf;
-    int dstStride  = output.bufs[c].stride;
+    int dstStride = output.bufs[c].stride;
 
     for (int y = 0, blockNumY = 0; y + blockSizeY <= height; y += blockSizeY, blockNumY++)
     {
@@ -496,23 +539,23 @@ void EncTemporalFilter::applyMotion(const Array2D<MotionVector> &mvs, const PelS
         const MotionVector &mv = mvs.get(blockNumX,blockNumY);
         const int dx = mv.x >> csx ;
         const int dy = mv.y >> csy ;
-        const int xInt = mv.x >> (4+csx) ;
-        const int yInt = mv.y >> (4+csy) ;
+        const int xInt = mv.x >> (4 + csx) ;
+        const int yInt = mv.y >> (4 + csy) ;
 
         const int *xFilter = m_interpolationFilter[dx & 0xf];
         const int *yFilter = m_interpolationFilter[dy & 0xf]; // will add 6 bit.
-        const int numFilterTaps=7;
-        const int centreTapOffset=3;
+        const int numFilterTaps   = 7;
+        const int centerTapOffset = 3;
 
         int tempArray[lumaBlockSize + numFilterTaps][lumaBlockSize];
 
         for (int by = 1; by < blockSizeY + numFilterTaps; by++)
         {
-          const int yOffset = y + by + yInt - centreTapOffset;
-          const Pel *sourceRow = srcImage+yOffset*srcStride;
+          const int yOffset = y + by + yInt - centerTapOffset;
+          const Pel *sourceRow = srcImage + yOffset * srcStride;
           for (int bx = 0; bx < blockSizeX; bx++)
           {
-            int base = x + bx + xInt - centreTapOffset;
+            int base = x + bx + xInt - centerTapOffset;
             const Pel *rowStart = sourceRow + base;
 
             int sum = 0;
@@ -527,10 +570,10 @@ void EncTemporalFilter::applyMotion(const Array2D<MotionVector> &mvs, const PelS
           }
         }
 
-        Pel *dstRow = dstImage+y*dstStride;
-        for (int by = 0; by < blockSizeY; by++, dstRow+=dstStride)
+        Pel *dstRow = dstImage + y * dstStride;
+        for (int by = 0; by < blockSizeY; by++, dstRow += dstStride)
         {
-          Pel *dstPel=dstRow+x;
+          Pel *dstPel = dstRow + x;
           for (int bx = 0; bx < blockSizeX; bx++, dstPel++)
           {
             int sum = 0;
@@ -553,7 +596,7 @@ void EncTemporalFilter::applyMotion(const Array2D<MotionVector> &mvs, const PelS
 }
 
 void EncTemporalFilter::bilateralFilter(const PelStorage &orgPic,
-  const std::deque<TemporalFilterSourcePicInfo> &srcFrameInfo,
+  std::deque<TemporalFilterSourcePicInfo> &srcFrameInfo,
   PelStorage &newOrgPic,
   double overallStrength) const
 {
@@ -566,7 +609,7 @@ void EncTemporalFilter::bilateralFilter(const PelStorage &orgPic,
   }
 
   int refStrengthRow = 2;
-  if (numRefs == m_range*2)
+  if (numRefs == m_range * 2)
   {
     refStrengthRow = 0;
   }
@@ -578,44 +621,90 @@ void EncTemporalFilter::bilateralFilter(const PelStorage &orgPic,
   const double lumaSigmaSq = (m_QP - m_sigmaZeroPoint) * (m_QP - m_sigmaZeroPoint) * m_sigmaMultiplier;
   const double chromaSigmaSq = 30 * 30;
 
-  for(int c=0; c< getNumberValidComponents(m_chromaFormatIDC); c++)
+  for(int c = 0; c < getNumberValidComponents(m_chromaFormatIDC); c++)
   {
-    const ComponentID compID=(ComponentID)c;
+    const ComponentID compID = (ComponentID)c;
     const int height = orgPic.bufs[c].height;
     const int width  = orgPic.bufs[c].width;
-    const Pel *srcPelRow = orgPic.bufs[c].buf;
-    const int srcStride = orgPic.bufs[c].stride;
-    Pel *dstPelRow = newOrgPic.bufs[c].buf;
-    const int dstStride = newOrgPic.bufs[c].stride;
-    const double sigmaSq = isChroma(compID)? chromaSigmaSq : lumaSigmaSq;
+    const Pel* srcPelRow = orgPic.bufs[c].buf;
+    const int  srcStride = orgPic.bufs[c].stride;
+          Pel* dstPelRow = newOrgPic.bufs[c].buf;
+    const int  dstStride = newOrgPic.bufs[c].stride;
+    const double sigmaSq = isChroma(compID) ? chromaSigmaSq : lumaSigmaSq;
     const double weightScaling = overallStrength * (isChroma(compID) ? m_chromaFactor : 0.4);
-    const Pel maxSampleValue = (1<<m_internalBitDepth[toChannelType(compID)])-1;
-    const double bitDepthDiffWeighting=1024.0 / (maxSampleValue+1);
-
-    for (int y = 0; y < height; y++, srcPelRow+=srcStride, dstPelRow+=dstStride)
+    const Pel maxSampleValue   = (1 << m_internalBitDepth[toChannelType(compID)]) - 1;
+    const double bitDepthDiffWeighting = 1024.0 / (maxSampleValue + 1);
+    const int lumaBlockSize = 8;
+    const int csx = getComponentScaleX(compID, m_chromaFormatIDC);
+    const int csy = getComponentScaleY(compID, m_chromaFormatIDC);
+    const int blockSizeX = lumaBlockSize >> csx;
+    const int blockSizeY = lumaBlockSize >> csy;
+
+    for (int y = 0; y < height; y++, srcPelRow += srcStride, dstPelRow += dstStride)
     {
-      const Pel *srcPel=srcPelRow;
-      Pel *dstPel=dstPelRow;
+      const Pel *srcPel = srcPelRow;
+      Pel *dstPel = dstPelRow;
       for (int x = 0; x < width; x++, srcPel++, dstPel++)
       {
         const int orgVal = (int) *srcPel;
         double temporalWeightSum = 1.0;
         double newVal = (double) orgVal;
+        if ((y % blockSizeY == 0) && (x % blockSizeX == 0))
+        {
+          for (int i = 0; i < numRefs; i++)
+          {
+            double variance = 0, diffsum = 0;
+            for (int y1 = 0; y1 < blockSizeY - 1; y1++)
+            {
+              for (int x1 = 0; x1 < blockSizeX - 1; x1++)
+              {
+                int pix  = *(srcPel + x1);
+                int pixR = *(srcPel + x1 + 1);
+                int pixD = *(srcPel + x1 + srcStride);
+                int ref  = *(correctedPics[i].bufs[c].buf + ((y + y1) * correctedPics[i].bufs[c].stride + x + x1));
+                int refR = *(correctedPics[i].bufs[c].buf + ((y + y1) * correctedPics[i].bufs[c].stride + x + x1 + 1));
+                int refD = *(correctedPics[i].bufs[c].buf + ((y + y1 + 1) * correctedPics[i].bufs[c].stride + x + x1));
+
+                int diff  = pix  - ref;
+                int diffR = pixR - refR;
+                int diffD = pixD - refD;
+
+                variance += diff * diff;
+                diffsum  += (diffR - diff) * (diffR - diff);
+                diffsum  += (diffD - diff) * (diffD - diff);
+              }
+            }
+            srcFrameInfo[i].mvs.get(x / blockSizeX, y / blockSizeY).noise = (int) round((300 * variance + 50) / (10 * diffsum + 50));
+          }
+        }
+        double minError = 9999999;
+        for (int i = 0; i < numRefs; i++)
+        {
+          minError = std::min(minError, (double) srcFrameInfo[i].mvs.get(x / blockSizeX, y / blockSizeY).error);
+        }
         for (int i = 0; i < numRefs; i++)
         {
-          const Pel *pCorrectedPelPtr=correctedPics[i].bufs[c].buf+(y*correctedPics[i].bufs[c].stride+x);
+          const int error = srcFrameInfo[i].mvs.get(x / blockSizeX, y / blockSizeY).error;
+          const int noise = srcFrameInfo[i].mvs.get(x / blockSizeX, y / blockSizeY).noise;
+          const Pel *pCorrectedPelPtr = correctedPics[i].bufs[c].buf + (y * correctedPics[i].bufs[c].stride + x);
           const int refVal = (int) *pCorrectedPelPtr;
           double diff = (double)(refVal - orgVal);
           diff *= bitDepthDiffWeighting;
           double diffSq = diff * diff;
-          const int index = std::min(1, std::abs(srcFrameInfo[i].origOffset) - 1);
-          const double weight = weightScaling * m_refStrengths[refStrengthRow][index] * exp(-diffSq / (2 * sigmaSq));
+          const int index = std::min(3, std::abs(srcFrameInfo[i].origOffset) - 1);
+          double ww = 1, sw = 1;
+          ww *= (noise < 25) ? 1.0 : 0.6;
+          sw *= (noise < 25) ? 1.0 : 0.8;
+          ww *= (error < 50) ? 1.2 : ((error > 100) ? 0.6 : 1.0);
+          sw *= (error < 50) ? 1.0 : 0.8;
+          ww *= ((minError + 1) / (error + 1));
+          double weight = weightScaling * m_refStrengths[refStrengthRow][index] * ww * exp(-diffSq / (2 * sw * sigmaSq));
           newVal += weight * refVal;
           temporalWeightSum += weight;
         }
         newVal /= temporalWeightSum;
         Pel sampleVal = (Pel)round(newVal);
-        sampleVal=(sampleVal<0?0 : (sampleVal>maxSampleValue ? maxSampleValue : sampleVal));
+        sampleVal = (sampleVal < 0 ? 0 : (sampleVal > maxSampleValue ? maxSampleValue : sampleVal));
         *dstPel = sampleVal;
       }
     }
diff --git a/source/Lib/EncoderLib/EncTemporalFilter.h b/source/Lib/EncoderLib/EncTemporalFilter.h
index b46b265dc..42f2f88c8 100644
--- a/source/Lib/EncoderLib/EncTemporalFilter.h
+++ b/source/Lib/EncoderLib/EncTemporalFilter.h
@@ -3,7 +3,7 @@
 * and contributor rights, including patent rights, and no such rights are
 * granted under this license.
 *
-* Copyright (c) 2010-2020, ITU/ISO/IEC
+* Copyright (c) 2010-2021, ITU/ISO/IEC
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
@@ -51,7 +51,8 @@ struct MotionVector
 {
   int x, y;
   int error;
-  MotionVector() : x(0), y(0), error(INT_LEAST32_MAX) {}
+  int noise;
+  MotionVector() : x(0), y(0), error(INT_LEAST32_MAX), noise(0) {}
   void set(int vectorX, int vectorY, int errorValue) { x = vectorX; y = vectorY; error = errorValue; }
 };
 
@@ -67,21 +68,21 @@ public:
 
   void allocate(int width, int height, const T& value=T())
   {
-    m_width=width;
-    m_height=height;
-    v.resize(std::size_t(m_width*m_height), value);
+    m_width  = width;
+    m_height = height;
+    v.resize(std::size_t(m_width * m_height), value);
   }
 
   T& get(int x, int y)
   {
-    assert(x<m_width && y<m_height);
-    return v[y*m_width+x];
+    assert(x < m_width && y < m_height);
+    return v[y * m_width + x];
   }
 
   const T& get(int x, int y) const
   {
-    assert(x<m_width && y<m_height);
-    return v[y*m_width+x];
+    assert(x < m_width && y < m_height);
+    return v[y * m_width + x];
   }
 };
 
@@ -129,7 +130,7 @@ private:
   static const int m_motionVectorFactor;
   static const int m_padding;
   static const int m_interpolationFilter[16][8];
-  static const double m_refStrengths[3][2];
+  static const double m_refStrengths[3][4];
 
   // Private member variables
   int m_FrameSkip;
@@ -155,7 +156,7 @@ private:
     const Array2D<MotionVector> *previous=0, const int factor = 1, const bool doubleRes = false) const;
   void motionEstimation(Array2D<MotionVector> &mvs, const PelStorage &orgPic, const PelStorage &buffer, const PelStorage &origSubsampled2, const PelStorage &origSubsampled4) const;
 
-  void bilateralFilter(const PelStorage &orgPic, const std::deque<TemporalFilterSourcePicInfo> &srcFrameInfo, PelStorage &newOrgPic, double overallStrength) const;
+  void bilateralFilter(const PelStorage &orgPic, std::deque<TemporalFilterSourcePicInfo> &srcFrameInfo, PelStorage &newOrgPic, double overallStrength) const;
   void applyMotion(const Array2D<MotionVector> &mvs, const PelStorage &input, PelStorage &output) const;
 }; // END CLASS DEFINITION EncTemporalFilter
 
diff --git a/source/Lib/EncoderLib/InterSearch.cpp b/source/Lib/EncoderLib/InterSearch.cpp
index ff9ba841d..039078e9e 100644
--- a/source/Lib/EncoderLib/InterSearch.cpp
+++ b/source/Lib/EncoderLib/InterSearch.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -110,6 +110,9 @@ InterSearch::InterSearch()
 
   setWpScalingDistParam( -1, REF_PIC_LIST_X, nullptr );
   m_affMVList = nullptr;
+#if GDR_ENABLED
+  m_affMVListSolid = nullptr;
+#endif
   m_affMVListSize = 0;
   m_affMVListIdx = 0;
   m_uniMvList = nullptr;
@@ -158,6 +161,14 @@ void InterSearch::destroy()
     delete[] m_affMVList;
     m_affMVList = nullptr;
   }
+#if GDR_ENABLED
+  if (m_affMVListSolid)
+  {
+    delete[] m_affMVListSolid;
+    m_affMVListSolid = nullptr;
+  }
+#endif
+
   m_affMVListIdx = 0;
   m_affMVListSize = 0;
   if (m_uniMvList)
@@ -177,13 +188,6 @@ void InterSearch::setTempBuffers( CodingStructure ****pSplitCS, CodingStructure
   m_pSaveCS  = pSaveCS;
 }
 
-#if ENABLE_SPLIT_PARALLELISM
-void InterSearch::copyState( const InterSearch& other )
-{
-  memcpy( m_aaiAdaptSR, other.m_aaiAdaptSR, sizeof( m_aaiAdaptSR ) );
-}
-#endif
-
 InterSearch::~InterSearch()
 {
   if (m_isInitialized)
@@ -263,7 +267,15 @@ void InterSearch::init( EncCfg*        pcEncCfg,
   m_pTempPel = new Pel[maxCUWidth*maxCUHeight];
   m_affMVListMaxSize = (pcEncCfg->getIntraPeriod() == (uint32_t)-1) ? AFFINE_ME_LIST_SIZE_LD : AFFINE_ME_LIST_SIZE;
   if (!m_affMVList)
+  {
     m_affMVList = new AffineMVInfo[m_affMVListMaxSize];
+#if GDR_ENABLED
+    if (!m_affMVListSolid)
+    {
+      m_affMVListSolid = new AffineMVInfoSolid[m_affMVListMaxSize];
+    }
+#endif
+  }
   m_affMVListIdx = 0;
   m_affMVListSize = 0;
   m_uniMvListMaxSize = 15;
@@ -284,8 +296,15 @@ void InterSearch::resetSavedAffineMotion()
     {
       m_affineMotion.acMvAffine4Para[i][j] = Mv( 0, 0 );
       m_affineMotion.acMvAffine6Para[i][j] = Mv( 0, 0 );
+#if GDR_ENABLED
+      m_affineMotion.acMvAffine4ParaSolid[i][j] = true;
+      m_affineMotion.acMvAffine6ParaSolid[i][j] = true;
+#endif
     }
     m_affineMotion.acMvAffine6Para[i][2] = Mv( 0, 0 );
+#if GDR_ENABLED
+    m_affineMotion.acMvAffine6ParaSolid[i][2] = true;
+#endif
 
     m_affineMotion.affine4ParaRefIdx[i] = -1;
     m_affineMotion.affine6ParaRefIdx[i] = -1;
@@ -298,7 +317,11 @@ void InterSearch::resetSavedAffineMotion()
   m_affineMotion.affine6ParaAvail = false;
 }
 
+#if GDR_ENABLED
+void InterSearch::storeAffineMotion(Mv acAffineMv[2][3], bool acAffineMvSolid[2][3], int16_t affineRefIdx[2], EAffineModel affineType, int bcwIdx)
+#else
 void InterSearch::storeAffineMotion( Mv acAffineMv[2][3], int16_t affineRefIdx[2], EAffineModel affineType, int bcwIdx )
+#endif
 {
   if ( ( bcwIdx == BCW_DEFAULT || !m_affineMotion.affine6ParaAvail ) && affineType == AFFINEMODEL_6PARAM )
   {
@@ -307,6 +330,9 @@ void InterSearch::storeAffineMotion( Mv acAffineMv[2][3], int16_t affineRefIdx[2
       for ( int j = 0; j < 3; j++ )
       {
         m_affineMotion.acMvAffine6Para[i][j] = acAffineMv[i][j];
+#if GDR_ENABLED
+        m_affineMotion.acMvAffine6ParaSolid[i][j] = acAffineMvSolid[i][j];
+#endif
       }
       m_affineMotion.affine6ParaRefIdx[i] = affineRefIdx[i];
     }
@@ -320,6 +346,9 @@ void InterSearch::storeAffineMotion( Mv acAffineMv[2][3], int16_t affineRefIdx[2
       for ( int j = 0; j < 2; j++ )
       {
         m_affineMotion.acMvAffine4Para[i][j] = acAffineMv[i][j];
+#if GDR_ENABLED
+        m_affineMotion.acMvAffine4ParaSolid[i][j] = acAffineMvSolid[i][j];
+#endif
       }
       m_affineMotion.affine4ParaRefIdx[i] = affineRefIdx[i];
     }
@@ -703,21 +732,46 @@ inline void InterSearch::xTZ8PointDiamondSearch( IntTZSearchStruct& rcStruct,
     } // iDist <= 8
   } // iDist == 1
 }
+#if GDR_ENABLED
+Distortion InterSearch::xPatternRefinement(
+  const PredictionUnit& pu,
+  RefPicList eRefPicList,
+  int iRefIdx,
+  const CPelBuf* pcPatternKey,
+  Mv baseRefMv,
+  int iFrac, Mv& rcMvFrac,
+  bool bAllowUseOfHadamard,
+  bool& rbCleanCandExist)
+#else
 
 Distortion InterSearch::xPatternRefinement( const CPelBuf* pcPatternKey,
                                             Mv baseRefMv,
                                             int iFrac, Mv& rcMvFrac,
                                             bool bAllowUseOfHadamard )
+#endif
 {
   Distortion  uiDist;
   Distortion  uiDistBest  = std::numeric_limits<Distortion>::max();
   uint32_t        uiDirecBest = 0;
 
+#if GDR_ENABLED
+  const CodingStructure &cs = *pu.cs;
+  const bool isEncodeGdrClean = cs.sps->getGDREnabledFlag() && cs.pcv->isEncoder && ((cs.picHeader->getInGdrInterval() && cs.isClean(pu.Y().topRight(), CHANNEL_TYPE_LUMA)) || (cs.picHeader->getNumVerVirtualBoundaries() == 0));
+  bool uiDistOk = false;
+  bool uiDistBestOk = false;
+  bool allOk = true;
+#endif
   Pel*  piRefPos;
   int iRefStride = pcPatternKey->width + 1;
   m_pcRdCost->setDistParam( m_cDistParam, *pcPatternKey, m_filteredBlock[0][0][0], iRefStride, m_lumaClpRng.bd, COMPONENT_Y, 0, 1, m_pcEncCfg->getUseHADME() && bAllowUseOfHadamard );
 
   const Mv* pcMvRefine = (iFrac == 2 ? s_acMvRefineH : s_acMvRefineQ);
+#if GDR_ENABLED
+  if (isEncodeGdrClean)
+  {
+    rbCleanCandExist = false;
+  }
+#endif
   for (uint32_t i = 0; i < 9; i++)
   {
     if (m_skipFracME && i > 0)
@@ -747,12 +801,51 @@ Distortion InterSearch::xPatternRefinement( const CPelBuf* pcPatternKey,
     uiDist = m_cDistParam.distFunc( m_cDistParam );
     uiDist += m_pcRdCost->getCostOfVectorWithPredictor( cMvTest.getHor(), cMvTest.getVer(), 0 );
 
+#if GDR_ENABLED
+    allOk = (uiDist < uiDistBest);
+
+    if (isEncodeGdrClean)
+    {
+      Mv motion = cMvTest;
+      MvPrecision curPrec = (iFrac == 2 ? MV_PRECISION_HALF : MV_PRECISION_QUARTER);
+      motion.changePrecision(curPrec, MV_PRECISION_INTERNAL);
+      uiDistOk = cs.isClean(pu.Y().bottomRight(), motion, eRefPicList, iRefIdx);
+
+      if (uiDistOk)
+      {
+        allOk = (uiDistBestOk) ? (uiDist < uiDistBest) : true;
+      }
+      else
+      {
+        allOk = false;
+      }
+    }
+#endif
+
+#if GDR_ENABLED
+    if (allOk)
+#else
     if ( uiDist < uiDistBest )
+#endif
     {
       uiDistBest  = uiDist;
       uiDirecBest = i;
       m_cDistParam.maximumDistortionForEarlyExit = uiDist;
+#if GDR_ENABLED
+      if (isEncodeGdrClean)
+      {
+        uiDistBestOk = uiDistOk;
+        rbCleanCandExist = true;
+      }
+#endif
+    }
+#if GDR_ENABLED
+    if (isEncodeGdrClean)
+    {
+      if (!rbCleanCandExist)
+        uiDistBest = 65535;
     }
+#endif
   }
 
   rcMvFrac = pcMvRefine[uiDirecBest];
@@ -785,7 +878,9 @@ void InterSearch::xIBCSearchMVCandUpdate(Distortion  sad, int x, int y, Distorti
     for (int t = CHROMA_REFINEMENT_CANDIDATES - 1; t >= 0; t--)
     {
       if (sad < sadBestCand[t])
+      {
         j = t;
+      }
     }
 
     for (int k = CHROMA_REFINEMENT_CANDIDATES - 1; k > j; k--)
@@ -835,13 +930,33 @@ int InterSearch::xIBCSearchMVChromaRefine(PredictionUnit& pu,
     }
 
     if ((!cMVCand[cand].getHor()) && (!cMVCand[cand].getVer()))
+    {
       continue;
+    }
 
     if (((int)(cuPelY + cMVCand[cand].getVer() + roiHeight) >= picHeight) || ((cuPelY + cMVCand[cand].getVer()) < 0))
+    {
       continue;
+    }
 
     if (((int)(cuPelX + cMVCand[cand].getHor() + roiWidth) >= picWidth) || ((cuPelX + cMVCand[cand].getHor()) < 0))
+    {
       continue;
+    }
+
+#if GDR_ENABLED
+    CodingStructure &cs = *pu.cs;
+    const bool isEncodeGdrClean = cs.sps->getGDREnabledFlag() && cs.pcv->isEncoder && ((cs.picHeader->getInGdrInterval() && cs.isClean(pu.Y().topRight(), CHANNEL_TYPE_LUMA)) || (cs.picHeader->getNumVerVirtualBoundaries() == 0));
+
+    if (isEncodeGdrClean)
+    {
+      Position curBR(cuPelX + roiWidth + cMVCand[cand].getHor() - 1, cuPelY + roiHeight + cMVCand[cand].getVer() - 1);    // is this correct???
+      if (!cs.isClean(curBR, CHANNEL_TYPE_LUMA))
+      {
+        continue;
+      }
+    }
+#endif
 
     tempSad = sadBestCand[cand];
 
@@ -954,6 +1069,10 @@ void InterSearch::xIntraPatternSearch(PredictionUnit& pu, IntTZSearchStruct&  cS
   Distortion  sadBestCand[CHROMA_REFINEMENT_CANDIDATES];
   Mv      cMVCand[CHROMA_REFINEMENT_CANDIDATES];
 
+#if GDR_ENABLED
+  CodingStructure &cs = *pu.cs;
+  const bool isEncodeGdrClean = cs.sps->getGDREnabledFlag() && cs.pcv->isEncoder && ((cs.picHeader->getInGdrInterval() && cs.isClean(pu.Y().topRight(), CHANNEL_TYPE_LUMA)) || (cs.picHeader->getNumVerVirtualBoundaries() == 0));
+#endif
 
   for (int cand = 0; cand < CHROMA_REFINEMENT_CANDIDATES; cand++)
   {
@@ -992,7 +1111,13 @@ void InterSearch::xIntraPatternSearch(PredictionUnit& pu, IntTZSearchStruct&  cS
         && !((xPred < srLeft) || (xPred > srRight)))
       {
         bool validCand = searchBv(pu, cuPelX, cuPelY, roiWidth, roiHeight, picWidth, picHeight, xPred, yPred, lcuWidth);
-
+#if GDR_ENABLED
+        if (isEncodeGdrClean)
+        {
+          Position BvBR(cuPelX + roiWidth + xPred - 1, cuPelY + roiHeight + yPred - 1);
+          validCand = validCand && cs.isClean(BvBR, CHANNEL_TYPE_LUMA);
+        }
+#endif
         if (validCand)
         {
           sad = m_pcRdCost->getBvCostMultiplePreds(xPred, yPred, pu.cs->sps->getAMVREnabledFlag());
@@ -1016,6 +1141,16 @@ void InterSearch::xIntraPatternSearch(PredictionUnit& pu, IntTZSearchStruct&  cS
       {
         continue;
       }
+#if GDR_ENABLED
+      if (isEncodeGdrClean)
+      {
+        Position BvBR(cuPelX + roiWidth - 1, cuPelY + roiHeight + y - 1);
+        if (!cs.isClean(BvBR, CHANNEL_TYPE_LUMA))
+        {
+          continue;
+        }
+      }
+#endif
 
       sad = m_pcRdCost->getBvCostMultiplePreds(0, y, pu.cs->sps->getAMVREnabledFlag());
       m_cDistParam.cur.buf = piRefSrch + cStruct.iRefStride * y;
@@ -1041,6 +1176,16 @@ void InterSearch::xIntraPatternSearch(PredictionUnit& pu, IntTZSearchStruct&  cS
       {
         continue;
       }
+#if GDR_ENABLED
+      if (isEncodeGdrClean)
+      {
+        Position BvBR(cuPelX + roiWidth + x - 1, cuPelY + roiHeight - 1);
+        if (!cs.isClean(BvBR, CHANNEL_TYPE_LUMA))
+        {
+          continue;
+        }
+      }
+#endif
 
       sad = m_pcRdCost->getBvCostMultiplePreds(x, 0, pu.cs->sps->getAMVREnabledFlag());
       m_cDistParam.cur.buf = piRefSrch + x;
@@ -1081,18 +1226,33 @@ void InterSearch::xIntraPatternSearch(PredictionUnit& pu, IntTZSearchStruct&  cS
       for (int y = std::max(srchRngVerTop, -cuPelY); y <= srchRngVerBottom; y += 2)
       {
         if ((y == 0) || ((int)(cuPelY + y + roiHeight) >= picHeight))
+        {
           continue;
+        }
 
         for (int x = std::max(srchRngHorLeft, -cuPelX); x <= srchRngHorRight; x++)
         {
           if ((x == 0) || ((int)(cuPelX + x + roiWidth) >= picWidth))
+          {
             continue;
+          }
 
           if (!searchBv(pu, cuPelX, cuPelY, roiWidth, roiHeight, picWidth, picHeight, x, y, lcuWidth))
           {
             continue;
           }
 
+#if GDR_ENABLED
+          if (isEncodeGdrClean)
+          {
+            Position BvBR(cuPelX + roiWidth + x - 1, cuPelY + roiHeight + y - 1);
+            if (!cs.isClean(BvBR, CHANNEL_TYPE_LUMA))
+            {
+              continue;
+            }
+          }
+#endif
+
           sad = m_pcRdCost->getBvCostMultiplePreds(x, y, pu.cs->sps->getAMVREnabledFlag());
           m_cDistParam.cur.buf = piRefSrch + cStruct.iRefStride * y + x;
           sad += m_cDistParam.distFunc(m_cDistParam);
@@ -1121,18 +1281,33 @@ void InterSearch::xIntraPatternSearch(PredictionUnit& pu, IntTZSearchStruct&  cS
       for (int y = (std::max(srchRngVerTop, -cuPelY) + 1); y <= srchRngVerBottom; y += 2)
       {
         if ((y == 0) || ((int)(cuPelY + y + roiHeight) >= picHeight))
+        {
           continue;
+        }
 
         for (int x = std::max(srchRngHorLeft, -cuPelX); x <= srchRngHorRight; x += 2)
         {
           if ((x == 0) || ((int)(cuPelX + x + roiWidth) >= picWidth))
+          {
             continue;
+          }
 
           if (!searchBv(pu, cuPelX, cuPelY, roiWidth, roiHeight, picWidth, picHeight, x, y, lcuWidth))
           {
             continue;
           }
 
+#if GDR_ENABLED
+          if (isEncodeGdrClean)
+          {
+            Position BvBR(cuPelX + roiWidth + x - 1, cuPelY + roiHeight + y - 1);
+            if (!cs.isClean(BvBR, CHANNEL_TYPE_LUMA))
+            {
+              continue;
+            }
+          }
+#endif
+
           sad = m_pcRdCost->getBvCostMultiplePreds(x, y, pu.cs->sps->getAMVREnabledFlag());
           m_cDistParam.cur.buf = piRefSrch + cStruct.iRefStride * y + x;
           sad += m_cDistParam.distFunc(m_cDistParam);
@@ -1175,20 +1350,32 @@ void InterSearch::xIntraPatternSearch(PredictionUnit& pu, IntTZSearchStruct&  cS
       for (int y = (std::max(srchRngVerTop, -cuPelY) + 1); y <= srchRngVerBottom; y += 2)
       {
         if ((y == 0) || ((int)(cuPelY + y + roiHeight) >= picHeight))
+        {
           continue;
-
-
+        }
 
         for (int x = (std::max(srchRngHorLeft, -cuPelX) + 1); x <= srchRngHorRight; x += 2)
         {
 
           if ((x == 0) || ((int)(cuPelX + x + roiWidth) >= picWidth))
+          {
             continue;
+          }
 
           if (!searchBv(pu, cuPelX, cuPelY, roiWidth, roiHeight, picWidth, picHeight, x, y, lcuWidth))
           {
             continue;
           }
+#if GDR_ENABLED
+          if (isEncodeGdrClean)
+          {
+            Position BvBR(cuPelX + roiWidth + x - 1, cuPelY + roiHeight + y - 1);
+            if (!cs.isClean(BvBR, CHANNEL_TYPE_LUMA))
+            {
+              continue;
+            }
+          }
+#endif
 
           sad = m_pcRdCost->getBvCostMultiplePreds(x, y, pu.cs->sps->getAMVREnabledFlag());
           m_cDistParam.cur.buf = piRefSrch + cStruct.iRefStride * y + x;
@@ -1264,6 +1451,11 @@ void InterSearch::xIBCEstimation(PredictionUnit& pu, PelUnitBuf& origBuf,
   CPelBuf* pcPatternKey = &tmpPattern;
   PelBuf tmpOrgLuma;
 
+#if GDR_ENABLED
+  CodingStructure &cs = *pu.cs;
+  const bool isEncodeGdrClean = cs.sps->getGDREnabledFlag() && cs.pcv->isEncoder && ((cs.picHeader->getInGdrInterval() && cs.isClean(pu.Y().topRight(), CHANNEL_TYPE_LUMA)) || (cs.picHeader->getNumVerVirtualBoundaries() == 0));
+#endif
+
   if ((pu.cs->slice->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag()))
   {
     const CompArea &area = pu.blocks[COMPONENT_Y];
@@ -1306,7 +1498,17 @@ void InterSearch::xIBCEstimation(PredictionUnit& pu, PelUnitBuf& origBuf,
 
       int xBv = bv.hor;
       int yBv = bv.ver;
+#if GDR_ENABLED
+      bool validCand = true;
+      if (isEncodeGdrClean)
+      {
+        Position BvBR(cuPelX + iRoiWidth + xBv - 1, cuPelY + iRoiHeight + yBv - 1);
+        validCand = validCand && cs.isClean(BvBR, CHANNEL_TYPE_LUMA);
+      }
+      if (validCand && searchBv(pu, cuPelX, cuPelY, iRoiWidth, iRoiHeight, iPicWidth, iPicHeight, xBv, yBv, lcuWidth))
+#else
       if (searchBv(pu, cuPelX, cuPelY, iRoiWidth, iRoiHeight, iPicWidth, iPicHeight, xBv, yBv, lcuWidth))
+#endif
       {
         buffered = true;
         Distortion sad = m_pcRdCost->getBvCostMultiplePreds(xBv, yBv, pu.cs->sps->getAMVREnabledFlag());
@@ -1341,7 +1543,17 @@ void InterSearch::xIBCEstimation(PredictionUnit& pu, PelUnitBuf& origBuf,
         int xPred = cMvPredEncOnly[cand].getHor();
         int yPred = cMvPredEncOnly[cand].getVer();
 
+#if GDR_ENABLED
+        bool validCand = true;
+        if (isEncodeGdrClean)
+        {
+          Position BvBR(cuPelX + iRoiWidth + xPred - 1, cuPelY + iRoiHeight + yPred - 1);
+          validCand = cs.isClean(BvBR, CHANNEL_TYPE_LUMA);
+        }
+        if (validCand && searchBv(pu, cuPelX, cuPelY, iRoiWidth, iRoiHeight, iPicWidth, iPicHeight, xPred, yPred, lcuWidth))
+#else
         if (searchBv(pu, cuPelX, cuPelY, iRoiWidth, iRoiHeight, iPicWidth, iPicHeight, xPred, yPred, lcuWidth))
+#endif
         {
           Distortion sad = m_pcRdCost->getBvCostMultiplePreds(xPred, yPred, pu.cs->sps->getAMVREnabledFlag());
           m_cDistParam.cur.buf = cStruct.piRefY + cStruct.iRefStride * yPred + xPred;
@@ -1410,16 +1622,8 @@ void InterSearch::xSetIntraSearchRange(PredictionUnit& pu, int iRoiWidth, int iR
   rcMvSrchRngRB <<= 2;
   bool temp = m_clipMvInSubPic;
   m_clipMvInSubPic = true;
-  xClipMv(rcMvSrchRngLT, pu.cu->lumaPos(),
-         pu.cu->lumaSize(),
-         sps
-      , *pu.cs->pps
-  );
-  xClipMv(rcMvSrchRngRB, pu.cu->lumaPos(),
-         pu.cu->lumaSize(),
-         sps
-      , *pu.cs->pps
-  );
+  xClipMv(rcMvSrchRngLT, pu.cu->lumaPos(), pu.cu->lumaSize(), sps, *pu.cs->pps);
+  xClipMv(rcMvSrchRngRB, pu.cu->lumaPos(), pu.cu->lumaSize(), sps, *pu.cs->pps);
   m_clipMvInSubPic = temp;
   rcMvSrchRngLT >>= 2;
   rcMvSrchRngRB >>= 2;
@@ -1438,6 +1642,20 @@ bool InterSearch::predIBCSearch(CodingUnit& cu, Partitioner& partitioner, const
     m_maxCompIDToPred = MAX_NUM_COMPONENT;
 
     CHECK(pu.cu != &cu, "PU is contained in another CU");
+#if GDR_ENABLED
+    CodingStructure &cs = *pu.cs;
+    const bool isEncodeGdrClean = cs.sps->getGDREnabledFlag() && cs.pcv->isEncoder && ((cs.picHeader->getInGdrInterval() && cs.isClean(pu.Y().topRight(), CHANNEL_TYPE_LUMA)) || (cs.picHeader->getNumVerVirtualBoundaries() == 0));
+#endif
+
+#if GDR_ENABLED
+    if (isEncodeGdrClean)
+    {
+      pu.mvSolid[0] = false;
+      pu.mvSolid[1] = false;
+      pu.mvValid[0] = false;
+      pu.mvValid[1] = false;
+    }
+#endif
     //////////////////////////////////////////////////////////
     /// ibc search
     pu.cu->imv = 2;
@@ -1498,10 +1716,13 @@ bool InterSearch::predIBCSearch(CodingUnit& cu, Partitioner& partitioner, const
         bvpIdxBest = bvpIdxTemp;
 
         if (cu.cs->sps->getAMVREnabledFlag() && cMv != cMvPred[bvpIdxTemp])
+        {
           pu.cu->imv = 1; // set as full-pel
+        }
         else
+        {
           pu.cu->imv = 0; // set as fractional-pel
-
+        }
       }
 
       unsigned int bitsBVPQP = MAX_UINT;
@@ -1526,9 +1747,10 @@ bool InterSearch::predIBCSearch(CodingUnit& cu, Partitioner& partitioner, const
         bvpIdxBest = bvpIdxTemp;
 
         if (cu.cs->sps->getAMVREnabledFlag())
+        {
           pu.cu->imv = 2; // set as quad-pel
+        }
       }
-
     }
 
     pu.bv = cMv; // bv is always at integer accuracy
@@ -1538,16 +1760,26 @@ bool InterSearch::predIBCSearch(CodingUnit& cu, Partitioner& partitioner, const
     pu.mvpIdx[REF_PIC_LIST_0] = bvpIdxBest;
 
     if(pu.cu->imv == 2 && cMv != amvpInfo4Pel.mvCand[bvpIdxBest])
+    {
       pu.mvd[REF_PIC_LIST_0] = cMv - amvpInfo4Pel.mvCand[bvpIdxBest];
+    }
     else
+    {
       pu.mvd[REF_PIC_LIST_0] = cMv - amvpInfo.mvCand[bvpIdxBest];
+    }
 
     if (pu.mvd[REF_PIC_LIST_0] == Mv(0, 0))
+    {
       pu.cu->imv = 0;
+    }
     if (pu.cu->imv == 2)
+    {
       assert((cMv.getHor() % 16 == 0) && (cMv.getVer() % 16 == 0));
+    }
     if (cu.cs->sps->getAMVREnabledFlag())
+    {
       assert(pu.cu->imv>0 || pu.mvd[REF_PIC_LIST_0] == Mv());
+    }
 
     pu.refIdx[REF_PIC_LIST_0] = MAX_NUM_REF;
 
@@ -1561,6 +1793,10 @@ void InterSearch::xxIBCHashSearch(PredictionUnit& pu, Mv* mvPred, int numMvPred,
   mv.setZero();
   m_pcRdCost->setCostScale(0);
 
+#if GDR_ENABLED
+  CodingStructure &cs = *pu.cs;
+  const bool isEncodeGdrClean = cs.sps->getGDREnabledFlag() && cs.pcv->isEncoder && ((cs.picHeader->getInGdrInterval() && cs.isClean(pu.Y().topRight(), CHANNEL_TYPE_LUMA)) || (cs.picHeader->getNumVerVirtualBoundaries() == 0));
+#endif
   std::vector<Position> candPos;
   if (ibcHashMap.ibcHashMatch(pu.Y(), candPos, *pu.cs, m_pcEncCfg->getIBCHashSearchMaxCand(), m_pcEncCfg->getIBCHashSearchRange4SmallBlk()))
   {
@@ -1587,6 +1823,13 @@ void InterSearch::xxIBCHashSearch(PredictionUnit& pu, Mv* mvPred, int numMvPred,
         {
           continue;
         }
+#if GDR_ENABLED
+        Position BvBR(cuPelX + roiWidth + candMv.getHor() - 1, cuPelY + roiHeight + candMv.getVer() - 1);
+        if (isEncodeGdrClean && !cs.isClean(BvBR, CHANNEL_TYPE_LUMA))
+        {
+          continue;
+        }
+#endif
 
         for (int n = 0; n < numMvPred; n++)
         {
@@ -1790,6 +2033,11 @@ bool InterSearch::xRectHashInterEstimation(PredictionUnit& pu, RefPicList& bestR
   unsigned int* hashValue1s = new unsigned int[baseNum];
   unsigned int* hashValue2s = new unsigned int[baseNum];
 
+#if GDR_ENABLED
+  CodingStructure &cs = *pu.cs;
+  const bool isEncodeGdrClean = cs.sps->getGDREnabledFlag() && cs.pcv->isEncoder && ((cs.picHeader->getInGdrInterval() && cs.isClean(pu.Y().topRight(), CHANNEL_TYPE_LUMA)) || (cs.picHeader->getNumVerVirtualBoundaries() == 0));
+#endif
+
   for (int k = 0; k < baseNum; k++)
   {
     if (isHorizontal)
@@ -1871,6 +2119,26 @@ bool InterSearch::xRectHashInterEstimation(PredictionUnit& pu, RefPicList& bestR
         AMVPInfo currAMVPInfoPel;
         AMVPInfo currAMVPInfo4Pel;
         AMVPInfo currAMVPInfoQPel;
+
+#if GDR_ENABLED
+        if (isEncodeGdrClean)
+        {
+          currAMVPInfoPel.allCandSolidInAbove = true;
+          currAMVPInfo4Pel.allCandSolidInAbove = true;
+          currAMVPInfoQPel.allCandSolidInAbove = true;
+
+          for (int i = 0; i < AMVP_MAX_NUM_CANDS_MEM; i++)
+          {
+            currAMVPInfoPel.mvSolid[i] = true;
+            currAMVPInfoPel.mvValid[i] = true;
+            currAMVPInfo4Pel.mvSolid[i] = true;
+            currAMVPInfo4Pel.mvValid[i] = true;
+            currAMVPInfoQPel.mvSolid[i] = true;
+            currAMVPInfoQPel.mvValid[i] = true;
+          }
+        }
+#endif
+
         pu.cu->imv = 2;
         PU::fillMvpCand(pu, eRefPicList, refIdx, currAMVPInfo4Pel);
         pu.cu->imv = 1;
@@ -1902,6 +2170,25 @@ bool InterSearch::xRectHashInterEstimation(PredictionUnit& pu, RefPicList& bestR
           m_hashMVStoreds[eRefPicList][refIdx][countMV++] = cMv;
           cMv.changePrecision(MV_PRECISION_INT, MV_PRECISION_QUARTER);
 
+#if GDR_ENABLED
+          bool allOk = true;
+          bool anyCandOk = false;
+          bool Valid = true;
+          if (isEncodeGdrClean)
+          {
+            Mv cMv16 = cMv;
+            cMv16.changePrecision(MV_PRECISION_QUARTER, MV_PRECISION_INTERNAL);
+            const Position bottomRight = pu.Y().bottomRight();
+            Valid = cs.isClean(bottomRight, cMv16, eRefPicList, refIdx);
+          }
+#endif
+
+#if GDR_ENABLED
+          if (!Valid)
+          {
+            continue;
+          }
+#endif
           for (int mvpIdxTemp = 0; mvpIdxTemp < 2; mvpIdxTemp++)
           {
             Mv cMvPredPel = currAMVPInfoQPel.mvCand[mvpIdxTemp];
@@ -1909,7 +2196,21 @@ bool InterSearch::xRectHashInterEstimation(PredictionUnit& pu, RefPicList& bestR
 
             unsigned int tempMVPbits = m_pcRdCost->getBitsOfVectorWithPredictor(cMv.getHor(), cMv.getVer(), 0);
 
+#if GDR_ENABLED
+            allOk = (tempMVPbits < curMVPbits);
+            if (isEncodeGdrClean)
+            {
+              bool isSolid = currAMVPInfoQPel.mvSolid[mvpIdxTemp];
+              allOk = allOk && isSolid;
+              if (allOk) anyCandOk = true;
+            }
+#endif
+
+#if GDR_ENABLED
+            if (allOk)
+#else
             if (tempMVPbits < curMVPbits)
+#endif
             {
               curMVPbits = tempMVPbits;
               curMVPIdx = mvpIdxTemp;
@@ -1922,7 +2223,24 @@ bool InterSearch::xRectHashInterEstimation(PredictionUnit& pu, RefPicList& bestR
               Mv mvPred1Pel = currAMVPInfoPel.mvCand[mvpIdxTemp];
               m_pcRdCost->setPredictor(mvPred1Pel);
               bitsMVP1Pel = m_pcRdCost->getBitsOfVectorWithPredictor(cMv.getHor(), cMv.getVer(), 2);
+#if GDR_ENABLED
+              allOk = (bitsMVP1Pel < curMVPbits);
+              if (isEncodeGdrClean)
+              {
+                bool isSolid = currAMVPInfoPel.mvSolid[mvpIdxTemp];
+                allOk = allOk && isSolid;
+                if (allOk)
+                {
+                  anyCandOk = true;
+                }
+              }
+#endif
+
+#if GDR_ENABLED
+              if (allOk)
+#else
               if (bitsMVP1Pel < curMVPbits)
+#endif
               {
                 curMVPbits = bitsMVP1Pel;
                 curMVPIdx = mvpIdxTemp;
@@ -1935,7 +2253,24 @@ bool InterSearch::xRectHashInterEstimation(PredictionUnit& pu, RefPicList& bestR
                 Mv mvPred4Pel = currAMVPInfo4Pel.mvCand[mvpIdxTemp];
                 m_pcRdCost->setPredictor(mvPred4Pel);
                 bitsMVP4Pel = m_pcRdCost->getBitsOfVectorWithPredictor(cMv.getHor(), cMv.getVer(), 4);
+#if GDR_ENABLED
+                allOk = (bitsMVP4Pel < curMVPbits);
+                if (isEncodeGdrClean)
+                {
+                  bool isSolid = currAMVPInfo4Pel.mvSolid[mvpIdxTemp];
+                  allOk = allOk && isSolid;
+                  if (allOk)
+                  {
+                    anyCandOk = true;
+                  }
+                }
+#endif
+
+#if GDR_ENABLED
+                if (allOk)
+#else
                 if (bitsMVP4Pel < curMVPbits)
+#endif
                 {
                   curMVPbits = bitsMVP4Pel;
                   curMVPIdx = mvpIdxTemp;
@@ -1944,6 +2279,14 @@ bool InterSearch::xRectHashInterEstimation(PredictionUnit& pu, RefPicList& bestR
               }
             }
           }
+
+#if GDR_ENABLED
+          if (isEncodeGdrClean && !anyCandOk)
+          {
+            continue;
+          }
+#endif
+
           curMVPbits += bitsOnRefIdx;
 
           m_cDistParam.cur.buf = refBufStart + (*it).y*refStride + (*it).x;
@@ -2014,6 +2357,10 @@ bool InterSearch::xHashInterEstimation(PredictionUnit& pu, RefPicList& bestRefPi
     return false;
   }
 
+#if GDR_ENABLED
+  CodingStructure &cs = *pu.cs;
+  const bool isEncodeGdrClean = cs.sps->getGDREnabledFlag() && cs.pcv->isEncoder && ((cs.picHeader->getInGdrInterval() && cs.isClean(pu.Y().topRight(), CHANNEL_TYPE_LUMA)) || (cs.picHeader->getNumVerVirtualBoundaries() == 0));
+#endif
   BlockHash currBlockHash;
   currBlockHash.x = xPos;
   currBlockHash.y = yPos;
@@ -2068,11 +2415,45 @@ bool InterSearch::xHashInterEstimation(PredictionUnit& pu, RefPicList& bestRefPi
         }
         AMVPInfo currAMVPInfoPel;
         AMVPInfo currAMVPInfo4Pel;
+#if GDR_ENABLED
+        if (isEncodeGdrClean)
+        {
+          currAMVPInfo4Pel.allCandSolidInAbove = true;
+          for (int i = 0; i < AMVP_MAX_NUM_CANDS_MEM; i++)
+          {
+            currAMVPInfo4Pel.mvSolid[i] = true;
+            currAMVPInfo4Pel.mvValid[i] = true;
+          }
+        }
+#endif
         pu.cu->imv = 2;
         PU::fillMvpCand(pu, eRefPicList, refIdx, currAMVPInfo4Pel);
+
+#if GDR_ENABLED
+        if (isEncodeGdrClean)
+        {
+          currAMVPInfoPel.allCandSolidInAbove = true;
+          for (int i = 0; i < AMVP_MAX_NUM_CANDS_MEM; i++)
+          {
+            currAMVPInfoPel.mvSolid[i] = true;
+            currAMVPInfoPel.mvValid[i] = true;
+          }
+        }
+#endif
         pu.cu->imv = 1;
         PU::fillMvpCand(pu, eRefPicList, refIdx, currAMVPInfoPel);
         AMVPInfo currAMVPInfoQPel;
+#if GDR_ENABLED
+        if (isEncodeGdrClean)
+        {
+          currAMVPInfoQPel.allCandSolidInAbove = true;
+          for (int i = 0; i < AMVP_MAX_NUM_CANDS_MEM; i++)
+          {
+            currAMVPInfoQPel.mvSolid[i] = true;
+            currAMVPInfoQPel.mvValid[i] = true;
+          }
+        }
+#endif
         pu.cu->imv = 0;
         PU::fillMvpCand(pu, eRefPicList, refIdx, currAMVPInfoQPel);
         CHECK(currAMVPInfoPel.numCand <= 1, "Wrong")
@@ -2102,6 +2483,27 @@ bool InterSearch::xHashInterEstimation(PredictionUnit& pu, RefPicList& bestRefPi
           m_hashMVStoreds[eRefPicList][refIdx][countMV++] = cMv;
           cMv.changePrecision(MV_PRECISION_INT, MV_PRECISION_QUARTER);
 
+#if GDR_ENABLED
+          bool Valid = true;
+          bool allOk = true;
+          bool anyCandOk = false;
+
+          if (isEncodeGdrClean)
+          {
+            Mv cMv16 = cMv;
+            cMv16.changePrecision(MV_PRECISION_QUARTER, MV_PRECISION_INTERNAL);
+            const Position bottomRight = pu.Y().bottomRight();
+            Valid = cs.isClean(bottomRight, cMv16, eRefPicList, refIdx);
+          }
+#endif
+
+#if GDR_ENABLED
+          if (!Valid)
+          {
+            continue;
+          }
+#endif
+
           for (int mvpIdxTemp = 0; mvpIdxTemp < 2; mvpIdxTemp++)
           {
             Mv cMvPredPel = currAMVPInfoQPel.mvCand[mvpIdxTemp];
@@ -2109,7 +2511,21 @@ bool InterSearch::xHashInterEstimation(PredictionUnit& pu, RefPicList& bestRefPi
 
             unsigned int tempMVPbits = m_pcRdCost->getBitsOfVectorWithPredictor(cMv.getHor(), cMv.getVer(), 0);
 
+#if GDR_ENABLED
+            allOk = (tempMVPbits < curMVPbits);
+            if (isEncodeGdrClean)
+            {
+              bool isSolid = currAMVPInfoQPel.mvSolid[mvpIdxTemp];
+              allOk = allOk && isSolid;
+              if (allOk) anyCandOk = true;
+            }
+#endif
+
+#if GDR_ENABLED
+            if (allOk)
+#else
             if (tempMVPbits < curMVPbits)
+#endif
             {
               curMVPbits = tempMVPbits;
               curMVPIdx = mvpIdxTemp;
@@ -2122,7 +2538,21 @@ bool InterSearch::xHashInterEstimation(PredictionUnit& pu, RefPicList& bestRefPi
               Mv mvPred1Pel = currAMVPInfoPel.mvCand[mvpIdxTemp];
               m_pcRdCost->setPredictor(mvPred1Pel);
               bitsMVP1Pel = m_pcRdCost->getBitsOfVectorWithPredictor(cMv.getHor(), cMv.getVer(), 2);
+#if GDR_ENABLED
+              allOk = (bitsMVP1Pel < curMVPbits);
+              if (isEncodeGdrClean)
+              {
+                bool isSolid = currAMVPInfoPel.mvSolid[mvpIdxTemp];
+                allOk = allOk && isSolid;
+                if (allOk) anyCandOk = true;
+              }
+#endif
+
+#if GDR_ENABLED
+              if (allOk)
+#else
               if (bitsMVP1Pel < curMVPbits)
+#endif
               {
                 curMVPbits = bitsMVP1Pel;
                 curMVPIdx = mvpIdxTemp;
@@ -2135,7 +2565,22 @@ bool InterSearch::xHashInterEstimation(PredictionUnit& pu, RefPicList& bestRefPi
                 Mv mvPred4Pel = currAMVPInfo4Pel.mvCand[mvpIdxTemp];
                 m_pcRdCost->setPredictor(mvPred4Pel);
                 bitsMVP4Pel = m_pcRdCost->getBitsOfVectorWithPredictor(cMv.getHor(), cMv.getVer(), 4);
+
+#if GDR_ENABLED
+                allOk = (bitsMVP4Pel < curMVPbits);
+                if (isEncodeGdrClean)
+                {
+                  bool isSolid = currAMVPInfo4Pel.mvSolid[mvpIdxTemp];
+                  allOk = allOk && isSolid;
+                  if (allOk) anyCandOk = true;
+                }
+#endif
+
+#if GDR_ENABLED
+                if (allOk)
+#else
                 if (bitsMVP4Pel < curMVPbits)
+#endif
                 {
                   curMVPbits = bitsMVP4Pel;
                   curMVPIdx = mvpIdxTemp;
@@ -2145,6 +2590,13 @@ bool InterSearch::xHashInterEstimation(PredictionUnit& pu, RefPicList& bestRefPi
             }
           }
 
+#if GDR_ENABLED
+          if (isEncodeGdrClean && !anyCandOk)
+          {
+            continue;
+          }
+#endif
+
           curMVPbits += bitsOnRefIdx;
 
           m_cDistParam.cur.buf = refBufStart + (*it).y*refStride + (*it).x;
@@ -2266,6 +2718,37 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner)
   int          aaiMvpIdx[2][33];
   int          aaiMvpNum[2][33];
 
+#if GDR_ENABLED
+  bool         cMvSolid[2];
+  bool         cMvValid[2];
+  bool         cMvBiSolid[2];
+  bool         cMvBiValid[2];
+
+  bool         cMvPredSolid[2][33];
+  bool         cMvPredBiSolid[2][33];
+
+  bool         cMvTempSolid[2][33];
+  bool         cMvTempValid[2][33];
+
+  bool         cMvHevcTempSolid[2][33];
+  bool         cMvHevcTempValid[2][33];
+
+  bool         allOk;
+  bool         bestBiPDistOk;
+  bool         biPDistTempOk;
+  bool         uiCostTempOk;
+  bool         uiCostTempL0Ok[MAX_NUM_REF];
+
+  bool         uiHevcCostOk;
+  bool         uiAffineCostOk;
+  bool         uiAffine6CostOk;
+  bool         uiCostOk[2];
+  bool         uiCostBiOk;
+  bool         costValidList1Ok;
+
+  bool         bCleanCandExist;
+#endif
+
   AMVPInfo     aacAMVPInfo[2][33];
 
   int          iRefIdx[2]={0,0}; //If un-initialized, may cause SEGV in bi-directional prediction iterative stage.
@@ -2309,6 +2792,60 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner)
     checkNonAffine = m_affineMotion.hevcCost[1] < m_affineMotion.hevcCost[0] * 1.06f;
   }
 
+#if GDR_ENABLED
+  const bool isEncodeGdrClean = cs.sps->getGDREnabledFlag() && cs.pcv->isEncoder && ((cs.picHeader->getInGdrInterval() && cs.isClean(pu.Y().topRight(), CHANNEL_TYPE_LUMA)) || (cs.picHeader->getNumVerVirtualBoundaries() == 0));
+  const bool init_value = true;
+#endif
+
+  amvp[0].numCand = 0;
+  amvp[1].numCand = 0;
+  memset(aacAMVPInfo, 0, sizeof(aacAMVPInfo));
+
+#if GDR_ENABLED
+  if (isEncodeGdrClean)
+  {
+    biPDistTempOk = init_value;
+    bestBiPDistOk = init_value;
+    uiCostTempOk = init_value;
+
+    uiHevcCostOk = init_value;
+    uiAffineCostOk = init_value;
+    uiAffine6CostOk = init_value;
+    memset(uiCostOk, init_value, sizeof(uiCostOk));
+    uiCostBiOk = init_value;
+    uiCostTempOk = init_value;
+    costValidList1Ok = init_value;
+
+    memset(cMvSolid, init_value, sizeof(cMvSolid));
+    memset(cMvValid, init_value, sizeof(cMvValid));
+    memset(cMvBiSolid, !init_value, sizeof(cMvBiSolid));
+    memset(cMvBiValid, !init_value, sizeof(cMvBiValid));
+
+    memset(cMvPredSolid, init_value, sizeof(cMvPredSolid));
+    memset(cMvPredBiSolid, init_value, sizeof(cMvPredBiSolid));
+
+    memset(cMvTempSolid, init_value, sizeof(cMvTempSolid));
+    memset(cMvTempValid, init_value, sizeof(cMvTempValid));
+    memset(cMvHevcTempSolid, init_value, sizeof(cMvHevcTempSolid));
+    memset(cMvHevcTempValid, init_value, sizeof(cMvHevcTempValid));
+
+
+    memset(pu.mvSolid, init_value, sizeof(pu.mvSolid));
+    memset(pu.mvValid, init_value, sizeof(pu.mvValid));
+
+    memset(pu.mvAffiSolid, init_value, sizeof(pu.mvAffiSolid));
+    memset(pu.mvAffiValid, init_value, sizeof(pu.mvAffiValid));
+
+    memset(pu.mvpSolid, init_value, sizeof(pu.mvpSolid));
+    memset(pu.mvpType, init_value, sizeof(pu.mvpType));
+
+    pu.mvpPos[0] = Position(0, 0);
+    pu.mvpPos[1] = Position(0, 0);
+
+    bCleanCandExist = false;
+  }
+#endif
+
   {
     if (pu.cu->cs->bestParent != nullptr && pu.cu->cs->bestParent->getCU(CHANNEL_TYPE_LUMA) != nullptr && pu.cu->cs->bestParent->getCU(CHANNEL_TYPE_LUMA)->affine == false)
     {
@@ -2334,6 +2871,15 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner)
     Distortion   uiCostBi  =   std::numeric_limits<Distortion>::max();
     Distortion   uiCostTemp;
 
+#if GDR_ENABLED
+    memset(uiCostTempL0Ok, init_value, sizeof(uiCostTempL0Ok));
+
+    bool mvValidList1Solid = init_value;
+    bool mvValidList1Valid = init_value;
+    uiHevcCostOk = false;
+    uiAffineCostOk = false;
+#endif
+
     uint32_t         uiBits[3];
     uint32_t         uiBitsTemp;
     Distortion   bestBiPDist = std::numeric_limits<Distortion>::max();
@@ -2378,12 +2924,48 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner)
 
           aaiMvpIdx[iRefList][iRefIdxTemp] = pu.mvpIdx[eRefPicList];
           aaiMvpNum[iRefList][iRefIdxTemp] = pu.mvpNum[eRefPicList];
+#if GDR_ENABLED
+          if (isEncodeGdrClean)
+          {
+            biPDistTempOk = true;
+            biPDistTempOk = amvp[eRefPicList].mvSolid[aaiMvpIdx[iRefList][iRefIdxTemp]];
+            cMvPredSolid[iRefList][iRefIdxTemp] = biPDistTempOk;
+            cMvTempSolid[iRefList][iRefIdxTemp] = biPDistTempOk;
+            cMvTempValid[iRefList][iRefIdxTemp] = cs.isClean(pu.Y().bottomRight(), cMvTemp[iRefList][iRefIdxTemp], (RefPicList)iRefList, iRefIdxTemp);
+          }
+#endif
 
+#if GDR_ENABLED
+          allOk = (cs.picHeader->getMvdL1ZeroFlag() && iRefList == 1 && biPDistTemp < bestBiPDist);
+
+          if (isEncodeGdrClean)
+          {
+            if (biPDistTempOk)
+            {
+              allOk = (bestBiPDistOk) ? (cs.picHeader->getMvdL1ZeroFlag() && iRefList == 1 && biPDistTemp < bestBiPDist) : true;
+            }
+            else
+            {
+              allOk = false;
+            }
+          }
+#endif
+
+#if GDR_ENABLED
+          if (allOk)
+#else
           if(cs.picHeader->getMvdL1ZeroFlag() && iRefList==1 && biPDistTemp < bestBiPDist)
+#endif
           {
             bestBiPDist = biPDistTemp;
             bestBiPMvpL1 = aaiMvpIdx[iRefList][iRefIdxTemp];
             bestBiPRefIdxL1 = iRefIdxTemp;
+#if GDR_ENABLED
+            if (isEncodeGdrClean)
+            {
+              bestBiPDistOk = biPDistTempOk;
+            }
+#endif
           }
 
           uiBitsTemp += m_auiMVPIdxCost[aaiMvpIdx[iRefList][iRefIdxTemp]][AMVP_MAX_NUM_CANDS];
@@ -2393,8 +2975,21 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner)
             if ( cs.slice->getList1IdxToList0Idx( iRefIdxTemp ) >= 0 )
             {
               cMvTemp[1][iRefIdxTemp] = cMvTemp[0][cs.slice->getList1IdxToList0Idx( iRefIdxTemp )];
+#if GDR_ENABLED
+              if (isEncodeGdrClean)
+              {
+                cMvTempSolid[1][iRefIdxTemp] = cMvTempSolid[1][cs.slice->getList1IdxToList0Idx(iRefIdxTemp)];
+                cMvTempValid[1][iRefIdxTemp] = cs.isClean(pu.Y().bottomRight(), cMvTemp[1][iRefIdxTemp], (RefPicList)1, cs.slice->getList1IdxToList0Idx(iRefIdxTemp));
+              }
+#endif
               uiCostTemp = uiCostTempL0[cs.slice->getList1IdxToList0Idx( iRefIdxTemp )];
               /*first subtract the bit-rate part of the cost of the other list*/
+#if GDR_ENABLED
+              if (isEncodeGdrClean)
+              {
+                uiCostTempOk = uiCostTempL0Ok[cs.slice->getList1IdxToList0Idx(iRefIdxTemp)];
+              }
+#endif
               uiCostTemp -= m_pcRdCost->getCost( uiBitsTempL0[cs.slice->getList1IdxToList0Idx( iRefIdxTemp )] );
               /*correct the bit-rate part of the current ref*/
               m_pcRdCost->setPredictor  ( cMvPred[iRefList][iRefIdxTemp] );
@@ -2404,28 +2999,131 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner)
             }
             else
             {
+#if GDR_ENABLED
+              bCleanCandExist = false;
+              xMotionEstimation(pu, origBuf, eRefPicList, cMvPred[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], cMvTempSolid[iRefList][iRefIdxTemp], aaiMvpIdx[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp, amvp[eRefPicList], bCleanCandExist);
+#else
               xMotionEstimation( pu, origBuf, eRefPicList, cMvPred[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], aaiMvpIdx[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp, amvp[eRefPicList] );
+#endif
+
+#if GDR_ENABLED
+              if (isEncodeGdrClean)
+              {
+                int mvp_idx = aaiMvpIdx[iRefList][iRefIdxTemp];
+                cMvPredSolid[iRefList][iRefIdxTemp] = amvp[eRefPicList].mvSolid[mvp_idx];
+                cMvTempSolid[iRefList][iRefIdxTemp] = amvp[eRefPicList].mvSolid[mvp_idx];
+                cMvTempValid[iRefList][iRefIdxTemp] = cs.isClean(pu.Y().bottomRight(), cMvTemp[iRefList][iRefIdxTemp], (RefPicList)iRefList, iRefIdxTemp);
+
+                if (cMvTempValid[iRefList][iRefIdxTemp])
+                {
+                  cMvTempValid[iRefList][iRefIdxTemp] = cMvTempSolid[iRefList][iRefIdxTemp];
+                }
+
+                uiCostTempOk = bCleanCandExist;
+                uiCostTempOk = uiCostTempOk && cMvPredSolid[iRefList][iRefIdxTemp];
+                uiCostTempOk = uiCostTempOk && cMvTempSolid[iRefList][iRefIdxTemp];
+                uiCostTempOk = uiCostTempOk && cMvTempValid[iRefList][iRefIdxTemp];
+              }
+#endif
             }
           }
           else
           {
+#if GDR_ENABLED
+            bCleanCandExist = false;
+            xMotionEstimation(pu, origBuf, eRefPicList, cMvPred[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], cMvTempSolid[iRefList][iRefIdxTemp], aaiMvpIdx[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp, amvp[eRefPicList], bCleanCandExist);
+#else
             xMotionEstimation( pu, origBuf, eRefPicList, cMvPred[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], aaiMvpIdx[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp, amvp[eRefPicList] );
+#endif
+
+#if GDR_ENABLED
+            if (isEncodeGdrClean)
+            {
+              int mvp_idx = aaiMvpIdx[iRefList][iRefIdxTemp];
+              cMvPredSolid[iRefList][iRefIdxTemp] = amvp[eRefPicList].mvSolid[mvp_idx];
+              cMvTempSolid[iRefList][iRefIdxTemp] = amvp[eRefPicList].mvSolid[mvp_idx];
+              cMvTempValid[iRefList][iRefIdxTemp] = cs.isClean(pu.Y().bottomRight(), cMvTemp[iRefList][iRefIdxTemp], (RefPicList)iRefList, iRefIdxTemp);
+              if (cMvTempValid[iRefList][iRefIdxTemp])
+              {
+                cMvTempValid[iRefList][iRefIdxTemp] = cMvTempSolid[iRefList][iRefIdxTemp];
+              }
+
+              uiCostTempOk = bCleanCandExist;
+              uiCostTempOk = uiCostTempOk && cMvPredSolid[iRefList][iRefIdxTemp];
+              uiCostTempOk = uiCostTempOk && cMvTempSolid[iRefList][iRefIdxTemp];
+              uiCostTempOk = uiCostTempOk && cMvTempValid[iRefList][iRefIdxTemp];
+            }
+#endif
           }
           if( cu.cs->sps->getUseBcw() && cu.BcwIdx == BCW_DEFAULT && cu.cs->slice->isInterB() )
           {
             const bool checkIdentical = true;
             m_uniMotions.setReadMode(checkIdentical, (uint32_t)iRefList, (uint32_t)iRefIdxTemp);
+#if GDR_ENABLED
+            m_uniMotions.copyFrom(cMvTemp[iRefList][iRefIdxTemp], cMvTempSolid[iRefList][iRefIdxTemp], uiCostTemp - m_pcRdCost->getCost(uiBitsTemp), (uint32_t)iRefList, (uint32_t)iRefIdxTemp);
+#else
             m_uniMotions.copyFrom(cMvTemp[iRefList][iRefIdxTemp], uiCostTemp - m_pcRdCost->getCost(uiBitsTemp), (uint32_t)iRefList, (uint32_t)iRefIdxTemp);
+#endif
           }
           xCopyAMVPInfo( &amvp[eRefPicList], &aacAMVPInfo[iRefList][iRefIdxTemp]); // must always be done ( also when AMVP_MODE = AM_NONE )
-          xCheckBestMVP( eRefPicList, cMvTemp[iRefList][iRefIdxTemp], cMvPred[iRefList][iRefIdxTemp], aaiMvpIdx[iRefList][iRefIdxTemp], amvp[eRefPicList], uiBitsTemp, uiCostTemp, pu.cu->imv );
+#if GDR_ENABLED
+          xCheckBestMVP(pu, eRefPicList, cMvTemp[iRefList][iRefIdxTemp], cMvPred[iRefList][iRefIdxTemp], aaiMvpIdx[iRefList][iRefIdxTemp], amvp[eRefPicList], uiBitsTemp, uiCostTemp, pu.cu->imv);
 
+          if (isEncodeGdrClean)
+          {
+            int mvp_idx = aaiMvpIdx[iRefList][iRefIdxTemp];
+
+            cMvPredSolid[iRefList][iRefIdxTemp] = amvp[eRefPicList].mvSolid[mvp_idx];
+            cMvTempSolid[iRefList][iRefIdxTemp] = amvp[eRefPicList].mvSolid[mvp_idx];
+            cMvTempValid[iRefList][iRefIdxTemp] = cs.isClean(pu.Y().bottomRight(), cMvTemp[iRefList][iRefIdxTemp], (RefPicList)iRefList, iRefIdxTemp);
+            if (cMvTempValid[iRefList][iRefIdxTemp])
+            {
+              cMvTempValid[iRefList][iRefIdxTemp] = cMvTempSolid[iRefList][iRefIdxTemp];
+            }
+
+            uiCostTempOk = true;
+            uiCostTempOk = uiCostTempOk && cMvPredSolid[iRefList][iRefIdxTemp];
+            uiCostTempOk = uiCostTempOk && cMvTempSolid[iRefList][iRefIdxTemp];
+            uiCostTempOk = uiCostTempOk && cMvTempValid[iRefList][iRefIdxTemp];
+          }
+#else
+          xCheckBestMVP( eRefPicList, cMvTemp[iRefList][iRefIdxTemp], cMvPred[iRefList][iRefIdxTemp], aaiMvpIdx[iRefList][iRefIdxTemp], amvp[eRefPicList], uiBitsTemp, uiCostTemp, pu.cu->imv );
+#endif
           if ( iRefList == 0 )
           {
             uiCostTempL0[iRefIdxTemp] = uiCostTemp;
             uiBitsTempL0[iRefIdxTemp] = uiBitsTemp;
           }
+#if GDR_ENABLED
+          if (isEncodeGdrClean)
+          {
+            uiCostTempL0Ok[iRefIdxTemp] = uiCostTempOk;
+          }
+#endif
+
+#if GDR_ENABLED
+          allOk = (uiCostTemp < uiCost[iRefList]);
+          if (isEncodeGdrClean)
+          {
+            if (uiCostTempOk)
+            {
+              allOk = (uiCostOk[iRefList]) ? (uiCostTemp < uiCost[iRefList]) : true;
+            }
+            else
+            {
+              allOk = false;
+            }
+
+            allOk = allOk && bCleanCandExist;
+          }
+#endif
+
+
+#if GDR_ENABLED
+          if (allOk)
+#else
           if ( uiCostTemp < uiCost[iRefList] )
+#endif
           {
             uiCost[iRefList] = uiCostTemp;
             uiBits[iRefList] = uiBitsTemp; // storing for bi-prediction
@@ -2433,21 +3131,65 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner)
             // set motion
             cMv    [iRefList] = cMvTemp[iRefList][iRefIdxTemp];
             iRefIdx[iRefList] = iRefIdxTemp;
+
+#if GDR_ENABLED
+            if (isEncodeGdrClean)
+            {
+              uiCostOk[iRefList] = uiCostTempOk;
+              cMvSolid[iRefList] = cMvTempSolid[iRefList][iRefIdxTemp];
+              cMvValid[iRefList] = cs.isClean(pu.Y().bottomRight(), cMv[iRefList], (RefPicList)iRefList, iRefIdx[iRefList]);
+            }
+#endif
           }
 
+
+#if GDR_ENABLED
+          allOk = (iRefList == 1 && uiCostTemp < costValidList1 && cs.slice->getList1IdxToList0Idx(iRefIdxTemp) < 0);
+          if (isEncodeGdrClean)
+          {
+            if (uiCostTempOk)
+            {
+              allOk = (costValidList1Ok) ? (iRefList == 1 && uiCostTemp < costValidList1 && cs.slice->getList1IdxToList0Idx(iRefIdxTemp) < 0) : true;
+            }
+            else
+            {
+              allOk = false;
+            }
+          }
+#endif
+
+#if GDR_ENABLED
+          if (allOk)
+#else
           if ( iRefList == 1 && uiCostTemp < costValidList1 && cs.slice->getList1IdxToList0Idx( iRefIdxTemp ) < 0 )
+#endif
           {
             costValidList1 = uiCostTemp;
             bitsValidList1 = uiBitsTemp;
 
             // set motion
             mvValidList1     = cMvTemp[iRefList][iRefIdxTemp];
+#if GDR_ENABLED
+            if (isEncodeGdrClean)
+            {
+              costValidList1Ok = uiCostTempOk;
+              mvValidList1Solid = cMvTempSolid[iRefList][iRefIdxTemp];
+              mvValidList1Valid = cs.isClean(pu.Y().bottomRight(), mvValidList1, (RefPicList)iRefList, iRefIdxTemp);
+            }
+#endif
             refIdxValidList1 = iRefIdxTemp;
           }
         }
       }
 
       ::memcpy(cMvHevcTemp, cMvTemp, sizeof(cMvTemp));
+#if GDR_ENABLED
+      if (isEncodeGdrClean)
+      {
+        ::memcpy(cMvHevcTempSolid, cMvTempSolid, sizeof(cMvTempSolid));
+        ::memcpy(cMvHevcTempValid, cMvTempValid, sizeof(cMvTempValid));
+      }
+#endif
       if (cu.imv == 0 && (!cu.slice->getSPS()->getUseBcw() || bcwIdx == BCW_DEFAULT))
       {
         insertUniMvCands(pu.Y(), cMvTemp);
@@ -2469,8 +3211,23 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner)
         iRefIdxBi[0] = iRefIdx[0];
         iRefIdxBi[1] = iRefIdx[1];
 
+#if GDR_ENABLED
+        if (isEncodeGdrClean)
+        {
+          cMvBiSolid[0] = cMvSolid[0];
+          cMvBiSolid[1] = cMvSolid[1];
+          cMvBiValid[0] = cMvValid[0];
+          cMvBiValid[1] = cMvValid[1];
+        }
+#endif
         ::memcpy( cMvPredBi,   cMvPred,   sizeof( cMvPred   ) );
         ::memcpy( aaiMvpIdxBi, aaiMvpIdx, sizeof( aaiMvpIdx ) );
+#if GDR_ENABLED
+        if (isEncodeGdrClean)
+        {
+          ::memcpy(cMvPredBiSolid, cMvPredSolid, sizeof(cMvPredSolid));
+        }
+#endif
 
         uint32_t uiMotBits[2];
 
@@ -2481,10 +3238,25 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner)
           cMvPredBi  [1][bestBiPRefIdxL1] = amvp[REF_PIC_LIST_1].mvCand[bestBiPMvpL1];
 
           cMvBi    [1] = cMvPredBi[1][bestBiPRefIdxL1];
+#if GDR_ENABLED
+          if (isEncodeGdrClean)
+          {
+            cMvPredBiSolid[1][bestBiPRefIdxL1] = amvp[REF_PIC_LIST_1].mvSolid[bestBiPMvpL1];
+            cMvBiSolid[1] = cMvPredBiSolid[1][bestBiPRefIdxL1];
+            cMvBiValid[1] = cs.isClean(pu.Y().bottomRight(), cMvBi[1], REF_PIC_LIST_1, bestBiPRefIdxL1);
+          }
+#endif
           iRefIdxBi[1] = bestBiPRefIdxL1;
           pu.mv    [REF_PIC_LIST_1] = cMvBi[1];
           pu.refIdx[REF_PIC_LIST_1] = iRefIdxBi[1];
           pu.mvpIdx[REF_PIC_LIST_1] = bestBiPMvpL1;
+#if GDR_ENABLED
+          if (isEncodeGdrClean)
+          {
+            pu.mvSolid[REF_PIC_LIST_1] = cMvBiSolid[1];
+            pu.mvValid[REF_PIC_LIST_1] = cs.isClean(pu.Y().bottomRight(), pu.mv[REF_PIC_LIST_1], REF_PIC_LIST_1, pu.refIdx[REF_PIC_LIST_1]);
+          }
+#endif
 
           if( m_pcEncCfg->getMCTSEncConstraint() )
           {
@@ -2519,6 +3291,13 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner)
           uiBits[2] = uiMbBits[2] + uiMotBits[0] + uiMotBits[1];
 
           cMvTemp[1][bestBiPRefIdxL1] = cMvBi[1];
+#if GDR_ENABLED
+          if (isEncodeGdrClean)
+          {
+            cMvTempSolid[1][bestBiPRefIdxL1] = cMvBiSolid[1];
+            cMvTempValid[1][bestBiPRefIdxL1] = cs.isClean(pu.Y().bottomRight(), cMvBi[1], REF_PIC_LIST_1, bestBiPRefIdxL1);
+          }
+#endif
         }
         else
         {
@@ -2529,126 +3308,313 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner)
 
         if( doBiPred )
         {
-        // 4-times iteration (default)
-        int iNumIter = 4;
-
-        // fast encoder setting: only one iteration
-        if ( m_pcEncCfg->getFastInterSearchMode()==FASTINTERSEARCH_MODE1 || m_pcEncCfg->getFastInterSearchMode()==FASTINTERSEARCH_MODE2 || cs.picHeader->getMvdL1ZeroFlag() )
-        {
-          iNumIter = 1;
-        }
+          // 4-times iteration (default)
+          int iNumIter = 4;
 
-        enforceBcwPred = (bcwIdx != BCW_DEFAULT);
-        for ( int iIter = 0; iIter < iNumIter; iIter++ )
-        {
-          int         iRefList    = iIter % 2;
+          // fast encoder setting: only one iteration
+          if (m_pcEncCfg->getFastInterSearchMode() == FASTINTERSEARCH_MODE1
+              || m_pcEncCfg->getFastInterSearchMode() == FASTINTERSEARCH_MODE2 || cs.picHeader->getMvdL1ZeroFlag())
+          {
+            iNumIter = 1;
+          }
 
-          if ( m_pcEncCfg->getFastInterSearchMode()==FASTINTERSEARCH_MODE1 || m_pcEncCfg->getFastInterSearchMode()==FASTINTERSEARCH_MODE2 )
+          enforceBcwPred = (bcwIdx != BCW_DEFAULT);
+          for (int iIter = 0; iIter < iNumIter; iIter++)
           {
-            if( uiCost[0] <= uiCost[1] )
+            int iRefList = iIter % 2;
+
+            if (m_pcEncCfg->getFastInterSearchMode() == FASTINTERSEARCH_MODE1
+                || m_pcEncCfg->getFastInterSearchMode() == FASTINTERSEARCH_MODE2)
             {
-              iRefList = 1;
+#if GDR_ENABLED
+              allOk = (uiCost[0] <= uiCost[1]);
+              if (isEncodeGdrClean)
+              {
+                if (uiCostOk[0])
+                {
+                  allOk = (uiCostOk[1]) ? (uiCost[0] <= uiCost[1]) : true;
+                }
+                else
+                {
+                  allOk = false;
+                }
+              }
+#endif
+
+#if GDR_ENABLED
+              if (allOk)
+#else
+              if (uiCost[0] <= uiCost[1])
+#endif
+              {
+                iRefList = 1;
+              }
+              else
+              {
+                iRefList = 0;
+              }
+              if (bcwIdx != BCW_DEFAULT)
+              {
+                iRefList =
+                  (abs(getBcwWeight(bcwIdx, REF_PIC_LIST_0)) > abs(getBcwWeight(bcwIdx, REF_PIC_LIST_1)) ? 1 : 0);
+              }
             }
-            else
+            else if (iIter == 0)
             {
               iRefList = 0;
             }
-            if( bcwIdx != BCW_DEFAULT )
+            if (iIter == 0 && !cs.picHeader->getMvdL1ZeroFlag())
             {
-              iRefList = ( abs( getBcwWeight(bcwIdx, REF_PIC_LIST_0 ) ) > abs( getBcwWeight(bcwIdx, REF_PIC_LIST_1 ) ) ? 1 : 0 );
+              pu.mv[1 - iRefList]     = cMv[1 - iRefList];
+              pu.refIdx[1 - iRefList] = iRefIdx[1 - iRefList];
+#if GDR_ENABLED
+              if (isEncodeGdrClean)
+              {
+                pu.mvSolid[1 - iRefList] = cMvSolid[1 - iRefList];
+                pu.mvValid[1 - iRefList] = cs.isClean(pu.Y().bottomRight(), pu.mv[1 - iRefList], (RefPicList)(1 - iRefList), pu.refIdx[1 - iRefList]);
+              }
+#endif
+              PelUnitBuf predBufTmp = m_tmpPredStorage[1 - iRefList].getBuf(UnitAreaRelative(cu, pu));
+              motionCompensation(pu, predBufTmp, RefPicList(1 - iRefList));
             }
-          }
-          else if ( iIter == 0 )
-          {
-            iRefList = 0;
-          }
-          if ( iIter == 0 && !cs.picHeader->getMvdL1ZeroFlag())
-          {
-            pu.mv    [1 - iRefList] = cMv    [1 - iRefList];
-            pu.refIdx[1 - iRefList] = iRefIdx[1 - iRefList];
 
-            PelUnitBuf predBufTmp = m_tmpPredStorage[1 - iRefList].getBuf( UnitAreaRelative(cu, pu) );
-            motionCompensation( pu, predBufTmp, RefPicList(1 - iRefList) );
-          }
-
-          RefPicList  eRefPicList = ( iRefList ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
+            RefPicList eRefPicList = (iRefList ? REF_PIC_LIST_1 : REF_PIC_LIST_0);
 
-          if(cs.picHeader->getMvdL1ZeroFlag())
-          {
-            iRefList = 0;
-            eRefPicList = REF_PIC_LIST_0;
-          }
-
-          bool bChanged = false;
-
-          iRefStart = 0;
-          iRefEnd   = cs.slice->getNumRefIdx(eRefPicList)-1;
-          for (int iRefIdxTemp = iRefStart; iRefIdxTemp <= iRefEnd; iRefIdxTemp++)
-          {
-            if( m_pcEncCfg->getUseBcwFast() && (bcwIdx != BCW_DEFAULT)
-              && (pu.cu->slice->getRefPic(eRefPicList, iRefIdxTemp)->getPOC() == pu.cu->slice->getRefPic(RefPicList(1 - iRefList), pu.refIdx[1 - iRefList])->getPOC())
-              && (!pu.cu->imv && pu.cu->slice->getTLayer()>1))
+            if (cs.picHeader->getMvdL1ZeroFlag())
             {
-              continue;
+              iRefList    = 0;
+              eRefPicList = REF_PIC_LIST_0;
             }
-            uiBitsTemp = uiMbBits[2] + uiMotBits[1-iRefList];
-            uiBitsTemp += ((cs.slice->getSPS()->getUseBcw() == true) ? getWeightIdxBits(bcwIdx) : 0);
-            if ( cs.slice->getNumRefIdx(eRefPicList) > 1 )
+
+            bool bChanged = false;
+
+            iRefStart = 0;
+            iRefEnd   = cs.slice->getNumRefIdx(eRefPicList) - 1;
+            for (int iRefIdxTemp = iRefStart; iRefIdxTemp <= iRefEnd; iRefIdxTemp++)
             {
-              uiBitsTemp += iRefIdxTemp+1;
-              if ( iRefIdxTemp == cs.slice->getNumRefIdx(eRefPicList)-1 )
+              if (m_pcEncCfg->getUseBcwFast() && (bcwIdx != BCW_DEFAULT)
+                  && (pu.cu->slice->getRefPic(eRefPicList, iRefIdxTemp)->getPOC()
+                      == pu.cu->slice->getRefPic(RefPicList(1 - iRefList), pu.refIdx[1 - iRefList])->getPOC())
+                  && (!pu.cu->imv && pu.cu->slice->getTLayer() > 1))
               {
-                uiBitsTemp--;
+                continue;
               }
-            }
-            uiBitsTemp += m_auiMVPIdxCost[aaiMvpIdxBi[iRefList][iRefIdxTemp]][AMVP_MAX_NUM_CANDS];
-            if ( cs.slice->getBiDirPred() )
-            {
-              uiBitsTemp += 1; // add one bit for symmetrical MVD mode
-            }
-            // call ME
-            xCopyAMVPInfo(&aacAMVPInfo[iRefList][iRefIdxTemp], &amvp[eRefPicList] );
-            xMotionEstimation ( pu, origBuf, eRefPicList, cMvPredBi[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], aaiMvpIdxBi[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp, amvp[eRefPicList], true );
-            xCheckBestMVP( eRefPicList, cMvTemp[iRefList][iRefIdxTemp], cMvPredBi[iRefList][iRefIdxTemp], aaiMvpIdxBi[iRefList][iRefIdxTemp], amvp[eRefPicList], uiBitsTemp, uiCostTemp, pu.cu->imv);
-            if ( uiCostTemp < uiCostBi )
-            {
-              bChanged = true;
+              uiBitsTemp = uiMbBits[2] + uiMotBits[1 - iRefList];
+              uiBitsTemp += ((cs.slice->getSPS()->getUseBcw() == true) ? getWeightIdxBits(bcwIdx) : 0);
+              if (cs.slice->getNumRefIdx(eRefPicList) > 1)
+              {
+                uiBitsTemp += iRefIdxTemp + 1;
+                if (iRefIdxTemp == cs.slice->getNumRefIdx(eRefPicList) - 1)
+                {
+                  uiBitsTemp--;
+                }
+              }
+              uiBitsTemp += m_auiMVPIdxCost[aaiMvpIdxBi[iRefList][iRefIdxTemp]][AMVP_MAX_NUM_CANDS];
+              if (cs.slice->getBiDirPred())
+              {
+                uiBitsTemp += 1;   // add one bit for symmetrical MVD mode
+              }
+              // call ME
+              xCopyAMVPInfo(&aacAMVPInfo[iRefList][iRefIdxTemp], &amvp[eRefPicList]);
+#if GDR_ENABLED
+              bCleanCandExist = false;
+              xMotionEstimation(pu, origBuf, eRefPicList, cMvPredBi[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], cMvTempSolid[iRefList][iRefIdxTemp], aaiMvpIdxBi[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp, amvp[eRefPicList], bCleanCandExist, true);
+#else
+              xMotionEstimation(pu, origBuf, eRefPicList, cMvPredBi[iRefList][iRefIdxTemp], iRefIdxTemp,
+                                cMvTemp[iRefList][iRefIdxTemp], aaiMvpIdxBi[iRefList][iRefIdxTemp], uiBitsTemp,
+                                uiCostTemp, amvp[eRefPicList], true);
+#endif
+#if GDR_ENABLED
+              if (isEncodeGdrClean)
+              {
+                int mvp_idx = aaiMvpIdxBi[iRefList][iRefIdxTemp];
+                cMvPredBiSolid[iRefList][iRefIdxTemp] = amvp[eRefPicList].mvSolid[mvp_idx];
+                cMvTempSolid[iRefList][iRefIdxTemp] = amvp[eRefPicList].mvSolid[mvp_idx];
+                cMvTempValid[iRefList][iRefIdxTemp] = cs.isClean(pu.Y().bottomRight(), cMvTemp[iRefList][iRefIdxTemp], (RefPicList)iRefList, iRefIdxTemp);
+                if (cMvTempValid[iRefList][iRefIdxTemp])
+                {
+                  cMvTempValid[iRefList][iRefIdxTemp] = cMvTempSolid[iRefList][iRefIdxTemp];
+                }
 
-              cMvBi[iRefList]     = cMvTemp[iRefList][iRefIdxTemp];
-              iRefIdxBi[iRefList] = iRefIdxTemp;
+                uiCostTempOk = bCleanCandExist;
+                uiCostTempOk = uiCostTempOk && cMvPredBiSolid[iRefList][iRefIdxTemp];
+                uiCostTempOk = uiCostTempOk && cMvTempSolid[iRefList][iRefIdxTemp];
+                uiCostTempOk = uiCostTempOk && cMvTempValid[iRefList][iRefIdxTemp];
+              }
+#endif
 
-              uiCostBi            = uiCostTemp;
-              uiMotBits[iRefList] = uiBitsTemp - uiMbBits[2] - uiMotBits[1-iRefList];
-              uiMotBits[iRefList] -= ((cs.slice->getSPS()->getUseBcw() == true) ? getWeightIdxBits(bcwIdx) : 0);
-              uiBits[2]           = uiBitsTemp;
+#if GDR_ENABLED
+              // note : uiCostTemp is the new Best MVP cost,
+              //        solid info will be at amvp[eRefPicList].mvSolid[aaiMvpIdx[iRefList][iRefIdxTemp]];
+              xCheckBestMVP(pu, eRefPicList, cMvTemp[iRefList][iRefIdxTemp], cMvPredBi[iRefList][iRefIdxTemp], aaiMvpIdxBi[iRefList][iRefIdxTemp], amvp[eRefPicList], uiBitsTemp, uiCostTemp, pu.cu->imv);
 
-              if(iNumIter!=1)
+              if (isEncodeGdrClean)
               {
-                //  Set motion
-                pu.mv    [eRefPicList] = cMvBi    [iRefList];
-                pu.refIdx[eRefPicList] = iRefIdxBi[iRefList];
+                int mvp_idx = aaiMvpIdxBi[iRefList][iRefIdxTemp];
+
+                cMvPredBiSolid[iRefList][iRefIdxTemp] = amvp[eRefPicList].mvSolid[mvp_idx];
+                cMvTempSolid[iRefList][iRefIdxTemp] = amvp[eRefPicList].mvSolid[mvp_idx];
+                cMvTempValid[iRefList][iRefIdxTemp] = cs.isClean(pu.Y().bottomRight(), cMvTemp[iRefList][iRefIdxTemp], (RefPicList)iRefList, iRefIdxTemp);
+                if (cMvTempValid[iRefList][iRefIdxTemp])
+                {
+                  cMvTempValid[iRefList][iRefIdxTemp] = cMvTempSolid[iRefList][iRefIdxTemp];
+                }
 
-                PelUnitBuf predBufTmp = m_tmpPredStorage[iRefList].getBuf( UnitAreaRelative(cu, pu) );
-                motionCompensation( pu, predBufTmp, eRefPicList );
+                uiCostTempOk = true;
+                uiCostTempOk = uiCostTempOk && cMvPredBiSolid[iRefList][iRefIdxTemp];
+                uiCostTempOk = uiCostTempOk && cMvTempSolid[iRefList][iRefIdxTemp];
+                uiCostTempOk = uiCostTempOk && cMvTempValid[iRefList][iRefIdxTemp];
               }
-            }
-          } // for loop-iRefIdxTemp
+#else
 
-          if ( !bChanged )
-          {
-            if ((uiCostBi <= uiCost[0] && uiCostBi <= uiCost[1]) || enforceBcwPred)
+              xCheckBestMVP(eRefPicList, cMvTemp[iRefList][iRefIdxTemp], cMvPredBi[iRefList][iRefIdxTemp],
+                            aaiMvpIdxBi[iRefList][iRefIdxTemp], amvp[eRefPicList], uiBitsTemp, uiCostTemp, pu.cu->imv);
+#endif
+#if GDR_ENABLED
+              allOk = (uiCostTemp < uiCostBi);
+              if (isEncodeGdrClean)
+              {
+                if (uiCostTempOk)
+                {
+                  allOk = (uiCostBiOk) ? (uiCostTemp < uiCostBi) : true;
+                }
+                else
+                {
+                  allOk = false;
+                }
+              }
+#endif
+#if GDR_ENABLED
+              if (allOk)
+#else
+              if (uiCostTemp < uiCostBi)
+#endif
+              {
+                bChanged = true;
+
+                cMvBi[iRefList]     = cMvTemp[iRefList][iRefIdxTemp];
+#if GDR_ENABLED
+                if (isEncodeGdrClean)
+                {
+                  cMvBiSolid[iRefList] = cMvTempSolid[iRefList][iRefIdxTemp];
+                  cMvBiValid[iRefList] = cs.isClean(pu.Y().bottomRight(), cMvTemp[iRefList][iRefIdxTemp], (RefPicList)iRefList, iRefIdxTemp);
+                }
+#endif
+                iRefIdxBi[iRefList] = iRefIdxTemp;
+
+                uiCostBi            = uiCostTemp;
+#if GDR_ENABLED
+                if (isEncodeGdrClean)
+                {
+                  uiCostBiOk = uiCostTempOk;
+                }
+#endif
+                uiMotBits[iRefList] = uiBitsTemp - uiMbBits[2] - uiMotBits[1 - iRefList];
+                uiMotBits[iRefList] -= ((cs.slice->getSPS()->getUseBcw() == true) ? getWeightIdxBits(bcwIdx) : 0);
+                uiBits[2] = uiBitsTemp;
+
+                if (iNumIter != 1)
+                {
+                  //  Set motion
+                  pu.mv[eRefPicList]     = cMvBi[iRefList];
+                  pu.refIdx[eRefPicList] = iRefIdxBi[iRefList];
+#if GDR_ENABLED
+                  if (isEncodeGdrClean)
+                  {
+                    pu.mvSolid[eRefPicList] = cMvBiSolid[iRefList];
+                    pu.mvValid[eRefPicList] = cs.isClean(pu.Y().bottomRight(), pu.mv[eRefPicList], (RefPicList)eRefPicList, pu.refIdx[eRefPicList]);
+                  }
+#endif
+                  PelUnitBuf predBufTmp = m_tmpPredStorage[iRefList].getBuf(UnitAreaRelative(cu, pu));
+                  motionCompensation(pu, predBufTmp, eRefPicList);
+                }
+              }
+            }   // for loop-iRefIdxTemp
+
+            if (!bChanged)
             {
-              xCopyAMVPInfo(&aacAMVPInfo[0][iRefIdxBi[0]], &amvp[REF_PIC_LIST_0]);
-              xCheckBestMVP( REF_PIC_LIST_0, cMvBi[0], cMvPredBi[0][iRefIdxBi[0]], aaiMvpIdxBi[0][iRefIdxBi[0]], amvp[REF_PIC_LIST_0], uiBits[2], uiCostBi, pu.cu->imv);
-              if(!cs.picHeader->getMvdL1ZeroFlag())
+#if GDR_ENABLED
+              allOk = ((uiCostBi <= uiCost[0] && uiCostBi <= uiCost[1]) || enforceBcwPred);
+
+              if (isEncodeGdrClean)
+              {
+                if (uiCostBiOk)
+                {
+                  allOk = (uiCostOk[0] && uiCostOk[1]) ? ((uiCostBi <= uiCost[0] && uiCostBi <= uiCost[1]) || enforceBcwPred) : true;
+                }
+                else
+                {
+                  allOk = false;
+                }
+              }
+#endif
+#if GDR_ENABLED
+              if (allOk)
+#else
+              if ((uiCostBi <= uiCost[0] && uiCostBi <= uiCost[1]) || enforceBcwPred)
+#endif
               {
-                xCopyAMVPInfo(&aacAMVPInfo[1][iRefIdxBi[1]], &amvp[REF_PIC_LIST_1]);
-                xCheckBestMVP( REF_PIC_LIST_1, cMvBi[1], cMvPredBi[1][iRefIdxBi[1]], aaiMvpIdxBi[1][iRefIdxBi[1]], amvp[REF_PIC_LIST_1], uiBits[2], uiCostBi, pu.cu->imv);
+                xCopyAMVPInfo(&aacAMVPInfo[0][iRefIdxBi[0]], &amvp[REF_PIC_LIST_0]);
+#if GDR_ENABLED
+                // note : uiCostBi is the new Best MVP cost,
+                //          solid info will be at amvp[eRefPicList].mvSolid[aaiMvpIdx[iRefList][iRefIdxTemp]];
+                xCheckBestMVP(pu, REF_PIC_LIST_0, cMvBi[0], cMvPredBi[0][iRefIdxBi[0]], aaiMvpIdxBi[0][iRefIdxBi[0]], amvp[REF_PIC_LIST_0], uiBits[2], uiCostBi, pu.cu->imv);
+
+                if (isEncodeGdrClean)
+                {
+                  int mvp_idx = aaiMvpIdxBi[0][iRefIdxBi[0]];
+
+                  cMvPredBiSolid[0][iRefIdxBi[0]] = amvp[0].mvSolid[mvp_idx];
+                  cMvBiSolid[0] = amvp[0].mvSolid[mvp_idx];
+                  cMvBiValid[0] = cs.isClean(pu.Y().bottomRight(), cMvBi[0], (RefPicList)0, iRefIdxBi[0]);
+                  if (cMvBiValid[0])
+                  {
+                    cMvBiValid[0] = cMvBiSolid[0];
+                  }
+
+                  uiCostBiOk = true;
+                  uiCostBiOk = uiCostBiOk && cMvPredBiSolid[0][iRefIdxBi[0]];
+                  uiCostBiOk = uiCostBiOk && cMvBiSolid[0];
+                  uiCostBiOk = uiCostBiOk && cMvBiValid[0];
+                }
+#else
+                xCheckBestMVP(REF_PIC_LIST_0, cMvBi[0], cMvPredBi[0][iRefIdxBi[0]], aaiMvpIdxBi[0][iRefIdxBi[0]],
+                              amvp[REF_PIC_LIST_0], uiBits[2], uiCostBi, pu.cu->imv);
+#endif
+                if (!cs.picHeader->getMvdL1ZeroFlag())
+                {
+                  xCopyAMVPInfo(&aacAMVPInfo[1][iRefIdxBi[1]], &amvp[REF_PIC_LIST_1]);
+#if GDR_ENABLED
+                  // note : uiCostBi is the new Best MVP cost,
+                  //          solid info will be at amvp[eRefPicList].mvSolid[aaiMvpIdx[iRefList][iRefIdxTemp]];
+                  xCheckBestMVP(pu, REF_PIC_LIST_1, cMvBi[1], cMvPredBi[1][iRefIdxBi[1]], aaiMvpIdxBi[1][iRefIdxBi[1]], amvp[REF_PIC_LIST_1], uiBits[2], uiCostBi, pu.cu->imv);
+
+                  if (isEncodeGdrClean)
+                  {
+                    int mvp_idx = aaiMvpIdxBi[1][iRefIdxBi[1]];
+
+                    cMvPredBiSolid[1][iRefIdxBi[1]] = aaiMvpIdxBi[1][iRefIdxBi[1]];
+                    cMvBiSolid[1] = amvp[REF_PIC_LIST_1].mvSolid[mvp_idx];
+                    cMvBiValid[1] = cs.isClean(pu.Y().bottomRight(), cMvBi[1], (RefPicList)1, iRefIdxBi[1]);
+                    if (cMvBiValid[1])
+                    {
+                      cMvBiValid[1] = cMvBiSolid[1];
+                    }
+
+                    uiCostBiOk = true;
+                    uiCostBiOk = uiCostBiOk && cMvPredBiSolid[1][iRefIdxBi[1]];
+                    uiCostBiOk = uiCostBiOk && cMvBiSolid[1];
+                    uiCostBiOk = uiCostBiOk && cMvBiValid[1];
+                  }
+#else
+                  xCheckBestMVP(REF_PIC_LIST_1, cMvBi[1], cMvPredBi[1][iRefIdxBi[1]], aaiMvpIdxBi[1][iRefIdxBi[1]],
+                                amvp[REF_PIC_LIST_1], uiBits[2], uiCostBi, pu.cu->imv);
+#endif
+                }
               }
+              break;
             }
-            break;
-          }
-        } // for loop-iter
+          }   // for loop-iter
         }
         cu.refIdxBi[0] = iRefIdxBi[0];
         cu.refIdxBi[1] = iRefIdxBi[1];
@@ -2667,12 +3633,31 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner)
           CHECK (refIdxCur==-1 || refIdxTar==-1, "Uninitialized reference index not allowed");
 
           if ( aacAMVPInfo[curRefList][refIdxCur].mvCand[0] == aacAMVPInfo[curRefList][refIdxCur].mvCand[1] )
+          {
             aacAMVPInfo[curRefList][refIdxCur].numCand = 1;
+          }
           if ( aacAMVPInfo[tarRefList][refIdxTar].mvCand[0] == aacAMVPInfo[tarRefList][refIdxTar].mvCand[1] )
+          {
             aacAMVPInfo[tarRefList][refIdxTar].numCand = 1;
+          }
 
           MvField cCurMvField, cTarMvField;
           Distortion costStart = std::numeric_limits<Distortion>::max();
+
+#if GDR_ENABLED
+          bool cMvPredSymSolid[2] = { init_value, init_value };
+          bool cMvPredSymValid[2] = { init_value, init_value };
+
+          bool cCurMvFieldSolid = init_value;
+          bool cTarMvFieldSolid = init_value;
+          bool cCurMvFieldValid = init_value;
+          bool cTarMvFieldValid = init_value;
+
+          bool costStartOk = false;
+          bool symCostOk = init_value;
+          bool costOk = init_value;
+          bool bestCostOk = init_value;
+#endif
           for ( int i = 0; i < aacAMVPInfo[curRefList][refIdxCur].numCand; i++ )
           {
             for ( int j = 0; j < aacAMVPInfo[tarRefList][refIdxTar].numCand; j++ )
@@ -2680,11 +3665,46 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner)
               cCurMvField.setMvField( aacAMVPInfo[curRefList][refIdxCur].mvCand[i], refIdxCur );
               cTarMvField.setMvField( aacAMVPInfo[tarRefList][refIdxTar].mvCand[j], refIdxTar );
               Distortion cost = xGetSymmetricCost( pu, origBuf, eCurRefList, cCurMvField, cTarMvField, bcwIdx );
+
+#if GDR_ENABLED
+              if (isEncodeGdrClean)
+              {
+                cCurMvFieldSolid = aacAMVPInfo[curRefList][refIdxCur].mvSolid[i];
+                cTarMvFieldSolid = aacAMVPInfo[tarRefList][refIdxTar].mvSolid[i];
+                costOk = cCurMvFieldSolid && cTarMvFieldSolid;
+              }
+#endif
+#if GDR_ENABLED
+              allOk = (cost < costStart);
+              if (isEncodeGdrClean)
+              {
+                if (costOk)
+                {
+                  allOk = (costStartOk) ? (cost < costStart) : true;
+                }
+                else
+                {
+                  allOk = false;
+                }
+              }
+#endif
+#if GDR_ENABLED
+              if (allOk)
+#else
               if ( cost < costStart )
+#endif
               {
                 costStart = cost;
                 cMvPredSym[curRefList] = aacAMVPInfo[curRefList][refIdxCur].mvCand[i];
                 cMvPredSym[tarRefList] = aacAMVPInfo[tarRefList][refIdxTar].mvCand[j];
+#if GDR_ENABLED
+                if (isEncodeGdrClean)
+                {
+                  costStartOk = costOk;
+                  cMvPredSymSolid[curRefList] = aacAMVPInfo[curRefList][refIdxCur].mvSolid[i];
+                  cMvPredSymSolid[tarRefList] = aacAMVPInfo[tarRefList][refIdxTar].mvSolid[j];
+                }
+#endif
                 mvpIdxSym[curRefList] = i;
                 mvpIdxSym[tarRefList] = j;
               }
@@ -2693,6 +3713,13 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner)
           cCurMvField.mv = cMvPredSym[curRefList];
           cTarMvField.mv = cMvPredSym[tarRefList];
 
+#if GDR_ENABLED
+          if (isEncodeGdrClean)
+          {
+            cCurMvFieldSolid = cMvPredSymSolid[curRefList];
+            cTarMvFieldSolid = cMvPredSymSolid[tarRefList];
+          }
+#endif
           m_pcRdCost->setCostScale(0);
           Mv pred = cMvPredSym[curRefList];
           pred.changeTransPrecInternal2Amvr(pu.cu->imv);
@@ -2737,7 +3764,9 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner)
           for (int i = 0; i < m_uniMvListSize; i++)
           {
             if ( symmvdCands.size() >= 5 )
+            {
               break;
+            }
             BlkUniMvInfo* curMvInfo = m_uniMvList + ((m_uniMvListIdx - 1 - i + m_uniMvListMaxSize) % (m_uniMvListMaxSize));
             smmvdCandsGen(curMvInfo->uniMvs[curRefList][refIdxCur], true);
           }
@@ -2755,11 +3784,63 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner)
             }
 
             Distortion bestCost = costStart;
+#if GDR_ENABLED
+            symmvdCheckBestMvp(pu, origBuf, mvStart, (RefPicList)curRefList, aacAMVPInfo, bcwIdx, cMvPredSym, cMvPredSymSolid, mvpIdxSym, costStart);
+#else
             symmvdCheckBestMvp(pu, origBuf, mvStart, (RefPicList)curRefList, aacAMVPInfo, bcwIdx, cMvPredSym, mvpIdxSym, costStart);
+#endif
+
+#if GDR_ENABLED
+            if (isEncodeGdrClean)
+            {
+              int mvp_idx0 = mvpIdxSym[0];
+              int mvp_idx1 = mvpIdxSym[1];
+
+              cMvPredSymSolid[curRefList] = aacAMVPInfo[curRefList][refIdxCur].mvSolid[mvp_idx0];
+              cMvPredSymSolid[tarRefList] = aacAMVPInfo[tarRefList][refIdxTar].mvSolid[mvp_idx1];
+              cMvPredSymValid[curRefList] = cs.isClean(pu.Y().bottomRight(), mvStart, (RefPicList)curRefList, pu.cu->slice->getSymRefIdx(curRefList));
+              cMvPredSymValid[tarRefList] = cs.isClean(pu.Y().bottomRight(), mvStart, (RefPicList)tarRefList, pu.cu->slice->getSymRefIdx(tarRefList));
+
+              costStartOk = true;
+              costStartOk = costStartOk && cMvPredSymSolid[curRefList];
+              costStartOk = costStartOk && cMvPredSymSolid[tarRefList];
+              costStartOk = costStartOk && cMvPredSymValid[curRefList];
+              costStartOk = costStartOk && cMvPredSymValid[tarRefList];
+            }
+#endif
+
+#if GDR_ENABLED
+            bool allOk = (costStart < bestCost);
+            if (isEncodeGdrClean)
+            {
+              if (costStartOk)
+              {
+                allOk = (bestCostOk) ? (costStart < bestCost) : true;
+              }
+              else
+              {
+                allOk = false;
+              }
+            }
+#endif
+
+#if GDR_ENABLED
+            if (allOk)
+#else
             if (costStart < bestCost)
+#endif
             {
               cCurMvField.setMvField(mvStart, refIdxCur);
               cTarMvField.setMvField(mvStart.getSymmvdMv(cMvPredSym[curRefList], cMvPredSym[tarRefList]), refIdxTar);
+#if GDR_ENABLED
+              if (isEncodeGdrClean)
+              {
+                cCurMvFieldSolid = cMvPredSymSolid[curRefList];
+                cTarMvFieldSolid = cMvPredSymSolid[tarRefList];
+                cCurMvFieldValid = cMvPredSymValid[curRefList];
+                cTarMvFieldValid = cMvPredSymValid[tarRefList];
+              }
+#endif
             }
           }
           Mv startPtMv = cCurMvField.mv;
@@ -2768,13 +3849,47 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner)
           symCost = costStart - mvpCost;
 
           // ME
+#if GDR_ENABLED
+          xSymmetricMotionEstimation(pu, origBuf, cMvPredSym[curRefList], cMvPredSym[tarRefList], eCurRefList, cCurMvField, cTarMvField, symCost, bcwIdx, costStartOk);
+#else
           xSymmetricMotionEstimation( pu, origBuf, cMvPredSym[curRefList], cMvPredSym[tarRefList], eCurRefList, cCurMvField, cTarMvField, symCost, bcwIdx );
-
+#endif
           symCost += mvpCost;
 
+#if GDR_ENABLED
+          if (isEncodeGdrClean)
+          {
+            cCurMvFieldValid = cs.isClean(pu.Y().bottomRight(), cCurMvField.mv, (RefPicList)(eCurRefList), cCurMvField.refIdx);
+            cTarMvFieldValid = cs.isClean(pu.Y().bottomRight(), cTarMvField.mv, (RefPicList)(1 - eCurRefList), cTarMvField.refIdx);
+            symCostOk = (cMvPredSymSolid[curRefList] && cMvPredSymSolid[tarRefList]) && (cCurMvFieldValid && cTarMvFieldValid);
+          }
+#endif
           if (startPtMv != cCurMvField.mv)
           { // if ME change MV, run a final check for best MVP.
+#if GDR_ENABLED
+            symmvdCheckBestMvp(pu, origBuf, cCurMvField.mv, (RefPicList)curRefList, aacAMVPInfo, bcwIdx, cMvPredSym, cMvPredSymSolid, mvpIdxSym, symCost);
+#else
             symmvdCheckBestMvp(pu, origBuf, cCurMvField.mv, (RefPicList)curRefList, aacAMVPInfo, bcwIdx, cMvPredSym, mvpIdxSym, symCost, true);
+#endif
+
+#if GDR_ENABLED
+            if (isEncodeGdrClean)
+            {
+              int mvp_idx0 = mvpIdxSym[0];
+              int mvp_idx1 = mvpIdxSym[1];
+
+              cMvPredSymSolid[curRefList] = aacAMVPInfo[curRefList][refIdxCur].mvSolid[mvp_idx0];
+              cMvPredSymSolid[tarRefList] = aacAMVPInfo[tarRefList][refIdxTar].mvSolid[mvp_idx1];
+              cMvPredSymValid[curRefList] = cs.isClean(pu.Y().bottomRight(), cCurMvField.mv, (RefPicList)curRefList, pu.cu->slice->getSymRefIdx(curRefList));
+              cMvPredSymValid[tarRefList] = cs.isClean(pu.Y().bottomRight(), cCurMvField.mv, (RefPicList)tarRefList, pu.cu->slice->getSymRefIdx(tarRefList));
+
+              symCostOk = true;
+              symCostOk = symCostOk && cMvPredSymSolid[curRefList];
+              symCostOk = symCostOk && cMvPredSymSolid[tarRefList];
+              symCostOk = symCostOk && cMvPredSymValid[curRefList];
+              symCostOk = symCostOk && cMvPredSymValid[tarRefList];
+            }
+#endif
           }
 
           bits = uiMbBits[2];
@@ -2786,13 +3901,37 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner)
           if( m_pcEncCfg->getMCTSEncConstraint() )
           {
             if( !( MCTSHelper::checkMvForMCTSConstraint( pu, cCurMvField.mv ) && MCTSHelper::checkMvForMCTSConstraint( pu, cTarMvField.mv ) ) )
+            {
               symCost = std::numeric_limits<Distortion>::max();
+            }
           }
           // save results
+#if GDR_ENABLED
+          bool allOk = (symCost < uiCostBi);
+          if (isEncodeGdrClean)
+          {
+            if (symCostOk)
+            {
+              allOk = (uiCostBiOk) ? (symCost < uiCostBi) : true;
+            }
+            else
+            {
+              allOk = false;
+            }
+          }
+#endif
+
+#if GDR_ENABLED
+          if (allOk)
+#else
           if ( symCost < uiCostBi )
+#endif
           {
             uiCostBi = symCost;
             symMode = 1 + curRefList;
+#if GDR_ENABLED
+            uiCostBiOk = symCostOk;
+#endif
 
             cMvBi[curRefList] = cCurMvField.mv;
             iRefIdxBi[curRefList] = cCurMvField.refIdx;
@@ -2803,6 +3942,16 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner)
             iRefIdxBi[tarRefList] = cTarMvField.refIdx;
             aaiMvpIdxBi[tarRefList][cTarMvField.refIdx] = mvpIdxSym[tarRefList];
             cMvPredBi[tarRefList][iRefIdxBi[tarRefList]] = cMvPredSym[tarRefList];
+
+#if GDR_ENABLED
+            if (isEncodeGdrClean)
+            {
+              cMvBiValid[curRefList] = cCurMvFieldValid;
+              cMvBiValid[tarRefList] = cTarMvFieldValid;
+              cMvPredBiSolid[curRefList][iRefIdxBi[curRefList]] = cMvPredSymSolid[curRefList];
+              cMvPredBiSolid[tarRefList][iRefIdxBi[tarRefList]] = cMvPredSymSolid[tarRefList];
+            }
+#endif
           }
         }
       } // if (B_SLICE)
@@ -2810,43 +3959,107 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner)
 
 
       //  Clear Motion Field
-    pu.mv    [REF_PIC_LIST_0] = Mv();
-    pu.mv    [REF_PIC_LIST_1] = Mv();
-    pu.mvd   [REF_PIC_LIST_0] = cMvZero;
-    pu.mvd   [REF_PIC_LIST_1] = cMvZero;
-    pu.refIdx[REF_PIC_LIST_0] = NOT_VALID;
-    pu.refIdx[REF_PIC_LIST_1] = NOT_VALID;
-    pu.mvpIdx[REF_PIC_LIST_0] = NOT_VALID;
-    pu.mvpIdx[REF_PIC_LIST_1] = NOT_VALID;
-    pu.mvpNum[REF_PIC_LIST_0] = NOT_VALID;
-    pu.mvpNum[REF_PIC_LIST_1] = NOT_VALID;
+      pu.mv[REF_PIC_LIST_0]     = Mv();
+      pu.mv[REF_PIC_LIST_1]     = Mv();
+      pu.mvd[REF_PIC_LIST_0]    = cMvZero;
+      pu.mvd[REF_PIC_LIST_1]    = cMvZero;
+      pu.refIdx[REF_PIC_LIST_0] = NOT_VALID;
+      pu.refIdx[REF_PIC_LIST_1] = NOT_VALID;
+      pu.mvpIdx[REF_PIC_LIST_0] = NOT_VALID;
+      pu.mvpIdx[REF_PIC_LIST_1] = NOT_VALID;
+      pu.mvpNum[REF_PIC_LIST_0] = NOT_VALID;
+      pu.mvpNum[REF_PIC_LIST_1] = NOT_VALID;
+
+#if GDR_ENABLED
+    if (isEncodeGdrClean)
+    {
+      pu.mvSolid[REF_PIC_LIST_0] = true;
+      pu.mvSolid[REF_PIC_LIST_1] = true;
+      pu.mvValid[REF_PIC_LIST_0] = true;
+      pu.mvValid[REF_PIC_LIST_1] = true;
+    }
+#endif
+      // Set Motion Field
 
+      cMv[1]     = mvValidList1;
+#if GDR_ENABLED
+      if (isEncodeGdrClean)
+      {
+        cMvSolid[1] = mvValidList1Solid;
+        cMvValid[1] = mvValidList1Valid;
+      }
+#endif
+      iRefIdx[1] = refIdxValidList1;
+      uiBits[1]  = bitsValidList1;
+      uiCost[1]  = costValidList1;
+#if GDR_ENABLED
+      if (isEncodeGdrClean)
+      {
+        uiCostOk[1] = costValidList1Ok;
+      }
+#endif
+      if (cu.cs->pps->getWPBiPred() == true && tryBipred && (bcwIdx != BCW_DEFAULT))
+      {
+        CHECK(iRefIdxBi[0] < 0, "Invalid picture reference index");
+        CHECK(iRefIdxBi[1] < 0, "Invalid picture reference index");
+        wp0 = cu.cs->slice->getWpScaling(REF_PIC_LIST_0, iRefIdxBi[0]);
+        wp1 = cu.cs->slice->getWpScaling(REF_PIC_LIST_1, iRefIdxBi[1]);
+        if (WPScalingParam::isWeighted(wp0) || WPScalingParam::isWeighted(wp1))
+        {
+          uiCostBi       = MAX_UINT;
+#if GDR_ENABLED
+          if (isEncodeGdrClean)
+          {
+            uiCostBiOk = false;
+          }
+#endif
+          enforceBcwPred = false;
+        }
+      }
+      if (enforceBcwPred)
+      {
+        uiCost[0] = uiCost[1] = MAX_UINT;
+#if GDR_ENABLED
+        uiCostOk[0] = uiCostOk[1] = false;
+#endif
+      }
 
-    // Set Motion Field
+      uiLastModeTemp = uiLastMode;
+#if GDR_ENABLED
+      allOk = ((uiCostBi <= uiCost[0] && uiCostBi <= uiCost[1]) || enforceBcwPred);
 
-    cMv    [1] = mvValidList1;
-    iRefIdx[1] = refIdxValidList1;
-    uiBits [1] = bitsValidList1;
-    uiCost [1] = costValidList1;
-    if (cu.cs->pps->getWPBiPred() == true && tryBipred && (bcwIdx != BCW_DEFAULT))
-    {
-      CHECK(iRefIdxBi[0]<0, "Invalid picture reference index");
-      CHECK(iRefIdxBi[1]<0, "Invalid picture reference index");
-      wp0 = cu.cs->slice->getWpScaling(REF_PIC_LIST_0, iRefIdxBi[0]);
-      wp1 = cu.cs->slice->getWpScaling(REF_PIC_LIST_1, iRefIdxBi[1]);
-      if (WPScalingParam::isWeighted(wp0) || WPScalingParam::isWeighted(wp1))
+      if (isEncodeGdrClean)
       {
-        uiCostBi = MAX_UINT;
-        enforceBcwPred = false;
+        if (uiCostBiOk)
+        {
+          allOk = (uiCostOk[0] && uiCostOk[1]) ? ((uiCostBi <= uiCost[0] && uiCostBi <= uiCost[1]) || enforceBcwPred) : true;
+        }
+        else
+        {
+          allOk = false;
+        }
       }
-    }
-    if( enforceBcwPred )
-    {
-      uiCost[0] = uiCost[1] = MAX_UINT;
-    }
 
-      uiLastModeTemp = uiLastMode;
+      bool L0ok = (uiCost[0] <= uiCost[1]);
+
+      if (isEncodeGdrClean)
+      {
+        if (uiCostOk[0])
+        {
+          L0ok = (uiCostOk[1]) ? (uiCost[0] <= uiCost[1]) : true;
+        }
+        else
+        {
+          L0ok = false;
+        }
+      }
+#endif
+
+#if GDR_ENABLED
+      if (allOk)
+#else
       if ( uiCostBi <= uiCost[0] && uiCostBi <= uiCost[1])
+#endif
       {
         uiLastMode = 2;
         pu.mv    [REF_PIC_LIST_0] = cMvBi[0];
@@ -2862,8 +4075,23 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner)
         pu.interDir = 3;
 
         pu.cu->smvdMode = symMode;
+#if GDR_ENABLED
+        if (isEncodeGdrClean)
+        {
+          int mvp_idx0 = pu.mvpIdx[REF_PIC_LIST_0];
+          int mvp_idx1 = pu.mvpIdx[REF_PIC_LIST_1];
+          pu.mvSolid[REF_PIC_LIST_0] = cMvBiSolid[REF_PIC_LIST_0] && cMvPredBiSolid[REF_PIC_LIST_0][mvp_idx0];
+          pu.mvSolid[REF_PIC_LIST_1] = cMvBiSolid[REF_PIC_LIST_1] && cMvPredBiSolid[REF_PIC_LIST_1][mvp_idx1];
+          pu.mvValid[REF_PIC_LIST_0] = cs.isClean(pu.Y().bottomRight(), pu.mv[REF_PIC_LIST_0], (RefPicList)REF_PIC_LIST_0, pu.refIdx[REF_PIC_LIST_0]);
+          pu.mvValid[REF_PIC_LIST_1] = cs.isClean(pu.Y().bottomRight(), pu.mv[REF_PIC_LIST_1], (RefPicList)REF_PIC_LIST_1, pu.refIdx[REF_PIC_LIST_1]);
+        }
+#endif
       }
+#if GDR_ENABLED
+      else if (L0ok)
+#else
       else if ( uiCost[0] <= uiCost[1] )
+#endif
       {
         uiLastMode = 0;
         pu.mv    [REF_PIC_LIST_0] = cMv[0];
@@ -2872,6 +4100,13 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner)
         pu.mvpIdx[REF_PIC_LIST_0] = aaiMvpIdx[0][iRefIdx[0]];
         pu.mvpNum[REF_PIC_LIST_0] = aaiMvpNum[0][iRefIdx[0]];
         pu.interDir = 1;
+#if GDR_ENABLED
+        if (isEncodeGdrClean)
+        {
+          pu.mvSolid[REF_PIC_LIST_0] = cMvSolid[REF_PIC_LIST_0] && cMvPredSolid[0][iRefIdx[0]];
+          pu.mvValid[REF_PIC_LIST_0] = cs.isClean(pu.Y().bottomRight(), pu.mv[REF_PIC_LIST_0], (RefPicList)REF_PIC_LIST_0, pu.refIdx[REF_PIC_LIST_0]);
+        }
+#endif
       }
       else
       {
@@ -2882,6 +4117,13 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner)
         pu.mvpIdx[REF_PIC_LIST_1] = aaiMvpIdx[1][iRefIdx[1]];
         pu.mvpNum[REF_PIC_LIST_1] = aaiMvpNum[1][iRefIdx[1]];
         pu.interDir = 2;
+#if GDR_ENABLED
+        if (isEncodeGdrClean)
+        {
+          pu.mvSolid[REF_PIC_LIST_1] = cMvSolid[REF_PIC_LIST_1] && cMvPredSolid[1][iRefIdx[1]];
+          pu.mvValid[REF_PIC_LIST_1] = cs.isClean(pu.Y().bottomRight(), pu.mv[REF_PIC_LIST_1], (RefPicList)REF_PIC_LIST_1, pu.refIdx[REF_PIC_LIST_1]);
+        }
+#endif
       }
 
       if( bcwIdx != BCW_DEFAULT )
@@ -2889,14 +4131,29 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner)
         cu.BcwIdx = BCW_DEFAULT; // Reset to default for the Non-NormalMC modes.
       }
 
-    uiHevcCost = ( uiCostBi <= uiCost[0] && uiCostBi <= uiCost[1] ) ? uiCostBi : ( ( uiCost[0] <= uiCost[1] ) ? uiCost[0] : uiCost[1] );
+      uiHevcCost = (uiCostBi <= uiCost[0] && uiCostBi <= uiCost[1])
+                     ? uiCostBi
+                     : ((uiCost[0] <= uiCost[1]) ? uiCost[0] : uiCost[1]);
+#if GDR_ENABLED
+      if (isEncodeGdrClean)
+      {
+        uiHevcCostOk = (uiCostBi <= uiCost[0] && uiCostBi <= uiCost[1]) ? uiCostBiOk : ((uiCost[0] <= uiCost[1]) ? uiCostOk[0] : uiCostOk[1]);
+      }
+#endif
     }
+
     if (cu.Y().width > 8 && cu.Y().height > 8 && cu.slice->getSPS()->getUseAffine()
       && checkAffine
       && (bcwIdx == BCW_DEFAULT || m_affineModeSelected || !m_pcEncCfg->getUseBcwFast())
       )
     {
       m_hevcCost = uiHevcCost;
+#if GDR_ENABLED
+      if (isEncodeGdrClean)
+      {
+        m_hevcCostOk = uiHevcCostOk;
+      }
+#endif
       // save normal hevc result
       uint32_t uiMRGIndex = pu.mergeIdx;
       bool bMergeFlag = pu.mergeFlag;
@@ -2916,28 +4173,101 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner)
       cHevcMvField[0].setMvField( pu.mv[REF_PIC_LIST_0], pu.refIdx[REF_PIC_LIST_0] );
       cHevcMvField[1].setMvField( pu.mv[REF_PIC_LIST_1], pu.refIdx[REF_PIC_LIST_1] );
 
+#if GDR_ENABLED
+      bool cHevcMvFieldSolid[2] = { true, true };
+      bool cHevcMvFieldValid[2] = { true, true };
+
+      if (isEncodeGdrClean)
+      {
+        cHevcMvFieldSolid[0] = pu.mvSolid[0];
+        cHevcMvFieldSolid[1] = pu.mvSolid[1];
+        cHevcMvFieldValid[0] = pu.mvValid[0];
+        cHevcMvFieldValid[1] = pu.mvValid[1];
+      }
+#endif
+
       // do affine ME & Merge
       cu.affineType = AFFINEMODEL_4PARAM;
       Mv acMvAffine4Para[2][33][3];
+#if GDR_ENABLED
+      bool acMvAffine4ParaSolid[2][33][3];
+
+      for (int i = 0; i < 2; i++)
+        for (int j = 0; j < 33; j++)
+          for (int k = 0; k < 3; k++)
+            acMvAffine4ParaSolid[i][j][k] = true;
+#endif
       int refIdx4Para[2] = { -1, -1 };
 
+#if GDR_ENABLED
+      xPredAffineInterSearch(pu, origBuf, puIdx, uiLastModeTemp, uiAffineCost, cMvHevcTemp, cMvHevcTempSolid, acMvAffine4Para, acMvAffine4ParaSolid, refIdx4Para, bcwIdx, enforceBcwPred,
+        ((cu.slice->getSPS()->getUseBcw() == true) ? getWeightIdxBits(bcwIdx) : 0));
+#else
       xPredAffineInterSearch(pu, origBuf, puIdx, uiLastModeTemp, uiAffineCost, cMvHevcTemp, acMvAffine4Para, refIdx4Para, bcwIdx, enforceBcwPred,
         ((cu.slice->getSPS()->getUseBcw() == true) ? getWeightIdxBits(bcwIdx) : 0));
+#endif
 
       if ( pu.cu->imv == 0 )
       {
+#if GDR_ENABLED
+        storeAffineMotion(pu.mvAffi, pu.mvAffiSolid, pu.refIdx, AFFINEMODEL_4PARAM, bcwIdx);
+#else
         storeAffineMotion( pu.mvAffi, pu.refIdx, AFFINEMODEL_4PARAM, bcwIdx );
+#endif
       }
 
+#if GDR_ENABLED
+      if (isEncodeGdrClean)
+      {
+        uiAffineCostOk = true;
+
+        if (pu.interDir & 0x01)
+        {
+          uiAffineCostOk = uiAffineCostOk && pu.mvAffiSolid[0][0] && pu.mvAffiSolid[0][1];
+          uiAffineCostOk = uiAffineCostOk && pu.mvAffiValid[0][0] && pu.mvAffiValid[0][1];
+        }
+
+        if (pu.interDir & 0x02)
+        {
+          uiAffineCostOk = uiAffineCostOk && pu.mvAffiSolid[1][0] && pu.mvAffiSolid[1][1];
+          uiAffineCostOk = uiAffineCostOk && pu.mvAffiValid[1][0] && pu.mvAffiValid[1][1];
+        }
+      }
+#endif
+
       if ( cu.slice->getSPS()->getUseAffineType() )
       {
+#if GDR_ENABLED
+        allOk = (uiAffineCost < uiHevcCost * 1.05);
+        if (isEncodeGdrClean)
+        {
+          if (uiAffineCostOk)
+          {
+            allOk = (uiHevcCostOk) ? (uiAffineCost < uiHevcCost * 1.05) : true;
+          }
+          else
+          {
+            allOk = false;
+          }
+        }
+#endif
+
+#if GDR_ENABLED
+        if (allOk)
+#else
         if ( uiAffineCost < uiHevcCost * 1.05 ) ///< condition for 6 parameter affine ME
+#endif
         {
           // save 4 parameter results
           Mv bestMv[2][3], bestMvd[2][3];
           int bestMvpIdx[2], bestMvpNum[2], bestRefIdx[2];
           uint8_t bestInterDir;
 
+#if GDR_ENABLED
+          bool bestMvSolid[2][3];
+          bool bestMvValid[2][3];
+#endif
+
           bestInterDir = pu.interDir;
           bestRefIdx[0] = pu.refIdx[0];
           bestRefIdx[1] = pu.refIdx[1];
@@ -2954,6 +4284,19 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner)
             bestMvd[refList][0] = pu.mvdAffi[refList][0];
             bestMvd[refList][1] = pu.mvdAffi[refList][1];
             bestMvd[refList][2] = pu.mvdAffi[refList][2];
+
+#if GDR_ENABLED
+            if (isEncodeGdrClean)
+            {
+              bestMvSolid[refList][0] = pu.mvAffiSolid[refList][0];
+              bestMvSolid[refList][1] = pu.mvAffiSolid[refList][1];
+              bestMvSolid[refList][2] = pu.mvAffiSolid[refList][2];
+
+              bestMvValid[refList][0] = pu.mvAffiValid[refList][0];
+              bestMvValid[refList][1] = pu.mvAffiValid[refList][1];
+              bestMvValid[refList][2] = pu.mvAffiValid[refList][2];
+            }
+#endif
           }
 
           refIdx4Para[0] = bestRefIdx[0];
@@ -2961,16 +4304,63 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner)
 
           Distortion uiAffine6Cost = std::numeric_limits<Distortion>::max();
           cu.affineType = AFFINEMODEL_6PARAM;
+#if GDR_ENABLED
+          xPredAffineInterSearch(pu, origBuf, puIdx, uiLastModeTemp, uiAffine6Cost, cMvHevcTemp, cMvHevcTempSolid, acMvAffine4Para, acMvAffine4ParaSolid, refIdx4Para, bcwIdx, enforceBcwPred,
+            ((cu.slice->getSPS()->getUseBcw() == true) ? getWeightIdxBits(bcwIdx) : 0));
+#else
           xPredAffineInterSearch(pu, origBuf, puIdx, uiLastModeTemp, uiAffine6Cost, cMvHevcTemp, acMvAffine4Para, refIdx4Para, bcwIdx, enforceBcwPred,
             ((cu.slice->getSPS()->getUseBcw() == true) ? getWeightIdxBits(bcwIdx) : 0));
+#endif
+
+          if ( pu.cu->imv == 0 )
+          {
+#if GDR_ENABLED
+            storeAffineMotion(pu.mvAffi, pu.mvAffiSolid, pu.refIdx, AFFINEMODEL_6PARAM, bcwIdx);
+#else
+            storeAffineMotion( pu.mvAffi, pu.refIdx, AFFINEMODEL_6PARAM, bcwIdx );
+#endif
+          }
+
+#if GDR_ENABLED
+          if (isEncodeGdrClean)
+          {
+            uiAffine6CostOk = true;
+
+            if (pu.interDir & 0x01)
+            {
+              uiAffine6CostOk = uiAffine6CostOk && pu.mvAffiSolid[0][0] && pu.mvAffiSolid[0][1] && pu.mvAffiSolid[0][2];
+              uiAffine6CostOk = uiAffine6CostOk && pu.mvAffiValid[0][0] && pu.mvAffiValid[0][1] && pu.mvAffiValid[0][2];
+            }
 
-          if ( pu.cu->imv == 0 )
+            if (pu.interDir & 0x02)
+            {
+              uiAffine6CostOk = uiAffine6CostOk && pu.mvAffiSolid[1][0] && pu.mvAffiSolid[1][1] && pu.mvAffiSolid[1][2];
+              uiAffine6CostOk = uiAffine6CostOk && pu.mvAffiValid[1][0] && pu.mvAffiValid[1][1] && pu.mvAffiValid[1][2];
+            }
+          }
+#endif
+
+#if GDR_ENABLED
+          allOk = (uiAffineCost <= uiAffine6Cost);
+          if (isEncodeGdrClean)
           {
-            storeAffineMotion( pu.mvAffi, pu.refIdx, AFFINEMODEL_6PARAM, bcwIdx );
+            if (uiAffineCostOk)
+            {
+              allOk = (uiAffine6CostOk) ? (uiAffineCost < uiHevcCost * 1.05) : true;
+            }
+            else
+            {
+              allOk = false;
+            }
           }
+#endif
 
           // reset to 4 parameter affine inter mode
+#if GDR_ENABLED
+          if (allOk && (uiAffineCost <= uiAffine6Cost))
+#else
           if ( uiAffineCost <= uiAffine6Cost )
+#endif
           {
             cu.affineType = AFFINEMODEL_4PARAM;
             pu.interDir = bestInterDir;
@@ -2989,10 +4379,37 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner)
 
             PU::setAllAffineMv( pu, bestMv[0][0], bestMv[0][1], bestMv[0][2], REF_PIC_LIST_0);
             PU::setAllAffineMv( pu, bestMv[1][0], bestMv[1][1], bestMv[1][2], REF_PIC_LIST_1);
+
+#if GDR_ENABLED
+            if (isEncodeGdrClean)
+            {
+              pu.mvAffiSolid[REF_PIC_LIST_0][0] = bestMvSolid[REF_PIC_LIST_0][0];
+              pu.mvAffiSolid[REF_PIC_LIST_0][1] = bestMvSolid[REF_PIC_LIST_0][1];
+              pu.mvAffiSolid[REF_PIC_LIST_0][2] = bestMvSolid[REF_PIC_LIST_0][2];
+
+              pu.mvAffiValid[REF_PIC_LIST_0][0] = bestMvValid[REF_PIC_LIST_0][0];
+              pu.mvAffiValid[REF_PIC_LIST_0][1] = bestMvValid[REF_PIC_LIST_0][1];
+              pu.mvAffiValid[REF_PIC_LIST_0][2] = bestMvValid[REF_PIC_LIST_0][2];
+
+              pu.mvAffiSolid[REF_PIC_LIST_1][0] = bestMvSolid[REF_PIC_LIST_1][0];
+              pu.mvAffiSolid[REF_PIC_LIST_1][1] = bestMvSolid[REF_PIC_LIST_1][1];
+              pu.mvAffiSolid[REF_PIC_LIST_1][2] = bestMvSolid[REF_PIC_LIST_1][2];
+
+              pu.mvAffiValid[REF_PIC_LIST_1][0] = bestMvValid[REF_PIC_LIST_1][0];
+              pu.mvAffiValid[REF_PIC_LIST_1][1] = bestMvValid[REF_PIC_LIST_1][1];
+              pu.mvAffiValid[REF_PIC_LIST_1][2] = bestMvValid[REF_PIC_LIST_1][2];
+            }
+#endif
           }
           else
           {
             uiAffineCost = uiAffine6Cost;
+#if GDR_ENABLED
+            if (isEncodeGdrClean)
+            {
+              uiAffineCostOk = uiAffine6CostOk;
+            }
+#endif
           }
         }
 
@@ -3006,7 +4423,26 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner)
           uiAffineCost = std::numeric_limits<Distortion>::max();
         }
       }
+#if GDR_ENABLED
+      allOk = (uiHevcCost <= uiAffineCost);
+      if (isEncodeGdrClean)
+      {
+        if (uiHevcCostOk)
+        {
+          allOk = (uiAffineCostOk) ? (uiHevcCost <= uiAffineCost) : true;
+        }
+        else
+        {
+          allOk = false;
+        }
+      }
+#endif
+
+#if GDR_ENABLED
+      if (allOk)
+#else
       if ( uiHevcCost <= uiAffineCost )
+#endif
       {
         // set hevc me result
         cu.affine = false;
@@ -3025,6 +4461,15 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner)
         pu.mvpNum[REF_PIC_LIST_1] = uiMvpNum[1];
         pu.mvd[REF_PIC_LIST_0] = cMvd[0];
         pu.mvd[REF_PIC_LIST_1] = cMvd[1];
+#if GDR_ENABLED
+        if (isEncodeGdrClean)
+        {
+          pu.mvSolid[REF_PIC_LIST_0] = cHevcMvFieldSolid[0];
+          pu.mvSolid[REF_PIC_LIST_1] = cHevcMvFieldSolid[1];
+          pu.mvValid[REF_PIC_LIST_0] = cHevcMvFieldValid[0];
+          pu.mvValid[REF_PIC_LIST_1] = cHevcMvFieldValid[1];
+        }
+#endif
       }
       else
       {
@@ -3043,9 +4488,7 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner)
     }
     m_maxCompIDToPred = MAX_NUM_COMPONENT;
 
-    {
-      PU::spanMotionInfo( pu, mergeCtx );
-    }
+    PU::spanMotionInfo(pu, mergeCtx);
 
     m_skipPROF = false;
     m_encOnly = false;
@@ -3093,6 +4536,25 @@ void InterSearch::xEstimateMvPredAMVP( PredictionUnit& pu, PelUnitBuf& origBuf,
   int        i;
 
   AMVPInfo*  pcAMVPInfo = &rAMVPInfo;
+#if GDR_ENABLED
+  const CodingStructure &cs = *pu.cs;
+  const bool isEncodeGdrClean = cs.sps->getGDREnabledFlag() && cs.pcv->isEncoder && ((cs.picHeader->getInGdrInterval() && cs.isClean(pu.Y().topRight(), CHANNEL_TYPE_LUMA)) || (cs.picHeader->getNumVerVirtualBoundaries() == 0));
+#endif
+
+#if GDR_ENABLED
+  if (isEncodeGdrClean)
+  {
+    pcAMVPInfo->allCandSolidInAbove = true;
+    for (int i = 0; i < AMVP_MAX_NUM_CANDS_MEM; i++)
+    {
+      pcAMVPInfo->mvSolid[i] = true;
+      pcAMVPInfo->mvValid[i] = true;
+    }
+  }
+
+  bool uiBestCostOk = false;
+  bool uiTmpCostOk = false;
+#endif
 
   // Fill the MV Candidates
   if (!bFilled)
@@ -3103,6 +4565,12 @@ void InterSearch::xEstimateMvPredAMVP( PredictionUnit& pu, PelUnitBuf& origBuf,
   // initialize Mvp index & Mvp
   iBestIdx = 0;
   cBestMv  = pcAMVPInfo->mvCand[0];
+#if GDR_ENABLED
+  if (isEncodeGdrClean)
+  {
+    uiBestCostOk = pcAMVPInfo->mvSolid[0];
+  }
+#endif
 
   PelUnitBuf predBuf = m_tmpStorageLCU.getBuf( UnitAreaRelative(*pu.cu, pu) );
 
@@ -3110,12 +4578,46 @@ void InterSearch::xEstimateMvPredAMVP( PredictionUnit& pu, PelUnitBuf& origBuf,
   for( i = 0 ; i < pcAMVPInfo->numCand; i++)
   {
     Distortion uiTmpCost = xGetTemplateCost( pu, origBuf, predBuf, pcAMVPInfo->mvCand[i], i, AMVP_MAX_NUM_CANDS, eRefPicList, iRefIdx );
+
+#if GDR_ENABLED
+    if (isEncodeGdrClean)
+    {
+      uiTmpCostOk = pcAMVPInfo->mvSolid[i];
+    }
+#endif
+
+#if GDR_ENABLED
+    bool allOk = (uiBestCost > uiTmpCost);
+
+    if (isEncodeGdrClean)
+    {
+      if (uiBestCostOk)
+      {
+        allOk = (uiTmpCostOk) ? (uiBestCost > uiTmpCost) : true;
+      }
+      else
+      {
+        allOk = false;
+      }
+    }
+#endif
+
+#if GDR_ENABLED
+    if (allOk)
+#else
     if( uiBestCost > uiTmpCost )
+#endif
     {
       uiBestCost     = uiTmpCost;
       cBestMv        = pcAMVPInfo->mvCand[i];
       iBestIdx       = i;
       (*puiDistBiP)  = uiTmpCost;
+#if GDR_ENABLED
+      if (isEncodeGdrClean)
+      {
+        uiBestCostOk = uiTmpCostOk;
+      }
+#endif
     }
   }
 
@@ -3124,6 +4626,13 @@ void InterSearch::xEstimateMvPredAMVP( PredictionUnit& pu, PelUnitBuf& origBuf,
   pu.mvpIdx[eRefPicList] = iBestIdx;
   pu.mvpNum[eRefPicList] = pcAMVPInfo->numCand;
 
+#if GDR_ENABLED
+  if (isEncodeGdrClean)
+  {
+    pu.mvpSolid[eRefPicList] = pcAMVPInfo->mvSolid[iBestIdx];
+  }
+#endif
+
   return;
 }
 
@@ -3168,11 +4677,28 @@ void InterSearch::xCopyAMVPInfo (AMVPInfo* pSrc, AMVPInfo* pDst)
   for (int i = 0; i < pSrc->numCand; i++)
   {
     pDst->mvCand[i] = pSrc->mvCand[i];
+#if GDR_ENABLED
+    pDst->mvPos[i] = pSrc->mvPos[i];
+    pDst->mvSolid[i] = pSrc->mvSolid[i];
+    pDst->mvValid[i] = pSrc->mvValid[i];
+    pDst->mvType[i] = pSrc->mvType[i];
+#endif
   }
 }
 
+#if GDR_ENABLED
+void InterSearch::xCheckBestMVP(PredictionUnit &pu, RefPicList eRefPicList, Mv cMv, Mv& rcMvPred, int& riMVPIdx, AMVPInfo& amvpInfo, uint32_t& ruiBits, Distortion& ruiCost, const uint8_t imv)
+#else
 void InterSearch::xCheckBestMVP ( RefPicList eRefPicList, Mv cMv, Mv& rcMvPred, int& riMVPIdx, AMVPInfo& amvpInfo, uint32_t& ruiBits, Distortion& ruiCost, const uint8_t imv )
+#endif
 {
+#if GDR_ENABLED
+  const CodingStructure &cs = *pu.cs;
+  const bool isEncodeGdrClean = cs.sps->getGDREnabledFlag() && cs.pcv->isEncoder && ((cs.picHeader->getInGdrInterval() && cs.isClean(pu.Y().topRight(), CHANNEL_TYPE_LUMA)) || (cs.picHeader->getNumVerVirtualBoundaries() == 0));
+  bool iBestMvBitsOk = false;
+  bool iMvBitsOk = false;
+#endif
+
   if ( imv > 0 && imv < 3 )
   {
     return;
@@ -3199,6 +4725,12 @@ void InterSearch::xCheckBestMVP ( RefPicList eRefPicList, Mv cMv, Mv& rcMvPred,
   int iOrgMvBits = m_pcRdCost->getBitsOfVectorWithPredictor(mv.getHor(), mv.getVer(), 0);
   iOrgMvBits += m_auiMVPIdxCost[riMVPIdx][AMVP_MAX_NUM_CANDS];
   int iBestMvBits = iOrgMvBits;
+#if GDR_ENABLED
+  if (isEncodeGdrClean)
+  {
+    iBestMvBitsOk = pcAMVPInfo->mvSolid[riMVPIdx];
+  }
+#endif
 
   for (int iMVPIdx = 0; iMVPIdx < pcAMVPInfo->numCand; iMVPIdx++)
   {
@@ -3213,10 +4745,36 @@ void InterSearch::xCheckBestMVP ( RefPicList eRefPicList, Mv cMv, Mv& rcMvPred,
     int iMvBits = m_pcRdCost->getBitsOfVectorWithPredictor(mv.getHor(), mv.getVer(), 0);
     iMvBits += m_auiMVPIdxCost[iMVPIdx][AMVP_MAX_NUM_CANDS];
 
+#if GDR_ENABLED
+    bool allOk = (iMvBits < iBestMvBits);
+    if (isEncodeGdrClean)
+    {
+      iMvBitsOk = pcAMVPInfo->mvSolid[iMVPIdx];
+      if (iMvBitsOk)
+      {
+        allOk = (iBestMvBitsOk) ? (iMvBits < iBestMvBits) : true;
+      }
+      else
+      {
+        allOk = false;
+      }
+    }
+#endif
+
+#if GDR_ENABLED
+    if (allOk)
+#else
     if (iMvBits < iBestMvBits)
+#endif
     {
       iBestMvBits = iMvBits;
       iBestMVPIdx = iMVPIdx;
+#if GDR_ENABLED
+      if (isEncodeGdrClean)
+      {
+        iBestMvBitsOk = iMvBitsOk;
+      }
+#endif
     }
   }
 
@@ -3250,11 +4808,7 @@ Distortion InterSearch::xGetTemplateCost( const PredictionUnit& pu,
   // prediction pattern
   const bool bi = pu.cu->slice->testWeightPred() && pu.cu->slice->getSliceType()==P_SLICE;
 
-
-  xPredInterBlk( COMPONENT_Y, pu, picRef, cMvCand, predBuf, bi, pu.cu->slice->clpRng( COMPONENT_Y )
-                , false
-                , false
-                );
+  xPredInterBlk(COMPONENT_Y, pu, picRef, cMvCand, predBuf, bi, pu.cu->slice->clpRng(COMPONENT_Y), false, false);
 
   if ( bi )
   {
@@ -3269,7 +4823,11 @@ Distortion InterSearch::xGetTemplateCost( const PredictionUnit& pu,
   return uiCost;
 }
 
+#if GDR_ENABLED
+Distortion InterSearch::xGetAffineTemplateCost(PredictionUnit& pu, PelUnitBuf& origBuf, PelUnitBuf& predBuf, Mv acMvCand[3], int iMVPIdx, int iMVPNum, RefPicList eRefPicList, int iRefIdx, bool& rbOk)
+#else
 Distortion InterSearch::xGetAffineTemplateCost( PredictionUnit& pu, PelUnitBuf& origBuf, PelUnitBuf& predBuf, Mv acMvCand[3], int iMVPIdx, int iMVPNum, RefPicList eRefPicList, int iRefIdx )
+#endif
 {
   Distortion uiCost = std::numeric_limits<Distortion>::max();
 
@@ -3280,7 +4838,12 @@ Distortion InterSearch::xGetAffineTemplateCost( PredictionUnit& pu, PelUnitBuf&
   Mv mv[3];
   memcpy(mv, acMvCand, sizeof(mv));
   m_iRefListIdx = eRefPicList;
+
+#if GDR_ENABLED
+  rbOk = xPredAffineBlk(COMPONENT_Y, pu, picRef, mv, predBuf, bi, pu.cu->slice->clpRng(COMPONENT_Y));
+#else
   xPredAffineBlk(COMPONENT_Y, pu, picRef, mv, predBuf, bi, pu.cu->slice->clpRng(COMPONENT_Y));
+#endif
   if( bi )
   {
     xWeightedPredictionUni( pu, predBuf, eRefPicList, predBuf, iRefIdx, m_maxCompIDToPred );
@@ -3296,9 +4859,17 @@ Distortion InterSearch::xGetAffineTemplateCost( PredictionUnit& pu, PelUnitBuf&
   return uiCost;
 }
 
+#if GDR_ENABLED
+void InterSearch::xMotionEstimation(PredictionUnit& pu, PelUnitBuf& origBuf, RefPicList eRefPicList, Mv& rcMvPred, int iRefIdxPred, Mv& rcMv, bool &rcMvSolid, int& riMVPIdx, uint32_t& ruiBits, Distortion& ruiCost, const AMVPInfo& amvpInfo, bool& rbCleanCandExist, bool bBi)
+#else
 void InterSearch::xMotionEstimation(PredictionUnit& pu, PelUnitBuf& origBuf, RefPicList eRefPicList, Mv& rcMvPred, int iRefIdxPred, Mv& rcMv, int& riMVPIdx, uint32_t& ruiBits, Distortion& ruiCost, const AMVPInfo& amvpInfo, bool bBi)
+#endif
 {
+#if GDR_ENABLED
+  if (pu.cu->cs->sps->getUseBcw() && pu.cu->BcwIdx != BCW_DEFAULT && !bBi && xReadBufferedUniMv(pu, eRefPicList, iRefIdxPred, rcMvPred, rcMv, rcMvSolid, ruiBits, ruiCost))
+#else
   if( pu.cu->cs->sps->getUseBcw() && pu.cu->BcwIdx != BCW_DEFAULT && !bBi && xReadBufferedUniMv(pu, eRefPicList, iRefIdxPred, rcMvPred, rcMv, ruiBits, ruiCost) )
+#endif
   {
     return;
   }
@@ -3408,7 +4979,9 @@ void InterSearch::xMotionEstimation(PredictionUnit& pu, PelUnitBuf& origBuf, Ref
         }
       }
       if (j < i)
+      {
         continue;
+      }
 
       cTmpMv = curMvInfo->uniMvs[eRefPicList][iRefIdxPred];
       clipMv( cTmpMv, pu.cu->lumaPos(), pu.cu->lumaSize(), *pu.cs->sps, *pu.cs->pps );
@@ -3427,7 +5000,11 @@ void InterSearch::xMotionEstimation(PredictionUnit& pu, PelUnitBuf& origBuf, Ref
 
     if( !bQTBTMV )
     {
+#if GDR_ENABLED
+      xSetSearchRange(pu, bestInitMv, iSrchRng, cStruct.searchRange, cStruct, eRefPicList, iRefIdxPred);
+#else
       xSetSearchRange(pu, bestInitMv, iSrchRng, cStruct.searchRange, cStruct);
+#endif
     }
     xPatternSearch( cStruct, rcMv, ruiCost);
   }
@@ -3473,7 +5050,11 @@ void InterSearch::xMotionEstimation(PredictionUnit& pu, PelUnitBuf& origBuf, Ref
         MCTSHelper::clipMvToArea( rcMv, pu.Y(), curTileAreaSubPelRestricted, *pu.cs->sps, 0 );
       }
     }
+#if GDR_ENABLED
+    xPatternSearchFracDIF(pu, eRefPicList, iRefIdxPred, cStruct, rcMv, cMvHalf, cMvQter, ruiCost, rbCleanCandExist);
+#else
     xPatternSearchFracDIF( pu, eRefPicList, iRefIdxPred, cStruct, rcMv, cMvHalf, cMvQter, ruiCost );
+#endif
     m_pcRdCost->setCostScale( 0 );
     rcMv <<= 2;
     rcMv  += ( cMvHalf <<= 1 );
@@ -3486,7 +5067,11 @@ void InterSearch::xMotionEstimation(PredictionUnit& pu, PelUnitBuf& origBuf, Ref
   else // integer refinement for integer-pel and 4-pel resolution
   {
     rcMv.changePrecision(MV_PRECISION_INT, MV_PRECISION_INTERNAL);
+#if GDR_ENABLED
+    xPatternSearchIntRefine(pu, cStruct, rcMv, rcMvPred, riMVPIdx, ruiBits, ruiCost, amvpInfo, fWeight, eRefPicList, iRefIdxPred, rbCleanCandExist);
+#else
     xPatternSearchIntRefine( pu, cStruct, rcMv, rcMvPred, riMVPIdx, ruiBits, ruiCost, amvpInfo, fWeight);
+#endif
   }
   DTRACE(g_trace_ctx, D_ME, "   MECost<L%d,%d>: %6d (%d)  MV:%d,%d\n", (int)eRefPicList, (int)bBi, ruiCost, ruiBits, rcMv.getHor() << 2, rcMv.getVer() << 2);
 }
@@ -3498,14 +5083,61 @@ void InterSearch::xSetSearchRange ( const PredictionUnit& pu,
                                     const int iSrchRng,
                                     SearchRange& sr
                                   , IntTZSearchStruct& cStruct
+#if GDR_ENABLED
+                                  , RefPicList eRefPicList
+                                  , int iRefIdx
+#endif
 )
 {
   const int iMvShift = MV_FRACTIONAL_BITS_INTERNAL;
   Mv cFPMvPred = cMvPred;
   clipMv( cFPMvPred, pu.cu->lumaPos(), pu.cu->lumaSize(), *pu.cs->sps, *pu.cs->pps );
-  
+
   Mv mvTL(cFPMvPred.getHor() - (iSrchRng << iMvShift), cFPMvPred.getVer() - (iSrchRng << iMvShift));
   Mv mvBR(cFPMvPred.getHor() + (iSrchRng << iMvShift), cFPMvPred.getVer() + (iSrchRng << iMvShift));
+#if GDR_ENABLED
+  if (m_pcEncCfg->getGdrEnabled())
+  {
+    bool isRefGdrPicture = pu.cs->slice->getRefPic(eRefPicList, iRefIdx)->cs->picHeader->getInGdrInterval();
+    if (isRefGdrPicture)
+    {
+      mvTL = { cFPMvPred.getHor(), cFPMvPred.getVer() };
+      mvBR = { cFPMvPred.getHor(), cFPMvPred.getVer() };
+
+      const int lumaPixelAway = 4;
+      const int chromaPixelAway = 5;
+
+      const Position LastPos = pu.Y().bottomRight();
+
+      const int iMvShift = MV_FRACTIONAL_BITS_INTERNAL;
+      const int iMvLumaFrac = (1 << iMvShift);
+      const int iMvChromaFrac = (iMvLumaFrac << 1);
+      const int iFracOne = (1 << iMvShift);
+
+      const bool isIntLumaMv = (cFPMvPred.getHor() % iMvLumaFrac) == 0;
+      const bool isIntChromaMv = (cFPMvPred.getHor() % iMvChromaFrac) == 0;
+
+      const int scaled_endx = pu.cs->slice->getRefPic(eRefPicList, iRefIdx)->cs->picHeader->getVirtualBoundariesPosX(0) << iMvShift;
+
+      const Position OrigFracPos = Position(LastPos.x << iMvShift, LastPos.y << iMvShift);
+      const int last_luma_pos = ((OrigFracPos.x / iMvLumaFrac)   * iMvLumaFrac) + cFPMvPred.getHor() + (isIntLumaMv ? 0 : (lumaPixelAway << iMvShift));
+      const int last_chroma_pos = ((OrigFracPos.x / iMvChromaFrac) * iMvChromaFrac) + cFPMvPred.getHor() + (isIntChromaMv ? 0 : (chromaPixelAway << iMvShift));
+
+      const int last_pel_pos = std::max(last_luma_pos, last_chroma_pos);
+
+      const int distance = Clip3(-(iSrchRng << iMvShift), (iSrchRng << iMvShift), scaled_endx - (last_pel_pos + iFracOne));
+
+
+      int srLeft = cFPMvPred.getHor() - (iSrchRng << iMvShift);
+      int srRight = cFPMvPred.getHor() + distance;
+      int srTop = cFPMvPred.getVer() - (iSrchRng << iMvShift);
+      int srBottom = cFPMvPred.getVer() + (iSrchRng << iMvShift);
+
+      mvTL = { srLeft, srTop };
+      mvBR = { srRight, srBottom };
+    }
+  }
+#endif
 
   if (m_pcEncCfg->getMCTSEncConstraint())
   {
@@ -3514,16 +5146,8 @@ void InterSearch::xSetSearchRange ( const PredictionUnit& pu,
   }
   else
   {
-    xClipMv( mvTL, pu.cu->lumaPos(),
-            pu.cu->lumaSize(),
-            *pu.cs->sps
-          , *pu.cs->pps
-    );
-    xClipMv( mvBR, pu.cu->lumaPos(),
-            pu.cu->lumaSize(),
-            *pu.cs->sps
-          , *pu.cs->pps
-    );
+    xClipMv(mvTL, pu.cu->lumaPos(), pu.cu->lumaSize(), *pu.cs->sps, *pu.cs->pps);
+    xClipMv(mvBR, pu.cu->lumaPos(), pu.cu->lumaSize(), *pu.cs->sps, *pu.cs->pps);
   }
 
   mvTL.divideByPowerOf2( iMvShift );
@@ -3542,13 +5166,21 @@ void InterSearch::xSetSearchRange ( const PredictionUnit& pu,
     Position posRBinCTU(posRB.x & pcv->maxCUWidthMask, posRB.y & pcv->maxCUHeightMask);
     Position posLTinCTU = Position(posTL.x & pcv->maxCUWidthMask, posTL.y & pcv->maxCUHeightMask).offset(-4, -4);
     if (sr.left < -posLTinCTU.x)
+    {
       sr.left = -posLTinCTU.x;
+    }
     if (sr.top < -posLTinCTU.y)
+    {
       sr.top = -posLTinCTU.y;
+    }
     if (sr.right >((int)pcv->maxCUWidth - 4 - posRBinCTU.x))
+    {
       sr.right = (int)pcv->maxCUWidth - 4 - posRBinCTU.x;
+    }
     if (sr.bottom >((int)pcv->maxCUHeight - 4 - posRBinCTU.y))
+    {
       sr.bottom = (int)pcv->maxCUHeight - 4 - posRBinCTU.y;
+    }
     if (posLTinCTU.x == -4 || posLTinCTU.y == -4)
     {
       sr.left = sr.right = sr.bottom = sr.top = 0;
@@ -3670,6 +5302,10 @@ void InterSearch::xTZSearch( const PredictionUnit& pu,
   const uint32_t uiStarRefinementRounds                  = 2;  // star refinement stop X rounds after best match (must be >=1)
   const bool bNewZeroNeighbourhoodTest               = bExtendedSettings;
 
+#if GDR_ENABLED
+  const CodingStructure &cs = *pu.cs;
+  const bool isEncodeGdrClean = cs.sps->getGDREnabledFlag() && cs.pcv->isEncoder && ((cs.picHeader->getInGdrInterval() && cs.isClean(pu.Y().topRight(), CHANNEL_TYPE_LUMA)) || (cs.picHeader->getNumVerVirtualBoundaries() == 0));
+#endif
   int iSearchRange = m_iSearchRange;
   if( m_pcEncCfg->getMCTSEncConstraint() )
   {
@@ -3745,7 +5381,9 @@ void InterSearch::xTZSearch( const PredictionUnit& pu,
       }
     }
     if (j < i)
+    {
       continue;
+    }
 
     Mv cTmpMv = curMvInfo->uniMvs[eRefPicList][iRefIdxPred];
     clipMv( cTmpMv, pu.cu->lumaPos(), pu.cu->lumaSize(), *pu.cs->sps, *pu.cs->pps );
@@ -3754,6 +5392,37 @@ void InterSearch::xTZSearch( const PredictionUnit& pu,
 
     Distortion uiSad = m_cDistParam.distFunc(m_cDistParam);
     uiSad += m_pcRdCost->getCostOfVectorWithPredictor(cTmpMv.hor, cTmpMv.ver, cStruct.imvShift);
+#if GDR_ENABLED
+    bool allOk = (uiSad < cStruct.uiBestSad);
+
+    if (isEncodeGdrClean)
+    {
+      Mv motion = cTmpMv;
+      motion.changePrecision(MV_PRECISION_INT, MV_PRECISION_INTERNAL);
+      bool cTmpMvOk = cs.isClean(pu.Y().bottomRight(), motion, eRefPicList, iRefIdxPred);
+
+      Mv bestMv = { cStruct.iBestX, cStruct.iBestY };
+      bestMv.changePrecision(MV_PRECISION_INT, MV_PRECISION_INTERNAL);
+      bool bestMvOk = cs.isClean(pu.Y().bottomRight(), bestMv, eRefPicList, iRefIdxPred);
+
+      if (cTmpMvOk)
+      {
+        allOk = (bestMvOk) ? (uiSad < cStruct.uiBestSad) : true;
+      }
+      else
+      {
+        allOk = false;
+      }
+    }
+
+    if (allOk)
+    {
+      cStruct.uiBestSad = uiSad;
+      cStruct.iBestX = cTmpMv.hor;
+      cStruct.iBestY = cTmpMv.ver;
+      m_cDistParam.maximumDistortionForEarlyExit = uiSad;
+    }
+#else
     if (uiSad < cStruct.uiBestSad)
     {
       cStruct.uiBestSad = uiSad;
@@ -3761,13 +5430,18 @@ void InterSearch::xTZSearch( const PredictionUnit& pu,
       cStruct.iBestY = cTmpMv.ver;
       m_cDistParam.maximumDistortionForEarlyExit = uiSad;
     }
+#endif
   }
 
   {
     // set search range
     Mv currBestMv(cStruct.iBestX, cStruct.iBestY );
     currBestMv <<= MV_FRACTIONAL_BITS_INTERNAL;
+#if GDR_ENABLED
+    xSetSearchRange(pu, currBestMv, m_iSearchRange >> (bFastSettings ? 1 : 0), sr, cStruct, eRefPicList, iRefIdxPred);
+#else
     xSetSearchRange(pu, currBestMv, m_iSearchRange >> (bFastSettings ? 1 : 0), sr, cStruct);
+#endif
   }
   if (m_pcEncCfg->getUseHashME() && (m_currRefPicList == 0 || pu.cu->slice->getList1IdxToList0Idx(m_currRefPicIndex) < 0))
   {
@@ -4033,7 +5707,6 @@ void InterSearch::xTZSearchSelective( const PredictionUnit& pu,
     integerMv2Nx2NPred.divideByPowerOf2(2);
 
     xTZSearchHelp( cStruct, integerMv2Nx2NPred.getHor(), integerMv2Nx2NPred.getVer(), 0, 0);
-
   }
 
   for (int i = 0; i < m_uniMvListSize; i++)
@@ -4050,7 +5723,9 @@ void InterSearch::xTZSearchSelective( const PredictionUnit& pu,
       }
     }
     if (j < i)
+    {
       continue;
+    }
 
     Mv cTmpMv = curMvInfo->uniMvs[eRefPicList][iRefIdxPred];
     clipMv( cTmpMv, pu.cu->lumaPos(), pu.cu->lumaSize(), *pu.cs->sps, *pu.cs->pps );
@@ -4072,7 +5747,11 @@ void InterSearch::xTZSearchSelective( const PredictionUnit& pu,
     // set search range
     Mv currBestMv(cStruct.iBestX, cStruct.iBestY );
     currBestMv <<= 2;
+#if GDR_ENABLED
+    xSetSearchRange(pu, currBestMv, m_iSearchRange, sr, cStruct, eRefPicList, iRefIdxPred);
+#else
     xSetSearchRange( pu, currBestMv, m_iSearchRange, sr, cStruct );
+#endif
   }
   if (m_pcEncCfg->getUseHashME() && (m_currRefPicList == 0 || pu.cu->slice->getList1IdxToList0Idx(m_currRefPicIndex) < 0))
   {
@@ -4169,8 +5848,16 @@ void InterSearch::xTZSearchSelective( const PredictionUnit& pu,
   ruiSAD = cStruct.uiBestSad - m_pcRdCost->getCostOfVectorWithPredictor( cStruct.iBestX, cStruct.iBestY, cStruct.imvShift );
 }
 
+#if GDR_ENABLED
+void InterSearch::xPatternSearchIntRefine(PredictionUnit& pu, IntTZSearchStruct&  cStruct, Mv& rcMv, Mv& rcMvPred, int& riMVPIdx, uint32_t& ruiBits, Distortion& ruiCost, const AMVPInfo& amvpInfo, double fWeight, RefPicList eRefPicList, int iRefIdxPred, bool& rbCleanCandExist)
+#else
 void InterSearch::xPatternSearchIntRefine(PredictionUnit& pu, IntTZSearchStruct&  cStruct, Mv& rcMv, Mv& rcMvPred, int& riMVPIdx, uint32_t& ruiBits, Distortion& ruiCost, const AMVPInfo& amvpInfo, double fWeight)
+#endif
 {
+#if GDR_ENABLED
+  const CodingStructure &cs = *pu.cs;
+  const bool isEncodeGdrClean = cs.sps->getGDREnabledFlag() && cs.pcv->isEncoder && ((cs.picHeader->getInGdrInterval() && cs.isClean(pu.Y().topRight(), CHANNEL_TYPE_LUMA)) || (cs.picHeader->getNumVerVirtualBoundaries() == 0));
+#endif
 
   CHECK( pu.cu->imv == 0 || pu.cu->imv == IMV_HPEL , "xPatternSearchIntRefine(): Sub-pel MV used.");
   CHECK( amvpInfo.mvCand[riMVPIdx] != rcMvPred, "xPatternSearchIntRefine(): MvPred issue.");
@@ -4202,6 +5889,11 @@ void InterSearch::xPatternSearchIntRefine(PredictionUnit& pu, IntTZSearchStruct&
   cBaseMvd[1].roundTransPrecInternal2Amvr(pu.cu->imv);
 
   // test best integer position and all 8 neighboring positions
+#if GDR_ENABLED
+  bool allOk = true;
+  bool uiDistOk = false;
+  bool uiBestDistOk = false;
+#endif
   for (int pos = 0; pos < 9; pos ++)
   {
     Mv cTestMv[2];
@@ -4249,12 +5941,42 @@ void InterSearch::xPatternSearchIntRefine(PredictionUnit& pu, IntTZSearchStruct&
       iMvBits += m_pcRdCost->getBitsOfVectorWithPredictor( mv.getHor(), mv.getVer(), 0 );
       uiDist += m_pcRdCost->getCost(iMvBits);
 
+#if GDR_ENABLED
+      allOk = (uiDist < uiBestDist);
+      if (isEncodeGdrClean)
+      {
+        bool isSolid = amvpInfo.mvSolid[iMVPIdx];
+        bool isValid = cs.isClean(pu.Y().bottomRight(), cTestMv[iMVPIdx], eRefPicList, iRefIdxPred);
+
+        uiDistOk = isSolid && isValid;
+        if (uiDistOk)
+        {
+          allOk = (uiBestDistOk) ? (uiDist < uiBestDist) : true;
+        }
+        else
+        {
+          allOk = false;
+        }
+      }
+#endif
+
+#if GDR_ENABLED
+      if (allOk)
+#else
       if (uiDist < uiBestDist)
+#endif
       {
         uiBestDist = uiDist;
         cBestMv = cTestMv[iMVPIdx];
         iBestMVPIdx = iMVPIdx;
         iBestBits = iMvBits;
+#if GDR_ENABLED
+        if (isEncodeGdrClean)
+        {
+          uiBestDistOk = uiDistOk;
+          rbCleanCandExist = true;
+        }
+#endif
       }
     }
   }
@@ -4290,6 +6012,9 @@ void InterSearch::xPatternSearchFracDIF(
   Mv&                   rcMvHalf,
   Mv&                   rcMvQter,
   Distortion&           ruiCost
+#if GDR_ENABLED
+  , bool&                rbCleanCandExist
+#endif
 )
 {
 
@@ -4303,7 +6028,11 @@ void InterSearch::xPatternSearchFracDIF(
     m_pcRdCost->setCostScale(0);
     xExtDIFUpSamplingH(&cPatternRoi, cStruct.useAltHpelIf);
     rcMvQter = rcMvInt;   rcMvQter <<= 2;    // for mv-cost
+#if GDR_ENABLED
+    ruiCost = xPatternRefinement(pu, eRefPicList, iRefIdx, cStruct.pcPatternKey, baseRefMv, 1, rcMvQter, !pu.cs->slice->getDisableSATDForRD(), rbCleanCandExist);
+#else
     ruiCost = xPatternRefinement(cStruct.pcPatternKey, baseRefMv, 1, rcMvQter, !pu.cs->slice->getDisableSATDForRD());
+#endif
     return;
   }
 
@@ -4322,19 +6051,29 @@ void InterSearch::xPatternSearchFracDIF(
 
   rcMvHalf = rcMvInt;   rcMvHalf <<= 1;    // for mv-cost
   Mv baseRefMv(0, 0);
+#if GDR_ENABLED
+  ruiCost = xPatternRefinement(pu, eRefPicList, iRefIdx, cStruct.pcPatternKey, baseRefMv, 2, rcMvHalf, (!pu.cs->slice->getDisableSATDForRD()), rbCleanCandExist);
+#else
   ruiCost = xPatternRefinement(cStruct.pcPatternKey, baseRefMv, 2, rcMvHalf, (!pu.cs->slice->getDisableSATDForRD()));
+#endif
 
   //  quarter-pel refinement
   if (cStruct.imvShift == IMV_OFF)
   {
-  m_pcRdCost->setCostScale( 0 );
-  xExtDIFUpSamplingQ ( &cPatternRoi, rcMvHalf );
-  baseRefMv = rcMvHalf;
-  baseRefMv <<= 1;
-
-  rcMvQter = rcMvInt;    rcMvQter <<= 1;    // for mv-cost
-  rcMvQter += rcMvHalf;  rcMvQter <<= 1;
-  ruiCost = xPatternRefinement(cStruct.pcPatternKey, baseRefMv, 1, rcMvQter, (!pu.cs->slice->getDisableSATDForRD()));
+    m_pcRdCost->setCostScale(0);
+    xExtDIFUpSamplingQ(&cPatternRoi, rcMvHalf);
+    baseRefMv = rcMvHalf;
+    baseRefMv <<= 1;
+
+    rcMvQter = rcMvInt;
+    rcMvQter <<= 1;   // for mv-cost
+    rcMvQter += rcMvHalf;
+    rcMvQter <<= 1;
+#if GDR_ENABLED
+    ruiCost = xPatternRefinement(pu, eRefPicList, iRefIdx, cStruct.pcPatternKey, baseRefMv, 1, rcMvQter, (!pu.cs->slice->getDisableSATDForRD()), rbCleanCandExist);
+#else
+    ruiCost = xPatternRefinement(cStruct.pcPatternKey, baseRefMv, 1, rcMvQter, (!pu.cs->slice->getDisableSATDForRD()));
+#endif
   }
 }
 
@@ -4390,9 +6129,20 @@ Distortion InterSearch::xGetSymmetricCost( PredictionUnit& pu, PelUnitBuf& origB
   return(cost);
 }
 
+#if GDR_ENABLED
+Distortion InterSearch::xSymmeticRefineMvSearch( PredictionUnit &pu, PelUnitBuf& origBuf, Mv& rcMvCurPred, Mv& rcMvTarPred
+  , RefPicList eRefPicList, MvField& rCurMvField, MvField& rTarMvField, Distortion uiMinCost, int SearchPattern, int nSearchStepShift, uint32_t uiMaxSearchRounds, int bcwIdx, bool& rOk)
+#else
 Distortion InterSearch::xSymmeticRefineMvSearch( PredictionUnit &pu, PelUnitBuf& origBuf, Mv& rcMvCurPred, Mv& rcMvTarPred
   , RefPicList eRefPicList, MvField& rCurMvField, MvField& rTarMvField, Distortion uiMinCost, int SearchPattern, int nSearchStepShift, uint32_t uiMaxSearchRounds, int bcwIdx )
+#endif
 {
+#if GDR_ENABLED
+  const CodingStructure &cs = *pu.cs;
+  const bool isEncodeGdrClean = cs.sps->getGDREnabledFlag() && cs.pcv->isEncoder && ((cs.picHeader->getInGdrInterval() && cs.isClean(pu.Y().topRight(), CHANNEL_TYPE_LUMA)) || (cs.picHeader->getNumVerVirtualBoundaries() == 0));
+  bool uiCostOk;
+  bool uiMinCostOk = rOk;
+#endif
   const Mv mvSearchOffsetCross[4] = { Mv( 0 , 1 ) , Mv( 1 , 0 ) , Mv( 0 , -1 ) , Mv( -1 ,  0 ) };
   const Mv mvSearchOffsetSquare[8] = { Mv( -1 , 1 ) , Mv( 0 , 1 ) , Mv( 1 ,  1 ) , Mv( 1 ,  0 ) , Mv( 1 , -1 ) , Mv( 0 , -1 ) , Mv( -1 , -1 ) , Mv( -1 , 0 ) };
   const Mv mvSearchOffsetDiamond[8] = { Mv( 0 , 2 ) , Mv( 1 , 1 ) , Mv( 2 ,  0 ) , Mv( 1 , -1 ) , Mv( 0 , -2 ) , Mv( -1 , -1 ) , Mv( -2 ,  0 ) , Mv( -1 , 1 ) };
@@ -4468,6 +6218,10 @@ Distortion InterSearch::xSymmeticRefineMvSearch( PredictionUnit &pu, PelUnitBuf&
       uint32_t uiMvBits = m_pcRdCost->getBitsOfVectorWithPredictor( mv.getHor(), mv.getVer(), 0 );
       Distortion uiCost = m_pcRdCost->getCost( uiMvBits );
 
+#if GDR_ENABLED
+      uiCostOk = cs.isClean(pu.Y().bottomRight(), mvCand.mv, eRefPicList, mvCand.refIdx);
+#endif
+
       // get MVD pair and set target MV
       mvPair.refIdx = rTarMvField.refIdx;
       mvPair.mv.set( rcMvTarPred.hor - (mvCand.mv.hor - rcMvCurPred.hor), rcMvTarPred.ver - (mvCand.mv.ver - rcMvCurPred.ver) );
@@ -4477,12 +6231,33 @@ Distortion InterSearch::xSymmeticRefineMvSearch( PredictionUnit &pu, PelUnitBuf&
           continue; // Skip this this pos
       }
       uiCost += xGetSymmetricCost( pu, origBuf, eRefPicList, mvCand, mvPair, bcwIdx );
+
+#if GDR_ENABLED
+      bool allOk = (uiCost < uiMinCost);
+      if (isEncodeGdrClean)
+      {
+        bool curValid = cs.isClean(pu.Y().bottomRight(), mvCand.mv, (RefPicList)(eRefPicList), mvCand.refIdx);
+        bool tarValid = cs.isClean(pu.Y().bottomRight(), mvPair.mv, (RefPicList)(1 - eRefPicList), mvPair.refIdx);
+        allOk = curValid && tarValid;
+      }
+#endif
+
+#if GDR_ENABLED
+      if (allOk)
+#else
       if ( uiCost < uiMinCost )
+#endif
       {
         uiMinCost = uiCost;
         rCurMvField = mvCand;
         rTarMvField = mvPair;
         nBestDirect = nDirect;
+#if GDR_ENABLED
+        if (isEncodeGdrClean)
+        {
+          uiMinCostOk = uiCostOk;
+        }
+#endif
       }
     }
 
@@ -4499,11 +6274,19 @@ Distortion InterSearch::xSymmeticRefineMvSearch( PredictionUnit &pu, PelUnitBuf&
     nDirectEnd = nBestDirect + nStep;
   }
 
+#if GDR_ENABLED
+  rOk = uiMinCostOk;
+#endif
+
   return(uiMinCost);
 }
 
 
+#if GDR_ENABLED
+bool InterSearch::xSymmetricMotionEstimation(PredictionUnit& pu, PelUnitBuf& origBuf, Mv& rcMvCurPred, Mv& rcMvTarPred, RefPicList eRefPicList, MvField& rCurMvField, MvField& rTarMvField, Distortion& ruiCost, int bcwIdx, bool& ruiCostOk)
+#else
 void InterSearch::xSymmetricMotionEstimation( PredictionUnit& pu, PelUnitBuf& origBuf, Mv& rcMvCurPred, Mv& rcMvTarPred, RefPicList eRefPicList, MvField& rCurMvField, MvField& rTarMvField, Distortion& ruiCost, int bcwIdx )
+#endif
 {
   // Refine Search
   int nSearchStepShift = MV_FRACTIONAL_BITS_DIFF;
@@ -4513,8 +6296,17 @@ void InterSearch::xSymmetricMotionEstimation( PredictionUnit& pu, PelUnitBuf& or
   nSearchStepShift += pu.cu->imv == IMV_HPEL ? 1 : (pu.cu->imv << 1);
   nDiamondRound >>= pu.cu->imv;
 
+#if GDR_ENABLED
+  ruiCost = xSymmeticRefineMvSearch(pu, origBuf, rcMvCurPred, rcMvTarPred, eRefPicList, rCurMvField, rTarMvField, ruiCost, 2, nSearchStepShift, nDiamondRound, bcwIdx, ruiCostOk);
+  ruiCost = xSymmeticRefineMvSearch(pu, origBuf, rcMvCurPred, rcMvTarPred, eRefPicList, rCurMvField, rTarMvField, ruiCost, 0, nSearchStepShift, nCrossRound, bcwIdx, ruiCostOk);
+#else
   ruiCost = xSymmeticRefineMvSearch( pu, origBuf, rcMvCurPred, rcMvTarPred, eRefPicList, rCurMvField, rTarMvField, ruiCost, 2, nSearchStepShift, nDiamondRound, bcwIdx );
   ruiCost = xSymmeticRefineMvSearch( pu, origBuf, rcMvCurPred, rcMvTarPred, eRefPicList, rCurMvField, rTarMvField, ruiCost, 0, nSearchStepShift, nCrossRound, bcwIdx );
+#endif
+
+#if GDR_ENABLED
+  return ruiCostOk;
+#endif
 }
 
 void InterSearch::xPredAffineInterSearch( PredictionUnit&       pu,
@@ -4523,7 +6315,13 @@ void InterSearch::xPredAffineInterSearch( PredictionUnit&       pu,
                                           uint32_t&                 lastMode,
                                           Distortion&           affineCost,
                                           Mv                    hevcMv[2][33]
+#if GDR_ENABLED
+                                        , bool                  hevcMvSolid[2][33]
+#endif
                                         , Mv                    mvAffine4Para[2][33][3]
+#if GDR_ENABLED
+                                        , bool                  mvAffine4ParaSolid[2][33][3]
+#endif
                                         , int                   refIdx4Para[2]
                                         , uint8_t               bcwIdx
                                         , bool                  enforceBcwPred
@@ -4551,6 +6349,27 @@ void InterSearch::xPredAffineInterSearch( PredictionUnit&       pu,
   int       aaiMvpIdx[2][33];
   int       aaiMvpNum[2][33];
 
+#if GDR_ENABLED
+  bool      aacMvSolid[2][3];
+  bool      aacMvValid[2][3];
+
+  bool      cMvTempSolid[2][33][3];
+  bool      cMvTempValid[2][33][3];
+
+  bool      cMvBiSolid[2][3];
+  bool      cMvBiValid[2][3];
+
+  bool      cMvPredSolid[2][33][3];
+  bool      cMvPredBiSolid[2][33][3];
+
+  bool      mvValidList1Solid[3];
+  bool      mvValidList1Valid[3];
+
+  bool      mvHevcSolid[3];
+
+  const CodingStructure &cs = *pu.cs;
+  const bool isEncodeGdrClean = cs.sps->getGDREnabledFlag() && cs.pcv->isEncoder && ((cs.picHeader->getInGdrInterval() && cs.isClean(pu.Y().topRight(), CHANNEL_TYPE_LUMA)) || (cs.picHeader->getNumVerVirtualBoundaries() == 0));
+#endif
   AffineAMVPInfo aacAffineAMVPInfo[2][33];
   AffineAMVPInfo affiAMVPInfoTemp[2];
 
@@ -4561,13 +6380,73 @@ void InterSearch::xPredAffineInterSearch( PredictionUnit&       pu,
 
   int           iRefStart, iRefEnd;
 
-  int           bestBiPRefIdxL1 = 0;
-  int           bestBiPMvpL1 = 0;
-  Distortion biPDistTemp = std::numeric_limits<Distortion>::max();
+  int           bestBiPRefIdxL1 = 0;
+  int           bestBiPMvpL1 = 0;
+  Distortion biPDistTemp = std::numeric_limits<Distortion>::max();
+
+#if GDR_ENABLED
+  bool init_value = true;
+
+  bool          allOk = true;
+  bool          biPDistTempOk = init_value;
+  bool          bestBiPDistOk = init_value;
+
+
+  // if (isEncodeGdrClean)
+  {
+    iRefIdxBi[0] = -1;
+    iRefIdxBi[1] = -1;
+    memset(mvHevcSolid, init_value, sizeof(mvHevcSolid));
+
+    // note : will have Solid problem if initialize to true
+    memset(aacMvSolid, false, sizeof(aacMvSolid));
+    memset(aacMvValid, false, sizeof(aacMvValid));
+
+    memset(cMvBiSolid, init_value, sizeof(cMvBiSolid));
+    memset(cMvBiValid, init_value, sizeof(cMvBiValid));
+
+    memset(cMvTempSolid, init_value, sizeof(cMvTempSolid));
+    memset(cMvTempValid, init_value, sizeof(cMvTempValid));
+
+    memset(mvValidList1Solid, init_value, sizeof(mvValidList1Solid));
+    memset(mvValidList1Valid, init_value, sizeof(mvValidList1Valid));
+
+    // AffineAMVPInfo aacAffineAMVPInfo[2][33];
+    ::memset(aacAffineAMVPInfo, 0, sizeof(aacAffineAMVPInfo));
+    ::memset(affiAMVPInfoTemp, 0, sizeof(affiAMVPInfoTemp));
+
+    for (int i = 0; i < 2; i++)
+    {
+      for (int j = 0; j < 33; j++)
+      {
+        for (int k = 0; k < AMVP_MAX_NUM_CANDS_MEM; k++)
+        {
+          aacAffineAMVPInfo[i][j].mvSolidLT[k] = init_value;
+          aacAffineAMVPInfo[i][j].mvSolidRT[k] = init_value;
+          aacAffineAMVPInfo[i][j].mvSolidLB[k] = init_value;
+        }
+      }
+
+      for (int k = 0; k < AMVP_MAX_NUM_CANDS_MEM; k++)
+      {
+        affiAMVPInfoTemp[i].mvSolidLT[k] = init_value;
+        affiAMVPInfoTemp[i].mvSolidRT[k] = init_value;
+        affiAMVPInfoTemp[i].mvSolidLB[k] = init_value;
+      }
+    }
+  }
+
+  bool bAnyClean = false;
+#endif
 
   Distortion    uiCost[2] = { std::numeric_limits<Distortion>::max(), std::numeric_limits<Distortion>::max() };
   Distortion    uiCostBi  = std::numeric_limits<Distortion>::max();
   Distortion    uiCostTemp;
+#if GDR_ENABLED
+  bool uiCostOk[2] = { init_value, init_value };
+  bool uiCostBiOk = init_value;
+  bool uiCostTempOk = init_value;
+#endif
 
   uint32_t          uiBits[3] = { 0 };
   uint32_t          uiBitsTemp;
@@ -4578,12 +6457,24 @@ void InterSearch::xPredAffineInterSearch( PredictionUnit&       pu,
   {
     uiCostTempL0[iNumRef] = std::numeric_limits<Distortion>::max();
   }
+
+#if GDR_ENABLED
+  bool uiCostTempL0Ok[MAX_NUM_REF];
+  for (int iNumRef = 0; iNumRef < MAX_NUM_REF; iNumRef++)
+  {
+    uiCostTempL0Ok[iNumRef] = true;
+  }
+#endif
+
   uint32_t uiBitsTempL0[MAX_NUM_REF];
 
   Mv            mvValidList1[4];
   int           refIdxValidList1 = 0;
   uint32_t          bitsValidList1 = MAX_UINT;
   Distortion costValidList1 = std::numeric_limits<Distortion>::max();
+#if GDR_ENABLED
+  bool costValidList1Ok = true;
+#endif
   Mv            mvHevc[3];
   const bool affineAmvrEnabled = pu.cu->slice->getSPS()->getAffineAmvrEnabledFlag();
   int tryBipred = 0;
@@ -4624,7 +6515,22 @@ void InterSearch::xPredAffineInterSearch( PredictionUnit&       pu,
         biPDistTemp += m_pcRdCost->getCost( xCalcAffineMVBits( pu, cMvPred[iRefList][iRefIdxTemp], cMvPred[iRefList][iRefIdxTemp] ) );
       }
       aaiMvpIdx[iRefList][iRefIdxTemp] = pu.mvpIdx[eRefPicList];
-      aaiMvpNum[iRefList][iRefIdxTemp] = pu.mvpNum[eRefPicList];;
+      aaiMvpNum[iRefList][iRefIdxTemp] = pu.mvpNum[eRefPicList];
+
+#if GDR_ENABLED
+      if (isEncodeGdrClean)
+      {
+        int mvpIdx = aaiMvpIdx[iRefList][iRefIdxTemp];
+        cMvPredSolid[iRefList][iRefIdxTemp][0] = affiAMVPInfoTemp[eRefPicList].mvSolidLT[mvpIdx];
+        cMvPredSolid[iRefList][iRefIdxTemp][1] = affiAMVPInfoTemp[eRefPicList].mvSolidRT[mvpIdx];
+        cMvPredSolid[iRefList][iRefIdxTemp][2] = affiAMVPInfoTemp[eRefPicList].mvSolidLB[mvpIdx];
+
+        biPDistTempOk = true;
+        biPDistTempOk = biPDistTempOk && affiAMVPInfoTemp[eRefPicList].mvSolidLT[mvpIdx] && affiAMVPInfoTemp[eRefPicList].mvSolidRT[mvpIdx];
+        biPDistTempOk = biPDistTempOk && ((mvNum > 2) ? affiAMVPInfoTemp[eRefPicList].mvSolidLB[mvpIdx] : true);
+      }
+#endif
+
       if ( pu.cu->affineType == AFFINEMODEL_6PARAM && refIdx4Para[iRefList] != iRefIdxTemp )
       {
         xCopyAffineAMVPInfo( affiAMVPInfoTemp[eRefPicList], aacAffineAMVPInfo[iRefList][iRefIdxTemp] );
@@ -4636,11 +6542,26 @@ void InterSearch::xPredAffineInterSearch( PredictionUnit&       pu,
       {
         mvHevc[i] = hevcMv[iRefList][iRefIdxTemp];
         mvHevc[i].roundAffinePrecInternal2Amvr(pu.cu->imv);
+
+#if GDR_ENABLED
+        if (isEncodeGdrClean)
+        {
+          mvHevcSolid[i] = hevcMvSolid[iRefList][iRefIdxTemp];
+        }
+#endif
       }
       PelUnitBuf predBuf = m_tmpStorageLCU.getBuf( UnitAreaRelative(*pu.cu, pu) );
+#if GDR_ENABLED
+      bool uiCandCostOk = true;
+      Distortion uiCandCost = xGetAffineTemplateCost(pu, origBuf, predBuf, mvHevc, aaiMvpIdx[iRefList][iRefIdxTemp],
+        AMVP_MAX_NUM_CANDS, eRefPicList, iRefIdxTemp, uiCandCostOk);
 
+      uiCandCostOk = uiCandCostOk && mvHevcSolid[0] && mvHevcSolid[1] && ((mvNum > 2) ? mvHevcSolid[2] : true);
+
+#else
       Distortion uiCandCost = xGetAffineTemplateCost(pu, origBuf, predBuf, mvHevc, aaiMvpIdx[iRefList][iRefIdxTemp],
                                                      AMVP_MAX_NUM_CANDS, eRefPicList, iRefIdxTemp);
+#endif
 
       if ( affineAmvrEnabled )
       {
@@ -4655,19 +6576,58 @@ void InterSearch::xPredAffineInterSearch( PredictionUnit&       pu,
       if ( savedParaAvail )
       {
         Mv mvFour[3];
+#if GDR_ENABLED
+        bool mvFourSolid[3] = { true, true, true };
+#endif
         for ( int i = 0; i < mvNum; i++ )
         {
           mvFour[i] = affine4Para ? m_affineMotion.acMvAffine4Para[iRefList][i] : m_affineMotion.acMvAffine6Para[iRefList][i];
           mvFour[i].roundAffinePrecInternal2Amvr(pu.cu->imv);
+#if GDR_ENABLED
+          mvFourSolid[i] = affine4Para ? m_affineMotion.acMvAffine4ParaSolid[iRefList][i] : m_affineMotion.acMvAffine6ParaSolid[iRefList][i];
+#endif
         }
 
+#if GDR_ENABLED
+        bool candCostInheritOk = true;
+        Distortion candCostInherit = xGetAffineTemplateCost(pu, origBuf, predBuf, mvFour, aaiMvpIdx[iRefList][iRefIdxTemp], AMVP_MAX_NUM_CANDS, eRefPicList, iRefIdxTemp, candCostInheritOk);
+
+        candCostInheritOk = candCostInheritOk && mvFourSolid[0] && mvFourSolid[1] && ((mvNum > 2) ? mvFourSolid[2] : true);
+#else
         Distortion candCostInherit = xGetAffineTemplateCost( pu, origBuf, predBuf, mvFour, aaiMvpIdx[iRefList][iRefIdxTemp], AMVP_MAX_NUM_CANDS, eRefPicList, iRefIdxTemp );
+#endif
         candCostInherit += m_pcRdCost->getCost( xCalcAffineMVBits( pu, mvFour, cMvPred[iRefList][iRefIdxTemp] ) );
 
+#if GDR_ENABLED
+        allOk = (candCostInherit < uiCandCost);
+        if (isEncodeGdrClean)
+        {
+          if (candCostInheritOk)
+          {
+            allOk = (uiCandCostOk) ? (candCostInherit < uiCandCost) : true;
+          }
+          else
+          {
+            allOk = false;
+          }
+        }
+#endif
+
+#if GDR_ENABLED
+        if (allOk)
+#else
         if ( candCostInherit < uiCandCost )
+#endif
         {
           uiCandCost = candCostInherit;
           memcpy( mvHevc, mvFour, 3 * sizeof( Mv ) );
+#if GDR_ENABLED
+          if (isEncodeGdrClean)
+          {
+            uiCandCostOk = candCostInheritOk;
+            memcpy(mvHevcSolid, mvFourSolid, 3 * sizeof(bool));
+          }
+#endif
         }
       }
 
@@ -4679,6 +6639,10 @@ void InterSearch::xPredAffineInterSearch( PredictionUnit&       pu,
         for (int i = 0; i < m_affMVListSize; i++)
         {
           AffineMVInfo *mvInfo = m_affMVList + ((m_affMVListIdx - i - 1 + m_affMVListMaxSize) % (m_affMVListMaxSize));
+#if GDR_ENABLED
+          AffineMVInfoSolid *mvInfoSolid = m_affMVListSolid + ((m_affMVListIdx - i - 1 + m_affMVListMaxSize) % (m_affMVListMaxSize));
+#endif
+
           //check;
           int j = 0;
           for (; j < i; j++)
@@ -4694,9 +6658,17 @@ void InterSearch::xPredAffineInterSearch( PredictionUnit&       pu,
             }
           }
           if (j < i)
+          {
             continue;
+          }
 
           Mv mvTmp[3], *nbMv = mvInfo->affMVs[iRefList][iRefIdxTemp];
+#if GDR_ENABLED
+          bool mvTmpSolid[3];
+          bool *nbMvSolid = mvInfoSolid->affMVsSolid[iRefList][iRefIdxTemp];
+          mvTmpSolid[0] = nbMvSolid[0];
+          mvTmpSolid[1] = nbMvSolid[1];
+#endif
           int vx, vy;
           int dMvHorX, dMvHorY, dMvVerX, dMvVerY;
           int mvScaleHor = nbMv[0].getHor() << shift;
@@ -4721,15 +6693,48 @@ void InterSearch::xPredAffineInterSearch( PredictionUnit&       pu,
           clipMv( mvTmp[1], pu.cu->lumaPos(), pu.cu->lumaSize(), *pu.cs->sps, *pu.cs->pps );
           mvTmp[0].roundAffinePrecInternal2Amvr(pu.cu->imv);
           mvTmp[1].roundAffinePrecInternal2Amvr(pu.cu->imv);
+
+#if GDR_ENABLED
+          bool tmpCostOk = true;
+          Distortion tmpCost = xGetAffineTemplateCost(pu, origBuf, predBuf, mvTmp, aaiMvpIdx[iRefList][iRefIdxTemp], AMVP_MAX_NUM_CANDS, eRefPicList, iRefIdxTemp, tmpCostOk);
+          tmpCostOk = tmpCostOk && mvTmpSolid[0] && mvTmpSolid[1];
+#else
           Distortion tmpCost = xGetAffineTemplateCost(pu, origBuf, predBuf, mvTmp, aaiMvpIdx[iRefList][iRefIdxTemp], AMVP_MAX_NUM_CANDS, eRefPicList, iRefIdxTemp);
+#endif
           if ( affineAmvrEnabled )
           {
             tmpCost += m_pcRdCost->getCost( xCalcAffineMVBits( pu, mvTmp, cMvPred[iRefList][iRefIdxTemp] ) );
           }
+#if GDR_ENABLED
+          allOk = (tmpCost < uiCandCost);
+          if (isEncodeGdrClean)
+          {
+            if (tmpCostOk)
+            {
+              allOk = (uiCandCostOk) ? (tmpCost < uiCandCost) : true;
+            }
+            else
+            {
+              allOk = false;
+            }
+          }
+#endif
+
+#if GDR_ENABLED
+          if (allOk)
+#else
           if (tmpCost < uiCandCost)
+#endif
           {
             uiCandCost = tmpCost;
             std::memcpy(mvHevc, mvTmp, 3 * sizeof(Mv));
+#if GDR_ENABLED
+            if (isEncodeGdrClean)
+            {
+              uiCandCostOk = tmpCostOk;
+              std::memset(mvHevcSolid, true, 3 * sizeof(bool));
+            }
+#endif
           }
         }
       }
@@ -4738,6 +6743,12 @@ void InterSearch::xPredAffineInterSearch( PredictionUnit&       pu,
         Mv mvFour[3];
         mvFour[0] = mvAffine4Para[iRefList][iRefIdxTemp][0];
         mvFour[1] = mvAffine4Para[iRefList][iRefIdxTemp][1];
+#if GDR_ENABLED
+        bool mvFourSolid[3];
+        mvFourSolid[0] = mvAffine4ParaSolid[iRefList][iRefIdxTemp][0];
+        mvFourSolid[1] = mvAffine4ParaSolid[iRefList][iRefIdxTemp][1];
+#endif
+
         mvAffine4Para[iRefList][iRefIdxTemp][0].roundAffinePrecInternal2Amvr(pu.cu->imv);
         mvAffine4Para[iRefList][iRefIdxTemp][1].roundAffinePrecInternal2Amvr(pu.cu->imv);
 
@@ -4753,36 +6764,134 @@ void InterSearch::xPredAffineInterSearch( PredictionUnit&       pu,
         mvFour[0].roundAffinePrecInternal2Amvr(pu.cu->imv);
         mvFour[1].roundAffinePrecInternal2Amvr(pu.cu->imv);
         mvFour[2].roundAffinePrecInternal2Amvr(pu.cu->imv);
+
+#if GDR_ENABLED
+        bool uiCandCostInheritOk = true;
+        Distortion uiCandCostInherit = xGetAffineTemplateCost(pu, origBuf, predBuf, mvFour, aaiMvpIdx[iRefList][iRefIdxTemp], AMVP_MAX_NUM_CANDS, eRefPicList, iRefIdxTemp, uiCandCostInheritOk);
+        uiCandCostInheritOk = uiCandCostInheritOk && mvFourSolid[0] && mvFourSolid[1];
+#else
         Distortion uiCandCostInherit = xGetAffineTemplateCost( pu, origBuf, predBuf, mvFour, aaiMvpIdx[iRefList][iRefIdxTemp], AMVP_MAX_NUM_CANDS, eRefPicList, iRefIdxTemp );
+#endif
+
         if ( affineAmvrEnabled )
         {
           uiCandCostInherit += m_pcRdCost->getCost( xCalcAffineMVBits( pu, mvFour, cMvPred[iRefList][iRefIdxTemp] ) );
         }
+#if GDR_ENABLED
+        allOk = (uiCandCostInherit < uiCandCost);
+
+        if (isEncodeGdrClean)
+        {
+          if (uiCandCostInheritOk)
+          {
+            allOk = (uiCandCostOk) ? (uiCandCostInherit < uiCandCost) : true;
+          }
+          else
+          {
+            allOk = false;
+          }
+        }
+#endif
+
+#if GDR_ENABLED
+        if (allOk)
+#else
         if ( uiCandCostInherit < uiCandCost )
+#endif
         {
           uiCandCost = uiCandCostInherit;
           for ( int i = 0; i < 3; i++ )
           {
             mvHevc[i] = mvFour[i];
+#if GDR_ENABLED
+            if (isEncodeGdrClean)
+            {
+              uiCandCostOk = uiCandCostInheritOk;
+              mvHevcSolid[i] = true;
+            }
+#endif
           }
         }
       }
 
+
+#if GDR_ENABLED
+      allOk = (uiCandCost < biPDistTemp);
+
+      if (isEncodeGdrClean)
+      {
+        if (uiCandCostOk)
+        {
+          allOk = (biPDistTempOk) ? (uiCandCost < biPDistTemp) : true;
+        }
+        else
+        {
+          allOk = false;
+        }
+      }
+#endif
+
+#if GDR_ENABLED
+      if (allOk)
+#else
       if ( uiCandCost < biPDistTemp )
+#endif
       {
         ::memcpy( cMvTemp[iRefList][iRefIdxTemp], mvHevc, sizeof(Mv)*3 );
+#if GDR_ENABLED
+        if (isEncodeGdrClean)
+        {
+          cMvTempSolid[iRefList][iRefIdxTemp][0] = mvHevcSolid[0];
+          cMvTempSolid[iRefList][iRefIdxTemp][1] = mvHevcSolid[1];
+          cMvTempSolid[iRefList][iRefIdxTemp][2] = mvHevcSolid[2];
+        }
+#endif
       }
       else
       {
         ::memcpy( cMvTemp[iRefList][iRefIdxTemp], cMvPred[iRefList][iRefIdxTemp], sizeof(Mv)*3 );
+#if GDR_ENABLED
+        if (isEncodeGdrClean)
+        {
+          cMvTempSolid[iRefList][iRefIdxTemp][0] = cMvPredSolid[iRefList][iRefIdxTemp][0];
+          cMvTempSolid[iRefList][iRefIdxTemp][1] = cMvPredSolid[iRefList][iRefIdxTemp][1];
+          cMvTempSolid[iRefList][iRefIdxTemp][2] = cMvPredSolid[iRefList][iRefIdxTemp][2];
+        }
+#endif
       }
 
       // GPB list 1, save the best MvpIdx, RefIdx and Cost
+#if GDR_ENABLED
+      allOk = (slice.getPicHeader()->getMvdL1ZeroFlag() && iRefList == 1 && (biPDistTemp < bestBiPDist));
+
+      if (isEncodeGdrClean)
+      {
+        if (biPDistTempOk)
+        {
+          allOk = (bestBiPDistOk) ? (slice.getPicHeader()->getMvdL1ZeroFlag() && iRefList == 1 && (biPDistTemp < bestBiPDist)) : true;
+        }
+        else
+        {
+          allOk = false;
+        }
+      }
+#endif
+
+#if GDR_ENABLED
+      if (allOk)
+#else
       if ( slice.getPicHeader()->getMvdL1ZeroFlag() && iRefList==1 && biPDistTemp < bestBiPDist )
+#endif
       {
         bestBiPDist = biPDistTemp;
         bestBiPMvpL1 = aaiMvpIdx[iRefList][iRefIdxTemp];
         bestBiPRefIdxL1 = iRefIdxTemp;
+#if GDR_ENABLED
+        if (isEncodeGdrClean)
+        {
+          bestBiPDistOk = biPDistTempOk;
+        }
+#endif
       }
 
       // Update bits
@@ -4794,6 +6903,13 @@ void InterSearch::xPredAffineInterSearch( PredictionUnit&       pu,
         {
           int iList1ToList0Idx = slice.getList1IdxToList0Idx( iRefIdxTemp );
           ::memcpy( cMvTemp[1][iRefIdxTemp], cMvTemp[0][iList1ToList0Idx], sizeof(Mv)*3 );
+#if GDR_ENABLED
+          if (isEncodeGdrClean)
+          {
+            ::memcpy(cMvTempSolid[1][iRefIdxTemp], cMvTempSolid[0][iList1ToList0Idx], sizeof(bool) * 3);
+            uiCostTempOk = uiCostTempL0Ok[iList1ToList0Idx];
+          }
+#endif
           uiCostTemp = uiCostTempL0[iList1ToList0Idx];
 
           uiCostTemp -= m_pcRdCost->getCost( uiBitsTempL0[iList1ToList0Idx] );
@@ -4804,52 +6920,249 @@ void InterSearch::xPredAffineInterSearch( PredictionUnit&       pu,
         }
         else
         {
+#if GDR_ENABLED
+          xAffineMotionEstimation(pu, origBuf, eRefPicList, cMvPred[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], cMvTempSolid[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp
+            , aaiMvpIdx[iRefList][iRefIdxTemp], affiAMVPInfoTemp[eRefPicList], bAnyClean
+#else
           xAffineMotionEstimation( pu, origBuf, eRefPicList, cMvPred[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp
                                    , aaiMvpIdx[iRefList][iRefIdxTemp], affiAMVPInfoTemp[eRefPicList]
+#endif
           );
+
+#if GDR_ENABLED
+          if (isEncodeGdrClean)
+          {
+            int mvp_idx = aaiMvpIdx[iRefList][iRefIdxTemp];
+            PelUnitBuf     tmpBuf = m_tmpAffiStorage.getBuf(UnitAreaRelative(*pu.cu, pu));
+            const Picture *refPic = pu.cu->slice->getRefPic((RefPicList)iRefList, iRefIdxTemp);
+
+
+            cMvPredSolid[iRefList][iRefIdxTemp][0] = affiAMVPInfoTemp[eRefPicList].mvSolidLT[mvp_idx];
+            cMvPredSolid[iRefList][iRefIdxTemp][1] = affiAMVPInfoTemp[eRefPicList].mvSolidRT[mvp_idx];
+            cMvPredSolid[iRefList][iRefIdxTemp][2] = affiAMVPInfoTemp[eRefPicList].mvSolidLB[mvp_idx];
+
+            cMvTempSolid[iRefList][iRefIdxTemp][0] = cMvPredSolid[iRefList][iRefIdxTemp][0];
+            cMvTempSolid[iRefList][iRefIdxTemp][1] = cMvPredSolid[iRefList][iRefIdxTemp][1];
+            cMvTempSolid[iRefList][iRefIdxTemp][2] = cMvPredSolid[iRefList][iRefIdxTemp][2];
+
+            bool isSubPuYYClean = xPredAffineBlk(COMPONENT_Y, pu, refPic, cMvTemp[iRefList][iRefIdxTemp], tmpBuf, false, pu.cu->slice->clpRng(COMPONENT_Y));
+            bool isSubPuCbClean = (isSubPuYYClean) ? xPredAffineBlk(COMPONENT_Cb, pu, refPic, cMvTemp[iRefList][iRefIdxTemp], tmpBuf, false, pu.cu->slice->clpRng(COMPONENT_Cb)) : false;
+
+            cMvTempValid[iRefList][iRefIdxTemp][0] = isSubPuYYClean && isSubPuCbClean;
+            cMvTempValid[iRefList][iRefIdxTemp][1] = isSubPuYYClean && isSubPuCbClean;
+            cMvTempValid[iRefList][iRefIdxTemp][2] = isSubPuYYClean && isSubPuCbClean;
+
+            uiCostTempOk = true;
+            uiCostTempOk = uiCostTempOk && cMvPredSolid[iRefList][iRefIdxTemp][0] && cMvPredSolid[iRefList][iRefIdxTemp][1];
+            uiCostTempOk = uiCostTempOk && ((mvNum > 2) ? cMvPredSolid[iRefList][iRefIdxTemp][2] : true);
+            uiCostTempOk = uiCostTempOk && cMvTempSolid[iRefList][iRefIdxTemp][0] && cMvTempSolid[iRefList][iRefIdxTemp][1] && ((mvNum > 2) ? cMvTempSolid[iRefList][iRefIdxTemp][2] : true);
+            uiCostTempOk = uiCostTempOk && cMvTempValid[iRefList][iRefIdxTemp][0] && cMvTempValid[iRefList][iRefIdxTemp][1] && ((mvNum > 2) ? cMvTempValid[iRefList][iRefIdxTemp][2] : true);
+          }
+#endif
         }
       }
       else
       {
+#if GDR_ENABLED
+        xAffineMotionEstimation(pu, origBuf, eRefPicList, cMvPred[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], cMvTempSolid[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp
+          , aaiMvpIdx[iRefList][iRefIdxTemp], affiAMVPInfoTemp[eRefPicList], bAnyClean
+        );
+#else
         xAffineMotionEstimation( pu, origBuf, eRefPicList, cMvPred[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp
                                  , aaiMvpIdx[iRefList][iRefIdxTemp], affiAMVPInfoTemp[eRefPicList]
         );
+#endif
+
+#if GDR_ENABLED
+        if (isEncodeGdrClean)
+        {
+          int mvp_idx = aaiMvpIdx[iRefList][iRefIdxTemp];
+          PelUnitBuf     tmpBuf = m_tmpAffiStorage.getBuf(UnitAreaRelative(*pu.cu, pu));
+          const Picture *refPic = pu.cu->slice->getRefPic((RefPicList)iRefList, iRefIdxTemp);
+
+          cMvPredSolid[iRefList][iRefIdxTemp][0] = affiAMVPInfoTemp[eRefPicList].mvSolidLT[mvp_idx];
+          cMvPredSolid[iRefList][iRefIdxTemp][1] = affiAMVPInfoTemp[eRefPicList].mvSolidRT[mvp_idx];
+          cMvPredSolid[iRefList][iRefIdxTemp][2] = affiAMVPInfoTemp[eRefPicList].mvSolidLB[mvp_idx];
+
+          cMvTempSolid[iRefList][iRefIdxTemp][0] = cMvPredSolid[iRefList][iRefIdxTemp][0];
+          cMvTempSolid[iRefList][iRefIdxTemp][1] = cMvPredSolid[iRefList][iRefIdxTemp][1];
+          cMvTempSolid[iRefList][iRefIdxTemp][2] = cMvPredSolid[iRefList][iRefIdxTemp][2];
+
+          bool isSubPuYYClean = xPredAffineBlk(COMPONENT_Y, pu, refPic, cMvTemp[iRefList][iRefIdxTemp], tmpBuf, false, pu.cu->slice->clpRng(COMPONENT_Y));
+          bool isSubPuCbClean = (isSubPuYYClean) ? xPredAffineBlk(COMPONENT_Cb, pu, refPic, cMvTemp[iRefList][iRefIdxTemp], tmpBuf, false, pu.cu->slice->clpRng(COMPONENT_Cb)) : false;
+
+          cMvTempValid[iRefList][iRefIdxTemp][0] = isSubPuYYClean && isSubPuCbClean;
+          cMvTempValid[iRefList][iRefIdxTemp][1] = isSubPuYYClean && isSubPuCbClean;
+          cMvTempValid[iRefList][iRefIdxTemp][2] = isSubPuYYClean && isSubPuCbClean;
+
+          uiCostTempOk = true;
+          uiCostTempOk = uiCostTempOk && cMvPredSolid[iRefList][iRefIdxTemp][0] && cMvPredSolid[iRefList][iRefIdxTemp][1];
+          uiCostTempOk = uiCostTempOk && ((mvNum > 2) ? cMvPredSolid[iRefList][iRefIdxTemp][2] : true);
+          uiCostTempOk = uiCostTempOk && cMvTempSolid[iRefList][iRefIdxTemp][0] && cMvTempSolid[iRefList][iRefIdxTemp][1] && ((mvNum > 2) ? cMvTempSolid[iRefList][iRefIdxTemp][2] : true);
+          uiCostTempOk = uiCostTempOk && cMvTempValid[iRefList][iRefIdxTemp][0] && cMvTempValid[iRefList][iRefIdxTemp][1] && ((mvNum > 2) ? cMvTempValid[iRefList][iRefIdxTemp][2] : true);
+        }
+#endif
       }
       if(pu.cu->cs->sps->getUseBcw() && pu.cu->BcwIdx == BCW_DEFAULT && pu.cu->slice->isInterB())
       {
         m_uniMotions.setReadModeAffine(true, (uint8_t)iRefList, (uint8_t)iRefIdxTemp, pu.cu->affineType);
+#if GDR_ENABLED
+        if (isEncodeGdrClean)
+        {
+          m_uniMotions.copyAffineMvFrom(
+            cMvTemp[iRefList][iRefIdxTemp],
+            cMvTempSolid[iRefList][iRefIdxTemp],
+            uiCostTemp - m_pcRdCost->getCost(uiBitsTemp),
+            (uint8_t)iRefList,
+            (uint8_t)iRefIdxTemp,
+            pu.cu->affineType,
+            aaiMvpIdx[iRefList][iRefIdxTemp]
+          );
+        }
+        else
+        {
+          m_uniMotions.copyAffineMvFrom(cMvTemp[iRefList][iRefIdxTemp], uiCostTemp - m_pcRdCost->getCost(uiBitsTemp), (uint8_t)iRefList, (uint8_t)iRefIdxTemp, pu.cu->affineType
+            , aaiMvpIdx[iRefList][iRefIdxTemp]
+          );
+        }
+#else
         m_uniMotions.copyAffineMvFrom(cMvTemp[iRefList][iRefIdxTemp], uiCostTemp - m_pcRdCost->getCost(uiBitsTemp), (uint8_t)iRefList, (uint8_t)iRefIdxTemp, pu.cu->affineType
                                       , aaiMvpIdx[iRefList][iRefIdxTemp]
         );
+#endif
       }
       // Set best AMVP Index
       xCopyAffineAMVPInfo( affiAMVPInfoTemp[eRefPicList], aacAffineAMVPInfo[iRefList][iRefIdxTemp] );
+#if GDR_ENABLED
+      if ( pu.cu->imv != 2 || !m_pcEncCfg->getUseAffineAmvrEncOpt() )
+      {
+        xCheckBestAffineMVP( pu, affiAMVPInfoTemp[eRefPicList], eRefPicList, cMvTemp[iRefList][iRefIdxTemp], cMvPred[iRefList][iRefIdxTemp], aaiMvpIdx[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp );
+        if (isEncodeGdrClean)
+        {
+          int mvp_idx = aaiMvpIdx[iRefList][iRefIdxTemp];
+
+          cMvPredSolid[iRefList][iRefIdxTemp][0] = affiAMVPInfoTemp[eRefPicList].mvSolidLT[mvp_idx];
+          cMvPredSolid[iRefList][iRefIdxTemp][1] = affiAMVPInfoTemp[eRefPicList].mvSolidRT[mvp_idx];
+          cMvPredSolid[iRefList][iRefIdxTemp][2] = affiAMVPInfoTemp[eRefPicList].mvSolidLB[mvp_idx];
+
+          cMvTempSolid[iRefList][iRefIdxTemp][0] = cMvPredSolid[iRefList][iRefIdxTemp][0];
+          cMvTempSolid[iRefList][iRefIdxTemp][1] = cMvPredSolid[iRefList][iRefIdxTemp][0];
+          cMvTempSolid[iRefList][iRefIdxTemp][2] = cMvPredSolid[iRefList][iRefIdxTemp][0];
+
+          if (cMvTempValid[iRefList][iRefIdxTemp][0] && cMvTempValid[iRefList][iRefIdxTemp][1] && cMvTempValid[iRefList][iRefIdxTemp][2])
+          {
+            cMvTempValid[iRefList][iRefIdxTemp][0] = cMvPredSolid[iRefList][iRefIdxTemp][0];
+            cMvTempValid[iRefList][iRefIdxTemp][1] = cMvPredSolid[iRefList][iRefIdxTemp][0];
+            cMvTempValid[iRefList][iRefIdxTemp][2] = cMvPredSolid[iRefList][iRefIdxTemp][0];
+          }
+
+          uiCostTempOk = true;
+          uiCostTempOk = uiCostTempOk && cMvPredSolid[iRefList][iRefIdxTemp][0] && cMvPredSolid[iRefList][iRefIdxTemp][1];
+          uiCostTempOk = uiCostTempOk && ((mvNum > 2) ? cMvPredSolid[iRefList][iRefIdxTemp][2] : true);
+          uiCostTempOk = uiCostTempOk && cMvTempSolid[iRefList][iRefIdxTemp][0] && cMvTempSolid[iRefList][iRefIdxTemp][1] && ((mvNum > 2) ? cMvTempSolid[iRefList][iRefIdxTemp][2] : true);
+          uiCostTempOk = uiCostTempOk && cMvTempValid[iRefList][iRefIdxTemp][0] && cMvTempValid[iRefList][iRefIdxTemp][1] && ((mvNum > 2) ? cMvTempValid[iRefList][iRefIdxTemp][2] : true);
+        }
+      }
+#else
       if ( pu.cu->imv != 2 || !m_pcEncCfg->getUseAffineAmvrEncOpt() )
-      xCheckBestAffineMVP( pu, affiAMVPInfoTemp[eRefPicList], eRefPicList, cMvTemp[iRefList][iRefIdxTemp], cMvPred[iRefList][iRefIdxTemp], aaiMvpIdx[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp );
+      {
+        xCheckBestAffineMVP( pu, affiAMVPInfoTemp[eRefPicList], eRefPicList, cMvTemp[iRefList][iRefIdxTemp], cMvPred[iRefList][iRefIdxTemp], aaiMvpIdx[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp );
+      }
+#endif
 
       if ( iRefList == 0 )
       {
         uiCostTempL0[iRefIdxTemp] = uiCostTemp;
         uiBitsTempL0[iRefIdxTemp] = uiBitsTemp;
+#if GDR_ENABLED
+        if (isEncodeGdrClean)
+        {
+          uiCostTempL0Ok[iRefIdxTemp] = uiCostTempOk;
+        }
+#endif
       }
       DTRACE( g_trace_ctx, D_COMMON, " (%d) uiCostTemp=%d, uiCost[iRefList]=%d\n", DTRACE_GET_COUNTER(g_trace_ctx,D_COMMON), uiCostTemp, uiCost[iRefList] );
+#if GDR_ENABLED
+      allOk = (uiCostTemp < uiCost[iRefList]);
+
+      if (isEncodeGdrClean)
+      {
+        if (uiCostTempOk)
+        {
+          allOk = (uiCostOk[iRefList]) ? (uiCostTemp < uiCost[iRefList]) : true;
+        }
+        else
+        {
+          allOk = false;
+        }
+      }
+#endif
+
+#if GDR_ENABLED
+      if (allOk)
+#else
       if ( uiCostTemp < uiCost[iRefList] )
+#endif
       {
         uiCost[iRefList] = uiCostTemp;
         uiBits[iRefList] = uiBitsTemp; // storing for bi-prediction
 
+#if GDR_ENABLED
+        if (isEncodeGdrClean)
+        {
+          uiCostOk[iRefList] = uiCostTempOk;
+        }
+#endif
         // set best motion
         ::memcpy( aacMv[iRefList], cMvTemp[iRefList][iRefIdxTemp], sizeof(Mv) * 3 );
+#if GDR_ENABLED
+        if (isEncodeGdrClean)
+        {
+          ::memcpy(aacMvSolid[iRefList], cMvTempSolid[iRefList][iRefIdxTemp], sizeof(bool) * 3);
+          ::memcpy(aacMvValid[iRefList], cMvTempValid[iRefList][iRefIdxTemp], sizeof(bool) * 3);
+        }
+#endif
         iRefIdx[iRefList] = iRefIdxTemp;
       }
 
+
+#if GDR_ENABLED
+      allOk = (iRefList == 1 && uiCostTemp < costValidList1 && slice.getList1IdxToList0Idx(iRefIdxTemp) < 0);
+
+      if (isEncodeGdrClean)
+      {
+        if (uiCostTempOk)
+        {
+          allOk = (costValidList1Ok) ? (iRefList == 1 && uiCostTemp < costValidList1 && slice.getList1IdxToList0Idx(iRefIdxTemp) < 0) : true;
+        }
+        else
+        {
+          allOk = false;
+        }
+      }
+#endif
+
+
+#if GDR_ENABLED
+      if (allOk)
+#else
       if ( iRefList == 1 && uiCostTemp < costValidList1 && slice.getList1IdxToList0Idx( iRefIdxTemp ) < 0 )
+#endif
       {
         costValidList1 = uiCostTemp;
         bitsValidList1 = uiBitsTemp;
 
         // set motion
         memcpy( mvValidList1, cMvTemp[iRefList][iRefIdxTemp], sizeof(Mv)*3 );
+
+#if GDR_ENABLED
+        if (isEncodeGdrClean)
+        {
+          costValidList1Ok = uiCostTempOk;
+          ::memcpy(mvValidList1Solid, cMvTempSolid[iRefList][iRefIdxTemp], sizeof(bool) * 3);
+          ::memcpy(mvValidList1Valid, cMvTempSolid[iRefList][iRefIdxTemp], sizeof(bool) * 3);
+        }
+#endif
         refIdxValidList1 = iRefIdxTemp;
       }
     } // End refIdx loop
@@ -4858,9 +7171,15 @@ void InterSearch::xPredAffineInterSearch( PredictionUnit&       pu,
   if ( pu.cu->affineType == AFFINEMODEL_4PARAM )
   {
     ::memcpy( mvAffine4Para, cMvTemp, sizeof( cMvTemp ) );
+#if GDR_ENABLED
+    ::memcpy(mvAffine4ParaSolid, cMvTempSolid, sizeof(cMvTempSolid));
+#endif
     if ( pu.cu->imv == 0 && ( !pu.cu->cs->sps->getUseBcw() || bcwIdx == BCW_DEFAULT ) )
     {
       AffineMVInfo *affMVInfo = m_affMVList + m_affMVListIdx;
+#if GDR_ENABLED
+      AffineMVInfoSolid *affMVInfoSolid = m_affMVListSolid + m_affMVListIdx;
+#endif
 
       //check;
       int j = 0;
@@ -4872,10 +7191,19 @@ void InterSearch::xPredAffineInterSearch( PredictionUnit&       pu,
           break;
         }
       }
+#if GDR_ENABLED
+      if (j < m_affMVListSize)
+      {
+        affMVInfo = m_affMVList + ((m_affMVListIdx - j - 1 + m_affMVListMaxSize) % (m_affMVListMaxSize));
+        affMVInfoSolid = m_affMVListSolid + ((m_affMVListIdx - j - 1 + m_affMVListMaxSize) % (m_affMVListMaxSize));
+      }
+      ::memcpy(affMVInfo->affMVs, cMvTemp, sizeof(cMvTemp));
+      ::memcpy(affMVInfoSolid->affMVsSolid, cMvTempSolid, sizeof(cMvTempSolid));
+#else
       if (j < m_affMVListSize)
         affMVInfo = m_affMVList + ((m_affMVListIdx - j - 1 + m_affMVListMaxSize) % (m_affMVListMaxSize));
-
       ::memcpy(affMVInfo->affMVs, cMvTemp, sizeof(cMvTemp));
+#endif
 
       if (j == m_affMVListSize)
       {
@@ -4903,6 +7231,15 @@ void InterSearch::xPredAffineInterSearch( PredictionUnit&       pu,
     ::memcpy( cMvPredBi,   cMvPred,   sizeof(cMvPred)   );
     ::memcpy( aaiMvpIdxBi, aaiMvpIdx, sizeof(aaiMvpIdx) );
 
+#if GDR_ENABLED
+    if (isEncodeGdrClean)
+    {
+      ::memcpy(cMvBiSolid, aacMvSolid, sizeof(cMvBiSolid));
+      ::memcpy(cMvBiValid, aacMvValid, sizeof(cMvBiValid));
+      ::memcpy(cMvPredBiSolid, cMvPredSolid, sizeof(cMvPredSolid));
+    }
+#endif
+
     uint32_t uiMotBits[2];
     bool doBiPred = true;
 
@@ -4920,6 +7257,33 @@ void InterSearch::xPredAffineInterSearch( PredictionUnit&       pu,
       ::memcpy( cMvBi[1],                      pcMvTemp, sizeof(Mv)*3 );
       ::memcpy( cMvTemp[1][bestBiPRefIdxL1],   pcMvTemp, sizeof(Mv)*3 );
       iRefIdxBi[1] = bestBiPRefIdxL1;
+#if GDR_ENABLED
+      if (isEncodeGdrClean)
+      {
+        PelUnitBuf     tmpBuf = m_tmpAffiStorage.getBuf(UnitAreaRelative(*pu.cu, pu));
+        const Picture *refPic = pu.cu->slice->getRefPic((RefPicList)REF_PIC_LIST_1, iRefIdxBi[1]);
+
+        cMvPredBiSolid[1][bestBiPRefIdxL1][0] = affiAMVPInfoTemp[REF_PIC_LIST_1].mvSolidLT[bestBiPMvpL1];
+        cMvPredBiSolid[1][bestBiPRefIdxL1][1] = affiAMVPInfoTemp[REF_PIC_LIST_1].mvSolidRT[bestBiPMvpL1];
+        cMvPredBiSolid[1][bestBiPRefIdxL1][2] = affiAMVPInfoTemp[REF_PIC_LIST_1].mvSolidLB[bestBiPMvpL1];
+
+        cMvBiSolid[1][0] = affiAMVPInfoTemp[REF_PIC_LIST_1].mvSolidLT[bestBiPMvpL1];
+        cMvBiSolid[1][1] = affiAMVPInfoTemp[REF_PIC_LIST_1].mvSolidRT[bestBiPMvpL1];
+        cMvBiSolid[1][2] = affiAMVPInfoTemp[REF_PIC_LIST_1].mvSolidLB[bestBiPMvpL1];
+
+
+        bool isSubPuYYClean = xPredAffineBlk(COMPONENT_Y, pu, refPic, cMvTemp[1][bestBiPRefIdxL1], tmpBuf, false, pu.cu->slice->clpRng(COMPONENT_Y));
+        bool isSubPuCbClean = (isSubPuYYClean) ? xPredAffineBlk(COMPONENT_Cb, pu, refPic, cMvTemp[1][bestBiPRefIdxL1], tmpBuf, false, pu.cu->slice->clpRng(COMPONENT_Cb)) : false;
+
+        cMvBiValid[1][0] = isSubPuYYClean && isSubPuCbClean;
+        cMvBiValid[1][1] = isSubPuYYClean && isSubPuCbClean;
+        cMvBiValid[1][2] = isSubPuYYClean && isSubPuCbClean;
+
+        cMvTempSolid[1][bestBiPRefIdxL1][0] = affiAMVPInfoTemp[REF_PIC_LIST_1].mvSolidLT[bestBiPMvpL1];
+        cMvTempSolid[1][bestBiPRefIdxL1][1] = affiAMVPInfoTemp[REF_PIC_LIST_1].mvSolidRT[bestBiPMvpL1];
+        cMvTempSolid[1][bestBiPRefIdxL1][2] = affiAMVPInfoTemp[REF_PIC_LIST_1].mvSolidLB[bestBiPMvpL1];
+      }
+#endif
 
       if( m_pcEncCfg->getMCTSEncConstraint() )
       {
@@ -4942,6 +7306,26 @@ void InterSearch::xPredAffineInterSearch( PredictionUnit&       pu,
       PU::setAllAffineMv( pu, cMvBi[1][0], cMvBi[1][1], cMvBi[1][2], REF_PIC_LIST_1);
       pu.refIdx[REF_PIC_LIST_1] = iRefIdxBi[1];
 
+#if GDR_ENABLED
+      if (isEncodeGdrClean)
+      {
+        PelUnitBuf     tmpBuf = m_tmpAffiStorage.getBuf(UnitAreaRelative(*pu.cu, pu));
+        const Picture *refPic = pu.cu->slice->getRefPic((RefPicList)REF_PIC_LIST_1, pu.refIdx[REF_PIC_LIST_1]);
+
+        pu.mvAffiSolid[REF_PIC_LIST_1][0] = cMvBiSolid[REF_PIC_LIST_1][0];
+        pu.mvAffiSolid[REF_PIC_LIST_1][1] = cMvBiSolid[REF_PIC_LIST_1][1];
+        pu.mvAffiSolid[REF_PIC_LIST_1][2] = cMvBiSolid[REF_PIC_LIST_1][2];
+
+
+        bool isSubPuYYClean = xPredAffineBlk(COMPONENT_Y, pu, refPic, cMvBi[1], tmpBuf, false, pu.cu->slice->clpRng(COMPONENT_Y));
+        bool isSubPuCbClean = (isSubPuYYClean) ? xPredAffineBlk(COMPONENT_Cb, pu, refPic, cMvBi[1], tmpBuf, false, pu.cu->slice->clpRng(COMPONENT_Cb)) : false;
+
+        pu.mvAffiValid[REF_PIC_LIST_1][0] = cMvBiValid[REF_PIC_LIST_1][0] = isSubPuYYClean && isSubPuCbClean;
+        pu.mvAffiValid[REF_PIC_LIST_1][1] = cMvBiValid[REF_PIC_LIST_1][1] = isSubPuYYClean && isSubPuCbClean;
+        pu.mvAffiValid[REF_PIC_LIST_1][2] = cMvBiValid[REF_PIC_LIST_1][2] = isSubPuYYClean && isSubPuCbClean;
+      }
+#endif
+
       PelUnitBuf predBufTmp = m_tmpPredStorage[REF_PIC_LIST_1].getBuf( UnitAreaRelative(*pu.cu, pu) );
       motionCompensation( pu, predBufTmp, REF_PIC_LIST_1 );
 
@@ -4977,13 +7361,33 @@ void InterSearch::xPredAffineInterSearch( PredictionUnit&       pu,
       iNumIter = 1;
     }
 
-    for ( int iIter = 0; iIter < iNumIter; iIter++ )
-    {
-      // Set RefList
-      int iRefList = iIter % 2;
-      if ( m_pcEncCfg->getFastInterSearchMode()==FASTINTERSEARCH_MODE1 || m_pcEncCfg->getFastInterSearchMode()==FASTINTERSEARCH_MODE2 )
-      {
+    for ( int iIter = 0; iIter < iNumIter; iIter++ )
+    {
+      // Set RefList
+      int iRefList = iIter % 2;
+      if ( m_pcEncCfg->getFastInterSearchMode()==FASTINTERSEARCH_MODE1 || m_pcEncCfg->getFastInterSearchMode()==FASTINTERSEARCH_MODE2 )
+      {
+#if GDR_ENABLED
+        allOk = (uiCost[0] <= uiCost[1]);
+
+        if (isEncodeGdrClean)
+        {
+          if (uiCostOk[0])
+          {
+            allOk = (uiCostOk[1]) ? (uiCost[0] <= uiCost[1]) : true;
+          }
+          else
+          {
+            allOk = false;
+          }
+        }
+#endif
+
+#if GDR_ENABLED
+        if (allOk)
+#else
         if( uiCost[0] <= uiCost[1] )
+#endif
         {
           iRefList = 1;
         }
@@ -5006,6 +7410,25 @@ void InterSearch::xPredAffineInterSearch( PredictionUnit&       pu,
       {
         PU::setAllAffineMv( pu, aacMv[1-iRefList][0], aacMv[1-iRefList][1], aacMv[1-iRefList][2], RefPicList(1-iRefList));
         pu.refIdx[1-iRefList] = iRefIdx[1-iRefList];
+#if GDR_ENABLED
+        if (isEncodeGdrClean)
+        {
+          PelUnitBuf     tmpBuf = m_tmpAffiStorage.getBuf(UnitAreaRelative(*pu.cu, pu));
+          const Picture *refPic = pu.cu->slice->getRefPic((RefPicList)(1 - iRefList), pu.refIdx[1 - iRefList]);
+
+          pu.mvAffiSolid[1 - iRefList][0] = aacMvSolid[1 - iRefList][0];
+          pu.mvAffiSolid[1 - iRefList][1] = aacMvSolid[1 - iRefList][1];
+          pu.mvAffiSolid[1 - iRefList][2] = aacMvSolid[1 - iRefList][2];
+
+
+          bool isSubPuYYClean = xPredAffineBlk(COMPONENT_Y, pu, refPic, aacMv[1 - iRefList], tmpBuf, false, pu.cu->slice->clpRng(COMPONENT_Y));
+          bool isSubPuCbClean = (isSubPuYYClean) ? xPredAffineBlk(COMPONENT_Cb, pu, refPic, aacMv[1 - iRefList], tmpBuf, false, pu.cu->slice->clpRng(COMPONENT_Cb)) : false;
+
+          pu.mvAffiValid[1 - iRefList][0] = aacMvValid[1 - iRefList][0] = isSubPuYYClean && isSubPuCbClean;
+          pu.mvAffiValid[1 - iRefList][1] = aacMvValid[1 - iRefList][1] = isSubPuYYClean && isSubPuCbClean;
+          pu.mvAffiValid[1 - iRefList][2] = aacMvValid[1 - iRefList][2] = isSubPuYYClean && isSubPuCbClean;
+        }
+#endif
 
         PelUnitBuf predBufTmp = m_tmpPredStorage[1 - iRefList].getBuf( UnitAreaRelative(*pu.cu, pu) );
         motionCompensation( pu, predBufTmp, RefPicList(1 - iRefList) );
@@ -5049,20 +7472,129 @@ void InterSearch::xPredAffineInterSearch( PredictionUnit&       pu,
         uiBitsTemp += m_auiMVPIdxCost[aaiMvpIdxBi[iRefList][iRefIdxTemp]][AMVP_MAX_NUM_CANDS];
 
         // call Affine ME
+#if GDR_ENABLED
+        xAffineMotionEstimation(pu, origBuf, eRefPicList, cMvPredBi[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], cMvTempSolid[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp,
+          aaiMvpIdxBi[iRefList][iRefIdxTemp], aacAffineAMVPInfo[iRefList][iRefIdxTemp], bAnyClean,
+          true);
+#else
         xAffineMotionEstimation( pu, origBuf, eRefPicList, cMvPredBi[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp,
                                  aaiMvpIdxBi[iRefList][iRefIdxTemp], aacAffineAMVPInfo[iRefList][iRefIdxTemp],
           true );
+#endif
+
+#if GDR_ENABLED
+        if (isEncodeGdrClean)
+        {
+          int mvp_idx = aaiMvpIdx[iRefList][iRefIdxTemp];
+          PelUnitBuf     tmpBuf = m_tmpAffiStorage.getBuf(UnitAreaRelative(*pu.cu, pu));
+          const Picture *refPic = pu.cu->slice->getRefPic((RefPicList)iRefList, iRefIdxTemp);
+
+          cMvPredBiSolid[iRefList][iRefIdxTemp][0] = aacAffineAMVPInfo[iRefList][iRefIdxTemp].mvSolidLT[mvp_idx];
+          cMvPredBiSolid[iRefList][iRefIdxTemp][1] = aacAffineAMVPInfo[iRefList][iRefIdxTemp].mvSolidRT[mvp_idx];
+          cMvPredBiSolid[iRefList][iRefIdxTemp][2] = aacAffineAMVPInfo[iRefList][iRefIdxTemp].mvSolidLB[mvp_idx];
+
+          cMvTempSolid[iRefList][iRefIdxTemp][0] = cMvPredBiSolid[iRefList][iRefIdxTemp][0];
+          cMvTempSolid[iRefList][iRefIdxTemp][1] = cMvPredSolid[iRefList][iRefIdxTemp][1];
+          cMvTempSolid[iRefList][iRefIdxTemp][2] = cMvPredSolid[iRefList][iRefIdxTemp][2];
+
+
+          bool isSubPuYYClean = xPredAffineBlk(COMPONENT_Y, pu, refPic, cMvTemp[iRefList][iRefIdxTemp], tmpBuf, false, pu.cu->slice->clpRng(COMPONENT_Y));
+          bool isSubPuCbClean = (isSubPuYYClean) ? xPredAffineBlk(COMPONENT_Cb, pu, refPic, cMvTemp[iRefList][iRefIdxTemp], tmpBuf, false, pu.cu->slice->clpRng(COMPONENT_Cb)) : false;
+
+          cMvTempValid[iRefList][iRefIdxTemp][0] = isSubPuYYClean && isSubPuCbClean;
+          cMvTempValid[iRefList][iRefIdxTemp][1] = isSubPuYYClean && isSubPuCbClean;
+          cMvTempValid[iRefList][iRefIdxTemp][2] = isSubPuYYClean && isSubPuCbClean;
+
+          uiCostTempOk = true;
+          uiCostTempOk = uiCostTempOk && cMvPredBiSolid[iRefList][iRefIdxTemp][0] && cMvPredBiSolid[iRefList][iRefIdxTemp][1];
+          uiCostTempOk = uiCostTempOk && ((mvNum > 2) ? cMvPredBiSolid[iRefList][iRefIdxTemp][2] : true);
+          uiCostTempOk = uiCostTempOk && cMvTempSolid[iRefList][iRefIdxTemp][0] && cMvTempSolid[iRefList][iRefIdxTemp][1] && ((mvNum > 2) ? cMvTempSolid[iRefList][iRefIdxTemp][2] : true);
+          uiCostTempOk = uiCostTempOk && cMvTempValid[iRefList][iRefIdxTemp][0] && cMvTempValid[iRefList][iRefIdxTemp][1] && ((mvNum > 2) ? cMvTempValid[iRefList][iRefIdxTemp][2] : true);
+        }
+#endif
+
         xCopyAffineAMVPInfo( aacAffineAMVPInfo[iRefList][iRefIdxTemp], affiAMVPInfoTemp[eRefPicList] );
+#if GDR_ENABLED
+        if ( pu.cu->imv != 2 || !m_pcEncCfg->getUseAffineAmvrEncOpt() )
+        {
+          xCheckBestAffineMVP( pu, affiAMVPInfoTemp[eRefPicList], eRefPicList, cMvTemp[iRefList][iRefIdxTemp], cMvPredBi[iRefList][iRefIdxTemp], aaiMvpIdxBi[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp );
+          if (isEncodeGdrClean)
+          {
+            int mvp_idx = aaiMvpIdxBi[iRefList][iRefIdxTemp];
+
+            cMvPredBiSolid[iRefList][iRefIdxTemp][0] = affiAMVPInfoTemp[eRefPicList].mvSolidLT[mvp_idx];
+            cMvPredBiSolid[iRefList][iRefIdxTemp][1] = affiAMVPInfoTemp[eRefPicList].mvSolidRT[mvp_idx];
+            cMvPredBiSolid[iRefList][iRefIdxTemp][2] = affiAMVPInfoTemp[eRefPicList].mvSolidLB[mvp_idx];
+
+            cMvTempSolid[iRefList][iRefIdxTemp][0] = cMvPredBiSolid[iRefList][iRefIdxTemp][0];
+            cMvTempSolid[iRefList][iRefIdxTemp][1] = cMvPredBiSolid[iRefList][iRefIdxTemp][1];
+            cMvTempSolid[iRefList][iRefIdxTemp][2] = cMvPredBiSolid[iRefList][iRefIdxTemp][2];
+
+            if (cMvTempValid[iRefList][iRefIdxTemp][0] && cMvTempValid[iRefList][iRefIdxTemp][1] && cMvTempValid[iRefList][iRefIdxTemp][2])
+            {
+              cMvTempValid[iRefList][iRefIdxTemp][0] = cMvPredBiSolid[iRefList][iRefIdxTemp][0];
+              cMvTempValid[iRefList][iRefIdxTemp][1] = cMvPredBiSolid[iRefList][iRefIdxTemp][1];
+              cMvTempValid[iRefList][iRefIdxTemp][2] = cMvPredBiSolid[iRefList][iRefIdxTemp][2];
+            }
+
+            uiCostTempOk = true;
+            uiCostTempOk = uiCostTempOk && cMvPredBiSolid[iRefList][iRefIdxTemp][0] && cMvPredBiSolid[iRefList][iRefIdxTemp][1];
+            uiCostTempOk = uiCostTempOk && ((mvNum > 2) ? cMvPredBiSolid[iRefList][iRefIdxTemp][2] : true);
+            uiCostTempOk = uiCostTempOk && cMvTempSolid[iRefList][iRefIdxTemp][0] && cMvTempSolid[iRefList][iRefIdxTemp][1] && ((mvNum > 2) ? cMvTempSolid[iRefList][iRefIdxTemp][2] : true);
+            uiCostTempOk = uiCostTempOk && cMvTempValid[iRefList][iRefIdxTemp][0] && cMvTempValid[iRefList][iRefIdxTemp][1] && ((mvNum > 2) ? cMvTempValid[iRefList][iRefIdxTemp][2] : true);
+          }
+        }
+#else
         if ( pu.cu->imv != 2 || !m_pcEncCfg->getUseAffineAmvrEncOpt() )
-        xCheckBestAffineMVP( pu, affiAMVPInfoTemp[eRefPicList], eRefPicList, cMvTemp[iRefList][iRefIdxTemp], cMvPredBi[iRefList][iRefIdxTemp], aaiMvpIdxBi[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp );
+        {
+          xCheckBestAffineMVP(pu, affiAMVPInfoTemp[eRefPicList], eRefPicList, cMvTemp[iRefList][iRefIdxTemp],
+                              cMvPredBi[iRefList][iRefIdxTemp], aaiMvpIdxBi[iRefList][iRefIdxTemp], uiBitsTemp,
+                              uiCostTemp);
+        }
+#endif
+
+#if GDR_ENABLED
+        allOk = (uiCostTemp < uiCostBi);
+
+        if (isEncodeGdrClean)
+        {
+          if (uiCostTempOk)
+          {
+            allOk = (uiCostBiOk) ? (uiCostTemp < uiCostBi) : true;
+          }
+          else
+          {
+            allOk = false;
+          }
+        }
+#endif
+
+
 
+#if GDR_ENABLED
+        if (allOk)
+#else
         if ( uiCostTemp < uiCostBi )
+#endif
         {
           bChanged = true;
           ::memcpy( cMvBi[iRefList], cMvTemp[iRefList][iRefIdxTemp], sizeof(Mv)*3 );
+#if GDR_ENABLED
+          if (isEncodeGdrClean)
+          {
+            ::memcpy(cMvBiSolid[iRefList], cMvTempSolid[iRefList][iRefIdxTemp], sizeof(bool) * 3);
+            ::memcpy(cMvBiValid[iRefList], cMvTempValid[iRefList][iRefIdxTemp], sizeof(bool) * 3);
+          }
+#endif
           iRefIdxBi[iRefList] = iRefIdxTemp;
 
           uiCostBi            = uiCostTemp;
+#if GDR_ENABLED
+          if (isEncodeGdrClean)
+          {
+            uiCostBiOk = uiCostTempOk;
+          }
+#endif
           uiMotBits[iRefList] = uiBitsTemp - uiMbBits[2] - uiMotBits[1-iRefList];
           uiMotBits[iRefList] -= ((pu.cu->slice->getSPS()->getUseBcw() == true) ? bcwIdxBits : 0);
           uiBits[2]           = uiBitsTemp;
@@ -5072,6 +7604,28 @@ void InterSearch::xPredAffineInterSearch( PredictionUnit&       pu,
             //  Set motion
             PU::setAllAffineMv( pu, cMvBi[iRefList][0], cMvBi[iRefList][1], cMvBi[iRefList][2], eRefPicList);
             pu.refIdx[eRefPicList] = iRefIdxBi[eRefPicList];
+
+#if GDR_ENABLED
+            if (isEncodeGdrClean)
+            {
+              bool isSubPuYYClean;
+              bool isSubPuCbClean;
+              PelUnitBuf     tmpBuf = m_tmpAffiStorage.getBuf(UnitAreaRelative(*pu.cu, pu));
+              const Picture *refPic = pu.cu->slice->getRefPic((RefPicList)iRefList, pu.refIdx[eRefPicList]);
+
+              pu.mvAffiSolid[eRefPicList][0] = cMvBiSolid[iRefList][0];
+              pu.mvAffiSolid[eRefPicList][1] = cMvBiSolid[iRefList][1];
+              pu.mvAffiSolid[eRefPicList][2] = cMvBiSolid[iRefList][2];
+
+              isSubPuYYClean = xPredAffineBlk(COMPONENT_Y, pu, refPic, cMvBi[iRefList], tmpBuf, false, pu.cu->slice->clpRng(COMPONENT_Y));
+              isSubPuCbClean = (isSubPuYYClean) ? xPredAffineBlk(COMPONENT_Cb, pu, refPic, cMvBi[iRefList], tmpBuf, false, pu.cu->slice->clpRng(COMPONENT_Cb)) : false;
+
+              pu.mvAffiValid[eRefPicList][0] = cMvBiValid[iRefList][0] = isSubPuYYClean && isSubPuCbClean;
+              pu.mvAffiValid[eRefPicList][1] = cMvBiValid[iRefList][1] = isSubPuYYClean && isSubPuCbClean;
+              pu.mvAffiValid[eRefPicList][2] = cMvBiValid[iRefList][2] = isSubPuYYClean && isSubPuCbClean;
+            }
+#endif
+
             PelUnitBuf predBufTmp = m_tmpPredStorage[iRefList].getBuf( UnitAreaRelative(*pu.cu, pu) );
             motionCompensation( pu, predBufTmp, eRefPicList );
           }
@@ -5080,15 +7634,89 @@ void InterSearch::xPredAffineInterSearch( PredictionUnit&       pu,
 
       if ( !bChanged )
       {
+#if GDR_ENABLED
+        allOk = ((uiCostBi <= uiCost[0] && uiCostBi <= uiCost[1]) || enforceBcwPred);
+
+        if (isEncodeGdrClean)
+        {
+          if (uiCostBiOk)
+          {
+            allOk = (uiCostOk[0] && uiCostOk[1]) ? ((uiCostBi <= uiCost[0] && uiCostBi <= uiCost[1]) || enforceBcwPred) : true;
+          }
+          else
+          {
+            allOk = false;
+          }
+        }
+#endif
+
+#if GDR_ENABLED
+        if (allOk)
+#else
         if ((uiCostBi <= uiCost[0] && uiCostBi <= uiCost[1]) || enforceBcwPred)
+#endif
         {
           xCopyAffineAMVPInfo( aacAffineAMVPInfo[0][iRefIdxBi[0]], affiAMVPInfoTemp[REF_PIC_LIST_0] );
           xCheckBestAffineMVP( pu, affiAMVPInfoTemp[REF_PIC_LIST_0], REF_PIC_LIST_0, cMvBi[0], cMvPredBi[0][iRefIdxBi[0]], aaiMvpIdxBi[0][iRefIdxBi[0]], uiBits[2], uiCostBi );
+#if GDR_ENABLED
+          if (isEncodeGdrClean)
+          {
+            int mvp_idx = aaiMvpIdxBi[0][iRefIdxBi[0]];
+
+            cMvPredBiSolid[REF_PIC_LIST_0][iRefIdxBi[0]][0] = affiAMVPInfoTemp[REF_PIC_LIST_0].mvSolidLT[mvp_idx];
+            cMvPredBiSolid[REF_PIC_LIST_0][iRefIdxBi[0]][1] = affiAMVPInfoTemp[REF_PIC_LIST_0].mvSolidRT[mvp_idx];
+            cMvPredBiSolid[REF_PIC_LIST_0][iRefIdxBi[0]][2] = affiAMVPInfoTemp[REF_PIC_LIST_0].mvSolidLB[mvp_idx];
+
+            cMvBiSolid[REF_PIC_LIST_0][0] = cMvPredBiSolid[REF_PIC_LIST_0][iRefIdxBi[0]][0];
+            cMvBiSolid[REF_PIC_LIST_0][1] = cMvPredBiSolid[REF_PIC_LIST_0][iRefIdxBi[0]][1];
+            cMvBiSolid[REF_PIC_LIST_0][2] = cMvPredBiSolid[REF_PIC_LIST_0][iRefIdxBi[0]][2];
+
+            if (cMvBiValid[REF_PIC_LIST_0][0] && cMvBiValid[REF_PIC_LIST_0][1] && cMvBiValid[REF_PIC_LIST_0][2])
+            {
+              cMvBiValid[REF_PIC_LIST_0][0] = cMvPredBiSolid[REF_PIC_LIST_0][iRefIdxBi[0]][0];
+              cMvBiValid[REF_PIC_LIST_0][1] = cMvPredBiSolid[REF_PIC_LIST_0][iRefIdxBi[0]][1];
+              cMvBiValid[REF_PIC_LIST_0][2] = cMvPredBiSolid[REF_PIC_LIST_0][iRefIdxBi[0]][2];
+            }
+
+            uiCostBiOk = true;
+            uiCostBiOk = uiCostBiOk && cMvPredBiSolid[REF_PIC_LIST_0][iRefIdxBi[0]][0] && cMvPredBiSolid[REF_PIC_LIST_0][iRefIdxBi[0]][1];
+            uiCostBiOk = uiCostBiOk && ((mvNum > 2) ? cMvPredBiSolid[REF_PIC_LIST_0][iRefIdxBi[0]][2] : true);
+            uiCostBiOk = uiCostBiOk && cMvBiSolid[0][0] && cMvBiSolid[0][1] && ((mvNum > 2) ? cMvBiSolid[0][2] : true);
+            uiCostBiOk = uiCostBiOk && cMvBiValid[0][0] && cMvBiValid[0][1] && ((mvNum > 2) ? cMvBiValid[0][2] : true);
+          }
+#endif
 
           if ( !slice.getPicHeader()->getMvdL1ZeroFlag() )
           {
             xCopyAffineAMVPInfo( aacAffineAMVPInfo[1][iRefIdxBi[1]], affiAMVPInfoTemp[REF_PIC_LIST_1] );
             xCheckBestAffineMVP( pu, affiAMVPInfoTemp[REF_PIC_LIST_1], REF_PIC_LIST_1, cMvBi[1], cMvPredBi[1][iRefIdxBi[1]], aaiMvpIdxBi[1][iRefIdxBi[1]], uiBits[2], uiCostBi );
+#if GDR_ENABLED
+            if (isEncodeGdrClean)
+            {
+              int mvp_idx = aaiMvpIdxBi[1][iRefIdxBi[1]];
+
+              cMvPredBiSolid[REF_PIC_LIST_1][iRefIdxBi[1]][0] = affiAMVPInfoTemp[REF_PIC_LIST_1].mvSolidLT[mvp_idx];
+              cMvPredBiSolid[REF_PIC_LIST_1][iRefIdxBi[1]][1] = affiAMVPInfoTemp[REF_PIC_LIST_1].mvSolidRT[mvp_idx];
+              cMvPredBiSolid[REF_PIC_LIST_1][iRefIdxBi[1]][2] = affiAMVPInfoTemp[REF_PIC_LIST_1].mvSolidLB[mvp_idx];
+
+              cMvBiSolid[REF_PIC_LIST_1][0] = cMvPredBiSolid[REF_PIC_LIST_1][iRefIdxBi[1]][0];
+              cMvBiSolid[REF_PIC_LIST_1][1] = cMvPredBiSolid[REF_PIC_LIST_1][iRefIdxBi[1]][1];
+              cMvBiSolid[REF_PIC_LIST_1][2] = cMvPredBiSolid[REF_PIC_LIST_1][iRefIdxBi[1]][2];
+
+              if (cMvBiValid[REF_PIC_LIST_1][0] && cMvBiValid[REF_PIC_LIST_1][1] && cMvBiValid[REF_PIC_LIST_1][2])
+              {
+                cMvBiValid[REF_PIC_LIST_1][0] = cMvPredBiSolid[REF_PIC_LIST_1][iRefIdxBi[1]][0];
+                cMvBiValid[REF_PIC_LIST_1][1] = cMvPredBiSolid[REF_PIC_LIST_1][iRefIdxBi[1]][1];
+                cMvBiValid[REF_PIC_LIST_1][2] = cMvPredBiSolid[REF_PIC_LIST_1][iRefIdxBi[1]][2];
+              }
+
+              uiCostBiOk = true;
+              uiCostBiOk = uiCostBiOk && cMvPredBiSolid[REF_PIC_LIST_1][iRefIdxBi[1]][0] && cMvPredBiSolid[REF_PIC_LIST_1][iRefIdxBi[1]][1];
+              uiCostBiOk = uiCostBiOk && ((mvNum > 2) ? cMvPredBiSolid[REF_PIC_LIST_1][iRefIdxBi[1]][2] : true);
+              uiCostBiOk = uiCostBiOk && cMvBiSolid[1][0] && cMvBiSolid[1][1] && ((mvNum > 2) ? cMvBiSolid[1][2] : true);
+              uiCostBiOk = uiCostBiOk && cMvBiValid[1][0] && cMvBiValid[1][1] && ((mvNum > 2) ? cMvBiValid[1][2] : true);
+            }
+#endif
           }
         }
         break;
@@ -5120,6 +7748,15 @@ void InterSearch::xPredAffineInterSearch( PredictionUnit&       pu,
   iRefIdx[1] = refIdxValidList1;
   uiBits[1]  = bitsValidList1;
   uiCost[1]  = costValidList1;
+
+#if GDR_ENABLED
+  if (isEncodeGdrClean)
+  {
+    memcpy(aacMvSolid[1], mvValidList1Solid, sizeof(bool) * 3);
+    memcpy(aacMvValid[1], mvValidList1Valid, sizeof(bool) * 3);
+    uiCostOk[1] = costValidList1Ok;
+  }
+#endif
   if (pu.cs->pps->getWPBiPred() == true && tryBipred && (bcwIdx != BCW_DEFAULT))
   {
     CHECK(iRefIdxBi[0]<0, "Invalid picture reference index");
@@ -5131,15 +7768,46 @@ void InterSearch::xPredAffineInterSearch( PredictionUnit&       pu,
     {
       uiCostBi = MAX_UINT;
       enforceBcwPred = false;
+#if GDR_ENABLED
+      uiCostBiOk = false;
+#endif
     }
   }
   if( enforceBcwPred )
   {
     uiCost[0] = uiCost[1] = MAX_UINT;
+#if GDR_ENABLED
+    uiCostOk[0] = uiCostOk[1] = false;
+#endif
   }
 
   // Affine ME result set
+#if GDR_ENABLED
+  bool BiOk = (uiCostBi <= uiCost[0] && uiCostBi <= uiCost[1]);
+
+  if (isEncodeGdrClean)
+  {
+    if (uiCostBiOk)
+      BiOk = (uiCostOk[0] && uiCostOk[1]) ? (uiCostBi <= uiCost[0] && uiCostBi <= uiCost[1]) : true;
+    else
+      BiOk = false;
+  }
+
+  bool L0ok = (uiCost[0] <= uiCost[1]);
+  if (isEncodeGdrClean)
+  {
+    if (uiCostOk[0])
+      L0ok = (uiCostOk[1]) ? (uiCost[0] <= uiCost[1]) : true;
+    else
+      L0ok = false;
+  }
+#endif
+
+#if GDR_ENABLED
+  if (BiOk)
+#else
   if ( uiCostBi <= uiCost[0] && uiCostBi <= uiCost[1] ) // Bi
+#endif
   {
     lastMode = 2;
     affineCost = uiCostBi;
@@ -5149,6 +7817,48 @@ void InterSearch::xPredAffineInterSearch( PredictionUnit&       pu,
     pu.refIdx[REF_PIC_LIST_0] = iRefIdxBi[0];
     pu.refIdx[REF_PIC_LIST_1] = iRefIdxBi[1];
 
+#if GDR_ENABLED
+    if (isEncodeGdrClean)
+    {
+      PelUnitBuf     tmpBuf = m_tmpAffiStorage.getBuf(UnitAreaRelative(*pu.cu, pu));
+      const Picture *refPic0 = (pu.refIdx[REF_PIC_LIST_0] < 0) ? nullptr : pu.cu->slice->getRefPic((RefPicList)REF_PIC_LIST_0, pu.refIdx[REF_PIC_LIST_0]);
+      const Picture *refPic1 = (pu.refIdx[REF_PIC_LIST_1] < 0) ? nullptr : pu.cu->slice->getRefPic((RefPicList)REF_PIC_LIST_1, pu.refIdx[REF_PIC_LIST_1]);
+
+      pu.mvAffiSolid[REF_PIC_LIST_0][0] = cMvBiSolid[REF_PIC_LIST_0][0];
+      pu.mvAffiSolid[REF_PIC_LIST_0][1] = cMvBiSolid[REF_PIC_LIST_0][1];
+      pu.mvAffiSolid[REF_PIC_LIST_0][2] = cMvBiSolid[REF_PIC_LIST_0][2];
+
+      bool isSubPuYYClean0 = false;
+      bool isSubPuCbClean0 = false;
+      if (refPic0) {
+        isSubPuYYClean0 = xPredAffineBlk(COMPONENT_Y, pu, refPic0, cMvBi[0], tmpBuf, false, pu.cu->slice->clpRng(COMPONENT_Y));
+        isSubPuCbClean0 = (isSubPuYYClean0) ? xPredAffineBlk(COMPONENT_Cb, pu, refPic0, cMvBi[0], tmpBuf, false, pu.cu->slice->clpRng(COMPONENT_Cb)) : false;
+      }
+
+      pu.mvAffiValid[REF_PIC_LIST_0][0] = cMvBiValid[REF_PIC_LIST_0][0] = isSubPuYYClean0 && isSubPuCbClean0;
+      pu.mvAffiValid[REF_PIC_LIST_0][1] = cMvBiValid[REF_PIC_LIST_0][1] = isSubPuYYClean0 && isSubPuCbClean0;
+      pu.mvAffiValid[REF_PIC_LIST_0][2] = cMvBiValid[REF_PIC_LIST_0][2] = isSubPuYYClean0 && isSubPuCbClean0;
+
+
+      pu.mvAffiSolid[REF_PIC_LIST_1][0] = cMvBiSolid[REF_PIC_LIST_1][0];
+      pu.mvAffiSolid[REF_PIC_LIST_1][1] = cMvBiSolid[REF_PIC_LIST_1][1];
+      pu.mvAffiSolid[REF_PIC_LIST_1][2] = cMvBiSolid[REF_PIC_LIST_1][2];
+
+      bool isSubPuYYClean1 = false;
+      bool isSubPuCbClean1 = false;
+      if (refPic1)
+      {
+        isSubPuYYClean1 = xPredAffineBlk(COMPONENT_Y, pu, refPic1, cMvBi[1], tmpBuf, false, pu.cu->slice->clpRng(COMPONENT_Y));
+        isSubPuCbClean1 = (isSubPuYYClean1) ? xPredAffineBlk(COMPONENT_Cb, pu, refPic1, cMvBi[1], tmpBuf, false, pu.cu->slice->clpRng(COMPONENT_Cb)) : false;
+      }
+
+      pu.mvAffiValid[REF_PIC_LIST_1][0] = cMvBiValid[REF_PIC_LIST_1][0] = isSubPuYYClean1 && isSubPuCbClean1;
+      pu.mvAffiValid[REF_PIC_LIST_1][1] = cMvBiValid[REF_PIC_LIST_1][1] = isSubPuYYClean1 && isSubPuCbClean1;
+      pu.mvAffiValid[REF_PIC_LIST_1][2] = cMvBiValid[REF_PIC_LIST_1][2] = isSubPuYYClean1 && isSubPuCbClean1;
+    }
+#endif
+
+
     for ( int verIdx = 0; verIdx < mvNum; verIdx++ )
     {
       pu.mvdAffi[REF_PIC_LIST_0][verIdx] = cMvBi[0][verIdx] - cMvPredBi[0][iRefIdxBi[0]][verIdx];
@@ -5160,13 +7870,30 @@ void InterSearch::xPredAffineInterSearch( PredictionUnit&       pu,
       }
     }
 
-
     pu.mvpIdx[REF_PIC_LIST_0] = aaiMvpIdxBi[0][iRefIdxBi[0]];
     pu.mvpNum[REF_PIC_LIST_0] = aaiMvpNum[0][iRefIdxBi[0]];
     pu.mvpIdx[REF_PIC_LIST_1] = aaiMvpIdxBi[1][iRefIdxBi[1]];
     pu.mvpNum[REF_PIC_LIST_1] = aaiMvpNum[1][iRefIdxBi[1]];
+
+#if GDR_ENABLED
+    if (isEncodeGdrClean)
+    {
+      pu.mvpSolid[REF_PIC_LIST_0] = affiAMVPInfoTemp[0].mvSolidLT[pu.mvpIdx[0]] && affiAMVPInfoTemp[0].mvSolidRT[pu.mvpIdx[0]];
+      pu.mvpSolid[REF_PIC_LIST_1] = affiAMVPInfoTemp[1].mvSolidLT[pu.mvpIdx[1]] && affiAMVPInfoTemp[1].mvSolidRT[pu.mvpIdx[1]];
+
+      if (pu.cu->affineType == AFFINEMODEL_6PARAM)
+      {
+        pu.mvpSolid[REF_PIC_LIST_0] = pu.mvpSolid[REF_PIC_LIST_0] && affiAMVPInfoTemp[0].mvSolidLB[pu.mvpIdx[0]];
+        pu.mvpSolid[REF_PIC_LIST_1] = pu.mvpSolid[REF_PIC_LIST_1] && affiAMVPInfoTemp[1].mvSolidLB[pu.mvpIdx[1]];
+      }
+    }
+#endif
   }
+#if GDR_ENABLED
+  else if (L0ok) // List 0
+#else
   else if ( uiCost[0] <= uiCost[1] ) // List 0
+#endif
   {
     lastMode = 0;
     affineCost = uiCost[0];
@@ -5174,6 +7901,27 @@ void InterSearch::xPredAffineInterSearch( PredictionUnit&       pu,
     PU::setAllAffineMv( pu, aacMv[0][0], aacMv[0][1], aacMv[0][2], REF_PIC_LIST_0);
     pu.refIdx[REF_PIC_LIST_0] = iRefIdx[0];
 
+#if GDR_ENABLED
+    if (isEncodeGdrClean)
+    {
+      bool isSubPuYYClean;
+      bool isSubPuCbClean;
+      PelUnitBuf     tmpBuf = m_tmpAffiStorage.getBuf(UnitAreaRelative(*pu.cu, pu));
+      const Picture *refPic = pu.cu->slice->getRefPic((RefPicList)REF_PIC_LIST_0, pu.refIdx[REF_PIC_LIST_0]);
+
+      pu.mvAffiSolid[0][0] = aacMvSolid[0][0];
+      pu.mvAffiSolid[0][1] = aacMvSolid[0][1];
+      pu.mvAffiSolid[0][2] = aacMvSolid[0][2];
+
+      isSubPuYYClean = xPredAffineBlk(COMPONENT_Y, pu, refPic, aacMv[0], tmpBuf, false, pu.cu->slice->clpRng(COMPONENT_Y));
+      isSubPuCbClean = (isSubPuYYClean) ? xPredAffineBlk(COMPONENT_Cb, pu, refPic, aacMv[0], tmpBuf, false, pu.cu->slice->clpRng(COMPONENT_Cb)) : false;
+
+      pu.mvAffiValid[0][0] = aacMvValid[0][0] = isSubPuYYClean && isSubPuCbClean;
+      pu.mvAffiValid[0][1] = aacMvValid[0][1] = isSubPuYYClean && isSubPuCbClean;
+      pu.mvAffiValid[0][2] = aacMvValid[0][2] = isSubPuYYClean && isSubPuCbClean;
+    }
+#endif
+
     for ( int verIdx = 0; verIdx < mvNum; verIdx++ )
     {
       pu.mvdAffi[REF_PIC_LIST_0][verIdx] = aacMv[0][verIdx] - cMvPred[0][iRefIdx[0]][verIdx];
@@ -5185,6 +7933,17 @@ void InterSearch::xPredAffineInterSearch( PredictionUnit&       pu,
 
     pu.mvpIdx[REF_PIC_LIST_0] = aaiMvpIdx[0][iRefIdx[0]];
     pu.mvpNum[REF_PIC_LIST_0] = aaiMvpNum[0][iRefIdx[0]];
+#if GDR_ENABLED
+    if (isEncodeGdrClean)
+    {
+      pu.mvpSolid[REF_PIC_LIST_0] = affiAMVPInfoTemp[0].mvSolidLT[pu.mvpIdx[0]] && affiAMVPInfoTemp[0].mvSolidRT[pu.mvpIdx[0]];
+
+      if (pu.cu->affineType == AFFINEMODEL_6PARAM)
+      {
+        pu.mvpSolid[REF_PIC_LIST_0] = pu.mvpSolid[REF_PIC_LIST_0] && affiAMVPInfoTemp[0].mvSolidLB[pu.mvpIdx[0]];
+      }
+    }
+#endif
   }
   else
   {
@@ -5194,6 +7953,27 @@ void InterSearch::xPredAffineInterSearch( PredictionUnit&       pu,
     PU::setAllAffineMv( pu, aacMv[1][0], aacMv[1][1], aacMv[1][2], REF_PIC_LIST_1);
     pu.refIdx[REF_PIC_LIST_1] = iRefIdx[1];
 
+#if GDR_ENABLED
+    if (isEncodeGdrClean)
+    {
+      bool isSubPuYYClean;
+      bool isSubPuCbClean;
+      PelUnitBuf     tmpBuf = m_tmpAffiStorage.getBuf(UnitAreaRelative(*pu.cu, pu));
+      const Picture *refPic = pu.cu->slice->getRefPic((RefPicList)REF_PIC_LIST_1, pu.refIdx[REF_PIC_LIST_1]);
+
+      pu.mvAffiSolid[1][0] = aacMvSolid[1][0];
+      pu.mvAffiSolid[1][1] = aacMvSolid[1][1];
+      pu.mvAffiSolid[1][2] = aacMvSolid[1][2];
+
+      isSubPuYYClean = xPredAffineBlk(COMPONENT_Y, pu, refPic, aacMv[1], tmpBuf, false, pu.cu->slice->clpRng(COMPONENT_Y));
+      isSubPuCbClean = (isSubPuYYClean) ? xPredAffineBlk(COMPONENT_Cb, pu, refPic, aacMv[1], tmpBuf, false, pu.cu->slice->clpRng(COMPONENT_Cb)) : false;
+
+      pu.mvAffiValid[1][0] = aacMvValid[1][0] = isSubPuYYClean && isSubPuCbClean;
+      pu.mvAffiValid[1][1] = aacMvValid[1][1] = isSubPuYYClean && isSubPuCbClean;
+      pu.mvAffiValid[1][2] = aacMvValid[1][2] = isSubPuYYClean && isSubPuCbClean;
+    }
+#endif
+
     for ( int verIdx = 0; verIdx < mvNum; verIdx++ )
     {
       pu.mvdAffi[REF_PIC_LIST_1][verIdx] = aacMv[1][verIdx] - cMvPred[1][iRefIdx[1]][verIdx];
@@ -5205,6 +7985,17 @@ void InterSearch::xPredAffineInterSearch( PredictionUnit&       pu,
 
     pu.mvpIdx[REF_PIC_LIST_1] = aaiMvpIdx[1][iRefIdx[1]];
     pu.mvpNum[REF_PIC_LIST_1] = aaiMvpNum[1][iRefIdx[1]];
+#if GDR_ENABLED
+    if (isEncodeGdrClean)
+    {
+      pu.mvpSolid[REF_PIC_LIST_1] = affiAMVPInfoTemp[1].mvSolidLT[pu.mvpIdx[1]] && affiAMVPInfoTemp[1].mvSolidRT[pu.mvpIdx[1]];
+
+      if (pu.cu->affineType == AFFINEMODEL_6PARAM)
+      {
+        pu.mvpSolid[REF_PIC_LIST_1] = pu.mvpSolid[REF_PIC_LIST_1] && affiAMVPInfoTemp[1].mvSolidLB[pu.mvpIdx[1]];
+      }
+    }
+#endif
   }
   if( bcwIdx != BCW_DEFAULT )
   {
@@ -5285,6 +8076,11 @@ void solveEqual(double dEqualCoeff[7][7], int iOrder, double *dAffinePara)
 
 void InterSearch::xCheckBestAffineMVP( PredictionUnit &pu, AffineAMVPInfo &affineAMVPInfo, RefPicList eRefPicList, Mv acMv[3], Mv acMvPred[3], int& riMVPIdx, uint32_t& ruiBits, Distortion& ruiCost )
 {
+#if GDR_ENABLED
+  const CodingStructure &cs = *pu.cs;
+  const bool isEncodeGdrClean = cs.sps->getGDREnabledFlag() && cs.pcv->isEncoder && ((cs.picHeader->getInGdrInterval() && cs.isClean(pu.Y().topRight(), CHANNEL_TYPE_LUMA)) || (cs.picHeader->getNumVerVirtualBoundaries() == 0));
+#endif
+
   if ( affineAMVPInfo.numCand < 2 )
   {
     return;
@@ -5318,7 +8114,39 @@ void InterSearch::xCheckBestAffineMVP( PredictionUnit &pu, AffineAMVPInfo &affin
     int iMvBits = xCalcAffineMVBits( pu, acMv, tmpPredMv );
     iMvBits += m_auiMVPIdxCost[iMVPIdx][AMVP_MAX_NUM_CANDS];
 
+#if GDR_ENABLED
+    bool allOk = (iMvBits < iBestMvBits);
+    if (isEncodeGdrClean)
+    {
+      bool curOk = affineAMVPInfo.mvSolidLT[iMVPIdx] && affineAMVPInfo.mvSolidRT[iMVPIdx];
+      if (pu.cu->affineType == AFFINEMODEL_6PARAM)
+      {
+        curOk = curOk && affineAMVPInfo.mvSolidLB[iMVPIdx];
+      }
+
+      bool best_ok = affineAMVPInfo.mvSolidLT[iBestMVPIdx] && affineAMVPInfo.mvSolidRT[iBestMVPIdx];
+      if (pu.cu->affineType == AFFINEMODEL_6PARAM)
+      {
+        curOk = curOk && affineAMVPInfo.mvSolidLB[iBestMVPIdx];
+      }
+
+      if (curOk)
+      {
+        allOk = (best_ok) ? (iMvBits < iBestMvBits) : true;
+      }
+      else
+      {
+        allOk = false;
+      }
+    }
+#endif
+
+
+#if GDR_ENABLED
+    if (allOk)
+#else
     if (iMvBits < iBestMvBits)
+#endif
     {
       iBestMvBits = iMvBits;
       iBestMVPIdx = iMVPIdx;
@@ -5337,6 +8165,21 @@ void InterSearch::xCheckBestAffineMVP( PredictionUnit &pu, AffineAMVPInfo &affin
   }
 }
 
+#if GDR_ENABLED
+void InterSearch::xAffineMotionEstimation(PredictionUnit& pu,
+  PelUnitBuf&     origBuf,
+  RefPicList      eRefPicList,
+  Mv              acMvPred[3],
+  int             iRefIdxPred,
+  Mv              acMv[3],
+  bool            acMvSolid[3],
+  uint32_t&       ruiBits,
+  Distortion&     ruiCost,
+  int&            mvpIdx,
+  const AffineAMVPInfo& aamvpi,
+  bool&           rbCleanCandExist,
+  bool            bBi)
+#else
 void InterSearch::xAffineMotionEstimation( PredictionUnit& pu,
                                            PelUnitBuf&     origBuf,
                                            RefPicList      eRefPicList,
@@ -5348,13 +8191,25 @@ void InterSearch::xAffineMotionEstimation( PredictionUnit& pu,
                                            int&            mvpIdx,
                                            const AffineAMVPInfo& aamvpi,
                                            bool            bBi)
+#endif
 {
+#if GDR_ENABLED
+  if (pu.cu->cs->sps->getUseBcw() && pu.cu->BcwIdx != BCW_DEFAULT && !bBi && xReadBufferedAffineUniMv(pu, eRefPicList, iRefIdxPred, acMvPred, acMv, acMvSolid, ruiBits, ruiCost
+    , mvpIdx, aamvpi
+  ))
+#else
   if( pu.cu->cs->sps->getUseBcw() && pu.cu->BcwIdx != BCW_DEFAULT && !bBi && xReadBufferedAffineUniMv(pu, eRefPicList, iRefIdxPred, acMvPred, acMv, ruiBits, ruiCost
       , mvpIdx, aamvpi
   ) )
+#endif
   {
     return;
   }
+#if GDR_ENABLED
+  const CodingStructure &cs = *pu.cs;
+  const bool isEncodeGdrClean = cs.sps->getGDREnabledFlag() && cs.pcv->isEncoder && ((cs.picHeader->getInGdrInterval() && cs.isClean(pu.Y().topRight(), CHANNEL_TYPE_LUMA)) || (cs.picHeader->getNumVerVirtualBoundaries() == 0));
+  bool acMvValid[3];
+#endif
 
   uint32_t dirBits = ruiBits - m_auiMVPIdxCost[mvpIdx][aamvpi.numCand];
   int bestMvpIdx   = mvpIdx;
@@ -5391,6 +8246,11 @@ void InterSearch::xAffineMotionEstimation( PredictionUnit& pu,
   // Set start Mv position, use input mv as started search mv
   Mv acMvTemp[3];
   ::memcpy( acMvTemp, acMv, sizeof(Mv)*3 );
+
+#if GDR_ENABLED
+  bool acMvTempSolid[3];
+  ::memcpy(acMvTempSolid, acMvSolid, sizeof(bool) * 3);
+#endif
   // Set delta mv
   // malloc buffer
   int iParaNum = pu.cu->affineType ? 7 : 5;
@@ -5406,6 +8266,13 @@ void InterSearch::xAffineMotionEstimation( PredictionUnit& pu,
 
   Distortion uiCostBest = std::numeric_limits<Distortion>::max();
   uint32_t uiBitsBest = 0;
+#if GDR_ENABLED
+  bool uiCostBestOk = true;
+  bool uiCostTempOk = true;
+  bool costTempOk = true;
+
+  bool allOk = true;
+#endif
 
   // do motion compensation with origin mv
   if( m_pcEncCfg->getMCTSEncConstraint() )
@@ -5433,7 +8300,11 @@ void InterSearch::xAffineMotionEstimation( PredictionUnit& pu,
   {
     acMvTemp[2].roundAffinePrecInternal2Amvr(pu.cu->imv);
   }
+#if GDR_ENABLED
+  bool YYOk = xPredAffineBlk(COMPONENT_Y, pu, refPic, acMvTemp, predBuf, false, pu.cs->slice->clpRng(COMPONENT_Y));
+#else
   xPredAffineBlk( COMPONENT_Y, pu, refPic, acMvTemp, predBuf, false, pu.cs->slice->clpRng( COMPONENT_Y ) );
+#endif
 
   // get error
   uiCostBest = m_pcRdCost->getDistPart(predBuf.Y(), pBuf->Y(), pu.cs->sps->getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y, distFunc);
@@ -5454,6 +8325,25 @@ void InterSearch::xAffineMotionEstimation( PredictionUnit& pu,
     uiBitsBest += xCalcAffineMVBits( pu, acMvTemp, acMvPred );
     DTRACE( g_trace_ctx, D_COMMON, " (%d) yy uiBitsBest=%d\n", DTRACE_GET_COUNTER(g_trace_ctx,D_COMMON), uiBitsBest );
   }
+
+#if GDR_ENABLED
+  if (isEncodeGdrClean)
+  {
+    acMvSolid[0] = aamvpi.mvSolidLT[mvpIdx];
+    acMvSolid[1] = aamvpi.mvSolidRT[mvpIdx];
+    acMvSolid[2] = aamvpi.mvSolidLB[mvpIdx];
+
+    bool isSubPuYYClean = YYOk;
+    bool isSubPuCbClean = true;
+
+    acMvValid[0] = isSubPuYYClean && isSubPuCbClean;
+    acMvValid[1] = isSubPuYYClean && isSubPuCbClean;
+    acMvValid[2] = isSubPuYYClean && isSubPuCbClean;
+
+    uiCostBestOk = (acMvSolid[0] && acMvSolid[1] && acMvSolid[2]) && (acMvValid[0] && acMvValid[1] && acMvValid[2]);
+  }
+#endif
+
   uiCostBest = (Distortion)( floor( fWeight * (double)uiCostBest ) + (double)m_pcRdCost->getCost( uiBitsBest ) );
 
   DTRACE( g_trace_ctx, D_COMMON, " (%d) uiBitsBest=%d, uiCostBest=%d\n", DTRACE_GET_COUNTER(g_trace_ctx,D_COMMON), uiBitsBest, uiCostBest );
@@ -5617,7 +8507,11 @@ void InterSearch::xAffineMotionEstimation( PredictionUnit& pu,
       }
     }
 
+#if GDR_ENABLED
+    bool YYOk = xPredAffineBlk(COMPONENT_Y, pu, refPic, acMvTemp, predBuf, false, pu.cu->slice->clpRng(COMPONENT_Y));
+#else
     xPredAffineBlk( COMPONENT_Y, pu, refPic, acMvTemp, predBuf, false, pu.cu->slice->clpRng( COMPONENT_Y ) );
+#endif
 
     // get error
     Distortion uiCostTemp = m_pcRdCost->getDistPart(predBuf.Y(), pBuf->Y(), pu.cs->sps->getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y, distFunc);
@@ -5637,12 +8531,53 @@ void InterSearch::xAffineMotionEstimation( PredictionUnit& pu,
     {
       uiBitsTemp += xCalcAffineMVBits( pu, acMvTemp, acMvPred );
     }
+#if GDR_ENABLED
+    if (isEncodeGdrClean)
+    {
+      acMvSolid[0] = aamvpi.mvSolidLT[bestMvpIdx];
+      acMvSolid[1] = aamvpi.mvSolidRT[bestMvpIdx];
+      acMvSolid[2] = aamvpi.mvSolidLB[bestMvpIdx];
+
+      bool isSubPuYYClean = YYOk;
+      bool isSubPuCbClean = true;
+
+      acMvValid[0] = isSubPuYYClean && isSubPuCbClean;
+      acMvValid[1] = isSubPuYYClean && isSubPuCbClean;
+      acMvValid[2] = isSubPuYYClean && isSubPuCbClean;
+
+      uiCostTempOk = (acMvSolid[0] && acMvSolid[1] && acMvSolid[2]) && (acMvValid[0] && acMvValid[1] && acMvValid[2]);
+    }
+#endif
+
     uiCostTemp = (Distortion)( floor( fWeight * (double)uiCostTemp ) + (double)m_pcRdCost->getCost( uiBitsTemp ) );
 
     // store best cost and mv
+#if GDR_ENABLED
+    allOk = (uiCostTemp < uiCostBest);
+    if (isEncodeGdrClean)
+    {
+      if (uiCostTempOk)
+      {
+        allOk = (uiCostBestOk) ? (uiCostTemp < uiCostBest) : true;
+      }
+      else
+      {
+        allOk = false;
+      }
+    }
+
+    if (allOk)
+#else
     if ( uiCostTemp < uiCostBest )
+#endif
     {
       uiCostBest = uiCostTemp;
+#if GDR_ENABLED
+      if (isEncodeGdrClean)
+      {
+        uiCostBestOk = uiCostTempOk;
+      }
+#endif
       uiBitsBest = uiBitsTemp;
       memcpy( acMv, acMvTemp, sizeof(Mv) * 3 );
       mvpIdx = bestMvpIdx;
@@ -5651,7 +8586,30 @@ void InterSearch::xAffineMotionEstimation( PredictionUnit& pu,
 
   auto checkCPMVRdCost = [&](Mv ctrlPtMv[3])
   {
+#if GDR_ENABLED
+    bool YYOk = xPredAffineBlk(COMPONENT_Y, pu, refPic, ctrlPtMv, predBuf, false, pu.cu->slice->clpRng(COMPONENT_Y));
+#else
     xPredAffineBlk(COMPONENT_Y, pu, refPic, ctrlPtMv, predBuf, false, pu.cu->slice->clpRng(COMPONENT_Y));
+#endif
+
+#if GDR_ENABLED
+    if (isEncodeGdrClean)
+    {
+      acMvSolid[0] = aamvpi.mvSolidLT[bestMvpIdx];
+      acMvSolid[1] = aamvpi.mvSolidRT[bestMvpIdx];
+      acMvSolid[2] = aamvpi.mvSolidLB[bestMvpIdx];
+
+      bool isSubPuYYClean = YYOk;
+      bool isSubPuCbClean = true; // (isSubPuYYClean) ? xPredAffineBlk(COMPONENT_Cb, pu, refPic, ctrlPtMv, tmpBuf, false, pu.cu->slice->clpRng(COMPONENT_Cb)) : false;
+
+      acMvValid[0] = isSubPuYYClean && isSubPuCbClean;
+      acMvValid[1] = isSubPuYYClean && isSubPuCbClean;
+      acMvValid[2] = isSubPuYYClean && isSubPuCbClean;
+
+      costTempOk = (acMvSolid[0] && acMvSolid[1] && acMvSolid[2]) && (acMvValid[0] && acMvValid[1] && acMvValid[2]);
+    }
+#endif
+
     // get error
     Distortion costTemp = m_pcRdCost->getDistPart(predBuf.Y(), pBuf->Y(), pu.cs->sps->getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y, distFunc);
     // get cost with mv
@@ -5660,9 +8618,33 @@ void InterSearch::xAffineMotionEstimation( PredictionUnit& pu,
     bitsTemp += xCalcAffineMVBits( pu, ctrlPtMv, acMvPred );
     costTemp = (Distortion)(floor(fWeight * (double)costTemp) + (double)m_pcRdCost->getCost(bitsTemp));
     // store best cost and mv
+#if GDR_ENABLED
+    bool allOk = (costTemp < uiCostBest);
+    if (isEncodeGdrClean)
+    {
+      if (costTempOk)
+      {
+        allOk = (uiCostBestOk) ? (costTemp < uiCostBest) : true;
+      }
+      else
+      {
+        allOk = false;
+      }
+    }
+
+    if (allOk)
+#else
     if (costTemp < uiCostBest)
+#endif
     {
       uiCostBest = costTemp;
+#if GDR_ENABLED
+      if (isEncodeGdrClean)
+      {
+        uiCostBestOk = costTempOk;
+        rbCleanCandExist = true;
+      }
+#endif
       uiBitsBest = bitsTemp;
       ::memcpy(acMv, ctrlPtMv, sizeof(Mv) * 3);
     }
@@ -5686,7 +8668,9 @@ void InterSearch::xAffineMotionEstimation( PredictionUnit& pu,
         acMvTemp[j] = mvPredTmp[j];
 
         if (j)
+        {
           acMvTemp[j] += dMv;
+        }
 
         checkCPMVRdCost(acMvTemp);
       }
@@ -5741,15 +8725,62 @@ void InterSearch::xAffineMotionEstimation( PredictionUnit& pu,
           {
             acMvTemp[j].set(centerMv[j].getHor() + (testPos[i][0] << mvShift), centerMv[j].getVer() + (testPos[i][1] << mvShift));
             clipMv( acMvTemp[j], pu.cu->lumaPos(), pu.cu->lumaSize(), *pu.cs->sps, *pu.cs->pps );
+#if GDR_ENABLED
+            bool YYOk = xPredAffineBlk(COMPONENT_Y, pu, refPic, acMvTemp, predBuf, false, pu.cu->slice->clpRng(COMPONENT_Y));
+#else
             xPredAffineBlk(COMPONENT_Y, pu, refPic, acMvTemp, predBuf, false, pu.cu->slice->clpRng(COMPONENT_Y));
+#endif
+
+#if GDR_ENABLED
+            if (isEncodeGdrClean)
+            {
+              acMvSolid[0] = aamvpi.mvSolidLT[bestMvpIdx];
+              acMvSolid[1] = aamvpi.mvSolidRT[bestMvpIdx];
+              acMvSolid[2] = aamvpi.mvSolidLB[bestMvpIdx];
+
+              bool isSubPuYYClean = YYOk;
+              bool isSubPuCbClean = true;
+
+              acMvValid[0] = isSubPuYYClean && isSubPuCbClean;
+              acMvValid[1] = isSubPuYYClean && isSubPuCbClean;
+              acMvValid[2] = isSubPuYYClean && isSubPuCbClean;
+
+              costTempOk = (acMvSolid[0] && acMvSolid[1] && acMvSolid[2]) && (acMvValid[0] && acMvValid[1] && acMvValid[2]);
+            }
+#endif
+
             Distortion costTemp = m_pcRdCost->getDistPart(predBuf.Y(), pBuf->Y(), pu.cs->sps->getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y, distFunc);
             uint32_t bitsTemp = ruiBits;
             bitsTemp += xCalcAffineMVBits(pu, acMvTemp, acMvPred);
             costTemp = (Distortion)(floor(fWeight * (double)costTemp) + (double)m_pcRdCost->getCost(bitsTemp));
 
+#if GDR_ENABLED
+            bool allOk = (costTemp < uiCostBest);
+            if (isEncodeGdrClean)
+            {
+              if (costTempOk)
+              {
+                allOk = (uiCostBestOk) ? (costTemp < uiCostBest) : true;
+              }
+              else
+              {
+                allOk = false;
+              }
+            }
+
+            if (allOk)
+#else
             if (costTemp < uiCostBest)
+#endif
             {
               uiCostBest = costTemp;
+#if GDR_ENABLED
+              if (isEncodeGdrClean)
+              {
+                uiCostBestOk = costTempOk;
+                rbCleanCandExist = true;
+              }
+#endif
               uiBitsBest = bitsTemp;
               ::memcpy(acMv, acMvTemp, sizeof(Mv) * 3);
               modelChange = true;
@@ -5769,6 +8800,12 @@ void InterSearch::xAffineMotionEstimation( PredictionUnit& pu,
   acMvPred[1] = aamvpi.mvCandRT[mvpIdx];
   acMvPred[2] = aamvpi.mvCandLB[mvpIdx];
 
+#if GDR_ENABLED
+  acMvSolid[0] = aamvpi.mvSolidLT[mvpIdx];
+  acMvSolid[1] = aamvpi.mvSolidRT[mvpIdx];
+  acMvSolid[2] = aamvpi.mvSolidLB[mvpIdx];
+#endif
+
   ruiBits = uiBitsBest;
   ruiCost = uiCostBest;
   DTRACE( g_trace_ctx, D_COMMON, " (%d) uiBitsBest=%d, uiCostBest=%d\n", DTRACE_GET_COUNTER(g_trace_ctx,D_COMMON), uiBitsBest, uiCostBest );
@@ -5786,6 +8823,12 @@ void InterSearch::xEstimateAffineAMVP( PredictionUnit&  pu,
   int        iBestIdx = 0;
   Distortion uiBestCost = std::numeric_limits<Distortion>::max();
 
+#if GDR_ENABLED
+  const CodingStructure &cs = *pu.cs;
+  const bool isEncodeGdrClean = cs.sps->getGDREnabledFlag() && cs.pcv->isEncoder && ((cs.picHeader->getInGdrInterval() && cs.isClean(pu.Y().topRight(), CHANNEL_TYPE_LUMA)) || (cs.picHeader->getNumVerVirtualBoundaries() == 0));
+  bool uiBestCostOk = false;
+#endif
+
   // Fill the MV Candidates
   PU::fillAffineMvpCand( pu, eRefPicList, iRefIdx, affineAMVPInfo );
   CHECK( affineAMVPInfo.numCand == 0, "Assertion failed." );
@@ -5798,9 +8841,36 @@ void InterSearch::xEstimateAffineAMVP( PredictionUnit&  pu,
   {
     Mv mv[3] = { affineAMVPInfo.mvCandLT[i], affineAMVPInfo.mvCandRT[i], affineAMVPInfo.mvCandLB[i] };
 
+#if GDR_ENABLED
+    bool uiTmpCostOk = true;
+    Distortion uiTmpCost = xGetAffineTemplateCost(pu, origBuf, predBuf, mv, i, AMVP_MAX_NUM_CANDS, eRefPicList, iRefIdx, uiTmpCostOk);
+    uiTmpCostOk = uiTmpCostOk && affineAMVPInfo.mvSolidLT[i] && affineAMVPInfo.mvSolidRT[i];
+    uiTmpCostOk = uiTmpCostOk && ((pu.cu->affineType == AFFINEMODEL_6PARAM) ? affineAMVPInfo.mvSolidLB[i] : true);
+#else
     Distortion uiTmpCost = xGetAffineTemplateCost( pu, origBuf, predBuf, mv, i, AMVP_MAX_NUM_CANDS, eRefPicList, iRefIdx );
+#endif
+
+#if GDR_ENABLED
+    bool allOk = uiBestCost > uiTmpCost;
+
+    if (isEncodeGdrClean)
+    {
+      if (uiTmpCostOk)
+      {
+        allOk = uiBestCostOk ? (uiBestCost > uiTmpCost) : true;
+      }
+      else
+      {
+        allOk = false;
+      }
+    }
+#endif
 
+#if GDR_ENABLED
+    if (allOk)
+#else
     if ( uiBestCost > uiTmpCost )
+#endif
     {
       uiBestCost = uiTmpCost;
       bestMvLT = affineAMVPInfo.mvCandLT[i];
@@ -5808,6 +8878,12 @@ void InterSearch::xEstimateAffineAMVP( PredictionUnit&  pu,
       bestMvLB = affineAMVPInfo.mvCandLB[i];
       iBestIdx  = i;
       *puiDistBiP = uiTmpCost;
+#if GDR_ENABLED
+      if (isEncodeGdrClean)
+      {
+        uiBestCostOk = uiTmpCostOk;
+      }
+#endif
     }
   }
 
@@ -5818,6 +8894,10 @@ void InterSearch::xEstimateAffineAMVP( PredictionUnit&  pu,
 
   pu.mvpIdx[eRefPicList] = iBestIdx;
   pu.mvpNum[eRefPicList] = affineAMVPInfo.numCand;
+
+#if GDR_ENABLED
+  pu.mvpSolid[eRefPicList] = uiBestCostOk;
+#endif
   DTRACE( g_trace_ctx, D_COMMON, "#estAffi=%d \n", affineAMVPInfo.numCand );
 }
 
@@ -5828,6 +8908,24 @@ void InterSearch::xCopyAffineAMVPInfo (AffineAMVPInfo& src, AffineAMVPInfo& dst)
   ::memcpy( dst.mvCandLT, src.mvCandLT, sizeof(Mv)*src.numCand );
   ::memcpy( dst.mvCandRT, src.mvCandRT, sizeof(Mv)*src.numCand );
   ::memcpy( dst.mvCandLB, src.mvCandLB, sizeof(Mv)*src.numCand );
+
+#if GDR_ENABLED
+  ::memcpy(dst.mvSolidLT, src.mvSolidLT, sizeof(bool)*src.numCand);
+  ::memcpy(dst.mvSolidRT, src.mvSolidRT, sizeof(bool)*src.numCand);
+  ::memcpy(dst.mvSolidLB, src.mvSolidLB, sizeof(bool)*src.numCand);
+
+  ::memcpy(dst.mvValidLT, src.mvValidLT, sizeof(bool)*src.numCand);
+  ::memcpy(dst.mvValidRT, src.mvValidRT, sizeof(bool)*src.numCand);
+  ::memcpy(dst.mvValidLB, src.mvValidLB, sizeof(bool)*src.numCand);
+
+  ::memcpy(dst.mvTypeLT, src.mvTypeLT, sizeof(MvpType)*src.numCand);
+  ::memcpy(dst.mvTypeRT, src.mvTypeRT, sizeof(MvpType)*src.numCand);
+  ::memcpy(dst.mvTypeLB, src.mvTypeLB, sizeof(MvpType)*src.numCand);
+
+  ::memcpy(dst.mvPosLT, src.mvPosLT, sizeof(Position)*src.numCand);
+  ::memcpy(dst.mvPosRT, src.mvPosRT, sizeof(Position)*src.numCand);
+  ::memcpy(dst.mvPosLB, src.mvPosLB, sizeof(Position)*src.numCand);
+#endif
 }
 
 
@@ -5852,17 +8950,18 @@ void InterSearch::xExtDIFUpSamplingH(CPelBuf* pattern, bool useAltHpelIf)
   int halfFilterSize = (filterSize>>1);
   const Pel *srcPtr = pattern->buf - halfFilterSize*srcStride - 1;
 
-  const ChromaFormat chFmt = m_currChromaFormat;
-
-  m_if.filterHor(COMPONENT_Y, srcPtr, srcStride, m_filteredBlockTmp[0][0], intStride, width + 1, height + filterSize, 0 << MV_FRACTIONAL_BITS_DIFF, false, chFmt, clpRng, 0, false, useAltHpelIf);
+  m_if.filterHor(COMPONENT_Y, srcPtr, srcStride, m_filteredBlockTmp[0][0], intStride, width + 1, height + filterSize,
+                 0 << MV_FRACTIONAL_BITS_DIFF, false, clpRng, 0, false, useAltHpelIf);
   if (!m_skipFracME)
   {
-    m_if.filterHor(COMPONENT_Y, srcPtr, srcStride, m_filteredBlockTmp[2][0], intStride, width + 1, height + filterSize, 2 << MV_FRACTIONAL_BITS_DIFF, false, chFmt, clpRng, 0, false, useAltHpelIf);
+    m_if.filterHor(COMPONENT_Y, srcPtr, srcStride, m_filteredBlockTmp[2][0], intStride, width + 1, height + filterSize,
+                   2 << MV_FRACTIONAL_BITS_DIFF, false, clpRng, 0, false, useAltHpelIf);
   }
 
   intPtr = m_filteredBlockTmp[0][0] + halfFilterSize * intStride + 1;
   dstPtr = m_filteredBlock[0][0][0];
-  m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width + 0, height + 0, 0 << MV_FRACTIONAL_BITS_DIFF, false, true, chFmt, clpRng, 0, false, useAltHpelIf);
+  m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width + 0, height + 0, 0 << MV_FRACTIONAL_BITS_DIFF,
+                 false, true, clpRng, 0, false, useAltHpelIf);
   if (m_skipFracME)
   {
     return;
@@ -5870,21 +8969,21 @@ void InterSearch::xExtDIFUpSamplingH(CPelBuf* pattern, bool useAltHpelIf)
 
   intPtr = m_filteredBlockTmp[0][0] + (halfFilterSize - 1) * intStride + 1;
   dstPtr = m_filteredBlock[2][0][0];
-  m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width + 0, height + 1, 2 << MV_FRACTIONAL_BITS_DIFF, false, true, chFmt, clpRng, 0, false, useAltHpelIf);
+  m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width + 0, height + 1, 2 << MV_FRACTIONAL_BITS_DIFF,
+                 false, true, clpRng, 0, false, useAltHpelIf);
 
   intPtr = m_filteredBlockTmp[2][0] + halfFilterSize * intStride;
   dstPtr = m_filteredBlock[0][2][0];
-  m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width + 1, height + 0, 0 << MV_FRACTIONAL_BITS_DIFF, false, true, chFmt, clpRng, 0, false, useAltHpelIf);
+  m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width + 1, height + 0, 0 << MV_FRACTIONAL_BITS_DIFF,
+                 false, true, clpRng, 0, false, useAltHpelIf);
 
   intPtr = m_filteredBlockTmp[2][0] + (halfFilterSize - 1) * intStride;
   dstPtr = m_filteredBlock[2][2][0];
-  m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width + 1, height + 1, 2 << MV_FRACTIONAL_BITS_DIFF, false, true, chFmt, clpRng, 0, false, useAltHpelIf);
+  m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width + 1, height + 1, 2 << MV_FRACTIONAL_BITS_DIFF,
+                 false, true, clpRng, 0, false, useAltHpelIf);
 }
 
 
-
-
-
 /**
 * \brief Generate quarter-sample interpolated blocks
 *
@@ -5910,8 +9009,6 @@ void InterSearch::xExtDIFUpSamplingQ( CPelBuf* pattern, Mv halfPelRef )
 
   int extHeight = (halfPelRef.getVer() == 0) ? height + filterSize : height + filterSize-1;
 
-  const ChromaFormat chFmt = m_currChromaFormat;
-
   // Horizontal filter 1/4
   srcPtr = pattern->buf - halfFilterSize * srcStride - 1;
   intPtr = m_filteredBlockTmp[1][0];
@@ -5923,7 +9020,8 @@ void InterSearch::xExtDIFUpSamplingQ( CPelBuf* pattern, Mv halfPelRef )
   {
     srcPtr += 1;
   }
-  m_if.filterHor(COMPONENT_Y, srcPtr, srcStride, intPtr, intStride, width, extHeight, 1 << MV_FRACTIONAL_BITS_DIFF, false, chFmt, clpRng);
+  m_if.filterHor(COMPONENT_Y, srcPtr, srcStride, intPtr, intStride, width, extHeight, 1 << MV_FRACTIONAL_BITS_DIFF,
+                 false, clpRng);
 
   // Horizontal filter 3/4
   srcPtr = pattern->buf - halfFilterSize*srcStride - 1;
@@ -5936,7 +9034,8 @@ void InterSearch::xExtDIFUpSamplingQ( CPelBuf* pattern, Mv halfPelRef )
   {
     srcPtr += 1;
   }
-  m_if.filterHor(COMPONENT_Y, srcPtr, srcStride, intPtr, intStride, width, extHeight, 3 << MV_FRACTIONAL_BITS_DIFF, false, chFmt, clpRng);
+  m_if.filterHor(COMPONENT_Y, srcPtr, srcStride, intPtr, intStride, width, extHeight, 3 << MV_FRACTIONAL_BITS_DIFF,
+                 false, clpRng);
 
   // Generate @ 1,1
   intPtr = m_filteredBlockTmp[1][0] + (halfFilterSize-1) * intStride;
@@ -5945,12 +9044,14 @@ void InterSearch::xExtDIFUpSamplingQ( CPelBuf* pattern, Mv halfPelRef )
   {
     intPtr += intStride;
   }
-  m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 1 << MV_FRACTIONAL_BITS_DIFF, false, true, chFmt, clpRng);
+  m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 1 << MV_FRACTIONAL_BITS_DIFF, false,
+                 true, clpRng);
 
   // Generate @ 3,1
   intPtr = m_filteredBlockTmp[1][0] + (halfFilterSize-1) * intStride;
   dstPtr = m_filteredBlock[3][1][0];
-  m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 3 << MV_FRACTIONAL_BITS_DIFF, false, true, chFmt, clpRng);
+  m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 3 << MV_FRACTIONAL_BITS_DIFF, false,
+                 true, clpRng);
 
   if (halfPelRef.getVer() != 0)
   {
@@ -5961,7 +9062,8 @@ void InterSearch::xExtDIFUpSamplingQ( CPelBuf* pattern, Mv halfPelRef )
     {
       intPtr += intStride;
     }
-    m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 2 << MV_FRACTIONAL_BITS_DIFF, false, true, chFmt, clpRng);
+    m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 2 << MV_FRACTIONAL_BITS_DIFF,
+                   false, true, clpRng);
 
     // Generate @ 2,3
     intPtr = m_filteredBlockTmp[3][0] + (halfFilterSize - 1) * intStride;
@@ -5970,19 +9072,22 @@ void InterSearch::xExtDIFUpSamplingQ( CPelBuf* pattern, Mv halfPelRef )
     {
       intPtr += intStride;
     }
-    m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 2 << MV_FRACTIONAL_BITS_DIFF, false, true, chFmt, clpRng);
+    m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 2 << MV_FRACTIONAL_BITS_DIFF,
+                   false, true, clpRng);
   }
   else
   {
     // Generate @ 0,1
     intPtr = m_filteredBlockTmp[1][0] + halfFilterSize * intStride;
     dstPtr = m_filteredBlock[0][1][0];
-    m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 0 << MV_FRACTIONAL_BITS_DIFF, false, true, chFmt, clpRng);
+    m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 0 << MV_FRACTIONAL_BITS_DIFF,
+                   false, true, clpRng);
 
     // Generate @ 0,3
     intPtr = m_filteredBlockTmp[3][0] + halfFilterSize * intStride;
     dstPtr = m_filteredBlock[0][3][0];
-    m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 0 << MV_FRACTIONAL_BITS_DIFF, false, true, chFmt, clpRng);
+    m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 0 << MV_FRACTIONAL_BITS_DIFF,
+                   false, true, clpRng);
   }
 
   if (halfPelRef.getHor() != 0)
@@ -5998,7 +9103,8 @@ void InterSearch::xExtDIFUpSamplingQ( CPelBuf* pattern, Mv halfPelRef )
     {
       intPtr += intStride;
     }
-    m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 1 << MV_FRACTIONAL_BITS_DIFF, false, true, chFmt, clpRng);
+    m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 1 << MV_FRACTIONAL_BITS_DIFF,
+                   false, true, clpRng);
 
     // Generate @ 3,2
     intPtr = m_filteredBlockTmp[2][0] + (halfFilterSize - 1) * intStride;
@@ -6011,7 +9117,8 @@ void InterSearch::xExtDIFUpSamplingQ( CPelBuf* pattern, Mv halfPelRef )
     {
       intPtr += intStride;
     }
-    m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 3 << MV_FRACTIONAL_BITS_DIFF, false, true, chFmt, clpRng);
+    m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 3 << MV_FRACTIONAL_BITS_DIFF,
+                   false, true, clpRng);
   }
   else
   {
@@ -6022,7 +9129,8 @@ void InterSearch::xExtDIFUpSamplingQ( CPelBuf* pattern, Mv halfPelRef )
     {
       intPtr += intStride;
     }
-    m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 1 << MV_FRACTIONAL_BITS_DIFF, false, true, chFmt, clpRng);
+    m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 1 << MV_FRACTIONAL_BITS_DIFF,
+                   false, true, clpRng);
 
     // Generate @ 3,0
     intPtr = m_filteredBlockTmp[0][0] + (halfFilterSize - 1) * intStride + 1;
@@ -6031,7 +9139,8 @@ void InterSearch::xExtDIFUpSamplingQ( CPelBuf* pattern, Mv halfPelRef )
     {
       intPtr += intStride;
     }
-    m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 3 << MV_FRACTIONAL_BITS_DIFF, false, true, chFmt, clpRng);
+    m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 3 << MV_FRACTIONAL_BITS_DIFF,
+                   false, true, clpRng);
   }
 
   // Generate @ 1,3
@@ -6041,12 +9150,14 @@ void InterSearch::xExtDIFUpSamplingQ( CPelBuf* pattern, Mv halfPelRef )
   {
     intPtr += intStride;
   }
-  m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 1 << MV_FRACTIONAL_BITS_DIFF, false, true, chFmt, clpRng);
+  m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 1 << MV_FRACTIONAL_BITS_DIFF, false,
+                 true, clpRng);
 
   // Generate @ 3,3
   intPtr = m_filteredBlockTmp[3][0] + (halfFilterSize - 1) * intStride;
   dstPtr = m_filteredBlock[3][3][0];
-  m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 3 << MV_FRACTIONAL_BITS_DIFF, false, true, chFmt, clpRng);
+  m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 3 << MV_FRACTIONAL_BITS_DIFF, false,
+                 true, clpRng);
 }
 
 
@@ -6128,16 +9239,15 @@ void InterSearch::xEncodeInterResidualQT(CodingStructure &cs, Partitioner &parti
       )
     {
       {
-        {
-          const bool  chroma_cbf = TU::getCbfAtDepth( currTU, COMPONENT_Cb, currDepth );
-          if (!(cu.sbtInfo && (currDepth == 0 || (currDepth == 1 && currTU.noResidual))))
-          m_CABACEstimator->cbf_comp( cs, chroma_cbf, currArea.blocks[COMPONENT_Cb], currDepth );
-        }
-        {
-          const bool  chroma_cbf = TU::getCbfAtDepth( currTU, COMPONENT_Cr, currDepth );
-          if (!(cu.sbtInfo && (currDepth == 0 || (currDepth == 1 && currTU.noResidual))))
-          m_CABACEstimator->cbf_comp( cs, chroma_cbf, currArea.blocks[COMPONENT_Cr], currDepth, TU::getCbfAtDepth( currTU, COMPONENT_Cb, currDepth ) );
-        }
+        const bool chroma_cbf = TU::getCbfAtDepth(currTU, COMPONENT_Cb, currDepth);
+        if (!(cu.sbtInfo && (currDepth == 0 || (currDepth == 1 && currTU.noResidual))))
+          m_CABACEstimator->cbf_comp(cs, chroma_cbf, currArea.blocks[COMPONENT_Cb], currDepth);
+      }
+      {
+        const bool chroma_cbf = TU::getCbfAtDepth(currTU, COMPONENT_Cr, currDepth);
+        if (!(cu.sbtInfo && (currDepth == 0 || (currDepth == 1 && currTU.noResidual))))
+          m_CABACEstimator->cbf_comp(cs, chroma_cbf, currArea.blocks[COMPONENT_Cr], currDepth,
+                                     TU::getCbfAtDepth(currTU, COMPONENT_Cb, currDepth));
       }
     }
 
@@ -6180,7 +9290,9 @@ void InterSearch::xEncodeInterResidualQT(CodingStructure &cs, Partitioner &parti
         partitioner.splitCurrArea( PartSplit( cu.getSbtTuSplit() ), cs );
       }
       else
+      {
         THROW( "Implicit TU split not available!" );
+      }
 
       do
       {
@@ -6529,9 +9641,13 @@ void InterSearch::xEstimateInterResidualQT(CodingStructure &cs, Partitioner &par
     {
       const ComponentID compID    = ComponentID(c);
       if (compID == COMPONENT_Y && !luma)
+      {
         continue;
+      }
       if (compID != COMPONENT_Y && !chroma)
+      {
         continue;
+      }
       const CompArea&   compArea  = tu.blocks[compID];
       const int channelBitDepth   = sps.getBitDepth(toChannelType(compID));
 
@@ -6552,8 +9668,8 @@ void InterSearch::xEstimateInterResidualQT(CodingStructure &cs, Partitioner &par
       }
       else
       {
-      trModes.push_back( TrMode( 0, true ) ); //DCT2
-      nNumTransformCands = 1;
+        trModes.push_back(TrMode(0, true));   // DCT2
+        nNumTransformCands = 1;
       }
       //for a SBT-no-residual TU, the RDO process should be called once, in order to get the RD cost
       if( tsAllowed && !tu.noResidual )
@@ -6598,149 +9714,149 @@ void InterSearch::xEstimateInterResidualQT(CodingStructure &cs, Partitioner &par
       const int numTransformCandidates = nNumTransformCands;
       for( int transformMode = 0; transformMode < numTransformCandidates; transformMode++ )
       {
-          const bool isFirstMode  = transformMode == 0;
-          // copy the original residual into the residual buffer
-          if (colorTransFlag)
-          {
-            csFull->getResiBuf(compArea).copyFrom(colorTransResidual.bufs[compID]);
-          }
-          else
+        const bool isFirstMode = transformMode == 0;
+        // copy the original residual into the residual buffer
+        if (colorTransFlag)
+        {
+          csFull->getResiBuf(compArea).copyFrom(colorTransResidual.bufs[compID]);
+        }
+        else
           csFull->getResiBuf(compArea).copyFrom(cs.getOrgResiBuf(compArea));
 
-          m_CABACEstimator->getCtx() = ctxStart;
-          m_CABACEstimator->resetBits();
+        m_CABACEstimator->getCtx() = ctxStart;
+        m_CABACEstimator->resetBits();
 
+        if (!(m_pcEncCfg->getCostMode() == COST_LOSSLESS_CODING && slice.isLossless()))
+        {
+          if (bestTU.mtsIdx[compID] == MTS_SKIP && m_pcEncCfg->getUseTransformSkipFast())
           {
-            if (!(m_pcEncCfg->getCostMode() == COST_LOSSLESS_CODING && slice.isLossless()))
-            {
-            if (bestTU.mtsIdx[compID] == MTS_SKIP && m_pcEncCfg->getUseTransformSkipFast())
-            {
-              continue;
-            }
-            if( !trModes[transformMode].second )
-            {
-              continue;
-            }
-            }
-            tu.mtsIdx[compID] = trModes[transformMode].first;
+            continue;
+          }
+          if (!trModes[transformMode].second)
+          {
+            continue;
           }
-          QpParam cQP(tu, compID);  // note: uses tu.transformSkip[compID]
+        }
+        tu.mtsIdx[compID] = trModes[transformMode].first;
+        QpParam cQP(tu, compID);   // note: uses tu.transformSkip[compID]
 
 #if RDOQ_CHROMA_LAMBDA
-          m_pcTrQuant->selectLambda(compID);
+        m_pcTrQuant->selectLambda(compID);
 #endif
-          if (slice.getLmcsEnabledFlag() && isChroma(compID) && slice.getPicHeader()->getLmcsChromaResidualScaleFlag())
-          {
-            double cRescale = (double)(1 << CSCALE_FP_PREC) / (double)(tu.getChromaAdj());
-            m_pcTrQuant->setLambda(m_pcTrQuant->getLambda() / (cRescale*cRescale));
-          }
-          if ( sps.getJointCbCrEnabledFlag() && isChroma( compID ) && ( tu.cu->cs->slice->getSliceQp() > 18 ) )
-          {
-            m_pcTrQuant->setLambda( 1.05 * m_pcTrQuant->getLambda() );
-          }
+        if (slice.getLmcsEnabledFlag() && isChroma(compID) && slice.getPicHeader()->getLmcsChromaResidualScaleFlag())
+        {
+          double cRescale = (double) (1 << CSCALE_FP_PREC) / (double) (tu.getChromaAdj());
+          m_pcTrQuant->setLambda(m_pcTrQuant->getLambda() / (cRescale * cRescale));
+        }
+        if (sps.getJointCbCrEnabledFlag() && isChroma(compID) && (tu.cu->cs->slice->getSliceQp() > 18))
+        {
+          m_pcTrQuant->setLambda(1.05 * m_pcTrQuant->getLambda());
+        }
 
-          TCoeff     currAbsSum = 0;
-          uint64_t   currCompFracBits = 0;
-          Distortion currCompDist = 0;
-          double     currCompCost = 0;
-          uint64_t   nonCoeffFracBits = 0;
-          Distortion nonCoeffDist = 0;
-          double     nonCoeffCost = 0;
+        TCoeff     currAbsSum       = 0;
+        uint64_t   currCompFracBits = 0;
+        Distortion currCompDist     = 0;
+        double     currCompCost     = 0;
+        uint64_t   nonCoeffFracBits = 0;
+        Distortion nonCoeffDist     = 0;
+        double     nonCoeffCost     = 0;
 
-          if (!colorTransFlag && slice.getLmcsEnabledFlag() && isChroma(compID) && slice.getPicHeader()->getLmcsChromaResidualScaleFlag() && tu.blocks[compID].width*tu.blocks[compID].height > 4)
+        if (!colorTransFlag && slice.getLmcsEnabledFlag() && isChroma(compID)
+            && slice.getPicHeader()->getLmcsChromaResidualScaleFlag()
+            && tu.blocks[compID].width * tu.blocks[compID].height > 4)
+        {
+          PelBuf resiBuf = csFull->getResiBuf(compArea);
+          resiBuf.scaleSignal(tu.getChromaAdj(), 1, tu.cu->cs->slice->clpRng(compID));
+        }
+        if (nNumTransformCands > 1)
+        {
+          if (transformMode == 0)
           {
-            PelBuf resiBuf = csFull->getResiBuf(compArea);
-            resiBuf.scaleSignal(tu.getChromaAdj(), 1, tu.cu->cs->slice->clpRng(compID));
+            m_pcTrQuant->transformNxN(tu, compID, cQP, &trModes, m_pcEncCfg->getMTSInterMaxCand());
+            tu.mtsIdx[compID] = trModes[0].first;
           }
-          if( nNumTransformCands > 1 )
+          if (!(m_pcEncCfg->getCostMode() == COST_LOSSLESS_CODING && slice.isLossless() && tu.mtsIdx[compID] == 0))
           {
-            if( transformMode == 0 )
-            {
-              m_pcTrQuant->transformNxN( tu, compID, cQP, &trModes, m_pcEncCfg->getMTSInterMaxCand() );
-              tu.mtsIdx[compID] = trModes[0].first;
-            }
-            if (!(m_pcEncCfg->getCostMode() == COST_LOSSLESS_CODING && slice.isLossless() && tu.mtsIdx[compID] == 0))
-            {
-              m_pcTrQuant->transformNxN( tu, compID, cQP, currAbsSum, m_CABACEstimator->getCtx(), true );
-            }
+            m_pcTrQuant->transformNxN(tu, compID, cQP, currAbsSum, m_CABACEstimator->getCtx(), true);
           }
-          else
+        }
+        else
+        {
+          m_pcTrQuant->transformNxN(tu, compID, cQP, currAbsSum, m_CABACEstimator->getCtx());
+        }
+
+        if (isFirstMode || (currAbsSum == 0))
+        {
+          const CPelBuf zeroBuf(m_pTempPel, compArea);
+          const CPelBuf orgResi = colorTransFlag ? colorTransResidual.bufs[compID] : csFull->getOrgResiBuf(compArea);
+
           {
-            m_pcTrQuant->transformNxN( tu, compID, cQP, currAbsSum, m_CABACEstimator->getCtx() );
+            nonCoeffDist = m_pcRdCost->getDistPart(zeroBuf, orgResi, channelBitDepth, compID,
+                                                   DF_SSE);   // initialized with zero residual distortion
           }
 
-          if (isFirstMode || (currAbsSum == 0))
+          if (!tu.noResidual)
           {
-            const CPelBuf zeroBuf(m_pTempPel, compArea);
-            const CPelBuf orgResi = colorTransFlag ? colorTransResidual.bufs[compID] : csFull->getOrgResiBuf(compArea);
-
-            {
-              nonCoeffDist = m_pcRdCost->getDistPart( zeroBuf, orgResi, channelBitDepth, compID, DF_SSE ); // initialized with zero residual distortion
-            }
-
-            if( !tu.noResidual )
-            {
             const bool prevCbf = ( compID == COMPONENT_Cr ? tu.cbf[COMPONENT_Cb] : false );
             m_CABACEstimator->cbf_comp( *csFull, false, compArea, currDepth, prevCbf );
+          }
 
-            }
-
-            nonCoeffFracBits = m_CABACEstimator->getEstFracBits();
+          nonCoeffFracBits = m_CABACEstimator->getEstFracBits();
 #if WCG_EXT
-            if( m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled() )
-            {
-              nonCoeffCost   = m_pcRdCost->calcRdCost(nonCoeffFracBits, nonCoeffDist, false);
-            }
-            else
-#endif
-              if (cs.slice->getSPS()->getUseColorTrans())
-              {
-                nonCoeffCost = m_pcRdCost->calcRdCost(nonCoeffFracBits, nonCoeffDist, false);
-              }
-              else
-              {
-                nonCoeffCost = m_pcRdCost->calcRdCost(nonCoeffFracBits, nonCoeffDist);
-              }
+          if (m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled())
+          {
+            nonCoeffCost = m_pcRdCost->calcRdCost(nonCoeffFracBits, nonCoeffDist, false);
           }
-
-          if ((puiZeroDist != NULL) && isFirstMode)
+          else
+#endif
+            if (cs.slice->getSPS()->getUseColorTrans())
           {
-            *puiZeroDist += nonCoeffDist; // initialized with zero residual distortion
+            nonCoeffCost = m_pcRdCost->calcRdCost(nonCoeffFracBits, nonCoeffDist, false);
           }
-          if (m_pcEncCfg->getCostMode() == COST_LOSSLESS_CODING && slice.isLossless() && tu.mtsIdx[compID] == 0)
+          else
           {
-            currAbsSum = 0;
+            nonCoeffCost = m_pcRdCost->calcRdCost(nonCoeffFracBits, nonCoeffDist);
           }
+        }
 
-          if (currAbsSum > 0) //if non-zero coefficients are present, a residual needs to be derived for further prediction
-          {
-            if (isFirstMode)
-            {
-              m_CABACEstimator->getCtx() = ctxStart;
-              m_CABACEstimator->resetBits();
-            }
+        if ((puiZeroDist != NULL) && isFirstMode)
+        {
+          *puiZeroDist += nonCoeffDist;   // initialized with zero residual distortion
+        }
+        if (m_pcEncCfg->getCostMode() == COST_LOSSLESS_CODING && slice.isLossless() && tu.mtsIdx[compID] == 0)
+        {
+          currAbsSum = 0;
+        }
 
-            const bool prevCbf = ( compID == COMPONENT_Cr ? tu.cbf[COMPONENT_Cb] : false );
-            m_CABACEstimator->cbf_comp( *csFull, true, compArea, currDepth, prevCbf );
-            if( compID == COMPONENT_Cr )
-            {
-              const int cbfMask = ( tu.cbf[COMPONENT_Cb] ? 2 : 0 ) + 1;
-              m_CABACEstimator->joint_cb_cr( tu, cbfMask );
-            }
+        if (currAbsSum
+            > 0)   // if non-zero coefficients are present, a residual needs to be derived for further prediction
+        {
+          if (isFirstMode)
+          {
+            m_CABACEstimator->getCtx() = ctxStart;
+            m_CABACEstimator->resetBits();
+          }
 
-            CUCtx cuCtx;
-            cuCtx.isDQPCoded = true;
-            cuCtx.isChromaQpAdjCoded = true;
-            m_CABACEstimator->residual_coding(tu, compID, &cuCtx);
-            m_CABACEstimator->mts_idx(cu, &cuCtx);
+          const bool prevCbf = (compID == COMPONENT_Cr ? tu.cbf[COMPONENT_Cb] : false);
+          m_CABACEstimator->cbf_comp(*csFull, true, compArea, currDepth, prevCbf);
+          if (compID == COMPONENT_Cr)
+          {
+            const int cbfMask = (tu.cbf[COMPONENT_Cb] ? 2 : 0) + 1;
+            m_CABACEstimator->joint_cb_cr(tu, cbfMask);
+          }
 
-            if (compID == COMPONENT_Y && tu.mtsIdx[compID] > MTS_SKIP && !cuCtx.mtsLastScanPos)
-            {
-              currCompCost = MAX_DOUBLE;
-            }
-            else
-            {
+          CUCtx cuCtx;
+          cuCtx.isDQPCoded         = true;
+          cuCtx.isChromaQpAdjCoded = true;
+          m_CABACEstimator->residual_coding(tu, compID, &cuCtx);
+          m_CABACEstimator->mts_idx(cu, &cuCtx);
 
+          if (compID == COMPONENT_Y && tu.mtsIdx[compID] > MTS_SKIP && !cuCtx.mtsLastScanPos)
+          {
+            currCompCost = MAX_DOUBLE;
+          }
+          else
+          {
             currCompFracBits = m_CABACEstimator->getEstFracBits();
 
             PelBuf resiBuf = csFull->getResiBuf(compArea);
@@ -6759,53 +9875,53 @@ void InterSearch::xEstimateInterResidualQT(CodingStructure &cs, Partitioner &par
 #else
             currCompCost = m_pcRdCost->calcRdCost(currCompFracBits, currCompDist);
 #endif
-            }
-          }
-          else if( transformMode > 0 )
-          {
-            currCompCost = MAX_DOUBLE;
           }
-          else
+        }
+        else if (transformMode > 0)
+        {
+          currCompCost = MAX_DOUBLE;
+        }
+        else
+        {
+          currCompFracBits = nonCoeffFracBits;
+          currCompDist     = nonCoeffDist;
+          currCompCost     = nonCoeffCost;
+
+          tu.cbf[compID] = 0;
+        }
+
+        // evaluate
+        if ((currCompCost < minCost[compID]) || (transformMode == 1 && currCompCost == minCost[compID]))
+        {
+          // copy component
+          if (isFirstMode && ((nonCoeffCost < currCompCost) || (currAbsSum == 0)))   // check for forced null
           {
+            tu.getCoeffs(compID).fill(0);
+            csFull->getResiBuf(compArea).fill(0);
+            tu.cbf[compID] = 0;
+
+            currAbsSum       = 0;
             currCompFracBits = nonCoeffFracBits;
             currCompDist     = nonCoeffDist;
             currCompCost     = nonCoeffCost;
-
-            tu.cbf[compID] = 0;
           }
 
-          // evaluate
-          if( ( currCompCost < minCost[compID] ) || ( transformMode == 1 && currCompCost == minCost[compID] ) )
-          {
-            // copy component
-            if (isFirstMode && ((nonCoeffCost < currCompCost) || (currAbsSum == 0))) // check for forced null
-            {
-              tu.getCoeffs( compID ).fill( 0 );
-              csFull->getResiBuf( compArea ).fill( 0 );
-              tu.cbf[compID]   = 0;
-
-              currAbsSum       = 0;
-              currCompFracBits = nonCoeffFracBits;
-              currCompDist     = nonCoeffDist;
-              currCompCost     = nonCoeffCost;
-            }
-
-            uiSingleDistComp[compID] = currCompDist;
-            uiSingleFracBits[compID] = currCompFracBits;
-            minCost[compID]          = currCompCost;
+          uiSingleDistComp[compID] = currCompDist;
+          uiSingleFracBits[compID] = currCompFracBits;
+          minCost[compID]          = currCompCost;
 
-              bestTU.copyComponentFrom( tu, compID );
-              saveCS.getResiBuf( compArea ).copyFrom( csFull->getResiBuf( compArea ) );
-          }
-          if( tu.noResidual )
-          {
-            CHECK( currCompFracBits > 0 || currAbsSum, "currCompFracBits > 0 when tu noResidual" );
-          }
+          bestTU.copyComponentFrom(tu, compID);
+          saveCS.getResiBuf(compArea).copyFrom(csFull->getResiBuf(compArea));
+        }
+        if (tu.noResidual)
+        {
+          CHECK(currCompFracBits > 0 || currAbsSum, "currCompFracBits > 0 when tu noResidual");
+        }
       }
 
-        // copy component
-        tu.copyComponentFrom( bestTU, compID );
-        csFull->getResiBuf( compArea ).copyFrom( saveCS.getResiBuf( compArea ) );
+      // copy component
+      tu.copyComponentFrom(bestTU, compID);
+      csFull->getResiBuf(compArea).copyFrom(saveCS.getResiBuf(compArea));
       if (colorTransFlag && (m_pcEncCfg->getCostMode() != COST_LOSSLESS_CODING || !slice.isLossless()))
       {
         m_pcTrQuant->lambdaAdjustColorTrans(false);
@@ -6867,8 +9983,8 @@ void InterSearch::xEstimateInterResidualQT(CodingStructure &cs, Partitioner &par
         }
         else
         {
-        orgResiCb[0].copyFrom(cs.getOrgResiBuf(cbArea));
-        orgResiCr[0].copyFrom(cs.getOrgResiBuf(crArea));
+          orgResiCb[0].copyFrom(cs.getOrgResiBuf(cbArea));
+          orgResiCr[0].copyFrom(cs.getOrgResiBuf(crArea));
         }
         if (!colorTransFlag && reshape)
         {
@@ -6889,185 +10005,203 @@ void InterSearch::xEstimateInterResidualQT(CodingStructure &cs, Partitioner &par
         std::vector<TrMode> trModes;
         if (checkDCTOnly || checkTSOnly)
         {
-          numTransformCands = 1;
-        }
-
-        if (!checkTSOnly)
-        {
-          trModes.push_back(TrMode(0, true)); // DCT2
-        }
-        if (tsAllowed && !checkDCTOnly)
-        {
-          trModes.push_back(TrMode(1, true));//TS
-        }
-        for (int modeId = 0; modeId < numTransformCands; modeId++)
-        {
-          if (modeId && !cbfDCT2)
-          {
-            continue;
-          }
-          if (!trModes[modeId].second)
-          {
-            continue;
-          }
-        TCoeff     currAbsSum       = 0;
-        uint64_t   currCompFracBits = 0;
-        Distortion currCompDistCb   = 0;
-        Distortion currCompDistCr   = 0;
-        double     currCompCost     = 0;
-
-        tu.jointCbCr = (uint8_t) cbfMask;
-          // encoder bugfix: initialize mtsIdx for chroma under JointCbCrMode.
-        tu.mtsIdx[codeCompId]  = trModes[modeId].first;
-        tu.mtsIdx[otherCompId] = MTS_DCT2_DCT2;
-        int         codedCbfMask = 0;
-        if (colorTransFlag && (m_pcEncCfg->getCostMode() != COST_LOSSLESS_CODING || !slice.isLossless()))
-        {
-          m_pcTrQuant->lambdaAdjustColorTrans(true);
-          m_pcTrQuant->selectLambda(codeCompId);
-        }
-        else
-        {
-          m_pcTrQuant->selectLambda(codeCompId);
-        }
-        // Lambda is loosened for the joint mode with respect to single modes as the same residual is used for both chroma blocks
-        const int    absIct = abs( TU::getICTMode(tu) );
-        const double lfact  = ( absIct == 1 || absIct == 3 ? 0.8 : 0.5 );
-        m_pcTrQuant->setLambda( lfact * m_pcTrQuant->getLambda() );
-        if ( checkJointCbCr && (tu.cu->cs->slice->getSliceQp() > 18))
-        {
-          m_pcTrQuant->setLambda( 1.05 * m_pcTrQuant->getLambda() );
-        }
-
-        m_CABACEstimator->getCtx() = ctxStart;
-        m_CABACEstimator->resetBits();
-
-        PelBuf cbResi = csFull->getResiBuf(cbArea);
-        PelBuf crResi = csFull->getResiBuf(crArea);
-        cbResi.copyFrom(orgResiCb[cbfMask]);
-        crResi.copyFrom(orgResiCr[cbfMask]);
-
-        if ( reshape )
-        {
-          double cRescale = (double)(1 << CSCALE_FP_PREC) / (double)(tu.getChromaAdj());
-          m_pcTrQuant->setLambda(m_pcTrQuant->getLambda() / (cRescale*cRescale));
-        }
-
-        Distortion currCompDistY = MAX_UINT64;
-        QpParam qpCbCr(tu, codeCompId);
-
-        tu.getCoeffs(otherCompId).fill(0);   // do we need that?
-        TU::setCbfAtDepth(tu, otherCompId, tu.depth, false);
-
-        PelBuf &codeResi   = (codeCompId == COMPONENT_Cr ? crResi : cbResi);
-        TCoeff  compAbsSum = 0;
-        if (numTransformCands > 1)
-        {
-          if (modeId == 0)
-          {
-            m_pcTrQuant->transformNxN(tu, codeCompId, qpCbCr, &trModes, m_pcEncCfg->getMTSInterMaxCand());
-            tu.mtsIdx[codeCompId] = trModes[modeId].first;
-            tu.mtsIdx[otherCompId] = MTS_DCT2_DCT2;
-          }
-          m_pcTrQuant->transformNxN(tu, codeCompId, qpCbCr, compAbsSum, m_CABACEstimator->getCtx(), true);
-        }
-        else
-        m_pcTrQuant->transformNxN(tu, codeCompId, qpCbCr, compAbsSum, m_CABACEstimator->getCtx());
-        if (compAbsSum > 0)
-        {
-          m_pcTrQuant->invTransformNxN(tu, codeCompId, codeResi, qpCbCr);
-          codedCbfMask += (codeCompId == COMPONENT_Cb ? 2 : 1);
-        }
-        else
-        {
-          codeResi.fill(0);
-        }
-
-        if (tu.jointCbCr == 3 && codedCbfMask == 2)
-        {
-          codedCbfMask = 3;
-          TU::setCbfAtDepth(tu, COMPONENT_Cr, tu.depth, true);
+          numTransformCands = 1;
         }
-        if (codedCbfMask && tu.jointCbCr != codedCbfMask)
+
+        if (!checkTSOnly)
         {
-          codedCbfMask = 0;
+          trModes.push_back(TrMode(0, true)); // DCT2
         }
-        currAbsSum = codedCbfMask;
-
-        if (!tu.mtsIdx[codeCompId])
+        if (tsAllowed && !checkDCTOnly)
         {
-          cbfDCT2 = (currAbsSum > 0);
+          trModes.push_back(TrMode(1, true));//TS
         }
-        if (currAbsSum > 0)
+        for (int modeId = 0; modeId < numTransformCands; modeId++)
         {
-          m_CABACEstimator->cbf_comp(cs, codedCbfMask >> 1, cbArea, currDepth, false);
-          m_CABACEstimator->cbf_comp(cs, codedCbfMask & 1, crArea, currDepth, codedCbfMask >> 1);
-          m_CABACEstimator->joint_cb_cr(tu, codedCbfMask);
-          if (codedCbfMask >> 1)
-            m_CABACEstimator->residual_coding(tu, COMPONENT_Cb);
-          if (codedCbfMask & 1)
-            m_CABACEstimator->residual_coding(tu, COMPONENT_Cr);
-          currCompFracBits = m_CABACEstimator->getEstFracBits();
+          if (modeId && !cbfDCT2)
+          {
+            continue;
+          }
+          if (!trModes[modeId].second)
+          {
+            continue;
+          }
+          TCoeff     currAbsSum       = 0;
+          uint64_t   currCompFracBits = 0;
+          Distortion currCompDistCb   = 0;
+          Distortion currCompDistCr   = 0;
+          double     currCompCost     = 0;
+
+          tu.jointCbCr = (uint8_t) cbfMask;
+          // encoder bugfix: initialize mtsIdx for chroma under JointCbCrMode.
+          tu.mtsIdx[codeCompId]  = trModes[modeId].first;
+          tu.mtsIdx[otherCompId] = MTS_DCT2_DCT2;
+          int codedCbfMask       = 0;
+          if (colorTransFlag && (m_pcEncCfg->getCostMode() != COST_LOSSLESS_CODING || !slice.isLossless()))
+          {
+            m_pcTrQuant->lambdaAdjustColorTrans(true);
+            m_pcTrQuant->selectLambda(codeCompId);
+          }
+          else
+          {
+            m_pcTrQuant->selectLambda(codeCompId);
+          }
+          // Lambda is loosened for the joint mode with respect to single modes as the same residual is used for both
+          // chroma blocks
+          const int    absIct = abs(TU::getICTMode(tu));
+          const double lfact  = (absIct == 1 || absIct == 3 ? 0.8 : 0.5);
+          m_pcTrQuant->setLambda(lfact * m_pcTrQuant->getLambda());
+          if (checkJointCbCr && (tu.cu->cs->slice->getSliceQp() > 18))
+          {
+            m_pcTrQuant->setLambda(1.05 * m_pcTrQuant->getLambda());
+          }
+
+          m_CABACEstimator->getCtx() = ctxStart;
+          m_CABACEstimator->resetBits();
+
+          PelBuf cbResi = csFull->getResiBuf(cbArea);
+          PelBuf crResi = csFull->getResiBuf(crArea);
+          cbResi.copyFrom(orgResiCb[cbfMask]);
+          crResi.copyFrom(orgResiCr[cbfMask]);
 
-          m_pcTrQuant->invTransformICT(tu, cbResi, crResi);
-          if (!colorTransFlag && reshape)
+          if (reshape)
           {
-            cbResi.scaleSignal(tu.getChromaAdj(), 0, tu.cu->cs->slice->clpRng(COMPONENT_Cb));
-            crResi.scaleSignal(tu.getChromaAdj(), 0, tu.cu->cs->slice->clpRng(COMPONENT_Cr));
+            double cRescale = (double) (1 << CSCALE_FP_PREC) / (double) (tu.getChromaAdj());
+            m_pcTrQuant->setLambda(m_pcTrQuant->getLambda() / (cRescale * cRescale));
           }
 
-          if (colorTransFlag)
+          Distortion currCompDistY = MAX_UINT64;
+          QpParam    qpCbCr(tu, codeCompId);
+
+          tu.getCoeffs(otherCompId).fill(0);   // do we need that?
+          TU::setCbfAtDepth(tu, otherCompId, tu.depth, false);
+
+          PelBuf &codeResi   = (codeCompId == COMPONENT_Cr ? crResi : cbResi);
+          TCoeff  compAbsSum = 0;
+          if (numTransformCands > 1)
           {
-            PelUnitBuf     orgResidual = orgResi->subBuf(relativeUnitArea);
-            PelUnitBuf     invColorTransResidual = m_colorTransResiBuf[2].getBuf(relativeUnitArea);
-            csFull->getResiBuf(currArea).colorSpaceConvert(invColorTransResidual, false, slice.clpRng(COMPONENT_Y));
-            if (reshape)
+            if (modeId == 0)
             {
-              invColorTransResidual.bufs[1].scaleSignal(tu.getChromaAdj(), 0, tu.cu->cs->slice->clpRng(COMPONENT_Cb));
-              invColorTransResidual.bufs[2].scaleSignal(tu.getChromaAdj(), 0, tu.cu->cs->slice->clpRng(COMPONENT_Cr));
+              m_pcTrQuant->transformNxN(tu, codeCompId, qpCbCr, &trModes, m_pcEncCfg->getMTSInterMaxCand());
+              tu.mtsIdx[codeCompId]  = trModes[modeId].first;
+              tu.mtsIdx[otherCompId] = MTS_DCT2_DCT2;
             }
-
-            currCompDistY = m_pcRdCost->getDistPart(orgResidual.bufs[COMPONENT_Y], invColorTransResidual.bufs[COMPONENT_Y], sps.getBitDepth(toChannelType(COMPONENT_Y)), COMPONENT_Y, DF_SSE);
-            currCompDistCb = m_pcRdCost->getDistPart(orgResidual.bufs[COMPONENT_Cb], invColorTransResidual.bufs[COMPONENT_Cb], sps.getBitDepth(toChannelType(COMPONENT_Cb)), COMPONENT_Cb, DF_SSE);
-            currCompDistCr = m_pcRdCost->getDistPart(orgResidual.bufs[COMPONENT_Cr], invColorTransResidual.bufs[COMPONENT_Cr], sps.getBitDepth(toChannelType(COMPONENT_Cr)), COMPONENT_Cr, DF_SSE);
-            currCompCost = m_pcRdCost->calcRdCost(uiSingleFracBits[COMPONENT_Y] + currCompFracBits, currCompDistY + currCompDistCr + currCompDistCb, false);
+            m_pcTrQuant->transformNxN(tu, codeCompId, qpCbCr, compAbsSum, m_CABACEstimator->getCtx(), true);
+          }
+          else
+          {
+            m_pcTrQuant->transformNxN(tu, codeCompId, qpCbCr, compAbsSum, m_CABACEstimator->getCtx());
+          }
+          if (compAbsSum > 0)
+          {
+            m_pcTrQuant->invTransformNxN(tu, codeCompId, codeResi, qpCbCr);
+            codedCbfMask += (codeCompId == COMPONENT_Cb ? 2 : 1);
           }
           else
           {
-          currCompDistCb = m_pcRdCost->getDistPart(csFull->getOrgResiBuf(cbArea), cbResi, channelBitDepth, COMPONENT_Cb, DF_SSE);
-          currCompDistCr = m_pcRdCost->getDistPart(csFull->getOrgResiBuf(crArea), crResi, channelBitDepth, COMPONENT_Cr, DF_SSE);
+            codeResi.fill(0);
+          }
+
+          if (tu.jointCbCr == 3 && codedCbfMask == 2)
+          {
+            codedCbfMask = 3;
+            TU::setCbfAtDepth(tu, COMPONENT_Cr, tu.depth, true);
+          }
+          if (codedCbfMask && tu.jointCbCr != codedCbfMask)
+          {
+            codedCbfMask = 0;
+          }
+          currAbsSum = codedCbfMask;
+
+          if (!tu.mtsIdx[codeCompId])
+          {
+            cbfDCT2 = (currAbsSum > 0);
+          }
+          if (currAbsSum > 0)
+          {
+            m_CABACEstimator->cbf_comp(cs, codedCbfMask >> 1, cbArea, currDepth, false);
+            m_CABACEstimator->cbf_comp(cs, codedCbfMask & 1, crArea, currDepth, codedCbfMask >> 1);
+            m_CABACEstimator->joint_cb_cr(tu, codedCbfMask);
+            if (codedCbfMask >> 1)
+            {
+              m_CABACEstimator->residual_coding(tu, COMPONENT_Cb);
+            }
+            if (codedCbfMask & 1)
+            {
+              m_CABACEstimator->residual_coding(tu, COMPONENT_Cr);
+            }
+            currCompFracBits = m_CABACEstimator->getEstFracBits();
+
+            m_pcTrQuant->invTransformICT(tu, cbResi, crResi);
+            if (!colorTransFlag && reshape)
+            {
+              cbResi.scaleSignal(tu.getChromaAdj(), 0, tu.cu->cs->slice->clpRng(COMPONENT_Cb));
+              crResi.scaleSignal(tu.getChromaAdj(), 0, tu.cu->cs->slice->clpRng(COMPONENT_Cr));
+            }
+
+            if (colorTransFlag)
+            {
+              PelUnitBuf orgResidual           = orgResi->subBuf(relativeUnitArea);
+              PelUnitBuf invColorTransResidual = m_colorTransResiBuf[2].getBuf(relativeUnitArea);
+              csFull->getResiBuf(currArea).colorSpaceConvert(invColorTransResidual, false, slice.clpRng(COMPONENT_Y));
+              if (reshape)
+              {
+                invColorTransResidual.bufs[1].scaleSignal(tu.getChromaAdj(), 0, tu.cu->cs->slice->clpRng(COMPONENT_Cb));
+                invColorTransResidual.bufs[2].scaleSignal(tu.getChromaAdj(), 0, tu.cu->cs->slice->clpRng(COMPONENT_Cr));
+              }
+
+              currCompDistY =
+                m_pcRdCost->getDistPart(orgResidual.bufs[COMPONENT_Y], invColorTransResidual.bufs[COMPONENT_Y],
+                                        sps.getBitDepth(toChannelType(COMPONENT_Y)), COMPONENT_Y, DF_SSE);
+              currCompDistCb =
+                m_pcRdCost->getDistPart(orgResidual.bufs[COMPONENT_Cb], invColorTransResidual.bufs[COMPONENT_Cb],
+                                        sps.getBitDepth(toChannelType(COMPONENT_Cb)), COMPONENT_Cb, DF_SSE);
+              currCompDistCr =
+                m_pcRdCost->getDistPart(orgResidual.bufs[COMPONENT_Cr], invColorTransResidual.bufs[COMPONENT_Cr],
+                                        sps.getBitDepth(toChannelType(COMPONENT_Cr)), COMPONENT_Cr, DF_SSE);
+              currCompCost = m_pcRdCost->calcRdCost(uiSingleFracBits[COMPONENT_Y] + currCompFracBits,
+                                                    currCompDistY + currCompDistCr + currCompDistCb, false);
+            }
+            else
+            {
+              currCompDistCb =
+                m_pcRdCost->getDistPart(csFull->getOrgResiBuf(cbArea), cbResi, channelBitDepth, COMPONENT_Cb, DF_SSE);
+              currCompDistCr =
+                m_pcRdCost->getDistPart(csFull->getOrgResiBuf(crArea), crResi, channelBitDepth, COMPONENT_Cr, DF_SSE);
 #if WCG_EXT
-          currCompCost   = m_pcRdCost->calcRdCost(currCompFracBits, currCompDistCr + currCompDistCb, false);
+              currCompCost = m_pcRdCost->calcRdCost(currCompFracBits, currCompDistCr + currCompDistCb, false);
 #else
-          currCompCost   = m_pcRdCost->calcRdCost(currCompFracBits, currCompDistCr + currCompDistCb);
+              currCompCost = m_pcRdCost->calcRdCost(currCompFracBits, currCompDistCr + currCompDistCb);
 #endif
+            }
           }
-        }
-        else
-          currCompCost = MAX_DOUBLE;
-
-        // evaluate
-        if( currCompCost < minCostCbCr )
-        {
-          uiSingleDistComp[COMPONENT_Cb] = currCompDistCb;
-          uiSingleDistComp[COMPONENT_Cr] = currCompDistCr;
-          if (colorTransFlag)
+          else
           {
-            uiSingleDistComp[COMPONENT_Y] = currCompDistY;
+            currCompCost = MAX_DOUBLE;
           }
-          minCostCbCr                    = currCompCost;
+
+          // evaluate
+          if (currCompCost < minCostCbCr)
           {
-            bestTU.copyComponentFrom(tu, COMPONENT_Cb);
-            bestTU.copyComponentFrom(tu, COMPONENT_Cr);
-            saveCS.getResiBuf(cbArea).copyFrom(csFull->getResiBuf(cbArea));
-            saveCS.getResiBuf(crArea).copyFrom(csFull->getResiBuf(crArea));
+            uiSingleDistComp[COMPONENT_Cb] = currCompDistCb;
+            uiSingleDistComp[COMPONENT_Cr] = currCompDistCr;
+            if (colorTransFlag)
+            {
+              uiSingleDistComp[COMPONENT_Y] = currCompDistY;
+            }
+            minCostCbCr = currCompCost;
+            {
+              bestTU.copyComponentFrom(tu, COMPONENT_Cb);
+              bestTU.copyComponentFrom(tu, COMPONENT_Cr);
+              saveCS.getResiBuf(cbArea).copyFrom(csFull->getResiBuf(cbArea));
+              saveCS.getResiBuf(crArea).copyFrom(csFull->getResiBuf(crArea));
+            }
           }
-        }
 
-        if (colorTransFlag && (m_pcEncCfg->getCostMode() != COST_LOSSLESS_CODING || !slice.isLossless()))
-        {
-          m_pcTrQuant->lambdaAdjustColorTrans(false);
-        }
+          if (colorTransFlag && (m_pcEncCfg->getCostMode() != COST_LOSSLESS_CODING || !slice.isLossless()))
+          {
+            m_pcTrQuant->lambdaAdjustColorTrans(false);
+          }
         }
       }
       // copy component
@@ -7083,27 +10217,36 @@ void InterSearch::xEstimateInterResidualQT(CodingStructure &cs, Partitioner &par
     {
       static const ComponentID cbf_getComp[MAX_NUM_COMPONENT] = { COMPONENT_Cb, COMPONENT_Cr, COMPONENT_Y };
       for( unsigned c = isChromaEnabled(tu.chromaFormat)?0 : 2; c < MAX_NUM_COMPONENT; c++)
-    {
-      const ComponentID compID = cbf_getComp[c];
-      if (compID == COMPONENT_Y && !luma)
-        continue;
-      if (compID != COMPONENT_Y && !chroma)
-        continue;
-      if( tu.blocks[compID].valid() )
       {
-        const bool prevCbf = ( compID == COMPONENT_Cr ? TU::getCbfAtDepth( tu, COMPONENT_Cb, currDepth ) : false );
-        m_CABACEstimator->cbf_comp( *csFull, TU::getCbfAtDepth( tu, compID, currDepth ), tu.blocks[compID], currDepth, prevCbf );
+        const ComponentID compID = cbf_getComp[c];
+        if (compID == COMPONENT_Y && !luma)
+        {
+          continue;
+        }
+        if (compID != COMPONENT_Y && !chroma)
+        {
+          continue;
+        }
+        if (tu.blocks[compID].valid())
+        {
+          const bool prevCbf = (compID == COMPONENT_Cr ? TU::getCbfAtDepth(tu, COMPONENT_Cb, currDepth) : false);
+          m_CABACEstimator->cbf_comp(*csFull, TU::getCbfAtDepth(tu, compID, currDepth), tu.blocks[compID], currDepth,
+                                     prevCbf);
+        }
       }
     }
-    }
 
     for (uint32_t ch = 0; ch < numValidComp; ch++)
     {
       const ComponentID compID = ComponentID(ch);
       if (compID == COMPONENT_Y && !luma)
+      {
         continue;
+      }
       if (compID != COMPONENT_Y && !chroma)
+      {
         continue;
+      }
       if (tu.blocks[compID].valid())
       {
         if( compID == COMPONENT_Cr )
@@ -7142,7 +10285,9 @@ void InterSearch::xEstimateInterResidualQT(CodingStructure &cs, Partitioner &par
     }
     else
 #endif
-    csFull->cost      = m_pcRdCost->calcRdCost(csFull->fracBits, csFull->dist);
+    {
+      csFull->cost = m_pcRdCost->calcRdCost(csFull->fracBits, csFull->dist);
+    }
   } // check full
 
   // code sub-blocks
@@ -7162,14 +10307,13 @@ void InterSearch::xEstimateInterResidualQT(CodingStructure &cs, Partitioner &par
       partitioner.splitCurrArea( PartSplit( cu.getSbtTuSplit() ), cs );
     }
     else
+    {
       THROW( "Implicit TU split not available!" );
+    }
 
     do
     {
-      xEstimateInterResidualQT(*csSplit, partitioner, bCheckFull ? nullptr : puiZeroDist
-        , luma, chroma
-        , orgResi
-      );
+      xEstimateInterResidualQT(*csSplit, partitioner, bCheckFull ? nullptr : puiZeroDist, luma, chroma, orgResi);
 
       csSplit->cost = m_pcRdCost->calcRdCost( csSplit->fracBits, csSplit->dist );
     } while( partitioner.nextPart( *csSplit ) );
@@ -7189,26 +10333,23 @@ void InterSearch::xEstimateInterResidualQT(CodingStructure &cs, Partitioner &par
         }
       }
 
+      for (auto &currTU: csSplit->traverseTUs(currArea, partitioner.chType))
       {
-
-        for( auto &currTU : csSplit->traverseTUs( currArea, partitioner.chType ) )
-        {
-          TU::setCbfAtDepth   ( currTU, COMPONENT_Y,  currDepth, compCbf[ COMPONENT_Y  ] );
-          if( currArea.chromaFormat != CHROMA_400 )
-          {
-            TU::setCbfAtDepth ( currTU, COMPONENT_Cb, currDepth, compCbf[ COMPONENT_Cb ] );
-            TU::setCbfAtDepth ( currTU, COMPONENT_Cr, currDepth, compCbf[ COMPONENT_Cr ] );
-          }
-        }
-
-        anyCbfSet    = compCbf[ COMPONENT_Y  ];
+        TU::setCbfAtDepth(currTU, COMPONENT_Y, currDepth, compCbf[COMPONENT_Y]);
         if( currArea.chromaFormat != CHROMA_400 )
         {
-          anyCbfSet |= compCbf[ COMPONENT_Cb ];
-          anyCbfSet |= compCbf[ COMPONENT_Cr ];
+          TU::setCbfAtDepth(currTU, COMPONENT_Cb, currDepth, compCbf[COMPONENT_Cb]);
+          TU::setCbfAtDepth(currTU, COMPONENT_Cr, currDepth, compCbf[COMPONENT_Cr]);
         }
       }
 
+      anyCbfSet = compCbf[COMPONENT_Y];
+      if (currArea.chromaFormat != CHROMA_400)
+      {
+        anyCbfSet |= compCbf[COMPONENT_Cb];
+        anyCbfSet |= compCbf[COMPONENT_Cr];
+      }
+
       m_CABACEstimator->getCtx() = ctxStart;
       m_CABACEstimator->resetBits();
 
@@ -7288,9 +10429,13 @@ void InterSearch::encodeResAndCalcRdInterCU(CodingStructure &cs, Partitioner &pa
     {
       const ComponentID compID = ComponentID(comp);
       if (compID == COMPONENT_Y && !luma)
+      {
         continue;
+      }
       if (compID != COMPONENT_Y && !chroma)
+      {
         continue;
+      }
       CPelBuf reco = cs.getRecoBuf (compID);
       CPelBuf org  = cs.getOrgBuf  (compID);
 #if WCG_EXT
@@ -7308,11 +10453,16 @@ void InterSearch::encodeResAndCalcRdInterCU(CodingStructure &cs, Partitioner &pa
           distortion += m_pcRdCost->getDistPart(org, tmpRecLuma, sps.getBitDepth(toChannelType(compID)), compID, DF_SSE_WTD, &orgLuma);
         }
         else
-        distortion += m_pcRdCost->getDistPart( org, reco, sps.getBitDepth( toChannelType( compID ) ), compID, DF_SSE_WTD, &orgLuma );
+        {
+          distortion +=
+            m_pcRdCost->getDistPart(org, reco, sps.getBitDepth(toChannelType(compID)), compID, DF_SSE_WTD, &orgLuma);
+        }
       }
       else
 #endif
-      distortion += m_pcRdCost->getDistPart( org, reco, sps.getBitDepth( toChannelType( compID ) ), compID, DF_SSE );
+      {
+        distortion += m_pcRdCost->getDistPart(org, reco, sps.getBitDepth(toChannelType(compID)), compID, DF_SSE);
+      }
     }
 
     m_CABACEstimator->resetBits();
@@ -7341,12 +10491,16 @@ void InterSearch::encodeResAndCalcRdInterCU(CodingStructure &cs, Partitioner &pa
       tmpPred.copyFrom(cs.getPredBuf(COMPONENT_Y));
 
       if (!cu.firstPU->ciipFlag && !CU::isIBC(cu))
+      {
         tmpPred.rspSignal(m_pcReshape->getFwdLUT());
+      }
       cs.getResiBuf(COMPONENT_Y).rspSignal(m_pcReshape->getFwdLUT());
       cs.getResiBuf(COMPONENT_Y).subtract(tmpPred);
     }
     else
-    cs.getResiBuf().bufs[0].subtract(cs.getPredBuf().bufs[0]);
+    {
+      cs.getResiBuf().bufs[0].subtract(cs.getPredBuf().bufs[0]);
+    }
   }
   if (chroma && isChromaEnabled(cs.pcv->chrFormat))
   {
@@ -7447,101 +10601,104 @@ void InterSearch::encodeResAndCalcRdInterCU(CodingStructure &cs, Partitioner &pa
     cs.dist = 0;
     cs.cost = 0;
 
-  if (colorTransFlag)
-  {
-    cs.getOrgResiBuf().bufs[0].copyFrom(orgResidual.bufs[0]);
-    cs.getOrgResiBuf().bufs[1].copyFrom(orgResidual.bufs[1]);
-    cs.getOrgResiBuf().bufs[2].copyFrom(orgResidual.bufs[2]);
+    if (colorTransFlag)
+    {
+      cs.getOrgResiBuf().bufs[0].copyFrom(orgResidual.bufs[0]);
+      cs.getOrgResiBuf().bufs[1].copyFrom(orgResidual.bufs[1]);
+      cs.getOrgResiBuf().bufs[2].copyFrom(orgResidual.bufs[2]);
 
-    memset(m_pTempPel, 0, sizeof(Pel) * localUnitArea.blocks[0].area());
-    zeroDistortion = 0;
-    for (int compIdx = 0; compIdx < 3; compIdx++)
+      memset(m_pTempPel, 0, sizeof(Pel) * localUnitArea.blocks[0].area());
+      zeroDistortion = 0;
+      for (int compIdx = 0; compIdx < 3; compIdx++)
+      {
+        ComponentID   componentID = (ComponentID) compIdx;
+        const CPelBuf zeroBuf(m_pTempPel, localUnitArea.blocks[compIdx]);
+        zeroDistortion += m_pcRdCost->getDistPart(zeroBuf, orgResidual.bufs[compIdx],
+                                                  sps.getBitDepth(toChannelType(componentID)), componentID, DF_SSE);
+      }
+      xEstimateInterResidualQT(cs, partitioner, NULL, luma, chroma, &orgResidual);
+    }
+    else
     {
-      ComponentID componentID = (ComponentID)compIdx;
-      const CPelBuf zeroBuf(m_pTempPel, localUnitArea.blocks[compIdx]);
-      zeroDistortion += m_pcRdCost->getDistPart(zeroBuf, orgResidual.bufs[compIdx], sps.getBitDepth(toChannelType(componentID)), componentID, DF_SSE);
+      zeroDistortion = 0;
+      if (luma)
+      {
+        cs.getOrgResiBuf().bufs[0].copyFrom(orgResidual.bufs[0]);
+      }
+      if (chroma && isChromaEnabled(cs.pcv->chrFormat))
+      {
+        cs.getOrgResiBuf().bufs[1].copyFrom(orgResidual.bufs[1]);
+        cs.getOrgResiBuf().bufs[2].copyFrom(orgResidual.bufs[2]);
+      }
+      xEstimateInterResidualQT(cs, partitioner, &zeroDistortion, luma, chroma);
     }
-    xEstimateInterResidualQT(cs, partitioner, NULL, luma, chroma, &orgResidual);
-  }
-  else
-  {
-    zeroDistortion = 0;
-  if (luma)
-  {
-    cs.getOrgResiBuf().bufs[0].copyFrom(orgResidual.bufs[0]);
-  }
-  if (chroma && isChromaEnabled(cs.pcv->chrFormat))
-  {
-    cs.getOrgResiBuf().bufs[1].copyFrom(orgResidual.bufs[1]);
-    cs.getOrgResiBuf().bufs[2].copyFrom(orgResidual.bufs[2]);
-  }
-  xEstimateInterResidualQT(cs, partitioner, &zeroDistortion, luma, chroma);
-  }
-  TransformUnit &firstTU = *cs.getTU( partitioner.chType );
+    TransformUnit &firstTU = *cs.getTU(partitioner.chType);
 
-  cu.rootCbf = false;
-  m_CABACEstimator->resetBits();
-  m_CABACEstimator->rqt_root_cbf( cu );
-  const uint64_t  zeroFracBits = m_CABACEstimator->getEstFracBits();
-  double zeroCost;
-  {
-#if WCG_EXT
-    if( m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled() )
+    cu.rootCbf = false;
+    m_CABACEstimator->resetBits();
+    m_CABACEstimator->rqt_root_cbf(cu);
+    const uint64_t zeroFracBits = m_CABACEstimator->getEstFracBits();
+    double         zeroCost;
     {
-      zeroCost = m_pcRdCost->calcRdCost( zeroFracBits, zeroDistortion, false );
-    }
-    else
+#if WCG_EXT
+      if (m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled())
+      {
+        zeroCost = m_pcRdCost->calcRdCost(zeroFracBits, zeroDistortion, false);
+      }
+      else
 #endif
-    zeroCost = m_pcRdCost->calcRdCost( zeroFracBits, zeroDistortion );
-  }
-
-  const int  numValidTBlocks   = ::getNumberValidTBlocks( *cs.pcv );
-  for (uint32_t i = 0; i < numValidTBlocks; i++)
-  {
-    cu.rootCbf |= TU::getCbfAtDepth(firstTU, ComponentID(i), 0);
-  }
+      {
+        zeroCost = m_pcRdCost->calcRdCost(zeroFracBits, zeroDistortion);
+      }
+    }
 
-  // -------------------------------------------------------
-  // If a block full of 0's is efficient, then just use 0's.
-  // The costs at this point do not include header bits.
+    const int numValidTBlocks = ::getNumberValidTBlocks(*cs.pcv);
+    for (uint32_t i = 0; i < numValidTBlocks; i++)
+    {
+      cu.rootCbf |= TU::getCbfAtDepth(firstTU, ComponentID(i), 0);
+    }
 
-  if (zeroCost < cs.cost || !cu.rootCbf)
-  {
-    cs.cost = zeroCost;
-    cu.colorTransform = false;
-    cu.sbtInfo = 0;
-    cu.rootCbf = false;
+    // -------------------------------------------------------
+    // If a block full of 0's is efficient, then just use 0's.
+    // The costs at this point do not include header bits.
 
-    cs.clearTUs();
+    if (zeroCost < cs.cost || !cu.rootCbf)
+    {
+      cs.cost           = zeroCost;
+      cu.colorTransform = false;
+      cu.sbtInfo        = 0;
+      cu.rootCbf        = false;
 
-    // add new "empty" TU(s) spanning the whole CU
-    cs.addEmptyTUs( partitioner );
-  }
-  if (!iter)
-  {
-    rootCbfFirstColorSpace = cu.rootCbf;
-  }
-  if (cs.cost < bestCost)
-  {
-    bestIter = iter;
+      cs.clearTUs();
 
-    if (iter != (numAllowedColorSpace - 1))
+      // add new "empty" TU(s) spanning the whole CU
+      cs.addEmptyTUs(partitioner);
+    }
+    if (!iter)
+    {
+      rootCbfFirstColorSpace = cu.rootCbf;
+    }
+    if (cs.cost < bestCost)
     {
-      bestCost = cs.cost;
-      bestColorTrans = cu.colorTransform;
-      bestRootCbf = cu.rootCbf;
-      bestsbtInfo = cu.sbtInfo;
+      bestIter = iter;
 
-      saveCS.clearTUs();
-      for (const auto &ptu : cs.tus)
+      if (iter != (numAllowedColorSpace - 1))
       {
-        TransformUnit &tu = saveCS.addTU(*ptu, ptu->chType);
-        tu = *ptu;
+        bestCost       = cs.cost;
+        bestColorTrans = cu.colorTransform;
+        bestRootCbf    = cu.rootCbf;
+        bestsbtInfo    = cu.sbtInfo;
+
+        saveCS.clearTUs();
+        for (const auto &ptu: cs.tus)
+        {
+          TransformUnit &tu = saveCS.addTU(*ptu, ptu->chType);
+          tu                = *ptu;
+        }
+        saveCS.getResiBuf(curUnitArea).copyFrom(cs.getResiBuf(curUnitArea));
       }
-      saveCS.getResiBuf(curUnitArea).copyFrom(cs.getResiBuf(curUnitArea));
     }
   }
-  }
 
   if (bestIter != (numAllowedColorSpace - 1))
   {
@@ -7586,7 +10743,9 @@ void InterSearch::encodeResAndCalcRdInterCU(CodingStructure &cs, Partitioner &pa
       tmpPred.copyFrom(cs.getPredBuf(COMPONENT_Y));
 
       if (!cu.firstPU->ciipFlag && !CU::isIBC(cu))
+      {
         tmpPred.rspSignal(m_pcReshape->getFwdLUT());
+      }
 
       cs.getRecoBuf(COMPONENT_Y).reconstruct(tmpPred, cs.getResiBuf(COMPONENT_Y), cs.slice->clpRng(COMPONENT_Y));
     }
@@ -7612,9 +10771,13 @@ void InterSearch::encodeResAndCalcRdInterCU(CodingStructure &cs, Partitioner &pa
   {
     const ComponentID compID = ComponentID(comp);
     if (compID == COMPONENT_Y && !luma)
+    {
       continue;
+    }
     if (compID != COMPONENT_Y && !chroma)
+    {
       continue;
+    }
     CPelBuf reco = cs.getRecoBuf (compID);
     CPelBuf org  = cs.getOrgBuf  (compID);
 
@@ -7633,7 +10796,9 @@ void InterSearch::encodeResAndCalcRdInterCU(CodingStructure &cs, Partitioner &pa
         finalDistortion += m_pcRdCost->getDistPart(org, tmpRecLuma, sps.getBitDepth(toChannelType(compID)), compID, DF_SSE_WTD, &orgLuma);
       }
       else
+      {
         finalDistortion += m_pcRdCost->getDistPart(org, reco, sps.getBitDepth(toChannelType(compID)), compID, DF_SSE_WTD, &orgLuma);
+      }
     }
     else
 #endif
@@ -7715,11 +10880,19 @@ double InterSearch::xGetMEDistortionWeight(uint8_t bcwIdx, RefPicList eRefPicLis
     return 0.5;
   }
 }
+#if GDR_ENABLED
+bool InterSearch::xReadBufferedUniMv(PredictionUnit& pu, RefPicList eRefPicList, int32_t iRefIdx, Mv& pcMvPred, Mv& rcMv, bool& rcMvSolid, uint32_t& ruiBits, Distortion& ruiCost)
+#else
 bool InterSearch::xReadBufferedUniMv(PredictionUnit& pu, RefPicList eRefPicList, int32_t iRefIdx, Mv& pcMvPred, Mv& rcMv, uint32_t& ruiBits, Distortion& ruiCost)
+#endif
 {
   if (m_uniMotions.isReadMode((uint32_t)eRefPicList, (uint32_t)iRefIdx))
   {
+#if GDR_ENABLED
+    m_uniMotions.copyTo(rcMv, rcMvSolid, ruiCost, (uint32_t)eRefPicList, (uint32_t)iRefIdx);
+#else
     m_uniMotions.copyTo(rcMv, ruiCost, (uint32_t)eRefPicList, (uint32_t)iRefIdx);
+#endif
 
     Mv pred = pcMvPred;
     pred.changeTransPrecInternal2Amvr(pu.cu->imv);
@@ -7737,13 +10910,23 @@ bool InterSearch::xReadBufferedUniMv(PredictionUnit& pu, RefPicList eRefPicList,
   return false;
 }
 
+#if GDR_ENABLED
+bool InterSearch::xReadBufferedAffineUniMv(PredictionUnit& pu, RefPicList eRefPicList, int32_t iRefIdx, Mv acMvPred[3], Mv acMv[3], bool acMvSolid[3], uint32_t& ruiBits, Distortion& ruiCost
+  , int& mvpIdx, const AffineAMVPInfo& aamvpi
+)
+#else
 bool InterSearch::xReadBufferedAffineUniMv(PredictionUnit& pu, RefPicList eRefPicList, int32_t iRefIdx, Mv acMvPred[3], Mv acMv[3], uint32_t& ruiBits, Distortion& ruiCost
   , int& mvpIdx, const AffineAMVPInfo& aamvpi
 )
+#endif
 {
   if (m_uniMotions.isReadModeAffine((uint32_t)eRefPicList, (uint32_t)iRefIdx, pu.cu->affineType))
   {
+#if GDR_ENABLED
+    m_uniMotions.copyAffineMvTo(acMv, acMvSolid, ruiCost, (uint32_t)eRefPicList, (uint32_t)iRefIdx, pu.cu->affineType, mvpIdx);
+#else
     m_uniMotions.copyAffineMvTo(acMv, ruiCost, (uint32_t)eRefPicList, (uint32_t)iRefIdx, pu.cu->affineType, mvpIdx);
+#endif
     m_pcRdCost->setCostScale(0);
     acMvPred[0] = aamvpi.mvCandLT[mvpIdx];
     acMvPred[1] = aamvpi.mvCandRT[mvpIdx];
@@ -7765,6 +10948,7 @@ bool InterSearch::xReadBufferedAffineUniMv(PredictionUnit& pu, RefPicList eRefPi
   }
   return false;
 }
+
 void InterSearch::initWeightIdxBits()
 {
   for (int n = 0; n < BCW_NUM; ++n)
@@ -7808,20 +10992,45 @@ uint32_t InterSearch::xDetermineBestMvp( PredictionUnit& pu, Mv acMvTemp[3], int
 {
   bool mvpUpdated  = false;
   uint32_t minBits = std::numeric_limits<uint32_t>::max();
+#if GDR_ENABLED
+  const CodingStructure &cs = *pu.cs;
+  const bool isEncodeGdrClean = cs.sps->getGDREnabledFlag() && cs.pcv->isEncoder && ((cs.picHeader->getInGdrInterval() && cs.isClean(pu.Y().topRight(), CHANNEL_TYPE_LUMA)) || (cs.picHeader->getNumVerVirtualBoundaries() == 0));
+#endif
+
   for ( int i = 0; i < aamvpi.numCand; i++ )
   {
     Mv mvPred[3] = { aamvpi.mvCandLT[i], aamvpi.mvCandRT[i], aamvpi.mvCandLB[i] };
     uint32_t candBits = m_auiMVPIdxCost[i][aamvpi.numCand];
     candBits += xCalcAffineMVBits( pu, acMvTemp, mvPred );
 
+#if GDR_ENABLED
+    bool isSolid = true;
+    if (isEncodeGdrClean)
+    {
+      isSolid = aamvpi.mvSolidLT[i] && aamvpi.mvSolidRT[i];
+      if (pu.cu->affineType == AFFINEMODEL_6PARAM)
+      {
+        isSolid = isSolid && aamvpi.mvSolidLB[i];
+      }
+    }
+
+    if ((candBits < minBits) && isSolid)
+#else
     if ( candBits < minBits )
+#endif
     {
       minBits    = candBits;
       mvpIdx     = i;
       mvpUpdated = true;
     }
   }
+
+#if GDR_ENABLED
+  mvpUpdated = true; // do not check mvp update for GDR
+#endif
+
   CHECK( !mvpUpdated, "xDetermineBestMvp() error" );
+
   return minBits;
 }
 
@@ -7833,11 +11042,22 @@ void InterSearch::symmvdCheckBestMvp(
   AMVPInfo amvpInfo[2][33],
   int32_t bcwIdx,
   Mv cMvPredSym[2],
+#if GDR_ENABLED
+  bool cMvPredSymSolid[2],
+#endif
   int32_t mvpIdxSym[2],
   Distortion& bestCost,
   bool skip
 )
 {
+#if GDR_ENABLED
+  CodingStructure &cs = *pu.cs;
+  const bool isEncodeGdrClean = cs.sps->getGDREnabledFlag() && cs.pcv->isEncoder && ((cs.picHeader->getInGdrInterval() && cs.isClean(pu.Y().topRight(), CHANNEL_TYPE_LUMA)) || (cs.picHeader->getNumVerVirtualBoundaries() == 0));
+  bool bestCostOk = true;
+  bool costOk = true;
+  bool allOk;
+#endif
+
   RefPicList tarRefList = (RefPicList)(1 - curRefList);
   int32_t refIdxCur = pu.cu->slice->getSymRefIdx(curRefList);
   int32_t refIdxTar = pu.cu->slice->getSymRefIdx(tarRefList);
@@ -7880,7 +11100,9 @@ void InterSearch::symmvdCheckBestMvp(
     for (int j = 0; j < amvpTar.numCand; j++)
     {
       if (skipMvpIdx[curRefList] == i && skipMvpIdx[tarRefList] == j)
+      {
         continue;
+      }
 
       cTarMvField.setMvField(curMv.getSymmvdMv(amvpCur.mvCand[i], amvpTar.mvCand[j]), refIdxTar);
 
@@ -7913,11 +11135,48 @@ void InterSearch::symmvdCheckBestMvp(
       bits += m_auiMVPIdxCost[i][AMVP_MAX_NUM_CANDS];
       bits += m_auiMVPIdxCost[j][AMVP_MAX_NUM_CANDS];
       cost += m_pcRdCost->getCost(bits);
+#if GDR_ENABLED
+      if (isEncodeGdrClean)
+      {
+        bool curSolid = amvpCur.mvSolid[i];
+        bool tarSolid = amvpTar.mvSolid[j];
+        costOk = curSolid && tarSolid;
+      }
+#endif
+
+
+#if GDR_ENABLED
+      allOk = (cost < bestCost);
+      if (isEncodeGdrClean)
+      {
+        if (costOk)
+        {
+          allOk = (bestCostOk) ? (cost < bestCost) : true;
+        }
+        else
+        {
+          allOk = false;
+        }
+      }
+#endif
+
+#if GDR_ENABLED
+      if (allOk)
+#else
       if (cost < bestCost)
+#endif
       {
         bestCost = cost;
         cMvPredSym[curRefList] = amvpCur.mvCand[i];
         cMvPredSym[tarRefList] = amvpTar.mvCand[j];
+#if GDR_ENABLED
+        if (isEncodeGdrClean)
+        {
+          bestCostOk = costOk;
+          cMvPredSymSolid[curRefList] = amvpCur.mvSolid[i];
+          cMvPredSymSolid[tarRefList] = amvpTar.mvSolid[j];
+        }
+#endif
         mvpIdxSym[curRefList] = i;
         mvpIdxSym[tarRefList] = j;
       }
@@ -7972,7 +11231,9 @@ bool InterSearch::searchBv(PredictionUnit& pu, int xPos, int yPos, int width, in
 
   // Don't search the above CTU row
   if (refTopY >> ctuSizeLog2 < yPos >> ctuSizeLog2)
+  {
     return false;
+  }
 
   // Don't search the below CTU row
   if (refBottomY >> ctuSizeLog2 > yPos >> ctuSizeLog2)
@@ -8017,22 +11278,32 @@ bool InterSearch::searchBv(PredictionUnit& pu, int xPos, int yPos, int width, in
       int offset64y = (refPosCol.y >> (ctuSizeLog2 - 1)) << (ctuSizeLog2 - 1);
       const Position refPosCol64x64 = {offset64x, offset64y};
       if (pu.cs->isDecomp(refPosCol64x64, toChannelType(COMPONENT_Y)))
+      {
         return false;
+      }
       if (refPosCol64x64 == pu.Y().topLeft())
+      {
         return false;
+      }
     }
   }
   else
+  {
     return false;
+  }
 
   // in the same CTU, or valid area from left CTU. Check if the reference block is already coded
   const Position refPosLT = pu.Y().topLeft().offset(xBv, yBv);
   const Position refPosBR = pu.Y().bottomRight().offset(xBv, yBv);
   const ChannelType      chType = toChannelType(COMPONENT_Y);
   if (!pu.cs->isDecomp(refPosBR, chType))
+  {
     return false;
+  }
   if (!pu.cs->isDecomp(refPosLT, chType))
+  {
     return false;
+  }
   return true;
 }
 
diff --git a/source/Lib/EncoderLib/InterSearch.h b/source/Lib/EncoderLib/InterSearch.h
index 5e9df41e9..129642026 100644
--- a/source/Lib/EncoderLib/InterSearch.h
+++ b/source/Lib/EncoderLib/InterSearch.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -77,6 +77,12 @@ struct AffineMVInfo
   int x, y, w, h;
 };
 
+#if GDR_ENABLED 
+struct AffineMVInfoSolid
+{
+  bool  affMVsSolid[2][33][3];
+};
+#endif
 struct BlkUniMvInfo
 {
   Mv uniMvs[2][33];
@@ -93,6 +99,11 @@ typedef struct
   Distortion affineCost[3];
   bool affine4ParaAvail;
   bool affine6ParaAvail;
+
+#if GDR_ENABLED
+  bool acMvAffine4ParaSolid[2][3];
+  bool acMvAffine6ParaSolid[2][3];
+#endif
 } EncAffineMotion;
 
 /// encoder search class
@@ -118,6 +129,9 @@ private:
   bool            m_affineModeSelected;
   std::unordered_map< Position, std::unordered_map< Size, BlkRecord> > m_ctuRecord;
   AffineMVInfo       *m_affMVList;
+#if GDR_ENABLED  
+  AffineMVInfoSolid  *m_affMVListSolid;
+#endif
   int             m_affMVListIdx;
   int             m_affMVListSize;
   int             m_affMVListMaxSize;
@@ -126,6 +140,9 @@ private:
   int             m_uniMvListSize;
   int             m_uniMvListMaxSize;
   Distortion      m_hevcCost;
+#if GDR_ENABLED  
+  bool            m_hevcCostOk;
+#endif
   EncAffineMotion m_affineMotion;
   PatentBvCand    m_defaultCachedBvs;
 protected:
@@ -206,38 +223,65 @@ public:
 
   void setTempBuffers               (CodingStructure ****pSlitCS, CodingStructure ****pFullCS, CodingStructure **pSaveCS );
   void resetCtuRecord               ()             { m_ctuRecord.clear(); }
-#if ENABLE_SPLIT_PARALLELISM
-  void copyState                    ( const InterSearch& other );
-#endif
   void setAffineModeSelected        ( bool flag) { m_affineModeSelected = flag; }
   void resetAffineMVList() { m_affMVListIdx = 0; m_affMVListSize = 0; }
+#if GDR_ENABLED
+  void savePrevAffMVInfo(int idx, AffineMVInfo &tmpMVInfo, AffineMVInfoSolid &tmpMVInfoSolid, bool& isSaved)
+#else
   void savePrevAffMVInfo(int idx, AffineMVInfo &tmpMVInfo, bool& isSaved)
+#endif
   {
     if (m_affMVListSize > idx)
     {
       tmpMVInfo = m_affMVList[(m_affMVListIdx - 1 - idx + m_affMVListMaxSize) % m_affMVListMaxSize];
+#if GDR_ENABLED
+      tmpMVInfoSolid = m_affMVListSolid[(m_affMVListIdx - 1 - idx + m_affMVListMaxSize) % m_affMVListMaxSize];
+#endif
       isSaved = true;
     }
     else
       isSaved = false;
   }
+#if GDR_ENABLED
+  void addAffMVInfo(AffineMVInfo &tmpMVInfo, AffineMVInfoSolid &tmpMVInfoSolid)
+#else
   void addAffMVInfo(AffineMVInfo &tmpMVInfo)
+#endif
   {
     int j = 0;
     AffineMVInfo *prevInfo = nullptr;
+#if GDR_ENABLED
+    AffineMVInfoSolid *prevInfoSolid = nullptr;
+#endif
     for (; j < m_affMVListSize; j++)
     {
       prevInfo = m_affMVList + ((m_affMVListIdx - j - 1 + m_affMVListMaxSize) % (m_affMVListMaxSize));
+#if GDR_ENABLED
+      prevInfoSolid = m_affMVListSolid + ((m_affMVListIdx - j - 1 + m_affMVListMaxSize) % (m_affMVListMaxSize));
+#endif
       if ((tmpMVInfo.x == prevInfo->x) && (tmpMVInfo.y == prevInfo->y) && (tmpMVInfo.w == prevInfo->w) && (tmpMVInfo.h == prevInfo->h))
       {
         break;
       }
     }
+#if GDR_ENABLED
     if (j < m_affMVListSize)
+    {
       *prevInfo = tmpMVInfo;
+      *prevInfoSolid = tmpMVInfoSolid;
+    }
+#else
+    if (j < m_affMVListSize)
+    {
+      *prevInfo = tmpMVInfo;
+    }
+#endif
     else
     {
       m_affMVList[m_affMVListIdx] = tmpMVInfo;
+#if GDR_ENABLED
+      m_affMVListSolid[m_affMVListIdx] = tmpMVInfoSolid;
+#endif
       m_affMVListIdx = (m_affMVListIdx + 1) % m_affMVListMaxSize;
       m_affMVListSize = std::min(m_affMVListSize + 1, m_affMVListMaxSize);
     }
@@ -315,13 +359,21 @@ public:
     }
   }
   void resetSavedAffineMotion();
+#if GDR_ENABLED
+  void storeAffineMotion(Mv acAffineMv[2][3], bool acAffineMvSolid[2][3], int16_t affineRefIdx[2], EAffineModel affineType, int bcwIdx);
+#else
   void storeAffineMotion( Mv acAffineMv[2][3], int16_t affineRefIdx[2], EAffineModel affineType, int bcwIdx );
+#endif
   bool searchBv(PredictionUnit& pu, int xPos, int yPos, int width, int height, int picWidth, int picHeight, int xBv, int yBv, int ctuSize);
   void setClipMvInSubPic(bool flag) { m_clipMvInSubPic = flag; }
 protected:
 
   /// sub-function for motion vector refinement used in fractional-pel accuracy
+#if GDR_ENABLED
+  Distortion  xPatternRefinement(const PredictionUnit& pu, RefPicList eRefPicList, int iRefIdx, const CPelBuf* pcPatternKey, Mv baseRefMv, int iFrac, Mv& rcMvFrac, bool bAllowUseOfHadamard, bool& rbCleanCandExist);
+#else
   Distortion  xPatternRefinement    ( const CPelBuf* pcPatternKey, Mv baseRefMv, int iFrac, Mv& rcMvFrac, bool bAllowUseOfHadamard );
+#endif
 
    typedef struct
    {
@@ -403,6 +455,20 @@ protected:
                                     Distortion*           puiDistBiP = NULL
                                   );
 
+ #if GDR_ENABLED
+  void xCheckBestMVP(
+    PredictionUnit &pu,
+    RefPicList  eRefPicList,
+    Mv          cMv,
+    Mv&         rcMvPred,
+    int&        riMVPIdx,
+    AMVPInfo&   amvpInfo,
+    uint32_t&   ruiBits,
+    Distortion& ruiCost
+    ,
+    const uint8_t  imv
+  );
+#else
   void xCheckBestMVP              ( RefPicList  eRefPicList,
                                     Mv          cMv,
                                     Mv&         rcMvPred,
@@ -413,6 +479,7 @@ protected:
                                     ,
                                     const uint8_t  imv
                                   );
+#endif
 
   Distortion xGetTemplateCost     ( const PredictionUnit& pu,
                                     PelUnitBuf&           origBuf,
@@ -435,6 +502,22 @@ protected:
   // motion estimation
   // -------------------------------------------------------------------------------------------------------------------
 
+#if GDR_ENABLED
+  void xMotionEstimation          ( PredictionUnit&       pu,
+                                    PelUnitBuf&           origBuf,
+                                    RefPicList            eRefPicList,
+                                    Mv&                   rcMvPred,                                    
+                                    int                   iRefIdxPred,
+                                    Mv&                   rcMv,
+                                    bool&                 rcMvSolid,
+                                    int&                  riMVPIdx,
+                                    uint32_t&             ruiBits,
+                                    Distortion&           ruiCost,
+                                    const AMVPInfo&       amvpInfo,
+                                    bool&                 rbCleanCandExist,
+                                    bool                  bBi = false
+                                  );
+#else
   void xMotionEstimation          ( PredictionUnit&       pu,
                                     PelUnitBuf&           origBuf,
                                     RefPicList            eRefPicList,
@@ -447,7 +530,7 @@ protected:
                                     const AMVPInfo&       amvpInfo,
                                     bool                  bBi = false
                                   );
-
+#endif
   void xTZSearch                  ( const PredictionUnit& pu,
                                     RefPicList            eRefPicList,
                                     int                   iRefIdxPred,
@@ -473,6 +556,10 @@ protected:
                                     const int             iSrchRng,
                                     SearchRange&          sr
                                   , IntTZSearchStruct &  cStruct
+#if GDR_ENABLED
+                                  , RefPicList eRefPicList
+                                  , int iRefIdx
+#endif
                                   );
 
   void xPatternSearchFast         ( const PredictionUnit& pu,
@@ -498,6 +585,11 @@ protected:
                                     Distortion&         ruiCost,
                                     const AMVPInfo&     amvpInfo,
                                     double              fWeight
+#if GDR_ENABLED
+                                    ,RefPicList         eRefPicList
+                                    ,int                iRefIdxPred
+                                    , bool&             rbCleanCandExist
+#endif
                                   );
 
   void xPatternSearchFracDIF      ( const PredictionUnit& pu,
@@ -508,6 +600,9 @@ protected:
                                     Mv&                   rcMvHalf,
                                     Mv&                   rcMvQter,
                                     Distortion&           ruiCost
+#if GDR_ENABLED
+                                    ,bool&                rbCleanCandExist
+#endif
                                   );
 
   void xPredAffineInterSearch     ( PredictionUnit&       pu,
@@ -516,13 +611,35 @@ protected:
                                     uint32_t&                 lastMode,
                                     Distortion&           affineCost,
                                     Mv                    hevcMv[2][33]
+#if GDR_ENABLED
+                                  , bool                  hevcMvSolid[2][33]
+#endif
                                   , Mv                    mvAffine4Para[2][33][3]
+#if GDR_ENABLED
+                                  , bool                  mvAffine4ParaSolid[2][33][3]
+#endif
                                   , int                   refIdx4Para[2]
                                   , uint8_t               bcwIdx = BCW_DEFAULT
                                   , bool                  enforceBcwPred = false
                                   , uint32_t              bcwIdxBits = 0
                                   );
 
+#if GDR_ENABLED
+  void xAffineMotionEstimation    ( PredictionUnit& pu,
+                                    PelUnitBuf&     origBuf,
+                                    RefPicList      eRefPicList,
+                                    Mv              acMvPred[3],                                    
+                                    int             iRefIdxPred,
+                                    Mv              acMv[3],
+                                    bool            acMvSolid[3],
+                                    uint32_t&       ruiBits,
+                                    Distortion&     ruiCost,
+                                    int&            mvpIdx,
+                                    const AffineAMVPInfo& aamvpi,
+                                    bool&           rbCleanCandExist,
+                                    bool            bBi = false
+  );
+#else
   void xAffineMotionEstimation    ( PredictionUnit& pu,
                                     PelUnitBuf&     origBuf,
                                     RefPicList      eRefPicList,
@@ -535,6 +652,7 @@ protected:
                                     const AffineAMVPInfo& aamvpi,
                                     bool            bBi = false
                                   );
+#endif
 
   void xEstimateAffineAMVP        ( PredictionUnit&  pu,
                                     AffineAMVPInfo&  affineAMVPInfo,
@@ -545,23 +663,50 @@ protected:
                                     Distortion*      puiDistBiP
                                   );
 
+#if GDR_ENABLED
+  Distortion xGetAffineTemplateCost(PredictionUnit& pu, PelUnitBuf& origBuf, PelUnitBuf& predBuf, Mv acMvCand[3], int iMVPIdx, int iMVPNum, RefPicList eRefPicList, int iRefIdx, bool& rbOk);
+#else
   Distortion xGetAffineTemplateCost( PredictionUnit& pu, PelUnitBuf& origBuf, PelUnitBuf& predBuf, Mv acMvCand[3], int iMVPIdx, int iMVPNum, RefPicList eRefPicList, int iRefIdx );
+#endif
 
   void xCopyAffineAMVPInfo        ( AffineAMVPInfo& src, AffineAMVPInfo& dst );
   void xCheckBestAffineMVP        ( PredictionUnit &pu, AffineAMVPInfo &affineAMVPInfo, RefPicList eRefPicList, Mv acMv[3], Mv acMvPred[3], int& riMVPIdx, uint32_t& ruiBits, Distortion& ruiCost );
 
   Distortion xGetSymmetricCost( PredictionUnit& pu, PelUnitBuf& origBuf, RefPicList eCurRefPicList, const MvField& cCurMvField, MvField& cTarMvField , int bcwIdx );
 
+#if GDR_ENABLED
+  Distortion xSymmeticRefineMvSearch( 
+    PredictionUnit& pu, PelUnitBuf& origBuf, 
+    Mv& rcMvCurPred, Mv& rcMvTarPred,
+    RefPicList eRefPicList, MvField& rCurMvField, MvField& rTarMvField, 
+    Distortion uiMinCost, int searchPattern, int nSearchStepShift, uint32_t uiMaxSearchRounds , int bcwIdx, bool& rbOk );
+#else
   Distortion xSymmeticRefineMvSearch( PredictionUnit& pu, PelUnitBuf& origBuf, Mv& rcMvCurPred, Mv& rcMvTarPred
     , RefPicList eRefPicList, MvField& rCurMvField, MvField& rTarMvField, Distortion uiMinCost, int searchPattern, int nSearchStepShift, uint32_t uiMaxSearchRounds , int bcwIdx );
+#endif
 
+#if GDR_ENABLED
+  bool xSymmetricMotionEstimation( PredictionUnit& pu, PelUnitBuf& origBuf, Mv& rcMvCurPred, Mv& rcMvTarPred,
+  RefPicList eRefPicList, MvField& rCurMvField, MvField& rTarMvField, Distortion& ruiCost, int bcwIdx, bool& ruiCostOk );
+#else
   void xSymmetricMotionEstimation( PredictionUnit& pu, PelUnitBuf& origBuf, Mv& rcMvCurPred, Mv& rcMvTarPred, RefPicList eRefPicList, MvField& rCurMvField, MvField& rTarMvField, Distortion& ruiCost, int bcwIdx );
+#endif
 
+#if GDR_ENABLED
+  bool xReadBufferedAffineUniMv(PredictionUnit& pu, RefPicList eRefPicList, int32_t iRefIdx, Mv acMvPred[3], Mv acMv[3], bool acMvSolid[3], uint32_t& ruiBits, Distortion& ruiCost
+    , int& mvpIdx, const AffineAMVPInfo& aamvpi
+  );
+#else
   bool xReadBufferedAffineUniMv   ( PredictionUnit& pu, RefPicList eRefPicList, int32_t iRefIdx, Mv acMvPred[3], Mv acMv[3], uint32_t& ruiBits, Distortion& ruiCost
                                     , int& mvpIdx, const AffineAMVPInfo& aamvpi
   );
+#endif
   double xGetMEDistortionWeight   ( uint8_t bcwIdx, RefPicList eRefPicList);
+#if GDR_ENABLED
+  bool xReadBufferedUniMv         (PredictionUnit& pu, RefPicList eRefPicList, int32_t iRefIdx, Mv& pcMvPred, Mv& rcMv, bool& rcMvSolid, uint32_t& ruiBits, Distortion& ruiCost);
+#else
   bool xReadBufferedUniMv         ( PredictionUnit& pu, RefPicList eRefPicList, int32_t iRefIdx, Mv& pcMvPred, Mv& rcMv, uint32_t& ruiBits, Distortion& ruiCost);
+#endif
 
   void xClipMv                    ( Mv& rcMv, const struct Position& pos, const struct Size& size, const class SPS& sps, const class PPS& pps );
 
@@ -577,6 +722,9 @@ public:
     AMVPInfo amvpInfo[2][33],
     int32_t bcwIdx,
     Mv cMvPredSym[2],
+#if GDR_ENABLED
+    bool cMvPredSymSolid[2],
+#endif
     int32_t mvpIdxSym[2],
     Distortion& bestCost,
     bool skip = false
diff --git a/source/Lib/EncoderLib/IntraSearch.cpp b/source/Lib/EncoderLib/IntraSearch.cpp
index 063ef8b3a..0bd6d5ee8 100644
--- a/source/Lib/EncoderLib/IntraSearch.cpp
+++ b/source/Lib/EncoderLib/IntraSearch.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -68,8 +68,6 @@ IntraSearch::IntraSearch()
   {
     m_pSharedPredTransformSkip[ch] = nullptr;
   }
-  m_truncBinBits = nullptr;
-  m_escapeNumBins = nullptr;
   m_minErrorIndexMap = nullptr;
   for (unsigned i = 0; i < (MAXPLTSIZE + 1); i++)
   {
@@ -163,21 +161,6 @@ void IntraSearch::destroy()
   m_tmpStorageLCU.destroy();
   m_colorTransResiBuf.destroy();
   m_isInitialized = false;
-  if (m_truncBinBits != nullptr)
-  {
-    for (unsigned i = 0; i < m_symbolSize; i++)
-    {
-      delete[] m_truncBinBits[i];
-      m_truncBinBits[i] = nullptr;
-    }
-    delete[] m_truncBinBits;
-    m_truncBinBits = nullptr;
-  }
-  if (m_escapeNumBins != nullptr)
-  {
-    delete[] m_escapeNumBins;
-    m_escapeNumBins = nullptr;
-  }
   if (m_indexError[0] != nullptr)
   {
     for (unsigned i = 0; i < (MAXPLTSIZE + 1); i++)
@@ -310,20 +293,6 @@ void IntraSearch::init( EncCfg*        pcEncCfg,
   m_isInitialized = true;
   if (pcEncCfg->getPLTMode())
   {
-    m_symbolSize = (1 << bitDepthY); // pixel values are within [0, SymbolSize-1] with size SymbolSize
-    if (m_truncBinBits == nullptr)
-    {
-      m_truncBinBits = new uint16_t*[m_symbolSize];
-      for (unsigned i = 0; i < m_symbolSize; i++)
-      {
-        m_truncBinBits[i] = new uint16_t[m_symbolSize + 1];
-      }
-    }
-    if (m_escapeNumBins == nullptr)
-    {
-      m_escapeNumBins = new uint16_t[m_symbolSize];
-    }
-    initTBCTable(bitDepthY);
     if (m_indexError[0] == nullptr)
     {
       for (unsigned i = 0; i < (MAXPLTSIZE + 1); i++)
@@ -367,12 +336,197 @@ double IntraSearch::findInterCUCost( CodingUnit &cu )
   return COST_UNKNOWN;
 }
 
+#if GDR_ENABLED
+int IntraSearch::getNumTopRecons(PredictionUnit &pu, int luma_dirMode, bool isChroma)
+{
+  int w = isChroma ? pu.Cb().width  : pu.Y().width;
+  int h = isChroma ? pu.Cb().height : pu.Y().height;
+
+  int numOfTopRecons = w;
+
+  static const int angTable[32] = { 0,    1,    2,    3,    4,    6,     8,   10,   12,   14,   16,   18,   20,   23,   26,   29,   32,   35,   39,  45,  51,  57,  64,  73,  86, 102, 128, 171, 256, 341, 512, 1024 };
+  static const int invAngTable[32] = {
+    0,   16384, 8192, 5461, 4096, 2731, 2048, 1638, 1365, 1170, 1024, 910, 819, 712, 630, 565,
+    512, 468,   420,  364,  321,  287,  256,  224,  191,  161,  128,  96,  64,  48,  32,  16
+  };   // (512 * 32) / Angle
+
+  const int refIdx             = pu.multiRefIdx;
+  const int predModeIntra      = getModifiedWideAngle(w, h, luma_dirMode);
+  const int isModeVer          = predModeIntra >= DIA_IDX;
+  const int intraPredAngleMode = (isModeVer) ? predModeIntra - VER_IDX : -(predModeIntra - HOR_IDX);
+
+  const int absAngMode         = abs(intraPredAngleMode);
+  const int signAng            = intraPredAngleMode < 0 ? -1 : 1;
+  const int absAng             = (luma_dirMode > DC_IDX && luma_dirMode < NUM_LUMA_MODE) ? angTable[absAngMode] : 0;
+
+  const int invAngle           = invAngTable[absAngMode];
+  const int intraPredAngle     = signAng * absAng;
+
+  const int sideSize = isModeVer ? h : w;
+  const int maxScale = 2;
+
+  const int angularScale = std::min(maxScale, floorLog2(sideSize) - (floorLog2(3 * invAngle - 2) - 8));
+
+  bool applyPDPC;
+
+
+  // 1.0 derive PDPC
+  applyPDPC  = (refIdx == 0) ? true : false;
+  if (luma_dirMode > DC_IDX && luma_dirMode < NUM_LUMA_MODE)
+  {
+    if (intraPredAngleMode < 0)
+    {
+      applyPDPC &= false;
+    }
+    else if (intraPredAngleMode > 0)
+    {
+      applyPDPC &= (angularScale >= 0);
+    }
+  }
+
+  // 2.0 calculate number of recons
+  switch (luma_dirMode)
+  {
+  case PLANAR_IDX:
+    numOfTopRecons = applyPDPC ? (w + 1) : (w + 1);
+    break;
+
+  case DC_IDX:
+    numOfTopRecons = applyPDPC ? (w) : (w);
+    break;
+
+  case HOR_IDX:
+    numOfTopRecons = applyPDPC ? (w) : (w);
+    break;
+
+  case VER_IDX:
+    numOfTopRecons = applyPDPC ? (w) : (w);
+    break;
+
+  default:
+    // 2..66
+    // note: There should be a way to reduce the number of top recons, in case of non PDPC
+    applyPDPC |= isChroma;
+
+    if (predModeIntra >= DIA_IDX)
+    {
+      if (intraPredAngle < 0)
+      {
+        numOfTopRecons = (applyPDPC) ? (w + w) : (w + 1);
+      }
+      else
+      {
+        numOfTopRecons = (applyPDPC) ? (w + w) : (w + w);
+      }
+    }
+    else
+    {
+      if (intraPredAngle < 0)
+      {
+        numOfTopRecons = (applyPDPC) ? (w + w) : (w);
+      }
+      else
+      {
+        numOfTopRecons = (applyPDPC) ? (w + w) : (w);
+      }
+    }
+    break;
+  }
+
+  return numOfTopRecons;
+}
+
+bool IntraSearch::isValidIntraPredLuma(PredictionUnit &pu, int luma_dirMode)
+{
+  bool isValid  = true;
+  PicHeader *ph = pu.cs->picHeader;
+
+  if (ph->getInGdrInterval())
+  {
+    int x = pu.Y().x;
+
+    // count num of recons on the top
+    int virX             = ph->getVirtualBoundariesPosX(0);
+    int numOfTopRecons = getNumTopRecons(pu, luma_dirMode, false);
+
+    // check if recon is out of boundary
+    if (x < virX && virX < (x + numOfTopRecons))
+    {
+      isValid = false;
+    }
+  }
+
+  return isValid;
+}
+
+bool IntraSearch::isValidIntraPredChroma(PredictionUnit &pu, int luma_dirMode, int chroma_dirMode)
+{
+  bool isValid = true;
+  CodingStructure *cs = pu.cs;
+  PicHeader       *ph = cs->picHeader;
+
+  if (ph->getInGdrInterval())
+  {
+    // note: chroma cordinate
+    int cbX = pu.Cb().x;
+    //int cbY = pu.Cb().y;
+    int cbW = pu.Cb().width;
+    int cbH = pu.Cb().height;
+
+    int chromaScaleX = getComponentScaleX(COMPONENT_Cb, cs->area.chromaFormat);
+    int chromaScaleY = getComponentScaleY(COMPONENT_Cb, cs->area.chromaFormat);
+
+    int lumaX = cbX << chromaScaleX;
+    // int lumaY = cbY << chromaScaleY;
+    int lumaW = cbW << chromaScaleX;
+    int lumaH = cbH << chromaScaleY;
+
+    int numOfTopRecons = lumaW;
+    int virX           = ph->getVirtualBoundariesPosX(0);
+
+    // count num of recons on the top
+    switch (chroma_dirMode)
+    {
+
+    case LM_CHROMA_IDX :
+      numOfTopRecons = lumaW;
+      break;
+
+    case MDLM_L_IDX :
+      numOfTopRecons = lumaW;
+      break;
+
+    // note: could reduce the actual #of
+    case MDLM_T_IDX:
+      numOfTopRecons = (lumaW + lumaH);
+      break;
+
+    case DM_CHROMA_IDX :
+      numOfTopRecons = getNumTopRecons(pu, luma_dirMode, true) << chromaScaleX;
+      break;
+
+    default :
+      numOfTopRecons = getNumTopRecons(pu, chroma_dirMode, true) << chromaScaleX;
+      break;
+    }
+
+    // check if recon is out of boundary
+    if (lumaX < virX && virX < (lumaX + numOfTopRecons))
+    {
+      isValid = false;
+    }
+  }
+
+  return isValid;
+}
+#endif
+
 bool IntraSearch::estIntraPredLumaQT(CodingUnit &cu, Partitioner &partitioner, const double bestCostSoFar, bool mtsCheckRangeFlag, int mtsFirstCheckId, int mtsLastCheckId, bool moreProbMTSIdxFirst, CodingStructure* bestCS)
 {
   CodingStructure       &cs            = *cu.cs;
   const SPS             &sps           = *cs.sps;
-  const uint32_t             uiWidthBit    = floorLog2(partitioner.currArea().lwidth() );
-  const uint32_t             uiHeightBit   =                   floorLog2(partitioner.currArea().lheight());
+  const uint32_t         logWidth      = floorLog2(partitioner.currArea().lwidth());
+  const uint32_t         logHeight     = floorLog2(partitioner.currArea().lheight());
 
   // Lambda calculation at equivalent Qp of 4 is recommended because at that Qp, the quantization divisor is 1.
   const double sqrtLambdaForFirstPass = m_pcRdCost->getMotionLambda( ) * FRAC_BITS_SCALE;
@@ -435,7 +589,7 @@ bool IntraSearch::estIntraPredLumaQT(CodingUnit &cu, Partitioner &partitioner, c
     //reset the variables used for the tests
     m_regIntraRDListWithCosts.clear();
     int numTotalPartsHor = (int)height >> floorLog2(CU::getISPSplitDim(width, height, TU_1D_HORZ_SPLIT));
-    int numTotalPartsVer = (int)width  >> floorLog2(CU::getISPSplitDim(width, height, TU_1D_VERT_SPLIT)); 
+    int numTotalPartsVer = (int)width  >> floorLog2(CU::getISPSplitDim(width, height, TU_1D_VERT_SPLIT));
     m_ispTestedModes[0].init( numTotalPartsHor, numTotalPartsVer );
     //the total number of subpartitions is modified to take into account the cases where LFNST cannot be combined with ISP due to size restrictions
     numTotalPartsHor = sps.getUseLFNST() && CU::canUseLfnstWithISP(cu.Y(), HOR_INTRA_SUBPARTITIONS) ? numTotalPartsHor : 0;
@@ -447,16 +601,19 @@ bool IntraSearch::estIntraPredLumaQT(CodingUnit &cu, Partitioner &partitioner, c
   }
 
   const bool testBDPCM = sps.getBDPCMEnabledFlag() && CU::bdpcmAllowed(cu, ComponentID(partitioner.chType)) && cu.mtsFlag == 0 && cu.lfnstIdx == 0;
-  static_vector<ModeInfo, FAST_UDI_MAX_RDMODE_NUM> uiHadModeList;
-  static_vector<double, FAST_UDI_MAX_RDMODE_NUM> CandCostList;
-  static_vector<double, FAST_UDI_MAX_RDMODE_NUM> CandHadList;
+  static_vector<ModeInfo, FAST_UDI_MAX_RDMODE_NUM> hadModeList;
+  static_vector<double, FAST_UDI_MAX_RDMODE_NUM>   candCostList;
+  static_vector<double, FAST_UDI_MAX_RDMODE_NUM>   candHadList;
 
   auto &pu = *cu.firstPU;
+#if GDR_ENABLED
+  const bool isEncodeGdrClean = cs.sps->getGDREnabledFlag() && cs.pcv->isEncoder && ((cs.picHeader->getInGdrInterval() && cs.isClean(pu.Y().topRight(), CHANNEL_TYPE_LUMA)) || (cs.picHeader->getNumVerVirtualBoundaries() == 0));
+#endif
   bool validReturn = false;
   {
-    CandHadList.clear();
-    CandCostList.clear();
-    uiHadModeList.clear();
+    candHadList.clear();
+    candCostList.clear();
+    hadModeList.clear();
 
     CHECK(pu.cu != &cu, "PU is not contained in the CU");
 
@@ -467,10 +624,9 @@ bool IntraSearch::estIntraPredLumaQT(CodingUnit &cu, Partitioner &partitioner, c
     const bool testMip = mipAllowed && !(cu.lwidth() > (8 * cu.lheight()) || cu.lheight() > (8 * cu.lwidth()));
     const bool supportedMipBlkSize = pu.lwidth() <= MIP_MAX_WIDTH && pu.lheight() <= MIP_MAX_HEIGHT;
 
-    static_vector<ModeInfo, FAST_UDI_MAX_RDMODE_NUM> uiRdModeList;
+    static_vector<ModeInfo, FAST_UDI_MAX_RDMODE_NUM> rdModeList;
 
-    int numModesForFullRD = 3;
-    numModesForFullRD = g_aucIntraModeNumFast_UseMPM_2D[uiWidthBit - MIN_CU_LOG2][uiHeightBit - MIN_CU_LOG2];
+    int numModesForFullRD = g_intraModeNumFastUseMPM2D[logWidth - MIN_CU_LOG2][logHeight - MIN_CU_LOG2];
 
 #if INTRA_FULL_SEARCH
     numModesForFullRD = numModesAvailable;
@@ -478,12 +634,12 @@ bool IntraSearch::estIntraPredLumaQT(CodingUnit &cu, Partitioner &partitioner, c
 
     if (isSecondColorSpace)
     {
-      uiRdModeList.clear();
+      rdModeList.clear();
       if (m_numSavedRdModeFirstColorSpace[m_savedRdModeIdx] > 0)
       {
         for (int i = 0; i < m_numSavedRdModeFirstColorSpace[m_savedRdModeIdx]; i++)
         {
-          uiRdModeList.push_back(m_savedRdModeFirstColorSpace[m_savedRdModeIdx][i]);
+          rdModeList.push_back(m_savedRdModeFirstColorSpace[m_savedRdModeIdx][i]);
         }
       }
       else
@@ -547,23 +703,23 @@ bool IntraSearch::estIntraPredLumaQT(CodingUnit &cu, Partitioner &partitioner, c
 
           //===== init pattern for luma prediction =====
           initIntraPatternChType(cu, pu.Y(), true);
-          bool bSatdChecked[NUM_INTRA_MODE];
-          memset(bSatdChecked, 0, sizeof(bSatdChecked));
+          bool satdChecked[NUM_INTRA_MODE];
+          std::fill_n(satdChecked, NUM_INTRA_MODE, false);
 
           if (!LFNSTLoadFlag)
           {
             for (int modeIdx = 0; modeIdx < numModesAvailable; modeIdx++)
             {
-              uint32_t   uiMode    = modeIdx;
+              uint32_t   mode      = modeIdx;
               Distortion minSadHad = 0;
 
               // Skip checking extended Angular modes in the first round of SATD
-              if (uiMode > DC_IDX && (uiMode & 1))
+              if (mode > DC_IDX && (mode & 1))
               {
                 continue;
               }
 
-              bSatdChecked[uiMode] = true;
+              satdChecked[mode] = true;
 
               pu.intraDir[0] = modeIdx;
 
@@ -580,46 +736,76 @@ bool IntraSearch::estIntraPredLumaQT(CodingUnit &cu, Partitioner &partitioner, c
               m_CABACEstimator->getCtx() = SubCtx(Ctx::IntraLumaMpmFlag, ctxStartIntraMode);
               m_CABACEstimator->getCtx() = SubCtx( Ctx::MultiRefLineIdx, ctxStartMrlIdx );
 
-              uint64_t fracModeBits = xFracModeBitsIntra(pu, uiMode, CHANNEL_TYPE_LUMA);
+              uint64_t fracModeBits = xFracModeBitsIntra(pu, mode, CHANNEL_TYPE_LUMA);
 
               double cost = (double) minSadHad + (double) fracModeBits * sqrtLambdaForFirstPass;
 
-              DTRACE(g_trace_ctx, D_INTRA_COST, "IntraHAD: %u, %llu, %f (%d)\n", minSadHad, fracModeBits, cost, uiMode);
+              DTRACE(g_trace_ctx, D_INTRA_COST, "IntraHAD: %u, %llu, %f (%d)\n", minSadHad, fracModeBits, cost, mode);
 
-              updateCandList(ModeInfo(false, false, 0, NOT_INTRA_SUBPARTITIONS, uiMode), cost, uiRdModeList,
-                             CandCostList, numModesForFullRD);
-              updateCandList(ModeInfo(false, false, 0, NOT_INTRA_SUBPARTITIONS, uiMode), double(minSadHad),
-                             uiHadModeList, CandHadList, numHadCand);
+#if GDR_ENABLED
+              if (isEncodeGdrClean)
+              {
+                if (isValidIntraPredLuma(pu, mode))
+                {
+                  updateCandList(ModeInfo(false, false, 0, NOT_INTRA_SUBPARTITIONS, mode), cost, rdModeList,
+                                 candCostList, numModesForFullRD);
+                  updateCandList(ModeInfo(false, false, 0, NOT_INTRA_SUBPARTITIONS, mode), double(minSadHad),
+                                 hadModeList, candHadList, numHadCand);
+                }
+              }
+              else
+              {
+                updateCandList(ModeInfo(false, false, 0, NOT_INTRA_SUBPARTITIONS, mode), cost, rdModeList, candCostList,
+                               numModesForFullRD);
+                updateCandList(ModeInfo(false, false, 0, NOT_INTRA_SUBPARTITIONS, mode), double(minSadHad), hadModeList,
+                               candHadList, numHadCand);
+              }
+#else
+              updateCandList(ModeInfo(false, false, 0, NOT_INTRA_SUBPARTITIONS, mode), cost, rdModeList, candCostList,
+                             numModesForFullRD);
+              updateCandList(ModeInfo(false, false, 0, NOT_INTRA_SUBPARTITIONS, mode), double(minSadHad), hadModeList,
+                             candHadList, numHadCand);
+#endif
             }
             if (!sps.getUseMIP() && LFNSTSaveFlag)
             {
               // save found best modes
-              m_uiSavedNumRdModesLFNST = numModesForFullRD;
-              m_uiSavedRdModeListLFNST = uiRdModeList;
-              m_dSavedModeCostLFNST    = CandCostList;
+              m_savedNumRdModesLFNST = numModesForFullRD;
+              m_savedRdModeListLFNST = rdModeList;
+              m_savedModeCostLFNST   = candCostList;
               // PBINTRA fast
-              m_uiSavedHadModeListLFNST = uiHadModeList;
-              m_dSavedHadListLFNST      = CandHadList;
+              m_savedHadModeListLFNST   = hadModeList;
+              m_savedHadListLFNST       = candHadList;
               LFNSTSaveFlag             = false;
             }
           }   // NSSTFlag
           if (!sps.getUseMIP() && LFNSTLoadFlag)
           {
             // restore saved modes
-            numModesForFullRD = m_uiSavedNumRdModesLFNST;
-            uiRdModeList      = m_uiSavedRdModeListLFNST;
-            CandCostList      = m_dSavedModeCostLFNST;
+            numModesForFullRD = m_savedNumRdModesLFNST;
+            rdModeList        = m_savedRdModeListLFNST;
+            candCostList      = m_savedModeCostLFNST;
             // PBINTRA fast
-            uiHadModeList = m_uiSavedHadModeListLFNST;
-            CandHadList   = m_dSavedHadListLFNST;
+            hadModeList = m_savedHadModeListLFNST;
+            candHadList = m_savedHadListLFNST;
           }   // !LFNSTFlag
 
           if (!(sps.getUseMIP() && LFNSTLoadFlag))
           {
-            static_vector<ModeInfo, FAST_UDI_MAX_RDMODE_NUM> parentCandList = uiRdModeList;
+            static_vector<ModeInfo, FAST_UDI_MAX_RDMODE_NUM> parentCandList = rdModeList;
 
             // Second round of SATD for extended Angular modes
+#if GDR_ENABLED
+            int nn = numModesForFullRD;
+            if (isEncodeGdrClean)
+            {
+              nn = std::min((int)numModesForFullRD, (int)parentCandList.size());
+            }
+
+            for (int modeIdx = 0; modeIdx < nn; modeIdx++)
+#else
             for (int modeIdx = 0; modeIdx < numModesForFullRD; modeIdx++)
+#endif
             {
               unsigned parentMode = parentCandList[modeIdx].modeId;
               if (parentMode > (DC_IDX + 1) && parentMode < (NUM_LUMA_MODE - 1))
@@ -628,7 +814,7 @@ bool IntraSearch::estIntraPredLumaQT(CodingUnit &cu, Partitioner &partitioner, c
                 {
                   unsigned mode = parentMode + subModeIdx;
 
-                  if (!bSatdChecked[mode])
+                  if (!satdChecked[mode])
                   {
                     pu.intraDir[0] = mode;
 
@@ -652,12 +838,32 @@ bool IntraSearch::estIntraPredLumaQT(CodingUnit &cu, Partitioner &partitioner, c
 
                     double cost = (double) minSadHad + (double) fracModeBits * sqrtLambdaForFirstPass;
 
-                    updateCandList(ModeInfo(false, false, 0, NOT_INTRA_SUBPARTITIONS, mode), cost, uiRdModeList,
-                                   CandCostList, numModesForFullRD);
+#if GDR_ENABLED
+                    if (isEncodeGdrClean)
+                    {
+                      if (isValidIntraPredLuma(pu, mode))
+                      {
+                        updateCandList(ModeInfo(false, false, 0, NOT_INTRA_SUBPARTITIONS, mode), cost, rdModeList,
+                                       candCostList, numModesForFullRD);
+                        updateCandList(ModeInfo(false, false, 0, NOT_INTRA_SUBPARTITIONS, mode), double(minSadHad),
+                                       hadModeList, candHadList, numHadCand);
+                      }
+                    }
+                    else
+                    {
+                      updateCandList(ModeInfo(false, false, 0, NOT_INTRA_SUBPARTITIONS, mode), cost, rdModeList,
+                                     candCostList, numModesForFullRD);
+                      updateCandList(ModeInfo(false, false, 0, NOT_INTRA_SUBPARTITIONS, mode), double(minSadHad),
+                                     hadModeList, candHadList, numHadCand);
+                    }
+#else
+                    updateCandList(ModeInfo(false, false, 0, NOT_INTRA_SUBPARTITIONS, mode), cost, rdModeList,
+                                   candCostList, numModesForFullRD);
                     updateCandList(ModeInfo(false, false, 0, NOT_INTRA_SUBPARTITIONS, mode), double(minSadHad),
-                                   uiHadModeList, CandHadList, numHadCand);
+                                   hadModeList, candHadList, numHadCand);
+#endif
 
-                    bSatdChecked[mode] = true;
+                    satdChecked[mode] = true;
                   }
                 }
               }
@@ -665,7 +871,7 @@ bool IntraSearch::estIntraPredLumaQT(CodingUnit &cu, Partitioner &partitioner, c
             if (saveDataForISP)
             {
               // we save the regular intra modes list
-              m_ispCandListHor = uiRdModeList;
+              m_ispCandListHor = rdModeList;
             }
             pu.multiRefIdx    = 1;
             const int numMPMs = NUM_MOST_PROBABLE_MODES;
@@ -703,31 +909,57 @@ bool IntraSearch::estIntraPredLumaQT(CodingUnit &cu, Partitioner &partitioner, c
                   uint64_t fracModeBits = xFracModeBitsIntra(pu, mode, CHANNEL_TYPE_LUMA);
 
                   double cost = (double) minSadHad + (double) fracModeBits * sqrtLambdaForFirstPass;
-                  updateCandList(ModeInfo(false, false, multiRefIdx, NOT_INTRA_SUBPARTITIONS, mode), cost, uiRdModeList,
-                                 CandCostList, numModesForFullRD);
+#if GDR_ENABLED
+                  if (isEncodeGdrClean)
+                  {
+                    if (isValidIntraPredLuma(pu, mode))
+                    {
+                      updateCandList(ModeInfo(false, false, multiRefIdx, NOT_INTRA_SUBPARTITIONS, mode), cost,
+                                     rdModeList, candCostList, numModesForFullRD);
+                      updateCandList(ModeInfo(false, false, multiRefIdx, NOT_INTRA_SUBPARTITIONS, mode),
+                                     double(minSadHad), hadModeList, candHadList, numHadCand);
+                    }
+                  }
+                  else
+                  {
+                    updateCandList(ModeInfo(false, false, multiRefIdx, NOT_INTRA_SUBPARTITIONS, mode), cost, rdModeList,
+                                   candCostList, numModesForFullRD);
+                    updateCandList(ModeInfo(false, false, multiRefIdx, NOT_INTRA_SUBPARTITIONS, mode),
+                                   double(minSadHad), hadModeList, candHadList, numHadCand);
+                  }
+#else
+                  updateCandList(ModeInfo(false, false, multiRefIdx, NOT_INTRA_SUBPARTITIONS, mode), cost, rdModeList,
+                                 candCostList, numModesForFullRD);
                   updateCandList(ModeInfo(false, false, multiRefIdx, NOT_INTRA_SUBPARTITIONS, mode), double(minSadHad),
-                                 uiHadModeList, CandHadList, numHadCand);
+                                 hadModeList, candHadList, numHadCand);
+#endif
                 }
               }
             }
-            CHECKD(uiRdModeList.size() != numModesForFullRD, "Error: RD mode list size");
+#if GDR_ENABLED
+            if (!isEncodeGdrClean)
+            {
+              CHECKD(rdModeList.size() != numModesForFullRD, "Error: RD mode list size");
+            }
+#else
+            CHECKD(rdModeList.size() != numModesForFullRD, "Error: RD mode list size");
+#endif
 
             if (LFNSTSaveFlag && testMip
                 && !allowLfnstWithMip(cu.firstPU->lumaSize()))   // save a different set for the next run
             {
               // save found best modes
-              m_uiSavedRdModeListLFNST = uiRdModeList;
-              m_dSavedModeCostLFNST    = CandCostList;
+              m_savedRdModeListLFNST = rdModeList;
+              m_savedModeCostLFNST   = candCostList;
               // PBINTRA fast
-              m_uiSavedHadModeListLFNST = uiHadModeList;
-              m_dSavedHadListLFNST      = CandHadList;
-              m_uiSavedNumRdModesLFNST =
-                g_aucIntraModeNumFast_UseMPM_2D[uiWidthBit - MIN_CU_LOG2][uiHeightBit - MIN_CU_LOG2];
-              m_uiSavedRdModeListLFNST.resize(m_uiSavedNumRdModesLFNST);
-              m_dSavedModeCostLFNST.resize(m_uiSavedNumRdModesLFNST);
+              m_savedHadModeListLFNST   = hadModeList;
+              m_savedHadListLFNST       = candHadList;
+              m_savedNumRdModesLFNST    = g_intraModeNumFastUseMPM2D[logWidth - MIN_CU_LOG2][logHeight - MIN_CU_LOG2];
+              m_savedRdModeListLFNST.resize(m_savedNumRdModesLFNST);
+              m_savedModeCostLFNST.resize(m_savedNumRdModesLFNST);
               // PBINTRA fast
-              m_uiSavedHadModeListLFNST.resize(3);
-              m_dSavedHadListLFNST.resize(3);
+              m_savedHadModeListLFNST.resize(3);
+              m_savedHadListLFNST.resize(3);
               LFNSTSaveFlag = false;
             }
             //*** Derive MIP candidates using Hadamard
@@ -739,11 +971,11 @@ bool IntraSearch::estIntraPredLumaQT(CodingUnit &cu, Partitioner &partitioner, c
               for (uint32_t uiModeFull = 0; uiModeFull < numModesFull; uiModeFull++)
               {
                 const bool     isTransposed = (uiModeFull >= transpOff ? true : false);
-                const uint32_t uiMode       = (isTransposed ? uiModeFull - transpOff : uiModeFull);
+                const uint32_t mode         = (isTransposed ? uiModeFull - transpOff : uiModeFull);
 
                 numModesForFullRD++;
-                uiRdModeList.push_back(ModeInfo(true, isTransposed, 0, NOT_INTRA_SUBPARTITIONS, uiMode));
-                CandCostList.push_back(0);
+                rdModeList.push_back(ModeInfo(true, isTransposed, 0, NOT_INTRA_SUBPARTITIONS, mode));
+                candCostList.push_back(0);
               }
             }
             else if (testMip)
@@ -761,10 +993,10 @@ bool IntraSearch::estIntraPredLumaQT(CodingUnit &cu, Partitioner &partitioner, c
               for (uint32_t uiModeFull = 0; uiModeFull < numModesFull; uiModeFull++)
               {
                 const bool     isTransposed = (uiModeFull >= transpOff ? true : false);
-                const uint32_t uiMode       = (isTransposed ? uiModeFull - transpOff : uiModeFull);
+                const uint32_t mode         = (isTransposed ? uiModeFull - transpOff : uiModeFull);
 
                 pu.mipTransposedFlag           = isTransposed;
-                pu.intraDir[CHANNEL_TYPE_LUMA] = uiMode;
+                pu.intraDir[CHANNEL_TYPE_LUMA] = mode;
                 predIntraMip(COMPONENT_Y, piPred, pu);
 
                 // Use the min between SAD and HAD as the cost criterion
@@ -774,44 +1006,63 @@ bool IntraSearch::estIntraPredLumaQT(CodingUnit &cu, Partitioner &partitioner, c
 
                 m_CABACEstimator->getCtx() = SubCtx(Ctx::MipFlag, ctxStartMipFlag);
 
-                uint64_t fracModeBits = xFracModeBitsIntra(pu, uiMode, CHANNEL_TYPE_LUMA);
+                uint64_t fracModeBits = xFracModeBitsIntra(pu, mode, CHANNEL_TYPE_LUMA);
 
                 double cost            = double(minSadHad) + double(fracModeBits) * sqrtLambdaForFirstPass;
                 mipHadCost[uiModeFull] = cost;
                 DTRACE(g_trace_ctx, D_INTRA_COST, "IntraMIP: %u, %llu, %f (%d)\n", minSadHad, fracModeBits, cost,
                        uiModeFull);
 
-                updateCandList(ModeInfo(true, isTransposed, 0, NOT_INTRA_SUBPARTITIONS, uiMode), cost, uiRdModeList,
-                               CandCostList, numModesForFullRD + 1);
-                updateCandList(ModeInfo(true, isTransposed, 0, NOT_INTRA_SUBPARTITIONS, uiMode),
-                               0.8 * double(minSadHad), uiHadModeList, CandHadList, numHadCand);
+#if GDR_ENABLED
+                if (isEncodeGdrClean)
+                {
+                  if (isValidIntraPredLuma(pu, mode))
+                  {
+                    updateCandList(ModeInfo(true, isTransposed, 0, NOT_INTRA_SUBPARTITIONS, mode), cost, rdModeList,
+                                   candCostList, numModesForFullRD + 1);
+                    updateCandList(ModeInfo(true, isTransposed, 0, NOT_INTRA_SUBPARTITIONS, mode),
+                                   0.8 * double(minSadHad), hadModeList, candHadList, numHadCand);
+                  }
+                }
+                else
+                {
+                  updateCandList(ModeInfo(true, isTransposed, 0, NOT_INTRA_SUBPARTITIONS, mode), cost, rdModeList,
+                                 candCostList, numModesForFullRD + 1);
+                  updateCandList(ModeInfo(true, isTransposed, 0, NOT_INTRA_SUBPARTITIONS, mode),
+                                 0.8 * double(minSadHad), hadModeList, candHadList, numHadCand);
+                }
+#else
+                updateCandList(ModeInfo(true, isTransposed, 0, NOT_INTRA_SUBPARTITIONS, mode), cost, rdModeList,
+                               candCostList, numModesForFullRD + 1);
+                updateCandList(ModeInfo(true, isTransposed, 0, NOT_INTRA_SUBPARTITIONS, mode), 0.8 * double(minSadHad),
+                               hadModeList, candHadList, numHadCand);
+#endif
               }
 
               const double thresholdHadCost = 1.0 + 1.4 / sqrt((double) (pu.lwidth() * pu.lheight()));
-              reduceHadCandList(uiRdModeList, CandCostList, numModesForFullRD, thresholdHadCost, mipHadCost, pu,
-                                fastMip);
+              reduceHadCandList(rdModeList, candCostList, numModesForFullRD, thresholdHadCost, mipHadCost, pu, fastMip);
             }
             if (sps.getUseMIP() && LFNSTSaveFlag)
             {
               // save found best modes
-              m_uiSavedNumRdModesLFNST = numModesForFullRD;
-              m_uiSavedRdModeListLFNST = uiRdModeList;
-              m_dSavedModeCostLFNST    = CandCostList;
+              m_savedNumRdModesLFNST = numModesForFullRD;
+              m_savedRdModeListLFNST = rdModeList;
+              m_savedModeCostLFNST   = candCostList;
               // PBINTRA fast
-              m_uiSavedHadModeListLFNST = uiHadModeList;
-              m_dSavedHadListLFNST      = CandHadList;
+              m_savedHadModeListLFNST   = hadModeList;
+              m_savedHadListLFNST       = candHadList;
               LFNSTSaveFlag             = false;
             }
           }
           else   // if( sps.getUseMIP() && LFNSTLoadFlag)
           {
             // restore saved modes
-            numModesForFullRD = m_uiSavedNumRdModesLFNST;
-            uiRdModeList      = m_uiSavedRdModeListLFNST;
-            CandCostList      = m_dSavedModeCostLFNST;
+            numModesForFullRD = m_savedNumRdModesLFNST;
+            rdModeList        = m_savedRdModeListLFNST;
+            candCostList      = m_savedModeCostLFNST;
             // PBINTRA fast
-            uiHadModeList = m_uiSavedHadModeListLFNST;
-            CandHadList   = m_dSavedHadListLFNST;
+            hadModeList = m_savedHadModeListLFNST;
+            candHadList = m_savedHadListLFNST;
           }
 
           if (m_pcEncCfg->getFastUDIUseMPMEnabled())
@@ -828,16 +1079,38 @@ bool IntraSearch::estIntraPredLumaQT(CodingUnit &cu, Partitioner &partitioner, c
               bool     mostProbableModeIncluded = false;
               ModeInfo mostProbableMode( false, false, 0, NOT_INTRA_SUBPARTITIONS, uiPreds[j] );
 
+#if GDR_ENABLED
+              int nn = numModesForFullRD;
+              if (isEncodeGdrClean)
+              {
+                nn = std::min((int) numModesForFullRD, (int) rdModeList.size());
+              }
+
+              for (int i = 0; i < nn; i++)
+#else
               for (int i = 0; i < numModesForFullRD; i++)
+#endif
+              {
+                mostProbableModeIncluded |= (mostProbableMode == rdModeList[i]);
+              }
+#if GDR_ENABLED
+              if (!isEncodeGdrClean)
               {
-                mostProbableModeIncluded |= (mostProbableMode == uiRdModeList[i]);
+                if (!mostProbableModeIncluded)
+                {
+                  numModesForFullRD++;
+                  rdModeList.push_back(mostProbableMode);
+                  candCostList.push_back(0);
+                }
               }
+#else
               if (!mostProbableModeIncluded)
               {
                 numModesForFullRD++;
-                uiRdModeList.push_back(mostProbableMode);
-                CandCostList.push_back(0);
+                rdModeList.push_back(mostProbableMode);
+                candCostList.push_back(0);
               }
+#endif
             }
             if (saveDataForISP)
             {
@@ -851,10 +1124,20 @@ bool IntraSearch::estIntraPredLumaQT(CodingUnit &cu, Partitioner &partitioner, c
                 {
                   mostProbableModeIncluded |= (mostProbableMode == m_ispCandListHor[i]);
                 }
+#if GDR_ENABLED
+                if (!isEncodeGdrClean)
+                {
+                  if (!mostProbableModeIncluded)
+                  {
+                    m_ispCandListHor.push_back(mostProbableMode);
+                  }
+                }
+#else
                 if (!mostProbableModeIncluded)
                 {
                   m_ispCandListHor.push_back(mostProbableMode);
                 }
+#endif
               }
             }
           }
@@ -867,7 +1150,7 @@ bool IntraSearch::estIntraPredLumaQT(CodingUnit &cu, Partitioner &partitioner, c
         {
           // Store the modes to be checked with RD
           m_savedNumRdModes[lfnstIdx] = numModesForFullRD;
-          std::copy_n(uiRdModeList.begin(), numModesForFullRD, m_savedRdModeList[lfnstIdx]);
+          std::copy_n(rdModeList.begin(), numModesForFullRD, m_savedRdModeList[lfnstIdx]);
         }
       }
       else   // mtsUsage = 2 (here we potentially reduce the number of modes that will be full-RD checked)
@@ -883,7 +1166,7 @@ bool IntraSearch::estIntraPredLumaQT(CodingUnit &cu, Partitioner &partitioner, c
           {
             if (m_modeCostStore[lfnstIdx][i] <= thresholdSkipMode * m_bestModeCostStore[lfnstIdx])
             {
-              uiRdModeList.push_back(m_savedRdModeList[lfnstIdx][i]);
+              rdModeList.push_back(m_savedRdModeList[lfnstIdx][i]);
               numModesForFullRD++;
             }
           }
@@ -893,29 +1176,36 @@ bool IntraSearch::estIntraPredLumaQT(CodingUnit &cu, Partitioner &partitioner, c
         {
           // Restore the modes to be checked with RD
           numModesForFullRD = m_savedNumRdModes[lfnstIdx];
-          uiRdModeList.resize(numModesForFullRD);
-          std::copy_n(m_savedRdModeList[lfnstIdx], m_savedNumRdModes[lfnstIdx], uiRdModeList.begin());
-          CandCostList.resize(numModesForFullRD);
+          rdModeList.resize(numModesForFullRD);
+          std::copy_n(m_savedRdModeList[lfnstIdx], m_savedNumRdModes[lfnstIdx], rdModeList.begin());
+          candCostList.resize(numModesForFullRD);
         }
       }
 
-      CHECK(numModesForFullRD != uiRdModeList.size(), "Inconsistent state!");
+#if GDR_ENABLED
+      if (!isEncodeGdrClean)
+      {
+        CHECK(numModesForFullRD != rdModeList.size(), "Inconsistent state!");
+      }
+#else
+      CHECK(numModesForFullRD != rdModeList.size(), "Inconsistent state!");
+#endif
 
       // after this point, don't use numModesForFullRD
 
       // PBINTRA fast
-      if (m_pcEncCfg->getUsePbIntraFast() && !cs.slice->isIntra() && uiRdModeList.size() < numModesAvailable
+      if (m_pcEncCfg->getUsePbIntraFast() && !cs.slice->isIntra() && rdModeList.size() < numModesAvailable
           && !cs.slice->getDisableSATDForRD() && (mtsUsageFlag != 2 || lfnstIdx > 0))
       {
         double   pbintraRatio = (lfnstIdx > 0) ? 1.25 : PBINTRA_RATIO;
         int      maxSize      = -1;
         ModeInfo bestMipMode;
         int      bestMipIdx = -1;
-        for (int idx = 0; idx < uiRdModeList.size(); idx++)
+        for (int idx = 0; idx < rdModeList.size(); idx++)
         {
-          if (uiRdModeList[idx].mipFlg)
+          if (rdModeList[idx].mipFlg)
           {
-            bestMipMode = uiRdModeList[idx];
+            bestMipMode = rdModeList[idx];
             bestMipIdx  = idx;
             break;
           }
@@ -923,19 +1213,19 @@ bool IntraSearch::estIntraPredLumaQT(CodingUnit &cu, Partitioner &partitioner, c
         const int numHadCand = 3;
         for (int k = numHadCand - 1; k >= 0; k--)
         {
-          if (CandHadList.size() < (k + 1) || CandHadList[k] > cs.interHad * pbintraRatio)
+          if (candHadList.size() < (k + 1) || candHadList[k] > cs.interHad * pbintraRatio)
           {
             maxSize = k;
           }
         }
         if (maxSize > 0)
         {
-          uiRdModeList.resize(std::min<size_t>(uiRdModeList.size(), maxSize));
+          rdModeList.resize(std::min<size_t>(rdModeList.size(), maxSize));
           if (bestMipIdx >= 0)
           {
-            if (uiRdModeList.size() <= bestMipIdx)
+            if (rdModeList.size() <= bestMipIdx)
             {
-              uiRdModeList.push_back(bestMipMode);
+              rdModeList.push_back(bestMipMode);
             }
           }
           if (saveDataForISP)
@@ -960,17 +1250,29 @@ bool IntraSearch::estIntraPredLumaQT(CodingUnit &cu, Partitioner &partitioner, c
       }
     }
 
-    int numNonISPModes = (int)uiRdModeList.size();
+    int numNonISPModes = (int) rdModeList.size();
 
     if ( testISP )
     {
       // we reserve positions for ISP in the common full RD list
+#if GDR_ENABLED
+      if (!isEncodeGdrClean)
+      {
+        const int maxNumRDModesISP = sps.getUseLFNST() ? 16 * NUM_LFNST_NUM_PER_SET : 16;
+        m_curIspLfnstIdx = 0;
+        for (int i = 0; i < maxNumRDModesISP; i++)
+        {
+          rdModeList.push_back(ModeInfo(false, false, 0, INTRA_SUBPARTITIONS_RESERVED, 0));
+        }
+      }
+#else
       const int maxNumRDModesISP = sps.getUseLFNST() ? 16 * NUM_LFNST_NUM_PER_SET : 16;
       m_curIspLfnstIdx = 0;
       for (int i = 0; i < maxNumRDModesISP; i++)
       {
-        uiRdModeList.push_back( ModeInfo( false, false, 0, INTRA_SUBPARTITIONS_RESERVED, 0 ) );
+        rdModeList.push_back(ModeInfo(false, false, 0, INTRA_SUBPARTITIONS_RESERVED, 0));
       }
+#endif
     }
 
     //===== check modes (using r-d costs) =====
@@ -989,7 +1291,7 @@ bool IntraSearch::estIntraPredLumaQT(CodingUnit &cu, Partitioner &partitioner, c
     csBest->picture = cs.picture;
 
     // just to be sure
-    numModesForFullRD = ( int ) uiRdModeList.size();
+    numModesForFullRD = (int) rdModeList.size();
     TUIntraSubPartitioner subTuPartitioner( partitioner );
     if ( testISP )
     {
@@ -998,7 +1300,7 @@ bool IntraSearch::estIntraPredLumaQT(CodingUnit &cu, Partitioner &partitioner, c
     }
     int bestLfnstIdx = cu.lfnstIdx;
 
-    for (int mode = isSecondColorSpace ? 0 : -2 * int(testBDPCM); mode < (int)uiRdModeList.size(); mode++)
+    for (int mode = isSecondColorSpace ? 0 : -2 * int(testBDPCM); mode < (int) rdModeList.size(); mode++)
     {
       // set CU/PU to luma prediction mode
       ModeInfo uiOrgMode;
@@ -1015,9 +1317,9 @@ bool IntraSearch::estIntraPredLumaQT(CodingUnit &cu, Partitioner &partitioner, c
       else
       {
         cu.bdpcmMode = 0;
-        uiOrgMode = uiRdModeList[mode];
+        uiOrgMode    = rdModeList[mode];
       }
-      if (!cu.bdpcmMode && uiRdModeList[mode].ispMod == INTRA_SUBPARTITIONS_RESERVED)
+      if (!cu.bdpcmMode && rdModeList[mode].ispMod == INTRA_SUBPARTITIONS_RESERVED)
       {
         if (mode == numNonISPModes)   // the list needs to be sorted only once
         {
@@ -1030,13 +1332,13 @@ bool IntraSearch::estIntraPredLumaQT(CodingUnit &cu, Partitioner &partitioner, c
             break;
           }
         }
-        xGetNextISPMode(uiRdModeList[mode], (mode > 0 ? &uiRdModeList[mode - 1] : nullptr), Size(width, height));
-        if (uiRdModeList[mode].ispMod == INTRA_SUBPARTITIONS_RESERVED)
+        xGetNextISPMode(rdModeList[mode], (mode > 0 ? &rdModeList[mode - 1] : nullptr), Size(width, height));
+        if (rdModeList[mode].ispMod == INTRA_SUBPARTITIONS_RESERVED)
         {
           continue;
         }
         cu.lfnstIdx = m_curIspLfnstIdx;
-        uiOrgMode   = uiRdModeList[mode];
+        uiOrgMode   = rdModeList[mode];
       }
       cu.mipFlag                     = uiOrgMode.mipFlg;
       pu.mipTransposedFlag           = uiOrgMode.mipTrFlg;
@@ -1084,9 +1386,7 @@ bool IntraSearch::estIntraPredLumaQT(CodingUnit &cu, Partitioner &partitioner, c
         }
         else
         {
-          tmpValidReturn = xRecurIntraCodingLumaQT(
-            *csTemp, partitioner, uiBestPUMode.ispMod ? bestCurrentCost : MAX_DOUBLE, -1, TU_NO_ISP,
-            uiBestPUMode.ispMod, mtsCheckRangeFlag, mtsFirstCheckId, mtsLastCheckId, moreProbMTSIdxFirst);
+          tmpValidReturn = xRecurIntraCodingLumaQT(*csTemp, partitioner, mtsCheckRangeFlag, mtsFirstCheckId, mtsLastCheckId, moreProbMTSIdxFirst);
         }
       }
 
@@ -1330,7 +1630,11 @@ void IntraSearch::estIntraPredChromaQT( CodingUnit &cu, Partitioner &partitioner
       {
         int mode = chromaCandModes[idx];
         satdModeList[idx] = mode;
+#if JVET_W0133_CONSTRAINED_RASL_ENCODING
+        if (PU::isLMCMode(mode) && (!PU::isLMCModeEnabled(pu, mode) || cu.slice->getDisableLmChromaCheck()))
+#else
         if (PU::isLMCMode(mode) && !PU::isLMCModeEnabled(pu, mode))
+#endif
         {
           continue;
         }
@@ -1417,21 +1721,25 @@ void IntraSearch::estIntraPredChromaQT( CodingUnit &cu, Partitioner &partitioner
       Distortion baseDist = cs.dist;
       bool testBDPCM = true;
       testBDPCM = testBDPCM && CU::bdpcmAllowed(cu, COMPONENT_Cb) && cu.ispMode == 0 && cu.mtsFlag == 0 && cu.lfnstIdx == 0;
-      for (int32_t uiMode = uiMinMode - (2 * int(testBDPCM)); uiMode < uiMaxMode; uiMode++)
+      for (int32_t mode = uiMinMode - (2 * int(testBDPCM)); mode < uiMaxMode; mode++)
       {
         int chromaIntraMode;
 
-        if (uiMode < 0)
+        if (mode < 0)
         {
-            cu.bdpcmModeChroma = -uiMode;
-            chromaIntraMode = cu.bdpcmModeChroma == 2 ? chromaCandModes[1] : chromaCandModes[2];
+          cu.bdpcmModeChroma = -mode;
+          chromaIntraMode    = cu.bdpcmModeChroma == 2 ? chromaCandModes[1] : chromaCandModes[2];
         }
         else
         {
-          chromaIntraMode = chromaCandModes[uiMode];
+          chromaIntraMode = chromaCandModes[mode];
 
           cu.bdpcmModeChroma = 0;
+#if JVET_W0133_CONSTRAINED_RASL_ENCODING
+          if( PU::isLMCMode( chromaIntraMode ) && ( !PU::isLMCModeEnabled( pu, chromaIntraMode ) || cu.slice->getDisableLmChromaCheck() ) )
+#else
           if( PU::isLMCMode( chromaIntraMode ) && ! PU::isLMCModeEnabled( pu, chromaIntraMode ) )
+#endif
           {
             continue;
           }
@@ -1464,7 +1772,17 @@ void IntraSearch::estIntraPredChromaQT( CodingUnit &cu, Partitioner &partitioner
         double    dCost   = m_pcRdCost->calcRdCost( fracBits, uiDist - baseDist );
 
         //----- compare -----
+#if GDR_ENABLED
+        bool allOk = (dCost < dBestCost);
+        if (m_pcEncCfg->getGdrEnabled())
+        {
+          allOk = allOk && dBestCost && isValidIntraPredChroma(pu, (int)PU::getCoLocatedIntraLumaMode(pu), chromaIntraMode);
+        }
+
+        if (allOk)
+#else
         if( dCost < dBestCost )
+#endif
         {
           if( lumaUsesISP && dCost < bestCostSoFar )
           {
@@ -1868,7 +2186,7 @@ void IntraSearch::preCalcPLTIndexRD(CodingStructure& cs, Partitioner& partitione
       {
         if (lossless)
         {
-          rate += m_escapeNumBins[curPel[comp]];
+          rate += getEpExGolombNumBins(curPel[comp], 5);
         }
         else
         {
@@ -1881,7 +2199,7 @@ void IntraSearch::preCalcPLTIndexRD(CodingStructure& cs, Partitioner& partitione
           {
             error += tmpErr * tmpErr;
           }
-          rate += m_escapeNumBins[paPixelValue[comp]];   // encode quantized escape color
+          rate += getEpExGolombNumBins(paPixelValue[comp], 5);   // encode quantized escape color
         }
       }
       double rdCost = (double)error + m_pcRdCost->getLambda()*(double)rate;
@@ -2188,7 +2506,7 @@ double IntraSearch::rateDistOptPLT(
       rdCost = MAX_DOUBLE;
       return rdCost;
     }
-    rdCost += m_pcRdCost->getLambda()*(m_truncBinBits[(runIndex > refIndex) ? runIndex - 1 : runIndex][(scanPos == 0) ? (indexMaxValue + 1) : indexMaxValue] << SCALE_BITS);
+    rdCost += m_pcRdCost->getLambda()*(getTruncBinBits((runIndex > refIndex) ? runIndex - 1 : runIndex, (scanPos == 0) ? (indexMaxValue + 1) : indexMaxValue)  << SCALE_BITS);
   }
   rdCost += m_indexError[runIndex][m_scanOrder[scanPos].idx] * (1 << SCALE_BITS);
   if (scanPos > 0)
@@ -2206,6 +2524,7 @@ double IntraSearch::rateDistOptPLT(
   }
   return rdCost;
 }
+
 uint32_t IntraSearch::getEpExGolombNumBins(uint32_t symbol, uint32_t count)
 {
   uint32_t numBins = 0;
@@ -2257,26 +2576,6 @@ uint32_t IntraSearch::getTruncBinBits(uint32_t symbol, uint32_t maxSymbol)
   return idxCodeBit;
 }
 
-void IntraSearch::initTBCTable(int bitDepth)
-{
-  for (uint32_t i = 0; i < m_symbolSize; i++)
-  {
-    memset(m_truncBinBits[i], 0, sizeof(uint16_t)*(m_symbolSize + 1));
-  }
-  for (uint32_t i = 0; i < (m_symbolSize + 1); i++)
-  {
-    for (uint32_t j = 0; j < i; j++)
-    {
-      m_truncBinBits[j][i] = getTruncBinBits(j, i);
-    }
-  }
-  memset(m_escapeNumBins, 0, sizeof(uint16_t)*m_symbolSize);
-  for (uint32_t i = 0; i < m_symbolSize; i++)
-  {
-    m_escapeNumBins[i] = getEpExGolombNumBins(i, 5);
-  }
-}
-
 void IntraSearch::calcPixelPred(CodingStructure& cs, Partitioner& partitioner, uint32_t yPos, uint32_t xPos, ComponentID compBegin, uint32_t numComp)
 {
   CodingUnit    &cu = *cs.getCU(partitioner.chType);
@@ -2401,9 +2700,10 @@ void IntraSearch::derivePLTLossy(CodingStructure& cs, Partitioner& partitioner,
 
   TransformUnit &tu = *cs.getTU(partitioner.chType);
   QpParam cQP(tu, compBegin);
-  int qp = cQP.Qp(true) - 12;
+  int qp = cQP.Qp(true) - 6*(channelBitDepth_L - 8);
   qp = (qp < 0) ? 0 : ((qp > 56) ? 56 : qp);
   int errorLimit = g_paletteQuant[qp];
+
   if (lossless)
   {
     errorLimit = 0;
@@ -3356,7 +3656,7 @@ void IntraSearch::xIntraCodingACTTUBlock(TransformUnit &tu, const ComponentID &c
 {
   if (!tu.blocks[compID].valid())
   {
-    CHECK(1, "tu does not exist");
+    THROW("tu does not exist");
   }
 
   CodingStructure     &cs = *tu.cs;
@@ -3614,13 +3914,10 @@ bool IntraSearch::xIntraCodingLumaISP(CodingStructure& cs, Partitioner& partitio
   return !earlySkipISP;
 }
 
-
-bool IntraSearch::xRecurIntraCodingLumaQT( CodingStructure &cs, Partitioner &partitioner, const double bestCostSoFar, const int subTuIdx, const PartSplit ispType, const bool ispIsCurrentWinner, bool mtsCheckRangeFlag, int mtsFirstCheckId, int mtsLastCheckId, bool moreProbMTSIdxFirst )
+bool IntraSearch::xRecurIntraCodingLumaQT( CodingStructure &cs, Partitioner &partitioner, bool mtsCheckRangeFlag, int mtsFirstCheckId, int mtsLastCheckId, bool moreProbMTSIdxFirst )
 {
-        int   subTuCounter = subTuIdx;
   const UnitArea &currArea = partitioner.currArea();
   const CodingUnit     &cu = *cs.getCU( currArea.lumaPos(), partitioner.chType );
-        bool  earlySkipISP = false;
   uint32_t currDepth       = partitioner.currTrDepth;
   const SPS &sps           = *cs.sps;
   bool bCheckFull          = true;
@@ -3629,11 +3926,8 @@ bool IntraSearch::xRecurIntraCodingLumaQT( CodingStructure &cs, Partitioner &par
   bCheckSplit              = partitioner.canSplit( TU_MAX_TR_SPLIT, cs );
   const Slice           &slice = *cs.slice;
 
-  if( cu.ispMode )
-  {
-    bCheckSplit = partitioner.canSplit( ispType, cs );
-    bCheckFull = !bCheckSplit;
-  }
+  CHECK(cu.ispMode != NOT_INTRA_SUBPARTITIONS, "Use the function xIntraCodingLumaISP for ISP cases.");
+
   uint32_t    numSig           = 0;
 
   double     dSingleCost                        = MAX_DOUBLE;
@@ -3750,8 +4044,6 @@ bool IntraSearch::xRecurIntraCodingLumaQT( CodingStructure &cs, Partitioner &par
     bool    cbfBestModeValid = false;
     bool    cbfDCT2  = true;
 
-    double bestDCT2cost = MAX_DOUBLE;
-    double threshold = m_pcEncCfg->getUseFastISP() && !cu.ispMode && ispIsCurrentWinner && nNumTransformCands > 1 ? 1 + 1.4 / sqrt( cu.lwidth() * cu.lheight() ) : 1;
     for( int modeId = firstCheckId; modeId <= ( sps.getUseLFNST() ? lastCheckId : ( nNumTransformCands - 1 ) ); modeId++ )
     {
       uint8_t transformIndex = modeId;
@@ -3779,12 +4071,6 @@ bool IntraSearch::xRecurIntraCodingLumaQT( CodingStructure &cs, Partitioner &par
           {
             continue;
           }
-          // we compare the DCT-II cost against the best ISP cost so far (except for TS)
-          if (m_pcEncCfg->getUseFastISP() && !cu.ispMode && ispIsCurrentWinner && trModes[modeId].first != MTS_DCT2_DCT2
-              && (trModes[modeId].first != MTS_SKIP || !tsAllowed) && bestDCT2cost > bestCostSoFar * threshold)
-          {
-            continue;
-          }
         }
         tu.mtsIdx[COMPONENT_Y] = trModes[modeId].first;
       }
@@ -3813,10 +4099,6 @@ bool IntraSearch::xRecurIntraCodingLumaQT( CodingStructure &cs, Partitioner &par
           default0Save1Load2 = 2;
         }
       }
-      if( cu.ispMode )
-      {
-        default0Save1Load2 = 0;
-      }
       if( sps.getUseLFNST() )
       {
         if( cu.mtsFlag )
@@ -3893,6 +4175,7 @@ bool IntraSearch::xRecurIntraCodingLumaQT( CodingStructure &cs, Partitioner &par
       }
 
       cuCtx.mtsLastScanPos = false;
+      cuCtx.violatesMtsCoeffConstraint = false;
       //----- determine rate and r-d cost -----
       if( ( sps.getUseLFNST() ? ( modeId == lastCheckId && modeId != 0 && checkTransformSkip ) : ( trModes[ modeId ].first != 0 ) ) && !TU::getCbfAtDepth( tu, COMPONENT_Y, currDepth ) )
       {
@@ -3903,20 +4186,13 @@ bool IntraSearch::xRecurIntraCodingLumaQT( CodingStructure &cs, Partitioner &par
         }
         else
         {
-          singleTmpFracBits = xGetIntraFracBitsQT(*csFull, partitioner, true, false, subTuCounter, ispType, &cuCtx);
+          singleTmpFracBits = xGetIntraFracBitsQT(*csFull, partitioner, true, false, -1, TU_NO_ISP, &cuCtx);
           singleCostTmp = m_pcRdCost->calcRdCost(singleTmpFracBits, singleDistTmpLuma);
         }
       }
       else
       {
-        if( cu.ispMode && m_pcRdCost->calcRdCost( csFull->fracBits, csFull->dist + singleDistTmpLuma ) > bestCostSoFar )
-        {
-          earlySkipISP = true;
-        }
-        else
-        {
-          singleTmpFracBits = xGetIntraFracBitsQT( *csFull, partitioner, true, false, subTuCounter, ispType, &cuCtx );
-        }
+        singleTmpFracBits = xGetIntraFracBitsQT(*csFull, partitioner, true, false, -1, TU_NO_ISP, &cuCtx);
         if (tu.mtsIdx[COMPONENT_Y] > MTS_SKIP)
         {
           if (!cuCtx.mtsLastScanPos)
@@ -3934,10 +4210,6 @@ bool IntraSearch::xRecurIntraCodingLumaQT( CodingStructure &cs, Partitioner &par
         }
       }
 
-      if ( !cu.ispMode && nNumTransformCands > 1 && modeId == firstCheckId )
-      {
-        bestDCT2cost = singleCostTmp;
-      }
 
       if (singleCostTmp < dSingleCost)
       {
@@ -4037,53 +4309,19 @@ bool IntraSearch::xRecurIntraCodingLumaQT( CodingStructure &cs, Partitioner &par
       partitioner.splitCurrArea( TU_MAX_TR_SPLIT, cs );
     }
 
-    if( cu.ispMode )
-    {
-      partitioner.splitCurrArea( ispType, *csSplit );
-    }
     do
     {
-      bool tmpValidReturnSplit = xRecurIntraCodingLumaQT( *csSplit, partitioner, bestCostSoFar, subTuCounter, ispType, false, mtsCheckRangeFlag, mtsFirstCheckId, mtsLastCheckId );
-      subTuCounter += subTuCounter != -1 ? 1 : 0;
+      bool tmpValidReturnSplit = xRecurIntraCodingLumaQT( *csSplit, partitioner, false, mtsCheckRangeFlag, mtsFirstCheckId, mtsLastCheckId );
       if( sps.getUseLFNST() && !tmpValidReturnSplit )
       {
         splitIsSelected = false;
         break;
       }
 
-      if( !cu.ispMode )
-      {
-        csSplit->setDecomp( partitioner.currArea().Y() );
-      }
-      else if( CU::isISPFirst( cu, partitioner.currArea().Y(), COMPONENT_Y ) )
-      {
-        csSplit->setDecomp( cu.Y() );
-      }
+      csSplit->setDecomp(partitioner.currArea().Y());
+
+      uiSplitCbfLuma |= TU::getCbfAtDepth(*csSplit->getTU(partitioner.currArea().lumaPos(), partitioner.chType, -1), COMPONENT_Y, partitioner.currTrDepth);
 
-      uiSplitCbfLuma |= TU::getCbfAtDepth( *csSplit->getTU( partitioner.currArea().lumaPos(), partitioner.chType, subTuCounter - 1 ), COMPONENT_Y, partitioner.currTrDepth );
-      if( cu.ispMode )
-      {
-        //exit condition if the accumulated cost is already larger than the best cost so far (no impact in RD performance)
-        if( csSplit->cost > bestCostSoFar )
-        {
-          earlySkipISP    = true;
-          splitIsSelected = false;
-          break;
-        }
-        else
-        {
-          //more restrictive exit condition
-          bool tuIsDividedInRows = CU::divideTuInRows( cu );
-          int nSubPartitions = tuIsDividedInRows ? cu.lheight() >> floorLog2(cu.firstTU->lheight()) : cu.lwidth() >> floorLog2(cu.firstTU->lwidth());
-          double threshold = nSubPartitions == 2 ? 0.95 : subTuCounter == 1 ? 0.83 : 0.91;
-          if( subTuCounter < nSubPartitions && csSplit->cost > bestCostSoFar*threshold )
-          {
-            earlySkipISP    = true;
-            splitIsSelected = false;
-            break;
-          }
-        }
-      }
     } while( partitioner.nextPart( *csSplit ) );
 
     partitioner.exitCurrSplit();
@@ -4108,7 +4346,7 @@ bool IntraSearch::xRecurIntraCodingLumaQT( CodingStructure &cs, Partitioner &par
       cuCtx.mtsLastScanPos = false;
 
       //----- determine rate and r-d cost -----
-      csSplit->fracBits = xGetIntraFracBitsQT( *csSplit, partitioner, true, false, cu.ispMode ? 0 : -1, ispType, &cuCtx );
+      csSplit->fracBits = xGetIntraFracBitsQT( *csSplit, partitioner, true, false, -1, TU_NO_ISP, &cuCtx );
 
       //--- update cost ---
       csSplit->cost     = m_pcRdCost->calcRdCost(csSplit->fracBits, csSplit->dist);
@@ -4125,16 +4363,8 @@ bool IntraSearch::xRecurIntraCodingLumaQT( CodingStructure &cs, Partitioner &par
       // otherwise this would've happened in useSubStructure
       cs.picture->getRecoBuf(currArea.Y()).copyFrom(cs.getRecoBuf(currArea.Y()));
       cs.picture->getPredBuf(currArea.Y()).copyFrom(cs.getPredBuf(currArea.Y()));
-
-      if( cu.ispMode && earlySkipISP )
-      {
-        cs.cost = MAX_DOUBLE;
-      }
-      else
-      {
-        cs.cost = m_pcRdCost->calcRdCost( cs.fracBits, cs.dist );
-        retVal = true;
-      }
+      cs.cost = m_pcRdCost->calcRdCost(cs.fracBits, cs.dist);
+      retVal = true;
     }
   }
   return retVal;
@@ -4245,6 +4475,7 @@ bool IntraSearch::xRecurIntraCodingACTQT(CodingStructure &cs, Partitioner &parti
 
     const bool tsAllowed = TU::isTSAllowed(tu, COMPONENT_Y);
     const bool mtsAllowed = CU::isMTSAllowed(cu, COMPONENT_Y);
+    const bool lossless = m_pcEncCfg->getCostMode() == COST_LOSSLESS_CODING && slice.isLossless();
     std::vector<TrMode> trModes;
 
     if (sps.getUseLFNST())
@@ -4261,7 +4492,7 @@ bool IntraSearch::xRecurIntraCodingACTQT(CodingStructure &cs, Partitioner &parti
     }
     else
     {
-      if (m_pcEncCfg->getCostMode() == COST_LOSSLESS_CODING && slice.isLossless())
+      if (lossless)
       {
         nNumTransformCands = 1;
         CHECK(!tsAllowed && !cu.bdpcmMode, "transform skip should be enabled for LS");
@@ -4316,8 +4547,13 @@ bool IntraSearch::xRecurIntraCodingACTQT(CodingStructure &cs, Partitioner &parti
     bool    cbfDCT2 = true;
     if (m_pcEncCfg->getCostMode() != COST_LOSSLESS_CODING || !slice.isLossless())
     m_pcRdCost->lambdaAdjustColorTrans(true, COMPONENT_Y);
-    for (int modeId = firstCheckId; modeId <= ((m_pcEncCfg->getCostMode() == COST_LOSSLESS_CODING && slice.isLossless()) ? (nNumTransformCands - 1) : lastCheckId); modeId++)
+    for (int modeIndex = firstCheckId; sps.getUseLFNST() || modeIndex < trModes.size(); modeIndex++)
     {
+      const int modeId = sps.getUseLFNST() ? modeIndex : trModes[modeIndex].first;
+      if (modeId > lastCheckId)
+      {
+        break;
+      }
       uint8_t transformIndex = modeId;
       csFull->getResiBuf(tu.Y()).copyFrom(csFull->getOrgResiBuf(tu.Y()));
 
@@ -4337,18 +4573,18 @@ bool IntraSearch::xRecurIntraCodingACTQT(CodingStructure &cs, Partitioner &parti
       }
       else
       {
-        if (!(m_pcEncCfg->getCostMode() == COST_LOSSLESS_CODING && slice.isLossless()))
+        if (!lossless)
         {
           if (!cbfDCT2 || (m_pcEncCfg->getUseTransformSkipFast() && bestLumaModeId == 1))
           {
             break;
           }
-          if (!trModes[modeId].second)
+          if (!trModes[modeIndex].second)
           {
             continue;
           }
         }
-        tu.mtsIdx[COMPONENT_Y] = trModes[modeId].first;
+        tu.mtsIdx[COMPONENT_Y] = modeId;
       }
 
       singleDistTmpLuma = 0;
@@ -4428,7 +4664,7 @@ bool IntraSearch::xRecurIntraCodingACTQT(CodingStructure &cs, Partitioner &parti
       cuCtx.isDQPCoded = true;
       cuCtx.isChromaQpAdjCoded = true;
       //----- determine rate and r-d cost -----
-      if ((sps.getUseLFNST() ? (modeId == lastCheckId && modeId != 0 && checkTransformSkip) : (trModes[modeId].first != 0)) && !TU::getCbfAtDepth(tu, COMPONENT_Y, currDepth))
+      if ((sps.getUseLFNST() ? (modeId == lastCheckId && modeId != 0 && checkTransformSkip) : (modeId != 0)) && !TU::getCbfAtDepth(tu, COMPONENT_Y, currDepth))
       {
         //In order not to code TS flag when cbf is zero, the case for TS with cbf being zero is forbidden.
         if (m_pcEncCfg->getCostMode() != COST_LOSSLESS_CODING || !slice.isLossless())
@@ -4473,8 +4709,8 @@ bool IntraSearch::xRecurIntraCodingACTQT(CodingStructure &cs, Partitioner &parti
         }
         else
         {
-          bestLumaModeId = trModes[modeId].first;
-          if (trModes[modeId].first == 0)
+          bestLumaModeId = modeId;
+          if (modeId == 0)
           {
             cbfDCT2 = TU::getCbfAtDepth(tu, COMPONENT_Y, currDepth);
           }
@@ -4548,7 +4784,7 @@ bool IntraSearch::xRecurIntraCodingACTQT(CodingStructure &cs, Partitioner &parti
       bool        cbfDCT2 = true;
 
       trModes.clear();
-      if (m_pcEncCfg->getCostMode() == COST_LOSSLESS_CODING && slice.isLossless())
+      if (lossless)
       {
         numTransformCands = 1;
         CHECK(!tsAllowed && !cu.bdpcmModeChroma, "transform skip should be enabled for LS");
@@ -5438,9 +5674,9 @@ ChromaCbfs IntraSearch::xRecurIntraChromaCodingQT( CodingStructure &cs, Partitio
   return cbfs;
 }
 
-uint64_t IntraSearch::xFracModeBitsIntra(PredictionUnit &pu, const uint32_t &uiMode, const ChannelType &chType)
+uint64_t IntraSearch::xFracModeBitsIntra(PredictionUnit &pu, const uint32_t &mode, const ChannelType &chType)
 {
-  uint32_t orgMode = uiMode;
+  uint32_t orgMode = mode;
 
   if (!pu.ciipFlag)
   std::swap(orgMode, pu.intraDir[chType]);
@@ -5910,7 +6146,7 @@ bool IntraSearch::xSortISPCandList(double bestCostSoFar, double bestNonISPCost,
   m_ispCandListVer.clear();
 
   // we sort the normal intra modes according to their full RD costs
-  std::sort(m_regIntraRDListWithCosts.begin(), m_regIntraRDListWithCosts.end(), ModeInfoWithCost::compareModeInfoWithCost);
+  std::stable_sort(m_regIntraRDListWithCosts.begin(), m_regIntraRDListWithCosts.end(), ModeInfoWithCost::compareModeInfoWithCost);
 
   // we get the best angle from the regular intra list
   int bestNormalIntraAngle = -1;
diff --git a/source/Lib/EncoderLib/IntraSearch.h b/source/Lib/EncoderLib/IntraSearch.h
index f911e0fe2..67253de40 100644
--- a/source/Lib/EncoderLib/IntraSearch.h
+++ b/source/Lib/EncoderLib/IntraSearch.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -363,11 +363,11 @@ private:
   int                                                m_numSavedRdModeFirstColorSpace[4 * NUM_LFNST_NUM_PER_SET * 2];
   int                                                m_savedRdModeIdx;
 
-  static_vector<ModeInfo, FAST_UDI_MAX_RDMODE_NUM> m_uiSavedRdModeListLFNST;
-  static_vector<ModeInfo, FAST_UDI_MAX_RDMODE_NUM> m_uiSavedHadModeListLFNST;
-  uint32_t                                         m_uiSavedNumRdModesLFNST;
-  static_vector<double,   FAST_UDI_MAX_RDMODE_NUM> m_dSavedModeCostLFNST;
-  static_vector<double,   FAST_UDI_MAX_RDMODE_NUM> m_dSavedHadListLFNST;
+  static_vector<ModeInfo, FAST_UDI_MAX_RDMODE_NUM> m_savedRdModeListLFNST;
+  static_vector<ModeInfo, FAST_UDI_MAX_RDMODE_NUM> m_savedHadModeListLFNST;
+  uint32_t                                         m_savedNumRdModesLFNST;
+  static_vector<double, FAST_UDI_MAX_RDMODE_NUM>   m_savedModeCostLFNST;
+  static_vector<double, FAST_UDI_MAX_RDMODE_NUM>   m_savedHadListLFNST;
 
   PelStorage      m_tmpStorageLCU;
   PelStorage      m_colorTransResiBuf;
@@ -385,9 +385,6 @@ protected:
   CtxCache*       m_CtxCache;
 
   bool            m_isInitialized;
-  uint32_t        m_symbolSize;
-  uint16_t**      m_truncBinBits;
-  uint16_t*       m_escapeNumBins;
   bool            m_bestEscape;
   double*         m_indexError[MAXPLTSIZE + 1];
   uint8_t*        m_minErrorIndexMap; // store the best index in terms of distortion for each pixel
@@ -433,13 +430,18 @@ public:
   bool estIntraPredLumaQT(CodingUnit &cu, Partitioner& pm, const double bestCostSoFar = MAX_DOUBLE, bool mtsCheckRangeFlag = false, int mtsFirstCheckId = 0, int mtsLastCheckId = 0, bool moreProbMTSIdxFirst = false, CodingStructure* bestCS = NULL);
   void estIntraPredChromaQT       ( CodingUnit &cu, Partitioner& pm, const double maxCostAllowed = MAX_DOUBLE );
   void PLTSearch                  ( CodingStructure &cs, Partitioner& partitioner, ComponentID compBegin, uint32_t numComp);
-  uint64_t xFracModeBitsIntra     (PredictionUnit &pu, const uint32_t &uiMode, const ChannelType &compID);
+  uint64_t xFracModeBitsIntra(PredictionUnit &pu, const uint32_t &mode, const ChannelType &compID);
   void invalidateBestModeCost     () { for( int i = 0; i < NUM_LFNST_NUM_PER_SET; i++ ) m_bestModeCostValid[ i ] = false; };
 
   void sortRdModeListFirstColorSpace(ModeInfo mode, double cost, char bdpcmMode, ModeInfo* rdModeList, double* rdCostList, char* bdpcmModeList, int& candNum);
   void invalidateBestRdModeFirstColorSpace();
   void setSavedRdModeIdx(int idx) { m_savedRdModeIdx = idx; }
 
+#if GDR_ENABLED
+  int  getNumTopRecons(PredictionUnit &pu, int luma_dirMode, bool isChroma);
+  bool isValidIntraPredLuma(PredictionUnit &pu, int luma_dirMode);
+  bool isValidIntraPredChroma(PredictionUnit &pu, int luma_dirMode, int chroma_dirMode);
+#endif
 protected:
 
   // -------------------------------------------------------------------------------------------------------------------
@@ -463,7 +465,7 @@ protected:
   void xIntraCodingACTTUBlock(TransformUnit &tu, const ComponentID &compID, Distortion& ruiDist, std::vector<TrMode>* trModes = nullptr, const bool loadTr = false);
 
   ChromaCbfs xRecurIntraChromaCodingQT( CodingStructure &cs, Partitioner& pm, const double bestCostSoFar = MAX_DOUBLE,                          const PartSplit ispType = TU_NO_ISP );
-  bool       xRecurIntraCodingLumaQT  ( CodingStructure &cs, Partitioner& pm, const double bestCostSoFar = MAX_DOUBLE, const int subTuIdx = -1, const PartSplit ispType = TU_NO_ISP, const bool ispIsCurrentWinner = false, bool mtsCheckRangeFlag = false, int mtsFirstCheckId = 0, int mtsLastCheckId = 0, bool moreProbMTSIdxFirst = false );
+  bool       xRecurIntraCodingLumaQT  ( CodingStructure &cs, Partitioner& pm, bool mtsCheckRangeFlag = false, int mtsFirstCheckId = 0, int mtsLastCheckId = 0, bool moreProbMTSIdxFirst = false );
   bool       xRecurIntraCodingACTQT(CodingStructure &cs, Partitioner& pm, bool mtsCheckRangeFlag = false, int mtsFirstCheckId = 0, int mtsLastCheckId = 0, bool moreProbMTSIdxFirst = false);
   bool       xIntraCodingLumaISP      ( CodingStructure& cs, Partitioner& pm, const double bestCostSoFar = MAX_DOUBLE );
 
@@ -476,7 +478,6 @@ protected:
   void     deriveIndexMap         (CodingStructure& cs, Partitioner& partitioner, ComponentID compBegin, uint32_t numComp, PLTScanMode pltScanMode, double& dCost, bool* idxExist);
   bool     deriveSubblockIndexMap(CodingStructure& cs, Partitioner& partitioner, ComponentID compBegin, PLTScanMode pltScanMode, int minSubPos, int maxSubPos, const BinFracBits& fracBitsPltRunType, const BinFracBits* fracBitsPltIndexINDEX, const BinFracBits* fracBitsPltIndexCOPY, const double minCost, bool useRotate);
   double   rateDistOptPLT         (bool RunType, uint8_t RunIndex, bool prevRunType, uint8_t prevRunIndex, uint8_t aboveRunIndex, bool& prevCodedRunType, int& prevCodedRunPos, int scanPos, uint32_t width, int dist, int indexMaxValue, const BinFracBits* IndexfracBits, const BinFracBits& TypefracBits);
-  void     initTBCTable           (int bitDepth);
   uint32_t getTruncBinBits        (uint32_t symbol, uint32_t maxSymbol);
   uint32_t getEpExGolombNumBins   (uint32_t symbol, uint32_t count);
   void xGetNextISPMode                    ( ModeInfo& modeInfo, const ModeInfo* lastMode, const Size cuSize );
diff --git a/source/Lib/EncoderLib/NALwrite.cpp b/source/Lib/EncoderLib/NALwrite.cpp
index 49cc9aa6d..799e5c6c5 100644
--- a/source/Lib/EncoderLib/NALwrite.cpp
+++ b/source/Lib/EncoderLib/NALwrite.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -48,7 +48,7 @@ static const uint8_t emulation_prevention_three_byte = 3;
 
 void writeNalUnitHeader(ostream& out, OutputNALUnit& nalu)       // nal_unit_header()
 {
-OutputBitstream bsNALUHeader;
+  OutputBitstream bsNALUHeader;
   int forbiddenZero = 0;
   bsNALUHeader.write(forbiddenZero, 1);   // forbidden_zero_bit
   int nuhReservedZeroBit = 0;
diff --git a/source/Lib/EncoderLib/NALwrite.h b/source/Lib/EncoderLib/NALwrite.h
index d70242926..477cbb7b2 100644
--- a/source/Lib/EncoderLib/NALwrite.h
+++ b/source/Lib/EncoderLib/NALwrite.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/EncoderLib/RateCtrl.cpp b/source/Lib/EncoderLib/RateCtrl.cpp
index 18a9580ed..0e33acb63 100644
--- a/source/Lib/EncoderLib/RateCtrl.cpp
+++ b/source/Lib/EncoderLib/RateCtrl.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -402,120 +402,117 @@ void EncRCGOP::create( EncRCSeq* encRCSeq, int numPic )
     }
     else if (encRCSeq->getAdaptiveBits() == 2 && encRCSeq->getGOPSize() == 16 )  // for GOP size = 16, random access case
     {
-      {
-        const double qdfParaLev2A = 0.5847;
-        const double qdfParaLev2B = -0.0782;
-        const double qdfParaLev3A = 0.5468;
-        const double qdfParaLev3B = -0.1364;
-        const double qdfParaLev4A = 0.6539;
-        const double qdfParaLev4B = -0.203;
-        const double qdfParaLev5A = 0.8623;
-        const double qdfParaLev5B = -0.4676;
-        double qdfLev1Lev2 = Clip3(0.12, 0.9, qdfParaLev2A * encRCSeq->getPicPara(2).m_skipRatio + qdfParaLev2B);
-        double qdfLev1Lev3 = Clip3(0.13, 0.9, qdfParaLev3A * encRCSeq->getPicPara(3).m_skipRatio + qdfParaLev3B);
-        double qdfLev1Lev4 = Clip3(0.15, 0.9, qdfParaLev4A * encRCSeq->getPicPara(4).m_skipRatio + qdfParaLev4B);
-        double qdfLev1Lev5 = Clip3(0.20, 0.9, qdfParaLev5A * encRCSeq->getPicPara(5).m_skipRatio + qdfParaLev5B);
-        double qdfLev2Lev3 = Clip3(0.09, 0.9, qdfLev1Lev3 * (1 - qdfLev1Lev2));
-        double qdfLev2Lev4 = Clip3(0.12, 0.9, qdfLev1Lev4 * (1 - qdfLev1Lev2));
-        double qdfLev2Lev5 = Clip3(0.14, 0.9, qdfLev1Lev5 * (1 - qdfLev1Lev2));
-        double qdfLev3Lev4 = Clip3(0.06, 0.9, qdfLev1Lev4 * (1 - qdfLev1Lev3));
-        double qdfLev3Lev5 = Clip3(0.09, 0.9, qdfLev1Lev5 * (1 - qdfLev1Lev3));
-        double qdfLev4Lev5 = Clip3(0.10, 0.9, qdfLev1Lev5 * (1 - qdfLev1Lev4));
-
-        double lambdaLev1 = 1 / (1 + 2 * (qdfLev1Lev2 + 2 * qdfLev1Lev3 + 4 * qdfLev1Lev4 + 8 * qdfLev1Lev5));
-        double lambdaLev2 = 1 / (1 + (3 * qdfLev2Lev3 + 5 * qdfLev2Lev4 + 8 * qdfLev2Lev5));
-        double lambdaLev3 = 1 / (1 + 2 * qdfLev3Lev4 + 4 * qdfLev3Lev5);
-        double lambdaLev4 = 1 / (1 + 2 * qdfLev4Lev5);
-        double lambdaLev5 = 1 / (1.0);
-
-        lambdaRatio[0] = 1.0;
-        lambdaRatio[1] = lambdaLev2 / lambdaLev1;
-        lambdaRatio[2] = lambdaLev3 / lambdaLev1;
-        lambdaRatio[3] = lambdaLev4 / lambdaLev1;
-        lambdaRatio[4] = lambdaLev5 / lambdaLev1;
-        lambdaRatio[5] = lambdaLev5 / lambdaLev1;
-        lambdaRatio[6] = lambdaLev4 / lambdaLev1;
-        lambdaRatio[7] = lambdaLev5 / lambdaLev1;
-        lambdaRatio[8] = lambdaLev5 / lambdaLev1;
-        lambdaRatio[9] = lambdaLev3 / lambdaLev1;
-        lambdaRatio[10] = lambdaLev4 / lambdaLev1;
-        lambdaRatio[11] = lambdaLev5 / lambdaLev1;
-        lambdaRatio[12] = lambdaLev5 / lambdaLev1;
-        lambdaRatio[13] = lambdaLev4 / lambdaLev1;
-        lambdaRatio[14] = lambdaLev5 / lambdaLev1;
-        lambdaRatio[15] = lambdaLev5 / lambdaLev1;
-      }
+      const double qdfParaLev2A = 0.5847;
+      const double qdfParaLev2B = -0.0782;
+      const double qdfParaLev3A = 0.5468;
+      const double qdfParaLev3B = -0.1364;
+      const double qdfParaLev4A = 0.6539;
+      const double qdfParaLev4B = -0.203;
+      const double qdfParaLev5A = 0.8623;
+      const double qdfParaLev5B = -0.4676;
+      double       qdfLev1Lev2  = Clip3(0.12, 0.9, qdfParaLev2A * encRCSeq->getPicPara(2).m_skipRatio + qdfParaLev2B);
+      double       qdfLev1Lev3  = Clip3(0.13, 0.9, qdfParaLev3A * encRCSeq->getPicPara(3).m_skipRatio + qdfParaLev3B);
+      double       qdfLev1Lev4  = Clip3(0.15, 0.9, qdfParaLev4A * encRCSeq->getPicPara(4).m_skipRatio + qdfParaLev4B);
+      double       qdfLev1Lev5  = Clip3(0.20, 0.9, qdfParaLev5A * encRCSeq->getPicPara(5).m_skipRatio + qdfParaLev5B);
+      double       qdfLev2Lev3  = Clip3(0.09, 0.9, qdfLev1Lev3 * (1 - qdfLev1Lev2));
+      double       qdfLev2Lev4  = Clip3(0.12, 0.9, qdfLev1Lev4 * (1 - qdfLev1Lev2));
+      double       qdfLev2Lev5  = Clip3(0.14, 0.9, qdfLev1Lev5 * (1 - qdfLev1Lev2));
+      double       qdfLev3Lev4  = Clip3(0.06, 0.9, qdfLev1Lev4 * (1 - qdfLev1Lev3));
+      double       qdfLev3Lev5  = Clip3(0.09, 0.9, qdfLev1Lev5 * (1 - qdfLev1Lev3));
+      double       qdfLev4Lev5  = Clip3(0.10, 0.9, qdfLev1Lev5 * (1 - qdfLev1Lev4));
+
+      double lambdaLev1 = 1 / (1 + 2 * (qdfLev1Lev2 + 2 * qdfLev1Lev3 + 4 * qdfLev1Lev4 + 8 * qdfLev1Lev5));
+      double lambdaLev2 = 1 / (1 + (3 * qdfLev2Lev3 + 5 * qdfLev2Lev4 + 8 * qdfLev2Lev5));
+      double lambdaLev3 = 1 / (1 + 2 * qdfLev3Lev4 + 4 * qdfLev3Lev5);
+      double lambdaLev4 = 1 / (1 + 2 * qdfLev4Lev5);
+      double lambdaLev5 = 1 / (1.0);
+
+      lambdaRatio[0]  = 1.0;
+      lambdaRatio[1]  = lambdaLev2 / lambdaLev1;
+      lambdaRatio[2]  = lambdaLev3 / lambdaLev1;
+      lambdaRatio[3]  = lambdaLev4 / lambdaLev1;
+      lambdaRatio[4]  = lambdaLev5 / lambdaLev1;
+      lambdaRatio[5]  = lambdaLev5 / lambdaLev1;
+      lambdaRatio[6]  = lambdaLev4 / lambdaLev1;
+      lambdaRatio[7]  = lambdaLev5 / lambdaLev1;
+      lambdaRatio[8]  = lambdaLev5 / lambdaLev1;
+      lambdaRatio[9]  = lambdaLev3 / lambdaLev1;
+      lambdaRatio[10] = lambdaLev4 / lambdaLev1;
+      lambdaRatio[11] = lambdaLev5 / lambdaLev1;
+      lambdaRatio[12] = lambdaLev5 / lambdaLev1;
+      lambdaRatio[13] = lambdaLev4 / lambdaLev1;
+      lambdaRatio[14] = lambdaLev5 / lambdaLev1;
+      lambdaRatio[15] = lambdaLev5 / lambdaLev1;
     }
     else if (encRCSeq->getAdaptiveBits() == 2 && encRCSeq->getGOPSize() == 32 )  // for GOP size = 32, random access case
     {
-      {
-        const double qdfParaLev2A = 0.7534;
-        const double qdfParaLev2B = -0.0303;
-        const double qdfParaLev3A = 0.7044;
-        const double qdfParaLev3B = -0.0445;
-        const double qdfParaLev4A = 0.7084;
-        const double qdfParaLev4B = -0.1401;
-        const double qdfParaLev5A = 0.8844;
-        const double qdfParaLev5B = -0.3676;
-        const double qdfParaLev6A = 1.2336;
-        const double qdfParaLev6B = -0.7511;
-
-        double qdfLev1Lev2 = Clip3(0.12, 0.9, qdfParaLev2A * encRCSeq->getPicPara(2).m_skipRatio + qdfParaLev2B);
-        double qdfLev1Lev3 = Clip3(0.13, 0.9, qdfParaLev3A * encRCSeq->getPicPara(3).m_skipRatio + qdfParaLev3B);
-        double qdfLev1Lev4 = Clip3(0.15, 0.9, qdfParaLev4A * encRCSeq->getPicPara(4).m_skipRatio + qdfParaLev4B);
-        double qdfLev1Lev5 = Clip3(0.20, 0.9, qdfParaLev5A * encRCSeq->getPicPara(5).m_skipRatio + qdfParaLev5B);
-        double qdfLev1Lev6 = Clip3(0.25, 0.9, qdfParaLev6A * encRCSeq->getPicPara(6).m_skipRatio + qdfParaLev6B);
-        double qdfLev2Lev3 = Clip3(0.09, 0.9, qdfLev1Lev3 * (1 - qdfLev1Lev2));
-        double qdfLev2Lev4 = Clip3(0.12, 0.9, qdfLev1Lev4 * (1 - qdfLev1Lev2));
-        double qdfLev2Lev5 = Clip3(0.14, 0.9, qdfLev1Lev5 * (1 - qdfLev1Lev2));
-        double qdfLev2Lev6 = Clip3(0.16, 0.9, qdfLev1Lev6 * (1 - qdfLev1Lev2));
-        double qdfLev3Lev4 = Clip3(0.06, 0.9, qdfLev1Lev4 * (1 - qdfLev1Lev3));
-        double qdfLev3Lev5 = Clip3(0.09, 0.9, qdfLev1Lev5 * (1 - qdfLev1Lev3));
-        double qdfLev3Lev6 = Clip3(0.10, 0.9, qdfLev1Lev6 * (1 - qdfLev1Lev3));
-        double qdfLev4Lev5 = Clip3(0.10, 0.9, qdfLev1Lev5 * (1 - qdfLev1Lev4));
-        double qdfLev4Lev6 = Clip3(0.10, 0.9, qdfLev1Lev6 * (1 - qdfLev1Lev4));
-        double qdfLev5Lev6 = Clip3(0.12, 0.9, qdfLev1Lev6 * (1 - qdfLev1Lev5));
-
-         double lambdaLev1 = 1 / (1 + 2 * qdfLev1Lev2 + 4 * qdfLev1Lev3 + 6 * qdfLev1Lev4 + 8 * qdfLev1Lev5 + 10 * qdfLev1Lev6);
-         double lambdaLev2 = 1 / (1 + 3 * qdfLev2Lev3 + 5 * qdfLev2Lev4 + 8 * qdfLev2Lev5 + 9 * qdfLev2Lev6);
-         double lambdaLev3 = 1 / (1 + 2 * qdfLev3Lev4 + 4 * qdfLev3Lev5 + 6 * qdfLev3Lev6);
-         double lambdaLev4 = 1 / (1 + 2 * qdfLev4Lev5 + 4 * qdfLev4Lev6);
-         double lambdaLev5 = 1 / (1 + 2 * qdfLev5Lev6);
-         double lambdaLev6 = 1 / (1.0);
-
-         lambdaRatio[0] = 1.0;
-         lambdaRatio[1]  = lambdaLev2 / lambdaLev1;
-         lambdaRatio[2]  = lambdaLev3 / lambdaLev1;
-         lambdaRatio[3]  = lambdaLev4 / lambdaLev1;
-         lambdaRatio[4]  = lambdaLev5 / lambdaLev1;
-         lambdaRatio[5]  = lambdaLev6 / lambdaLev1;
-         lambdaRatio[6]  = lambdaLev6 / lambdaLev1;
-         lambdaRatio[7]  = lambdaLev5 / lambdaLev1;
-         lambdaRatio[8]  = lambdaLev6 / lambdaLev1;
-         lambdaRatio[9]  = lambdaLev6 / lambdaLev1;
-         lambdaRatio[10] = lambdaLev4 / lambdaLev1;
-         lambdaRatio[11] = lambdaLev5 / lambdaLev1;
-         lambdaRatio[12] = lambdaLev6 / lambdaLev1;
-         lambdaRatio[13] = lambdaLev6 / lambdaLev1;
-         lambdaRatio[14] = lambdaLev5 / lambdaLev1;
-         lambdaRatio[15] = lambdaLev6 / lambdaLev1;
-         lambdaRatio[16] = lambdaLev6 / lambdaLev1;
-         lambdaRatio[17] = lambdaLev3 / lambdaLev1;
-         lambdaRatio[18] = lambdaLev4 / lambdaLev1;
-         lambdaRatio[19] = lambdaLev5 / lambdaLev1;
-         lambdaRatio[20] = lambdaLev6 / lambdaLev1;
-         lambdaRatio[21] = lambdaLev6 / lambdaLev1;
-         lambdaRatio[22] = lambdaLev5 / lambdaLev1;
-         lambdaRatio[23] = lambdaLev6 / lambdaLev1;
-         lambdaRatio[24] = lambdaLev6 / lambdaLev1;
-         lambdaRatio[25] = lambdaLev4 / lambdaLev1;
-         lambdaRatio[26] = lambdaLev5 / lambdaLev1;
-         lambdaRatio[27] = lambdaLev6 / lambdaLev1;
-         lambdaRatio[28] = lambdaLev6 / lambdaLev1;
-         lambdaRatio[29] = lambdaLev5 / lambdaLev1;
-         lambdaRatio[30] = lambdaLev6 / lambdaLev1;
-         lambdaRatio[31] = lambdaLev6 / lambdaLev1;
-      }
+      const double qdfParaLev2A = 0.7534;
+      const double qdfParaLev2B = -0.0303;
+      const double qdfParaLev3A = 0.7044;
+      const double qdfParaLev3B = -0.0445;
+      const double qdfParaLev4A = 0.7084;
+      const double qdfParaLev4B = -0.1401;
+      const double qdfParaLev5A = 0.8844;
+      const double qdfParaLev5B = -0.3676;
+      const double qdfParaLev6A = 1.2336;
+      const double qdfParaLev6B = -0.7511;
+
+      double qdfLev1Lev2 = Clip3(0.12, 0.9, qdfParaLev2A * encRCSeq->getPicPara(2).m_skipRatio + qdfParaLev2B);
+      double qdfLev1Lev3 = Clip3(0.13, 0.9, qdfParaLev3A * encRCSeq->getPicPara(3).m_skipRatio + qdfParaLev3B);
+      double qdfLev1Lev4 = Clip3(0.15, 0.9, qdfParaLev4A * encRCSeq->getPicPara(4).m_skipRatio + qdfParaLev4B);
+      double qdfLev1Lev5 = Clip3(0.20, 0.9, qdfParaLev5A * encRCSeq->getPicPara(5).m_skipRatio + qdfParaLev5B);
+      double qdfLev1Lev6 = Clip3(0.25, 0.9, qdfParaLev6A * encRCSeq->getPicPara(6).m_skipRatio + qdfParaLev6B);
+      double qdfLev2Lev3 = Clip3(0.09, 0.9, qdfLev1Lev3 * (1 - qdfLev1Lev2));
+      double qdfLev2Lev4 = Clip3(0.12, 0.9, qdfLev1Lev4 * (1 - qdfLev1Lev2));
+      double qdfLev2Lev5 = Clip3(0.14, 0.9, qdfLev1Lev5 * (1 - qdfLev1Lev2));
+      double qdfLev2Lev6 = Clip3(0.16, 0.9, qdfLev1Lev6 * (1 - qdfLev1Lev2));
+      double qdfLev3Lev4 = Clip3(0.06, 0.9, qdfLev1Lev4 * (1 - qdfLev1Lev3));
+      double qdfLev3Lev5 = Clip3(0.09, 0.9, qdfLev1Lev5 * (1 - qdfLev1Lev3));
+      double qdfLev3Lev6 = Clip3(0.10, 0.9, qdfLev1Lev6 * (1 - qdfLev1Lev3));
+      double qdfLev4Lev5 = Clip3(0.10, 0.9, qdfLev1Lev5 * (1 - qdfLev1Lev4));
+      double qdfLev4Lev6 = Clip3(0.10, 0.9, qdfLev1Lev6 * (1 - qdfLev1Lev4));
+      double qdfLev5Lev6 = Clip3(0.12, 0.9, qdfLev1Lev6 * (1 - qdfLev1Lev5));
+
+      double lambdaLev1 =
+        1 / (1 + 2 * qdfLev1Lev2 + 4 * qdfLev1Lev3 + 6 * qdfLev1Lev4 + 8 * qdfLev1Lev5 + 10 * qdfLev1Lev6);
+      double lambdaLev2 = 1 / (1 + 3 * qdfLev2Lev3 + 5 * qdfLev2Lev4 + 8 * qdfLev2Lev5 + 9 * qdfLev2Lev6);
+      double lambdaLev3 = 1 / (1 + 2 * qdfLev3Lev4 + 4 * qdfLev3Lev5 + 6 * qdfLev3Lev6);
+      double lambdaLev4 = 1 / (1 + 2 * qdfLev4Lev5 + 4 * qdfLev4Lev6);
+      double lambdaLev5 = 1 / (1 + 2 * qdfLev5Lev6);
+      double lambdaLev6 = 1 / (1.0);
+
+      lambdaRatio[0]  = 1.0;
+      lambdaRatio[1]  = lambdaLev2 / lambdaLev1;
+      lambdaRatio[2]  = lambdaLev3 / lambdaLev1;
+      lambdaRatio[3]  = lambdaLev4 / lambdaLev1;
+      lambdaRatio[4]  = lambdaLev5 / lambdaLev1;
+      lambdaRatio[5]  = lambdaLev6 / lambdaLev1;
+      lambdaRatio[6]  = lambdaLev6 / lambdaLev1;
+      lambdaRatio[7]  = lambdaLev5 / lambdaLev1;
+      lambdaRatio[8]  = lambdaLev6 / lambdaLev1;
+      lambdaRatio[9]  = lambdaLev6 / lambdaLev1;
+      lambdaRatio[10] = lambdaLev4 / lambdaLev1;
+      lambdaRatio[11] = lambdaLev5 / lambdaLev1;
+      lambdaRatio[12] = lambdaLev6 / lambdaLev1;
+      lambdaRatio[13] = lambdaLev6 / lambdaLev1;
+      lambdaRatio[14] = lambdaLev5 / lambdaLev1;
+      lambdaRatio[15] = lambdaLev6 / lambdaLev1;
+      lambdaRatio[16] = lambdaLev6 / lambdaLev1;
+      lambdaRatio[17] = lambdaLev3 / lambdaLev1;
+      lambdaRatio[18] = lambdaLev4 / lambdaLev1;
+      lambdaRatio[19] = lambdaLev5 / lambdaLev1;
+      lambdaRatio[20] = lambdaLev6 / lambdaLev1;
+      lambdaRatio[21] = lambdaLev6 / lambdaLev1;
+      lambdaRatio[22] = lambdaLev5 / lambdaLev1;
+      lambdaRatio[23] = lambdaLev6 / lambdaLev1;
+      lambdaRatio[24] = lambdaLev6 / lambdaLev1;
+      lambdaRatio[25] = lambdaLev4 / lambdaLev1;
+      lambdaRatio[26] = lambdaLev5 / lambdaLev1;
+      lambdaRatio[27] = lambdaLev6 / lambdaLev1;
+      lambdaRatio[28] = lambdaLev6 / lambdaLev1;
+      lambdaRatio[29] = lambdaLev5 / lambdaLev1;
+      lambdaRatio[30] = lambdaLev6 / lambdaLev1;
+      lambdaRatio[31] = lambdaLev6 / lambdaLev1;
     }
     else
     {
@@ -1235,7 +1232,7 @@ double EncRCPic::calAverageLambda()
       {
         totalSSE += m_LCUs[i].m_actualSSE;
         totalPixels += m_LCUs[i].m_numberOfPixel;
-       }
+      }
     }
   }
 
diff --git a/source/Lib/EncoderLib/RateCtrl.h b/source/Lib/EncoderLib/RateCtrl.h
index 078c27125..3c17d6be5 100644
--- a/source/Lib/EncoderLib/RateCtrl.h
+++ b/source/Lib/EncoderLib/RateCtrl.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/EncoderLib/SEIEncoder.cpp b/source/Lib/EncoderLib/SEIEncoder.cpp
index 2190f454f..9ae6a87d8 100644
--- a/source/Lib/EncoderLib/SEIEncoder.cpp
+++ b/source/Lib/EncoderLib/SEIEncoder.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -35,6 +35,7 @@
 #include "CommonLib/SEI.h"
 #include "EncGOP.h"
 #include "EncLib.h"
+#include <fstream>
 
 uint32_t calcMD5(const CPelUnitBuf& pic, PictureHash &digest, const BitDepths &bitDepths);
 uint32_t calcCRC(const CPelUnitBuf& pic, PictureHash &digest, const BitDepths &bitDepths);
@@ -93,10 +94,10 @@ void SEIEncoder::initSEIBufferingPeriod(SEIBufferingPeriod *bufferingPeriodSEI,
   {
     for(int j=0; j < bufferingPeriodSEI->m_bpCpbCnt; j++)
     {
-      bufferingPeriodSEI->m_initialCpbRemovalDelay[j][i][0] = uiInitialCpbRemovalDelay;
-      bufferingPeriodSEI->m_initialCpbRemovalDelay[j][i][1] = uiInitialCpbRemovalDelay;
-      bufferingPeriodSEI->m_initialCpbRemovalOffset[j][i][0] = uiInitialCpbRemovalDelay;
-      bufferingPeriodSEI->m_initialCpbRemovalOffset[j][i][1] = uiInitialCpbRemovalDelay;
+      bufferingPeriodSEI->m_initialCpbRemovalDelay[i][j][0] = uiInitialCpbRemovalDelay;
+      bufferingPeriodSEI->m_initialCpbRemovalDelay[i][j][1] = uiInitialCpbRemovalDelay;
+      bufferingPeriodSEI->m_initialCpbRemovalOffset[i][j][0] = uiInitialCpbRemovalDelay;
+      bufferingPeriodSEI->m_initialCpbRemovalOffset[i][j][1] = uiInitialCpbRemovalDelay;
     }
   }
   // We don't set concatenation_flag here. max_initial_removal_delay_for_concatenation depends on the usage scenario.
@@ -397,7 +398,7 @@ void SEIEncoder::initSEISampleAspectRatioInfo(SEISampleAspectRatioInfo* seiSampl
 //! Note: The SEI message structures input into this function will become part of the scalable nesting SEI and will be
 //!       automatically freed, when the nesting SEI is disposed.
 //  either targetOLS or targetLayer should be active, call with empty vector for the inactive mode
-void SEIEncoder::initSEIScalableNesting(SEIScalableNesting *scalableNestingSEI, SEIMessages &nestedSEIs, const std::vector<int> &targetOLSs, const std::vector<int> &targetLayers, const std::vector<uint16_t> &subpictureIDs)
+void SEIEncoder::initSEIScalableNesting(SEIScalableNesting *scalableNestingSEI, SEIMessages &nestedSEIs, const std::vector<int> &targetOLSs, const std::vector<int> &targetLayers, const std::vector<uint16_t> &subpictureIDs, uint16_t maxSubpicIdInPic)
 {
   CHECK(!(m_isInitialized), "Scalable Nesting SEI already initialized ");
   CHECK(!(scalableNestingSEI != NULL), "No Scalable Nesting SEI object passed");
@@ -442,8 +443,8 @@ void SEIEncoder::initSEIScalableNesting(SEIScalableNesting *scalableNestingSEI,
     scalableNestingSEI->m_snSubpicFlag = 1;
     scalableNestingSEI->m_snNumSubpics = (uint32_t) subpictureIDs.size();
     scalableNestingSEI->m_snSubpicId   = subpictureIDs;
-    scalableNestingSEI->m_snSubpicIdLen = max(1, ceilLog2((*std::max_element(subpictureIDs.begin(), subpictureIDs.end())) + 1));
-    CHECK ( scalableNestingSEI->m_snSubpicIdLen > 15, "Subpicture ID too large. Length must be <= 15 bits");
+    scalableNestingSEI->m_snSubpicIdLen = max(1, ceilLog2(maxSubpicIdInPic + 1));
+    CHECK ( scalableNestingSEI->m_snSubpicIdLen > 16, "Subpicture ID too large. Length must be <= 16 bits");
   }
   scalableNestingSEI->m_nestedSEIs.clear();
   for (SEIMessages::iterator it = nestedSEIs.begin(); it != nestedSEIs.end(); it++)
@@ -460,9 +461,7 @@ void SEIEncoder::initDecodedPictureHashSEI(SEIDecodedPictureHash *decodedPicture
   CHECK(!(decodedPictureHashSEI!=NULL), "Unspecified error");
 
   decodedPictureHashSEI->method = m_pcCfg->getDecodedPictureHashSEIType();
-#if FIX_TICKET_1405
   decodedPictureHashSEI->singleCompFlag = (m_pcCfg->getChromaFormatIdc() == 0);
-#endif
   switch (m_pcCfg->getDecodedPictureHashSEIType())
   {
     case HASHTYPE_MD5:
@@ -493,6 +492,21 @@ void SEIEncoder::initSEIDependentRAPIndication(SEIDependentRAPIndication *seiDep
   CHECK(!(seiDependentRAPIndication!=NULL), "Unspecified error");
 }
 
+void SEIEncoder::initSEIExtendedDrapIndication(SEIExtendedDrapIndication *sei)
+{
+  CHECK(!(m_isInitialized), "Extended DRAP SEI already initialized");
+  CHECK(!(sei!=NULL), "Need a seiExtendedDrapIndication for initialization (got nullptr)");
+  sei->m_edrapIndicationRapIdMinus1 = 0;
+  sei->m_edrapIndicationLeadingPicturesDecodableFlag = false;
+  sei->m_edrapIndicationReservedZero12Bits = 0;
+  sei->m_edrapIndicationNumRefRapPicsMinus1 = 0;
+  sei->m_edrapIndicationRefRapId.resize(sei->m_edrapIndicationNumRefRapPicsMinus1 + 1);
+  for (int i = 0; i <= sei->m_edrapIndicationNumRefRapPicsMinus1; i++)
+  {
+    sei->m_edrapIndicationRefRapId[i] = 0;
+  }
+}
+
 
 template <typename T>
 static void readTokenValue(T            &returnedValue, /// value returned
@@ -562,6 +576,143 @@ static void readTokenValueAndValidate(T            &returnedValue, /// value ret
   }
 }
 
+void SEIEncoder::readAnnotatedRegionSEI(std::istream &fic, SEIAnnotatedRegions *seiAnnoRegion, bool &failed)
+{
+  readTokenValue(seiAnnoRegion->m_hdr.m_cancelFlag, failed, fic, "SEIArCancelFlag");
+  if (!seiAnnoRegion->m_hdr.m_cancelFlag)
+  {
+    readTokenValue(seiAnnoRegion->m_hdr.m_notOptimizedForViewingFlag, failed, fic, "SEIArNotOptForViewingFlag");
+    readTokenValue(seiAnnoRegion->m_hdr.m_trueMotionFlag, failed, fic, "SEIArTrueMotionFlag");
+    readTokenValue(seiAnnoRegion->m_hdr.m_occludedObjectFlag, failed, fic, "SEIArOccludedObjsFlag");
+    readTokenValue(seiAnnoRegion->m_hdr.m_partialObjectFlagPresentFlag, failed, fic, "SEIArPartialObjsFlagPresentFlag");
+    readTokenValue(seiAnnoRegion->m_hdr.m_objectLabelPresentFlag, failed, fic, "SEIArObjLabelPresentFlag");
+    readTokenValue(seiAnnoRegion->m_hdr.m_objectConfidenceInfoPresentFlag, failed, fic, "SEIArObjConfInfoPresentFlag");
+    if (seiAnnoRegion->m_hdr.m_objectConfidenceInfoPresentFlag)
+    {
+      readTokenValueAndValidate<uint32_t>(seiAnnoRegion->m_hdr.m_objectConfidenceLength, failed, fic, "SEIArObjDetConfLength", uint32_t(0), uint32_t(255));
+    }
+    if (seiAnnoRegion->m_hdr.m_objectLabelPresentFlag)
+    {
+      readTokenValue(seiAnnoRegion->m_hdr.m_objectLabelLanguagePresentFlag, failed, fic, "SEIArObjLabelLangPresentFlag");
+      if (seiAnnoRegion->m_hdr.m_objectLabelLanguagePresentFlag)
+      {
+        readTokenValue(seiAnnoRegion->m_hdr.m_annotatedRegionsObjectLabelLang, failed, fic, "SEIArLabelLanguage");
+      }
+      uint32_t numLabelUpdates=0;
+      readTokenValueAndValidate<uint32_t>(numLabelUpdates, failed, fic, "SEIArNumLabelUpdates", uint32_t(0), uint32_t(255));
+      seiAnnoRegion->m_annotatedLabels.resize(numLabelUpdates);
+      for (auto it=seiAnnoRegion->m_annotatedLabels.begin(); it!=seiAnnoRegion->m_annotatedLabels.end(); it++)
+      {
+        SEIAnnotatedRegions::AnnotatedRegionLabel &ar=it->second;
+        readTokenValueAndValidate(it->first, failed, fic, "SEIArLabelIdc[c]", uint32_t(0), uint32_t(255));
+        bool cancelFlag;
+        readTokenValue(cancelFlag, failed, fic, "SEIArLabelCancelFlag[c]");
+        ar.labelValid=!cancelFlag;
+        if (ar.labelValid)
+        {
+          readTokenValue(ar.label, failed, fic, "SEIArLabel[c]");
+        }
+      }
+    }
+
+    uint32_t numObjectUpdates=0;
+    readTokenValueAndValidate<uint32_t>(numObjectUpdates, failed, fic, "SEIArNumObjUpdates", uint32_t(0), uint32_t(255));
+    seiAnnoRegion->m_annotatedRegions.resize(numObjectUpdates);
+    for (auto it=seiAnnoRegion->m_annotatedRegions.begin(); it!=seiAnnoRegion->m_annotatedRegions.end(); it++)
+    {
+      SEIAnnotatedRegions::AnnotatedRegionObject &ar = it->second;
+      readTokenValueAndValidate(it->first, failed, fic, "SEIArObjIdx[c]", uint32_t(0), uint32_t(255));
+      readTokenValue(ar.objectCancelFlag, failed, fic, "SEIArObjCancelFlag[c]");
+      ar.objectLabelValid=false;
+      ar.boundingBoxValid=false;
+      if (!ar.objectCancelFlag)
+      {
+        if (seiAnnoRegion->m_hdr.m_objectLabelPresentFlag)
+        {
+          readTokenValue(ar.objectLabelValid, failed, fic, "SEIArObjLabelUpdateFlag[c]");
+          if (ar.objectLabelValid)
+          {
+            readTokenValueAndValidate<uint32_t>(ar.objLabelIdx, failed, fic, "SEIArObjectLabelIdc[c]", uint32_t(0), uint32_t(255));
+          }
+          readTokenValue(ar.boundingBoxValid, failed, fic, "SEIArBoundBoxUpdateFlag[c]");
+          if (ar.boundingBoxValid)
+          {
+            readTokenValueAndValidate<uint32_t>(ar.boundingBoxTop, failed, fic, "SEIArObjTop[c]", uint32_t(0), uint32_t(0x7fffffff));
+            readTokenValueAndValidate<uint32_t>(ar.boundingBoxLeft, failed, fic, "SEIArObjLeft[c]", uint32_t(0), uint32_t(0x7fffffff));
+            readTokenValueAndValidate<uint32_t>(ar.boundingBoxWidth, failed, fic, "SEIArObjWidth[c]", uint32_t(0), uint32_t(0x7fffffff));
+            readTokenValueAndValidate<uint32_t>(ar.boundingBoxHeight, failed, fic, "SEIArObjHeight[c]", uint32_t(0), uint32_t(0x7fffffff));
+            if (seiAnnoRegion->m_hdr.m_partialObjectFlagPresentFlag)
+            {
+              readTokenValue(ar.partialObjectFlag, failed, fic, "SEIArObjPartUpdateFlag[c]");
+            }
+            if (seiAnnoRegion->m_hdr.m_objectConfidenceInfoPresentFlag)
+            {
+              readTokenValueAndValidate<uint32_t>(ar.objectConfidence, failed, fic, "SEIArObjDetConf[c]", uint32_t(0), uint32_t(1<<seiAnnoRegion->m_hdr.m_objectConfidenceLength)-1);
+            }
+          }
+          //Compare with existing attributes to decide whether it's a static object
+          //First check whether it's an existing object (or) new object
+          auto destIt = m_pcCfg->m_arObjects.find(it->first);
+          //New object
+          if (destIt == m_pcCfg->m_arObjects.end())
+          {
+            //New object arrived, needs to be appended to the map of tracked objects
+            m_pcCfg->m_arObjects[it->first] = ar;
+          }
+          //Existing object
+          else
+          {
+            // Size remains the same
+            if(m_pcCfg->m_arObjects[it->first].boundingBoxWidth == ar.boundingBoxWidth &&
+              m_pcCfg->m_arObjects[it->first].boundingBoxHeight == ar.boundingBoxHeight)
+              {
+                if(m_pcCfg->m_arObjects[it->first].boundingBoxTop == ar.boundingBoxTop &&
+                  m_pcCfg->m_arObjects[it->first].boundingBoxLeft == ar.boundingBoxLeft)
+                  {
+                    ar.boundingBoxValid = 0;
+                  }
+              }
+          }
+        }
+      }
+    }
+  }
+}
+
+bool SEIEncoder::initSEIAnnotatedRegions(SEIAnnotatedRegions* SEIAnnoReg, int currPOC)
+{
+  assert(m_isInitialized);
+  assert(SEIAnnoReg != NULL);
+
+  // reading external Annotated Regions Information SEI message parameters from file
+  if (!m_pcCfg->getAnnotatedRegionSEIFileRoot().empty())
+  {
+    bool failed = false;
+    // building the annotated regions file name with poc num in prefix "_poc.txt"
+    std::string AnnoRegionSEIFileWithPoc(m_pcCfg->getAnnotatedRegionSEIFileRoot());
+    {
+      std::stringstream suffix;
+      suffix << "_" << currPOC << ".txt";
+      AnnoRegionSEIFileWithPoc += suffix.str();
+    }
+    std::ifstream fic(AnnoRegionSEIFileWithPoc.c_str());
+    if (!fic.good() || !fic.is_open())
+    {
+      std::cerr << "No Annotated Regions SEI parameters file " << AnnoRegionSEIFileWithPoc << " for POC " << currPOC << std::endl;
+      return false;
+    }
+    //Read annotated region SEI parameters from the cfg file
+    readAnnotatedRegionSEI(fic, SEIAnnoReg, failed);
+    if (failed)
+    {
+      std::cerr << "Error while reading Annotated Regions SEI parameters file '" << AnnoRegionSEIFileWithPoc << "'" << std::endl;
+      exit(EXIT_FAILURE);
+    }
+  }
+  return true;
+}
+
+
 #if U0033_ALTERNATIVE_TRANSFER_CHARACTERISTICS_SEI
 void SEIEncoder::initSEIAlternativeTransferCharacteristics(SEIAlternativeTransferCharacteristics *seiAltTransCharacteristics)
 {
@@ -660,6 +811,230 @@ void SEIEncoder::initSEIContentColourVolume(SEIContentColourVolume *seiContentCo
     seiContentColourVolume->m_ccvAvgLuminanceValue = (uint32_t)(10000000 * m_pcCfg->getCcvSEIAvgLuminanceValue());
   }
 }
+
+void SEIEncoder::initSEIScalabilityDimensionInfo(SEIScalabilityDimensionInfo *sei)
+{
+  CHECK(!(m_isInitialized), "Scalability dimension information SEI already initialized");
+  CHECK(!(sei != NULL), "Need a seiScalabilityDimensionInfo for initialization (got nullptr)");
+  sei->m_sdiMaxLayersMinus1 = m_pcCfg->getSdiSEIMaxLayersMinus1();
+  sei->m_sdiMultiviewInfoFlag = m_pcCfg->getSdiSEIMultiviewInfoFlag();
+  sei->m_sdiAuxiliaryInfoFlag = m_pcCfg->getSdiSEIAuxiliaryInfoFlag();
+  if (sei->m_sdiMultiviewInfoFlag || sei->m_sdiAuxiliaryInfoFlag)
+  {
+    if (sei->m_sdiMultiviewInfoFlag)
+    {
+      sei->m_sdiViewIdLenMinus1 = m_pcCfg->getSdiSEIViewIdLenMinus1();
+    }
+    sei->m_sdiLayerId.resize(sei->m_sdiMaxLayersMinus1 + 1);
+    for (int i = 0; i <= sei->m_sdiMaxLayersMinus1; i++)
+    {
+      sei->m_sdiLayerId[i] = m_pcCfg->getSdiSEILayerId(i);
+      sei->m_sdiViewIdVal.resize(sei->m_sdiMaxLayersMinus1 + 1);
+      if (sei->m_sdiMultiviewInfoFlag)
+      {
+        sei->m_sdiViewIdVal[i] = m_pcCfg->getSdiSEIViewIdVal(i);
+      }
+      sei->m_sdiAuxId.resize(sei->m_sdiMaxLayersMinus1 + 1);
+      if (sei->m_sdiAuxiliaryInfoFlag)
+      {
+        sei->m_sdiAuxId[i] = m_pcCfg->getSdiSEIAuxId(i);
+        sei->m_sdiNumAssociatedPrimaryLayersMinus1.resize(sei->m_sdiMaxLayersMinus1 + 1);
+        sei->m_sdiAssociatedPrimaryLayerIdx.resize(sei->m_sdiMaxLayersMinus1 + 1);
+        if (sei->m_sdiAuxId[i] > 0)
+        {
+          sei->m_sdiNumAssociatedPrimaryLayersMinus1[i] = m_pcCfg->getSdiSEINumAssociatedPrimaryLayersMinus1(i);
+          sei->m_sdiAssociatedPrimaryLayerIdx[i].resize(sei->m_sdiNumAssociatedPrimaryLayersMinus1[i] + 1);
+          for (int j = 0; j <= sei->m_sdiNumAssociatedPrimaryLayersMinus1[i]; j++)
+          {
+            sei->m_sdiAssociatedPrimaryLayerIdx[i][j] = 0;
+          }
+        }
+      }
+    }
+    sei->m_sdiNumViews = 1;
+    if (sei->m_sdiMultiviewInfoFlag)
+    {
+      for (int i = 1; i <= sei->m_sdiMaxLayersMinus1; i++)
+      {
+        bool newViewFlag = true;
+        for (int j = 0; j < i; j++)
+        {
+          if (sei->m_sdiViewIdVal[i] == sei->m_sdiViewIdVal[j])
+          {
+            newViewFlag = false;
+          }
+        }
+        if (newViewFlag)
+        {
+          sei->m_sdiNumViews++;
+        }
+      }
+    }
+  }
+}
+
+void SEIEncoder::initSEIMultiviewAcquisitionInfo(SEIMultiviewAcquisitionInfo *sei)
+{
+  CHECK(!(m_isInitialized), "Multiview acquisition information SEI already initialized");
+  CHECK(!(sei != NULL), "Need a seiMultiviewAcquisitionInfo for initialization (got nullptr)");
+  sei->m_maiIntrinsicParamFlag        = m_pcCfg->getMaiSEIIntrinsicParamFlag();
+  sei->m_maiExtrinsicParamFlag        = m_pcCfg->getMaiSEIExtrinsicParamFlag();
+  sei->m_maiNumViewsMinus1            = m_pcCfg->getMaiSEINumViewsMinus1();
+  if (sei->m_maiIntrinsicParamFlag)
+  {
+    sei->m_maiIntrinsicParamsEqualFlag  = m_pcCfg->getMaiSEIIntrinsicParamsEqualFlag();
+    sei->m_maiPrecFocalLength           = m_pcCfg->getMaiSEIPrecFocalLength();
+    sei->m_maiPrecPrincipalPoint        = m_pcCfg->getMaiSEIPrecPrincipalPoint();
+    sei->m_maiPrecSkewFactor            = m_pcCfg->getMaiSEIPrecSkewFactor();
+    int numViews = sei->m_maiIntrinsicParamsEqualFlag ? 1 : sei->m_maiNumViewsMinus1 + 1;
+    sei->m_maiSignFocalLengthX       .resize( numViews );
+    sei->m_maiExponentFocalLengthX   .resize( numViews );
+    sei->m_maiMantissaFocalLengthX   .resize( numViews );
+    sei->m_maiSignFocalLengthY       .resize( numViews );
+    sei->m_maiExponentFocalLengthY   .resize( numViews );
+    sei->m_maiMantissaFocalLengthY   .resize( numViews );
+    sei->m_maiSignPrincipalPointX    .resize( numViews );
+    sei->m_maiExponentPrincipalPointX.resize( numViews );
+    sei->m_maiMantissaPrincipalPointX.resize( numViews );
+    sei->m_maiSignPrincipalPointY    .resize( numViews );
+    sei->m_maiExponentPrincipalPointY.resize( numViews );
+    sei->m_maiMantissaPrincipalPointY.resize( numViews );
+    sei->m_maiSignSkewFactor         .resize( numViews );
+    sei->m_maiExponentSkewFactor     .resize( numViews );
+    sei->m_maiMantissaSkewFactor     .resize( numViews );
+    for( int i = 0; i  <=  ( sei->m_maiIntrinsicParamsEqualFlag ? 0 : sei->m_maiNumViewsMinus1 ); i++ )
+    {
+      sei->m_maiSignFocalLengthX       [i] = m_pcCfg->getMaiSEISignFocalLengthX(i);
+      sei->m_maiExponentFocalLengthX   [i] = m_pcCfg->getMaiSEIExponentFocalLengthX(i);
+      sei->m_maiMantissaFocalLengthX   [i] = m_pcCfg->getMaiSEIMantissaFocalLengthX(i);
+      sei->m_maiSignFocalLengthY       [i] = m_pcCfg->getMaiSEISignFocalLengthY(i);
+      sei->m_maiExponentFocalLengthY   [i] = m_pcCfg->getMaiSEIExponentFocalLengthY(i);
+      sei->m_maiMantissaFocalLengthY   [i] = m_pcCfg->getMaiSEIMantissaFocalLengthY(i);
+      sei->m_maiSignPrincipalPointX    [i] = m_pcCfg->getMaiSEISignPrincipalPointX(i);
+      sei->m_maiExponentPrincipalPointX[i] = m_pcCfg->getMaiSEIExponentPrincipalPointX(i);
+      sei->m_maiMantissaPrincipalPointX[i] = m_pcCfg->getMaiSEIMantissaPrincipalPointX(i);
+      sei->m_maiSignPrincipalPointY    [i] = m_pcCfg->getMaiSEISignPrincipalPointY(i);
+      sei->m_maiExponentPrincipalPointY[i] = m_pcCfg->getMaiSEIExponentPrincipalPointY(i);
+      sei->m_maiMantissaPrincipalPointY[i] = m_pcCfg->getMaiSEIMantissaPrincipalPointY(i);
+      sei->m_maiSignSkewFactor         [i] = m_pcCfg->getMaiSEISignSkewFactor(i);
+      sei->m_maiExponentSkewFactor     [i] = m_pcCfg->getMaiSEIExponentSkewFactor(i);
+      sei->m_maiMantissaSkewFactor     [i] = m_pcCfg->getMaiSEIMantissaSkewFactor(i);
+    }
+  }
+  if (sei->m_maiExtrinsicParamFlag)
+  {
+    sei->m_maiPrecRotationParam = m_pcCfg->getMaiSEIPrecRotationParam();
+    sei->m_maiPrecTranslationParam = m_pcCfg->getMaiSEIPrecTranslationParam();
+    sei->m_maiSignR.resize(sei->m_maiNumViewsMinus1 + 1);
+    sei->m_maiExponentR.resize(sei->m_maiNumViewsMinus1 + 1);
+    sei->m_maiMantissaR.resize(sei->m_maiNumViewsMinus1 + 1);
+    sei->m_maiSignT.resize(sei->m_maiNumViewsMinus1 + 1);
+    sei->m_maiExponentT.resize(sei->m_maiNumViewsMinus1 + 1);
+    sei->m_maiMantissaT.resize(sei->m_maiNumViewsMinus1 + 1);
+    for (int i = 0; i <= sei->m_maiNumViewsMinus1; i++)
+    {
+      sei->m_maiSignR[i].resize(3);
+      sei->m_maiExponentR[i].resize(3);
+      sei->m_maiMantissaR[i].resize(3);
+      sei->m_maiSignT[i].resize(3);
+      sei->m_maiExponentT[i].resize(3);
+      sei->m_maiMantissaT[i].resize(3);
+      for (int j = 0; j < 3; j++)
+      {
+        sei->m_maiSignR[i][j].resize(3);
+        sei->m_maiExponentR[i][j].resize(3);
+        sei->m_maiMantissaR[i][j].resize(3);
+        for (int k = 0; k < 3; k++)
+        {
+          sei->m_maiSignR[i][j][k] = 0;
+          sei->m_maiExponentR[i][j][k] = 0;
+          sei->m_maiMantissaR[i][j][k] = 0;
+        }
+        sei->m_maiSignT[i][j] = 0;
+        sei->m_maiExponentT[i][j] = 0;
+        sei->m_maiMantissaT[i][j] = 0;
+      }
+    }
+  }
+}
+
+#if JVET_W0078_MVP_SEI 
+void SEIEncoder::initSEIMultiviewViewPosition(SEIMultiviewViewPosition *sei)
+{
+  CHECK(!(m_isInitialized), "Multiview view position SEI already initialized");
+  CHECK(!(sei != NULL), "Need a seiMultiviewViewPosition for initialization (got nullptr)");
+  sei->m_mvpNumViewsMinus1 = m_pcCfg->getMvpSEINumViewsMinus1();
+
+  int numViews = sei->m_mvpNumViewsMinus1 + 1;
+  sei->m_mvpViewPosition.resize(numViews);
+  for (int i = 0; i <= sei->m_mvpNumViewsMinus1; i++)
+  {
+    sei->m_mvpViewPosition[i] = m_pcCfg->getMvpSEIViewPosition(i);
+  }
+}
+#endif
+
+void SEIEncoder::initSEIAlphaChannelInfo(SEIAlphaChannelInfo *sei)
+{
+  CHECK(!(m_isInitialized), "Alpha channel information SEI already initialized");
+  CHECK(!(sei != NULL), "Need a seiAlphaChannelInfo for initialization (got nullptr)");
+  sei->m_aciCancelFlag = m_pcCfg->getAciSEICancelFlag();
+  sei->m_aciUseIdc = m_pcCfg->getAciSEIUseIdc();
+  sei->m_aciBitDepthMinus8 = m_pcCfg->getAciSEIBitDepthMinus8();
+  sei->m_aciTransparentValue = m_pcCfg->getAciSEITransparentValue();
+  sei->m_aciOpaqueValue = m_pcCfg->getAciSEIOpaqueValue();
+  sei->m_aciIncrFlag = m_pcCfg->getAciSEIIncrFlag();
+  sei->m_aciClipFlag = m_pcCfg->getAciSEIClipFlag();
+  sei->m_aciClipTypeFlag = m_pcCfg->getAciSEIClipTypeFlag();
+}
+
+void SEIEncoder::initSEIDepthRepresentationInfo(SEIDepthRepresentationInfo *sei)
+{
+  CHECK(!(m_isInitialized), "Depth representation information SEI already initialized");
+  CHECK(!(sei != NULL), "Need a seiDepthRepresentationInfo for initialization (got nullptr)");
+  sei->m_driZNearFlag = m_pcCfg->getDriSEIZNearFlag();
+  sei->m_driZFarFlag = m_pcCfg->getDriSEIZFarFlag();
+  sei->m_driDMinFlag = m_pcCfg->getDriSEIDMinFlag();
+  sei->m_driDMaxFlag = m_pcCfg->getDriSEIDMaxFlag();
+  sei->m_driZNear = m_pcCfg->getDriSEIZNear();
+  sei->m_driZFar = m_pcCfg->getDriSEIZFar();
+  sei->m_driDMin = m_pcCfg->getDriSEIDMin();
+  sei->m_driDMax = m_pcCfg->getDriSEIDMax();
+  sei->m_driDisparityRefViewId = m_pcCfg->getDriSEIDisparityRefViewId();
+  sei->m_driDepthRepresentationType = m_pcCfg->getDriSEIDepthRepresentationType();
+  sei->m_driDepthNonlinearRepresentationNumMinus1 = m_pcCfg->getDriSEINonlinearNumMinus1();
+  sei->m_driDepthNonlinearRepresentationModel.resize(sei->m_driDepthNonlinearRepresentationNumMinus1 + 1);
+  for(int i = 0; i < (sei->m_driDepthNonlinearRepresentationNumMinus1 + 1); i++)
+  {
+    sei->m_driDepthNonlinearRepresentationModel[i] = m_pcCfg->getDriSEINonlinearModel(i);
+  }
+}
+
+void SEIEncoder::initSEIColourTransformInfo(SEIColourTransformInfo* seiCTI)
+{
+  CHECK(!(m_isInitialized), "Unspecified error");
+  CHECK(!(seiCTI != NULL), "Unspecified error");
+
+  //  Set SEI message parameters read from command line options
+  seiCTI->m_id = m_pcCfg->getCtiSEIId();
+  seiCTI->m_signalInfoFlag = m_pcCfg->getCtiSEISignalInfoFlag();
+  seiCTI->m_fullRangeFlag = m_pcCfg->getCtiSEIFullRangeFlag();
+  seiCTI->m_primaries = m_pcCfg->getCtiSEIPrimaries();
+  seiCTI->m_transferFunction = m_pcCfg->getCtiSEITransferFunction();
+  seiCTI->m_matrixCoefs = m_pcCfg->getCtiSEIMatrixCoefs();
+  seiCTI->m_crossComponentFlag = m_pcCfg->getCtiSEICrossComponentFlag();
+  seiCTI->m_crossComponentInferred = m_pcCfg->getCtiSEICrossComponentInferred();
+  seiCTI->m_numberChromaLutMinus1 = m_pcCfg->getCtiSEINbChromaLut() - 1;
+  seiCTI->m_chromaOffset = m_pcCfg->getCtiSEIChromaOffset();
+
+  seiCTI->m_bitdepth = m_pcCfg->getBitDepth(CHANNEL_TYPE_LUMA);
+
+  for (int i = 0; i < MAX_NUM_COMPONENT; i++) {
+    seiCTI->m_lut[i] = m_pcCfg->getCtiSEILut(i);
+  }
+  seiCTI->m_log2NumberOfPointsPerLut = floorLog2(seiCTI->m_lut[0].numLutValues - 1);
+}
+
 void SEIEncoder::initSEISubpictureLevelInfo(SEISubpicureLevelInfo *sei, const SPS *sps)
 {
   const EncCfgParam::CfgSEISubpictureLevel &cfgSubPicLevel = m_pcCfg->getSubpicureLevelInfoSEICfg();
diff --git a/source/Lib/EncoderLib/SEIEncoder.h b/source/Lib/EncoderLib/SEIEncoder.h
index 0fc26901d..c608bb57a 100644
--- a/source/Lib/EncoderLib/SEIEncoder.h
+++ b/source/Lib/EncoderLib/SEIEncoder.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -68,11 +68,12 @@ public:
   void initSEIFramePacking(SEIFramePacking *sei, int currPicNum);
   void initSEIParameterSetsInclusionIndication(SEIParameterSetsInclusionIndication* sei);
   void initSEIDependentRAPIndication(SEIDependentRAPIndication *sei);
+  void initSEIExtendedDrapIndication(SEIExtendedDrapIndication *sei);
   void initSEIBufferingPeriod(SEIBufferingPeriod *sei, bool noLeadingPictures);
 #if U0033_ALTERNATIVE_TRANSFER_CHARACTERISTICS_SEI
   void initSEIAlternativeTransferCharacteristics(SEIAlternativeTransferCharacteristics *sei);
 #endif
-  void initSEIScalableNesting(SEIScalableNesting *scalableNestingSEI, SEIMessages &nestedSEIs, const std::vector<int> &targetOLSs, const std::vector<int> &targetLayers, const std::vector<uint16_t> &subpictureIDs);
+  void initSEIScalableNesting(SEIScalableNesting *scalableNestingSEI, SEIMessages &nestedSEIs, const std::vector<int> &targetOLSs, const std::vector<int> &targetLayers, const std::vector<uint16_t> &subpictureIDs, uint16_t maxSubpicIdInPic);
   void initDecodedPictureHashSEI(SEIDecodedPictureHash *sei, PelUnitBuf& pic, std::string &rHashString, const BitDepths &bitDepths);
   void initSEIErp(SEIEquirectangularProjection *sei);
   void initSEISphereRotation(SEISphereRotation *sei);
@@ -86,6 +87,16 @@ public:
   void initSEIContentLightLevel(SEIContentLightLevelInfo *sei);
   void initSEIAmbientViewingEnvironment(SEIAmbientViewingEnvironment *sei);
   void initSEIContentColourVolume(SEIContentColourVolume *sei);
+  void initSEIScalabilityDimensionInfo(SEIScalabilityDimensionInfo *sei);
+  void initSEIMultiviewAcquisitionInfo(SEIMultiviewAcquisitionInfo *sei);
+  void initSEIAlphaChannelInfo(SEIAlphaChannelInfo *sei);
+  void initSEIDepthRepresentationInfo(SEIDepthRepresentationInfo *sei);
+  bool initSEIAnnotatedRegions(SEIAnnotatedRegions *sei, int currPOC);
+  void initSEIColourTransformInfo(SEIColourTransformInfo* sei);
+  void readAnnotatedRegionSEI(std::istream &fic, SEIAnnotatedRegions *seiAnnoRegion, bool &failed);
+#if JVET_W0078_MVP_SEI
+  void initSEIMultiviewViewPosition(SEIMultiviewViewPosition *sei);
+#endif
 private:
   EncCfg* m_pcCfg;
   EncLib* m_pcEncLib;
diff --git a/source/Lib/EncoderLib/SEIwrite.cpp b/source/Lib/EncoderLib/SEIwrite.cpp
index e28979555..9719068e0 100644
--- a/source/Lib/EncoderLib/SEIwrite.cpp
+++ b/source/Lib/EncoderLib/SEIwrite.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -77,9 +77,15 @@ void SEIWriter::xWriteSEIpayloadData(OutputBitstream &bs, const SEI& sei, HRD &h
   case SEI::DEPENDENT_RAP_INDICATION:
     xWriteSEIDependentRAPIndication(*static_cast<const SEIDependentRAPIndication*>(&sei));
     break;
+  case SEI::EXTENDED_DRAP_INDICATION:
+    xWriteSEIEdrapIndication(*static_cast<const SEIExtendedDrapIndication*>(&sei));
+    break;
   case SEI::FRAME_PACKING:
     xWriteSEIFramePacking(*static_cast<const SEIFramePacking*>(&sei));
     break;
+  case SEI::DISPLAY_ORIENTATION:
+    xWriteSEIDisplayOrientation(*static_cast<const SEIDisplayOrientation*>(&sei));
+    break;
   case SEI::PARAMETER_SETS_INCLUSION_INDICATION:
     xWriteSEIParameterSetsInclusionIndication(*static_cast<const SEIParameterSetsInclusionIndication*>(&sei));
     break;
@@ -106,6 +112,23 @@ void SEIWriter::xWriteSEIpayloadData(OutputBitstream &bs, const SEI& sei, HRD &h
   case SEI::GENERALIZED_CUBEMAP_PROJECTION:
     xWriteSEIGeneralizedCubemapProjection(*static_cast<const SEIGeneralizedCubemapProjection*>(&sei));
     break;
+  case SEI::SCALABILITY_DIMENSION_INFO:
+    xWriteSEIScalabilityDimensionInfo(*static_cast<const SEIScalabilityDimensionInfo*>(&sei));
+    break;
+  case SEI::MULTIVIEW_ACQUISITION_INFO:
+    xWriteSEIMultiviewAcquisitionInfo(*static_cast<const SEIMultiviewAcquisitionInfo*>(&sei));
+    break;
+#if JVET_W0078_MVP_SEI 
+  case SEI::MULTIVIEW_VIEW_POSITION:
+    xWriteSEIMultiviewViewPosition(*static_cast<const SEIMultiviewViewPosition*>(&sei));
+    break;
+#endif
+  case SEI::ALPHA_CHANNEL_INFO:
+    xWriteSEIAlphaChannelInfo(*static_cast<const SEIAlphaChannelInfo*>(&sei));
+    break;
+  case SEI::DEPTH_REPRESENTATION_INFO:
+    xWriteSEIDepthRepresentationInfo(*static_cast<const SEIDepthRepresentationInfo*>(&sei));
+    break;
   case SEI::USER_DATA_REGISTERED_ITU_T_T35:
     xWriteSEIUserDataRegistered(*static_cast<const SEIUserDataRegistered*>(&sei));
     break;
@@ -121,12 +144,23 @@ void SEIWriter::xWriteSEIpayloadData(OutputBitstream &bs, const SEI& sei, HRD &h
   case SEI::CONTENT_COLOUR_VOLUME:
     xWriteSEIContentColourVolume(*static_cast<const SEIContentColourVolume*>(&sei));
     break;
+  case SEI::COLOUR_TRANSFORM_INFO:
+    xWriteSEIColourTransformInfo(*static_cast<const SEIColourTransformInfo*>(&sei));
+    break;
   case SEI::SUBPICTURE_LEVEL_INFO:
     xWriteSEISubpictureLevelInfo(*static_cast<const SEISubpicureLevelInfo*>(&sei));
     break;
   case SEI::SAMPLE_ASPECT_RATIO_INFO:
     xWriteSEISampleAspectRatioInfo(*static_cast<const SEISampleAspectRatioInfo*>(&sei));
     break;
+  case SEI::ANNOTATED_REGIONS:
+    xWriteSEIAnnotatedRegions(*static_cast<const SEIAnnotatedRegions*>(&sei));
+    break;
+#if JVET_W0133_CONSTRAINED_RASL_ENCODING
+  case SEI::CONSTRAINED_RASL_ENCODING:
+    xWriteSEIConstrainedRaslIndication(*static_cast<const SEIConstrainedRaslIndication*>(&sei));
+    break;
+#endif
   default:
     THROW("Trying to write unhandled SEI message");
     break;
@@ -228,10 +262,8 @@ void SEIWriter::xWriteSEIDecodedPictureHash(const SEIDecodedPictureHash& sei)
   if (traceString != 0) //use of this variable is needed to avoid a compiler error with G++ 4.6.1
   {
     WRITE_CODE(sei.method, 8, "dph_sei_hash_type");
-#if FIX_TICKET_1405
     WRITE_CODE(sei.singleCompFlag, 1, "dph_sei_single_component_flag");
     WRITE_CODE(0, 7, "dph_sei_reserved_zero_7bits");
-#endif
     for(uint32_t i=0; i<uint32_t(sei.m_pictureHash.hash.size()); i++)
     {
       WRITE_CODE(sei.m_pictureHash.hash[i], 8, traceString);
@@ -255,10 +287,11 @@ void SEIWriter::xWriteSEIDecodingUnitInfo(const SEIDecodingUnitInfo& sei, const
         WRITE_CODE( sei.m_duSptCpbRemovalDelayIncrement[i], bp.getDuCpbRemovalDelayIncrementLength(), "du_spt_cpb_removal_delay_increment[i]");
     }
   }
-  if (bp.m_decodingUnitDpbDuParamsInPicTimingSeiFlag)
+  if (!bp.m_decodingUnitDpbDuParamsInPicTimingSeiFlag)
   {
     WRITE_FLAG(sei.m_dpbOutputDuDelayPresentFlag, "dpb_output_du_delay_present_flag");
   }
+ 
   if(sei.m_dpbOutputDuDelayPresentFlag)
   {
     WRITE_CODE(sei.m_picSptDpbOutputDuDelay, bp.getDpbOutputDelayDuLength(), "pic_spt_dpb_output_du_delay");
@@ -328,13 +361,13 @@ void SEIWriter::xWriteSEIBufferingPeriod(const SEIBufferingPeriod& sei)
       {
         for( int j = 0; j < sei.m_bpCpbCnt; j ++ )
         {
-          WRITE_CODE( sei.m_initialCpbRemovalDelay[j][i][nalOrVcl],  sei.m_initialCpbRemovalDelayLength,           "initial_cpb_removal_delay[j][i][nalOrVcl]" );
-          WRITE_CODE( sei.m_initialCpbRemovalOffset[j][i][nalOrVcl], sei.m_initialCpbRemovalDelayLength,           "initial_cpb_removal_delay_offset[j][i][nalOrVcl]" );
+          WRITE_CODE( sei.m_initialCpbRemovalDelay[i][j][nalOrVcl],  sei.m_initialCpbRemovalDelayLength,           "initial_cpb_removal_delay[i][j][nalOrVcl]" );
+          WRITE_CODE( sei.m_initialCpbRemovalOffset[i][j][nalOrVcl], sei.m_initialCpbRemovalDelayLength,           "initial_cpb_removal_delay_offset[i][j][nalOrVcl]" );
         }
       }
     }
   }
-  if (sei.m_bpMaxSubLayers-1 > 0) 
+  if (sei.m_bpMaxSubLayers-1 > 0)
   {
     WRITE_FLAG(sei.m_sublayerDpbOutputOffsetsPresentFlag, "bp_sublayer_dpb_output_offsets_present_flag");
   }
@@ -453,11 +486,7 @@ void SEIWriter::xWriteSEIPictureTiming(const SEIPictureTiming& sei, const SEIBuf
       }
     }
   }
-#if !JVET_S0175_ASPECT5
-  WRITE_UVLC( sei.m_ptDisplayElementalPeriodsMinus1,          "pt_display_elemental_periods_minus1" );
-#else
   WRITE_CODE( sei.m_ptDisplayElementalPeriodsMinus1, 8,       "pt_display_elemental_periods_minus1" );
-#endif
 }
 
 void SEIWriter::xWriteSEIFrameFieldInfo(const SEIFrameFieldInfo& sei)
@@ -479,11 +508,7 @@ void SEIWriter::xWriteSEIFrameFieldInfo(const SEIFrameFieldInfo& sei)
     {
       WRITE_FLAG( sei.m_topFieldFirstFlag ? 1 : 0,            "ffi_top_field_first_flag" );
     }
-#if !JVET_S0175_ASPECT5
-    WRITE_UVLC( sei.m_displayElementalPeriodsMinus1,          "ffi_display_elemental_periods_minus1" );
-#else
     WRITE_CODE( sei.m_displayElementalPeriodsMinus1, 8,       "ffi_display_elemental_periods_minus1" );
-#endif
   }
   WRITE_CODE( sei.m_sourceScanType, 2,                        "ffi_source_scan_type" );
   WRITE_FLAG( sei.m_duplicateFlag ? 1 : 0,                    "ffi_duplicate_flag" );
@@ -494,6 +519,18 @@ void SEIWriter::xWriteSEIDependentRAPIndication(const SEIDependentRAPIndication&
   // intentionally empty
 }
 
+void SEIWriter::xWriteSEIEdrapIndication(const SEIExtendedDrapIndication& sei)
+{
+  WRITE_CODE( sei.m_edrapIndicationRapIdMinus1, 16,        "edrap_rap_id_minsu1" );
+  WRITE_FLAG( sei.m_edrapIndicationLeadingPicturesDecodableFlag ? 1 : 0, "edrap_leading_pictures_decodable_flag" );
+  WRITE_CODE( sei.m_edrapIndicationReservedZero12Bits, 12, "edrap_reserved_zero_12bits" );
+  WRITE_CODE( sei.m_edrapIndicationNumRefRapPicsMinus1, 3, "edrap_num_ref_rap_pics_minus1" );
+  for (int i = 0; i <= sei.m_edrapIndicationNumRefRapPicsMinus1; i++)
+  {
+    WRITE_CODE( sei.m_edrapIndicationRefRapId[i], 16, "edrap_ref_rap_id[i]" );
+  }
+}
+
 void SEIWriter::xWriteSEIScalableNesting(OutputBitstream& bs, const SEIScalableNesting& sei)
 {
   CHECK (sei.m_nestedSEIs.size()<1, "There must be at lease one SEI message nested in the scalable nesting SEI.")
@@ -585,6 +622,18 @@ void SEIWriter::xWriteSEIFramePacking(const SEIFramePacking& sei)
 }
 
 
+void SEIWriter::xWriteSEIDisplayOrientation(const SEIDisplayOrientation& sei)
+{
+  WRITE_FLAG(sei.m_doCancelFlag, "display_orientation_cancel_flag");
+
+  if (sei.m_doCancelFlag == 0)
+  {
+    WRITE_FLAG(sei.m_doPersistenceFlag, "display_orientation_persistence_flag");
+    WRITE_CODE(sei.m_doTransformType, 3, "display_orientation_transform_type");
+    WRITE_CODE(0, 3, "display_orientation_reserved_zero_3bits");
+  }
+}
+
 void SEIWriter::xWriteSEIParameterSetsInclusionIndication(const SEIParameterSetsInclusionIndication& sei)
 {
   WRITE_FLAG(sei.m_selfContainedClvsFlag, "psii_self_contained_clvs_flag");
@@ -608,6 +657,96 @@ void SEIWriter::xWriteSEIMasteringDisplayColourVolume(const SEIMasteringDisplayC
   WRITE_CODE( sei.values.minLuminance,     32,  "mdcv_min_display_mastering_luminance" );
 }
 
+void SEIWriter::xWriteSEIAnnotatedRegions(const SEIAnnotatedRegions &sei)
+{
+  WRITE_FLAG(sei.m_hdr.m_cancelFlag, "ar_cancel_flag");
+  if (!sei.m_hdr.m_cancelFlag)
+  {
+    WRITE_FLAG(sei.m_hdr.m_notOptimizedForViewingFlag, "ar_not_optimized_for_viewing_flag");
+    WRITE_FLAG(sei.m_hdr.m_trueMotionFlag, "ar_true_motion_flag");
+    WRITE_FLAG(sei.m_hdr.m_occludedObjectFlag, "ar_occluded_object_flag");
+    WRITE_FLAG(sei.m_hdr.m_partialObjectFlagPresentFlag, "ar_partial_object_flag_present_flag");
+    WRITE_FLAG(sei.m_hdr.m_objectLabelPresentFlag, "ar_object_label_present_flag");
+    WRITE_FLAG(sei.m_hdr.m_objectConfidenceInfoPresentFlag, "ar_object_confidence_info_present_flag");
+    if (sei.m_hdr.m_objectConfidenceInfoPresentFlag)
+    {
+      assert(sei.m_hdr.m_objectConfidenceLength <= 16 && sei.m_hdr.m_objectConfidenceLength>0);
+      WRITE_CODE((sei.m_hdr.m_objectConfidenceLength - 1), 4, "ar_object_confidence_length_minus_1");
+    }
+    if (sei.m_hdr.m_objectLabelPresentFlag)
+    {
+      WRITE_FLAG(sei.m_hdr.m_objectLabelLanguagePresentFlag, "ar_object_label_language_present_flag");
+      if (sei.m_hdr.m_objectLabelLanguagePresentFlag)
+      {
+        xWriteByteAlign();
+        assert(sei.m_hdr.m_annotatedRegionsObjectLabelLang.size()<256);
+        for (uint32_t j = 0; j < sei.m_hdr.m_annotatedRegionsObjectLabelLang.size(); j++)
+        {
+          char ch = sei.m_hdr.m_annotatedRegionsObjectLabelLang[j];
+          WRITE_CODE(ch, 8, "ar_object_label_language");
+        }
+        WRITE_CODE('\0', 8, "ar_label_language");
+      }
+    }
+    WRITE_UVLC((uint32_t)sei.m_annotatedLabels.size(), "ar_num_label_updates");
+    assert(sei.m_annotatedLabels.size()<256);
+    for(auto it=sei.m_annotatedLabels.begin(); it!=sei.m_annotatedLabels.end(); it++)
+    {
+      assert(it->first < 256);
+      WRITE_UVLC(it->first, "ar_label_idx[]");
+      const SEIAnnotatedRegions::AnnotatedRegionLabel &ar=it->second;
+      WRITE_FLAG(!ar.labelValid, "ar_label_cancel_flag");
+      if (ar.labelValid)
+      {
+        xWriteByteAlign();
+        assert(ar.label.size()<256);
+        for (uint32_t j = 0; j < ar.label.size(); j++)
+        {
+          char ch = ar.label[j];
+          WRITE_CODE(ch, 8, "ar_label[]");
+        }
+        WRITE_CODE('\0', 8, "ar_label[]");
+      }
+    }
+    WRITE_UVLC((uint32_t)sei.m_annotatedRegions.size(), "ar_num_object_updates");
+    assert(sei.m_annotatedRegions.size()<256);
+    for (auto it=sei.m_annotatedRegions.begin(); it!=sei.m_annotatedRegions.end(); it++)
+    {
+      const SEIAnnotatedRegions::AnnotatedRegionObject &ar = it->second;
+      WRITE_UVLC(it->first, "ar_object_idx");
+      WRITE_FLAG(ar.objectCancelFlag, "ar_object_cancel_flag");
+      if (!ar.objectCancelFlag)
+      {
+        if (sei.m_hdr.m_objectLabelPresentFlag)
+        {
+          WRITE_FLAG(ar.objectLabelValid, "ar_object_label_update_flag");
+          if (ar.objectLabelValid)
+          {
+            assert(ar.objLabelIdx<256);
+            WRITE_UVLC(ar.objLabelIdx, "ar_object_label_idx");
+          }
+        }
+        WRITE_FLAG(ar.boundingBoxValid, "ar_object_bounding_box_update_flag");
+        if (ar.boundingBoxValid)
+        {
+          WRITE_CODE(ar.boundingBoxTop,   16, "ar_bounding_box_top");
+          WRITE_CODE(ar.boundingBoxLeft,  16, "ar_bounding_box_left");
+          WRITE_CODE(ar.boundingBoxWidth, 16, "ar_bounding_box_width");
+          WRITE_CODE(ar.boundingBoxHeight,16, "ar_bounding_box_height");
+          if (sei.m_hdr.m_partialObjectFlagPresentFlag)
+          {
+            WRITE_UVLC(ar.partialObjectFlag, "ar_partial_object_flag");
+          }
+          if (sei.m_hdr.m_objectConfidenceInfoPresentFlag)
+          {
+            assert(ar.objectConfidence < (1<<sei.m_hdr.m_objectConfidenceLength));
+            WRITE_CODE(ar.objectConfidence, sei.m_hdr.m_objectConfidenceLength, "ar_object_confidence");
+          }
+        }
+      }
+    }
+  }
+}
 void SEIWriter::xWriteByteAlign()
 {
   if( m_pcBitIf->getNumberOfWrittenBits() % 8 != 0)
@@ -752,6 +891,245 @@ void SEIWriter::xWriteSEIGeneralizedCubemapProjection(const SEIGeneralizedCubema
   }
 }
 
+void SEIWriter::xWriteSEIScalabilityDimensionInfo(const SEIScalabilityDimensionInfo &sei)
+{
+  WRITE_CODE(sei.m_sdiMaxLayersMinus1, 6,                           "sdi_max_layers_minus1");
+  WRITE_FLAG(sei.m_sdiMultiviewInfoFlag,                            "sdi_multiview_info_flag");
+  WRITE_FLAG(sei.m_sdiAuxiliaryInfoFlag,                            "sdi_auxiliary_info_flag");
+  if (sei.m_sdiMultiviewInfoFlag || sei.m_sdiAuxiliaryInfoFlag)
+  {
+    if (sei.m_sdiMultiviewInfoFlag)
+    {
+      WRITE_CODE(sei.m_sdiViewIdLenMinus1, 4,                              "sdi_view_id_len_minus1");
+    }
+    for (int i = 0; i <= sei.m_sdiMaxLayersMinus1; i++)
+    {
+      WRITE_CODE(sei.m_sdiLayerId[i], 6,                                         "sdi_layer_id");
+      if (sei.m_sdiMultiviewInfoFlag)
+      {
+        WRITE_CODE(sei.m_sdiViewIdVal[i], sei.m_sdiViewIdLenMinus1 + 1,       "sdi_view_id_val");
+      }
+      if (sei.m_sdiAuxiliaryInfoFlag)
+      {
+        WRITE_CODE(sei.m_sdiAuxId[i], 8,                           "sdi_aux_id");
+        if (sei.m_sdiAuxId[i] > 0)
+        {
+          WRITE_CODE(sei.m_sdiNumAssociatedPrimaryLayersMinus1[i], 6,          "sdi_num_associated_primary_layers_minus1");
+          for (int j = 0; j <= sei.m_sdiNumAssociatedPrimaryLayersMinus1[i]; j++)
+          {
+            WRITE_CODE(sei.m_sdiAssociatedPrimaryLayerIdx[i][j], 6,               "sdi_associated_primary_layer_idx");
+          }
+        }
+      }
+    }
+  }
+}
+
+void SEIWriter::xWriteSEIMultiviewAcquisitionInfo(const SEIMultiviewAcquisitionInfo& sei)
+{
+  WRITE_FLAG( ( sei.m_maiIntrinsicParamFlag ? 1 : 0 ), "intrinsic_param_flag" );
+  WRITE_FLAG( ( sei.m_maiExtrinsicParamFlag ? 1 : 0 ), "extrinsic_param_flag" );
+  WRITE_UVLC(   sei.m_maiNumViewsMinus1               , "num_views_minus1"           );
+  if( sei.m_maiIntrinsicParamFlag )
+  {
+    WRITE_FLAG( ( sei.m_maiIntrinsicParamsEqualFlag ? 1 : 0 ), "intrinsic_params_equal_flag" );
+    WRITE_UVLC(   sei.m_maiPrecFocalLength                   , "prec_focal_length"           );
+    WRITE_UVLC(   sei.m_maiPrecPrincipalPoint                , "prec_principal_point"        );
+    WRITE_UVLC(   sei.m_maiPrecSkewFactor                    , "prec_skew_factor"            );
+
+    for( int i = 0; i  <=  ( sei.m_maiIntrinsicParamsEqualFlag ? 0 : sei.m_maiNumViewsMinus1 ); i++ )
+    {
+      WRITE_FLAG( ( sei.m_maiSignFocalLengthX       [i] ? 1 : 0 ),                                         "sign_focal_length_x"        );
+      WRITE_CODE(   sei.m_maiExponentFocalLengthX   [i]          , 6                                  ,    "exponent_focal_length_x"    );
+      WRITE_CODE(   sei.m_maiMantissaFocalLengthX   [i]          , sei.getMantissaFocalLengthXLen( i ),    "mantissa_focal_length_x"    );
+      WRITE_FLAG( ( sei.m_maiSignFocalLengthY       [i] ? 1 : 0 ),                                         "sign_focal_length_y"        );
+      WRITE_CODE(   sei.m_maiExponentFocalLengthY   [i]          , 6                                  ,    "exponent_focal_length_y"    );
+      WRITE_CODE(   sei.m_maiMantissaFocalLengthY   [i]          , sei.getMantissaFocalLengthYLen( i ),    "mantissa_focal_length_y"    );
+      WRITE_FLAG( ( sei.m_maiSignPrincipalPointX    [i] ? 1 : 0 ),                                         "sign_principal_point_x"     );
+      WRITE_CODE(   sei.m_maiExponentPrincipalPointX[i]          , 6,                                      "exponent_principal_point_x" );
+      WRITE_CODE(   sei.m_maiMantissaPrincipalPointX[i]          , sei.getMantissaPrincipalPointXLen( i ), "mantissa_principal_point_x" );
+      WRITE_FLAG( ( sei.m_maiSignPrincipalPointY    [i] ? 1 : 0 ),                                         "sign_principal_point_y"     );
+      WRITE_CODE(   sei.m_maiExponentPrincipalPointY[i]          , 6,                                      "exponent_principal_point_y" );
+      WRITE_CODE(   sei.m_maiMantissaPrincipalPointY[i]          , sei.getMantissaPrincipalPointYLen( i ), "mantissa_principal_point_y" );
+      WRITE_FLAG( ( sei.m_maiSignSkewFactor         [i] ? 1 : 0 ),                                         "sign_skew_factor"           );
+      WRITE_CODE(   sei.m_maiExponentSkewFactor     [i]          , 6,                                      "exponent_skew_factor"       );
+      WRITE_CODE(   sei.m_maiMantissaSkewFactor     [i]          , sei.getMantissaSkewFactorLen( i )  ,    "mantissa_skew_factor"       );
+    }
+  }
+  if( sei.m_maiExtrinsicParamFlag )
+  {
+    WRITE_UVLC( sei.m_maiPrecRotationParam   , "prec_rotation_param"    );
+    WRITE_UVLC( sei.m_maiPrecTranslationParam, "prec_translation_param" );
+    for( int i = 0; i  <=  sei.m_maiNumViewsMinus1; i++ )
+    {
+      for( int j = 0; j  <=  2; j++ )  /* row */
+      {
+        for( int k = 0; k  <=  2; k++ )  /* column */
+        {
+          WRITE_FLAG( ( sei.m_maiSignR    [i][j][k] ? 1 : 0 ),                                "sign_r"     );
+          WRITE_CODE(   sei.m_maiExponentR[i][j][k]          , 6,                             "exponent_r" );
+          WRITE_CODE(   sei.m_maiMantissaR[i][j][k]          , sei.getMantissaRLen( i,j,k ) , "mantissa_r" );
+        }
+        WRITE_FLAG( ( sei.m_maiSignT    [i][j] ? 1 : 0 ),                          "sign_t"     );
+        WRITE_CODE(   sei.m_maiExponentT[i][j]          , 6,                       "exponent_t" );
+        WRITE_CODE(   sei.m_maiMantissaT[i][j]          , sei.getMantissaTLen( i,j ),"mantissa_t" );
+      }
+    }
+  }
+};
+
+#if JVET_W0078_MVP_SEI 
+void SEIWriter::xWriteSEIMultiviewViewPosition(const SEIMultiviewViewPosition& sei)
+{
+  WRITE_UVLC(sei.m_mvpNumViewsMinus1, "num_views_minus1");
+  for (int i = 0; i <= sei.m_mvpNumViewsMinus1; i++)
+  {
+    WRITE_UVLC(sei.m_mvpViewPosition[i], "view_position");
+  }
+};
+#endif
+
+void SEIWriter::xWriteSEIAlphaChannelInfo( const SEIAlphaChannelInfo& sei)
+{
+  WRITE_FLAG( ( sei.m_aciCancelFlag ? 1 : 0 ), "alpha_channel_cancel_flag" );
+  if( !sei.m_aciCancelFlag )
+  {
+    WRITE_CODE( sei.m_aciUseIdc, 3, "alpha_channel_use_idc" );
+    WRITE_CODE( sei.m_aciBitDepthMinus8, 3, "alpha_channel_bit_depth_minus8" );
+    WRITE_CODE( sei.m_aciTransparentValue, sei.m_aciBitDepthMinus8+9, "alpha_transparent_value" );
+    WRITE_CODE( sei.m_aciOpaqueValue, sei.m_aciBitDepthMinus8+9, "alpha_opaque_value" );
+    WRITE_FLAG( ( sei.m_aciIncrFlag ? 1 : 0 ), "alpha_channel_incr_flag" );
+    WRITE_FLAG( ( sei.m_aciClipFlag ? 1 : 0 ), "alpha_channel_clip_flag" );
+    if( sei.m_aciClipFlag )
+    {
+      WRITE_FLAG( ( sei.m_aciClipTypeFlag ? 1 : 0 ), "alpha_channel_clip_type_flag" );
+    }
+  }
+};
+
+void SEIWriter::xWriteSEIDepthRepresentationInfo( const SEIDepthRepresentationInfo& sei)
+{
+  WRITE_FLAG( ( sei.m_driZNearFlag ? 1 : 0 ), "z_near_flag" );
+  WRITE_FLAG( ( sei.m_driZFarFlag ? 1 : 0 ), "z_far_flag" );
+  WRITE_FLAG( ( sei.m_driDMinFlag ? 1 : 0 ), "d_min_flag" );
+  WRITE_FLAG( ( sei.m_driDMaxFlag ? 1 : 0 ), "d_max_flag" );
+  WRITE_UVLC( sei.m_driDepthRepresentationType, "depth_representation_type" );
+  if( sei.m_driDMinFlag || sei.m_driDMaxFlag )
+  {
+    WRITE_UVLC( sei.m_driDisparityRefViewId, "disparity_ref_view_id" );
+  }
+  if( sei.m_driZNearFlag )
+  {
+    xWriteSEIDepthRepInfoElement(sei.m_driZNear);
+  }
+  if( sei.m_driZFarFlag )
+  {
+    xWriteSEIDepthRepInfoElement(sei.m_driZFar);
+  }
+  if( sei.m_driDMinFlag )
+  {
+    xWriteSEIDepthRepInfoElement(sei.m_driDMin);
+  }
+  if( sei.m_driDMaxFlag )
+  {
+    xWriteSEIDepthRepInfoElement(sei.m_driDMax);
+  }
+
+  if (sei.m_driDepthRepresentationType == 3)
+  {
+    WRITE_UVLC( sei.m_driDepthNonlinearRepresentationNumMinus1, "depth_nonlinear_representation_num_minus1" );
+    for( int i = 1; i  <=  sei.m_driDepthNonlinearRepresentationNumMinus1 + 1; i++ )
+    {
+      WRITE_UVLC(sei.m_driDepthNonlinearRepresentationModel.at(i - 1),"depth_nonlinear_representation_model[ i ]");
+    }
+  }
+}
+
+void SEIWriter::xWriteSEIDepthRepInfoElement( double f )
+{
+  uint32_t x_sign, x_exp, x_mantissa,x_mantissa_len;
+  if (f < 0)
+  {
+    f = f * (-1);
+    x_sign = 1;
+  }
+  else
+  {
+    x_sign = 0;
+  }
+  int exponent=0;
+  if(f >= 1)
+  {
+    while(f>=2)
+    {
+      exponent++;
+      f = f/2;
+    }
+  }
+  else
+  {
+    while (f<1)
+    {
+      exponent++;
+      f = f*2;
+    }
+    exponent=-exponent;
+  }
+
+  int i;
+  f = f -1;
+  double s = 1;
+  char s_mantissa[32];
+  double thr=1.0/(4.0*(1<<30));
+
+  if (f>=thr)
+  {
+    for(i=0;i<32;i++)
+    {
+      s /= 2;
+      if(f>=s)
+      {
+        f = f-s;
+        s_mantissa[i]=1;
+
+        if (f<thr)
+          break;
+      }
+      else
+      {
+        s_mantissa[i]=0;
+      }
+    }
+
+    if (i<32)
+      x_mantissa_len=i+1;
+    else
+      x_mantissa_len=32;
+
+    x_mantissa=0;
+
+    for(i=0;i<x_mantissa_len;i++)
+    {
+      if (s_mantissa[i]==1)
+        x_mantissa += (1u)<<(x_mantissa_len-1-i) ;
+    }
+
+  }
+  else
+  {
+    x_mantissa=0;
+    x_mantissa_len=1;
+  }
+
+  assert(exponent>=-31 && exponent<= (1<<7)-32);
+  x_exp=exponent+31;
+
+  WRITE_FLAG( x_sign,                          "da_sign_flag" );
+  WRITE_CODE( x_exp, 7 ,                       "da_exponent" );
+  WRITE_CODE( x_mantissa_len-1, 5 ,            "da_mantissa_len_minus1" );
+  WRITE_CODE( x_mantissa, x_mantissa_len ,     "da_mantissa" );
+};
+
 void SEIWriter::xWriteSEISubpictureLevelInfo(const SEISubpicureLevelInfo &sei)
 {
   CHECK(sei.m_numRefLevels < 1, "SEISubpicureLevelInfo: numRefLevels must be greater than zero");
@@ -922,4 +1300,65 @@ void SEIWriter::xWriteSEIContentColourVolume(const SEIContentColourVolume &sei)
   }
 }
 
+void SEIWriter::xWriteSEIColourTransformInfo(const SEIColourTransformInfo& sei)
+{
+  bool colourTransformCancelFlag = 0;
+  bool colourTransformPersistenceFlag = 0;
+
+  WRITE_UVLC(sei.m_id, "colour_transform_id");
+  WRITE_FLAG(colourTransformCancelFlag, "colour_transform_cancel_flag");
+
+  if (colourTransformCancelFlag == 0)
+  {
+    WRITE_FLAG(colourTransformPersistenceFlag, "colour_transform_persistence_flag");
+    WRITE_FLAG(sei.m_signalInfoFlag, "colour_transform_video_signal_info_present_flag");
+
+    if (sei.m_signalInfoFlag)
+    {
+      WRITE_FLAG(sei.m_fullRangeFlag, "colour_transform_full_range_flag");
+      WRITE_CODE(sei.m_primaries, 8, "colour_transform_primaries");
+      WRITE_CODE(sei.m_transferFunction, 8, "colour_transform_transfer_function");
+      WRITE_CODE(sei.m_matrixCoefs, 8, "colour_transform_matrix_coefficients");
+    }
+    WRITE_CODE(sei.m_bitdepth - 8, 4, "colour_transform_bit_depth_minus8"); 
+    WRITE_CODE(sei.m_log2NumberOfPointsPerLut - 1, 3, "colour_transform_log2_number_of_points_per_lut_minus1");
+    WRITE_FLAG(sei.m_crossComponentFlag, "colour_transform_cross_comp_flag");
+    if (sei.m_crossComponentFlag)
+    {
+      WRITE_FLAG(sei.m_crossComponentInferred, "colour_transform_cross_comp_inferred");
+    }
+
+    uint16_t lutCodingLength = 2 + sei.m_bitdepth - sei.m_log2NumberOfPointsPerLut;
+    for (uint32_t j = 0; j < sei.m_lut[0].numLutValues; j++)
+    {
+      WRITE_CODE(sei.m_lut[0].lutValues[j], lutCodingLength, "colour_transform_lut[0][i]");
+    }
+    if (sei.m_crossComponentFlag == 0 || sei.m_crossComponentInferred == 0)
+    {
+      WRITE_FLAG(sei.m_numberChromaLutMinus1, "colour_transform_number_chroma_lut_minus1");
+      for (uint32_t j = 0; j < sei.m_lut[1].numLutValues; j++)
+      {
+        WRITE_CODE(sei.m_lut[1].lutValues[j], lutCodingLength, "colour_transform_lut[1][i]");
+      }
+      if (sei.m_numberChromaLutMinus1 == 1)
+      {
+        for (uint32_t j = 0; j < sei.m_lut[2].numLutValues; j++)
+        {
+          WRITE_CODE(sei.m_lut[2].lutValues[j], lutCodingLength, "colour_transform_lut[2][i]");
+        }
+      }
+    }
+    else
+    {
+      WRITE_CODE(sei.m_chromaOffset, lutCodingLength, "colour_transform_chroma_offset");
+    }
+  }
+}
+
+#if JVET_W0133_CONSTRAINED_RASL_ENCODING
+void SEIWriter::xWriteSEIConstrainedRaslIndication(const SEIConstrainedRaslIndication& /*sei*/)
+{
+  // intentionally empty
+}
+#endif
 //! \}
diff --git a/source/Lib/EncoderLib/SEIwrite.h b/source/Lib/EncoderLib/SEIwrite.h
index 912e0ee87..4145c03cf 100644
--- a/source/Lib/EncoderLib/SEIwrite.h
+++ b/source/Lib/EncoderLib/SEIwrite.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -59,8 +59,10 @@ protected:
   void xWriteSEIPictureTiming(const SEIPictureTiming& sei, const SEIBufferingPeriod& bp, const uint32_t temporalId);
   void xWriteSEIFrameFieldInfo(const SEIFrameFieldInfo& sei);
   void xWriteSEIDependentRAPIndication(const SEIDependentRAPIndication& sei);
+  void xWriteSEIEdrapIndication(const SEIExtendedDrapIndication& sei);
   void xWriteSEIScalableNesting(OutputBitstream& bs, const SEIScalableNesting& sei);
   void xWriteSEIFramePacking(const SEIFramePacking& sei);
+  void xWriteSEIDisplayOrientation(const SEIDisplayOrientation& sei);
   void xWriteSEIParameterSetsInclusionIndication(const SEIParameterSetsInclusionIndication& sei);
   void xWriteSEIMasteringDisplayColourVolume( const SEIMasteringDisplayColourVolume& sei);
 #if U0033_ALTERNATIVE_TRANSFER_CHARACTERISTICS_SEI
@@ -71,14 +73,26 @@ protected:
   void xWriteSEIOmniViewport                      (const SEIOmniViewport& sei);
   void xWriteSEIRegionWisePacking                 (const SEIRegionWisePacking &sei);
   void xWriteSEIGeneralizedCubemapProjection      (const SEIGeneralizedCubemapProjection &sei);
+  void xWriteSEIScalabilityDimensionInfo          (const SEIScalabilityDimensionInfo& sei);
+  void xWriteSEIMultiviewAcquisitionInfo          (const SEIMultiviewAcquisitionInfo& sei);
+#if JVET_W0078_MVP_SEI 
+  void xWriteSEIMultiviewViewPosition             (const SEIMultiviewViewPosition& sei);
+#endif
+  void xWriteSEIAlphaChannelInfo                  (const SEIAlphaChannelInfo& sei);
+  void xWriteSEIDepthRepresentationInfo           (const SEIDepthRepresentationInfo& sei);
+  void xWriteSEIDepthRepInfoElement               (double f);
   void xWriteSEISubpictureLevelInfo               (const SEISubpicureLevelInfo &sei);
   void xWriteSEISampleAspectRatioInfo             (const SEISampleAspectRatioInfo &sei);
-
+#if JVET_W0133_CONSTRAINED_RASL_ENCODING
+  void xWriteSEIConstrainedRaslIndication         (const SEIConstrainedRaslIndication &sei);
+#endif
   void xWriteSEIUserDataRegistered(const SEIUserDataRegistered& sei);
   void xWriteSEIFilmGrainCharacteristics(const SEIFilmGrainCharacteristics& sei);
   void xWriteSEIContentLightLevelInfo(const SEIContentLightLevelInfo& sei);
   void xWriteSEIAmbientViewingEnvironment(const SEIAmbientViewingEnvironment& sei);
   void xWriteSEIContentColourVolume(const SEIContentColourVolume &sei);
+  void xWriteSEIColourTransformInfo(const SEIColourTransformInfo& sei);
+  void xWriteSEIAnnotatedRegions                  (const SEIAnnotatedRegions& sei);
   void xWriteSEIpayloadData(OutputBitstream &bs, const SEI& sei, HRD &hrd, const uint32_t temporalId);
   void xWriteByteAlign();
 protected:
diff --git a/source/Lib/EncoderLib/VLCWriter.cpp b/source/Lib/EncoderLib/VLCWriter.cpp
index e57585fa1..389e69af4 100644
--- a/source/Lib/EncoderLib/VLCWriter.cpp
+++ b/source/Lib/EncoderLib/VLCWriter.cpp
@@ -3,7 +3,7 @@
 * and contributor rights, including patent rights, and no such rights are
 * granted under this license.
 *
-* Copyright (c) 2010-2020, ITU/ISO/IEC
+* Copyright (c) 2010-2021, ITU/ISO/IEC
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
@@ -131,13 +131,13 @@ void VLCWriter::xWriteCode     ( uint32_t uiCode, uint32_t uiLength )
 void VLCWriter::xWriteUvlc     ( uint32_t uiCode )
 {
   uint32_t uiLength = 1;
-  uint32_t uiTemp = ++uiCode;
+  uint32_t temp     = ++uiCode;
 
-  CHECK( !uiTemp, "Integer overflow" );
+  CHECK(!temp, "Integer overflow");
 
-  while( 1 != uiTemp )
+  while (1 != temp)
   {
-    uiTemp >>= 1;
+    temp >>= 1;
     uiLength += 2;
   }
   // Take care of cases where uiLength > 32
@@ -284,9 +284,8 @@ void HLSWriter::codePPS( const PPS* pcPPS )
     WRITE_UVLC(conf.getWindowBottomOffset(), "pps_conf_win_bottom_offset");
   }
   Window scalingWindow = pcPPS->getScalingWindow();
-
-  WRITE_FLAG( scalingWindow.getWindowEnabledFlag(), "pps_scaling_window_explicit_signalling_flag" );
-  if( scalingWindow.getWindowEnabledFlag() )
+  WRITE_FLAG( pcPPS->getExplicitScalingWindowFlag(), "pps_scaling_window_explicit_signalling_flag");
+  if ( pcPPS->getExplicitScalingWindowFlag() )
   {
     WRITE_SVLC( scalingWindow.getWindowLeftOffset(), "pps_scaling_win_left_offset" );
     WRITE_SVLC( scalingWindow.getWindowRightOffset(), "pps_scaling_win_right_offset" );
@@ -715,10 +714,8 @@ void HLSWriter::codeGeneralHrdparameters(const GeneralHrdParams * hrd)
   WRITE_CODE(hrd->getTimeScale(), 32, "time_scale");
   WRITE_FLAG(hrd->getGeneralNalHrdParametersPresentFlag() ? 1 : 0, "general_nal_hrd_parameters_present_flag");
   WRITE_FLAG(hrd->getGeneralVclHrdParametersPresentFlag() ? 1 : 0, "general_vcl_hrd_parameters_present_flag");
-#if JVET_S0175_ASPECT6
   if( hrd->getGeneralNalHrdParametersPresentFlag() || hrd->getGeneralVclHrdParametersPresentFlag() )
   {
-#endif
     WRITE_FLAG(hrd->getGeneralSamePicTimingInAllOlsFlag() ? 1 : 0, "general_same_pic_timing_in_all_ols_flag");
     WRITE_FLAG(hrd->getGeneralDecodingUnitHrdParamsPresentFlag() ? 1 : 0, "general_decoding_unit_hrd_params_present_flag");
     if (hrd->getGeneralDecodingUnitHrdParamsPresentFlag())
@@ -732,9 +729,7 @@ void HLSWriter::codeGeneralHrdparameters(const GeneralHrdParams * hrd)
       WRITE_CODE(hrd->getCpbSizeDuScale(), 4, "cpb_size_du_scale");
     }
     WRITE_UVLC(hrd->getHrdCpbCntMinus1(), "hrd_cpb_cnt_minus1");
-#if JVET_S0175_ASPECT6
   }
-#endif
 }
 void HLSWriter::codeOlsHrdParameters(const GeneralHrdParams * generalHrd, const OlsHrdParams *olsHrd, const uint32_t firstSubLayer, const uint32_t maxNumSubLayersMinus1)
 {
@@ -752,11 +747,7 @@ void HLSWriter::codeOlsHrdParameters(const GeneralHrdParams * generalHrd, const
     {
       WRITE_UVLC(hrd->getElementDurationInTcMinus1(), "elemental_duration_in_tc_minus1");
     }
-#if JVET_S0175_ASPECT6
     else if ( (generalHrd->getGeneralNalHrdParametersPresentFlag() || generalHrd->getGeneralVclHrdParametersPresentFlag()) && generalHrd->getHrdCpbCntMinus1() == 0)
-#else
-    else if (generalHrd->getHrdCpbCntMinus1() == 0)
-#endif
     {
       WRITE_FLAG(hrd->getLowDelayHrdFlag() ? 1 : 0, "low_delay_hrd_flag");
     }
@@ -905,7 +896,7 @@ void HLSWriter::codeSPS( const SPS* pcSPS )
   WRITE_FLAG( pcSPS->getEntropyCodingSyncEnabledFlag() ? 1 : 0, "sps_entropy_coding_sync_enabled_flag" );
   WRITE_FLAG( pcSPS->getEntryPointsPresentFlag() ? 1 : 0, "sps_entry_point_offsets_present_flag" );
   WRITE_CODE(pcSPS->getBitsForPOC()-4, 4, "sps_log2_max_pic_order_cnt_lsb_minus4");
-  
+
   WRITE_FLAG(pcSPS->getPocMsbCycleFlag() ? 1 : 0, "sps_poc_msb_cycle_flag");
   if (pcSPS->getPocMsbCycleFlag())
   {
@@ -1272,6 +1263,15 @@ void HLSWriter::codeSPS( const SPS* pcSPS )
   {
 #if ENABLE_TRACING /*|| RExt__DECODER_DEBUG_BIT_STATISTICS*/
     static const char *syntaxStrings[]={ "sps_range_extension_flag",
+#if JVET_W2005_RANGE_EXTENSION_PROFILES
+      "sps_extension_7bits[0]",
+      "sps_extension_7bits[1]",
+      "sps_extension_7bits[2]",
+      "sps_extension_7bits[3]",
+      "sps_extension_7bits[4]",
+      "sps_extension_7bits[5]",
+      "sps_extension_7bits[6]" };
+#else
       "sps_multilayer_extension_flag",
       "sps_extension_6bits[0]",
       "sps_extension_6bits[1]",
@@ -1280,6 +1280,13 @@ void HLSWriter::codeSPS( const SPS* pcSPS )
       "sps_extension_6bits[4]",
       "sps_extension_6bits[5]" };
 #endif
+#endif
+
+#if JVET_W0178_CONSTRAINTS_ON_REXT_TOOLS
+    if (pcSPS->getBitDepth(CHANNEL_TYPE_LUMA) <= 10)
+      CHECK((sps_extension_flags[SPS_EXT__REXT] == 1),
+            "The value of sps_range_extension_flag shall be 0 when BitDepth is less than or equal to 10.");
+#endif
 
     for(int i=0; i<NUM_SPS_EXTENSION_FLAGS; i++)
     {
@@ -1296,13 +1303,31 @@ void HLSWriter::codeSPS( const SPS* pcSPS )
         {
           const SPSRExt &spsRangeExtension=pcSPS->getSpsRangeExtension();
 
+#if !JVET_W2005_RANGE_EXTENSION_PROFILES
           WRITE_FLAG( (spsRangeExtension.getTransformSkipRotationEnabledFlag() ? 1 : 0),      "transform_skip_rotation_enabled_flag");
           WRITE_FLAG( (spsRangeExtension.getTransformSkipContextEnabledFlag() ? 1 : 0),       "transform_skip_context_enabled_flag");
+#endif
           WRITE_FLAG( (spsRangeExtension.getExtendedPrecisionProcessingFlag() ? 1 : 0),       "extended_precision_processing_flag" );
+#if JVET_W0070_W0121_SPSRE_CLEANUP
+          if (pcSPS->getTransformSkipEnabledFlag())
+          {
+            WRITE_FLAG( (spsRangeExtension.getTSRCRicePresentFlag() ? 1 : 0),                 "sps_ts_residual_coding_rice_present_in_sh_flag");
+          }
+#else
+          WRITE_FLAG( (spsRangeExtension.getTSRCRicePresentFlag() ? 1 : 0),                   "sps_ts_residual_coding_rice_present_in_sh_flag");
+#endif
+#if !JVET_W2005_RANGE_EXTENSION_PROFILES
           WRITE_FLAG( (spsRangeExtension.getIntraSmoothingDisabledFlag() ? 1 : 0),            "intra_smoothing_disabled_flag" );
           WRITE_FLAG( (spsRangeExtension.getHighPrecisionOffsetsEnabledFlag() ? 1 : 0),       "high_precision_offsets_enabled_flag" );
+#endif
+          WRITE_FLAG( (spsRangeExtension.getRrcRiceExtensionEnableFlag() ? 1 : 0),                   "rrc_rice_extension_flag");
           WRITE_FLAG( (spsRangeExtension.getPersistentRiceAdaptationEnabledFlag() ? 1 : 0),   "persistent_rice_adaptation_enabled_flag" );
+#if JVET_W0046_RLSCP
+          WRITE_FLAG( (spsRangeExtension.getReverseLastSigCoeffEnabledFlag() ? 1 : 0),        "reverse_last_sig_coeff_enabled_flag" );
+#endif
+#if !JVET_W2005_RANGE_EXTENSION_PROFILES
           WRITE_FLAG( (spsRangeExtension.getCabacBypassAlignmentEnabledFlag() ? 1 : 0),       "cabac_bypass_alignment_enabled_flag" );
+#endif
           break;
         }
         default:
@@ -1335,7 +1360,6 @@ void HLSWriter::codeDCI(const DCI* dci)
   xWriteRbspTrailingBits();
 }
 
-#if JVET_S0163_ON_TARGETOLS_SUBLAYERS
 void HLSWriter::codeOPI(const OPI *opi)
 {
 #if ENABLE_TRACING
@@ -1344,19 +1368,18 @@ void HLSWriter::codeOPI(const OPI *opi)
   WRITE_FLAG(opi->getOlsInfoPresentFlag(), "opi_ols_info_present_flag");
   WRITE_FLAG(opi->getHtidInfoPresentFlag(), "opi_htid_info_present_flag");
 
-  if (opi->getOlsInfoPresentFlag()) 
+  if (opi->getOlsInfoPresentFlag())
   {
-    WRITE_UVLC(opi->getOpiOlsIdx(), "opi_ols_idx");  
+    WRITE_UVLC(opi->getOpiOlsIdx(), "opi_ols_idx");
   }
 
-  if (opi->getHtidInfoPresentFlag()) 
+  if (opi->getHtidInfoPresentFlag())
   {
-    WRITE_CODE(opi->getOpiHtidPlus1(), 3, "opi_htid_plus1");  
+    WRITE_CODE(opi->getOpiHtidPlus1(), 3, "opi_htid_plus1");
   }
   WRITE_FLAG(0, "opi_extension_flag");
   xWriteRbspTrailingBits();
 }
-#endif
 
 void HLSWriter::codeVPS(const VPS* pcVPS)
 {
@@ -1382,7 +1405,6 @@ void HLSWriter::codeVPS(const VPS* pcVPS)
       WRITE_FLAG(pcVPS->getIndependentLayerFlag(i), "vps_independent_layer_flag");
       if (!pcVPS->getIndependentLayerFlag(i))
       {
-#if JVET_R0193
         bool presentFlag = false;
         for (int j = 0; j < i; j++)
         {
@@ -1397,18 +1419,6 @@ void HLSWriter::codeVPS(const VPS* pcVPS)
             WRITE_CODE(pcVPS->getMaxTidIlRefPicsPlus1(i, j), 3, "max_tid_il_ref_pics_plus1[ i ][ j ]");
           }
         }
-#else
-        for (int j = 0; j < i; j++)
-        {
-          WRITE_FLAG(pcVPS->getDirectRefLayerFlag(i, j), "vps_direct_dependency_flag");
-        }
-        bool presentFlag = ( pcVPS->getMaxTidIlRefPicsPlus1(i) != 7 );
-        WRITE_FLAG(presentFlag, "vps_max_tid_ref_present_flag[ i ]");
-        if (presentFlag)
-        {
-          WRITE_CODE(pcVPS->getMaxTidIlRefPicsPlus1(i), 3, "vps_max_tid_il_ref_pics_plus1[ i ]");
-        }
-#endif
       }
     }
   }
@@ -1444,11 +1454,11 @@ void HLSWriter::codeVPS(const VPS* pcVPS)
   {
     if(i > 0)
       WRITE_FLAG(pcVPS->getPtPresentFlag(i), "vps_pt_present_flag");
-    if (!pcVPS->getDefaultPtlDpbHrdMaxTidFlag()) 
+    if (!pcVPS->getDefaultPtlDpbHrdMaxTidFlag())
     {
       WRITE_CODE(pcVPS->getPtlMaxTemporalId(i), 3, "vps_ptl_max_tid");
     }
-    else 
+    else
     {
       CHECK(pcVPS->getPtlMaxTemporalId(i) != pcVPS->getMaxSubLayers() - 1, "When vps_default_ptl_dpb_hrd_max_tid_flag is equal to 1, the value of vps_ptl_max_tid[ i ] is inferred to be equal to vps_max_sublayers_minus1");
     }
@@ -1462,7 +1472,7 @@ void HLSWriter::codeVPS(const VPS* pcVPS)
   CHECK(cnt>=8, "More than '8' alignment bytes written");
   for (int i = 0; i < pcVPS->getNumPtls(); i++)
   {
-    codeProfileTierLevel(&pcVPS->getProfileTierLevel(i), pcVPS->getPtPresentFlag(i), pcVPS->getPtlMaxTemporalId(i) - 1);
+    codeProfileTierLevel(&pcVPS->getProfileTierLevel(i), pcVPS->getPtPresentFlag(i), pcVPS->getPtlMaxTemporalId(i));
   }
   for (int i = 0; i < totalNumOlss; i++)
   {
@@ -1537,7 +1547,7 @@ void HLSWriter::codeVPS(const VPS* pcVPS)
       {
         WRITE_CODE(pcVPS->getHrdMaxTid(i), 3, "vps_hrd_max_tid[i]");
       }
-      else 
+      else
       {
         CHECK(pcVPS->getHrdMaxTid(i) != pcVPS->getMaxSubLayers() - 1, "When vps_default_ptl_dpb_hrd_max_tid_flag is equal to 1, the value of vps_hrd_max_tid[ i ] is inferred to be equal to vps_max_sublayers_minus1");
       }
@@ -1572,7 +1582,7 @@ void HLSWriter::codePictureHeader( PicHeader* picHeader, bool writeRbspTrailingB
   {
     slice = picHeader->getPic()->cs->slice;
   }
-WRITE_FLAG(picHeader->getGdrOrIrapPicFlag(), "ph_gdr_or_irap_pic_flag");
+  WRITE_FLAG(picHeader->getGdrOrIrapPicFlag(), "ph_gdr_or_irap_pic_flag");
   WRITE_FLAG(picHeader->getNonReferencePictureFlag(), "ph_non_ref_pic_flag");
   if (picHeader->getGdrOrIrapPicFlag())
   {
@@ -1601,6 +1611,11 @@ WRITE_FLAG(picHeader->getGdrOrIrapPicFlag(), "ph_gdr_or_irap_pic_flag");
   {
     picHeader->setRecoveryPocCnt( -1 );
   }
+#if GDR_ENC_TRACE
+  printf("-gdr_pic_flag:%d\n", picHeader->getGdrPicFlag());
+  printf("-recovery_poc_cnt:%d\n", picHeader->getRecoveryPocCnt());
+  printf("-InGdrInterval:%d\n", picHeader->getInGdrInterval());
+#endif
   // PH extra bits are not written in the reference encoder
   // as these bits are reserved for future extensions
   // for( i = 0; i < NumExtraPhBits; i++ )
@@ -1624,9 +1639,9 @@ WRITE_FLAG(picHeader->getGdrOrIrapPicFlag(), "ph_gdr_or_irap_pic_flag");
       WRITE_FLAG(picHeader->getAlfEnabledFlag(COMPONENT_Y), "ph_alf_enabled_flag");
       if (picHeader->getAlfEnabledFlag(COMPONENT_Y))
       {
-        WRITE_CODE(picHeader->getNumAlfAps(), 3, "ph_num_alf_aps_ids_luma");
-        const std::vector<int>&   apsId = picHeader->getAlfAPSs();
-        for (int i = 0; i < picHeader->getNumAlfAps(); i++)
+        WRITE_CODE(picHeader->getNumAlfApsIdsLuma(), 3, "ph_num_alf_aps_ids_luma");
+        const std::vector<int>&   apsId = picHeader->getAlfApsIdsLuma();
+        for (int i = 0; i < picHeader->getNumAlfApsIdsLuma(); i++)
         {
           WRITE_CODE(apsId[i], 3, "ph_alf_aps_id_luma");
         }
@@ -1696,6 +1711,10 @@ WRITE_FLAG(picHeader->getGdrOrIrapPicFlag(), "ph_gdr_or_irap_pic_flag");
     picHeader->setLmcsEnabledFlag(false);
     picHeader->setLmcsChromaResidualScaleFlag(false);
   }
+#if GDR_ENC_TRACE
+  printf("-pic_lmcs_enabled_flag:%d\n", picHeader->getLmcsEnabledFlag() ? 1 : 0);
+  printf("-pic_chroma_residual_scale_flag:%d\n", picHeader->getLmcsChromaResidualScaleFlag() ? 1 : 0);
+#endif
 
   // quantization scaling lists
   if( sps->getScalingListFlag() )
@@ -1719,6 +1738,56 @@ WRITE_FLAG(picHeader->getGdrOrIrapPicFlag(), "ph_gdr_or_irap_pic_flag");
     WRITE_FLAG( picHeader->getVirtualBoundariesPresentFlag(), "ph_virtual_boundaries_present_flag" );
     if( picHeader->getVirtualBoundariesPresentFlag() )
     {
+#if GDR_ENABLED
+      if (sps->getGDREnabledFlag())
+      {
+        int n = picHeader->getNumVerVirtualBoundaries();
+        for (unsigned i = 0; i < n; i++)
+        {
+          if (picHeader->getVirtualBoundariesPosX(i) == pps->getPicWidthInLumaSamples())
+          {
+            n = n - 1;
+          }
+        }
+
+        WRITE_UVLC(n, "ph_num_ver_virtual_boundaries");
+
+        if (pps->getPicWidthInLumaSamples() <= 8)
+        {
+          CHECK(picHeader->getNumVerVirtualBoundaries() != 0, "PH: When picture width is less than or equal to 8, the number of vertical virtual boundaries shall be equal to 0");
+        }
+        else
+        {
+          CHECK(picHeader->getNumVerVirtualBoundaries() > 3, "PH: The number of vertical virtual boundaries shall be in the range of 0 to 3");
+        }
+
+        for (unsigned i = 0; i < picHeader->getNumVerVirtualBoundaries(); i++)
+        {
+          if (picHeader->getVirtualBoundariesPosX(i) != pps->getPicWidthInLumaSamples())
+          {
+            WRITE_UVLC((picHeader->getVirtualBoundariesPosX(i) >> 3) - 1, "ph_virtual_boundary_pos_x_minus1[i]");
+            CHECK(((picHeader->getVirtualBoundariesPosX(i) >> 3) - 1) > (((pps->getPicWidthInLumaSamples() + 7) >> 3) - 2), "The value of ph_virtual_boundary_pos_x_minus1[ i ] shall be in the range of 0 to Ceil( pps_pic_width_in_luma_samples / 8 ) - 2, inclusive.");
+          }
+        }
+      }
+      else
+      {
+        WRITE_UVLC(picHeader->getNumVerVirtualBoundaries(), "ph_num_ver_virtual_boundaries");
+        if (pps->getPicWidthInLumaSamples() <= 8)
+        {
+          CHECK(picHeader->getNumVerVirtualBoundaries() != 0, "PH: When picture width is less than or equal to 8, the number of vertical virtual boundaries shall be equal to 0");
+        }
+        else
+        {
+          CHECK(picHeader->getNumVerVirtualBoundaries() > 3, "PH: The number of vertical virtual boundaries shall be in the range of 0 to 3");
+        }
+        for (unsigned i = 0; i < picHeader->getNumVerVirtualBoundaries(); i++)
+        {
+          WRITE_UVLC((picHeader->getVirtualBoundariesPosX(i) >> 3) - 1, "ph_virtual_boundary_pos_x_minus1[i]");
+          CHECK(((picHeader->getVirtualBoundariesPosX(i) >> 3) - 1) > (((pps->getPicWidthInLumaSamples() + 7) >> 3) - 2), "The value of ph_virtual_boundary_pos_x_minus1[ i ] shall be in the range of 0 to Ceil( pps_pic_width_in_luma_samples / 8 ) - 2, inclusive.");
+        }
+      }
+#else
       WRITE_UVLC(picHeader->getNumVerVirtualBoundaries(), "ph_num_ver_virtual_boundaries");
       if (pps->getPicWidthInLumaSamples() <= 8)
       {
@@ -1733,6 +1802,7 @@ WRITE_FLAG(picHeader->getGdrOrIrapPicFlag(), "ph_gdr_or_irap_pic_flag");
         WRITE_UVLC((picHeader->getVirtualBoundariesPosX(i) >> 3) - 1, "ph_virtual_boundary_pos_x_minus1[i]");
         CHECK(((picHeader->getVirtualBoundariesPosX(i)>>3) - 1) > (((pps->getPicWidthInLumaSamples() + 7) >> 3) - 2), "The value of ph_virtual_boundary_pos_x_minus1[ i ] shall be in the range of 0 to Ceil( pps_pic_width_in_luma_samples / 8 ) - 2, inclusive.");
       }
+#endif
       WRITE_UVLC(picHeader->getNumHorVirtualBoundaries(), "ph_num_hor_virtual_boundaries");
       if (pps->getPicHeightInLumaSamples() <= 8)
       {
@@ -1898,10 +1968,6 @@ WRITE_FLAG(picHeader->getGdrOrIrapPicFlag(), "ph_gdr_or_irap_pic_flag");
     {
       WRITE_UVLC( picHeader->getCuChromaQpOffsetSubdivIntra(), "ph_cu_chroma_qp_offset_subdiv_intra_slice" );
     }
-    else
-    {
-      picHeader->setCuChromaQpOffsetSubdivIntra( 0 );
-    }
   }
 
 
@@ -1931,11 +1997,8 @@ WRITE_FLAG(picHeader->getGdrOrIrapPicFlag(), "ph_gdr_or_irap_pic_flag");
     {
       WRITE_UVLC(picHeader->getCuChromaQpOffsetSubdivInter(), "ph_cu_chroma_qp_offset_subdiv_inter_slice");
     }
-    else
-    {
-      picHeader->setCuChromaQpOffsetSubdivInter(0);
-    }
-  // temporal motion vector prediction
+
+    // temporal motion vector prediction
     if (sps->getSPSTemporalMVPEnabledFlag())
     {
       WRITE_FLAG( picHeader->getEnableTMVPFlag(), "ph_temporal_mvp_enabled_flag" );
@@ -2209,27 +2272,27 @@ void HLSWriter::codeSliceHeader         ( Slice* pcSlice, PicHeader *picHeader )
 
   if (pcSlice->getSPS()->getALFEnabledFlag() && !pcSlice->getPPS()->getAlfInfoInPhFlag())
   {
-    const int alfEnabled = pcSlice->getTileGroupAlfEnabledFlag(COMPONENT_Y);
+    const int alfEnabled = pcSlice->getAlfEnabledFlag(COMPONENT_Y);
     WRITE_FLAG(alfEnabled, "sh_alf_enabled_flag");
 
     if (alfEnabled)
     {
-      WRITE_CODE(pcSlice->getTileGroupNumAps(), 3, "sh_num_alf_aps_ids_luma");
-      const std::vector<int>&   apsId = pcSlice->getTileGroupApsIdLuma();
-      for (int i = 0; i < pcSlice->getTileGroupNumAps(); i++)
+      WRITE_CODE(pcSlice->getNumAlfApsIdsLuma(), 3, "sh_num_alf_aps_ids_luma");
+      const std::vector<int>&   apsId = pcSlice->getAlfApsIdsLuma();
+      for (int i = 0; i < pcSlice->getNumAlfApsIdsLuma(); i++)
       {
         WRITE_CODE(apsId[i], 3, "sh_alf_aps_id_luma[i]");
       }
 
-      const int alfChromaIdc = pcSlice->getTileGroupAlfEnabledFlag(COMPONENT_Cb) + pcSlice->getTileGroupAlfEnabledFlag(COMPONENT_Cr) * 2;
+      const int alfChromaIdc = pcSlice->getAlfEnabledFlag(COMPONENT_Cb) + pcSlice->getAlfEnabledFlag(COMPONENT_Cr) * 2;
       if (chromaEnabled)
       {
-        WRITE_CODE(pcSlice->getTileGroupAlfEnabledFlag(COMPONENT_Cb), 1, "sh_alf_cb_enabled_flag");
-        WRITE_CODE(pcSlice->getTileGroupAlfEnabledFlag(COMPONENT_Cr), 1, "sh_alf_cr_enabled_flag");
+        WRITE_CODE(pcSlice->getAlfEnabledFlag(COMPONENT_Cb), 1, "sh_alf_cb_enabled_flag");
+        WRITE_CODE(pcSlice->getAlfEnabledFlag(COMPONENT_Cr), 1, "sh_alf_cr_enabled_flag");
       }
       if (alfChromaIdc)
       {
-        WRITE_CODE(pcSlice->getTileGroupApsIdChroma(), 3, "sh_alf_aps_id_chroma");
+        WRITE_CODE(pcSlice->getAlfApsIdChroma(), 3, "sh_alf_aps_id_chroma");
       }
 
       if (pcSlice->getSPS()->getCCALFEnabledFlag())
@@ -2239,14 +2302,14 @@ void HLSWriter::codeSliceHeader         ( Slice* pcSlice, PicHeader *picHeader )
         if (filterParam.ccAlfFilterEnabled[COMPONENT_Cb - 1])
         {
           // write CC ALF Cb APS ID
-          WRITE_CODE(pcSlice->getTileGroupCcAlfCbApsId(), 3, "sh_alf_cc_cb_aps_id");
+          WRITE_CODE(pcSlice->getCcAlfCbApsId(), 3, "sh_alf_cc_cb_aps_id");
         }
         // Cr
         WRITE_FLAG(filterParam.ccAlfFilterEnabled[COMPONENT_Cr - 1] ? 1 : 0, "sh_alf_cc_cr_enabled_flag");
         if (filterParam.ccAlfFilterEnabled[COMPONENT_Cr - 1])
         {
           // write CC ALF Cr APS ID
-          WRITE_CODE(pcSlice->getTileGroupCcAlfCrApsId(), 3, "sh_alf_cc_cr_aps_id");
+          WRITE_CODE(pcSlice->getCcAlfCrApsId(), 3, "sh_alf_cc_cr_aps_id");
         }
       }
     }
@@ -2560,7 +2623,16 @@ void HLSWriter::codeSliceHeader         ( Slice* pcSlice, PicHeader *picHeader )
     WRITE_FLAG(pcSlice->getTSResidualCodingDisabledFlag() ? 1 : 0, "sh_ts_residual_coding_disabled_flag");
   }
 
-
+  if ((!pcSlice->getTSResidualCodingDisabledFlag()) && (pcSlice->getSPS()->getSpsRangeExtension().getTSRCRicePresentFlag()))
+  {
+      WRITE_CODE(pcSlice->get_tsrc_index(), 3, "sh_ts_residual_coding_rice_idx_minus1");
+  }
+#if JVET_W0046_RLSCP
+  if (pcSlice->getSPS()->getSpsRangeExtension().getReverseLastSigCoeffEnabledFlag()) 
+  {
+    WRITE_FLAG(pcSlice->getReverseLastSigCoeffFlag(), "sh_reverse_last_sig_coeff_flag");
+  }
+#endif
   if(pcSlice->getPPS()->getSliceHeaderExtensionPresentFlag())
   {
     WRITE_UVLC(0,"sh_slice_header_extension_length");
@@ -2568,7 +2640,11 @@ void HLSWriter::codeSliceHeader         ( Slice* pcSlice, PicHeader *picHeader )
 
 }
 
+#if JVET_W2005_RANGE_EXTENSION_PROFILES
+void  HLSWriter::codeConstraintInfo  ( const ConstraintInfo* cinfo, const ProfileTierLevel* ptl )
+#else
 void  HLSWriter::codeConstraintInfo  ( const ConstraintInfo* cinfo )
+#endif
 {
   WRITE_FLAG(cinfo->getGciPresentFlag(), "gci_present_flag");
   if (cinfo->getGciPresentFlag())
@@ -2657,9 +2733,25 @@ void  HLSWriter::codeConstraintInfo  ( const ConstraintInfo* cinfo )
     WRITE_FLAG(cinfo->getNoLmcsConstraintFlag() ? 1 : 0, "gci_no_lmcs_constraint_flag");
     WRITE_FLAG(cinfo->getNoLadfConstraintFlag() ? 1 : 0, "gci_no_ladf_constraint_flag");
     WRITE_FLAG(cinfo->getNoVirtualBoundaryConstraintFlag() ? 1 : 0, "gci_no_virtual_boundaries_constraint_flag");
+#if JVET_W2005_RANGE_EXTENSION_PROFILES
+    Profile::Name profile = ptl->getProfileIdc();
+    if (profile == Profile::MAIN_12 || profile == Profile::MAIN_12_INTRA || profile == Profile::MAIN_12_STILL_PICTURE ||
+        profile == Profile::MAIN_12_444 || profile == Profile::MAIN_12_444_INTRA || profile == Profile::MAIN_12_444_STILL_PICTURE ||
+        profile == Profile::MAIN_16_444 || profile == Profile::MAIN_16_444_INTRA || profile == Profile::MAIN_16_444_STILL_PICTURE)
+    {
+      int numReservedBits = 1;
+      WRITE_CODE(numReservedBits, 8, "gci_num_reserved_bits");
+      WRITE_FLAG(cinfo->getLowerBitRateConstraintFlag() ? 1 : 0, "general_lower_bit_rate_constraint_flag");
+    }
+    else
+    {
+      WRITE_CODE(0, 8, "gci_num_reserved_bits");
+    }
+#else
     //The value of gci_num_reserved_bits shall be equal to 0 in bitstreams conforming to this version of this Specification.
     //Other values of gci_num_reserved_bits are reserved for future use by ITU-T | ISO/IEC.
     WRITE_CODE(0, 8, "gci_num_reserved_bits");
+#endif
   }
 
   while (!isByteAligned())
@@ -2683,7 +2775,11 @@ void  HLSWriter::codeProfileTierLevel    ( const ProfileTierLevel* ptl, bool pro
 
   if(profileTierPresentFlag)
   {
+#if JVET_W2005_RANGE_EXTENSION_PROFILES
+    codeConstraintInfo(ptl->getConstraintInfo(), ptl);
+#else
     codeConstraintInfo(ptl->getConstraintInfo());
+#endif
   }
 
   for (int i = maxNumSubLayersMinus1 - 1; i >= 0; i--)
@@ -2926,7 +3022,7 @@ void HLSWriter::xCodePredWeightTable(PicHeader *picHeader, const PPS *pps, const
     if (numRef == 0)
     {
       numLxWeights         = picHeader->getNumL1Weights();
-      if (pps->getWPBiPred() == 0) 
+      if (pps->getWPBiPred() == 0)
       {
         numLxWeights = 0;
       }
@@ -3077,4 +3173,4 @@ void HLSWriter::alfFilter( const AlfParam& alfParam, const bool isChroma, const
 }
 
 
-//! \}
\ No newline at end of file
+//! \}
diff --git a/source/Lib/EncoderLib/VLCWriter.h b/source/Lib/EncoderLib/VLCWriter.h
index db61a5196..ed1ff32d3 100644
--- a/source/Lib/EncoderLib/VLCWriter.h
+++ b/source/Lib/EncoderLib/VLCWriter.h
@@ -3,7 +3,7 @@
 * and contributor rights, including patent rights, and no such rights are
 * granted under this license.
 *
-* Copyright (c) 2010-2020, ITU/ISO/IEC
+* Copyright (c) 2010-2021, ITU/ISO/IEC
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
@@ -141,10 +141,12 @@ public:
   void  codeDCI                 ( const DCI* dci );
   void  codePictureHeader       ( PicHeader* picHeader, bool writeRbspTrailingBits, Slice *slice = 0 );
   void  codeSliceHeader         ( Slice* pcSlice, PicHeader *picheader = 0 );
-#if JVET_S0163_ON_TARGETOLS_SUBLAYERS
   void  codeOPI                 ( const OPI* opi );
-#endif
+#if JVET_W2005_RANGE_EXTENSION_PROFILES
+  void  codeConstraintInfo      ( const ConstraintInfo* cinfo, const ProfileTierLevel* ptl );
+#else
   void  codeConstraintInfo      ( const ConstraintInfo* cinfo );
+#endif
   void  codeProfileTierLevel    ( const ProfileTierLevel* ptl, bool profileTierPresentFlag, int maxNumSubLayersMinus1 );
   void  codeOlsHrdParameters(const GeneralHrdParams * generalHrd, const OlsHrdParams *olsHrd , const uint32_t firstSubLayer, const uint32_t maxNumSubLayersMinus1);
 
diff --git a/source/Lib/EncoderLib/WeightPredAnalysis.cpp b/source/Lib/EncoderLib/WeightPredAnalysis.cpp
index 6db6870f2..cad3d6cc8 100644
--- a/source/Lib/EncoderLib/WeightPredAnalysis.cpp
+++ b/source/Lib/EncoderLib/WeightPredAnalysis.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/EncoderLib/WeightPredAnalysis.h b/source/Lib/EncoderLib/WeightPredAnalysis.h
index 76c91be5f..7c7c0d333 100644
--- a/source/Lib/EncoderLib/WeightPredAnalysis.h
+++ b/source/Lib/EncoderLib/WeightPredAnalysis.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/Utilities/CMakeLists.txt b/source/Lib/Utilities/CMakeLists.txt
index 83b05cf5d..020a0afed 100644
--- a/source/Lib/Utilities/CMakeLists.txt
+++ b/source/Lib/Utilities/CMakeLists.txt
@@ -28,28 +28,8 @@ if( SET_ENABLE_TRACING )
   endif()
 endif()
 
-if( OpenMP_FOUND )
-  if( SET_ENABLE_SPLIT_PARALLELISM )
-    if( ENABLE_SPLIT_PARALLELISM )
-      target_compile_definitions( ${LIB_NAME} PUBLIC ENABLE_SPLIT_PARALLELISM=1 )
-    else()
-      target_compile_definitions( ${LIB_NAME} PUBLIC ENABLE_SPLIT_PARALLELISM=0 )
-    endif()
-  endif()
-  if( SET_ENABLE_WPP_PARALLELISM )
-    if( ENABLE_WPP_PARALLELISM )
-      target_compile_definitions( ${LIB_NAME} PUBLIC ENABLE_WPP_PARALLELISM=1 )
-    else()
-      target_compile_definitions( ${LIB_NAME} PUBLIC ENABLE_WPP_PARALLELISM=0 )
-    endif()
-  endif()
-else()
-  target_compile_definitions( ${LIB_NAME} PUBLIC ENABLE_SPLIT_PARALLELISM=0 )
-  target_compile_definitions( ${LIB_NAME} PUBLIC ENABLE_WPP_PARALLELISM=0 )
-endif()
-
 target_include_directories( ${LIB_NAME} PUBLIC . .. )
-target_link_libraries( ${LIB_NAME} CommonLib Threads::Threads )
+target_link_libraries( ${LIB_NAME} CommonLib )
 
 # example: place header files in different folders
 source_group( "Natvis Files" FILES ${NATVIS_FILES} )
diff --git a/source/Lib/Utilities/VideoIOYuv.cpp b/source/Lib/Utilities/VideoIOYuv.cpp
index 8a30ccc5d..166b214ac 100644
--- a/source/Lib/Utilities/VideoIOYuv.cpp
+++ b/source/Lib/Utilities/VideoIOYuv.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -948,7 +948,7 @@ bool VideoIOYuv::read ( PelUnitBuf& pic, PelUnitBuf& picOrg, const InputColourSp
 
     if (processComponent)
     {
-      if (! verifyPlane( dst, stride444, width444, height444, pad_h444, pad_v444, compID, format, m_fileBitdepth[chType]) )
+      if (! verifyPlane( dst, stride444, width444, height444, pad_h444, pad_v444, compID, picOrg.chromaFormat, m_fileBitdepth[chType]) )
       {
          EXIT("Source image contains values outside the specified bit range!");
       }
diff --git a/source/Lib/Utilities/VideoIOYuv.h b/source/Lib/Utilities/VideoIOYuv.h
index bf2c47056..8c5fe22e1 100644
--- a/source/Lib/Utilities/VideoIOYuv.h
+++ b/source/Lib/Utilities/VideoIOYuv.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/Utilities/program_options_lite.cpp b/source/Lib/Utilities/program_options_lite.cpp
index 859c59117..dd64f407f 100644
--- a/source/Lib/Utilities/program_options_lite.cpp
+++ b/source/Lib/Utilities/program_options_lite.cpp
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/Utilities/program_options_lite.h b/source/Lib/Utilities/program_options_lite.h
index 6fc3dd337..c21d69a51 100644
--- a/source/Lib/Utilities/program_options_lite.h
+++ b/source/Lib/Utilities/program_options_lite.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/libmd5/MD5.h b/source/Lib/libmd5/MD5.h
index d41a07424..15bf392a2 100644
--- a/source/Lib/libmd5/MD5.h
+++ b/source/Lib/libmd5/MD5.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/source/Lib/libmd5/libmd5.h b/source/Lib/libmd5/libmd5.h
index 4554c73d5..f3ac137ec 100644
--- a/source/Lib/libmd5/libmd5.h
+++ b/source/Lib/libmd5/libmd5.h
@@ -3,7 +3,7 @@
  * and contributor rights, including patent rights, and no such rights are
  * granted under this license.
  *
- * Copyright (c) 2010-2020, ITU/ISO/IEC
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
-- 
GitLab