changeset 12615:b11042b384af stable

Merge with default
author Aruna Matheswaran <aruna@multicorewareinc.com>
date Fri, 31 Jan 2020 00:40:19 +0530
parents 82a66ce12955 (current diff) fdbd4e4a2aff (diff)
children 5ee3593ebd82 dd2464df2f40
files
diffstat 213 files changed, 2377 insertions(+-), 934 deletions(-) [+]
line wrap: on
line diff
--- a/doc/reST/api.rst	Wed Sep 25 17:57:51 2019 +0530
+++ b/doc/reST/api.rst	Fri Jan 31 00:40:19 2020 +0530
@@ -191,7 +191,15 @@ changes made to the parameters for auto-
 	 *      switched out of; using reconfig to switch between ultrafast and other
 	 *      presets is not recommended without a more fine-grained breakdown of
 	 *      parameters to take this into account. */
-	int x265_encoder_reconfig(x265_encoder *, x265_param *);
+    int x265_encoder_reconfig(x265_encoder *, x265_param *);
+
+**x265_encoder_reconfig_zone()** Used to reconfigure rate-contol settings of zones mid-encode::
+
+    /* x265_encoder_reconfig_zone:
+     *      Properties of the zone will be copied to encoder's param and will be used only to
+     *      influence rate-control decisions of the zone.
+     *      returns 0 on successful copy and negative on failure.*/
+    int x265_encoder_reconfig(x265_encoder *, x265_param *);
 
 **x265_get_slicetype_poc_and_scenecut()** may be used to fetch slice type, poc and scene cut information mid-encode::
 
--- a/doc/reST/cli.rst	Wed Sep 25 17:57:51 2019 +0530
+++ b/doc/reST/cli.rst	Fri Jan 31 00:40:19 2020 +0530
@@ -501,6 +501,17 @@ frame counts) are only applicable to the
 	second. The decoder must re-combine the fields in their correct
 	orientation for display.
 
+.. option:: --frame-dup, --no-frame-dup
+
+	Enable Adaptive Frame duplication. Replaces 2-3 near-identical frames with one 
+	frame and sets pic_struct based on frame doubling / tripling. 
+	Default disabled.
+
+.. option:: --dup-threshold <integer>
+
+	Frame similarity threshold can vary between 1 and 99. This requires Adaptive
+	Frame Duplication to be enabled. Default 70.
+
 .. option:: --seek <integer>
 
 	Number of frames to skip at start of input file. Default 0
@@ -894,25 +905,30 @@ will not reuse analysis if slice type pa
 	Encoder outputs analysis information of each frame. Analysis data from save mode is
 	written to the file specified. Requires cutree, pmode to be off. Default disabled.
 	
+	The amount of analysis data stored is determined by :option:`--analysis-save-reuse-level`.
+	
 .. option:: --analysis-load <filename>
 
 	Encoder reuses analysis information from the file specified. By reading the analysis data writen by
 	an earlier encode of the same sequence, substantial redundant work may be avoided. Requires cutree, pmode
 	to be off. Default disabled.
 
-	The amount of analysis data stored/reused is determined by :option:`--analysis-reuse-level`.
+	The amount of analysis data reused is determined by :option:`--analysis-load-reuse-level`.
 
 .. option:: --analysis-reuse-file <filename>
 
-	Specify a filename for `multi-pass-opt-analysis` and `multi-pass-opt-distortion`.
+	Specify a filename for :option:`--multi-pass-opt-analysis` and option:`--multi-pass-opt-distortion`.
 	If no filename is specified, x265_analysis.dat is used.
 
-.. option:: --analysis-reuse-level <1..10>
-
-	Amount of information stored/reused in :option:`--analysis-reuse-mode` is distributed across levels.
-	Higher the value, higher the information stored/reused, faster the encode. Default 5.
-
-	Note that --analysis-reuse-level must be paired with analysis-reuse-mode.
+.. option:: --analysis-save-reuse-level <1..10>, --analysis-load-reuse-level <1..10>
+
+	'analysis-save-reuse-level' denotes the amount of information stored during :option:`--analysis-save` and
+	'analysis-load-reuse-level' denotes the amount of information reused during :option:`--analysis-load`.
+	Higher the value, higher the information stored/reused, faster the encode. Default 0. If not set during analysis-save/load,
+	the encoder will internally configure them to 5.
+
+	Note that :option:`--analysis-save-reuse-level` and :option:`--analysis-load-reuse-level` must be paired
+	with :option:`--analysis-save` and :option:`--analysis-load` respectively.
 
 	+--------------+------------------------------------------+
 	| Level        | Description                              |
@@ -939,15 +955,15 @@ will not reuse analysis if slice type pa
 
     Store/normalize ctu distortion in analysis-save/load.
     0 - Disabled.
-    1 - Save ctu distortion to the analysis file specified during analysis-save.
-        Load CTU distortion from the analysis file and normalize it across every frame during analysis-load.
+    1 - Save ctu distortion to the analysis file specified during :option:`--analysis-save`.
+        Load CTU distortion from the analysis file and normalize it across every frame during :option:`--analysis-load`.
     Default 0.
 
 .. option:: --scale-factor
 
 	Factor by which input video is scaled down for analysis save mode.
-	This option should be coupled with analysis-reuse-mode option, 
-	--analysis-reuse-level 10. The ctu size of load can either be the 
+	This option should be coupled with :option:`--analysis-load`/:option:`--analysis-save` 
+	at reuse levels 1 to 6 and 10. The ctu size of load can either be the 
 	same as that of save or double the size of save. Default 0.
 
 .. option:: --refine-intra <0..4>
@@ -1079,9 +1095,9 @@ as the residual quad-tree (RQT).
 	limiting depth for the other subTUs.
 	
 	Enabling levels 3 or 4 may cause a mismatch in the output bitstreams 
-	between option:`--analysis-save` and option:`--analysis-load`
+	between :option:`--analysis-save` and :option:`--analysis-load`
 	as all neighbouring CUs TU depth may not be available in the 
-	option:`--analysis-load` run as only the best mode's information is 
+	:option:`--analysis-load` run as only the best mode's information is 
 	available to it.
 	
 	Default: 0
@@ -1187,9 +1203,10 @@ Temporal / motion search options
 	followed by an optional star-search refinement. Full is an
 	exhaustive search; an order of magnitude slower than all other
 	searches but not much better than umh or star. SEA is similar to
-	FULL search; a three step motion search adopted from x264: DC 
-	calculation followed by ADS calculation followed by SAD of the
-	passed motion vector candidates, hence faster than Full search. 
+	x264's ESA implementation and a speed optimization of full search.
+    It is a three step motion search where the DC calculation is
+    followed by ADS calculation followed by SAD of the passed motion
+    vector candidates.
 
 	0. dia
 	1. hex **(default)**
@@ -1279,6 +1296,12 @@ Temporal / motion search options
        which will apply to all levels. Default is hex,umh,umh for 
        levels 0,1,2 respectively.
 
+.. option:: --hme-range <integer>,<integer>,<integer>
+
+	Search range for HME level 0, 1 and 2.
+	The Search Range for each HME level must be between 0 and 32768(excluding).
+	Default search range is 16,32,48 for level 0,1,2 respectively.
+
 Spatial/intra options
 =====================
 
@@ -1415,7 +1438,20 @@ Slice decision options
 	This value represents the percentage difference between the inter cost and
 	intra cost of a frame used in scenecut detection. For example, a value of 5 indicates,
 	if the inter cost of a frame is greater than or equal to 95 percent of the intra cost of the frame,
-	then detect this frame as scenecut. Values between 5 and 15 are recommended. Default 5.
+	then detect this frame as scenecut. Values between 5 and 15 are recommended. Default 5. 
+
+.. option:: --hist-scenecut, --no-hist-scenecut
+
+	Indicates that scenecuts need to be detected using luma edge and chroma histograms.
+	:option: `--hist-scenecut` enables scenecut detection using the histograms and disables the default scene cut algorithm.
+	:option: `--no-hist-scenecut` disables histogram based scenecut algorithm.
+	
+.. option:: --hist-threshold <0.0..2.0>
+
+	This value represents the threshold for normalized SAD of edge histograms used in scenecut detection.
+	This requires :option: `--hist-scenecut` to be enabled. For example, a value of 0.2 indicates that a frame with normalized SAD value 
+	greater than 0.2 against the previous frame as scenecut. 
+	Default 0.01.
 	
 .. option:: --radl <integer>
 	
@@ -1761,8 +1797,8 @@ Quality, rate control and rate distortio
 	and also redundant steps are skipped.
 	In pass 1 analysis information like motion vector, depth, reference and prediction
 	modes of the final best CTU partition is stored for each CTU.
-	Multipass analysis refinement cannot be enabled when 'analysis-save/analysis-load' option
-	is enabled and both will be disabled when enabled together. This feature requires 'pmode/pme'
+	Multipass analysis refinement cannot be enabled when :option:`--analysis-save`/:option:`analysis-load`
+	is enabled and both will be disabled when enabled together. This feature requires :option:`--pmode`/:option:`--pme`
 	to be disabled and hence pmode/pme will be disabled when enabled at the same time.
 
 	Default: disabled.
@@ -1773,9 +1809,9 @@ Quality, rate control and rate distortio
 	ratecontrol. In pass 1 distortion of best CTU partition is stored. CTUs with high
 	distortion get lower(negative)qp offsets and vice-versa for low distortion CTUs in pass 2.
 	This helps to improve the subjective quality.
-	Multipass refinement of qp cannot be enabled when 'analysis-save/analysis-load' option
-	is enabled and both will be disabled when enabled together. 'multi-pass-opt-distortion' 
-	requires 'pmode/pme' to be disabled and hence pmode/pme will be disabled when enabled along with it.
+	Multipass refinement of qp cannot be enabled when :option:`--analysis-save`/:option:`--analysis-load`
+	is enabled and both will be disabled when enabled together. It requires :option:`--pmode`/:option:`--pme` to be
+	disabled and hence pmode/pme will be disabled when enabled along with it.
 
 	Default: disabled.
 
@@ -1887,6 +1923,28 @@ Quality, rate control and rate distortio
 	
 	**CLI ONLY**
 
+.. option:: --scenecut-aware-qp, --no-scenecut-aware-qp
+   
+   Enables a ratecontrol algorithm for reducing the bits spent on the inter-frames
+   within the :option:`--scenecut-window` after a scenecut by increasing their QP
+   without any deterioration in visual quality. It also increases the quality of
+   scenecut I-Frames by reducing their QP. Default disabled.
+   
+.. option:: --scenecut-window <integer>
+
+   The duration(in milliseconds) for which there is a reduction in the bits spent
+   on the inter-frames after a scenecut by increasing their QP, when
+   :option:`--scenecut-aware-qp` is enabled. Default 500ms.
+   
+   **Range of values:** 0 to 1000
+   
+.. option:: --max-qp-delta <integer>
+
+   The offset by which QP is incremented for inter-frames
+   when :option:`--scenecut-aware-qp` is enabled. Default 5.
+   
+   **Range of values:**  0 to 10
+
 Quantization Options
 ====================
 
@@ -2198,18 +2256,20 @@ VUI fields must be manually specified.
     is specified. When enabled, signals max-cll and max-fall as 0 if :option:`max-cll` is unspecified.
     Default enabled.
 
-.. option:: --hdr, --no-hdr
-
-	Force signalling of HDR parameters in SEI packets. Enabled
+.. option:: --hdr10, --no-hdr10
+
+	Force signaling of HDR10 parameters in SEI packets. Enabled
 	automatically when :option:`--master-display` or :option:`--max-cll` is
 	specified. Useful when there is a desire to signal 0 values for max-cll
 	and max-fall. Default disabled.
 
-.. option:: --hdr-opt, --no-hdr-opt
-
-	Add luma and chroma offsets for HDR/WCG content.
-	Input video should be 10 bit 4:2:0. Applicable for HDR content. It is recommended
-	that AQ-mode be enabled along with this feature. Default disabled.
+.. option:: --hdr10-opt, --no-hdr10-opt
+
+	Enable block-level luma and chroma QP optimization for HDR10 content
+	as suggested in ITU-T H-series Recommendations  Supplement 15.
+	Source video should have HDR10 characteristics such as 10-bit depth 4:2:0
+	with Bt.2020 color primaries and SMPTE ST.2084 transfer characteristics.
+	It is recommended that AQ-mode be enabled along with this feature. Default disabled.
 
 .. option:: --dhdr10-info <filename>
 
@@ -2383,9 +2443,11 @@ Bitstream options
 	Only effective at RD levels 5 and 6
 
 .. option:: --idr-recovery-sei, --no-idr-recovery-sei
+
 	Emit RecoveryPoint info as sei in bitstream for each IDR frame. Default disabled.
 
 .. option:: --single-sei, --no-single-sei
+
 	Emit SEI messages in a single NAL unit instead of multiple NALs. Default disabled.
 	When HRD SEI is enabled the HM decoder will throw a warning.
 
@@ -2489,12 +2551,12 @@ See section :ref:`svthevc <SvtHevc>` for
 
 .. option:: --svt-preset-tuner <integer>
 
-    SVT-HEVC exposes 13 presets. Presets [3-12] of SVT-HEVC is mapped to x265's
-    presets [placebo-ultrafast]. Ultrafast is mapped to preset(12) of SVT-HEVC,
-    superfast to preset(11), placebo to preset(3) and so on. svt-preset-tuner works
-    only on top of placebo preset and maps to presets (0-2) of SVT-HEVC.
-
-    Values: [0-2]
+    SVT-HEVC exposes 12 presets. Presets [2-11] of SVT-HEVC is mapped to x265's
+    presets [placebo-ultrafast]. Ultrafast is mapped to preset(11) of SVT-HEVC,
+    superfast to preset(10), placebo to preset(2) and so on. svt-preset-tuner works
+    only on top of placebo preset and maps to presets (0-1) of SVT-HEVC.
+
+    Values: [0-1]
 
     **CLI_ONLY**
 
--- a/doc/reST/presets.rst	Wed Sep 25 17:57:51 2019 +0530
+++ b/doc/reST/presets.rst	Fri Jan 31 00:40:19 2020 +0530
@@ -67,9 +67,9 @@ changed from the value specified by the 
 +-----------------+-----+-----+-----+-----+-----+-----+------+------+------+------+
 | max-merge       |  2  |  2  |  2  |   2 |   2 |   2 |   3  |   4  |   5  |  5   |
 +-----------------+-----+-----+-----+-----+-----+-----+------+------+------+------+
-| early-skip      |  1  |  1  |  1  |   1 |   0 |   0 |   0  |   0  |   0  |  0   |
+| early-skip      |  1  |  1  |  1  |   1 |   0 |   1 |   0  |   0  |   0  |  0   |
 +-----------------+-----+-----+-----+-----+-----+-----+------+------+------+------+
-| recursion-skip  |  1  |  1  |  1  |   1 |   1 |   1 |   1  |   0  |   0  |  0   |
+| recursion-skip  |  1  |  1  |  1  |   1 |   1 |   1 |   1  |   1  |   1  |  0   |
 +-----------------+-----+-----+-----+-----+-----+-----+------+------+------+------+
 | fast-intra      |  1  |  1  |  1  |   1 |   1 |   0 |   0  |   0  |   0  |  0   |
 +-----------------+-----+-----+-----+-----+-----+-----+------+------+------+------+
--- a/doc/reST/svthevc.rst	Wed Sep 25 17:57:51 2019 +0530
+++ b/doc/reST/svthevc.rst	Fri Jan 31 00:40:19 2020 +0530
@@ -12,6 +12,10 @@ API should be used for all param assignm
 wont't be mapped to SVT-HEVC. This document describes the steps needed to compile x265 
 with SVT-HEVC and CLI options mapping between x265 and SVT-HEVC.
 
+Supported Version
+=================
+Version - 1.4.1
+
 Build Steps
 ===========
 This section describes the build steps to be followed to link SVT-HEVC with x265.
@@ -109,7 +113,15 @@ SVT-HEVC encoder options (Name as shown 
 +-------------------------------------------+------------------------------+------------------------------+
 | :option:`--nalu-file`                     | NaluFile                     | Any String                   |
 +-------------------------------------------+------------------------------+------------------------------+
-| :option:`--tune` zerolatency              | LatencyMode                  |                              |
+| :option:`--hrd`                           | hrdFlag                      | [0, 1]                       |
++-------------------------------------------+------------------------------+------------------------------+
+| :option:`--vbv-maxrate`                   | vbvMaxrate                   | Any Positive Integer         |
++-------------------------------------------+------------------------------+------------------------------+
+| :option:`--vbv-bufsize`                   | vbvBufsize                   | Any Positive Integer         |
++-------------------------------------------+------------------------------+------------------------------+
+| :option:`--vbv-init`                      | VbvBufInit                   | [0 - 100]                    |
++-------------------------------------------+------------------------------+------------------------------+
+| :option:`--frame-threads`                 | ThreadCount                  | Any Number                   |
 +-------------------------------------------+------------------------------+------------------------------+
 | :option:`--svt-search-width`              | SearchAreaWidth              | [1 - 256]                    |
 +-------------------------------------------+------------------------------+------------------------------+
@@ -139,64 +151,37 @@ section in the above table. Options star
 fecilitate access to the features of SVT-HEVC which couldn't be mapped to the existing x265 CLI's. 
 So these options will have effect only if SVT-HEVC is enabled and would be ignored with default x265 encode.
 
-Preset & Tune Options Mapping
+Preset Option Mapping
 =============================
-x265 has 10 presets from ultrafast to placebo whereas SVT-HEVC has 13 presets. Use :option:`--svt-preset-tuner` 
-with Placebo preset to access the additional 3 presets of SVT-HEVC. Note that :option:`--svt-preset-tuner` should be 
+x265 has 10 presets from ultrafast to placebo whereas SVT-HEVC has 12 presets. Use :option:`--svt-preset-tuner` 
+with Placebo preset to access the additional 2 presets of SVT-HEVC. Note that :option:`--svt-preset-tuner` should be 
 used only if SVT-HEVC is enabled and only with Placebo preset, would be ignored otherwise. 
 Below table shows the actual mapping of presets,
 
 +----------------------------------------+------------------------------+
 | x265 Preset                            | SVT-HEVC Preset              |
 +========================================+==============================+
-| Ultrafast                              | 12                           |
-+----------------------------------------+------------------------------+
-| Superfast                              | 11                           |
-+----------------------------------------+------------------------------+
-| Veryfast                               | 10                           |
-+----------------------------------------+------------------------------+
-| Faster                                 | 9                            |
+| Ultrafast                              | 11                           |
 +----------------------------------------+------------------------------+
-| Fast                                   | 8                            |
-+----------------------------------------+------------------------------+
-| Medium                                 | 7                            |
+| Superfast                              | 10                           |
 +----------------------------------------+------------------------------+
-| Slow                                   | 6                            |
+| Veryfast                               | 9                            |
 +----------------------------------------+------------------------------+
-| Slower                                 | 5                            |
+| Faster                                 | 8                            |
 +----------------------------------------+------------------------------+
-| Veryslow                               | 4                            |
+| Fast                                   | 7                            |
 +----------------------------------------+------------------------------+
-| Placebo                                | 3                            |
+| Medium                                 | 6                            |
++----------------------------------------+------------------------------+
+| Slow                                   | 5                            |
++----------------------------------------+------------------------------+
+| Slower                                 | 4                            |
++----------------------------------------+------------------------------+
+| Veryslow                               | 3                            |
++----------------------------------------+------------------------------+
+| Placebo                                | 2                            |
 +----------------------------------------+------------------------------+
 | Placebo :option:`--svt-preset-tuner` 0 | 0                            |
 +----------------------------------------+------------------------------+
 | Placebo :option:`--svt-preset-tuner` 1 | 1                            |
 +----------------------------------------+------------------------------+
-| Placebo :option:`--svt-preset-tuner` 2 | 2                            |
-+----------------------------------------+------------------------------+
-
-x265 has 5 tune modes (psnr, ssim, grain, zero-latency, animation) whereas SVT-HEVC
-has only 3 tune modes (0 - visual quality, 1 - PSNR / SSIM and 2 - VMAF). Below 
-table shows the mapping of tune modes,
-
-+-----------------------+---------------------------+
-| x265 Tune Modes       | SVT-HEVC Tune Modes       |
-+=======================+===========================+
-| vmaf                  | 2                         |
-+-----------------------+---------------------------+
-| psnr                  | 1                         |
-+-----------------------+---------------------------+
-| ssim                  | 1                         |
-+-----------------------+---------------------------+
-| grain                 | 0                         |
-+-----------------------+---------------------------+
-| fastdecode            | 0                         |
-+-----------------------+---------------------------+
-| zerolatency           | 0                         |
-+-----------------------+---------------------------+
-| animation             | 0                         |
-+-----------------------+---------------------------+
-
-Note that : 1.option:`--tune` animation is also mapped to "LatencyMode" of SVT-HEVC.
-            2.option: '--tune' vmaf is not supported in x265, its under development.
--- a/source/CMakeLists.txt	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/CMakeLists.txt	Fri Jan 31 00:40:19 2020 +0530
@@ -29,7 +29,7 @@ option(NATIVE_BUILD "Target the build CP
 option(STATIC_LINK_CRT "Statically link C runtime for release builds" OFF)
 mark_as_advanced(FPROFILE_USE FPROFILE_GENERATE NATIVE_BUILD)
 # X265_BUILD must be incremented each time the public API is changed
-set(X265_BUILD 179)
+set(X265_BUILD 188)
 configure_file("${PROJECT_SOURCE_DIR}/x265.def.in"
                "${PROJECT_BINARY_DIR}/x265.def")
 configure_file("${PROJECT_SOURCE_DIR}/x265_config.h.in"
@@ -573,8 +573,7 @@ endif()
 if(SVTHEVC_FOUND)
     install(FILES "${SVT_HEVC_INCLUDE_DIR}/EbApi.h" DESTINATION include)
     install(FILES "${SVT_HEVC_INCLUDE_DIR}/EbErrorCodes.h" DESTINATION include)
-    install(FILES "${SVT_HEVC_INCLUDE_DIR}/EbTime.h" DESTINATION include)
-    install(FILES "${SVT_HEVC_LIBRARY}" DESTINATION ${BIN_INSTALL_DIR})
+    install(FILES "${SVT_HEVC_LIBRARY}" DESTINATION ${LIB_INSTALL_DIR})
 endif()
 
 install(FILES x265.h "${PROJECT_BINARY_DIR}/x265_config.h" DESTINATION include)
--- a/source/cmake/FindNuma.cmake	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/cmake/FindNuma.cmake	Fri Jan 31 00:40:19 2020 +0530
@@ -14,7 +14,7 @@
 #   NUMA_LIBRARY
 #     Points to the libnuma that can be passed to target_link_libararies.
 #
-# Copyright (c) 2013-2017 MulticoreWare, Inc
+# Copyright (c) 2013-2020 MulticoreWare, Inc
 
 include(FindPackageHandleStandardArgs)
 
--- a/source/cmake/FindVLD.cmake	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/cmake/FindVLD.cmake	Fri Jan 31 00:40:19 2020 +0530
@@ -23,7 +23,7 @@
 #     target_link_libararies.
 #
 #
-# Copyright (c) 2013-2017 MulticoreWare, Inc
+# Copyright (c) 2013-2020 MulticoreWare, Inc
 #
 # Permission is hereby granted, free of charge, to any person obtaining a copy
 # of this software and associated documentation files (the "Software"), to deal
--- a/source/cmake/FindVtune.cmake	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/cmake/FindVtune.cmake	Fri Jan 31 00:40:19 2020 +0530
@@ -5,7 +5,7 @@
 #   VTUNE_INCLUDE_DIR: Points to the vtunes include dir
 #   VTUNE_LIBRARY_DIR: Points to the directory with libraries
 #
-# Copyright (c) 2013-2017 MulticoreWare, Inc
+# Copyright (c) 2013-2020 MulticoreWare, Inc
 
 include(FindPackageHandleStandardArgs)
 
--- a/source/cmake/Findsvthevc.cmake	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/cmake/Findsvthevc.cmake	Fri Jan 31 00:40:19 2020 +0530
@@ -15,34 +15,37 @@ else()
 SET(CMAKE_FIND_LIBRARY_SUFFIXES ".lib")
 endif()
 
-set(SVT_VERSION_MAJOR_REQUIRED 1)
-set(SVT_VERSION_MINOR_REQUIRED 3)
-set(SVT_VERSION_PATCHLEVEL_REQUIRED 0)
+set(SVT_VERSION_MAJOR_REQUIRED       1)
+set(SVT_VERSION_MINOR_REQUIRED       4)
+set(SVT_VERSION_PATCHLEVEL_REQUIRED  1)
 
 find_path(SVT_HEVC_INCLUDE_DIR
-    NAMES EbApi.h EbErrorCodes.h EbTime.h
+    NAMES EbApiVersion.h EbErrorCodes.h
     HINTS $ENV{SVT_HEVC_INCLUDE_DIR}
     PATHS ENV
     DOC "SVT-HEVC include directory")
 
 if(SVT_HEVC_INCLUDE_DIR)
-file(READ "${SVT_HEVC_INCLUDE_DIR}/EbApi.h" version)
-
-string(REGEX MATCH "SVT_VERSION_MAJOR       ([0-9]*)" _ ${version})
-set(SVT_VERSION_MAJOR ${CMAKE_MATCH_1})
-
-string(REGEX MATCH "SVT_VERSION_MINOR       ([0-9]*)" _ ${version})
-set(SVT_VERSION_MINOR ${CMAKE_MATCH_1})
+    if(EXISTS "${SVT_HEVC_INCLUDE_DIR}/EbApiVersion.h")
+        file(READ "${SVT_HEVC_INCLUDE_DIR}/EbApiVersion.h" version)
 
-string(REGEX MATCH "SVT_VERSION_PATCHLEVEL  ([0-9]*)" _ ${version})
-set(SVT_VERSION_PATCHLEVEL ${CMAKE_MATCH_1})
+        string(REGEX MATCH "SVT_VERSION_MAJOR       \\(([0-9]*)\\)" _ ${version})
+        set(SVT_VERSION_MAJOR ${CMAKE_MATCH_1})
 
-if(NOT ${SVT_VERSION_MAJOR} EQUAL "1" OR NOT ${SVT_VERSION_MINOR} EQUAL "3" OR NOT ${SVT_VERSION_PATCHLEVEL} EQUAL "0")
-    message (SEND_ERROR "-- Found SVT-HEVC Lib Version: ${SVT_VERSION_MAJOR}.${SVT_VERSION_MINOR}.${SVT_VERSION_PATCHLEVEL} which doesn't match the required version: ${SVT_VERSION_MAJOR_REQUIRED}.${SVT_VERSION_MINOR_REQUIRED}.${SVT_VERSION_PATCHLEVEL_REQUIRED}; Aborting configure  ")
-else()
-    message(STATUS "-- Found SVT-HEVC Lib Version: ${SVT_VERSION_MAJOR}.${SVT_VERSION_MINOR}.${SVT_VERSION_PATCHLEVEL}")
-endif()
+        string(REGEX MATCH "SVT_VERSION_MINOR       \\(([0-9]*)\\)" _ ${version})
+        set(SVT_VERSION_MINOR ${CMAKE_MATCH_1})
 
+        string(REGEX MATCH "SVT_VERSION_PATCHLEVEL  \\(([0-9]*)\\)" _ ${version})
+        set(SVT_VERSION_PATCHLEVEL ${CMAKE_MATCH_1})
+
+        if(NOT ${SVT_VERSION_MAJOR} EQUAL "1" OR NOT ${SVT_VERSION_MINOR} EQUAL "4" OR NOT ${SVT_VERSION_PATCHLEVEL} EQUAL "1")
+            message (SEND_ERROR "-- Found SVT-HEVC Lib Version: ${SVT_VERSION_MAJOR}.${SVT_VERSION_MINOR}.${SVT_VERSION_PATCHLEVEL} which doesn't match the required version: ${SVT_VERSION_MAJOR_REQUIRED}.${SVT_VERSION_MINOR_REQUIRED}.${SVT_VERSION_PATCHLEVEL_REQUIRED}; Aborting configure  ")
+        else()
+            message(STATUS "-- Found SVT-HEVC Lib Version: ${SVT_VERSION_MAJOR}.${SVT_VERSION_MINOR}.${SVT_VERSION_PATCHLEVEL}")
+        endif()
+    else()
+        message (SEND_ERROR "-- Required version of SVT-HEVC Lib: ${SVT_VERSION_MAJOR_REQUIRED}.${SVT_VERSION_MINOR_REQUIRED}.${SVT_VERSION_PATCHLEVEL_REQUIRED}; Aborting configure  ")
+    endif()
 endif()
 
 find_library(SVT_HEVC_LIBRARY
--- a/source/common/arm/asm-primitives.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/arm/asm-primitives.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *          Praveen Kumar Tiwari <praveen@multicorewareinc.com>
--- a/source/common/arm/asm.S	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/arm/asm.S	Fri Jan 31 00:40:19 2020 +0530
@@ -1,7 +1,7 @@
 /*****************************************************************************
  * asm.S: arm utility macros
  *****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Mans Rullgard <mans@mansr.com>
  *          David Conrad <lessen42@gmail.com>
--- a/source/common/arm/blockcopy8.S	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/arm/blockcopy8.S	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Radhakrishnan VR <radhakrishnan@multicorewareinc.com>
  * 
--- a/source/common/arm/blockcopy8.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/arm/blockcopy8.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *          Min Chen <chenm003@163.com>
--- a/source/common/arm/cpu-a.S	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/arm/cpu-a.S	Fri Jan 31 00:40:19 2020 +0530
@@ -1,7 +1,7 @@
 /*****************************************************************************
  * cpu-a.S: arm cpu detection
  *****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: David Conrad <lessen42@gmail.com>
  *          Dnyaneshwar Gorade <dnyaneshwar@multicorewareinc.com>
--- a/source/common/arm/dct-a.S	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/arm/dct-a.S	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Min Chen <chenm003@163.com>
  * 
--- a/source/common/arm/dct8.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/arm/dct8.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Min Chen <chenm003@163.com>
  *          Dnyaneshwar Gorade <dnyaneshwar@multicorewareinc.com>
--- a/source/common/arm/intrapred.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/arm/intrapred.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,7 +1,7 @@
 /*****************************************************************************
  * intrapred.h: Intra Prediction metrics
  *****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Min Chen <chenm003@163.com> <min.chen@multicorewareinc.com>
  *          Praveen Kumar Tiwari <praveen@multicorewareinc.com>
--- a/source/common/arm/ipfilter8.S	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/arm/ipfilter8.S	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Dnyaneshwar G <dnyaneshwar@multicorewareinc.com>
  *          Radhakrishnan VR <radhakrishnan@multicorewareinc.com>
--- a/source/common/arm/ipfilter8.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/arm/ipfilter8.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *          Dnyaneshwar Gorade <dnyaneshwar@multicorewareinc.com>
--- a/source/common/arm/loopfilter.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/arm/loopfilter.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Dnyaneshwar Gorade <dnyaneshwar@multicorewareinc.com>
  *          Praveen Kumar Tiwari <praveen@multicorewareinc.com>
--- a/source/common/arm/mc-a.S	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/arm/mc-a.S	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Dnyaneshwar Gorade <dnyaneshwar@multicorewareinc.com>
  *          Radhakrishnan <radhakrishnan@multicorewareinc.com>
--- a/source/common/arm/mc.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/arm/mc.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *
--- a/source/common/arm/pixel-util.S	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/arm/pixel-util.S	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Dnyaneshwar G <dnyaneshwar@multicorewareinc.com>
  *          Radhakrishnan VR <radhakrishnan@multicorewareinc.com>
--- a/source/common/arm/pixel-util.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/arm/pixel-util.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
 ;*          Min Chen <chenm003@163.com>
--- a/source/common/arm/pixel.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/arm/pixel.h	Fri Jan 31 00:40:19 2020 +0530
@@ -2,7 +2,7 @@
  * pixel.h: x86 pixel metrics
  *****************************************************************************
  * Copyright (C) 2003-2017 x265 project
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *          Loren Merritt <lorenm@u.washington.edu>
--- a/source/common/arm/sad-a.S	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/arm/sad-a.S	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: David Conrad <lessen42@gmail.com>
  *          Janne Grunau <janne-x264@jannau.net>
--- a/source/common/arm/ssd-a.S	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/arm/ssd-a.S	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Dnyaneshwar G <dnyaneshwar@multicorewareinc.com>
  * 
--- a/source/common/bitstream.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/bitstream.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Author: Steve Borho <steve@borho.org>
  *         Min Chen <chenm003@163.com>
--- a/source/common/common.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/common.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Deepthi Nandakumar <deepthi@multicorewareinc.com>
  *
--- a/source/common/common.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/common.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Deepthi Nandakumar <deepthi@multicorewareinc.com>
  *          Min Chen <chenm003@163.com>
@@ -129,12 +129,16 @@ typedef uint32_t sum_t;
 typedef uint64_t sum2_t;
 typedef uint64_t pixel4;
 typedef int64_t  ssum2_t;
+#define HISTOGRAM_BINS 1024
+#define SHIFT 1
 #else
 typedef uint8_t  pixel;
 typedef uint16_t sum_t;
 typedef uint32_t sum2_t;
 typedef uint32_t pixel4;
 typedef int32_t  ssum2_t; // Signed sum
+#define HISTOGRAM_BINS 256
+#define SHIFT 0
 #endif // if HIGH_BIT_DEPTH
 
 #if X265_DEPTH < 10
--- a/source/common/constants.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/constants.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
-* Copyright (C) 2013-2017 MulticoreWare, Inc
+* Copyright (C) 2013-2020 MulticoreWare, Inc
 *
 * Authors: Steve Borho <steve@borho.org>
 *          Min Chen <chenm003@163.com>
--- a/source/common/constants.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/constants.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *          Min Chen <chenm003@163.com>
--- a/source/common/contexts.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/contexts.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
-* Copyright (C) 2013-2017 MulticoreWare, Inc
+* Copyright (C) 2013-2020 MulticoreWare, Inc
 *
 * Authors: Steve Borho <steve@borho.org>
 *          Min Chen <chenm003@163.com>
--- a/source/common/cpu.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/cpu.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Loren Merritt <lorenm@u.washington.edu>
  *          Laurent Aimar <fenrir@via.ecp.fr>
--- a/source/common/cpu.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/cpu.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Loren Merritt <lorenm@u.washington.edu>
  *          Steve Borho <steve@borho.org>
--- a/source/common/cudata.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/cudata.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *          Min Chen <chenm003@163.com>
--- a/source/common/cudata.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/cudata.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *
--- a/source/common/dct.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/dct.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Mandar Gurav <mandar@multicorewareinc.com>
  *          Deepthi Devaki Akkoorath <deepthidevaki@multicorewareinc.com>
--- a/source/common/deblock.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/deblock.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
-* Copyright (C) 2013-2017 MulticoreWare, Inc
+* Copyright (C) 2013-2020 MulticoreWare, Inc
 *
 * Author: Gopu Govindaswamy <gopu@multicorewareinc.com>
 *         Min Chen <chenm003@163.com>
--- a/source/common/deblock.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/deblock.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
-* Copyright (C) 2013-2017 MulticoreWare, Inc
+* Copyright (C) 2013-2020 MulticoreWare, Inc
 *
 * Author: Gopu Govindaswamy <gopu@multicorewareinc.com>
 *         Min Chen <chenm003@163.com>
--- a/source/common/frame.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/frame.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
-* Copyright (C) 2013-2017 MulticoreWare, Inc
+* Copyright (C) 2013-2020 MulticoreWare, Inc
 *
 * Author: Steve Borho <steve@borho.org>
 *         Min Chen <chenm003@163.com>
@@ -57,6 +57,10 @@ Frame::Frame()
     m_addOnPrevChange = NULL;
     m_classifyFrame = false;
     m_fieldNum = 0;
+    m_picStruct = 0;
+    m_edgePic = NULL;
+    m_gaussianPic = NULL;
+    m_thetaPic = NULL;
 }
 
 bool Frame::create(x265_param *param, float* quantOffsets)
@@ -97,6 +101,20 @@ bool Frame::create(x265_param *param, fl
         CHECKED_MALLOC_ZERO(m_classifyCount, uint32_t, size);
     }
 
+    if (param->rc.aqMode == X265_AQ_EDGE || (param->rc.zonefileCount && param->rc.aqMode != 0))
+    {
+        uint32_t numCuInWidth = (param->sourceWidth + param->maxCUSize - 1) / param->maxCUSize;
+        uint32_t numCuInHeight = (param->sourceHeight + param->maxCUSize - 1) / param->maxCUSize;
+        uint32_t m_lumaMarginX = param->maxCUSize + 32; // search margin and 8-tap filter half-length, padded for 32-byte alignment
+        uint32_t m_lumaMarginY = param->maxCUSize + 16; // margin for 8-tap filter and infinite padding
+        intptr_t m_stride = (numCuInWidth * param->maxCUSize) + (m_lumaMarginX << 1);
+        int maxHeight = numCuInHeight * param->maxCUSize;
+
+        m_edgePic = X265_MALLOC(pixel, m_stride * (maxHeight + (m_lumaMarginY * 2)));
+        m_gaussianPic = X265_MALLOC(pixel, m_stride * (maxHeight + (m_lumaMarginY * 2)));
+        m_thetaPic = X265_MALLOC(pixel, m_stride * (maxHeight + (m_lumaMarginY * 2)));
+    }
+
     if (m_fencPic->create(param, !!m_param->bCopyPicToFrame) && m_lowres.create(param, m_fencPic, param->rc.qgSize))
     {
         X265_CHECK((m_reconColCount == NULL), "m_reconColCount was initialized");
@@ -242,4 +260,11 @@ void Frame::destroy()
         X265_FREE_ZERO(m_classifyVariance);
         X265_FREE_ZERO(m_classifyCount);
     }
+
+    if (m_param->rc.aqMode == X265_AQ_EDGE || (m_param->rc.zonefileCount && m_param->rc.aqMode != 0))
+    {
+        X265_FREE(m_edgePic);
+        X265_FREE(m_gaussianPic);
+        X265_FREE(m_thetaPic);
+    }
 }
--- a/source/common/frame.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/frame.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
-* Copyright (C) 2013-2017 MulticoreWare, Inc
+* Copyright (C) 2013-2020 MulticoreWare, Inc
 *
 * Author: Steve Borho <steve@borho.org>
 *         Min Chen <chenm003@163.com>
@@ -98,6 +98,7 @@ public:
 
     float*                 m_quantOffsets;       // points to quantOffsets in x265_picture
     x265_sei               m_userSEI;
+    uint32_t               m_picStruct;          // picture structure SEI message
     x265_dolby_vision_rpu            m_rpu;
 
     /* Frame Parallelism - notification between FrameEncoders of available motion reference rows */
@@ -131,6 +132,11 @@ public:
     bool                   m_classifyFrame;
     int                    m_fieldNum;
 
+    /* aq-mode 4 : Gaussian, edge and theta frames for edge information */
+    pixel*                 m_edgePic;
+    pixel*                 m_gaussianPic;
+    pixel*                 m_thetaPic;
+
     Frame();
 
     bool create(x265_param *param, float* quantOffsets);
--- a/source/common/framedata.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/framedata.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
-* Copyright (C) 2013-2017 MulticoreWare, Inc
+* Copyright (C) 2013-2020 MulticoreWare, Inc
 *
 * Author: Steve Borho <steve@borho.org>
 *
--- a/source/common/framedata.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/framedata.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
-* Copyright (C) 2013-2017 MulticoreWare, Inc
+* Copyright (C) 2013-2020 MulticoreWare, Inc
 *
 * Author: Steve Borho <steve@borho.org>
 *
--- a/source/common/intrapred.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/intrapred.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Min Chen <chenm003@163.com>
  *
--- a/source/common/ipfilter.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/ipfilter.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Deepthi Devaki <deepthidevaki@multicorewareinc.com>,
  *          Rajesh Paulraj <rajesh@multicorewareinc.com>
--- a/source/common/loopfilter.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/loopfilter.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
-* Copyright (C) 2013-2017 MulticoreWare, Inc
+* Copyright (C) 2013-2020 MulticoreWare, Inc
 *
 * Authors: Praveen Kumar Tiwari <praveen@multicorewareinc.com>
 *          Dnyaneshwar Gorade <dnyaneshwar@multicorewareinc.com>
--- a/source/common/lowres.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/lowres.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Gopu Govindaswamy <gopu@multicorewareinc.com>
  *          Ashok Kumar Mishra <ashok@multicorewareinc.com>
--- a/source/common/lowres.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/lowres.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Gopu Govindaswamy <gopu@multicorewareinc.com>
  *
--- a/source/common/md5.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/md5.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,7 +1,7 @@
 /*****************************************************************************
  * md5.cpp: Calculate MD5 for SEI
  *****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Min Chen <chenm003@163.com>
  *
--- a/source/common/md5.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/md5.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,7 +1,7 @@
 /*****************************************************************************
  * md5.h: Calculate MD5
  *****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Min Chen <chenm003@163.com>
  *
--- a/source/common/mv.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/mv.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *
--- a/source/common/param.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/param.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Deepthi Nandakumar <deepthi@multicorewareinc.com>
  *          Min Chen <min.chen@multicorewareinc.com>
@@ -135,6 +135,7 @@ void x265_param_default(x265_param* para
 
     /* Source specifications */
     param->internalBitDepth = X265_DEPTH;
+    param->sourceBitDepth = 8;
     param->internalCsp = X265_CSP_I420;
     param->levelIdc = 0; //Auto-detect level
     param->uhdBluray = 0;
@@ -146,7 +147,8 @@ void x265_param_default(x265_param* para
     param->bEnableAccessUnitDelimiters = 0;
     param->bEmitHRDSEI = 0;
     param->bEmitInfoSEI = 1;
-    param->bEmitHDRSEI = 0;
+    param->bEmitHDRSEI = 0; /*Deprecated*/
+    param->bEmitHDR10SEI = 0;
     param->bEmitIDRRecoverySEI = 0;
 
     /* CU definitions */
@@ -166,6 +168,8 @@ void x265_param_default(x265_param* para
     param->bFrameAdaptive = X265_B_ADAPT_TRELLIS;
     param->bBPyramid = 1;
     param->scenecutThreshold = 40; /* Magic number pulled in from x264 */
+    param->edgeTransitionThreshold = 0.01;
+    param->bHistBasedSceneCut = 0;
     param->lookaheadSlices = 8;
     param->lookaheadThreads = 0;
     param->scenecutBias = 5.0;
@@ -174,6 +178,9 @@ void x265_param_default(x265_param* para
     param->chunkEnd = 0;
     param->bEnableHRDConcatFlag = 0;
     param->bEnableFades = 0;
+    param->bEnableSceneCutAwareQp = 0;
+    param->scenecutWindow = 500;
+    param->maxQpDelta = 5;
 
     /* Intra Coding Tools */
     param->bEnableConstrainedIntra = 0;
@@ -204,6 +211,9 @@ void x265_param_default(x265_param* para
     param->bEnableHME = 0;
     param->hmeSearchMethod[0] = X265_HEX_SEARCH;
     param->hmeSearchMethod[1] = param->hmeSearchMethod[2] = X265_UMH_SEARCH;
+    param->hmeRange[0] = 16;
+    param->hmeRange[1] = 32;
+    param->hmeRange[2] = 48;
     param->bSourceReferenceEstimation = 0;
     param->limitTU = 0;
     param->dynamicRd = 0;
@@ -273,6 +283,8 @@ void x265_param_default(x265_param* para
     param->rc.qpMin = 0;
     param->rc.qpMax = QP_MAX_MAX;
     param->rc.bEnableConstVbv = 0;
+    param->bResetZoneConfig = 1;
+    param->reconfigWindowSize = 0;
 
     /* Video Usability Information (VUI) */
     param->vui.aspectRatioIdc = 0;
@@ -301,14 +313,21 @@ void x265_param_default(x265_param* para
     param->log2MaxPocLsb = 8;
     param->maxSlices = 1;
 
+    /*Conformance window*/
+    param->confWinRightOffset = 0;
+    param->confWinBottomOffset = 0;
+
     param->bEmitVUITimingInfo   = 1;
     param->bEmitVUIHRDInfo      = 1;
     param->bOptQpPPS            = 0;
     param->bOptRefListLengthPPS = 0;
     param->bOptCUDeltaQP        = 0;
     param->bAQMotion = 0;
-    param->bHDROpt = 0;
-    param->analysisReuseLevel = 5;
+    param->bHDROpt = 0; /*DEPRECATED*/
+    param->bHDR10Opt = 0;
+    param->analysisReuseLevel = 0;  /*DEPRECATED*/
+    param->analysisSaveReuseLevel = 0;
+    param->analysisLoadReuseLevel = 0;
     param->toneMapFile = NULL;
     param->bDhdr10opt = 0;
     param->dolbyProfile = 0;
@@ -338,6 +357,9 @@ void x265_param_default(x265_param* para
     param->pictureStructure = -1;
     param->bEmitCLL = 1;
 
+    param->bEnableFrameDuplication = 0;
+    param->dupThreshold = 70;
+
     /* SVT Hevc Encoder specific params */
     param->bEnableSvtHevc = 0;
     param->svtHevcParam = NULL;
@@ -563,6 +585,7 @@ int x265_param_default_preset(x265_param
             param->bframes = 0;
             param->lookaheadDepth = 0;
             param->scenecutThreshold = 0;
+            param->bHistBasedSceneCut = 0;
             param->rc.cuTree = 0;
             param->frameNumThreads = 1;
         }
@@ -598,7 +621,7 @@ int x265_param_default_preset(x265_param
     }
 
 #ifdef SVT_HEVC
-    if (svt_set_preset_tune(param, preset, tune))
+    if (svt_set_preset(param, preset))
         return -1;
 #endif
 
@@ -911,12 +934,13 @@ int x265_param_parse(x265_param* p, cons
     OPT("lookahead-slices") p->lookaheadSlices = atoi(value);
     OPT("scenecut")
     {
-        p->scenecutThreshold = atobool(value);
-        if (bError || p->scenecutThreshold)
-        {
-            bError = false;
-            p->scenecutThreshold = atoi(value);
-        }
+       p->scenecutThreshold = atobool(value);
+       if (bError || p->scenecutThreshold)
+       {
+           bError = false;
+           p->scenecutThreshold = atoi(value);
+           p->bHistBasedSceneCut = 0;
+       }
     }
     OPT("temporal-layers") p->bEnableTemporalSubLayers = atobool(value);
     OPT("keyint") p->keyframeMax = atoi(value);
@@ -1182,13 +1206,35 @@ int x265_param_parse(x265_param* p, cons
         OPT("opt-ref-list-length-pps") p->bOptRefListLengthPPS = atobool(value);
         OPT("multi-pass-opt-rps") p->bMultiPassOptRPS = atobool(value);
         OPT("scenecut-bias") p->scenecutBias = atof(value);
+        OPT("hist-scenecut")
+        {
+            p->bHistBasedSceneCut = atobool(value);
+            if (bError)
+            {
+                bError = false;
+                p->bHistBasedSceneCut = 0;
+            }
+            if (p->bHistBasedSceneCut)
+            {
+                bError = false;
+                p->scenecutThreshold = 0;
+            }
+        }
+        OPT("hist-threshold") p->edgeTransitionThreshold = atof(value);
         OPT("lookahead-threads") p->lookaheadThreads = atoi(value);
         OPT("opt-cu-delta-qp") p->bOptCUDeltaQP = atobool(value);
         OPT("multi-pass-opt-analysis") p->analysisMultiPassRefine = atobool(value);
         OPT("multi-pass-opt-distortion") p->analysisMultiPassDistortion = atobool(value);
         OPT("aq-motion") p->bAQMotion = atobool(value);
         OPT("dynamic-rd") p->dynamicRd = atof(value);
-        OPT("analysis-reuse-level") p->analysisReuseLevel = atoi(value);
+        OPT("analysis-reuse-level")
+        {
+            p->analysisReuseLevel = atoi(value);
+            p->analysisSaveReuseLevel = atoi(value);
+            p->analysisLoadReuseLevel = atoi(value);
+        }
+        OPT("analysis-save-reuse-level") p->analysisSaveReuseLevel = atoi(value);
+        OPT("analysis-load-reuse-level") p->analysisLoadReuseLevel = atoi(value);
         OPT("ssim-rd")
         {
             int bval = atobool(value);
@@ -1199,8 +1245,10 @@ int x265_param_parse(x265_param* p, cons
                 p->bSsimRd = atobool(value);
             }
         }
-        OPT("hdr") p->bEmitHDRSEI = atobool(value);
-        OPT("hdr-opt") p->bHDROpt = atobool(value);
+        OPT("hdr") p->bEmitHDR10SEI = atobool(value);  /*DEPRECATED*/
+        OPT("hdr10") p->bEmitHDR10SEI = atobool(value);
+        OPT("hdr-opt") p->bHDR10Opt = atobool(value); /*DEPRECATED*/
+        OPT("hdr10-opt") p->bHDR10Opt = atobool(value);
         OPT("limit-sao") p->bLimitSAO = atobool(value);
         OPT("dhdr10-info") p->toneMapFile = strdup(value);
         OPT("dhdr10-opt") p->bDhdr10opt = atobool(value);
@@ -1229,7 +1277,7 @@ int x265_param_parse(x265_param* p, cons
             }
             else if (strcmp(strdup(value), "off") == 0)
             {
-                p->bAnalysisType = NO_INFO;
+                p->bAnalysisType = DEFAULT;
             }
             else
             {
@@ -1288,8 +1336,13 @@ int x265_param_parse(x265_param* p, cons
             p->selectiveSAO = atoi(value);
         }
         OPT("fades") p->bEnableFades = atobool(value);
+        OPT("scenecut-aware-qp") p->bEnableSceneCutAwareQp = atobool(value);
+        OPT("scenecut-window") p->scenecutWindow = atoi(value);
+        OPT("max-qp-delta") p->maxQpDelta = atoi(value);
         OPT("field") p->bField = atobool( value );
         OPT("cll") p->bEmitCLL = atobool(value);
+        OPT("frame-dup") p->bEnableFrameDuplication = atobool(value);
+        OPT("dup-threshold") p->dupThreshold = atoi(value);
         OPT("hme") p->bEnableHME = atobool(value);
         OPT("hme-search")
         {
@@ -1311,6 +1364,11 @@ int x265_param_parse(x265_param* p, cons
             }
             p->bEnableHME = true;
         }
+        OPT("hme-range")
+        {
+            sscanf(value, "%d,%d,%d", &p->hmeRange[0], &p->hmeRange[1], &p->hmeRange[2]);
+            p->bEnableHME = true;
+        }
         else
             return X265_PARAM_BAD_NAME;
     }
@@ -1618,7 +1676,9 @@ int x265_check_params(x265_param* param)
     CHECK(param->scenecutThreshold < 0,
           "scenecutThreshold must be greater than 0");
     CHECK(param->scenecutBias < 0 || 100 < param->scenecutBias,
-           "scenecut-bias must be between 0 and 100");
+            "scenecut-bias must be between 0 and 100");
+    CHECK(param->edgeTransitionThreshold < 0.0 || 2.0 < param->edgeTransitionThreshold,
+            "hist-threshold must be between 0.0 and 2.0");
     CHECK(param->radl < 0 || param->radl > param->bframes,
           "radl must be between 0 and bframes");
     CHECK(param->rdPenalty < 0 || param->rdPenalty > 2,
@@ -1653,8 +1713,10 @@ int x265_check_params(x265_param* param)
           "Constant QP is incompatible with 2pass");
     CHECK(param->rc.bStrictCbr && (param->rc.bitrate <= 0 || param->rc.vbvBufferSize <=0),
           "Strict-cbr cannot be applied without specifying target bitrate or vbv bufsize");
-    CHECK((param->analysisSave || param->analysisLoad) && (param->analysisReuseLevel < 1 || param->analysisReuseLevel > 10),
-        "Invalid analysis refine level. Value must be between 1 and 10 (inclusive)");
+    CHECK(param->analysisSave && (param->analysisSaveReuseLevel < 0 || param->analysisSaveReuseLevel > 10),
+        "Invalid analysis save refine level. Value must be between 1 and 10 (inclusive)");
+    CHECK(param->analysisLoad && (param->analysisLoadReuseLevel < 0 || param->analysisLoadReuseLevel > 10),
+        "Invalid analysis load refine level. Value must be between 1 and 10 (inclusive)");
     CHECK(param->analysisLoad && (param->mvRefine < 1 || param->mvRefine > 3),
         "Invalid mv refinement level. Value must be between 1 and 3 (inclusive)");
     CHECK(param->scaleFactor > 2, "Invalid scale-factor. Supports factor <= 2");
@@ -1676,6 +1738,8 @@ int x265_check_params(x265_param* param)
         "Supported factor for controlling max AU size is from 0.5 to 1");
     CHECK((param->dolbyProfile != 0) && (param->dolbyProfile != 50) && (param->dolbyProfile != 81) && (param->dolbyProfile != 82),
         "Unsupported Dolby Vision profile, only profile 5, profile 8.1 and profile 8.2 enabled");
+    CHECK(param->dupThreshold < 1 || 99 < param->dupThreshold,
+        "Invalid frame-duplication threshold. Value must be between 1 and 99.");
     if (param->dolbyProfile)
     {
         CHECK((param->rc.vbvMaxBitrate <= 0 || param->rc.vbvBufferSize <= 0), "Dolby Vision requires VBV settings to enable HRD.\n");
@@ -1693,18 +1757,25 @@ int x265_check_params(x265_param* param)
     }
     CHECK(param->selectiveSAO < 0 || param->selectiveSAO > 4,
         "Invalid SAO tune level. Value must be between 0 and 4 (inclusive)");
+    CHECK(param->scenecutWindow < 0 || param->scenecutWindow > 1000,
+        "Invalid scenecut Window duration. Value must be between 0 and 1000(inclusive)");
+    CHECK(param->maxQpDelta < 0 || param->maxQpDelta > 10,
+        "Invalid maxQpDelta value. Value must be between 0 and 10 (inclusive)");
+    for(int level = 0; level < 3; level++)
+        CHECK(param->hmeRange[level] < 0 || param->hmeRange[level] >= 32768,
+            "Search Range for HME levels must be between 0 and 32768");
 #if !X86_64
     CHECK(param->searchMethod == X265_SEA && (param->sourceWidth > 840 || param->sourceHeight > 480),
         "SEA motion search does not support resolutions greater than 480p in 32 bit build");
 #endif
 
     if (param->masteringDisplayColorVolume || param->maxFALL || param->maxCLL)
-        param->bEmitHDRSEI = 1;
+        param->bEmitHDR10SEI = 1;
 
     bool isSingleSEI = (param->bRepeatHeaders
                      || param->bEmitHRDSEI
                      || param->bEmitInfoSEI
-                     || param->bEmitHDRSEI
+                     || param->bEmitHDR10SEI
                      || param->bEmitIDRRecoverySEI
                    || !!param->interlaceMode
                      || param->preferredTransferCharacteristics > 1
@@ -1716,6 +1787,8 @@ int x265_check_params(x265_param* param)
         param->bSingleSeiNal = 0;
         x265_log(param, X265_LOG_WARNING, "None of the SEI messages are enabled. Disabling Single SEI NAL\n");
     }
+    CHECK(param->confWinRightOffset < 0, "Conformance Window Right Offset must be 0 or greater");
+    CHECK(param->confWinBottomOffset < 0, "Conformance Window Bottom Offset must be 0 or greater");
     return check_failed;
 }
 
@@ -1772,9 +1845,13 @@ void x265_print_params(x265_param* param
         x265_log(param, X265_LOG_INFO, "ME / range / subpel / merge         : %s / %d / %d / %d\n",
             x265_motion_est_names[param->searchMethod], param->searchRange, param->subpelRefine, param->maxNumMergeCand);
 
-    if (param->keyframeMax != INT_MAX || param->scenecutThreshold)
-        x265_log(param, X265_LOG_INFO, "Keyframe min / max / scenecut / bias: %d / %d / %d / %.2lf\n", param->keyframeMin, param->keyframeMax, param->scenecutThreshold, param->scenecutBias * 100);
-    else
+    if (param->scenecutThreshold && param->keyframeMax != INT_MAX) 
+        x265_log(param, X265_LOG_INFO, "Keyframe min / max / scenecut / bias  : %d / %d / %d / %.2lf \n",
+                 param->keyframeMin, param->keyframeMax, param->scenecutThreshold, param->scenecutBias * 100);
+    else if (param->bHistBasedSceneCut && param->keyframeMax != INT_MAX) 
+        x265_log(param, X265_LOG_INFO, "Keyframe min / max / scenecut / edge threshold  : %d / %d / %d / %.2lf\n",
+                 param->keyframeMin, param->keyframeMax, param->bHistBasedSceneCut, param->edgeTransitionThreshold);
+    else if (param->keyframeMax == INT_MAX)
         x265_log(param, X265_LOG_INFO, "Keyframe min / max / scenecut       : disabled\n");
 
     if (param->cbQpOffset || param->crQpOffset)
@@ -1941,6 +2018,7 @@ char *x265_param2string(x265_param* p, i
     s += sprintf(s, " rc-lookahead=%d", p->lookaheadDepth);
     s += sprintf(s, " lookahead-slices=%d", p->lookaheadSlices);
     s += sprintf(s, " scenecut=%d", p->scenecutThreshold);
+    s += sprintf(s, " hist-scenecut=%d", p->bHistBasedSceneCut);
     s += sprintf(s, " radl=%d", p->radl);
     BOOL(p->bEnableHRDConcatFlag, "splice");
     BOOL(p->bIntraRefresh, "intra-refresh");
@@ -1968,9 +2046,15 @@ char *x265_param2string(x265_param* p, i
     s += sprintf(s, " subme=%d", p->subpelRefine);
     s += sprintf(s, " merange=%d", p->searchRange);
     BOOL(p->bEnableTemporalMvp, "temporal-mvp");
+    BOOL(p->bEnableFrameDuplication, "frame-dup");
+    if(p->bEnableFrameDuplication)
+        s += sprintf(s, " dup-threshold=%d", p->dupThreshold);
     BOOL(p->bEnableHME, "hme");
     if (p->bEnableHME)
+    {
         s += sprintf(s, " Level 0,1,2=%d,%d,%d", p->hmeSearchMethod[0], p->hmeSearchMethod[1], p->hmeSearchMethod[2]);
+        s += sprintf(s, " merange L0,L1,L2=%d,%d,%d", p->hmeRange[0], p->hmeRange[1], p->hmeRange[2]);
+    }
     BOOL(p->bEnableWeightedPred, "weightp");
     BOOL(p->bEnableWeightedBiPred, "weightb");
     BOOL(p->bSourceReferenceEstimation, "analyze-src-pics");
@@ -2085,10 +2169,11 @@ char *x265_param2string(x265_param* p, i
     BOOL(p->bOptRefListLengthPPS, "opt-ref-list-length-pps");
     BOOL(p->bMultiPassOptRPS, "multi-pass-opt-rps");
     s += sprintf(s, " scenecut-bias=%.2f", p->scenecutBias);
+    s += sprintf(s, " hist-threshold=%.2f", p->edgeTransitionThreshold);
     BOOL(p->bOptCUDeltaQP, "opt-cu-delta-qp");
     BOOL(p->bAQMotion, "aq-motion");
-    BOOL(p->bEmitHDRSEI, "hdr");
-    BOOL(p->bHDROpt, "hdr-opt");
+    BOOL(p->bEmitHDR10SEI, "hdr10");
+    BOOL(p->bHDR10Opt, "hdr10-opt");
     BOOL(p->bDhdr10opt, "dhdr10-opt");
     BOOL(p->bEmitIDRRecoverySEI, "idr-recovery-sei");
     if (p->analysisSave)
@@ -2096,6 +2181,8 @@ char *x265_param2string(x265_param* p, i
     if (p->analysisLoad)
         s += sprintf(s, " analysis-load");
     s += sprintf(s, " analysis-reuse-level=%d", p->analysisReuseLevel);
+    s += sprintf(s, " analysis-save-reuse-level=%d", p->analysisSaveReuseLevel);
+    s += sprintf(s, " analysis-load-reuse-level=%d", p->analysisLoadReuseLevel);
     s += sprintf(s, " scale-factor=%d", p->scaleFactor);
     s += sprintf(s, " refine-intra=%d", p->intraRefine);
     s += sprintf(s, " refine-inter=%d", p->interRefine);
@@ -2113,6 +2200,10 @@ char *x265_param2string(x265_param* p, i
     BOOL(p->bEnableSvtHevc, "svt");
     BOOL(p->bField, "field");
     s += sprintf(s, " qp-adaptation-range=%.2f", p->rc.qpAdaptationRange);
+    BOOL(p->bEnableSceneCutAwareQp, "scenecut-aware-qp");
+    if (p->bEnableSceneCutAwareQp)
+        s += sprintf(s, " scenecut-window=%d max-qp-delta=%d", p->scenecutWindow, p->maxQpDelta);
+    s += sprintf(s, "conformance-window-offsets right=%d bottom=%d", p->confWinRightOffset, p->confWinBottomOffset);
 #undef BOOL
     return buf;
 }
@@ -2205,6 +2296,7 @@ void x265_copy_params(x265_param* dst, x
     if (src->csvfn) dst->csvfn = strdup(src->csvfn);
     else dst->csvfn = NULL;
     dst->internalBitDepth = src->internalBitDepth;
+    dst->sourceBitDepth = src->sourceBitDepth;
     dst->internalCsp = src->internalCsp;
     dst->fpsNum = src->fpsNum;
     dst->fpsDenom = src->fpsDenom;
@@ -2234,6 +2326,7 @@ void x265_copy_params(x265_param* dst, x
     dst->lookaheadSlices = src->lookaheadSlices;
     dst->lookaheadThreads = src->lookaheadThreads;
     dst->scenecutThreshold = src->scenecutThreshold;
+    dst->bHistBasedSceneCut = src->bHistBasedSceneCut;
     dst->bIntraRefresh = src->bIntraRefresh;
     dst->maxCUSize = src->maxCUSize;
     dst->minCUSize = src->minCUSize;
@@ -2259,11 +2352,16 @@ void x265_copy_params(x265_param* dst, x
     dst->subpelRefine = src->subpelRefine;
     dst->searchRange = src->searchRange;
     dst->bEnableTemporalMvp = src->bEnableTemporalMvp;
+    dst->bEnableFrameDuplication = src->bEnableFrameDuplication;
+    dst->dupThreshold = src->dupThreshold;
     dst->bEnableHME = src->bEnableHME;
     if (src->bEnableHME)
     {
         for (int level = 0; level < 3; level++)
+        {
             dst->hmeSearchMethod[level] = src->hmeSearchMethod[level];
+            dst->hmeRange[level] = src->hmeRange[level];
+        }
     }
     dst->bEnableWeightedBiPred = src->bEnableWeightedBiPred;
     dst->bEnableWeightedPred = src->bEnableWeightedPred;
@@ -2319,6 +2417,8 @@ void x265_copy_params(x265_param* dst, x
     dst->rc.bEnableSlowFirstPass = src->rc.bEnableSlowFirstPass;
     dst->rc.zoneCount = src->rc.zoneCount;
     dst->rc.zonefileCount = src->rc.zonefileCount;
+    dst->reconfigWindowSize = src->reconfigWindowSize;
+    dst->bResetZoneConfig = src->bResetZoneConfig;
 
     if (src->rc.zonefileCount && src->rc.zones)
     {
@@ -2389,6 +2489,7 @@ void x265_copy_params(x265_param* dst, x
     dst->bOptRefListLengthPPS = src->bOptRefListLengthPPS;
     dst->bMultiPassOptRPS = src->bMultiPassOptRPS;
     dst->scenecutBias = src->scenecutBias;
+    dst->edgeTransitionThreshold = src->edgeTransitionThreshold;
     dst->gopLookahead = src->lookaheadDepth;
     dst->bOptCUDeltaQP = src->bOptCUDeltaQP;
     dst->analysisMultiPassDistortion = src->analysisMultiPassDistortion;
@@ -2396,10 +2497,13 @@ void x265_copy_params(x265_param* dst, x
     dst->bAQMotion = src->bAQMotion;
     dst->bSsimRd = src->bSsimRd;
     dst->dynamicRd = src->dynamicRd;
-    dst->bEmitHDRSEI = src->bEmitHDRSEI;
+    dst->bEmitHDR10SEI = src->bEmitHDR10SEI;
     dst->bEmitHRDSEI = src->bEmitHRDSEI;
-    dst->bHDROpt = src->bHDROpt;
+    dst->bHDROpt = src->bHDROpt; /*DEPRECATED*/
+    dst->bHDR10Opt = src->bHDR10Opt;
     dst->analysisReuseLevel = src->analysisReuseLevel;
+    dst->analysisSaveReuseLevel = src->analysisSaveReuseLevel;
+    dst->analysisLoadReuseLevel = src->analysisLoadReuseLevel;
     dst->bLimitSAO = src->bLimitSAO;
     if (src->toneMapFile) dst->toneMapFile = strdup(src->toneMapFile);
     else dst->toneMapFile = NULL;
@@ -2445,8 +2549,13 @@ void x265_copy_params(x265_param* dst, x
     dst->dolbyProfile = src->dolbyProfile;
     dst->bEnableSvtHevc = src->bEnableSvtHevc;
     dst->bEnableFades = src->bEnableFades;
+    dst->bEnableSceneCutAwareQp = src->bEnableSceneCutAwareQp;
+    dst->scenecutWindow = src->scenecutWindow;
+    dst->maxQpDelta = src->maxQpDelta;
     dst->bField = src->bField;
 
+    dst->confWinRightOffset = src->confWinRightOffset;
+    dst->confWinBottomOffset = src->confWinBottomOffset;
 #ifdef SVT_HEVC
     memcpy(dst->svtHevcParam, src->svtHevcParam, sizeof(EB_H265_ENC_CONFIGURATION));
 #endif
@@ -2473,8 +2582,8 @@ void svt_param_default(x265_param* param
     svtHevcParam->latencyMode = 0;
 
     //Preset & Tune
-    svtHevcParam->encMode = 9;
-    svtHevcParam->tune = 0;
+    svtHevcParam->encMode = 7;
+    svtHevcParam->tune = 1;
 
     // Interlaced Video 
     svtHevcParam->interlacedVideo = 0;
@@ -2514,10 +2623,10 @@ void svt_param_default(x265_param* param
     svtHevcParam->targetBitRate = 7000000;
     svtHevcParam->maxQpAllowed = 48;
     svtHevcParam->minQpAllowed = 10;
-    svtHevcParam->bitRateReduction = 1;
+    svtHevcParam->bitRateReduction = 0;
 
     // Thresholds
-    svtHevcParam->improveSharpness = 1;
+    svtHevcParam->improveSharpness = 0;
     svtHevcParam->videoUsabilityInfo = 0;
     svtHevcParam->highDynamicRangeInput = 0;
     svtHevcParam->accessUnitDelimiter = 0;
@@ -2527,7 +2636,7 @@ void svt_param_default(x265_param* param
     svtHevcParam->unregisteredUserDataSeiFlag = 0;
     svtHevcParam->recoveryPointSeiFlag = 0;
     svtHevcParam->enableTemporalId = 1;
-    svtHevcParam->profile = 2;
+    svtHevcParam->profile = 1;
     svtHevcParam->tier = 0;
     svtHevcParam->level = 0;
 
@@ -2558,34 +2667,31 @@ void svt_param_default(x265_param* param
     svtHevcParam->tileRowCount = 1;
     svtHevcParam->tileSliceMode = 0;
     svtHevcParam->unrestrictedMotionVector = 1;
+    svtHevcParam->threadCount = 0;
+
+    // vbv
+    svtHevcParam->hrdFlag = 0;
+    svtHevcParam->vbvMaxrate = 0;
+    svtHevcParam->vbvBufsize = 0;
+    svtHevcParam->vbvBufInit = 90;
 }
 
-int svt_set_preset_tune(x265_param* param, const char* preset, const char* tune)
+int svt_set_preset(x265_param* param, const char* preset)
 {
     EB_H265_ENC_CONFIGURATION* svtHevcParam = (EB_H265_ENC_CONFIGURATION*)param->svtHevcParam;
     
     if (preset)
     {
-        if (!strcmp(preset, "ultrafast")) svtHevcParam->encMode = 12;
-        else if (!strcmp(preset, "superfast")) svtHevcParam->encMode = 11;
-        else if (!strcmp(preset, "veryfast")) svtHevcParam->encMode = 10;
-        else if (!strcmp(preset, "faster")) svtHevcParam->encMode = 9;
-        else if (!strcmp(preset, "fast")) svtHevcParam->encMode = 8;
-        else if (!strcmp(preset, "medium")) svtHevcParam->encMode = 7;
-        else if (!strcmp(preset, "slow")) svtHevcParam->encMode = 6;
-        else if (!strcmp(preset, "slower")) svtHevcParam->encMode = 5;
-        else if (!strcmp(preset, "veryslow")) svtHevcParam->encMode = 4;
-        else if (!strcmp(preset, "placebo")) svtHevcParam->encMode = 3;
-        else  return -1;
-    }
-    if (tune)
-    {
-        if (!strcmp(tune, "psnr")) svtHevcParam->tune = 1;
-        else if (!strcmp(tune, "ssim")) svtHevcParam->tune = 1;
-        else if (!strcmp(tune, "grain")) svtHevcParam->tune = 0;
-        else if (!strcmp(tune, "animation")) svtHevcParam->tune = 0;
-        else if (!strcmp(tune, "vmaf")) svtHevcParam->tune = 2;
-        else if (!strcmp(tune, "zero-latency") || !strcmp(tune, "zerolatency")) svtHevcParam->latencyMode = 1;
+        if (!strcmp(preset, "ultrafast")) svtHevcParam->encMode = 11;
+        else if (!strcmp(preset, "superfast")) svtHevcParam->encMode = 10;
+        else if (!strcmp(preset, "veryfast")) svtHevcParam->encMode = 9;
+        else if (!strcmp(preset, "faster")) svtHevcParam->encMode = 8;
+        else if (!strcmp(preset, "fast")) svtHevcParam->encMode = 7;
+        else if (!strcmp(preset, "medium")) svtHevcParam->encMode = 6;
+        else if (!strcmp(preset, "slow")) svtHevcParam->encMode = 5;
+        else if (!strcmp(preset, "slower")) svtHevcParam->encMode =4;
+        else if (!strcmp(preset, "veryslow")) svtHevcParam->encMode = 3;
+        else if (!strcmp(preset, "placebo")) svtHevcParam->encMode = 2;
         else  return -1;
     }
     return 0;
@@ -2740,11 +2846,10 @@ int svt_param_parse(x265_param* param, c
     OPT("svt-speed-control") svtHevcParam->speedControlFlag = x265_atobool(value, bError);
     OPT("svt-preset-tuner")
     {
-        if (svtHevcParam->encMode == 3)
+        if (svtHevcParam->encMode == 2)
         {
             if (!strcmp(value, "0")) svtHevcParam->encMode = 0;
             else if (!strcmp(value, "1")) svtHevcParam->encMode = 1;
-            else if (!strcmp(value, "2")) svtHevcParam->encMode = 2;
             else
             {
                 x265_log(param, X265_LOG_ERROR, " Unsupported value=%s for svt-preset-tuner \n", value);
@@ -2770,6 +2875,16 @@ int svt_param_parse(x265_param* param, c
         else
             bError = true;
     }
+    OPT("hrd")
+        svtHevcParam->hrdFlag = (uint32_t)x265_atobool(value, bError);
+    OPT("vbv-maxrate")
+        svtHevcParam->vbvMaxrate = (uint32_t)x265_atoi(value, bError);
+    OPT("vbv-bufsize")
+        svtHevcParam->vbvBufsize = (uint32_t)x265_atoi(value, bError);
+    OPT("vbv-init")
+        svtHevcParam->vbvBufInit = (uint64_t)x265_atof(value, bError);
+    OPT("frame-threads")
+        svtHevcParam->threadCount = (uint32_t)x265_atoi(value, bError);
     else
         x265_log(param, X265_LOG_INFO, "SVT doesn't support %s param; Disabling it \n", name);
 
--- a/source/common/param.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/param.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Deepthi Nandakumar <deepthi@multicorewareinc.com>
  *          Praveen Kumar Tiwari <praveen@multicorewareinc.com>
--- a/source/common/piclist.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/piclist.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Gopu Govindaswamy <gopu@multicorewareinc.com>
  *
--- a/source/common/piclist.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/piclist.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Gopu Govindaswamy <gopu@multicorewareinc.com>
  *
--- a/source/common/picyuv.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/picyuv.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *          Min Chen <chenm003@163.com>
--- a/source/common/picyuv.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/picyuv.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *
--- a/source/common/pixel.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/pixel.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *          Mandar Gurav <mandar@multicorewareinc.com>
--- a/source/common/ppc/dct_altivec.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/ppc/dct_altivec.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Roger Moussalli <rmoussal@us.ibm.com>
  *          Min Chen <min.chen@multicorewareinc.com>
--- a/source/common/ppc/intrapred_altivec.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/ppc/intrapred_altivec.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Roger Moussalli <rmoussal@us.ibm.com>
  *          Min Chen <min.chen@multicorewareinc.com>
--- a/source/common/ppc/ipfilter_altivec.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/ppc/ipfilter_altivec.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Roger Moussalli <rmoussal@us.ibm.com>
  *          Min Chen <min.chen@multicorewareinc.com>
--- a/source/common/ppc/pixel_altivec.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/ppc/pixel_altivec.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *          Mandar Gurav <mandar@multicorewareinc.com>
--- a/source/common/ppc/ppccommon.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/ppc/ppccommon.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Min Chen <min.chen@multicorewareinc.com>
  *
--- a/source/common/predict.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/predict.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
-* Copyright (C) 2013-2017 MulticoreWare, Inc
+* Copyright (C) 2013-2020 MulticoreWare, Inc
 *
 * Authors: Deepthi Nandakumar <deepthi@multicorewareinc.com>
 *          Min Chen <chenm003@163.com>
--- a/source/common/predict.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/predict.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
-* Copyright (C) 2013-2017 MulticoreWare, Inc
+* Copyright (C) 2013-2020 MulticoreWare, Inc
 *
 * Authors: Deepthi Nandakumar <deepthi@multicorewareinc.com>
 *          Min Chen <chenm003@163.com>
--- a/source/common/primitives.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/primitives.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *
--- a/source/common/primitives.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/primitives.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *          Mandar Gurav <mandar@multicorewareinc.com>
--- a/source/common/quant.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/quant.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *          Min Chen <chenm003@163.com>
--- a/source/common/quant.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/quant.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *          Min Chen <chenm003@163.com>
--- a/source/common/scalinglist.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/scalinglist.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *
--- a/source/common/scalinglist.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/scalinglist.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *
--- a/source/common/shortyuv.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/shortyuv.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Deepthi Nandakumar <deepthi@multicorewareinc.com>
  *
--- a/source/common/shortyuv.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/shortyuv.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,7 +1,7 @@
 /*****************************************************************************
  * x265: ShortYUV class for short sized YUV-style frames
  *****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Deepthi Nandakumar <deepthi@multicorewareinc.com>
  *
--- a/source/common/slice.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/slice.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *
--- a/source/common/slice.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/slice.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *          Min Chen <chenm003@163.com>
--- a/source/common/threading.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/threading.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *
--- a/source/common/threading.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/threading.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *          Min Chen <chenm003@163.com>
--- a/source/common/threadpool.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/threadpool.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *          Min Chen <chenm003@163.com>
--- a/source/common/threadpool.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/threadpool.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *
--- a/source/common/vec/dct-sse3.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/vec/dct-sse3.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *          Mandar Gurav <mandar@multicorewareinc.com>
--- a/source/common/vec/dct-sse41.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/vec/dct-sse41.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *          Mandar Gurav <mandar@multicorewareinc.com>
--- a/source/common/vec/dct-ssse3.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/vec/dct-ssse3.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *          Mandar Gurav <mandar@multicorewareinc.com>
--- a/source/common/vec/vec-primitives.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/vec/vec-primitives.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *
--- a/source/common/version.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/version.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *          Min Chen <chenm003@163.com>
--- a/source/common/wavefront.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/wavefront.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *          Min Chen <chenm003@163.com>
--- a/source/common/wavefront.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/wavefront.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *          Min Chen <chenm003@163.com>
--- a/source/common/winxp.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/winxp.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *
--- a/source/common/winxp.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/winxp.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *
--- a/source/common/x86/asm-primitives.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/x86/asm-primitives.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *          Praveen Kumar Tiwari <praveen@multicorewareinc.com>
--- a/source/common/x86/blockcopy8.asm	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/x86/blockcopy8.asm	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 ;*****************************************************************************
-;* Copyright (C) 2013-2017 MulticoreWare, Inc
+;* Copyright (C) 2013-2020 MulticoreWare, Inc
 ;*
 ;* Authors: Praveen Kumar Tiwari <praveen@multicorewareinc.com>
 ;*          Murugan Vairavel <murugan@multicorewareinc.com>
--- a/source/common/x86/blockcopy8.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/x86/blockcopy8.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
 ;*          Min Chen <chenm003@163.com>
--- a/source/common/x86/const-a.asm	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/x86/const-a.asm	Fri Jan 31 00:40:19 2020 +0530
@@ -2,7 +2,7 @@
 ;* const-a.asm: x86 global constants
 ;*****************************************************************************
 ;* Copyright (C) 2003-2013 x264 project
-;* Copyright (C) 2013-2017 MulticoreWare, Inc
+;* Copyright (C) 2013-2020 MulticoreWare, Inc
 ;*
 ;* Authors: Loren Merritt <lorenm@u.washington.edu>
 ;*          Fiona Glaser <fiona@x264.com>
--- a/source/common/x86/cpu-a.asm	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/x86/cpu-a.asm	Fri Jan 31 00:40:19 2020 +0530
@@ -2,7 +2,7 @@
 ;* cpu-a.asm: x86 cpu utilities
 ;*****************************************************************************
 ;* Copyright (C) 2003-2013 x264 project
-;* Copyright (C) 2013-2017 MulticoreWare, Inc
+;* Copyright (C) 2013-2020 MulticoreWare, Inc
 ;*
 ;* Authors: Laurent Aimar <fenrir@via.ecp.fr>
 ;*          Loren Merritt <lorenm@u.washington.edu>
--- a/source/common/x86/dct8.asm	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/x86/dct8.asm	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 ;*****************************************************************************
-;* Copyright (C) 2013-2017 MulticoreWare, Inc
+;* Copyright (C) 2013-2020 MulticoreWare, Inc
 ;*
 ;* Authors: Nabajit Deka <nabajit@multicorewareinc.com>
 ;*          Min Chen <chenm003@163.com> <min.chen@multicorewareinc.com>
--- a/source/common/x86/dct8.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/x86/dct8.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Nabajit Deka <nabajit@multicorewareinc.com>
 ;*          Min Chen <chenm003@163.com>
--- a/source/common/x86/h-ipfilter16.asm	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/x86/h-ipfilter16.asm	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 ;*****************************************************************************
-;* Copyright (C) 2013-2017 MulticoreWare, Inc
+;* Copyright (C) 2013-2020 MulticoreWare, Inc
 ;*
 ;* Authors: Nabajit Deka <nabajit@multicorewareinc.com>
 ;*          Murugan Vairavel <murugan@multicorewareinc.com>
--- a/source/common/x86/h-ipfilter8.asm	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/x86/h-ipfilter8.asm	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 ;*****************************************************************************
-;* Copyright (C) 2013-2017 MulticoreWare, Inc
+;* Copyright (C) 2013-2020 MulticoreWare, Inc
 ;*
 ;* Authors: Min Chen <chenm003@163.com>
 ;*          Nabajit Deka <nabajit@multicorewareinc.com>
--- a/source/common/x86/h4-ipfilter16.asm	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/x86/h4-ipfilter16.asm	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 ;*****************************************************************************
-;* Copyright (C) 2013-2017 MulticoreWare, Inc
+;* Copyright (C) 2013-2020 MulticoreWare, Inc
 ;*
 ;* Authors: Nabajit Deka <nabajit@multicorewareinc.com>
 ;*          Murugan Vairavel <murugan@multicorewareinc.com>
--- a/source/common/x86/intrapred.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/x86/intrapred.h	Fri Jan 31 00:40:19 2020 +0530
@@ -2,7 +2,7 @@
  * intrapred.h: Intra Prediction metrics
  *****************************************************************************
  * Copyright (C) 2003-2013 x264 project
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Min Chen <chenm003@163.com> <min.chen@multicorewareinc.com>
  *          Praveen Kumar Tiwari <praveen@multicorewareinc.com>
--- a/source/common/x86/intrapred16.asm	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/x86/intrapred16.asm	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 ;*****************************************************************************
-;* Copyright (C) 2013-2017 MulticoreWare, Inc
+;* Copyright (C) 2013-2020 MulticoreWare, Inc
 ;*
 ;* Authors: Dnyaneshwar Gorade <dnyaneshwar@multicorewareinc.com>
 ;*          Yuvaraj Venkatesh <yuvaraj@multicorewareinc.com>
--- a/source/common/x86/intrapred8.asm	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/x86/intrapred8.asm	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 ;*****************************************************************************
-;* Copyright (C) 2013-2017 MulticoreWare, Inc
+;* Copyright (C) 2013-2020 MulticoreWare, Inc
 ;*
 ;* Authors: Min Chen <chenm003@163.com> <min.chen@multicorewareinc.com>
 ;*          Praveen Kumar Tiwari <praveen@multicorewareinc.com>
--- a/source/common/x86/intrapred8_allangs.asm	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/x86/intrapred8_allangs.asm	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 ;*****************************************************************************
-;* Copyright (C) 2013-2017 MulticoreWare, Inc
+;* Copyright (C) 2013-2020 MulticoreWare, Inc
 ;*
 ;* Authors: Min Chen <chenm003@163.com> <min.chen@multicorewareinc.com>
 ;*          Praveen Tiwari <praveen@multicorewareinc.com>
--- a/source/common/x86/ipfilter16.asm	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/x86/ipfilter16.asm	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 ;*****************************************************************************
-;* Copyright (C) 2013-2017 MulticoreWare, Inc
+;* Copyright (C) 2013-2020 MulticoreWare, Inc
 ;*
 ;* Authors: Nabajit Deka <nabajit@multicorewareinc.com>
 ;*          Murugan Vairavel <murugan@multicorewareinc.com>
--- a/source/common/x86/ipfilter8.asm	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/x86/ipfilter8.asm	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 ;*****************************************************************************
-;* Copyright (C) 2013-2017 MulticoreWare, Inc
+;* Copyright (C) 2013-2020 MulticoreWare, Inc
 ;*
 ;* Authors: Min Chen <chenm003@163.com>
 ;*          Nabajit Deka <nabajit@multicorewareinc.com>
@@ -14946,4 +14946,4 @@ FILTER_VERT_LUMA_64xN_AVX512 ps, 64
 ;-------------------------------------------------------------------------------------------------------------
 ;-------------------------------------------------------------------------------------------------------------
 ;ipfilter_luma_avx512 code end
-;-------------------------------------------------------------------------------------------------------------
\ No newline at end of file
+;-------------------------------------------------------------------------------------------------------------
--- a/source/common/x86/ipfilter8.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/x86/ipfilter8.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *
--- a/source/common/x86/loopfilter.asm	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/x86/loopfilter.asm	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 ;*****************************************************************************
-;* Copyright (C) 2013-2017 MulticoreWare, Inc
+;* Copyright (C) 2013-2020 MulticoreWare, Inc
 ;*
 ;* Authors: Min Chen <chenm001@163.com>
 ;*          Praveen Kumar Tiwari <praveen@multicorewareinc.com>
--- a/source/common/x86/loopfilter.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/x86/loopfilter.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Dnyaneshwar Gorade <dnyaneshwar@multicorewareinc.com>
  *          Praveen Kumar Tiwari <praveen@multicorewareinc.com>
--- a/source/common/x86/mc-a.asm	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/x86/mc-a.asm	Fri Jan 31 00:40:19 2020 +0530
@@ -2,7 +2,7 @@
 ;* mc-a.asm: x86 motion compensation
 ;*****************************************************************************
 ;* Copyright (C) 2003-2013 x264 project
-;* Copyright (C) 2013-2017 MulticoreWare, Inc
+;* Copyright (C) 2013-2020 MulticoreWare, Inc
 ;*
 ;* Authors: Loren Merritt <lorenm@u.washington.edu>
 ;*          Fiona Glaser <fiona@x264.com>
--- a/source/common/x86/mc-a2.asm	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/x86/mc-a2.asm	Fri Jan 31 00:40:19 2020 +0530
@@ -2,7 +2,7 @@
 ;* mc-a2.asm: x86 motion compensation
 ;*****************************************************************************
 ;* Copyright (C) 2003-2013 x264 project
-;* Copyright (C) 2013-2017 MulticoreWare, Inc
+;* Copyright (C) 2013-2020 MulticoreWare, Inc
 ;*
 ;* Authors: Loren Merritt <lorenm@u.washington.edu>
 ;*          Fiona Glaser <fiona@x264.com>
--- a/source/common/x86/mc.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/x86/mc.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *
--- a/source/common/x86/pixel-32.asm	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/x86/pixel-32.asm	Fri Jan 31 00:40:19 2020 +0530
@@ -2,7 +2,7 @@
 ;* pixel-32.asm: x86_32 pixel metrics
 ;*****************************************************************************
 ;* Copyright (C) 2003-2013 x264 project
-;* Copyright (C) 2013-2017 MulticoreWare, Inc
+;* Copyright (C) 2013-2020 MulticoreWare, Inc
 ;*
 ;* Authors: Loren Merritt <lorenm@u.washington.edu>
 ;*          Laurent Aimar <fenrir@via.ecp.fr>
--- a/source/common/x86/pixel-a.asm	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/x86/pixel-a.asm	Fri Jan 31 00:40:19 2020 +0530
@@ -2,7 +2,7 @@
 ;* pixel.asm: x86 pixel metrics
 ;*****************************************************************************
 ;* Copyright (C) 2003-2013 x264 project
-;* Copyright (C) 2013-2017 MulticoreWare, Inc
+;* Copyright (C) 2013-2020 MulticoreWare, Inc
 ;*
 ;* Authors: Loren Merritt <lorenm@u.washington.edu>
 ;*          Holger Lubitz <holger@lubitz.org>
--- a/source/common/x86/pixel-util.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/x86/pixel-util.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
 ;*          Min Chen <chenm003@163.com>
--- a/source/common/x86/pixel-util8.asm	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/x86/pixel-util8.asm	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 ;*****************************************************************************
-;* Copyright (C) 2013-2017 MulticoreWare, Inc
+;* Copyright (C) 2013-2020 MulticoreWare, Inc
 ;*
 ;* Authors: Min Chen <chenm003@163.com> <min.chen@multicorewareinc.com>
 ;*          Nabajit Deka <nabajit@multicorewareinc.com>
--- a/source/common/x86/pixel.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/x86/pixel.h	Fri Jan 31 00:40:19 2020 +0530
@@ -2,7 +2,7 @@
  * pixel.h: x86 pixel metrics
  *****************************************************************************
  * Copyright (C) 2003-2013 x264 project
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *          Loren Merritt <lorenm@u.washington.edu>
--- a/source/common/x86/pixeladd8.asm	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/x86/pixeladd8.asm	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 ;*****************************************************************************
-;* Copyright (C) 2013-2017 MulticoreWare, Inc
+;* Copyright (C) 2013-2020 MulticoreWare, Inc
 ;*
 ;* Authors: Praveen Kumar Tiwari <praveen@multicorewareinc.com>
 ;*          Min Chen <chenm003@163.com>
--- a/source/common/x86/sad-a.asm	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/x86/sad-a.asm	Fri Jan 31 00:40:19 2020 +0530
@@ -2,7 +2,7 @@
 ;* sad-a.asm: x86 sad functions
 ;*****************************************************************************
 ;* Copyright (C) 2003-2013 x264 project
-;* Copyright (C) 2013-2017 MulticoreWare, Inc
+;* Copyright (C) 2013-2020 MulticoreWare, Inc
 ;*
 ;* Authors: Loren Merritt <lorenm@u.washington.edu>
 ;*          Fiona Glaser <fiona@x264.com>
--- a/source/common/x86/sad16-a.asm	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/x86/sad16-a.asm	Fri Jan 31 00:40:19 2020 +0530
@@ -2,7 +2,7 @@
 ;* sad16-a.asm: x86 high depth sad functions
 ;*****************************************************************************
 ;* Copyright (C) 2003-2013 x264 project
-;* Copyright (C) 2013-2017 MulticoreWare, Inc
+;* Copyright (C) 2013-2020 MulticoreWare, Inc
 ;*
 ;* Authors: Oskar Arvidsson <oskar@irock.se>
 ;*          Henrik Gramner <henrik@gramner.com>
--- a/source/common/x86/seaintegral.asm	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/x86/seaintegral.asm	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 ;*****************************************************************************
-;* Copyright (C) 2013-2017 MulticoreWare, Inc
+;* Copyright (C) 2013-2020 MulticoreWare, Inc
 ;*
 ;* Authors: Jayashri Murugan <jayashri@multicorewareinc.com>
 ;*          Vignesh V Menon <vignesh@multicorewareinc.com>
--- a/source/common/x86/seaintegral.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/x86/seaintegral.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
-* Copyright (C) 2013-2017 MulticoreWare, Inc
+* Copyright (C) 2013-2020 MulticoreWare, Inc
 *
 * Authors: Vignesh V Menon <vignesh@multicorewareinc.com>
 *          Jayashri Murugan <jayashri@multicorewareinc.com>
--- a/source/common/x86/ssd-a.asm	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/x86/ssd-a.asm	Fri Jan 31 00:40:19 2020 +0530
@@ -2,7 +2,7 @@
 ;* ssd-a.asm: x86 ssd functions
 ;*****************************************************************************
 ;* Copyright (C) 2003-2013 x264 project
-;* Copyright (C) 2013-2017 MulticoreWare, Inc
+;* Copyright (C) 2013-2020 MulticoreWare, Inc
 ;*
 ;* Authors: Loren Merritt <lorenm@u.washington.edu>
 ;*          Fiona Glaser <fiona@x264.com>
@@ -3702,4 +3702,4 @@ cglobal pixel_ssd_s_aligned_32, 2,4,5
     movd    eax, xm0
 %endif
     RET
-%endif
\ No newline at end of file
+%endif
--- a/source/common/x86/v4-ipfilter16.asm	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/x86/v4-ipfilter16.asm	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 ;*****************************************************************************
-;* Copyright (C) 2013-2017 MulticoreWare, Inc
+;* Copyright (C) 2013-2020 MulticoreWare, Inc
 ;*
 ;* Authors: Nabajit Deka <nabajit@multicorewareinc.com>
 ;*          Murugan Vairavel <murugan@multicorewareinc.com>
@@ -3528,4 +3528,4 @@ cglobal interp_4tap_vert_%1_8x12, 4, 7, 
 FILTER_VER_CHROMA_AVX2_8x12 pp, 1, 6
 FILTER_VER_CHROMA_AVX2_8x12 ps, 0, INTERP_SHIFT_PS
 FILTER_VER_CHROMA_AVX2_8x12 sp, 1, INTERP_SHIFT_SP
-FILTER_VER_CHROMA_AVX2_8x12 ss, 0, 6
\ No newline at end of file
+FILTER_VER_CHROMA_AVX2_8x12 ss, 0, 6
--- a/source/common/x86/v4-ipfilter8.asm	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/x86/v4-ipfilter8.asm	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 ;*****************************************************************************
-;* Copyright (C) 2013-2017 MulticoreWare, Inc
+;* Copyright (C) 2013-2020 MulticoreWare, Inc
 ;*
 ;* Authors: Min Chen <chenm003@163.com>
 ;*          Nabajit Deka <nabajit@multicorewareinc.com>
--- a/source/common/x86/x86inc.asm	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/x86/x86inc.asm	Fri Jan 31 00:40:19 2020 +0530
@@ -2,7 +2,7 @@
 ;* x86inc.asm: x264asm abstraction layer
 ;*****************************************************************************
 ;* Copyright (C) 2003-2013 x264 project
-;* Copyright (C) 2013-2017 MulticoreWarae, Inc
+;* Copyright (C) 2013-2020 MulticoreWarae, Inc
 ;*
 ;* Authors: Loren Merritt <lorenm@u.washington.edu>
 ;*          Anton Mitrofanov <BugMaster@narod.ru>
--- a/source/common/x86/x86util.asm	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/x86/x86util.asm	Fri Jan 31 00:40:19 2020 +0530
@@ -2,7 +2,7 @@
 ;* x86util.asm: x86 utility macros
 ;*****************************************************************************
 ;* Copyright (C) 2003-2013 x264 project
-;* Copyright (C) 2013-2017 MulticoreWare, Inc
+;* Copyright (C) 2013-2020 MulticoreWare, Inc
 ;*
 ;* Authors: Holger Lubitz <holger@lubitz.org>
 ;*          Loren Merritt <lorenm@u.washington.edu>
--- a/source/common/yuv.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/yuv.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *          Min Chen <chenm003@163.com>
--- a/source/common/yuv.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/common/yuv.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *
--- a/source/dynamicHDR10/BasicStructures.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/dynamicHDR10/BasicStructures.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Bhavna Hariharan <bhavna@multicorewareinc.com>
  *          Kavitha Sampath <kavitha@multicorewareinc.com>
--- a/source/dynamicHDR10/JsonHelper.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/dynamicHDR10/JsonHelper.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Bhavna Hariharan <bhavna@multicorewareinc.com>
  *          Kavitha Sampath <kavitha@multicorewareinc.com>
--- a/source/dynamicHDR10/JsonHelper.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/dynamicHDR10/JsonHelper.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Bhavna Hariharan <bhavna@multicorewareinc.com>
  *          Kavitha Sampath <kavitha@multicorewareinc.com>
--- a/source/dynamicHDR10/LICENSE.txt	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/dynamicHDR10/LICENSE.txt	Fri Jan 31 00:40:19 2020 +0530
@@ -1,4 +1,4 @@
-Copyright (C) 2013-2017 MulticoreWare, Inc
+Copyright (C) 2013-2020 MulticoreWare, Inc
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
--- a/source/dynamicHDR10/SeiMetadataDictionary.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/dynamicHDR10/SeiMetadataDictionary.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Bhavna Hariharan <bhavna@multicorewareinc.com>
  *          Kavitha Sampath <kavitha@multicorewareinc.com>
--- a/source/dynamicHDR10/SeiMetadataDictionary.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/dynamicHDR10/SeiMetadataDictionary.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Bhavna Hariharan <bhavna@multicorewareinc.com>
  *          Kavitha Sampath <kavitha@multicorewareinc.com>
--- a/source/dynamicHDR10/api.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/dynamicHDR10/api.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Bhavna Hariharan <bhavna@multicorewareinc.com>
  *          Kavitha Sampath <kavitha@multicorewareinc.com>
--- a/source/dynamicHDR10/hdr10plus.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/dynamicHDR10/hdr10plus.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Bhavna Hariharan <bhavna@multicorewareinc.com>
  *          Kavitha Sampath <kavitha@multicorewareinc.com>
--- a/source/dynamicHDR10/metadataFromJson.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/dynamicHDR10/metadataFromJson.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Bhavna Hariharan <bhavna@multicorewareinc.com>
  *          Kavitha Sampath <kavitha@multicorewareinc.com>
--- a/source/dynamicHDR10/metadataFromJson.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/dynamicHDR10/metadataFromJson.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Bhavna Hariharan <bhavna@multicorewareinc.com>
  *          Kavitha Sampath <kavitha@multicorewareinc.com>
--- a/source/encoder/analysis.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/encoder/analysis.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
-* Copyright (C) 2013-2017 MulticoreWare, Inc
+* Copyright (C) 2013-2020 MulticoreWare, Inc
 *
 * Authors: Deepthi Nandakumar <deepthi@multicorewareinc.com>
 *          Steve Borho <steve@borho.org>
@@ -202,14 +202,17 @@ Mode& Analysis::compressCTU(CUData& ctu,
         m_reuseDepth = &m_reuseInterDataCTU->depth[ctu.m_cuAddr * ctu.m_numPartitions];
     }
     
-    if ((m_param->analysisSave || m_param->analysisLoad) && m_slice->m_sliceType != I_SLICE && m_param->analysisReuseLevel > 1 && m_param->analysisReuseLevel < 10)
+    int reuseLevel = X265_MAX(m_param->analysisSaveReuseLevel, m_param->analysisLoadReuseLevel);
+    if ((m_param->analysisSave || m_param->analysisLoad) && m_slice->m_sliceType != I_SLICE && reuseLevel > 1 && reuseLevel < 10)
     {
         int numPredDir = m_slice->isInterP() ? 1 : 2;
         m_reuseInterDataCTU = m_frame->m_analysisData.interData;
-        m_reuseRef = &m_reuseInterDataCTU->ref [ctu.m_cuAddr * X265_MAX_PRED_MODE_PER_CTU * numPredDir];
+        if (((m_param->analysisSaveReuseLevel > 1) && (m_param->analysisSaveReuseLevel < 7)) ||
+            ((m_param->analysisLoadReuseLevel > 1) && (m_param->analysisLoadReuseLevel < 7)))
+            m_reuseRef = &m_reuseInterDataCTU->ref[ctu.m_cuAddr * X265_MAX_PRED_MODE_PER_CTU * numPredDir];
         m_reuseDepth = &m_reuseInterDataCTU->depth[ctu.m_cuAddr * ctu.m_numPartitions];
         m_reuseModes = &m_reuseInterDataCTU->modes[ctu.m_cuAddr * ctu.m_numPartitions];
-        if (m_param->analysisReuseLevel > 4)
+        if (reuseLevel > 4)
         {
             m_reusePartSize = &m_reuseInterDataCTU->partSize[ctu.m_cuAddr * ctu.m_numPartitions];
             m_reuseMergeFlag = &m_reuseInterDataCTU->mergeFlag[ctu.m_cuAddr * ctu.m_numPartitions];
@@ -223,7 +226,7 @@ Mode& Analysis::compressCTU(CUData& ctu,
     if (m_slice->m_sliceType == I_SLICE)
     {
         x265_analysis_intra_data* intraDataCTU = m_frame->m_analysisData.intraData;
-        if (m_param->analysisLoad && m_param->analysisReuseLevel > 1)
+        if (m_param->analysisLoadReuseLevel > 1)
         {
             memcpy(ctu.m_cuDepth, &intraDataCTU->depth[ctu.m_cuAddr * numPartition], sizeof(uint8_t) * numPartition);
             memcpy(ctu.m_lumaIntraDir, &intraDataCTU->modes[ctu.m_cuAddr * numPartition], sizeof(uint8_t) * numPartition);
@@ -234,10 +237,10 @@ Mode& Analysis::compressCTU(CUData& ctu,
     }
     else
     {
-        bool bCopyAnalysis = ((m_param->analysisLoad && m_param->analysisReuseLevel == 10) || (m_param->bAnalysisType == AVC_INFO && m_param->analysisReuseLevel >= 7 && ctu.m_numPartitions <= 16));
-        bool BCompressInterCUrd0_4 = (m_param->bAnalysisType == AVC_INFO && m_param->analysisReuseLevel >= 7 && m_param->rdLevel <= 4);
-        bool BCompressInterCUrd5_6 = (m_param->bAnalysisType == AVC_INFO && m_param->analysisReuseLevel >= 7 && m_param->rdLevel >= 5 && m_param->rdLevel <= 6);
-        bCopyAnalysis = bCopyAnalysis || BCompressInterCUrd0_4 || BCompressInterCUrd5_6;
+        bool bCopyAnalysis = ((m_param->analysisLoadReuseLevel == 10) || (m_param->bAnalysisType == AVC_INFO && m_param->analysisLoadReuseLevel >= 7 && ctu.m_numPartitions <= 16));
+        bool bCompressInterCUrd0_4 = (m_param->bAnalysisType == AVC_INFO && m_param->analysisLoadReuseLevel >= 7 && m_param->rdLevel <= 4);
+        bool bCompressInterCUrd5_6 = (m_param->bAnalysisType == AVC_INFO && m_param->analysisLoadReuseLevel >= 7 && m_param->rdLevel >= 5 && m_param->rdLevel <= 6);
+        bCopyAnalysis = bCopyAnalysis || bCompressInterCUrd0_4 || bCompressInterCUrd5_6;
 
         if (bCopyAnalysis)
         {
@@ -275,8 +278,8 @@ Mode& Analysis::compressCTU(CUData& ctu,
             /* generate residual for entire CTU at once and copy to reconPic */
             encodeResidue(ctu, cuGeom);
         }
-        else if ((m_param->analysisLoad && m_param->analysisReuseLevel == 10 && (!(m_param->bAnalysisType == HEVC_INFO) || m_slice->m_sliceType != P_SLICE)) ||
-                 ((m_param->bAnalysisType == AVC_INFO) && m_param->analysisReuseLevel >= 7 && ctu.m_numPartitions <= 16))
+        else if ((m_param->analysisLoadReuseLevel == 10 && (!(m_param->bAnalysisType == HEVC_INFO) || m_slice->m_sliceType != P_SLICE)) ||
+                ((m_param->bAnalysisType == AVC_INFO) && m_param->analysisLoadReuseLevel >= 7 && ctu.m_numPartitions <= 16))
         {
             x265_analysis_inter_data* interDataCTU = m_frame->m_analysisData.interData;
             int posCTU = ctu.m_cuAddr * numPartition;
@@ -375,12 +378,12 @@ int32_t Analysis::loadTUDepth(CUGeom cuG
     CUData* neighbourCU;
     uint8_t count = 0;
     int32_t maxTUDepth = -1;
-    neighbourCU = m_slice->m_refFrameList[0][0]->m_encData->m_picCTU;
+    neighbourCU = &m_slice->m_refFrameList[0][0]->m_encData->m_picCTU[parentCTU.m_cuAddr];
     predDepth += neighbourCU->m_refTuDepth[cuGeom.geomRecurId];
     count++;
     if (m_slice->isInterB())
     {
-        neighbourCU = m_slice->m_refFrameList[1][0]->m_encData->m_picCTU;
+        neighbourCU = &m_slice->m_refFrameList[1][0]->m_encData->m_picCTU[parentCTU.m_cuAddr];
         predDepth += neighbourCU->m_refTuDepth[cuGeom.geomRecurId];
         count++;
     }
@@ -456,7 +459,7 @@ void Analysis::qprdRefine(const CUData& 
     int bestCUQP = qp;
     int lambdaQP = lqp;
     bool doQPRefine = (bDecidedDepth && depth <= m_slice->m_pps->maxCuDQPDepth) || (!bDecidedDepth && depth == m_slice->m_pps->maxCuDQPDepth);
-    if (m_param->analysisReuseLevel >= 7)
+    if (m_param->analysisLoadReuseLevel >= 7)
         doQPRefine = false;
     if (doQPRefine)
     {
@@ -1164,7 +1167,7 @@ SplitData Analysis::compressInterCU_rd0_
     SplitData splitCUData;
 
     bool bHEVCBlockAnalysis = (m_param->bAnalysisType == AVC_INFO && cuGeom.numPartitions > 16);
-    bool bRefineAVCAnalysis = (m_param->analysisReuseLevel == 7 && (m_modeFlag[0] || m_modeFlag[1]));
+    bool bRefineAVCAnalysis = (m_param->analysisLoadReuseLevel == 7 && (m_modeFlag[0] || m_modeFlag[1]));
     bool bNooffloading = !(m_param->bAnalysisType == AVC_INFO);
 
     if (bHEVCBlockAnalysis || bRefineAVCAnalysis || bNooffloading)
@@ -1259,7 +1262,7 @@ SplitData Analysis::compressInterCU_rd0_
                 mightSplit &= !bDecidedDepth;
             }
         }
-        if ((m_param->analysisLoad && m_param->analysisReuseLevel > 1 && m_param->analysisReuseLevel != 10))
+        if ((m_param->analysisLoadReuseLevel > 1 && m_param->analysisLoadReuseLevel != 10))
         {
             if (mightNotSplit && depth == m_reuseDepth[cuGeom.absPartIdx])
             {
@@ -1273,7 +1276,7 @@ SplitData Analysis::compressInterCU_rd0_
                     if (m_param->rdLevel)
                         skipModes = m_param->bEnableEarlySkip && md.bestMode;
                 }
-                if (m_param->analysisReuseLevel > 4 && m_reusePartSize[cuGeom.absPartIdx] == SIZE_2Nx2N)
+                if (m_param->analysisLoadReuseLevel > 4 && m_reusePartSize[cuGeom.absPartIdx] == SIZE_2Nx2N)
                 {
                     if (m_reuseModes[cuGeom.absPartIdx] != MODE_INTRA  && m_reuseModes[cuGeom.absPartIdx] != 4)
                     {
@@ -1300,7 +1303,8 @@ SplitData Analysis::compressInterCU_rd0_
             }
         }
         /* Step 1. Evaluate Merge/Skip candidates for likely early-outs, if skip mode was not set above */
-        if ((mightNotSplit && depth >= minDepth && !md.bestMode && !bCtuInfoCheck) || (m_param->bAnalysisType == AVC_INFO && m_param->analysisReuseLevel == 7 && (m_modeFlag[0] || m_modeFlag[1]))) /* TODO: Re-evaluate if analysis load/save still works */
+        if ((mightNotSplit && depth >= minDepth && !md.bestMode && !bCtuInfoCheck) || (m_param->bAnalysisType == AVC_INFO && m_param->analysisLoadReuseLevel == 7 && (m_modeFlag[0] || m_modeFlag[1])))
+            /* TODO: Re-evaluate if analysis load/save still works */
         {
             /* Compute Merge Cost */
             md.pred[PRED_MERGE].cu.initSubCU(parentCTU, cuGeom, qp);
@@ -1310,7 +1314,7 @@ SplitData Analysis::compressInterCU_rd0_
                 skipModes = (m_param->bEnableEarlySkip || m_refineLevel == 2)
                 && md.bestMode && md.bestMode->cu.isSkipped(0); // TODO: sa8d threshold per depth
         }
-        if (md.bestMode && m_param->bEnableRecursionSkip && !bCtuInfoCheck && !(m_param->bAnalysisType == AVC_INFO && m_param->analysisReuseLevel == 7 && (m_modeFlag[0] || m_modeFlag[1])))
+        if (md.bestMode && m_param->bEnableRecursionSkip && !bCtuInfoCheck && !(m_param->bAnalysisType == AVC_INFO && m_param->analysisLoadReuseLevel == 7 && (m_modeFlag[0] || m_modeFlag[1])))
         {
             skipRecursion = md.bestMode->cu.isSkipped(0);
             if (mightSplit && depth >= minDepth && !skipRecursion)
@@ -1321,7 +1325,7 @@ SplitData Analysis::compressInterCU_rd0_
                     skipRecursion = complexityCheckCU(*md.bestMode);
             }
         }
-        if (m_param->bAnalysisType == AVC_INFO && md.bestMode && cuGeom.numPartitions <= 16 && m_param->analysisReuseLevel == 7)
+        if (m_param->bAnalysisType == AVC_INFO && md.bestMode && cuGeom.numPartitions <= 16 && m_param->analysisLoadReuseLevel == 7)
             skipRecursion = true;
         /* Step 2. Evaluate each of the 4 split sub-blocks in series */
         if (mightSplit && !skipRecursion)
@@ -1378,7 +1382,7 @@ SplitData Analysis::compressInterCU_rd0_
                 splitPred->sa8dCost = m_rdCost.calcRdSADCost((uint32_t)splitPred->distortion, splitPred->sa8dBits);
         }
         /* If analysis mode is simple do not Evaluate other modes */
-        if (m_param->bAnalysisType == AVC_INFO && m_param->analysisReuseLevel == 7)
+        if (m_param->bAnalysisType == AVC_INFO && m_param->analysisLoadReuseLevel == 7)
         {
             if (m_slice->m_sliceType == P_SLICE)
             {
@@ -1857,7 +1861,7 @@ SplitData Analysis::compressInterCU_rd5_
     SplitData splitCUData;
 
     bool bHEVCBlockAnalysis = (m_param->bAnalysisType == AVC_INFO && cuGeom.numPartitions > 16);
-    bool bRefineAVCAnalysis = (m_param->analysisReuseLevel == 7 && (m_modeFlag[0] || m_modeFlag[1]));
+    bool bRefineAVCAnalysis = (m_param->analysisLoadReuseLevel == 7 && (m_modeFlag[0] || m_modeFlag[1]));
     bool bNooffloading = !(m_param->bAnalysisType == AVC_INFO);
 
     if (bHEVCBlockAnalysis || bRefineAVCAnalysis || bNooffloading)
@@ -1953,7 +1957,7 @@ SplitData Analysis::compressInterCU_rd5_
                 mightSplit &= !bDecidedDepth;
             }
         }
-        if (m_param->analysisLoad && m_param->analysisReuseLevel > 1 && m_param->analysisReuseLevel != 10)
+        if (m_param->analysisLoadReuseLevel > 1 && m_param->analysisLoadReuseLevel != 10)
         {
             if (mightNotSplit && depth == m_reuseDepth[cuGeom.absPartIdx])
             {
@@ -1971,7 +1975,7 @@ SplitData Analysis::compressInterCU_rd5_
                     if (m_param->bEnableRecursionSkip && depth && m_modeDepth[depth - 1].bestMode)
                         skipRecursion = md.bestMode && !md.bestMode->cu.getQtRootCbf(0);
                 }
-                if (m_param->analysisReuseLevel > 4 && m_reusePartSize[cuGeom.absPartIdx] == SIZE_2Nx2N)
+                if (m_param->analysisLoadReuseLevel > 4 && m_reusePartSize[cuGeom.absPartIdx] == SIZE_2Nx2N)
                     skipRectAmp = true && !!md.bestMode;
             }
         }
@@ -1999,7 +2003,7 @@ SplitData Analysis::compressInterCU_rd5_
         }
         /* Step 1. Evaluate Merge/Skip candidates for likely early-outs */
         if ((mightNotSplit && !md.bestMode && !bCtuInfoCheck) ||
-            (m_param->bAnalysisType == AVC_INFO && m_param->analysisReuseLevel == 7 && (m_modeFlag[0] || m_modeFlag[1])))
+            (m_param->bAnalysisType == AVC_INFO && m_param->analysisLoadReuseLevel == 7 && (m_modeFlag[0] || m_modeFlag[1])))
         {
             md.pred[PRED_SKIP].cu.initSubCU(parentCTU, cuGeom, qp);
             md.pred[PRED_MERGE].cu.initSubCU(parentCTU, cuGeom, qp);
@@ -2014,7 +2018,7 @@ SplitData Analysis::compressInterCU_rd5_
             if (m_param->bEnableRecursionSkip && depth && m_modeDepth[depth - 1].bestMode)
                 skipRecursion = md.bestMode && !md.bestMode->cu.getQtRootCbf(0);
         }
-        if (m_param->bAnalysisType == AVC_INFO && md.bestMode && cuGeom.numPartitions <= 16 && m_param->analysisReuseLevel == 7)
+        if (m_param->bAnalysisType == AVC_INFO && md.bestMode && cuGeom.numPartitions <= 16 && m_param->analysisLoadReuseLevel == 7)
             skipRecursion = true;
         // estimate split cost
         /* Step 2. Evaluate each of the 4 split sub-blocks in series */
@@ -2068,7 +2072,7 @@ SplitData Analysis::compressInterCU_rd5_
             checkDQPForSplitPred(*splitPred, cuGeom);
         }
         /* If analysis mode is simple do not Evaluate other modes */
-        if (m_param->bAnalysisType == AVC_INFO && m_param->analysisReuseLevel == 7)
+        if (m_param->bAnalysisType == AVC_INFO && m_param->analysisLoadReuseLevel == 7)
         {
             if (m_slice->m_sliceType == P_SLICE)
             {
@@ -2461,7 +2465,7 @@ void Analysis::recodeCU(const CUData& pa
             for (uint32_t part = 0; part < numPU; part++)
             {
                 PredictionUnit pu(mode.cu, cuGeom, part);
-                if ((m_param->analysisLoad && m_param->analysisReuseLevel == 10) || (m_param->bAnalysisType == AVC_INFO && m_param->analysisReuseLevel >= 7))
+                if (m_param->analysisLoadReuseLevel == 10 || (m_param->bAnalysisType == AVC_INFO && m_param->analysisLoadReuseLevel >= 7))
                 {
                     x265_analysis_inter_data* interDataCTU = m_frame->m_analysisData.interData;
                     int cuIdx = (mode.cu.m_cuAddr * parentCTU.m_numPartitions) + cuGeom.absPartIdx;
@@ -2475,7 +2479,7 @@ void Analysis::recodeCU(const CUData& pa
                     }
                     if (!mode.cu.m_mergeFlag[pu.puAbsPartIdx])
                     {
-                        if (m_param->mvRefine || m_param->interRefine == 1)
+                        if (m_param->interRefine == 1)
                             m_me.setSourcePU(*mode.fencYuv, pu.ctuAddr, pu.cuAbsPartIdx, pu.puAbsPartIdx, pu.width, pu.height, m_param->searchMethod, m_param->subpelRefine, false);
                         //AMVP
                         MV mvc[(MD_ABOVE_LEFT + 1) * 2 + 2];
@@ -2489,7 +2493,7 @@ void Analysis::recodeCU(const CUData& pa
 
                             int numMvc = mode.cu.getPMV(mode.interNeighbours, list, ref, mode.amvpCand[list][ref], mvc);
                             mvp = mode.amvpCand[list][ref][mode.cu.m_mvpIdx[list][pu.puAbsPartIdx]];
-                            if (m_param->mvRefine || m_param->interRefine == 1)
+                            if (m_param->interRefine == 1)
                             {
                                 MV outmv, mvpSelect[3];
                                 mvpSelect[0] = interDataCTU->mv[list][cuIdx + part].word;
@@ -2552,7 +2556,7 @@ void Analysis::recodeCU(const CUData& pa
                 checkDQPForSplitPred(*md.bestMode, cuGeom);
         }
 
-        if (m_param->bAnalysisType == AVC_INFO && m_param->analysisReuseLevel == 7)
+        if (m_param->bAnalysisType == AVC_INFO && m_param->analysisLoadReuseLevel == 7)
         {
             for (int list = 0; list < m_slice->isInterB() + 1; list++)
             {
@@ -2607,7 +2611,7 @@ void Analysis::recodeCU(const CUData& pa
                 if (m_slice->m_pps->bUseDQP && nextDepth <= m_slice->m_pps->maxCuDQPDepth)
                     nextQP = setLambdaFromQP(parentCTU, calculateQpforCuSize(parentCTU, childGeom));
 
-                int lamdaQP = (m_param->analysisReuseLevel >= 7) ? nextQP : lqp;
+                int lamdaQP = (m_param->analysisLoadReuseLevel >= 7) ? nextQP : lqp;
 
                 if (split)
                     m_param->rdLevel > 4 ? compressInterCU_rd5_6(parentCTU, childGeom, nextQP) : compressInterCU_rd0_4(parentCTU, childGeom, nextQP);
@@ -3013,7 +3017,7 @@ void Analysis::checkInter_rd0_4(Mode& in
     interMode.cu.setPredModeSubParts(MODE_INTER);
     int numPredDir = m_slice->isInterP() ? 1 : 2;
 
-    if (m_param->analysisLoad && m_reuseInterDataCTU && m_param->analysisReuseLevel > 1 && m_param->analysisReuseLevel != 10)
+    if (m_param->analysisLoadReuseLevel > 1 && m_param->analysisLoadReuseLevel != 10 && m_reuseInterDataCTU)
     {
         int refOffset = cuGeom.geomRecurId * 16 * numPredDir + partSize * numPredDir * 2;
         int index = 0;
@@ -3056,7 +3060,7 @@ void Analysis::checkInter_rd0_4(Mode& in
     }
     interMode.sa8dCost = m_rdCost.calcRdSADCost((uint32_t)interMode.distortion, interMode.sa8dBits);
 
-    if (m_param->analysisSave && m_reuseInterDataCTU && m_param->analysisReuseLevel > 1)
+    if (m_param->analysisSaveReuseLevel > 1 && m_reuseInterDataCTU)
     {
         int refOffset = cuGeom.geomRecurId * 16 * numPredDir + partSize * numPredDir * 2;
         int index = 0;
@@ -3078,7 +3082,7 @@ void Analysis::checkInter_rd5_6(Mode& in
     interMode.cu.setPredModeSubParts(MODE_INTER);
     int numPredDir = m_slice->isInterP() ? 1 : 2;
 
-    if (m_param->analysisLoad && m_reuseInterDataCTU && m_param->analysisReuseLevel > 1 && m_param->analysisReuseLevel != 10)
+    if (m_param->analysisLoadReuseLevel > 1 && m_param->analysisLoadReuseLevel != 10 && m_reuseInterDataCTU)
     {
         int refOffset = cuGeom.geomRecurId * 16 * numPredDir + partSize * numPredDir * 2;
         int index = 0;
@@ -3113,7 +3117,7 @@ void Analysis::checkInter_rd5_6(Mode& in
     /* predInterSearch sets interMode.sa8dBits, but this is ignored */
     encodeResAndCalcRdInterCU(interMode, cuGeom);
 
-    if (m_param->analysisSave && m_reuseInterDataCTU && m_param->analysisReuseLevel > 1)
+    if (m_param->analysisSaveReuseLevel > 1 && m_reuseInterDataCTU)
     {
         int refOffset = cuGeom.geomRecurId * 16 * numPredDir + partSize * numPredDir * 2;
         int index = 0;
@@ -3612,7 +3616,7 @@ int Analysis::calculateQpforCuSize(const
             qp += distortionData->offset[ctu.m_cuAddr];
     }
 
-    if (m_param->analysisLoad && m_param->analysisReuseLevel == 10 && m_param->rc.cuTree)
+    if (m_param->analysisLoadReuseLevel == 10 && m_param->rc.cuTree)
     {
         int cuIdx = (ctu.m_cuAddr * ctu.m_numPartitions) + cuGeom.absPartIdx;
         if (ctu.m_slice->m_sliceType == I_SLICE)
--- a/source/encoder/analysis.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/encoder/analysis.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
-* Copyright (C) 2013-2017 MulticoreWare, Inc
+* Copyright (C) 2013-2020 MulticoreWare, Inc
 *
 * Authors: Deepthi Nandakumar <deepthi@multicorewareinc.com>
 *          Steve Borho <steve@borho.org>
--- a/source/encoder/api.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/encoder/api.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *
@@ -100,7 +100,7 @@ x265_encoder *x265_encoder_open(x265_par
     if(param) PARAM_NS::x265_param_default(param);
     if(latestParam) PARAM_NS::x265_param_default(latestParam);
     if(zoneParam) PARAM_NS::x265_param_default(zoneParam);
-
+  
     if (!param || !latestParam || !zoneParam)
         goto fail;
     if (p->rc.zoneCount || p->rc.zonefileCount)
@@ -108,6 +108,7 @@ x265_encoder *x265_encoder_open(x265_par
         int zoneCount = p->rc.zonefileCount ? p->rc.zonefileCount : p->rc.zoneCount;
         param->rc.zones = x265_zone_alloc(zoneCount, !!p->rc.zonefileCount);
         latestParam->rc.zones = x265_zone_alloc(zoneCount, !!p->rc.zonefileCount);
+        zoneParam->rc.zones = x265_zone_alloc(zoneCount, !!p->rc.zonefileCount);
     }
 
     x265_copy_params(param, p);
@@ -175,6 +176,8 @@ x265_encoder *x265_encoder_open(x265_par
 
     // may change params for auto-detect, etc
     encoder->configure(param);
+    if (encoder->m_aborted)
+        goto fail;
     // may change rate control and CPB params
     if (!enforceLevel(*param, encoder->m_vps))
         goto fail;
@@ -189,10 +192,23 @@ x265_encoder *x265_encoder_open(x265_par
     }
 
     encoder->create();
+    p->frameNumThreads = encoder->m_param->frameNumThreads;
+
+    if (!param->bResetZoneConfig)
+    {
+        param->rc.zones = X265_MALLOC(x265_zone, param->rc.zonefileCount);
+        for (int i = 0; i < param->rc.zonefileCount; i++)
+        {
+            param->rc.zones[i].zoneParam = X265_MALLOC(x265_param, 1);
+            memcpy(param->rc.zones[i].zoneParam, param, sizeof(x265_param));
+            param->rc.zones[i].relativeComplexity = X265_MALLOC(double, param->reconfigWindowSize);
+        }
+    }
 
     memcpy(zoneParam, param, sizeof(x265_param));
     for (int i = 0; i < param->rc.zonefileCount; i++)
     {
+        param->rc.zones[i].startFrame = -1;
         encoder->configureZone(zoneParam, param->rc.zones[i].zoneParam);
     }
 
@@ -361,6 +377,36 @@ int x265_encoder_reconfig(x265_encoder* 
     return ret;
 }
 
+
+int x265_encoder_reconfig_zone(x265_encoder* enc, x265_zone* zone_in)
+{
+    if (!enc || !zone_in)
+        return -1;
+
+    Encoder* encoder = static_cast<Encoder*>(enc);
+    int read = encoder->zoneReadCount[encoder->m_zoneIndex].get();
+    int write = encoder->zoneWriteCount[encoder->m_zoneIndex].get();
+
+    x265_zone* zone = &(encoder->m_param->rc).zones[encoder->m_zoneIndex];
+    x265_param* zoneParam = zone->zoneParam;
+
+    if (write && (read < write))
+    {
+        read = encoder->zoneReadCount[encoder->m_zoneIndex].waitForChange(read);
+    }
+
+    zone->startFrame = zone_in->startFrame;
+    zoneParam->rc.bitrate = zone_in->zoneParam->rc.bitrate;
+    zoneParam->rc.vbvMaxBitrate = zone_in->zoneParam->rc.vbvMaxBitrate;
+    memcpy(zone->relativeComplexity, zone_in->relativeComplexity, sizeof(double) * encoder->m_param->reconfigWindowSize);
+    
+    encoder->zoneWriteCount[encoder->m_zoneIndex].incr();
+    encoder->m_zoneIndex++;
+    encoder->m_zoneIndex %= encoder->m_param->rc.zonefileCount;
+
+    return 0;
+}
+
 int x265_encoder_encode(x265_encoder *enc, x265_nal **pp_nal, uint32_t *pi_nal, x265_picture *pic_in, x265_picture *pic_out)
 {
     if (!enc)
@@ -371,12 +417,12 @@ int x265_encoder_encode(x265_encoder *en
 
 #ifdef SVT_HEVC
     EB_ERRORTYPE return_error;
-    static unsigned char picSendDone = 0;
-    numEncoded = 0;
-    static int codedNal = 0, eofReached = 0;
-	EB_H265_ENC_CONFIGURATION* svtParam = (EB_H265_ENC_CONFIGURATION*)encoder->m_svtAppData->svtHevcParams;
     if (encoder->m_param->bEnableSvtHevc)
     {
+        static unsigned char picSendDone = 0;
+        numEncoded = 0;
+        static int codedNal = 0, eofReached = 0;
+        EB_H265_ENC_CONFIGURATION* svtParam = (EB_H265_ENC_CONFIGURATION*)encoder->m_svtAppData->svtHevcParams;
         if (pic_in)
         {
             if (pic_in->colorSpace == X265_CSP_I420) // SVT-HEVC supports only yuv420p color space
@@ -727,6 +773,12 @@ void x265_alloc_analysis_data(x265_param
     int numDir = 2; //irrespective of P or B slices set direction as 2
     uint32_t numPlanes = param->internalCsp == X265_CSP_I400 ? 1 : 3;
 
+    int maxReuseLevel = X265_MAX(param->analysisSaveReuseLevel, param->analysisLoadReuseLevel);
+    int minReuseLevel = (param->analysisSaveReuseLevel && param->analysisLoadReuseLevel) ?
+                        X265_MIN(param->analysisSaveReuseLevel, param->analysisLoadReuseLevel) : maxReuseLevel;
+
+    bool isMultiPassOpt = param->analysisMultiPassRefine || param->analysisMultiPassDistortion;
+                      
 #if X265_DEPTH < 10 && (LINKED_10BIT || LINKED_12BIT)
     uint32_t numCUs_sse_t = param->internalBitDepth > 8 ? analysis->numCUsInFrame << 1 : analysis->numCUsInFrame;
 #elif X265_DEPTH >= 10 && LINKED_8BIT
@@ -734,7 +786,7 @@ void x265_alloc_analysis_data(x265_param
 #else
     uint32_t numCUs_sse_t = analysis->numCUsInFrame;
 #endif
-    if (param->analysisMultiPassRefine || param->analysisMultiPassDistortion || param->ctuDistortionRefine)
+    if (isMultiPassOpt || param->ctuDistortionRefine)
     {
         //Allocate memory for distortionData pointer
         CHECKED_MALLOC_ZERO(distortionData, x265_analysis_distortion_data, 1);
@@ -748,7 +800,7 @@ void x265_alloc_analysis_data(x265_param
         analysis->distortionData = distortionData;
     }
 
-    if (param->bDisableLookahead && isVbv)
+    if (!isMultiPassOpt && param->bDisableLookahead && isVbv)
     {
         CHECKED_MALLOC_ZERO(analysis->lookahead.intraSatdForVbv, uint32_t, analysis->numCuInHeight);
         CHECKED_MALLOC_ZERO(analysis->lookahead.satdForVbv, uint32_t, analysis->numCuInHeight);
@@ -757,40 +809,47 @@ void x265_alloc_analysis_data(x265_param
     }
 
     //Allocate memory for weightParam pointer
-    if (!(param->bAnalysisType == AVC_INFO))
+    if (!isMultiPassOpt && !(param->bAnalysisType == AVC_INFO))
         CHECKED_MALLOC_ZERO(analysis->wt, x265_weight_param, numPlanes * numDir);
 
-    if (param->analysisReuseLevel < 2)
-        return;
-
     //Allocate memory for intraData pointer
-    CHECKED_MALLOC_ZERO(intraData, x265_analysis_intra_data, 1);
-    CHECKED_MALLOC(intraData->depth, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
-    CHECKED_MALLOC_ZERO(intraData->modes, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
-    CHECKED_MALLOC_ZERO(intraData->partSizes, char, analysis->numPartitions * analysis->numCUsInFrame);
-    CHECKED_MALLOC_ZERO(intraData->chromaModes, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
-    if (param->rc.cuTree)
-        CHECKED_MALLOC_ZERO(intraData->cuQPOff, int8_t, analysis->numPartitions * analysis->numCUsInFrame);
+    if ((maxReuseLevel > 1) || isMultiPassOpt)
+    {
+        CHECKED_MALLOC_ZERO(intraData, x265_analysis_intra_data, 1);
+        CHECKED_MALLOC(intraData->depth, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
+    }
+
+    if (maxReuseLevel > 1)
+    {
+        CHECKED_MALLOC_ZERO(intraData->modes, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
+        CHECKED_MALLOC_ZERO(intraData->partSizes, char, analysis->numPartitions * analysis->numCUsInFrame);
+        CHECKED_MALLOC_ZERO(intraData->chromaModes, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
+        if (param->rc.cuTree)
+            CHECKED_MALLOC_ZERO(intraData->cuQPOff, int8_t, analysis->numPartitions * analysis->numCUsInFrame);
+    }
     analysis->intraData = intraData;
 
-    //Allocate memory for interData pointer based on ReuseLevels
-    CHECKED_MALLOC_ZERO(interData, x265_analysis_inter_data, 1);
-    CHECKED_MALLOC(interData->depth, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
-    CHECKED_MALLOC_ZERO(interData->modes, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
+    if ((maxReuseLevel > 1) || isMultiPassOpt)
+    {
+        //Allocate memory for interData pointer based on ReuseLevels
+        CHECKED_MALLOC_ZERO(interData, x265_analysis_inter_data, 1);
+        CHECKED_MALLOC(interData->depth, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
+        CHECKED_MALLOC_ZERO(interData->modes, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
 
-    if (param->rc.cuTree)
-        CHECKED_MALLOC_ZERO(interData->cuQPOff, int8_t, analysis->numPartitions * analysis->numCUsInFrame);
-    CHECKED_MALLOC_ZERO(interData->mvpIdx[0], uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
-    CHECKED_MALLOC_ZERO(interData->mvpIdx[1], uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
-    CHECKED_MALLOC_ZERO(interData->mv[0], x265_analysis_MV, analysis->numPartitions * analysis->numCUsInFrame);
-    CHECKED_MALLOC_ZERO(interData->mv[1], x265_analysis_MV, analysis->numPartitions * analysis->numCUsInFrame);
+        if (param->rc.cuTree && !isMultiPassOpt)
+            CHECKED_MALLOC_ZERO(interData->cuQPOff, int8_t, analysis->numPartitions * analysis->numCUsInFrame);
+        CHECKED_MALLOC_ZERO(interData->mvpIdx[0], uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
+        CHECKED_MALLOC_ZERO(interData->mvpIdx[1], uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
+        CHECKED_MALLOC_ZERO(interData->mv[0], x265_analysis_MV, analysis->numPartitions * analysis->numCUsInFrame);
+        CHECKED_MALLOC_ZERO(interData->mv[1], x265_analysis_MV, analysis->numPartitions * analysis->numCUsInFrame);
+    }
 
-    if (param->analysisReuseLevel > 4)
+    if (maxReuseLevel > 4)
     {
         CHECKED_MALLOC_ZERO(interData->partSize, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
         CHECKED_MALLOC_ZERO(interData->mergeFlag, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
     }
-    if (param->analysisReuseLevel >= 7)
+    if (maxReuseLevel >= 7)
     {
         CHECKED_MALLOC_ZERO(interData->interDir, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
         CHECKED_MALLOC_ZERO(interData->sadCost, int64_t, analysis->numPartitions * analysis->numCUsInFrame);
@@ -800,14 +859,13 @@ void x265_alloc_analysis_data(x265_param
             CHECKED_MALLOC_ZERO(analysis->modeFlag[dir], uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
         }
     }
-    else
+    if ((minReuseLevel >= 2) && (minReuseLevel <= 6))
     {
-        if (param->analysisMultiPassRefine || param->analysisMultiPassDistortion){
-            CHECKED_MALLOC_ZERO(interData->ref, int32_t, 2 * analysis->numPartitions * analysis->numCUsInFrame);
-        }
-        else
-            CHECKED_MALLOC_ZERO(interData->ref, int32_t, analysis->numCUsInFrame * X265_MAX_PRED_MODE_PER_CTU * numDir);
+        CHECKED_MALLOC_ZERO(interData->ref, int32_t, analysis->numCUsInFrame * X265_MAX_PRED_MODE_PER_CTU * numDir);
     }
+    if (isMultiPassOpt)
+        CHECKED_MALLOC_ZERO(interData->ref, int32_t, 2 * analysis->numPartitions * analysis->numCUsInFrame);
+
     analysis->interData = interData;
 
     return;
@@ -818,10 +876,15 @@ fail:
 
 void x265_free_analysis_data(x265_param *param, x265_analysis_data* analysis)
 {
+    int maxReuseLevel = X265_MAX(param->analysisSaveReuseLevel, param->analysisLoadReuseLevel);
+    int minReuseLevel = (param->analysisSaveReuseLevel && param->analysisLoadReuseLevel) ?
+                        X265_MIN(param->analysisSaveReuseLevel, param->analysisLoadReuseLevel) : maxReuseLevel;
+
     bool isVbv = param->rc.vbvMaxBitrate > 0 && param->rc.vbvBufferSize > 0;
+    bool isMultiPassOpt = param->analysisMultiPassRefine || param->analysisMultiPassDistortion;
 
     //Free memory for Lookahead pointers
-    if (param->bDisableLookahead && isVbv)
+    if (!isMultiPassOpt && param->bDisableLookahead && isVbv)
     {
         X265_FREE(analysis->lookahead.satdForVbv);
         X265_FREE(analysis->lookahead.intraSatdForVbv);
@@ -843,21 +906,21 @@ void x265_free_analysis_data(x265_param 
     }
 
     /* Early exit freeing weights alone if level is 1 (when there is no analysis inter/intra) */
-    if (analysis->wt && !(param->bAnalysisType == AVC_INFO))
+    if (!isMultiPassOpt && analysis->wt && !(param->bAnalysisType == AVC_INFO))
         X265_FREE(analysis->wt);
 
-    if (param->analysisReuseLevel < 2)
-        return;
-
     //Free memory for intraData pointers
     if (analysis->intraData)
     {
         X265_FREE((analysis->intraData)->depth);
-        X265_FREE((analysis->intraData)->modes);
-        X265_FREE((analysis->intraData)->partSizes);
-        X265_FREE((analysis->intraData)->chromaModes);
-        if (param->rc.cuTree)
-            X265_FREE((analysis->intraData)->cuQPOff);
+        if (!isMultiPassOpt)
+        {
+            X265_FREE((analysis->intraData)->modes);
+            X265_FREE((analysis->intraData)->partSizes);
+            X265_FREE((analysis->intraData)->chromaModes);
+            if (param->rc.cuTree)
+                X265_FREE((analysis->intraData)->cuQPOff);
+        }
         X265_FREE(analysis->intraData);
         analysis->intraData = NULL;
     }
@@ -867,19 +930,19 @@ void x265_free_analysis_data(x265_param 
     {
         X265_FREE((analysis->interData)->depth);
         X265_FREE((analysis->interData)->modes);
-        if (param->rc.cuTree)
+        if (!isMultiPassOpt && param->rc.cuTree)
             X265_FREE((analysis->interData)->cuQPOff);
         X265_FREE((analysis->interData)->mvpIdx[0]);
         X265_FREE((analysis->interData)->mvpIdx[1]);
         X265_FREE((analysis->interData)->mv[0]);
         X265_FREE((analysis->interData)->mv[1]);
 
-        if (param->analysisReuseLevel > 4)
+        if (maxReuseLevel > 4)
         {
             X265_FREE((analysis->interData)->mergeFlag);
             X265_FREE((analysis->interData)->partSize);
         }
-        if (param->analysisReuseLevel >= 7)
+        if (maxReuseLevel >= 7)
         {
             int numDir = 2;
             X265_FREE((analysis->interData)->interDir);
@@ -888,13 +951,13 @@ void x265_free_analysis_data(x265_param 
             {
                 X265_FREE((analysis->interData)->refIdx[dir]);
                 if (analysis->modeFlag[dir] != NULL)
-                {
+                { 
                     X265_FREE(analysis->modeFlag[dir]);
                     analysis->modeFlag[dir] = NULL;
                 }
             }
         }
-        else
+        if (((minReuseLevel >= 2) && (minReuseLevel <= 6)) || isMultiPassOpt)
             X265_FREE((analysis->interData)->ref);
         X265_FREE(analysis->interData);
         analysis->interData = NULL;
@@ -923,6 +986,7 @@ void x265_picture_init(x265_param *param
     pic->userSEI.numPayloads = 0;
     pic->rpu.payloadSize = 0;
     pic->rpu.payload = NULL;
+    pic->picStruct = 0;
 
     if ((param->analysisSave || param->analysisLoad) || (param->bAnalysisType == AVC_INFO))
     {
@@ -986,6 +1050,7 @@ static const x265_api libapi =
     &x265_encoder_open,
     &x265_encoder_parameters,
     &x265_encoder_reconfig,
+    &x265_encoder_reconfig_zone,
     &x265_encoder_headers,
     &x265_encoder_encode,
     &x265_encoder_get_stats,
--- a/source/encoder/bitcost.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/encoder/bitcost.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *          Min Chen <chenm003@163.com>
--- a/source/encoder/bitcost.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/encoder/bitcost.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *
--- a/source/encoder/dpb.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/encoder/dpb.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *          Min Chen <chenm003@163.com>
--- a/source/encoder/dpb.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/encoder/dpb.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *
@@ -52,12 +52,15 @@ public:
         m_lastIDR = 0;
         m_pocCRA = 0;
         m_bhasLeadingPicture = param->radl;
-        for (int i = 0; i < param->rc.zonefileCount; i++)
+        if (param->bResetZoneConfig)
         {
-            if (param->rc.zones[i].zoneParam->radl)
+            for (int i = 0; i < param->rc.zonefileCount ; i++)
             {
-                m_bhasLeadingPicture = param->rc.zones[i].zoneParam->radl;
-                break;
+                if (param->rc.zones[i].zoneParam->radl)
+                {
+                    m_bhasLeadingPicture = param->rc.zones[i].zoneParam->radl;
+                    break;
+                }
             }
         }
         m_bRefreshPending = false;
--- a/source/encoder/encoder.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/encoder/encoder.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *          Min Chen <chenm003@163.com>
@@ -81,6 +81,7 @@ DolbyVisionProfileSpec dovi[] =
 #define MVTHRESHOLD (10*10)
 #define PU_2Nx2N 1
 #define MAX_CHROMA_QP_OFFSET 12
+#define CONF_OFFSET_BYTES (2 * sizeof(int))
 static const char* defaultAnalysisFileName = "x265_analysis.dat";
 
 using namespace X265_NS;
@@ -117,6 +118,8 @@ Encoder::Encoder()
     m_cR = 1.0;
     for (int i = 0; i < X265_MAX_FRAME_THREADS; i++)
         m_frameEncoder[i] = NULL;
+    for (uint32_t i = 0; i < DUP_BUFFER; i++)
+        m_dupBuffer[i] = NULL;
     MotionEstimate::initScales();
 
 #if ENABLE_HDR10_PLUS
@@ -128,11 +131,17 @@ Encoder::Encoder()
 #if SVT_HEVC
     m_svtAppData = NULL;
 #endif
-
     m_prevTonemapPayload.payload = NULL;
     m_startPoint = 0;
     m_saveCTUSize = 0;
+    m_edgePic = NULL;
+    m_edgeHistThreshold = 0;
+    m_chromaHistThreshold = 0.0;
+    m_scaledEdgeThreshold = 0.0;
+    m_scaledChromaThreshold = 0.0;
+    m_zoneIndex = 0;
 }
+
 inline char *strcatFilename(const char *input, const char *suffix)
 {
     char *output = X265_MALLOC(char, strlen(input) + strlen(suffix) + 1);
@@ -160,6 +169,70 @@ void Encoder::create()
     int rows = (p->sourceHeight + p->maxCUSize - 1) >> g_log2Size[p->maxCUSize];
     int cols = (p->sourceWidth  + p->maxCUSize - 1) >> g_log2Size[p->maxCUSize];
 
+    if (m_param->bEnableFrameDuplication)
+    {
+        size_t framesize = 0;
+        int pixelbytes = p->sourceBitDepth > 8 ? 2 : 1;
+        for (int i = 0; i < x265_cli_csps[p->internalCsp].planes; i++)
+        {
+            int stride = (p->sourceWidth >> x265_cli_csps[p->internalCsp].width[i]) * pixelbytes;
+            framesize += (stride * (p->sourceHeight >> x265_cli_csps[p->internalCsp].height[i]));
+        }
+
+        //Sets the picture structure and emits it in the picture timing SEI message
+        m_param->pictureStructure = 0; 
+
+        for (uint32_t i = 0; i < DUP_BUFFER; i++)
+        {
+            m_dupBuffer[i] = (AdaptiveFrameDuplication*)x265_malloc(sizeof(AdaptiveFrameDuplication));
+            m_dupBuffer[i]->dupPic = NULL;
+            m_dupBuffer[i]->dupPic = x265_picture_alloc();
+            x265_picture_init(p, m_dupBuffer[i]->dupPic);
+            m_dupBuffer[i]->dupPlane = NULL;
+            m_dupBuffer[i]->dupPlane = X265_MALLOC(char, framesize);
+            m_dupBuffer[i]->dupPic->planes[0] = m_dupBuffer[i]->dupPlane;
+            m_dupBuffer[i]->bOccupied = false;
+            m_dupBuffer[i]->bDup = false;
+        }
+
+        if (!(p->sourceBitDepth == 8 && p->internalBitDepth == 8))
+        {
+            int size = p->sourceWidth * p->sourceHeight;
+            int hshift = CHROMA_H_SHIFT(p->internalCsp);
+            int vshift = CHROMA_V_SHIFT(p->internalCsp);
+            int widthC = p->sourceWidth >> hshift;
+            int heightC = p->sourceHeight >> vshift;
+
+            m_dupPicOne[0] = X265_MALLOC(pixel, size);
+            m_dupPicTwo[0] = X265_MALLOC(pixel, size);
+            if (p->internalCsp != X265_CSP_I400)
+            {
+                for (int k = 1; k < 3; k++)
+                {
+                    m_dupPicOne[k] = X265_MALLOC(pixel, widthC * heightC);
+                    m_dupPicTwo[k] = X265_MALLOC(pixel, widthC * heightC);
+                }
+            }
+        }
+    }
+
+    if (m_param->bHistBasedSceneCut)
+    {
+        for (int i = 0; i < x265_cli_csps[m_param->internalCsp].planes; i++)
+        {
+            m_planeSizes[i] = m_param->sourceWidth * m_param->sourceHeight >> x265_cli_csps[m_param->internalCsp].height[i];
+        }
+        uint32_t pixelbytes = m_param->sourceBitDepth > 8 ? 2 : 1;
+        m_edgePic = X265_MALLOC(pixel, m_planeSizes[0] * pixelbytes);
+        m_edgeHistThreshold = m_param->edgeTransitionThreshold;
+        m_chromaHistThreshold = m_edgeHistThreshold * 10.0;
+        m_chromaHistThreshold = x265_min(m_chromaHistThreshold, MAX_SCENECUT_THRESHOLD);
+        m_scaledEdgeThreshold = m_edgeHistThreshold * SCENECUT_STRENGTH_FACTOR;
+        m_scaledEdgeThreshold = x265_min(m_scaledEdgeThreshold, MAX_SCENECUT_THRESHOLD);
+        m_scaledChromaThreshold = m_chromaHistThreshold * SCENECUT_STRENGTH_FACTOR;
+        m_scaledChromaThreshold = x265_min(m_scaledChromaThreshold, MAX_SCENECUT_THRESHOLD);
+    }
+
     // Do not allow WPP if only one row or fewer than 3 columns, it is pointless and unstable
     if (rows == 1 || cols < 3)
     {
@@ -273,7 +346,13 @@ void Encoder::create()
             lookAheadThreadPool[i].start();
     m_lookahead->m_numPools = pools;
     m_dpb = new DPB(m_param);
-    m_rateControl = new RateControl(*m_param);
+    m_rateControl = new RateControl(*m_param, this);
+    if (!m_param->bResetZoneConfig)
+    {
+        zoneReadCount = new ThreadSafeInteger[m_param->rc.zonefileCount];
+        zoneWriteCount = new ThreadSafeInteger[m_param->rc.zonefileCount];
+    }
+
     initVPS(&m_vps);
     initSPS(&m_sps);
     initPPS(&m_pps);
@@ -396,15 +475,6 @@ void Encoder::create()
             m_aborted = true;
         }
     }
-    if (m_param->analysisLoad && m_param->bUseAnalysisFile)
-    {
-        m_analysisFileIn = x265_fopen(m_param->analysisLoad, "rb");
-        if (!m_analysisFileIn)
-        {
-            x265_log_file(NULL, X265_LOG_ERROR, "Analysis load: failed to open file %s\n", m_param->analysisLoad);
-            m_aborted = true;
-        }
-    }
 
     if (m_param->analysisMultiPassRefine || m_param->analysisMultiPassDistortion)
     {
@@ -572,7 +642,7 @@ int Encoder::setAnalysisDataAfterZScan(x
     if (analysis_data->sliceType == X265_TYPE_IDR || analysis_data->sliceType == X265_TYPE_I)
     {
         curFrame->m_analysisData.sliceType = X265_TYPE_I;
-        if (m_param->analysisReuseLevel < 7)
+        if (m_param->analysisLoadReuseLevel < 7)
             return -1;
         curFrame->m_analysisData.numPartitions = m_param->num4x4Partitions;
         int num16x16inCUWidth = m_param->maxCUSize >> 4;
@@ -602,7 +672,7 @@ int Encoder::setAnalysisDataAfterZScan(x
     else
     {
         uint32_t numDir = analysis_data->sliceType == X265_TYPE_P ? 1 : 2;
-        if (m_param->analysisReuseLevel < 7)
+        if (m_param->analysisLoadReuseLevel < 7)
             return -1;
         curFrame->m_analysisData.numPartitions = m_param->num4x4Partitions;
         int num16x16inCUWidth = m_param->maxCUSize >> 4;
@@ -644,7 +714,7 @@ int Encoder::setAnalysisDataAfterZScan(x
                             (interData)->mvpIdx[k][cuPos + cuOffset] = (srcInterData)->mvpIdx[k][(mbIndex * 16) + cuOffset];
                             (interData)->refIdx[k][cuPos + cuOffset] = (srcInterData)->refIdx[k][(mbIndex * 16) + cuOffset];
                             memcpy(&(interData)->mv[k][cuPos + cuOffset], &(srcInterData)->mv[k][(mbIndex * 16) + cuOffset], sizeof(MV));
-                            if (m_param->analysisReuseLevel == 7 && numPU == PU_2Nx2N &&
+                            if (m_param->analysisLoadReuseLevel == 7 && numPU == PU_2Nx2N &&
                                 ((interData)->depth[cuPos + cuOffset] == (m_param->maxCUSize >> 5)))
                             {
                                 int mv_x = (interData)->mv[k][cuPos + cuOffset].x;
@@ -678,7 +748,7 @@ int Encoder::setAnalysisData(x265_analys
             if (analysis_data->sliceType == X265_TYPE_IDR || analysis_data->sliceType == X265_TYPE_I)
             {
                 curFrame->m_analysisData.sliceType = X265_TYPE_I;
-                if (m_param->analysisReuseLevel < 2)
+                if (m_param->analysisLoadReuseLevel < 2)
                     return -1;
 
                 curFrame->m_analysisData.numPartitions = m_param->num4x4Partitions;
@@ -699,7 +769,7 @@ int Encoder::setAnalysisData(x265_analys
             else
             {
                 uint32_t numDir = analysis_data->sliceType == X265_TYPE_P ? 1 : 2;
-                if (m_param->analysisReuseLevel < 2)
+                if (m_param->analysisLoadReuseLevel < 2)
                     return -1;
 
                 curFrame->m_analysisData.numPartitions = m_param->num4x4Partitions;
@@ -712,7 +782,7 @@ int Encoder::setAnalysisData(x265_analys
                     memset(&(currInterData)->depth[count], (interData)->depth[d], bytes);
                     memset(&(currInterData)->modes[count], (interData)->modes[d], bytes);
                     memcpy(&(currInterData)->sadCost[count], &(analysis_data->interData)->sadCost[d], bytes);
-                    if (m_param->analysisReuseLevel > 4)
+                    if (m_param->analysisLoadReuseLevel > 4)
                     {
                         memset(&(currInterData)->partSize[count], (interData)->partSize[d], bytes);
                         int numPU = nbPartsTable[(interData)->partSize[d]];
@@ -720,7 +790,7 @@ int Encoder::setAnalysisData(x265_analys
                         {
                             if (pu) d++;
                             (currInterData)->mergeFlag[count + pu] = (interData)->mergeFlag[d];
-                            if (m_param->analysisReuseLevel >= 7)
+                            if (m_param->analysisLoadReuseLevel >= 7)
                             {
                                 (currInterData)->interDir[count + pu] = (interData)->interDir[d];
                                 for (uint32_t i = 0; i < numDir; i++)
@@ -728,7 +798,7 @@ int Encoder::setAnalysisData(x265_analys
                                     (currInterData)->mvpIdx[i][count + pu] = (interData)->mvpIdx[i][d];
                                     (currInterData)->refIdx[i][count + pu] = (interData)->refIdx[i][d];
                                     memcpy(&(currInterData)->mv[i][count + pu], &(interData)->mv[i][d], sizeof(MV));
-                                    if (m_param->analysisReuseLevel == 7 && numPU == PU_2Nx2N && m_param->num4x4Partitions <= 16)
+                                    if (m_param->analysisLoadReuseLevel == 7 && numPU == PU_2Nx2N && m_param->num4x4Partitions <= 16)
                                     {
                                         int mv_x = (currInterData)->mv[i][count + pu].x;
                                         int mv_y = (currInterData)->mv[i][count + pu].y;
@@ -771,6 +841,41 @@ void Encoder::destroy()
         m_exportedPic = NULL;
     }
 
+    if (m_param->bEnableFrameDuplication)
+    {
+        for (uint32_t i = 0; i < DUP_BUFFER; i++)
+        {
+            X265_FREE(m_dupBuffer[i]->dupPlane);
+            x265_picture_free(m_dupBuffer[i]->dupPic);
+            X265_FREE(m_dupBuffer[i]);
+        }
+
+        if (!(m_param->sourceBitDepth == 8 && m_param->internalBitDepth == 8))
+        {
+            for (int k = 0; k < 3; k++)
+            {
+                if (k == 0)
+                {
+                    X265_FREE(m_dupPicOne[k]);
+                    X265_FREE(m_dupPicTwo[k]);
+                }
+                else if(k >= 1 && m_param->internalCsp != X265_CSP_I400)
+                {
+                    X265_FREE(m_dupPicOne[k]);
+                    X265_FREE(m_dupPicTwo[k]);
+                }
+            }
+        }
+    }
+
+    if (m_param->bHistBasedSceneCut)
+    {
+        if (m_edgePic != NULL)
+        {
+            X265_FREE_ZERO(m_edgePic);
+        }
+    }
+
     for (int i = 0; i < m_param->frameNumThreads; i++)
     {
         if (m_frameEncoder[i])
@@ -791,6 +896,11 @@ void Encoder::destroy()
     }
 
     delete m_dpb;
+    if (!m_param->bResetZoneConfig && m_param->rc.zonefileCount)
+    {
+        delete[] zoneReadCount;
+        delete[] zoneWriteCount;
+    }
     if (m_rateControl)
     {
         m_rateControl->destroy();
@@ -981,6 +1091,386 @@ void Encoder::copyUserSEIMessages(Frame 
     }
 }
 
+//Find Sum of Squared Difference (SSD) between two pictures
+uint64_t Encoder::computeSSD(pixel *fenc, pixel *rec, intptr_t stride, uint32_t width, uint32_t height, x265_param *param)
+{
+    uint64_t ssd = 0;
+
+    if (!param->bEnableFrameDuplication || (width & 3))
+    {
+        if ((width | height) & 3)
+        {
+            /* Slow Path */
+            for (uint32_t y = 0; y < height; y++)
+            {
+                for (uint32_t x = 0; x < width; x++)
+                {
+                    int diff = (int)(fenc[x] - rec[x]);
+                    ssd += diff * diff;
+                }
+
+                fenc += stride;
+                rec += stride;
+            }
+
+            return ssd;
+        }
+    }
+
+    uint32_t y = 0;
+
+    /* Consume rows in ever narrower chunks of height */
+    for (int size = BLOCK_64x64; size >= BLOCK_4x4 && y < height; size--)
+    {
+        uint32_t rowHeight = 1 << (size + 2);
+
+        for (; y + rowHeight <= height; y += rowHeight)
+        {
+            uint32_t y1, x = 0;
+
+            /* Consume each row using the largest square blocks possible */
+            if (size == BLOCK_64x64 && !(stride & 31))
+                for (; x + 64 <= width; x += 64)
+                    ssd += primitives.cu[BLOCK_64x64].sse_pp(fenc + x, stride, rec + x, stride);
+
+            if (size >= BLOCK_32x32 && !(stride & 15))
+                for (; x + 32 <= width; x += 32)
+                    for (y1 = 0; y1 + 32 <= rowHeight; y1 += 32)
+                        ssd += primitives.cu[BLOCK_32x32].sse_pp(fenc + y1 * stride + x, stride, rec + y1 * stride + x, stride);
+
+            if (size >= BLOCK_16x16)
+                for (; x + 16 <= width; x += 16)
+                    for (y1 = 0; y1 + 16 <= rowHeight; y1 += 16)
+                        ssd += primitives.cu[BLOCK_16x16].sse_pp(fenc + y1 * stride + x, stride, rec + y1 * stride + x, stride);
+
+            if (size >= BLOCK_8x8)
+                for (; x + 8 <= width; x += 8)
+                    for (y1 = 0; y1 + 8 <= rowHeight; y1 += 8)
+                        ssd += primitives.cu[BLOCK_8x8].sse_pp(fenc + y1 * stride + x, stride, rec + y1 * stride + x, stride);
+
+            for (; x + 4 <= width; x += 4)
+                for (y1 = 0; y1 + 4 <= rowHeight; y1 += 4)
+                    ssd += primitives.cu[BLOCK_4x4].sse_pp(fenc + y1 * stride + x, stride, rec + y1 * stride + x, stride);
+
+            fenc += stride * rowHeight;
+            rec += stride * rowHeight;
+        }
+    }
+
+    /* Handle last few rows of frames for videos 
+    with height not divisble by 4 */
+    uint32_t h = height % y;
+    if (param->bEnableFrameDuplication && h)
+    {
+        for (uint32_t i = 0; i < h; i++)
+        {
+            for (uint32_t j = 0; j < width; j++)
+            {
+                int diff = (int)(fenc[j] - rec[j]);
+                ssd += diff * diff;
+            }
+
+            fenc += stride;
+            rec += stride;
+        }
+    }
+
+    return ssd;
+}
+
+//Compute the PSNR weightage between two pictures
+double Encoder::ComputePSNR(x265_picture *firstPic, x265_picture *secPic, x265_param *param)
+{
+    uint64_t ssdY = 0, ssdU = 0, ssdV = 0;
+    intptr_t strideL, strideC;
+    uint32_t widthL, heightL, widthC, heightC;
+    double psnrY = 0, psnrU = 0, psnrV = 0, psnrWeight = 0;
+    int width = firstPic->width;
+    int height = firstPic->height;
+    int hshift = CHROMA_H_SHIFT(firstPic->colorSpace);
+    int vshift = CHROMA_V_SHIFT(firstPic->colorSpace);
+    pixel *yFirstPic = NULL, *ySecPic = NULL;
+    pixel *uFirstPic = NULL, *uSecPic = NULL;
+    pixel *vFirstPic = NULL, *vSecPic = NULL;
+
+    strideL = widthL = width;
+    heightL = height;
+
+    strideC = widthC = widthL >> hshift;
+    heightC = heightL >> vshift;
+
+    int size = width * height;
+    int maxvalY = 255 << (X265_DEPTH - 8);
+    int maxvalC = 255 << (X265_DEPTH - 8);
+    double refValueY = (double)maxvalY * maxvalY * size;
+    double refValueC = (double)maxvalC * maxvalC * size / 4.0;
+
+    if (firstPic->bitDepth == 8 && X265_DEPTH == 8)
+    {
+        yFirstPic = (pixel*)firstPic->planes[0];
+        ySecPic = (pixel*)secPic->planes[0];
+        if (param->internalCsp != X265_CSP_I400)
+        {
+            uFirstPic = (pixel*)firstPic->planes[1];
+            uSecPic = (pixel*)secPic->planes[1];
+            vFirstPic = (pixel*)firstPic->planes[2];
+            vSecPic = (pixel*)secPic->planes[2];
+        }
+    }
+    else if (firstPic->bitDepth == 8 && X265_DEPTH > 8)
+    {
+        int shift = (X265_DEPTH - 8);
+        uint8_t *yChar1, *yChar2, *uChar1, *uChar2, *vChar1, *vChar2;
+
+        yChar1 = (uint8_t*)firstPic->planes[0];
+        yChar2 = (uint8_t*)secPic->planes[0];
+
+        primitives.planecopy_cp(yChar1, firstPic->stride[0] / sizeof(*yChar1), m_dupPicOne[0], firstPic->stride[0] / sizeof(*yChar1), width, height, shift);
+        primitives.planecopy_cp(yChar2, secPic->stride[0] / sizeof(*yChar2), m_dupPicTwo[0], secPic->stride[0] / sizeof(*yChar2), width, height, shift);
+
+        if (param->internalCsp != X265_CSP_I400)
+        {
+            uChar1 = (uint8_t*)firstPic->planes[1];
+            uChar2 = (uint8_t*)secPic->planes[1];
+            vChar1 = (uint8_t*)firstPic->planes[2];
+            vChar2 = (uint8_t*)secPic->planes[2];
+
+            primitives.planecopy_cp(uChar1, firstPic->stride[1] / sizeof(*uChar1), m_dupPicOne[1], firstPic->stride[1] / sizeof(*uChar1), widthC, heightC, shift);
+            primitives.planecopy_cp(uChar2, secPic->stride[1] / sizeof(*uChar2), m_dupPicTwo[1], secPic->stride[1] / sizeof(*uChar2), widthC, heightC, shift);
+
+            primitives.planecopy_cp(vChar1, firstPic->stride[2] / sizeof(*vChar1), m_dupPicOne[2], firstPic->stride[2] / sizeof(*vChar1), widthC, heightC, shift);
+            primitives.planecopy_cp(vChar2, secPic->stride[2] / sizeof(*vChar2), m_dupPicTwo[2], secPic->stride[2] / sizeof(*vChar2), widthC, heightC, shift);
+        }
+    }
+    else
+    {
+        uint16_t *yShort1, *yShort2, *uShort1, *uShort2, *vShort1, *vShort2;
+        /* defensive programming, mask off bits that are supposed to be zero */
+        uint16_t mask = (1 << X265_DEPTH) - 1;
+        int shift = abs(firstPic->bitDepth - X265_DEPTH);
+
+        yShort1 = (uint16_t*)firstPic->planes[0];
+        yShort2 = (uint16_t*)secPic->planes[0];
+
+        if (firstPic->bitDepth > X265_DEPTH)
+        {
+            /* shift right and mask pixels to final size */
+            primitives.planecopy_sp(yShort1, firstPic->stride[0] / sizeof(*yShort1), m_dupPicOne[0], firstPic->stride[0] / sizeof(*yShort1), width, height, shift, mask);
+            primitives.planecopy_sp(yShort2, secPic->stride[0] / sizeof(*yShort2), m_dupPicTwo[0], secPic->stride[0] / sizeof(*yShort2), width, height, shift, mask);
+        }
+        else /* Case for (pic.bitDepth <= X265_DEPTH) */
+        {
+            /* shift left and mask pixels to final size */
+            primitives.planecopy_sp_shl(yShort1, firstPic->stride[0] / sizeof(*yShort1), m_dupPicOne[0], firstPic->stride[0] / sizeof(*yShort1), width, height, shift, mask);
+            primitives.planecopy_sp_shl(yShort2, secPic->stride[0] / sizeof(*yShort2), m_dupPicTwo[0], secPic->stride[0] / sizeof(*yShort2), width, height, shift, mask);
+        }
+
+        if (param->internalCsp != X265_CSP_I400)
+        {
+            uShort1 = (uint16_t*)firstPic->planes[1];
+            uShort2 = (uint16_t*)secPic->planes[1];
+            vShort1 = (uint16_t*)firstPic->planes[2];
+            vShort2 = (uint16_t*)secPic->planes[2];
+
+            if (firstPic->bitDepth > X265_DEPTH)
+            {
+                primitives.planecopy_sp(uShort1, firstPic->stride[1] / sizeof(*uShort1), m_dupPicOne[1], firstPic->stride[1] / sizeof(*uShort1), widthC, heightC, shift, mask);
+                primitives.planecopy_sp(uShort2, secPic->stride[1] / sizeof(*uShort2), m_dupPicTwo[1], secPic->stride[1] / sizeof(*uShort2), widthC, heightC, shift, mask);
+
+                primitives.planecopy_sp(vShort1, firstPic->stride[2] / sizeof(*vShort1), m_dupPicOne[2], firstPic->stride[2] / sizeof(*vShort1), widthC, heightC, shift, mask);
+                primitives.planecopy_sp(vShort2, secPic->stride[2] / sizeof(*vShort2), m_dupPicTwo[2], secPic->stride[2] / sizeof(*vShort2), widthC, heightC, shift, mask);
+            }
+            else /* Case for (pic.bitDepth <= X265_DEPTH) */
+            {
+                primitives.planecopy_sp_shl(uShort1, firstPic->stride[1] / sizeof(*uShort1), m_dupPicOne[1], firstPic->stride[1] / sizeof(*uShort1), widthC, heightC, shift, mask);
+                primitives.planecopy_sp_shl(uShort2, secPic->stride[1] / sizeof(*uShort2), m_dupPicTwo[1], secPic->stride[1] / sizeof(*uShort2), widthC, heightC, shift, mask);
+
+                primitives.planecopy_sp_shl(vShort1, firstPic->stride[2] / sizeof(*vShort1), m_dupPicOne[2], firstPic->stride[2] / sizeof(*vShort1), widthC, heightC, shift, mask);
+                primitives.planecopy_sp_shl(vShort2, secPic->stride[2] / sizeof(*vShort2), m_dupPicTwo[2], secPic->stride[2] / sizeof(*vShort2), widthC, heightC, shift, mask);
+            }
+        }
+    }
+
+    if (!(firstPic->bitDepth == 8 && X265_DEPTH == 8))
+    {
+        yFirstPic = m_dupPicOne[0]; ySecPic = m_dupPicTwo[0];
+        uFirstPic = m_dupPicOne[1]; uSecPic = m_dupPicTwo[1];
+        vFirstPic = m_dupPicOne[2]; vSecPic = m_dupPicTwo[2];
+    }
+
+    //Compute SSD
+    ssdY = computeSSD(yFirstPic, ySecPic, strideL, widthL, heightL, param);
+    psnrY = (ssdY ? 10.0 * log10(refValueY / (double)ssdY) : 99.99);
+
+    if (param->internalCsp != X265_CSP_I400)
+    {
+        ssdU = computeSSD(uFirstPic, uSecPic, strideC, widthC, heightC, param);
+        ssdV = computeSSD(vFirstPic, vSecPic, strideC, widthC, heightC, param);
+        psnrU = (ssdU ? 10.0 * log10(refValueC / (double)ssdU) : 99.99);
+        psnrV = (ssdV ? 10.0 * log10(refValueC / (double)ssdV) : 99.99);
+    }
+
+    //Compute PSNR(picN,pic(N+1))
+    return psnrWeight = (psnrY * 6 + psnrU + psnrV) / 8;
+}
+
+void Encoder::copyPicture(x265_picture *dest, const x265_picture *src)
+{
+    dest->poc = src->poc;
+    dest->pts = src->pts;
+    dest->userSEI = src->userSEI;
+    dest->bitDepth = src->bitDepth;
+    dest->framesize = src->framesize;
+    dest->height = src->height;
+    dest->width = src->width;
+    dest->colorSpace = src->colorSpace;
+    dest->userSEI = src->userSEI;
+    dest->rpu.payload = src->rpu.payload;
+    dest->picStruct = src->picStruct;
+    dest->stride[0] = src->stride[0];
+    dest->stride[1] = src->stride[1];
+    dest->stride[2] = src->stride[2];
+    memcpy(dest->planes[0], src->planes[0], src->framesize * sizeof(char));
+    dest->planes[1] = (char*)dest->planes[0] + src->stride[0] * src->height;
+    dest->planes[2] = (char*)dest->planes[1] + src->stride[1] * (src->height >> x265_cli_csps[src->colorSpace].height[1]);
+}
+
+bool Encoder::computeHistograms(x265_picture *pic)
+{
+    pixel *src = (pixel *) pic->planes[0];
+    size_t bufSize = sizeof(pixel) * m_planeSizes[0];
+    int32_t planeCount = x265_cli_csps[m_param->internalCsp].planes;
+    int32_t numBytes = m_param->sourceBitDepth > 8 ? 2 : 1;
+    memset(m_edgePic, 0, bufSize * numBytes);
+
+    if (!computeEdge(m_edgePic, src, NULL, pic->width, pic->height, pic->width, false))
+    {
+        x265_log(m_param, X265_LOG_ERROR, "Failed edge computation!");
+        return false;
+    }
+
+    pixel pixelVal;
+    int64_t size = pic->height * (pic->stride[0] >> SHIFT);
+    int32_t *edgeHist = m_curEdgeHist;
+    memset(edgeHist, 0, 2 * sizeof(int32_t));
+    for (int64_t i = 0; i < size; i++)
+    {
+        if (!m_edgePic[i])
+           edgeHist[0]++;
+        else
+           edgeHist[1]++;
+    }
+
+    if (pic->colorSpace != X265_CSP_I400)
+    {
+        /* U Histogram Calculation */
+        int32_t HeightL = (pic->height >> x265_cli_csps[pic->colorSpace].height[1]);
+        size = HeightL * (pic->stride[1] >> SHIFT);
+        int32_t *uHist = m_curUVHist[0];
+        pixel *chromaPlane = (pixel *) pic->planes[1];
+
+        memset(uHist, 0, HISTOGRAM_BINS * sizeof(int32_t));
+
+        for (int64_t i = 0; i < size; i++)
+        {
+            pixelVal = chromaPlane[i];
+            uHist[pixelVal]++;
+        }
+
+        /* V Histogram Calculation */
+        if (planeCount == 3)
+        {
+            pixelVal = 0;
+            int32_t heightV = (pic->height >> x265_cli_csps[pic->colorSpace].height[2]);
+            size = heightV * (pic->stride[2] >> SHIFT);
+            int32_t *vHist = m_curUVHist[1];
+            chromaPlane = (pixel *) pic->planes[2];
+
+            memset(vHist, 0, HISTOGRAM_BINS * sizeof(int32_t));
+            for (int64_t i = 0; i < size; i++)
+            {
+                pixelVal = chromaPlane[i];
+                vHist[pixelVal]++;
+            }
+            for (int i = 0; i < HISTOGRAM_BINS; i++)
+            {
+                m_curMaxUVHist[i] = x265_max(uHist[i], vHist[i]);
+            }
+        }
+        else
+        {   /* in case of bi planar color space */
+            memcpy(m_curMaxUVHist, m_curUVHist[0], HISTOGRAM_BINS * sizeof(int32_t));
+        }
+    }
+    return true;
+}
+
+void Encoder::computeHistogramSAD(double *maxUVNormalizedSad, double *edgeNormalizedSad, int curPoc)
+{
+
+    if (curPoc == 0)
+    {   /* first frame is scenecut by default no sad computation for the same. */
+        *maxUVNormalizedSad = 0.0;
+        *edgeNormalizedSad  = 0.0;
+    }
+    else
+    {
+        /* compute sum of absolute difference of normalized histogram bins for maxUV and edge histograms. */
+        int32_t edgefreqDiff = 0;
+        int32_t maxUVfreqDiff = 0;
+        double  edgeProbabilityDiff = 0;
+
+        for (int j = 0; j < HISTOGRAM_BINS; j++)
+        {
+            if (j < 2)
+            {
+                edgefreqDiff = abs(m_curEdgeHist[j] - m_prevEdgeHist[j]);
+                edgeProbabilityDiff = (double) edgefreqDiff / m_planeSizes[0];
+                *edgeNormalizedSad += edgeProbabilityDiff;
+            }
+            maxUVfreqDiff = abs(m_curMaxUVHist[j] - m_prevMaxUVHist[j]);
+            *maxUVNormalizedSad += (double)maxUVfreqDiff / m_planeSizes[2];
+        }
+    }
+
+    /* store histograms of previous frame for reference */
+    size_t bufsize = HISTOGRAM_BINS * sizeof(int32_t);
+    memcpy(m_prevMaxUVHist, m_curMaxUVHist, bufsize);
+    memcpy(m_prevEdgeHist, m_curEdgeHist, 2 * sizeof(int32_t));
+}
+
+void Encoder::findSceneCuts(x265_picture *pic, bool& bDup, double maxUVSad, double edgeSad)
+{
+    pic->frameData.bScenecut = false;
+
+    if (pic->poc == 0)
+    {
+        /* for first frame */
+        pic->frameData.bScenecut = false;
+        bDup = false;
+    }
+    else
+    {
+        if (edgeSad == 0.0 && maxUVSad == 0.0)
+        {
+            bDup = true;
+        }
+        else if (edgeSad > m_edgeHistThreshold && maxUVSad >= m_chromaHistThreshold)
+        {
+            pic->frameData.bScenecut = true;
+            bDup = false;
+        }
+        else if (edgeSad > m_scaledEdgeThreshold || maxUVSad >= m_scaledChromaThreshold)
+        {
+            pic->frameData.bScenecut = true;
+            bDup = false;
+        }
+    }
+
+    if (pic->frameData.bScenecut)
+       x265_log(m_param, X265_LOG_DEBUG, "scene cut at %d \n", pic->poc);
+}
+
 /**
  * Feed one new input frame into the encoder, get one frame out. If pic_in is
  * NULL, a flush condition is implied and pic_in must be NULL for all subsequent
@@ -1004,6 +1494,12 @@ int Encoder::encode(const x265_picture* 
     if (m_aborted)
         return -1;
 
+    const x265_picture* inputPic = NULL;
+    static int written = 0, read = 0;
+    bool dontRead = false;
+    bool bdropFrame = false;
+    bool dropflag = false;
+
     if (m_exportedPic)
     {
         if (!m_param->bUseAnalysisFile && m_param->analysisSave)
@@ -1012,33 +1508,121 @@ int Encoder::encode(const x265_picture* 
         m_exportedPic = NULL;
         m_dpb->recycleUnreferenced();
     }
-    if (pic_in && (!m_param->chunkEnd || (m_encodedFrameNum < m_param->chunkEnd)))
-    {
-        if (m_latestParam->forceFlush == 1)
-        {
-            m_lookahead->setLookaheadQueue();
-            m_latestParam->forceFlush = 0;
-        }
-        if (m_latestParam->forceFlush == 2)
+    if ((pic_in && (!m_param->chunkEnd || (m_encodedFrameNum < m_param->chunkEnd))) || (m_param->bEnableFrameDuplication && !pic_in && (read < written)))
+    {
+        if (m_param->bHistBasedSceneCut && pic_in)
         {
-            m_lookahead->m_filled = false;
-            m_latestParam->forceFlush = 0;
+            x265_picture *pic = (x265_picture *) pic_in;
+            if (computeHistograms(pic))
+            {
+                double maxUVSad = 0.0, edgeSad = 0.0;
+                computeHistogramSAD(&maxUVSad, &edgeSad, pic_in->poc);
+                findSceneCuts(pic, bdropFrame, maxUVSad, edgeSad);
+            }
         }
 
-        if (pic_in->bitDepth < 8 || pic_in->bitDepth > 16)
+        if ((m_param->bEnableFrameDuplication && !pic_in && (read < written)))
+            dontRead = true;
+        else
         {
-            x265_log(m_param, X265_LOG_ERROR, "Input bit depth (%d) must be between 8 and 16\n",
-                     pic_in->bitDepth);
-            return -1;
+            if (m_latestParam->forceFlush == 1)
+            {
+                m_lookahead->setLookaheadQueue();
+                m_latestParam->forceFlush = 0;
+            }
+            if (m_latestParam->forceFlush == 2)
+            {
+                m_lookahead->m_filled = false;
+                m_latestParam->forceFlush = 0;
+            }
+
+            if (pic_in->bitDepth < 8 || pic_in->bitDepth > 16)
+            {
+                x265_log(m_param, X265_LOG_ERROR, "Input bit depth (%d) must be between 8 and 16\n",
+                         pic_in->bitDepth);
+                return -1;
+            }
         }
 
+        if (m_param->bEnableFrameDuplication)
+        {
+            double psnrWeight = 0;
+
+            if (!dontRead)
+            {
+                if (!m_dupBuffer[0]->bOccupied)
+                {
+                    copyPicture(m_dupBuffer[0]->dupPic, pic_in);
+                    m_dupBuffer[0]->bOccupied = true;
+                    written++;
+                    return 0;
+                }
+                else if (!m_dupBuffer[1]->bOccupied)
+                {
+                    copyPicture(m_dupBuffer[1]->dupPic, pic_in);
+                    m_dupBuffer[1]->bOccupied = true;
+                    written++;
+                }
+
+                if (m_param->bEnableFrameDuplication && m_param->bHistBasedSceneCut)
+                {
+                    if (!bdropFrame && m_dupBuffer[1]->dupPic->frameData.bScenecut == false)
+                    {
+                        psnrWeight = ComputePSNR(m_dupBuffer[0]->dupPic, m_dupBuffer[1]->dupPic, m_param);
+                        if (psnrWeight >= m_param->dupThreshold)
+                            dropflag = true;
+                    }
+                    else
+                    {
+                        dropflag = true;
+                    }
+                }
+                else if (m_param->bEnableFrameDuplication)
+                {
+                    psnrWeight = ComputePSNR(m_dupBuffer[0]->dupPic, m_dupBuffer[1]->dupPic, m_param);
+                    if (psnrWeight >= m_param->dupThreshold)
+                        dropflag = true;
+                }
+
+                if (dropflag)
+                {
+                    if (m_dupBuffer[0]->bDup)
+                    {
+                        m_dupBuffer[0]->dupPic->picStruct = tripling;
+                        m_dupBuffer[0]->bDup = false;
+                        read++;
+                    }
+                    else
+                    {
+                        m_dupBuffer[0]->dupPic->picStruct = doubling;
+                        m_dupBuffer[0]->bDup = true;
+                        m_dupBuffer[1]->bOccupied = false;
+                        read++;
+                        return 0;
+                    }
+                }
+                else if (m_dupBuffer[0]->bDup)
+                    m_dupBuffer[0]->bDup = false;
+                else
+                    m_dupBuffer[0]->dupPic->picStruct = 0;
+            }
+
+            if (read < written)
+            {
+                inputPic = m_dupBuffer[0]->dupPic;
+                read++;
+            }
+        }
+        else
+            inputPic = pic_in;
+
         Frame *inFrame;
-        x265_param* p = (m_reconfigure || m_reconfigureRc) ? m_latestParam : m_param;
+        x265_param *p = (m_reconfigure || m_reconfigureRc) ? m_latestParam : m_param;
         if (m_dpb->m_freeList.empty())
         {
             inFrame = new Frame;
             inFrame->m_encodeStartTime = x265_mdate();
-            if (inFrame->create(p, pic_in->quantOffsets))
+            if (inFrame->create(p, inputPic->quantOffsets))
             {
                 /* the first PicYuv created is asked to generate the CU and block unit offset
                  * arrays which are then shared with all subsequent PicYuv (orig and recon) 
@@ -1098,34 +1682,39 @@ int Encoder::encode(const x265_picture* 
         }
 
         /* Copy input picture into a Frame and PicYuv, send to lookahead */
-        inFrame->m_fencPic->copyFromPicture(*pic_in, *m_param, m_sps.conformanceWindow.rightOffset, m_sps.conformanceWindow.bottomOffset);
+        inFrame->m_fencPic->copyFromPicture(*inputPic, *m_param, m_sps.conformanceWindow.rightOffset, m_sps.conformanceWindow.bottomOffset);
 
         inFrame->m_poc       = ++m_pocLast;
-        inFrame->m_userData  = pic_in->userData;
-        inFrame->m_pts       = pic_in->pts;
-        inFrame->m_forceqp   = pic_in->forceqp;
+        inFrame->m_userData  = inputPic->userData;
+        inFrame->m_pts       = inputPic->pts;
+        if (m_param->bHistBasedSceneCut)
+        {
+            inFrame->m_lowres.bScenecut = (inputPic->frameData.bScenecut == 1) ? true : false;
+        }
+        inFrame->m_forceqp   = inputPic->forceqp;
         inFrame->m_param     = (m_reconfigure || m_reconfigureRc) ? m_latestParam : m_param;
+        inFrame->m_picStruct = inputPic->picStruct;
         if (m_param->bField && m_param->interlaceMode)
-            inFrame->m_fieldNum = pic_in->fieldNum;
-
-        copyUserSEIMessages(inFrame, pic_in);
-
-        /*Copy Dolby Vision RPU from pic_in to frame*/
-        if (pic_in->rpu.payloadSize)
+            inFrame->m_fieldNum = inputPic->fieldNum;
+
+        copyUserSEIMessages(inFrame, inputPic);
+
+        /*Copy Dolby Vision RPU from inputPic to frame*/
+        if (inputPic->rpu.payloadSize)
         {
-            inFrame->m_rpu.payloadSize = pic_in->rpu.payloadSize;
-            inFrame->m_rpu.payload = new uint8_t[pic_in->rpu.payloadSize];
-            memcpy(inFrame->m_rpu.payload, pic_in->rpu.payload, pic_in->rpu.payloadSize);
+            inFrame->m_rpu.payloadSize = inputPic->rpu.payloadSize;
+            inFrame->m_rpu.payload = new uint8_t[inputPic->rpu.payloadSize];
+            memcpy(inFrame->m_rpu.payload, inputPic->rpu.payload, inputPic->rpu.payloadSize);
         }
 
-        if (pic_in->quantOffsets != NULL)
+        if (inputPic->quantOffsets != NULL)
         {
             int cuCount;
             if (m_param->rc.qgSize == 8)
                 cuCount = inFrame->m_lowres.maxBlocksInRowFullRes * inFrame->m_lowres.maxBlocksInColFullRes;
             else
                 cuCount = inFrame->m_lowres.maxBlocksInRow * inFrame->m_lowres.maxBlocksInCol;
-            memcpy(inFrame->m_quantOffsets, pic_in->quantOffsets, cuCount * sizeof(float));
+            memcpy(inFrame->m_quantOffsets, inputPic->quantOffsets, cuCount * sizeof(float));
         }
 
         if (m_pocLast == 0)
@@ -1147,18 +1736,18 @@ int Encoder::encode(const x265_picture* 
         }
 
         /* Use the frame types from the first pass, if available */
-        int sliceType = (m_param->rc.bStatRead) ? m_rateControl->rateControlSliceType(inFrame->m_poc) : pic_in->sliceType;
-
-        /* In analysisSave mode, x265_analysis_data is allocated in pic_in and inFrame points to this */
+        int sliceType = (m_param->rc.bStatRead) ? m_rateControl->rateControlSliceType(inFrame->m_poc) : inputPic->sliceType;
+
+        /* In analysisSave mode, x265_analysis_data is allocated in inputPic and inFrame points to this */
         /* Load analysis data before lookahead->addPicture, since sliceType has been decided */
         if (m_param->analysisLoad)
         {
             /* reads analysis data for the frame and allocates memory based on slicetype */
-            static int paramBytes = 0;
+            static int paramBytes = CONF_OFFSET_BYTES;
             if (!inFrame->m_poc && m_param->bAnalysisType != HEVC_INFO)
             {
-                x265_analysis_data analysisData = pic_in->analysisData;
-                paramBytes = validateAnalysisData(&analysisData, 0);
+                x265_analysis_validate saveParam = inputPic->analysisData.saveParam;
+                paramBytes += validateAnalysisData(&saveParam, 0);
                 if (paramBytes == -1)
                 {
                     m_aborted = true;
@@ -1178,10 +1767,10 @@ int Encoder::encode(const x265_picture* 
                 uint32_t outOfBoundaryLowresH = extendedHeight - m_param->sourceHeight / 2;
                 if (outOfBoundaryLowresH * 2 >= m_param->maxCUSize)
                     cuLocInFrame.skipHeight = true;
-                readAnalysisFile(&inFrame->m_analysisData, inFrame->m_poc, pic_in, paramBytes, cuLocInFrame);
+                readAnalysisFile(&inFrame->m_analysisData, inFrame->m_poc, inputPic, paramBytes, cuLocInFrame);
             }
             else
-                readAnalysisFile(&inFrame->m_analysisData, inFrame->m_poc, pic_in, paramBytes);
+                readAnalysisFile(&inFrame->m_analysisData, inFrame->m_poc, inputPic, paramBytes);
             inFrame->m_poc = inFrame->m_analysisData.poc;
             sliceType = inFrame->m_analysisData.sliceType;
             inFrame->m_lowres.bScenecut = !!inFrame->m_analysisData.bScenecut;
@@ -1202,9 +1791,9 @@ int Encoder::encode(const x265_picture* 
                 }
             }
         }
-        if (m_param->bUseRcStats && pic_in->rcData)
+        if (m_param->bUseRcStats && inputPic->rcData)
         {
-            RcStats* rc = (RcStats*)pic_in->rcData;
+            RcStats* rc = (RcStats*)inputPic->rcData;
             m_rateControl->m_accumPQp = rc->cumulativePQp;
             m_rateControl->m_accumPNorm = rc->cumulativePNorm;
             m_rateControl->m_isNextGop = true;
@@ -1228,6 +1817,18 @@ int Encoder::encode(const x265_picture* 
             }
             m_param->bUseRcStats = 0;
         }
+
+        if (m_param->bEnableFrameDuplication && ((read < written) || (m_dupBuffer[0]->dupPic->picStruct == tripling && (read <= written))))
+        {
+            if (m_dupBuffer[0]->dupPic->picStruct == tripling)
+                m_dupBuffer[0]->bOccupied = m_dupBuffer[1]->bOccupied = false;
+            else
+            {
+                copyPicture(m_dupBuffer[0]->dupPic, m_dupBuffer[1]->dupPic);
+                m_dupBuffer[1]->bOccupied = false;
+            }
+        }
+
         if (m_reconfigureRc)
             inFrame->m_reconfigureRc = true;
 
@@ -1262,7 +1863,7 @@ int Encoder::encode(const x265_picture* 
             Slice *slice = outFrame->m_encData->m_slice;
             x265_frame_stats* frameData = NULL;
 
-            /* Free up pic_in->analysisData since it has already been used */
+            /* Free up inputPic->analysisData since it has already been used */
             if ((m_param->analysisLoad && !m_param->analysisSave) || ((m_param->bAnalysisType == AVC_INFO) && slice->m_sliceType != I_SLICE))
                 x265_free_analysis_data(m_param, &outFrame->m_analysisData);
 
@@ -1410,6 +2011,32 @@ int Encoder::encode(const x265_picture* 
 
             if ((m_outputCount + 1)  >= m_param->chunkStart)
                 finishFrameStats(outFrame, curEncoder, frameData, m_pocLast);
+            if (m_param->analysisSave)
+            {
+                pic_out->analysisData.frameBits = frameData->bits;
+                if (!slice->isIntra())
+                {
+                    for (int ref = 0; ref < MAX_NUM_REF; ref++)
+                        pic_out->analysisData.list0POC[ref] = frameData->list0POC[ref];
+
+                    double totalIntraPercent = 0;
+
+                    for (uint32_t depth = 0; depth < m_param->maxCUDepth; depth++)
+                        for (uint32_t intramode = 0; intramode < 3; intramode++)
+                            totalIntraPercent += frameData->cuStats.percentIntraDistribution[depth][intramode];
+                    totalIntraPercent += frameData->cuStats.percentIntraNxN;
+
+                    for (uint32_t depth = 0; depth < m_param->maxCUDepth; depth++)
+                        totalIntraPercent += frameData->puStats.percentIntraPu[depth];
+                    pic_out->analysisData.totalIntraPercent = totalIntraPercent;
+
+                    if (!slice->isInterP())
+                    {
+                        for (int ref = 0; ref < MAX_NUM_REF; ref++)
+                            pic_out->analysisData.list1POC[ref] = frameData->list1POC[ref];
+                    }
+                }
+            }
 
             /* Write RateControl Frame level stats in multipass encodes */
             if (m_param->rc.bStatWrite)
@@ -1460,6 +2087,9 @@ int Encoder::encode(const x265_picture* 
             frameEnc = m_lookahead->getDecidedPicture();
         if (frameEnc && !pass && (!m_param->chunkEnd || (m_encodedFrameNum < m_param->chunkEnd)))
         {
+            if (m_param->bEnableSceneCutAwareQp && frameEnc->m_lowres.bScenecut)
+                m_rateControl->m_lastScenecut = frameEnc->m_poc;
+
             if (m_param->analysisMultiPassRefine || m_param->analysisMultiPassDistortion)
             {
                 uint32_t widthInCU = (m_param->sourceWidth + m_param->maxCUSize - 1) >> m_param->maxLog2CUSize;
@@ -1470,12 +2100,15 @@ int Encoder::encode(const x265_picture* 
                 frameEnc->m_analysisData.poc = frameEnc->m_poc;
                 if (m_param->rc.bStatRead)
                     readAnalysisFile(&frameEnc->m_analysisData, frameEnc->m_poc, frameEnc->m_lowres.sliceType);
-             }
-
-            for (int i = 0; i < m_param->rc.zonefileCount; i++)
+            }
+
+            if (m_param->bResetZoneConfig)
             {
-                if (m_param->rc.zones[i].startFrame == frameEnc->m_poc)
-                    x265_encoder_reconfig(this, m_param->rc.zones[i].zoneParam);
+                for (int i = 0; i < m_param->rc.zonefileCount; i++)
+                {
+                    if (m_param->rc.zones[i].startFrame == frameEnc->m_poc)
+                        x265_encoder_reconfig(this, m_param->rc.zones[i].zoneParam);
+                }
             }
 
             if (frameEnc->m_reconfigureRc && m_reconfigureRc)
@@ -2292,12 +2925,12 @@ void Encoder::finishFrameStats(Frame* cu
         frameStats->ssim = ssim;
         if (!slice->isIntra())
         {
-            for (int ref = 0; ref < 16; ref++)
+            for (int ref = 0; ref < MAX_NUM_REF; ref++)
                 frameStats->list0POC[ref] = ref < slice->m_numRefIdx[0] ? slice->m_refPOCList[0][ref] - slice->m_lastIDR : -1;
 
             if (!slice->isInterP())
             {
-                for (int ref = 0; ref < 16; ref++)
+                for (int ref = 0; ref < MAX_NUM_REF; ref++)
                     frameStats->list1POC[ref] = ref < slice->m_numRefIdx[1] ? slice->m_refPOCList[1][ref] - slice->m_lastIDR : -1;
             }
         }
@@ -2480,7 +3113,7 @@ void Encoder::getStreamHeaders(NALList& 
     if (m_param->bSingleSeiNal)
         bs.resetBits();
 
-    if (m_param->bEmitHDRSEI)
+    if (m_param->bEmitHDR10SEI)
     {
         if (m_param->bEmitCLL)
         {
@@ -2648,7 +3281,7 @@ void Encoder::initPPS(PPS *pps)
 
     pps->chromaQpOffset[0] = m_param->cbQpOffset;
     pps->chromaQpOffset[1] = m_param->crQpOffset;
-    pps->pps_slice_chroma_qp_offsets_present_flag = m_param->bHDROpt;
+    pps->pps_slice_chroma_qp_offsets_present_flag = m_param->bHDR10Opt;
 
     pps->bConstrainedIntraPred = m_param->bEnableConstrainedIntra;
     pps->bUseWeightPred = m_param->bEnableWeightedPred;
@@ -2670,48 +3303,51 @@ void Encoder::initPPS(PPS *pps)
 
 void Encoder::configureZone(x265_param *p, x265_param *zone)
 {
-    p->maxNumReferences = zone->maxNumReferences;
-    p->bEnableFastIntra = zone->bEnableFastIntra;
-    p->bEnableEarlySkip = zone->bEnableEarlySkip;
-    p->bEnableRecursionSkip = zone->bEnableRecursionSkip;
-    p->searchMethod = zone->searchMethod;
-    p->searchRange = zone->searchRange;
-    p->subpelRefine = zone->subpelRefine;
-    p->rdoqLevel = zone->rdoqLevel;
-    p->rdLevel = zone->rdLevel;
-    p->bEnableRectInter = zone->bEnableRectInter;
-    p->maxNumMergeCand = zone->maxNumMergeCand;
-    p->bIntraInBFrames = zone->bIntraInBFrames;
-    if(zone->scalingLists)
-        p->scalingLists = strdup(zone->scalingLists);
-
-    p->rc.aqMode = zone->rc.aqMode;
-    p->rc.aqStrength = zone->rc.aqStrength;
-    p->noiseReductionInter = zone->noiseReductionInter;
-    p->noiseReductionIntra = zone->noiseReductionIntra;
-
-    p->limitModes = zone->limitModes;
-    p->bEnableSplitRdSkip = zone->bEnableSplitRdSkip;
-    p->bCULossless = zone->bCULossless;
-    p->bEnableRdRefine = zone->bEnableRdRefine;
-    p->limitTU = zone->limitTU;
-    p->bEnableTSkipFast = zone->bEnableTSkipFast;
-    p->rdPenalty = zone->rdPenalty;
-    p->dynamicRd = zone->dynamicRd;
-    p->bEnableTransformSkip = zone->bEnableTransformSkip;
-    p->bEnableAMP = zone->bEnableAMP;
-
-    if (m_param->rc.rateControlMode == X265_RC_ABR)
-        p->rc.bitrate = zone->rc.bitrate;
-    if (m_param->rc.rateControlMode == X265_RC_CRF)
-        p->rc.rfConstant = zone->rc.rfConstant;
-    if (m_param->rc.rateControlMode == X265_RC_CQP)
-    {
-        p->rc.qp = zone->rc.qp;
-        p->rc.aqMode = X265_AQ_NONE;
-        p->rc.hevcAq = 0;
-    }
-    p->radl = zone->radl;
+    if (m_param->bResetZoneConfig)
+    {
+        p->maxNumReferences = zone->maxNumReferences;
+        p->bEnableFastIntra = zone->bEnableFastIntra;
+        p->bEnableEarlySkip = zone->bEnableEarlySkip;
+        p->bEnableRecursionSkip = zone->bEnableRecursionSkip;
+        p->searchMethod = zone->searchMethod;
+        p->searchRange = zone->searchRange;
+        p->subpelRefine = zone->subpelRefine;
+        p->rdoqLevel = zone->rdoqLevel;
+        p->rdLevel = zone->rdLevel;
+        p->bEnableRectInter = zone->bEnableRectInter;
+        p->maxNumMergeCand = zone->maxNumMergeCand;
+        p->bIntraInBFrames = zone->bIntraInBFrames;
+        if (zone->scalingLists)
+            p->scalingLists = strdup(zone->scalingLists);
+
+        p->rc.aqMode = zone->rc.aqMode;
+        p->rc.aqStrength = zone->rc.aqStrength;
+        p->noiseReductionInter = zone->noiseReductionInter;
+        p->noiseReductionIntra = zone->noiseReductionIntra;
+
+        p->limitModes = zone->limitModes;
+        p->bEnableSplitRdSkip = zone->bEnableSplitRdSkip;
+        p->bCULossless = zone->bCULossless;
+        p->bEnableRdRefine = zone->bEnableRdRefine;
+        p->limitTU = zone->limitTU;
+        p->bEnableTSkipFast = zone->bEnableTSkipFast;
+        p->rdPenalty = zone->rdPenalty;
+        p->dynamicRd = zone->dynamicRd;
+        p->bEnableTransformSkip = zone->bEnableTransformSkip;
+        p->bEnableAMP = zone->bEnableAMP;
+
+        if (m_param->rc.rateControlMode == X265_RC_ABR)
+            p->rc.bitrate = zone->rc.bitrate;
+        if (m_param->rc.rateControlMode == X265_RC_CRF)
+            p->rc.rfConstant = zone->rc.rfConstant;
+        if (m_param->rc.rateControlMode == X265_RC_CQP)
+        {
+            p->rc.qp = zone->rc.qp;
+            p->rc.aqMode = X265_AQ_NONE;
+            p->rc.hevcAq = 0;
+        }
+        p->radl = zone->radl;
+    }
     memcpy(zone, p, sizeof(x265_param));
 }
 
@@ -2734,7 +3370,7 @@ void Encoder::configureDolbyVisionParams
     p->vui.matrixCoeffs = dovi[doviProfile].matrixCoeffs;
 
     if (dovi[doviProfile].doviProfileId == 81)
-        p->bEmitHDRSEI = p->bEmitCLL = 1;
+        p->bEmitHDR10SEI = p->bEmitCLL = 1;
 
     if (dovi[doviProfile].doviProfileId == 50)
         p->crQpOffset = 3;
@@ -2766,6 +3402,7 @@ void Encoder::configure(x265_param *p)
          * adaptive I frame placement */
         p->keyframeMax = INT_MAX;
         p->scenecutThreshold = 0;
+        p->bHistBasedSceneCut = 0;
     }
     else if (p->keyframeMax <= 1)
     {
@@ -2779,6 +3416,7 @@ void Encoder::configure(x265_param *p)
         p->lookaheadDepth = 0;
         p->bframes = 0;
         p->scenecutThreshold = 0;
+        p->bHistBasedSceneCut = 0;
         p->bFrameAdaptive = 0;
         p->rc.cuTree = 0;
         p->bEnableWeightedPred = 0;
@@ -2931,10 +3569,38 @@ void Encoder::configure(x265_param *p)
         p->rc.rfConstantMin = 0;
     }
 
-    if (!(p->bAnalysisType == HEVC_INFO) && (p->analysisLoad || p->analysisSave) && p->rc.cuTree && p->analysisReuseLevel < 10)
-    {
-        x265_log(p, X265_LOG_WARNING, "cu-tree works only with analysis reuse level 10, Disabling cu-tree\n");
-        p->rc.cuTree = 0;
+    if (p->analysisSaveReuseLevel && !p->analysisSave)
+    {
+        x265_log(p, X265_LOG_WARNING, "analysis-save-reuse-level can be set only when analysis-save is enabled."
+            " Resetting analysis-save-reuse-level to 0.\n");
+        p->analysisSaveReuseLevel = 0;
+    }
+
+    if (p->analysisLoadReuseLevel && !p->analysisLoad)
+    {
+        x265_log(p, X265_LOG_WARNING, "analysis-load-reuse-level can be set only when analysis-load is enabled."
+            " Resetting analysis-load-reuse-level to 0.\n");
+        p->analysisLoadReuseLevel = 0;
+    }
+
+    if (p->analysisSave && !p->analysisSaveReuseLevel)
+        p->analysisSaveReuseLevel = 5;
+
+    if (p->analysisLoad && !p->analysisLoadReuseLevel)
+        p->analysisLoadReuseLevel = 5;
+
+    if ((p->bAnalysisType == DEFAULT) && p->rc.cuTree)
+    {
+        if (p->analysisSaveReuseLevel && p->analysisSaveReuseLevel < 10)
+        {
+            x265_log(p, X265_LOG_WARNING, "cu-tree works only with analysis-save-reuse-level 10, Disabling cu-tree\n");
+            p->rc.cuTree = 0;
+        }
+        if (p->analysisLoadReuseLevel && p->analysisLoadReuseLevel < 10)
+        {
+            x265_log(p, X265_LOG_WARNING, "cu-tree works only with analysis-load-reuse-level 10, Disabling cu-tree\n");
+            p->rc.cuTree = 0;
+        }
     }
 
     if ((p->analysisLoad || p->analysisSave) && (p->bDistributeModeAnalysis || p->bDistributeMotionEstimation))
@@ -2956,45 +3622,37 @@ void Encoder::configure(x265_param *p)
         {
             p->scaleFactor = 0;
         }
-        else if ((!p->analysisLoad && !p->analysisSave) || (p->analysisReuseLevel > 6 && p->analysisReuseLevel != 10))
+        else if ((p->analysisSaveReuseLevel > 6 && p->analysisSaveReuseLevel != 10) || (p->analysisLoadReuseLevel > 6 && p->analysisLoadReuseLevel != 10))
         {
-            x265_log(p, X265_LOG_WARNING, "Input scaling works with analysis load/save and analysis-reuse-level 1-6 and 10. Disabling scale-factor.\n");
+            x265_log(p, X265_LOG_WARNING, "Input scaling works with analysis-save/load and analysis-save/load-reuse-level 1-6 and 10. Disabling scale-factor.\n");
             p->scaleFactor = 0;
         }
     }
 
-    if (p->intraRefine)
-    {
-        if (!p->analysisLoad || p->analysisReuseLevel < 10)
-        {
-            x265_log(p, X265_LOG_WARNING, "Intra refinement requires analysis load, analysis-reuse-level 10. Disabling intra refine.\n");
-            p->intraRefine = 0;
-        }
-    }
-
-    if (p->interRefine)
-    {
-        if (!p->analysisLoad || p->analysisReuseLevel < 10)
-        {
-            x265_log(p, X265_LOG_WARNING, "Inter refinement requires analysis load, analysis-reuse-level 10. Disabling inter refine.\n");
-            p->interRefine = 0;
-        }
-    }
-
-    if (p->bDynamicRefine)
-    {
-        if (!p->analysisLoad || p->analysisReuseLevel < 10)
-        {
-            x265_log(p, X265_LOG_WARNING, "Dynamic refinement requires analysis load, analysis-reuse-level 10. Disabling dynamic refine.\n");
-            p->bDynamicRefine = 0;
-        }
+    if (p->intraRefine && p->analysisLoadReuseLevel && p->analysisLoadReuseLevel < 10)
+    {
+        x265_log(p, X265_LOG_WARNING, "Intra refinement requires analysis load, analysis-load-reuse-level 10. Disabling intra refine.\n");
+        p->intraRefine = 0;
+    }
+
+    if (p->interRefine && p->analysisLoadReuseLevel && p->analysisLoadReuseLevel < 10)
+    {
+        x265_log(p, X265_LOG_WARNING, "Inter refinement requires analysis load, analysis-load-reuse-level 10. Disabling inter refine.\n");
+        p->interRefine = 0;
+    }
+
+    if (p->bDynamicRefine && p->analysisLoadReuseLevel && p->analysisLoadReuseLevel < 10)
+    {
+        x265_log(p, X265_LOG_WARNING, "Dynamic refinement requires analysis load, analysis-load-reuse-level 10. Disabling dynamic refine.\n");
+        p->bDynamicRefine = 0;
+
         if (p->interRefine)
         {
             x265_log(p, X265_LOG_WARNING, "Inter refine cannot be used with dynamic refine. Disabling refine-inter.\n");
             p->interRefine = 0;
         }
     }
-    if (p->scaleFactor && p->analysisLoad && !p->interRefine && !p->bDynamicRefine && p->analysisReuseLevel == 10)
+    if (p->scaleFactor && !p->interRefine && !p->bDynamicRefine && p->analysisLoadReuseLevel == 10)
     {
         x265_log(p, X265_LOG_WARNING, "Inter refinement 0 is not supported with scaling and analysis-reuse-level=10. Enabling refine-inter 1.\n");
         p->interRefine = 1;
@@ -3081,7 +3739,7 @@ void Encoder::configure(x265_param *p)
 
     if (!p->rc.bStatWrite && !p->rc.bStatRead && (p->analysisMultiPassRefine || p->analysisMultiPassDistortion))
     {
-        x265_log(p, X265_LOG_WARNING, "analysis-multi-pass/distortion is enabled only when rc multi pass is enabled. Disabling multi-pass-opt-analysis and multi-pass-opt-distortion");
+        x265_log(p, X265_LOG_WARNING, "analysis-multi-pass/distortion is enabled only when rc multi pass is enabled. Disabling multi-pass-opt-analysis and multi-pass-opt-distortion\n");
         p->analysisMultiPassRefine = 0;
         p->analysisMultiPassDistortion = 0;
     }
@@ -3095,26 +3753,78 @@ void Encoder::configure(x265_param *p)
     p->bSaoNonDeblocked &= p->bEnableSAO;
     p->bEnableTSkipFast &= p->bEnableTransformSkip;
     p->bLimitSAO &= p->bEnableSAO;
+
+    if (m_param->bUseAnalysisFile && m_param->analysisLoad && (p->confWinRightOffset || p->confWinBottomOffset))
+        x265_log(p, X265_LOG_WARNING, "It is recommended not to set conformance window offset in file based analysis-load."
+                                      " Offsets are shared in the analysis file already.\n");
     /* initialize the conformance window */
     m_conformanceWindow.bEnabled = false;
     m_conformanceWindow.rightOffset = 0;
     m_conformanceWindow.topOffset = 0;
     m_conformanceWindow.bottomOffset = 0;
     m_conformanceWindow.leftOffset = 0;
+
+    uint32_t padsize = 0;
+    if (m_param->analysisLoad && m_param->bUseAnalysisFile)
+    {
+        m_analysisFileIn = x265_fopen(m_param->analysisLoad, "rb");
+        if (!m_analysisFileIn)
+        {
+            x265_log_file(NULL, X265_LOG_ERROR, "Analysis load: failed to open file %s\n", m_param->analysisLoad);
+            m_aborted = true;
+        }
+        else
+        {
+            if (fread(&m_conformanceWindow.rightOffset, sizeof(int), 1, m_analysisFileIn) != 1)
+            {
+                x265_log(NULL, X265_LOG_ERROR, "Error reading analysis data. Conformance window right offset missing\n");
+                m_aborted = true;
+            }
+            else if (m_conformanceWindow.rightOffset && p->analysisLoadReuseLevel > 1)
+            {
+                int scaleFactor = p->scaleFactor < 2 ? 1 : p->scaleFactor;
+                padsize = m_conformanceWindow.rightOffset * scaleFactor;
+                p->sourceWidth += padsize;
+                m_conformanceWindow.bEnabled = true;
+                m_conformanceWindow.rightOffset = padsize;
+            }
+
+            if (fread(&m_conformanceWindow.bottomOffset, sizeof(int), 1, m_analysisFileIn) != 1)
+            {
+                x265_log(NULL, X265_LOG_ERROR, "Error reading analysis data. Conformance window bottom offset missing\n");
+                m_aborted = true;
+            }
+            else if (m_conformanceWindow.bottomOffset && p->analysisLoadReuseLevel > 1)
+            {
+                int scaleFactor = p->scaleFactor < 2 ? 1 : p->scaleFactor;
+                padsize = m_conformanceWindow.bottomOffset * scaleFactor;
+                p->sourceHeight += padsize;
+                m_conformanceWindow.bEnabled = true;
+                m_conformanceWindow.bottomOffset = padsize;
+            }
+        }
+    }
+
     /* set pad size if width is not multiple of the minimum CU size */
-    if (p->scaleFactor == 2 && ((p->sourceWidth / 2) & (p->minCUSize - 1)) && p->analysisLoad)
-    {
-        uint32_t rem = (p->sourceWidth / 2) & (p->minCUSize - 1);
-        uint32_t padsize = p->minCUSize - rem;
-        p->sourceWidth += padsize * 2;
-
-        m_conformanceWindow.bEnabled = true;
-        m_conformanceWindow.rightOffset = padsize * 2;
-    }
-    else if(p->sourceWidth & (p->minCUSize - 1))
+    if (p->confWinRightOffset)
+    {
+        if ((p->sourceWidth + p->confWinRightOffset) & (p->minCUSize - 1))
+        {
+            x265_log(p, X265_LOG_ERROR, "Incompatible conformance window right offset."
+                                          " This when added to the source width should be a multiple of minCUSize\n");
+            m_aborted = true;
+        }
+        else
+        {
+            p->sourceWidth += p->confWinRightOffset;
+            m_conformanceWindow.bEnabled = true;
+            m_conformanceWindow.rightOffset = p->confWinRightOffset;
+        }
+    }
+    else if (p->sourceWidth & (p->minCUSize - 1))
     {
         uint32_t rem = p->sourceWidth & (p->minCUSize - 1);
-        uint32_t padsize = p->minCUSize - rem;
+        padsize = p->minCUSize - rem;
         p->sourceWidth += padsize;
 
         m_conformanceWindow.bEnabled = true;
@@ -3160,6 +3870,30 @@ void Encoder::configure(x265_param *p)
         p->dynamicRd = 0;
         x265_log(p, X265_LOG_WARNING, "Dynamic-rd disabled, requires RD <= 4, VBV and aq-mode enabled\n");
     }
+
+    if (!p->bEnableFrameDuplication && p->dupThreshold && p->dupThreshold != 70)
+    {
+        x265_log(p, X265_LOG_WARNING, "Frame-duplication threshold works only with frame-duplication enabled. Enabling frame-duplication.\n");
+        p->bEnableFrameDuplication = 1;
+    }
+
+    if (p->bEnableFrameDuplication && p->interlaceMode)
+    {
+        x265_log(p, X265_LOG_WARNING, "Frame-duplication does not support interlace mode. Disabling Frame Duplication.\n");
+        p->bEnableFrameDuplication = 0;
+    }
+
+    if (p->bEnableFrameDuplication && p->pictureStructure != 0 && p->pictureStructure != -1)
+    {
+        x265_log(p, X265_LOG_WARNING, "Frame-duplication works only with pic_struct = 0. Setting pic-struct = 0.\n");
+        p->pictureStructure = 0;
+    }
+
+    if (m_param->bEnableFrameDuplication && (!bIsVbv || !m_param->bEmitHRDSEI))
+    {
+        x265_log(m_param, X265_LOG_WARNING, "Frame-duplication require NAL HRD and VBV parameters. Disabling frame duplication\n");
+        m_param->bEnableFrameDuplication = 0;
+    }
 #ifdef ENABLE_HDR10_PLUS
     if (m_param->bDhdr10opt && m_param->toneMapFile == NULL)
     {
@@ -3291,18 +4025,25 @@ void Encoder::configure(x265_param *p)
         }
     }
     /* set pad size if height is not multiple of the minimum CU size */
-    if (p->scaleFactor == 2 && ((p->sourceHeight / 2) & (p->minCUSize - 1)) && p->analysisLoad)
-    {
-        uint32_t rem = (p->sourceHeight / 2) & (p->minCUSize - 1);
-        uint32_t padsize = p->minCUSize - rem;
-        p->sourceHeight += padsize * 2;
-        m_conformanceWindow.bEnabled = true;
-        m_conformanceWindow.bottomOffset = padsize * 2;
+    if (p->confWinBottomOffset)
+    {
+        if ((p->sourceHeight + p->confWinBottomOffset) & (p->minCUSize - 1))
+        {
+            x265_log(p, X265_LOG_ERROR, "Incompatible conformance window bottom offset."
+                " This when added to the source height should be a multiple of minCUSize\n");
+            m_aborted = true;
+        }
+        else
+        {
+            p->sourceHeight += p->confWinBottomOffset;
+            m_conformanceWindow.bEnabled = true;
+            m_conformanceWindow.bottomOffset = p->confWinBottomOffset;
+        }
     }
     else if(p->sourceHeight & (p->minCUSize - 1))
     {
         uint32_t rem = p->sourceHeight & (p->minCUSize - 1);
-        uint32_t padsize = p->minCUSize - rem;
+        padsize = p->minCUSize - rem;
         p->sourceHeight += padsize;
         m_conformanceWindow.bEnabled = true;
         m_conformanceWindow.bottomOffset = padsize;
@@ -3329,21 +4070,21 @@ void Encoder::configure(x265_param *p)
         x265_log(p, X265_LOG_WARNING, "maxSlices can not be more than min(rows, MAX_NAL_UNITS-1), force set to %d\n", slicesLimit);
         p->maxSlices = slicesLimit;
     }
-    if (p->bHDROpt)
+    if (p->bHDR10Opt)
     {
         if (p->internalCsp != X265_CSP_I420 || p->internalBitDepth != 10 || p->vui.colorPrimaries != 9 ||
             p->vui.transferCharacteristics != 16 || p->vui.matrixCoeffs != 9)
         {
-            x265_log(p, X265_LOG_ERROR, "Recommended Settings for HDR: colour primaries should be BT.2020,\n"
+            x265_log(p, X265_LOG_ERROR, "Recommended Settings for HDR10-opt: colour primaries should be BT.2020,\n"
                                         "                                            transfer characteristics should be SMPTE ST.2084,\n"
                                         "                                            matrix coeffs should be BT.2020,\n"
                                         "                                            the input video should be 10 bit 4:2:0\n"
-                                        "                                            Disabling offset tuning for HDR videos\n");
-            p->bHDROpt = 0;
+                                        "                                            Disabling hdr10-opt.\n");
+            p->bHDR10Opt = 0;
         }
     }
 
-    if (m_param->toneMapFile || p->bHDROpt || p->bEmitHDRSEI)
+    if (m_param->toneMapFile || p->bHDR10Opt || p->bEmitHDR10SEI)
     {
         if (!p->bRepeatHeaders)
         {
@@ -3396,6 +4137,12 @@ void Encoder::configure(x265_param *p)
         x265_log(p, X265_LOG_WARNING, "Turning on repeat - headers for zone encoding\n");
     }
 
+    if (!m_param->bResetZoneConfig && (p->keyframeMax != p->keyframeMin))
+        x265_log(p, X265_LOG_WARNING, "External zone reconfiguration requires a fixed GOP size to enable appropriate signaling of HRD info\n");
+
+    if (!m_param->bResetZoneConfig && (p->reconfigWindowSize != (uint64_t)p->keyframeMax))
+        x265_log(p, X265_LOG_WARNING, "Zone size must be multiple of GOP size to enable appropriate signaling of HRD info\n");
+
     if (m_param->bEnableHME)
     {
         if (m_param->sourceHeight < 540)
@@ -3403,11 +4150,22 @@ void Encoder::configure(x265_param *p)
             x265_log(p, X265_LOG_WARNING, "Source height < 540p is too low for HME. Disabling HME.\n");
             p->bEnableHME = 0;
         }
-        if (m_param->bEnableHME && m_param->searchMethod != m_param->hmeSearchMethod[2])
-        {
+    }
+
+    if (m_param->bEnableHME)
+    {
+        if (m_param->searchMethod != m_param->hmeSearchMethod[2])
             m_param->searchMethod = m_param->hmeSearchMethod[2];
-        }
-    }
+        if (m_param->searchRange != m_param->hmeRange[2])
+            m_param->searchRange = m_param->hmeRange[2];
+    }
+
+   if (p->bHistBasedSceneCut && !p->edgeTransitionThreshold)
+   {
+       p->edgeTransitionThreshold = 0.01;
+       x265_log(p, X265_LOG_WARNING, "using  default threshold %.2lf for scene cut detection\n", p->edgeTransitionThreshold);
+   }
+
 }
 
 void Encoder::readAnalysisFile(x265_analysis_data* analysis, int curPoc, const x265_picture* picIn, int paramBytes)
@@ -3518,7 +4276,7 @@ void Encoder::readAnalysisFile(x265_anal
     {
         if (m_param->bAnalysisType == HEVC_INFO)
             return;
-        if (m_param->analysisReuseLevel < 2)
+        if (m_param->analysisLoadReuseLevel < 2)
             return;
 
         uint8_t *tempBuf = NULL, *depthBuf = NULL, *modeBuf = NULL, *partSizes = NULL;
@@ -3578,7 +4336,7 @@ void Encoder::readAnalysisFile(x265_anal
         uint32_t numDir = analysis->sliceType == X265_TYPE_P ? 1 : 2;
         uint32_t numPlanes = m_param->internalCsp == X265_CSP_I400 ? 1 : 3;
         X265_FREAD((WeightParam*)analysis->wt, sizeof(WeightParam), numPlanes * numDir, m_analysisFileIn, (picIn->analysisData.wt));
-        if (m_param->analysisReuseLevel < 2)
+        if (m_param->analysisLoadReuseLevel < 2)
             return;
 
         uint8_t *tempBuf = NULL, *depthBuf = NULL, *modeBuf = NULL, *partSize = NULL, *mergeFlag = NULL;
@@ -3587,9 +4345,9 @@ void Encoder::readAnalysisFile(x265_anal
         int8_t* refIdx[2];
         int8_t* cuQPBuf = NULL;
 
-        int numBuf = m_param->analysisReuseLevel > 4 ? 4 : 2;
+        int numBuf = m_param->analysisLoadReuseLevel > 4 ? 4 : 2;
         bool bIntraInInter = false;
-        if (m_param->analysisReuseLevel == 10)
+        if (m_param->analysisLoadReuseLevel == 10)
         {
             numBuf++;
             bIntraInInter = (analysis->sliceType == X265_TYPE_P || m_param->bIntraInBFrames);
@@ -3612,14 +4370,14 @@ void Encoder::readAnalysisFile(x265_anal
             X265_FREAD(modeBuf, sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->modes);
             if (m_param->rc.cuTree) { X265_FREAD(cuQPBuf, sizeof(int8_t), depthBytes, m_analysisFileIn, interPic->cuQPOff); }
 
-            if (m_param->analysisReuseLevel > 4)
+            if (m_param->analysisLoadReuseLevel > 4)
             {
                 partSize = modeBuf + depthBytes;
                 mergeFlag = partSize + depthBytes;
                 X265_FREAD(partSize, sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->partSize);
                 X265_FREAD(mergeFlag, sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->mergeFlag);
 
-                if (m_param->analysisReuseLevel == 10)
+                if (m_param->analysisLoadReuseLevel == 10)
                 {
                     interDir = mergeFlag + depthBytes;
                     X265_FREAD(interDir, sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->interDir);
@@ -3650,7 +4408,7 @@ void Encoder::readAnalysisFile(x265_anal
                 memset(&(analysis->interData)->modes[count], modeBuf[d], bytes);
                 if (m_param->rc.cuTree)
                     memset(&(analysis->interData)->cuQPOff[count], cuQPBuf[d], bytes);
-                if (m_param->analysisReuseLevel > 4)
+                if (m_param->analysisLoadReuseLevel > 4)
                 {
                     if (m_param->scaleFactor && modeBuf[d] == MODE_INTRA && partSize[d] == SIZE_NxN)
                         partSize[d] = SIZE_2Nx2N;
@@ -3660,7 +4418,7 @@ void Encoder::readAnalysisFile(x265_anal
                     {
                         if (pu) d++;
                         (analysis->interData)->mergeFlag[count + pu] = mergeFlag[d];
-                        if (m_param->analysisReuseLevel == 10)
+                        if (m_param->analysisLoadReuseLevel == 10)
                         {
                             (analysis->interData)->interDir[count + pu] = interDir[d];
                             for (uint32_t i = 0; i < numDir; i++)
@@ -3676,7 +4434,7 @@ void Encoder::readAnalysisFile(x265_anal
                             }
                         }
                     }
-                    if (m_param->analysisReuseLevel == 10 && bIntraInInter)
+                    if (m_param->analysisLoadReuseLevel == 10 && bIntraInInter)
                         memset(&(analysis->intraData)->chromaModes[count], chromaDir[d], bytes);
                 }
                 count += bytes;
@@ -3686,7 +4444,7 @@ void Encoder::readAnalysisFile(x265_anal
                 X265_FREE(cuQPBuf);
             X265_FREE(tempBuf);
         }
-        if (m_param->analysisReuseLevel == 10)
+        if (m_param->analysisLoadReuseLevel == 10)
         {
             if (m_param->bAnalysisType != HEVC_INFO)
             {
@@ -3869,7 +4627,7 @@ void Encoder::readAnalysisFile(x265_anal
 
     if (analysis->sliceType == X265_TYPE_IDR || analysis->sliceType == X265_TYPE_I)
     {
-        if (m_param->analysisReuseLevel < 2)
+        if (m_param->analysisLoadReuseLevel < 2)
             return;
 
         uint8_t *tempBuf = NULL, *depthBuf = NULL, *modeBuf = NULL, *partSizes = NULL;
@@ -3938,7 +4696,7 @@ void Encoder::readAnalysisFile(x265_anal
         uint32_t numDir = analysis->sliceType == X265_TYPE_P ? 1 : 2;
         uint32_t numPlanes = m_param->internalCsp == X265_CSP_I400 ? 1 : 3;
         X265_FREAD((WeightParam*)analysis->wt, sizeof(WeightParam), numPlanes * numDir, m_analysisFileIn, (picIn->analysisData.wt));
-        if (m_param->analysisReuseLevel < 2)
+        if (m_param->analysisLoadReuseLevel < 2)
             return;
 
         uint8_t *tempBuf = NULL, *depthBuf = NULL, *modeBuf = NULL, *partSize = NULL, *mergeFlag = NULL;
@@ -3947,9 +4705,9 @@ void Encoder::readAnalysisFile(x265_anal
         int8_t* refIdx[2];
         int8_t* cuQPBuf = NULL;
 
-        int numBuf = m_param->analysisReuseLevel > 4 ? 4 : 2;
+        int numBuf = m_param->analysisLoadReuseLevel > 4 ? 4 : 2;
         bool bIntraInInter = false;
-        if (m_param->analysisReuseLevel == 10)
+        if (m_param->analysisLoadReuseLevel == 10)
         {
             numBuf++;
             bIntraInInter = (analysis->sliceType == X265_TYPE_P || m_param->bIntraInBFrames);
@@ -3965,13 +4723,13 @@ void Encoder::readAnalysisFile(x265_anal
         X265_FREAD(depthBuf, sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->depth);
         X265_FREAD(modeBuf, sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->modes);
         if (m_param->rc.cuTree) { X265_FREAD(cuQPBuf, sizeof(int8_t), depthBytes, m_analysisFileIn, interPic->cuQPOff); }
-        if (m_param->analysisReuseLevel > 4)
+        if (m_param->analysisLoadReuseLevel > 4)
         {
             partSize = modeBuf + depthBytes;
             mergeFlag = partSize + depthBytes;
             X265_FREAD(partSize, sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->partSize);
             X265_FREAD(mergeFlag, sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->mergeFlag);
-            if (m_param->analysisReuseLevel == 10)
+            if (m_param->analysisLoadReuseLevel == 10)
             {
                 interDir = mergeFlag + depthBytes;
                 X265_FREAD(interDir, sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->interDir);
@@ -4015,10 +4773,10 @@ void Encoder::readAnalysisFile(x265_anal
                 memset(&(analysis->interData)->modes[count], modeBuf[d], bytes);
                 if (m_param->rc.cuTree)
                     memset(&(analysis->interData)->cuQPOff[count], cuQPBuf[d], bytes);
-                if (m_param->analysisReuseLevel == 10 && bIntraInInter)
+                if (m_param->analysisLoadReuseLevel == 10 && bIntraInInter)
                     memset(&(analysis->intraData)->chromaModes[count], chromaDir[d], bytes);
 
-                if (m_param->analysisReuseLevel > 4)
+                if (m_param->analysisLoadReuseLevel > 4)
                 {
                     puOrientation puOrient;
                     puOrient.init();
@@ -4044,7 +4802,7 @@ void Encoder::readAnalysisFile(x265_anal
                             d++;
 
                         (analysis->interData)->mergeFlag[count + pu] = mergeFlag[d];
-                        if (m_param->analysisReuseLevel == 10)
+                        if (m_param->analysisLoadReuseLevel == 10)
                         {
                             (analysis->interData)->interDir[count + pu] = interDir[d];
                             MV mvCopy[2];
@@ -4079,7 +4837,7 @@ void Encoder::readAnalysisFile(x265_anal
             X265_FREE(cuQPBuf);
         X265_FREE(tempBuf);
 
-        if (m_param->analysisReuseLevel == 10)
+        if (m_param->analysisLoadReuseLevel == 10)
         {
             for (uint32_t i = 0; i < numDir; i++)
             {
@@ -4120,7 +4878,7 @@ void Encoder::readAnalysisFile(x265_anal
 }
 
 
-int Encoder::validateAnalysisData(x265_analysis_data* analysis, int writeFlag)
+int Encoder::validateAnalysisData(x265_analysis_validate* saveParam, int writeFlag)
 {
 #define X265_PARAM_VALIDATE(analysisParam, size, bytes, param, errorMsg)\
     if(!writeFlag)\
@@ -4161,14 +4919,18 @@ int Encoder::validateAnalysisData(x265_a
     }\
     count++;
 
-    x265_analysis_validate *saveParam = &analysis->saveParam;
     FILE*     fileOffset = NULL;
     int       readValue = 0;
     int       count = 0;
 
+    if (m_param->bUseAnalysisFile && writeFlag)
+    {
+        X265_PARAM_VALIDATE(saveParam->rightOffset, sizeof(int), 1, &m_conformanceWindow.rightOffset, right-offset);
+        X265_PARAM_VALIDATE(saveParam->bottomOffset, sizeof(int), 1, &m_conformanceWindow.bottomOffset, bottom-offset);
+    }
+
     X265_PARAM_VALIDATE(saveParam->intraRefresh, sizeof(int), 1, &m_param->bIntraRefresh, intra-refresh);
     X265_PARAM_VALIDATE(saveParam->maxNumReferences, sizeof(int), 1, &m_param->maxNumReferences, ref);
-    X265_PARAM_VALIDATE(saveParam->analysisReuseLevel, sizeof(int), 1, &m_param->analysisReuseLevel, analysis-reuse-level);
     X265_PARAM_VALIDATE(saveParam->keyframeMax, sizeof(int), 1, &m_param->keyframeMax, keyint);
     X265_PARAM_VALIDATE(saveParam->keyframeMin, sizeof(int), 1, &m_param->keyframeMin, min-keyint);
     X265_PARAM_VALIDATE(saveParam->openGOP, sizeof(int), 1, &m_param->bOpenGOP, open-gop);
@@ -4184,6 +4946,7 @@ int Encoder::validateAnalysisData(x265_a
     int sourceHeight, sourceWidth;
     if (writeFlag)
     {
+        X265_PARAM_VALIDATE(saveParam->analysisReuseLevel, sizeof(int), 1, &m_param->analysisSaveReuseLevel, analysis - save - reuse - level);
         sourceHeight = m_param->sourceHeight - m_conformanceWindow.bottomOffset;
         sourceWidth = m_param->sourceWidth - m_conformanceWindow.rightOffset;
         X265_PARAM_VALIDATE(saveParam->sourceWidth, sizeof(int), 1, &sourceWidth, res-width);
@@ -4193,17 +4956,42 @@ int Encoder::validateAnalysisData(x265_a
     else
     {
         fileOffset = m_analysisFileIn;
+
+        int saveLevel = 0;
+        bool isIncompatibleReuseLevel = false;
+        int loadLevel = m_param->analysisLoadReuseLevel;
+
+        X265_FREAD(&saveLevel, sizeof(int), 1, m_analysisFileIn, &(saveParam->analysisReuseLevel));
+        
+        if (loadLevel == 10 && saveLevel != 10)
+            isIncompatibleReuseLevel = true;
+        else if (((loadLevel >= 7) && (loadLevel <= 9)) && ((saveLevel < 7) || (saveLevel > 9)))
+            isIncompatibleReuseLevel = true;
+        else if ((loadLevel == 5 || loadLevel == 6) && ((saveLevel != 5) && (saveLevel != 6)))
+            isIncompatibleReuseLevel = true;
+        else if ((loadLevel >= 2 && loadLevel <= 4) && (saveLevel < 2 || saveLevel > 6))
+            isIncompatibleReuseLevel = true;
+        else if (!saveLevel)
+            isIncompatibleReuseLevel = true;
+
+        if (isIncompatibleReuseLevel)
+        {
+            x265_log(NULL, X265_LOG_ERROR, "Error reading analysis data. Incompatible reuse-levels.\n");
+            m_aborted = true;
+            return -1;
+        }
+
         bool error = false;
         int curSourceHeight = m_param->sourceHeight - m_conformanceWindow.bottomOffset;
         int curSourceWidth = m_param->sourceWidth - m_conformanceWindow.rightOffset;
-
+      
         X265_FREAD(&sourceWidth, sizeof(int), 1, m_analysisFileIn, &(saveParam->sourceWidth));
         X265_FREAD(&sourceHeight, sizeof(int), 1, m_analysisFileIn, &(saveParam->sourceHeight));
         X265_FREAD(&readValue, sizeof(int), 1, m_analysisFileIn, &(saveParam->maxCUSize));
 
         bool isScaledRes = (2 * sourceHeight == curSourceHeight) && (2 * sourceWidth == curSourceWidth);
-        if (!isScaledRes && (sourceHeight != curSourceHeight || sourceWidth != curSourceWidth 
-                            || readValue != (int)m_param->maxCUSize || m_param->scaleFactor))
+        if (!isScaledRes && (m_param->analysisLoadReuseLevel > 1) && (sourceHeight != curSourceHeight
+            || sourceWidth != curSourceWidth || readValue != (int)m_param->maxCUSize || m_param->scaleFactor))
             error = true;
         else if (isScaledRes && !m_param->scaleFactor)
             error = true;
@@ -4495,7 +5283,7 @@ void Encoder::writeAnalysisFile(x265_ana
 
     if (!analysis->poc)
     {
-        if (validateAnalysisData(analysis, 1) == -1)
+        if (validateAnalysisData(&analysis->saveParam, 1) == -1)
         {
             m_aborted = true;
             return;
@@ -4518,7 +5306,7 @@ void Encoder::writeAnalysisFile(x265_ana
         analysis->frameRecordSize += analysis->numCUsInFrame * sizeof(sse_t);
     }
 
-    if (m_param->analysisReuseLevel > 1)
+    if (m_param->analysisSaveReuseLevel > 1)
     {
 
         if (analysis->sliceType == X265_TYPE_IDR || analysis->sliceType == X265_TYPE_I)
@@ -4571,14 +5359,14 @@ void Encoder::writeAnalysisFile(x265_ana
                     interDataCTU->depth[depthBytes] = depth;
 
                     predMode = ctu->m_predMode[absPartIdx];
-                    if (m_param->analysisReuseLevel != 10 && ctu->m_refIdx[1][absPartIdx] != -1)
+                    if (m_param->analysisSaveReuseLevel != 10 && ctu->m_refIdx[1][absPartIdx] != -1)
                         predMode = 4; // used as indicator if the block is coded as bidir
 
                     interDataCTU->modes[depthBytes] = predMode;
                     if (m_param->rc.cuTree)
                         interDataCTU->cuQPOff[depthBytes] = (int8_t)(ctu->m_qpAnalysis[absPartIdx] - baseQP);
 
-                    if (m_param->analysisReuseLevel > 4)
+                    if (m_param->analysisSaveReuseLevel > 4)
                     {
                         partSize = ctu->m_partSize[absPartIdx];
                         interDataCTU->partSize[depthBytes] = partSize;
@@ -4591,7 +5379,7 @@ void Encoder::writeAnalysisFile(x265_ana
                             if (puIdx) depthBytes++;
                             interDataCTU->mergeFlag[depthBytes] = ctu->m_mergeFlag[puabsPartIdx];
 
-                            if (m_param->analysisReuseLevel == 10)
+                            if (m_param->analysisSaveReuseLevel == 10)
                             {
                                 interDataCTU->interDir[depthBytes] = ctu->m_interDir[puabsPartIdx];
                                 for (uint32_t dir = 0; dir < numDir; dir++)
@@ -4602,12 +5390,12 @@ void Encoder::writeAnalysisFile(x265_ana
                                 }
                             }
                         }
-                        if (m_param->analysisReuseLevel == 10 && bIntraInInter)
+                        if (m_param->analysisSaveReuseLevel == 10 && bIntraInInter)
                             intraDataCTU->chromaModes[depthBytes] = ctu->m_chromaIntraDir[absPartIdx];
                     }
                     absPartIdx += ctu->m_numPartitions >> (depth * 2);
                 }
-                if (m_param->analysisReuseLevel == 10 && bIntraInInter)
+                if (m_param->analysisSaveReuseLevel == 10 && bIntraInInter)
                     memcpy(&intraDataCTU->modes[ctu->m_cuAddr * ctu->m_numPartitions], ctu->m_lumaIntraDir, sizeof(uint8_t)* ctu->m_numPartitions);
             }
         }
@@ -4622,10 +5410,10 @@ void Encoder::writeAnalysisFile(x265_ana
             analysis->frameRecordSize += depthBytes * 2;
             if (m_param->rc.cuTree)
             analysis->frameRecordSize += (sizeof(int8_t) * depthBytes);
-            if (m_param->analysisReuseLevel > 4)
+            if (m_param->analysisSaveReuseLevel > 4)
                 analysis->frameRecordSize += (depthBytes * 2);
 
-            if (m_param->analysisReuseLevel == 10)
+            if (m_param->analysisSaveReuseLevel == 10)
             {
                 /* Add Size of interDir, mvpIdx, refIdx, mv, luma and chroma modes */
                 analysis->frameRecordSize += depthBytes;
@@ -4657,7 +5445,7 @@ void Encoder::writeAnalysisFile(x265_ana
     if (analysis->sliceType > X265_TYPE_I)
         X265_FWRITE((WeightParam*)analysis->wt, sizeof(WeightParam), numPlanes * numDir, m_analysisFileOut);
 
-    if (m_param->analysisReuseLevel < 2)
+    if (m_param->analysisSaveReuseLevel < 2)
         return;
 
     if (analysis->sliceType == X265_TYPE_IDR || analysis->sliceType == X265_TYPE_I)
@@ -4675,11 +5463,11 @@ void Encoder::writeAnalysisFile(x265_ana
         X265_FWRITE((analysis->interData)->modes, sizeof(uint8_t), depthBytes, m_analysisFileOut);
         if (m_param->rc.cuTree)
             X265_FWRITE((analysis->interData)->cuQPOff, sizeof(int8_t), depthBytes, m_analysisFileOut);
-        if (m_param->analysisReuseLevel > 4)
+        if (m_param->analysisSaveReuseLevel > 4)
         {
             X265_FWRITE((analysis->interData)->partSize, sizeof(uint8_t), depthBytes, m_analysisFileOut);
             X265_FWRITE((analysis->interData)->mergeFlag, sizeof(uint8_t), depthBytes, m_analysisFileOut);
-            if (m_param->analysisReuseLevel == 10)
+            if (m_param->analysisSaveReuseLevel == 10)
             {
                 X265_FWRITE((analysis->interData)->interDir, sizeof(uint8_t), depthBytes, m_analysisFileOut);
                 if (bIntraInInter) X265_FWRITE((analysis->intraData)->chromaModes, sizeof(uint8_t), depthBytes, m_analysisFileOut);
@@ -4693,7 +5481,7 @@ void Encoder::writeAnalysisFile(x265_ana
                     X265_FWRITE((analysis->intraData)->modes, sizeof(uint8_t), analysis->numCUsInFrame * analysis->numPartitions, m_analysisFileOut);
             }
         }
-        if (m_param->analysisReuseLevel != 10)
+        if (m_param->analysisSaveReuseLevel != 10)
             X265_FWRITE((analysis->interData)->ref, sizeof(int32_t), analysis->numCUsInFrame * X265_MAX_PRED_MODE_PER_CTU * numDir, m_analysisFileOut);
 
     }
--- a/source/encoder/encoder.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/encoder/encoder.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *
@@ -88,6 +88,9 @@ struct EncStats
 };
 
 #define MAX_NUM_REF_IDX 64
+#define DUP_BUFFER 2
+#define doubling 7
+#define tripling 8
 
 struct RefIdxLastGOP
 {
@@ -141,6 +144,17 @@ struct puOrientation
     }
 };
 
+struct AdaptiveFrameDuplication
+{
+    x265_picture* dupPic;
+    char* dupPlane;
+
+    //Flag to denote the availability of the picture buffer.
+    bool bOccupied;
+
+    //Flag to check whether the picture has duplicated.
+    bool bDup;
+};
 
 class FrameEncoder;
 class DPB;
@@ -149,6 +163,9 @@ class RateControl;
 class ThreadPool;
 class FrameData;
 
+#define MAX_SCENECUT_THRESHOLD 2.0
+#define SCENECUT_STRENGTH_FACTOR 2.0
+
 class Encoder : public x265_encoder
 {
 public:
@@ -189,6 +206,10 @@ public:
     x265_param*        m_latestParam;     // Holds latest param during a reconfigure
     RateControl*       m_rateControl;
     Lookahead*         m_lookahead;
+    AdaptiveFrameDuplication* m_dupBuffer[DUP_BUFFER];      // picture buffer of size 2
+    /*Frame duplication: Two pictures used to compute PSNR */
+    pixel*             m_dupPicOne[3];
+    pixel*             m_dupPicTwo[3];
 
     bool               m_externalFlush;
     /* Collect statistics globally */
@@ -209,7 +230,7 @@ public:
     bool               m_reconfigureRc;
     bool               m_reconfigureZone;
 
-    int               m_saveCtuDistortionLevel;
+    int                m_saveCtuDistortionLevel;
 
     /* Begin intra refresh when one not in progress or else begin one as soon as the current 
      * one is done. Requires bIntraRefresh to be set.*/
@@ -226,11 +247,24 @@ public:
     Lock               m_rpsInSpsLock;
     int                m_rpsInSpsCount;
     /* For HDR*/
-    double                m_cB;
-    double                m_cR;
+    double             m_cB;
+    double             m_cR;
 
-    int                     m_bToneMap; // Enables tone-mapping
-    int                     m_enableNal;
+    int                m_bToneMap; // Enables tone-mapping
+    int                m_enableNal;
+
+    /* For histogram based scene-cut detection */
+    pixel*             m_edgePic;
+    int32_t            m_curUVHist[2][HISTOGRAM_BINS];
+    int32_t            m_curMaxUVHist[HISTOGRAM_BINS];
+    int32_t            m_prevMaxUVHist[HISTOGRAM_BINS];
+    int32_t            m_curEdgeHist[2];
+    int32_t            m_prevEdgeHist[2];
+    uint32_t           m_planeSizes[3];
+    double             m_edgeHistThreshold;
+    double             m_chromaHistThreshold;
+    double             m_scaledEdgeThreshold;
+    double             m_scaledChromaThreshold;
 
 #ifdef ENABLE_HDR10_PLUS
     const hdr10plus_api     *m_hdr10plus_api;
@@ -244,6 +278,8 @@ public:
 
     x265_sei_payload        m_prevTonemapPayload;
 
+    int                     m_zoneIndex;
+
     /* Collect frame level feature data */
     uint64_t*               m_rdCost;
     uint64_t*               m_variance;
@@ -253,6 +289,10 @@ public:
 
     bool                    m_saveCTUSize;
 
+
+    ThreadSafeInteger* zoneReadCount;
+    ThreadSafeInteger* zoneWriteCount;
+
     Encoder();
     ~Encoder()
     {
@@ -318,12 +358,22 @@ public:
 
     void finishFrameStats(Frame* pic, FrameEncoder *curEncoder, x265_frame_stats* frameStats, int inPoc);
 
-    int validateAnalysisData(x265_analysis_data* analysis, int readWriteFlag);
+    int validateAnalysisData(x265_analysis_validate* param, int readWriteFlag);
 
     void readUserSeiFile(x265_sei_payload& seiMsg, int poc);
 
     void calcRefreshInterval(Frame* frameEnc);
 
+    uint64_t computeSSD(pixel *fenc, pixel *rec, intptr_t stride, uint32_t width, uint32_t height, x265_param *param);
+
+    double ComputePSNR(x265_picture *firstPic, x265_picture *secPic, x265_param *param);
+
+    void copyPicture(x265_picture *dest, const x265_picture *src);
+
+    bool computeHistograms(x265_picture *pic);
+    void computeHistogramSAD(double *maxUVNormalizedSAD, double *edgeNormalizedSAD, int curPoc);
+    void findSceneCuts(x265_picture *pic, bool& bDup, double m_maxUVSADVal, double m_edgeSADVal);
+
     void initRefIdx();
     void analyseRefIdx(int *numRefIdx);
     void updateRefIdx();
--- a/source/encoder/entropy.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/encoder/entropy.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
-* Copyright (C) 2013-2017 MulticoreWare, Inc
+* Copyright (C) 2013-2020 MulticoreWare, Inc
 *
 * Authors: Steve Borho <steve@borho.org>
 *          Min Chen <chenm003@163.com>
--- a/source/encoder/entropy.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/encoder/entropy.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
-* Copyright (C) 2013-2017 MulticoreWare, Inc
+* Copyright (C) 2013-2020 MulticoreWare, Inc
 *
 * Authors: Steve Borho <steve@borho.org>
 *          Min Chen <chenm003@163.com>
--- a/source/encoder/frameencoder.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/encoder/frameencoder.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Chung Shin Yee <shinyee@multicorewareinc.com>
  *          Min Chen <chenm003@163.com>
@@ -591,7 +591,7 @@ void FrameEncoder::compressFrame()
 
     /* Clip slice QP to 0-51 spec range before encoding */
     slice->m_sliceQp = x265_clip3(-QP_BD_OFFSET, QP_MAX_SPEC, qp);
-    if (m_param->bHDROpt)
+    if (m_param->bHDR10Opt)
     {
         int qpCb = x265_clip3(-12, 0, (int)floor((m_top->m_cB * ((-.46) * qp + 9.26)) + 0.5 ));
         int qpCr = x265_clip3(-12, 0, (int)floor((m_top->m_cR * ((-.46) * qp + 9.26)) + 0.5 ));
@@ -713,6 +713,8 @@ void FrameEncoder::compressFrame()
                         sei->m_picStruct = (poc & 1) ? 2 /* bottom */ : 1 /* top */;
                 }
             }
+            else if (m_param->bEnableFrameDuplication)
+                sei->m_picStruct = m_frame->m_picStruct;
             else
                 sei->m_picStruct = m_param->pictureStructure;
 
--- a/source/encoder/frameencoder.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/encoder/frameencoder.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Shin Yee <shinyee@multicorewareinc.com>
  *          Min Chen <chenm003@163.com>
--- a/source/encoder/framefilter.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/encoder/framefilter.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Chung Shin Yee <shinyee@multicorewareinc.com>
  *          Min Chen <chenm003@163.com>
@@ -32,7 +32,6 @@
 
 using namespace X265_NS;
 
-static uint64_t computeSSD(pixel *fenc, pixel *rec, intptr_t stride, uint32_t width, uint32_t height);
 static float calculateSSIM(pixel *pix1, intptr_t stride1, pixel *pix2, intptr_t stride2, uint32_t width, uint32_t height, void *buf, uint32_t& cnt);
 
 namespace X265_NS
@@ -673,7 +672,7 @@ void FrameFilter::processPostRow(int row
         uint32_t width  = reconPic->m_picWidth - m_pad[0];
         uint32_t height = m_parallelFilter[row].getCUHeight();
 
-        uint64_t ssdY = computeSSD(fencPic->getLumaAddr(cuAddr), reconPic->getLumaAddr(cuAddr), stride, width, height);
+        uint64_t ssdY = m_frameEncoder->m_top->computeSSD(fencPic->getLumaAddr(cuAddr), reconPic->getLumaAddr(cuAddr), stride, width, height, m_param);
         m_frameEncoder->m_SSDY += ssdY;
 
         if (m_param->internalCsp != X265_CSP_I400)
@@ -682,8 +681,8 @@ void FrameFilter::processPostRow(int row
             width >>= m_hChromaShift;
             stride = reconPic->m_strideC;
 
-            uint64_t ssdU = computeSSD(fencPic->getCbAddr(cuAddr), reconPic->getCbAddr(cuAddr), stride, width, height);
-            uint64_t ssdV = computeSSD(fencPic->getCrAddr(cuAddr), reconPic->getCrAddr(cuAddr), stride, width, height);
+            uint64_t ssdU = m_frameEncoder->m_top->computeSSD(fencPic->getCbAddr(cuAddr), reconPic->getCbAddr(cuAddr), stride, width, height, m_param);
+            uint64_t ssdV = m_frameEncoder->m_top->computeSSD(fencPic->getCrAddr(cuAddr), reconPic->getCrAddr(cuAddr), stride, width, height, m_param);
 
             m_frameEncoder->m_SSDU += ssdU;
             m_frameEncoder->m_SSDV += ssdV;
@@ -825,71 +824,6 @@ void FrameFilter::computeMEIntegral(int 
     }
 }
 
-static uint64_t computeSSD(pixel *fenc, pixel *rec, intptr_t stride, uint32_t width, uint32_t height)
-{
-    uint64_t ssd = 0;
-
-    if ((width | height) & 3)
-    {
-        /* Slow Path */
-        for (uint32_t y = 0; y < height; y++)
-        {
-            for (uint32_t x = 0; x < width; x++)
-            {
-                int diff = (int)(fenc[x] - rec[x]);
-                ssd += diff * diff;
-            }
-
-            fenc += stride;
-            rec += stride;
-        }
-
-        return ssd;
-    }
-
-    uint32_t y = 0;
-
-    /* Consume rows in ever narrower chunks of height */
-    for (int size = BLOCK_64x64; size >= BLOCK_4x4 && y < height; size--)
-    {
-        uint32_t rowHeight = 1 << (size + 2);
-
-        for (; y + rowHeight <= height; y += rowHeight)
-        {
-            uint32_t y1, x = 0;
-
-            /* Consume each row using the largest square blocks possible */
-            if (size == BLOCK_64x64 && !(stride & 31))
-                for (; x + 64 <= width; x += 64)
-                    ssd += primitives.cu[BLOCK_64x64].sse_pp(fenc + x, stride, rec + x, stride);
-
-            if (size >= BLOCK_32x32 && !(stride & 15))
-                for (; x + 32 <= width; x += 32)
-                    for (y1 = 0; y1 + 32 <= rowHeight; y1 += 32)
-                        ssd += primitives.cu[BLOCK_32x32].sse_pp(fenc + y1 * stride + x, stride, rec + y1 * stride + x, stride);
-
-            if (size >= BLOCK_16x16)
-                for (; x + 16 <= width; x += 16)
-                    for (y1 = 0; y1 + 16 <= rowHeight; y1 += 16)
-                        ssd += primitives.cu[BLOCK_16x16].sse_pp(fenc + y1 * stride + x, stride, rec + y1 * stride + x, stride);
-
-            if (size >= BLOCK_8x8)
-                for (; x + 8 <= width; x += 8)
-                    for (y1 = 0; y1 + 8 <= rowHeight; y1 += 8)
-                        ssd += primitives.cu[BLOCK_8x8].sse_pp(fenc + y1 * stride + x, stride, rec + y1 * stride + x, stride);
-
-            for (; x + 4 <= width; x += 4)
-                for (y1 = 0; y1 + 4 <= rowHeight; y1 += 4)
-                    ssd += primitives.cu[BLOCK_4x4].sse_pp(fenc + y1 * stride + x, stride, rec + y1 * stride + x, stride);
-
-            fenc += stride * rowHeight;
-            rec += stride * rowHeight;
-        }
-    }
-
-    return ssd;
-}
-
 /* Function to calculate SSIM for each row */
 static float calculateSSIM(pixel *pix1, intptr_t stride1, pixel *pix2, intptr_t stride2, uint32_t width, uint32_t height, void *buf, uint32_t& cnt)
 {
--- a/source/encoder/framefilter.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/encoder/framefilter.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Chung Shin Yee <shinyee@multicorewareinc.com>
  *          Min Chen <chenm003@163.com>
--- a/source/encoder/level.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/encoder/level.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *          Min Chen <chenm003@163.com>
--- a/source/encoder/level.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/encoder/level.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *
--- a/source/encoder/motion.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/encoder/motion.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *          Min Chen <chenm003@163.com>
--- a/source/encoder/motion.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/encoder/motion.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *          Min Chen <chenm003@163.com>
--- a/source/encoder/nal.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/encoder/nal.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
-* Copyright (C) 2013-2017 MulticoreWare, Inc
+* Copyright (C) 2013-2020 MulticoreWare, Inc
 *
 * Authors: Steve Borho <steve@borho.org>
 *          Min Chen <chenm003@163.com>
--- a/source/encoder/nal.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/encoder/nal.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
-* Copyright (C) 2013-2017 MulticoreWare, Inc
+* Copyright (C) 2013-2020 MulticoreWare, Inc
 *
 * Authors: Steve Borho <steve@borho.org>
 *
--- a/source/encoder/ratecontrol.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/encoder/ratecontrol.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Sumalatha Polureddy <sumalatha@multicorewareinc.com>
  *          Aarthi Priya Thirumalai <aarthi@multicorewareinc.com>
@@ -53,7 +53,7 @@ namespace {
 {\
     bErr = 0;\
     p = strstr(opts, opt "=");\
-    char* q = strstr(opts, "no-" opt);\
+    char* q = strstr(opts, "no-" opt " ");\
     if (p && sscanf(p, opt "=%d" , &i) && param_val != i)\
         bErr = 1;\
     else if (!param_val && !q && !p)\
@@ -146,9 +146,10 @@ x265_zone* RateControl::getZone()
     return NULL;
 }
 
-RateControl::RateControl(x265_param& p)
+RateControl::RateControl(x265_param& p, Encoder *top)
 {
     m_param = &p;
+    m_top = top;
     int lowresCuWidth = ((m_param->sourceWidth / 2) + X265_LOWRES_CU_SIZE - 1) >> X265_LOWRES_CU_BITS;
     int lowresCuHeight = ((m_param->sourceHeight / 2) + X265_LOWRES_CU_SIZE - 1) >> X265_LOWRES_CU_BITS;
     m_ncu = lowresCuWidth * lowresCuHeight;
@@ -156,6 +157,7 @@ RateControl::RateControl(x265_param& p)
     m_qCompress = (m_param->rc.cuTree && !m_param->rc.hevcAq) ? 1 : m_param->rc.qCompress;
 
     // validate for param->rc, maybe it is need to add a function like x265_parameters_valiate()
+    m_zoneBufferIdx = 0;
     m_residualFrames = 0;
     m_partialResidualFrames = 0;
     m_residualCost = 0;
@@ -171,6 +173,8 @@ RateControl::RateControl(x265_param& p)
     m_lastPredictorReset = 0;
     m_avgPFrameQp = 0;
     m_isFirstMiniGop = false;
+    m_lastScenecut = -1;
+    m_lastScenecutAwareIFrame = -1;
     if (m_param->rc.rateControlMode == X265_RC_CRF)
     {
         m_param->rc.qp = (int)m_param->rc.rfConstant;
@@ -210,6 +214,7 @@ RateControl::RateControl(x265_param& p)
     m_lastBsliceSatdCost = 0;
     m_movingAvgSum = 0.0;
     m_isNextGop = false;
+    m_relativeComplexity = NULL;
 
     // vbv initialization
     m_param->rc.vbvBufferSize = x265_clip3(0, 2000000, m_param->rc.vbvBufferSize);
@@ -354,6 +359,16 @@ bool RateControl::init(const SPS& sps)
         m_initVbv = true;
     }
 
+    if (!m_param->bResetZoneConfig && (m_relativeComplexity == NULL))
+    {
+        m_relativeComplexity = X265_MALLOC(double, m_param->reconfigWindowSize);
+        if (m_relativeComplexity == NULL)
+        {
+            x265_log(m_param, X265_LOG_ERROR, "Failed to allocate memory for m_relativeComplexity\n");
+            return false;
+        }
+    }
+
     m_totalBits = 0;
     m_encodedBits = 0;
     m_framesDone = 0;
@@ -699,6 +714,8 @@ void RateControl::reconfigureRC()
     {
         m_param->rc.vbvBufferSize = x265_clip3(0, 2000000, m_param->rc.vbvBufferSize);
         m_param->rc.vbvMaxBitrate = x265_clip3(0, 2000000, m_param->rc.vbvMaxBitrate);
+        if (m_param->reconfigWindowSize)
+            m_param->rc.vbvMaxBitrate = (int)(m_param->rc.vbvMaxBitrate * (double)(m_fps / m_param->reconfigWindowSize));
         if (m_param->rc.vbvMaxBitrate < m_param->rc.bitrate &&
             m_param->rc.rateControlMode == X265_RC_ABR)
         {
@@ -753,7 +770,7 @@ void RateControl::reconfigureRC()
             m_qpConstant[P_SLICE] = m_qpConstant[I_SLICE] = m_qpConstant[B_SLICE] = m_qp;
         }
     }
-    m_bitrate = m_param->rc.bitrate * 1000;
+    m_bitrate = (double)m_param->rc.bitrate * 1000;
 }
 
 void RateControl::initHRD(SPS& sps)
@@ -1183,6 +1200,7 @@ int RateControl::rateControlSliceType(in
             m_param->rc.bStatRead = 0;
             m_param->bFrameAdaptive = 0;
             m_param->scenecutThreshold = 0;
+            m_param->bHistBasedSceneCut = 0;
             m_param->rc.cuTree = 0;
             if (m_param->bframes > 1)
                 m_param->bframes = 1;
@@ -1244,16 +1262,43 @@ int RateControl::rateControlStart(Frame*
     m_predType = getPredictorType(curFrame->m_lowres.sliceType, m_sliceType);
     rce->poc = m_curSlice->m_poc;
 
-    /* change ratecontrol stats for next zone if specified */
-    for (int i = 0; i < m_param->rc.zonefileCount; i++)
+    if (!m_param->bResetZoneConfig && (rce->encodeOrder % m_param->reconfigWindowSize == 0))
     {
-        if (m_param->rc.zones[i].startFrame == curFrame->m_encodeOrder)
+        int index = m_zoneBufferIdx % m_param->rc.zonefileCount;
+        int read = m_top->zoneReadCount[index].get();
+        int write = m_top->zoneWriteCount[index].get();
+        if (write <= read)
+            write = m_top->zoneWriteCount[index].waitForChange(write);
+        m_zoneBufferIdx++;
+
+        for (int i = 0; i < m_param->rc.zonefileCount; i++)
         {
-            m_param = m_param->rc.zones[i].zoneParam;
-            reconfigureRC();
-            init(*m_curSlice->m_sps);
+            if (m_param->rc.zones[i].startFrame == rce->encodeOrder)
+            {
+                m_param->rc.bitrate = m_param->rc.zones[i].zoneParam->rc.bitrate;
+                m_param->rc.vbvMaxBitrate = m_param->rc.zones[i].zoneParam->rc.vbvMaxBitrate;
+                memcpy(m_relativeComplexity, m_param->rc.zones[i].relativeComplexity, sizeof(double) * m_param->reconfigWindowSize);
+                reconfigureRC();
+                m_top->zoneReadCount[i].incr();
+            }
         }
     }
+    
+    
+    if (m_param->bResetZoneConfig)
+    {
+        /* change ratecontrol stats for next zone if specified */
+        for (int i = 0; i < m_param->rc.zonefileCount; i++)
+        {
+            if (m_param->rc.zones[i].startFrame == curFrame->m_encodeOrder)
+            {
+                m_param = m_param->rc.zones[i].zoneParam;
+                reconfigureRC();
+                init(*m_curSlice->m_sps);
+            }
+        }
+    }
+
     if (m_param->rc.bStatRead)
     {
         X265_CHECK(rce->poc >= 0 && rce->poc < m_numEntries, "bad encode ordinal\n");
@@ -1648,6 +1693,31 @@ double RateControl::tuneAbrQScaleFromFee
     return qScale;
 }
 
+double RateControl::tuneQScaleForZone(RateControlEntry *rce, double qScale)
+{
+    rce->frameSizePlanned = predictSize(&m_pred[m_predType], qScale, (double)m_currentSatd);
+    int loop = 0;
+
+    double availableBits = (double)m_param->rc.bitrate * 1000 * m_relativeComplexity[rce->encodeOrder % m_param->reconfigWindowSize];
+
+    // Tune qScale to adhere to the available frame bits.
+    for (int i = 0; i < 1000 && loop != 3; i++)
+    {
+        if (rce->frameSizePlanned < availableBits)
+        {
+            qScale = qScale / 1.01;
+            loop = loop | 1;
+        }
+        else if (rce->frameSizePlanned > availableBits)
+        {
+            qScale = qScale * 1.01;
+            loop = loop | 2;
+        }
+        rce->frameSizePlanned = predictSize(&m_pred[m_predType], qScale, (double)m_currentSatd);
+    }
+    return qScale;
+}
+
 double RateControl::tuneQScaleForGrain(double rcOverflow)
 {
     double qpstep = rcOverflow > 1.1 ? rcOverflow : m_lstep;
@@ -1776,6 +1846,16 @@ double RateControl::rateEstimateQscale(F
             }
             rce->qpNoVbv = q;
         }
+        /* Scenecut Aware QP offsets*/
+        if (m_param->bEnableSceneCutAwareQp)
+        {
+            double lqmin = m_lmin[m_sliceType];
+            double lqmax = m_lmax[m_sliceType];
+            qScale = scenecutAwareQp(curFrame, qScale);
+            qScale = x265_clip3(lqmin, lqmax, qScale);
+            q = x265_qScale2qp(qScale);
+            rce->qpNoVbv = q;
+        }
         if (m_isVbv)
         {
             lmin = m_lastQScaleFor[P_SLICE] / m_lstep;
@@ -1788,11 +1868,21 @@ double RateControl::rateEstimateQscale(F
                     qScale = x265_clip3(lmin, lmax, qScale);
                 q = x265_qScale2qp(qScale);
             }
+
+            if (!m_param->bResetZoneConfig)
+            {
+                double lqmin = m_lmin[m_sliceType];
+                double lqmax = m_lmax[m_sliceType];
+                qScale = tuneQScaleForZone(rce, qScale);
+                qScale = x265_clip3(lqmin, lqmax, qScale);
+            }
+
             if (!m_2pass)
             {
-                qScale = clipQscale(curFrame, rce, qScale);
                 /* clip qp to permissible range after vbv-lookahead estimation to avoid possible 
                  * mispredictions by initial frame size predictors */
+                qScale = clipQscale(curFrame, rce, qScale);
+
                 if (m_pred[m_predType].count == 1)
                     qScale = x265_clip3(lmin, lmax, qScale);
                 m_lastQScaleFor[m_sliceType] = qScale;
@@ -2014,7 +2104,29 @@ double RateControl::rateEstimateQscale(F
                 m_avgPFrameQp = m_avgPFrameQp == 0 ? rce->qpNoVbv : m_avgPFrameQp;
                 m_avgPFrameQp = (m_avgPFrameQp + rce->qpNoVbv) / 2;
             }
+
+            if (!m_param->bResetZoneConfig)
+            {
+                q = tuneQScaleForZone(rce, q);
+                q = x265_clip3(lqmin, lqmax, q);
+            }
+            /* Scenecut Aware QP offsets*/
+            if (m_param->bEnableSceneCutAwareQp)
+            {
+                double qmin = m_lmin[m_sliceType];
+                double qmax = m_lmax[m_sliceType];
+                q = scenecutAwareQp(curFrame, q);
+                q = x265_clip3(qmin, qmax, q);
+                rce->qpNoVbv = x265_qScale2qp(q);
+            }
             q = clipQscale(curFrame, rce, q);
+
+
+            if (m_2pass)
+                rce->frameSizePlanned = qScale2bits(rce, q);
+            else
+                rce->frameSizePlanned = predictSize(&m_pred[m_predType], q, (double)m_currentSatd);
+
             /*  clip qp to permissible range after vbv-lookahead estimation to avoid possible
              * mispredictions by initial frame size predictors, after each scenecut */
             bool isFrameAfterScenecut = m_sliceType!= I_SLICE && m_curSlice->m_refFrameList[0][0]->m_lowres.bScenecut;
@@ -2173,7 +2285,7 @@ double RateControl::clipQscale(Frame* cu
     if (m_isVbv && m_currentSatd > 0 && curFrame)
     {
         if (m_param->lookaheadDepth || m_param->rc.cuTree ||
-            m_param->scenecutThreshold ||
+            (m_param->scenecutThreshold || m_param->bHistBasedSceneCut) ||
             (m_param->bFrameAdaptive && m_param->bframes))
         {
            /* Lookahead VBV: If lookahead is done, raise the quantizer as necessary
@@ -2193,7 +2305,8 @@ double RateControl::clipQscale(Frame* cu
                 frameQ[B_SLICE] = frameQ[P_SLICE] * m_param->rc.pbFactor;
                 frameQ[I_SLICE] = frameQ[P_SLICE] / m_param->rc.ipFactor;
                 /* Loop over the planned future frames. */
-                for (int j = 0; bufferFillCur >= 0; j++)
+                bool iter = true;
+                for (int j = 0; bufferFillCur >= 0 && iter ; j++)
                 {
                     int type = curFrame->m_lowres.plannedType[j];
                     if (type == X265_TYPE_AUTO || totalDuration >= 1.0)
@@ -2207,6 +2320,8 @@ double RateControl::clipQscale(Frame* cu
                     int predType = getPredictorType(curFrame->m_lowres.plannedType[j], type);
                     curBits = predictSize(&m_pred[predType], frameQ[type], (double)satd);
                     bufferFillCur -= curBits;
+                    if (!m_param->bResetZoneConfig && ((uint64_t)j == (m_param->reconfigWindowSize - 1)))
+                        iter = false;
                 }
                 if (rce->vbvEndAdj)
                 {
@@ -2976,6 +3091,9 @@ void RateControl::destroy()
     X265_FREE(m_encOrder);
     for (int i = 0; i < 2; i++)
         X265_FREE(m_cuTreeStats.qpBuffer[i]);
+    
+    if (m_relativeComplexity)
+        X265_FREE(m_relativeComplexity);
 
 }
 
@@ -3024,3 +3142,52 @@ void RateControl::splitbUsed(char bused[
         buf = strstr(src, "~");
     }
 }
+
+double RateControl::scenecutAwareQp(Frame* curFrame, double q)
+{
+    uint32_t maxWindowSize = uint32_t((m_param->scenecutWindow / 1000.0) * (m_param->fpsNum / m_param->fpsDenom) + 0.5);
+    uint32_t windowSize = maxWindowSize / 3;
+    int lastScenecut = m_top->m_rateControl->m_lastScenecut;
+    int lastIFrame = m_top->m_rateControl->m_lastScenecutAwareIFrame;
+    double maxQpDelta = x265_qp2qScale(double(m_param->maxQpDelta));
+    double iSliceDelta = x265_qp2qScale(double(I_SLICE_DELTA));
+    double sliceTypeDelta = SLICE_TYPE_DELTA * maxQpDelta;
+    double window2Delta = WINDOW2_DELTA * maxQpDelta;
+    double window3Delta = WINDOW3_DELTA * maxQpDelta;
+
+    bool isFrameInsideWindow = curFrame->m_poc > lastScenecut && curFrame->m_poc <= (lastScenecut + int(maxWindowSize));
+
+    if (isFrameInsideWindow && IS_X265_TYPE_I(curFrame->m_lowres.sliceType))
+    {
+        m_top->m_rateControl->m_lastScenecutAwareIFrame = curFrame->m_poc;
+    }
+    else if (isFrameInsideWindow && (curFrame->m_lowres.sliceType == X265_TYPE_P))
+    {
+        if (!(lastIFrame > lastScenecut && lastIFrame <= (lastScenecut + int(maxWindowSize))
+            && curFrame->m_poc > lastIFrame))
+        {
+            q += maxQpDelta - sliceTypeDelta;
+            if (((curFrame->m_poc) > (lastScenecut + int(windowSize))) && ((curFrame->m_poc) <= (lastScenecut + 2 * int(windowSize))))
+                q -= window2Delta;
+            else if (curFrame->m_poc > lastScenecut + 2 * int(windowSize))
+                q -= window3Delta;
+        }
+    }
+    else if (isFrameInsideWindow && IS_X265_TYPE_B(curFrame->m_lowres.sliceType))
+    {
+        if (!(lastIFrame > lastScenecut && lastIFrame <= (lastScenecut + int(maxWindowSize))
+            && curFrame->m_poc > lastIFrame))
+        {
+            q += maxQpDelta;
+            if (curFrame->m_lowres.sliceType == X265_TYPE_B)
+                q += sliceTypeDelta;
+            if (((curFrame->m_poc) > (lastScenecut + int(windowSize))) && ((curFrame->m_poc) <= (lastScenecut + 2 * int(windowSize))))
+                q -= window2Delta;
+            else if (curFrame->m_poc > lastScenecut + 2 * int(windowSize))
+                q -= window3Delta;
+        }
+    }
+    if (IS_X265_TYPE_I(curFrame->m_lowres.sliceType) && curFrame->m_lowres.bScenecut)
+        q = q - iSliceDelta;
+    return q;
+}
--- a/source/encoder/ratecontrol.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/encoder/ratecontrol.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Sumalatha Polureddy <sumalatha@multicorewareinc.com>
  *          Aarthi Priya Thirumalai <aarthi@multicorewareinc.com>
@@ -46,6 +46,13 @@ struct SPS;
 #define MIN_AMORTIZE_FRACTION 0.2
 #define CLIP_DURATION(f) x265_clip3(MIN_FRAME_DURATION, MAX_FRAME_DURATION, f)
 
+/*Scenecut Aware QP*/
+#define I_SLICE_DELTA           2   /* Subtracted from base QP for the scenecut I frames*/
+#define SLICE_TYPE_DELTA        0.3 /* The offset decremented or incremented for P-frames or b-frames respectively*/
+#define WINDOW1_DELTA           0   /* The offset for the frames coming in the window-1*/
+#define WINDOW2_DELTA           0.3 /* The offset for the frames coming in the window-2*/
+#define WINDOW3_DELTA           0.6 /* The offset for the frames coming in the window-3*/
+
 struct Predictor
 {
     double coeffMin;
@@ -128,6 +135,10 @@ public:
     int         m_ncu;           /* number of CUs in a frame */
     int         m_qp;            /* updated qp for current frame */
 
+    /*Zone reconfiguration*/
+    double*     m_relativeComplexity;
+    int         m_zoneBufferIdx;
+
     bool   m_isAbr;
     bool   m_isVbv;
     bool   m_isCbr;
@@ -138,6 +149,8 @@ public:
     bool   m_initVbv;
     int    m_lastAbrResetPoc;
 
+    int    m_lastScenecut;
+    int    m_lastScenecutAwareIFrame;
     double m_rateTolerance;
     double m_frameDuration;     /* current frame duration in seconds */
     double m_bitrate;
@@ -228,6 +241,8 @@ public:
     int64_t m_predictedBits;
     int     *m_encOrder;
     RateControlEntry* m_rce2Pass;
+    Encoder* m_top;
+
     struct
     {
         uint16_t *qpBuffer[2]; /* Global buffers for converting MB-tree quantizer data. */
@@ -235,7 +250,7 @@ public:
                                 * This value is the current position (0 or 1). */
     } m_cuTreeStats;
 
-    RateControl(x265_param& p);
+    RateControl(x265_param& p, Encoder *enc);
     bool init(const SPS& sps);
     void initHRD(SPS& sps);
     void reconfigureRC();
@@ -255,6 +270,8 @@ public:
     int writeRateControlFrameStats(Frame* curFrame, RateControlEntry* rce);
     bool   initPass2();
 
+    double scenecutAwareQp(Frame* curFrame, double q);
+
 protected:
 
     static const int   s_slidingWindowFrames;
@@ -271,6 +288,7 @@ protected:
     double getQScale(RateControlEntry *rce, double rateFactor);
     double rateEstimateQscale(Frame* pic, RateControlEntry *rce); // main logic for calculating QP based on ABR
     double tuneAbrQScaleFromFeedback(double qScale);
+    double tuneQScaleForZone(RateControlEntry *rce, double qScale); // Tune qScale to adhere to zone budget
     void   accumPQpUpdate();
 
     int    getPredictorType(int lowresSliceType, int sliceType);
--- a/source/encoder/rdcost.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/encoder/rdcost.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
-* Copyright (C) 2013-2017 MulticoreWare, Inc
+* Copyright (C) 2013-2020 MulticoreWare, Inc
 *
 * Authors: Steve Borho <steve@borho.org>
 *          Min Chen <chenm003@163.com>
--- a/source/encoder/reference.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/encoder/reference.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *          Deepthi Devaki <deepthidevaki@multicorewareinc.com>
--- a/source/encoder/reference.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/encoder/reference.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *          Min Chen <chenm003@163.com>
--- a/source/encoder/sao.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/encoder/sao.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *          Min Chen <chenm003@163.com>
--- a/source/encoder/sao.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/encoder/sao.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *          Min Chen <chenm003@163.com>
--- a/source/encoder/search.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/encoder/search.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
-* Copyright (C) 2013-2017 MulticoreWare, Inc
+* Copyright (C) 2013-2020 MulticoreWare, Inc
 *
 * Authors: Steve Borho <steve@borho.org>
 *          Min Chen <chenm003@163.com>
@@ -2156,14 +2156,17 @@ void Search::searchMV(Mode& interMode, i
 {
     CUData& cu = interMode.cu;
     MV mv, mvmin, mvmax;
-    cu.clipMv(mv);
     int cand = 0, bestcost = INT_MAX;
-    do
+    while (cand < m_param->mvRefine)
     {
-        if (cand && (mvp[cand] == mvp[cand - 1] || (cand == 2 && mvp[cand] == mvp[cand - 2])))
+        if ((cand && mvp[cand] == mvp[cand - 1]) || (cand == 2 && (mvp[cand] == mvp[cand - 2] || mvp[cand] == mvp[cand - 1])))
+        {
+            cand++;
             continue;
+        }
         MV bestMV;
-        mv = mvp[cand];
+        mv = mvp[cand++];
+        cu.clipMv(mv);
         setSearchRange(cu, mv, m_param->searchRange, mvmin, mvmax);
         int cost = m_me.motionEstimate(&m_slice->m_mref[list][ref], mvmin, mvmax, mv, numMvc, mvc, m_param->searchRange, bestMV, m_param->maxSlices,
         m_param->bSourceReferenceEstimation ? m_slice->m_refFrameList[list][ref]->m_fencPic->getLumaAddr(0) : 0);
@@ -2172,7 +2175,7 @@ void Search::searchMV(Mode& interMode, i
             bestcost = cost;
             outmv = bestMV;
         }
-    }while (++cand < m_param->mvRefine);
+    }
 }
 /* find the best inter prediction for each PU of specified mode */
 void Search::predInterSearch(Mode& interMode, const CUGeom& cuGeom, bool bChromaMC, uint32_t refMasks[2])
@@ -2205,7 +2208,7 @@ void Search::predInterSearch(Mode& inter
         x265_analysis_inter_data* interDataCTU = NULL;
         int cuIdx;
         cuIdx = (interMode.cu.m_cuAddr * m_param->num4x4Partitions) + cuGeom.absPartIdx;
-        if (m_param->analysisReuseLevel == 10 && m_param->interRefine > 1)
+        if (m_param->analysisLoadReuseLevel == 10 && m_param->interRefine > 1)
         {
             interDataCTU = m_frame->m_analysisData.interData;
             if ((cu.m_predMode[pu.puAbsPartIdx] == interDataCTU->modes[cuIdx + pu.puAbsPartIdx])
@@ -2224,7 +2227,7 @@ void Search::predInterSearch(Mode& inter
 
         cu.getNeighbourMV(puIdx, pu.puAbsPartIdx, interMode.interNeighbours);
         /* Uni-directional prediction */
-        if ((m_param->analysisLoad && m_param->analysisReuseLevel > 1 && m_param->analysisReuseLevel != 10)
+        if ((m_param->analysisLoadReuseLevel > 1 && m_param->analysisLoadReuseLevel != 10)
             || (m_param->analysisMultiPassRefine && m_param->rc.bStatRead) || (m_param->bAnalysisType == AVC_INFO) || (useAsMVP))
         {
             for (int list = 0; list < numPredDir; list++)
@@ -2246,7 +2249,13 @@ void Search::predInterSearch(Mode& inter
                 const MV* amvp = interMode.amvpCand[list][ref];
                 int mvpIdx = selectMVP(cu, pu, amvp, list, ref);
                 MV mvmin, mvmax, outmv, mvp;
-                mvp = amvp[mvpIdx];
+                if (useAsMVP)
+                {
+                    mvp = interDataCTU->mv[list][cuIdx + puIdx].word;
+                    mvpIdx = interDataCTU->mvpIdx[list][cuIdx + puIdx];
+                }
+                else
+                    mvp = amvp[mvpIdx];
                 if (m_param->searchMethod == X265_SEA)
                 {
                     int puX = puIdx & 1;
@@ -2259,28 +2268,26 @@ void Search::predInterSearch(Mode& inter
                 int satdCost;
                 if (m_param->analysisMultiPassRefine && m_param->rc.bStatRead && mvpIdx == bestME[list].mvpIdx)
                     mvpIn = bestME[list].mv;
-                if (useAsMVP)
+                if (useAsMVP && m_param->mvRefine > 1)
                 {
                     MV bestmv, mvpSel[3];
                     int mvpIdxSel[3];
                     satdCost = m_me.COST_MAX;
-                    mvpSel[0] = interDataCTU->mv[list][cuIdx + puIdx].word;
-                    mvpIdxSel[0] = interDataCTU->mvpIdx[list][cuIdx + puIdx];
-                    if (m_param->mvRefine > 1)
+                    mvpSel[0] = mvp;
+                    mvpIdxSel[0] = mvpIdx;
+                    mvpIdx = selectMVP(cu, pu, amvp, list, ref);
+                    mvpSel[1] = interMode.amvpCand[list][ref][mvpIdx];
+                    mvpIdxSel[1] = mvpIdx;
+                    if (m_param->mvRefine > 2)
                     {
-                        mvpSel[1] = interMode.amvpCand[list][ref][mvpIdx];
-                        mvpIdxSel[1] = mvpIdx;
-                        if (m_param->mvRefine > 2)
-                        {
-                            mvpSel[2] = interMode.amvpCand[list][ref][!mvpIdx];
-                            mvpIdxSel[2] = !mvpIdx;
-                        }
+                        mvpSel[2] = interMode.amvpCand[list][ref][!mvpIdx];
+                        mvpIdxSel[2] = !mvpIdx;
                     }
                     for (int cand = 0; cand < m_param->mvRefine; cand++)
                     {
                         if (cand && (mvpSel[cand] == mvpSel[cand - 1] || (cand == 2 && mvpSel[cand] == mvpSel[cand - 2])))
                             continue;
-                        setSearchRange(cu, mvp, m_param->searchRange, mvmin, mvmax);
+                        setSearchRange(cu, mvpSel[cand], m_param->searchRange, mvmin, mvmax);
                         int bcost = m_me.motionEstimate(&m_slice->m_mref[list][ref], mvmin, mvmax, mvpSel[cand], numMvc, mvc, m_param->searchRange, bestmv, m_param->maxSlices,
                             m_param->bSourceReferenceEstimation ? m_slice->m_refFrameList[list][ref]->m_fencPic->getLumaAddr(0) : 0);
                         if (satdCost > bcost)
@@ -2291,6 +2298,7 @@ void Search::predInterSearch(Mode& inter
                             mvpIdx = mvpIdxSel[cand];
                         }
                     }
+                    mvpIn = mvp;
                 }
                 else
                 {
--- a/source/encoder/search.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/encoder/search.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
-* Copyright (C) 2013-2017 MulticoreWare, Inc
+* Copyright (C) 2013-2020 MulticoreWare, Inc
 *
 * Authors: Steve Borho <steve@borho.org>
 *          Min Chen <chenm003@163.com>
--- a/source/encoder/sei.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/encoder/sei.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
-* Copyright (C) 2013-2017 MulticoreWare, Inc
+* Copyright (C) 2013-2020 MulticoreWare, Inc
 *
 * Authors: Steve Borho <steve@borho.org>
 *
--- a/source/encoder/sei.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/encoder/sei.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
-* Copyright (C) 2013-2017 MulticoreWare, Inc
+* Copyright (C) 2013-2020 MulticoreWare, Inc
 *
 * Authors: Steve Borho <steve@borho.org>
 *
--- a/source/encoder/slicetype.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/encoder/slicetype.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Gopu Govindaswamy <gopu@multicorewareinc.com>
  *          Steve Borho <steve@borho.org>
@@ -85,12 +85,85 @@ inline uint32_t acEnergyPlane(Frame *cur
 
 } // end anonymous namespace
 
-void edgeFilter(Frame *curFrame, pixel *pic1, pixel *pic2, pixel *pic3, intptr_t stride, int height, int width)
+namespace X265_NS {
+
+bool computeEdge(pixel *edgePic, pixel *refPic, pixel *edgeTheta, intptr_t stride, int height, int width, bool bcalcTheta)
 {
+    intptr_t rowOne = 0, rowTwo = 0, rowThree = 0, colOne = 0, colTwo = 0, colThree = 0;
+    intptr_t middle = 0, topLeft = 0, topRight = 0, bottomLeft = 0, bottomRight = 0;
+
+    const int startIndex = 1;
+
+    if (!edgePic || !refPic || (!edgeTheta && bcalcTheta))
+    {
+        return false;
+    }
+    else
+    {
+        float gradientH = 0, gradientV = 0, radians = 0, theta = 0;
+        float gradientMagnitude = 0;
+        pixel blackPixel = 0;
+
+        //Applying Sobel filter expect for border pixels
+        height = height - startIndex;
+        width = width - startIndex;
+        for (int rowNum = startIndex; rowNum < height; rowNum++)
+        {
+            rowTwo = rowNum * stride;
+            rowOne = rowTwo - stride;
+            rowThree = rowTwo + stride;
+
+            for (int colNum = startIndex; colNum < width; colNum++)
+            {
+
+                 /*  Horizontal and vertical gradients
+                     [ -3   0   3 ]        [-3   -10  -3 ]
+                 gH =[ -10  0   10]   gV = [ 0    0    0 ]
+                     [ -3   0   3 ]        [ 3    10   3 ] */
+
+                colTwo = colNum;
+                colOne = colTwo - startIndex;
+                colThree = colTwo + startIndex;
+                middle = rowTwo + colTwo;
+                topLeft = rowOne + colOne;
+                topRight = rowOne + colThree;
+                bottomLeft = rowThree + colOne;
+                bottomRight = rowThree + colThree;
+                gradientH = (float)(-3 * refPic[topLeft] + 3 * refPic[topRight] - 10 * refPic[rowTwo + colOne] + 10 * refPic[rowTwo + colThree] - 3 * refPic[bottomLeft] + 3 * refPic[bottomRight]);
+                gradientV = (float)(-3 * refPic[topLeft] - 10 * refPic[rowOne + colTwo] - 3 * refPic[topRight] + 3 * refPic[bottomLeft] + 10 * refPic[rowThree + colTwo] + 3 * refPic[bottomRight]);
+                gradientMagnitude = sqrtf(gradientH * gradientH + gradientV * gradientV);
+                if(bcalcTheta) 
+                {
+                    edgeTheta[middle] = 0;
+                    radians = atan2(gradientV, gradientH);
+                    theta = (float)((radians * 180) / PI);
+                    if (theta < 0)
+                       theta = 180 + theta;
+                    edgeTheta[middle] = (pixel)theta;
+                }
+                edgePic[middle] = (pixel)(gradientMagnitude >= edgeThreshold ? edgeThreshold : blackPixel);
+            }
+        }
+        return true;
+    }
+}
+
+void edgeFilter(Frame *curFrame, x265_param* param)
+{
+    int height = curFrame->m_fencPic->m_picHeight;
+    int width = curFrame->m_fencPic->m_picWidth;
+    intptr_t stride = curFrame->m_fencPic->m_stride;
+    uint32_t numCuInHeight = (height + param->maxCUSize - 1) / param->maxCUSize;
+    int maxHeight = numCuInHeight * param->maxCUSize;
+
+    memset(curFrame->m_edgePic, 0, stride * (maxHeight + (curFrame->m_fencPic->m_lumaMarginY * 2)) * sizeof(pixel));
+    memset(curFrame->m_gaussianPic, 0, stride * (maxHeight + (curFrame->m_fencPic->m_lumaMarginY * 2)) * sizeof(pixel));
+    memset(curFrame->m_thetaPic, 0, stride * (maxHeight + (curFrame->m_fencPic->m_lumaMarginY * 2)) * sizeof(pixel));
+
     pixel *src = (pixel*)curFrame->m_fencPic->m_picOrg[0];
-    pixel *edgePic = pic1 + curFrame->m_fencPic->m_lumaMarginY * stride + curFrame->m_fencPic->m_lumaMarginX;
-    pixel *refPic = pic2 + curFrame->m_fencPic->m_lumaMarginY * stride + curFrame->m_fencPic->m_lumaMarginX;
-    pixel *edgeTheta = pic3 + curFrame->m_fencPic->m_lumaMarginY * stride + curFrame->m_fencPic->m_lumaMarginX;
+    pixel *edgePic = curFrame->m_edgePic + curFrame->m_fencPic->m_lumaMarginY * stride + curFrame->m_fencPic->m_lumaMarginX;
+    pixel *refPic = curFrame->m_gaussianPic + curFrame->m_fencPic->m_lumaMarginY * stride + curFrame->m_fencPic->m_lumaMarginX;
+    pixel *edgeTheta = curFrame->m_thetaPic + curFrame->m_fencPic->m_lumaMarginY * stride + curFrame->m_fencPic->m_lumaMarginX;
 
     for (int i = 0; i < height; i++)
     {
@@ -103,7 +176,8 @@ void edgeFilter(Frame *curFrame, pixel *
 
     //Applying Gaussian filter on the picture
     src = (pixel*)curFrame->m_fencPic->m_picOrg[0];
-    refPic = pic2 + curFrame->m_fencPic->m_lumaMarginY * stride + curFrame->m_fencPic->m_lumaMarginX;
+    refPic = curFrame->m_gaussianPic + curFrame->m_fencPic->m_lumaMarginY * stride + curFrame->m_fencPic->m_lumaMarginX;
+    edgePic = curFrame->m_edgePic + curFrame->m_fencPic->m_lumaMarginY * stride + curFrame->m_fencPic->m_lumaMarginX;
     pixel pixelValue = 0;
 
     for (int rowNum = 0; rowNum < height; rowNum++)
@@ -136,51 +210,8 @@ void edgeFilter(Frame *curFrame, pixel *
         }
     }
 
-#if HIGH_BIT_DEPTH //10-bit build
-    float threshold = 1023;
-    pixel whitePixel = 1023;
-#else
-    float threshold = 255;
-    pixel whitePixel = 255;
-#endif
-#define PI 3.14159265 
-
-    float gradientH = 0, gradientV = 0, radians = 0, theta = 0;
-    float gradientMagnitude = 0;
-    pixel blackPixel = 0;
-    edgePic = pic1 + curFrame->m_fencPic->m_lumaMarginY * stride + curFrame->m_fencPic->m_lumaMarginX;
-    //Applying Sobel filter on the gaussian filtered picture
-    for (int rowNum = 0; rowNum < height; rowNum++)
-    {
-        for (int colNum = 0; colNum < width; colNum++)
-        {
-            edgeTheta[(rowNum*stride) + colNum] = 0;
-            if ((rowNum != 0) && (colNum != 0) && (rowNum != height - 1) && (colNum != width - 1)) //Ignoring the border pixels of the picture
-            {
-                /*Horizontal and vertical gradients
-                       [ -3   0   3 ]        [-3   -10  -3 ]
-                  gH = [ -10  0   10]   gV = [ 0    0    0 ]
-                       [ -3   0   3 ]        [ 3    10   3 ]*/
-
-                const intptr_t rowOne = (rowNum - 1)*stride, colOne = colNum -1;
-                const intptr_t rowTwo = rowNum * stride, colTwo = colNum;
-                const intptr_t rowThree = (rowNum + 1)*stride, colThree = colNum + 1;
-                const intptr_t index = (rowNum*stride) + colNum;
-
-                gradientH = (float)(-3 * refPic[rowOne + colOne] + 3 * refPic[rowOne + colThree] - 10 * refPic[rowTwo + colOne] + 10 * refPic[rowTwo + colThree] - 3 * refPic[rowThree + colOne] + 3 * refPic[rowThree + colThree]);
-                gradientV = (float)(-3 * refPic[rowOne + colOne] - 10 * refPic[rowOne + colTwo] - 3 * refPic[rowOne + colThree] + 3 * refPic[rowThree + colOne] + 10 * refPic[rowThree + colTwo] + 3 * refPic[rowThree + colThree]);
-
-                gradientMagnitude = sqrtf(gradientH * gradientH + gradientV * gradientV);
-                radians = atan2(gradientV, gradientH);
-                theta = (float)((radians * 180) / PI);
-                if (theta < 0)
-                    theta = 180 + theta;
-                edgeTheta[(rowNum*stride) + colNum] = (pixel)theta;
-
-                edgePic[index] = gradientMagnitude >= threshold ? whitePixel : blackPixel;
-            }
-        }
-    }
+    if(!computeEdge(edgePic, refPic, edgeTheta, stride, height, width, true))
+        x265_log(NULL, X265_LOG_ERROR, "Failed edge computation!");
 }
 
 //Find the angle of a block by averaging the pixel angles 
@@ -198,8 +229,10 @@ inline void findAvgAngle(const pixel* bl
     angle = sum / (size*size);
 }
 
-uint32_t LookaheadTLD::edgeDensityCu(Frame* curFrame,pixel *edgeImage, pixel *edgeTheta, uint32_t &avgAngle, uint32_t blockX, uint32_t blockY, uint32_t qgSize)
+uint32_t LookaheadTLD::edgeDensityCu(Frame* curFrame, uint32_t &avgAngle, uint32_t blockX, uint32_t blockY, uint32_t qgSize)
 {
+    pixel *edgeImage = curFrame->m_edgePic + curFrame->m_fencPic->m_lumaMarginY * curFrame->m_fencPic->m_stride + curFrame->m_fencPic->m_lumaMarginX;
+    pixel *edgeTheta = curFrame->m_thetaPic + curFrame->m_fencPic->m_lumaMarginY * curFrame->m_fencPic->m_stride + curFrame->m_fencPic->m_lumaMarginX;
     intptr_t srcStride = curFrame->m_fencPic->m_stride;
     intptr_t blockOffsetLuma = blockX + (blockY * srcStride);
     int plane = 0; // Sobel filter is applied only on Y component
@@ -478,24 +511,14 @@ void LookaheadTLD::calcAdaptiveQuantFram
             }
             else
             {
-#define AQ_EDGE_BIAS 0.5
-#define EDGE_INCLINATION 45
-                uint32_t numCuInHeight = (maxRow + param->maxCUSize - 1) / param->maxCUSize;
-                int maxHeight = numCuInHeight * param->maxCUSize;
-                intptr_t stride = curFrame->m_fencPic->m_stride;
-                pixel *edgePic = X265_MALLOC(pixel, stride * (maxHeight + (curFrame->m_fencPic->m_lumaMarginY * 2)));
-                pixel *gaussianPic = X265_MALLOC(pixel, stride * (maxHeight + (curFrame->m_fencPic->m_lumaMarginY * 2)));
-                pixel *thetaPic = X265_MALLOC(pixel, stride * (maxHeight + (curFrame->m_fencPic->m_lumaMarginY * 2)));
-                memset(edgePic, 0, stride * (maxHeight + (curFrame->m_fencPic->m_lumaMarginY * 2)) * sizeof(pixel));
-                memset(gaussianPic, 0, stride * (maxHeight + (curFrame->m_fencPic->m_lumaMarginY * 2)) * sizeof(pixel));
-                memset(thetaPic, 0, stride * (maxHeight + (curFrame->m_fencPic->m_lumaMarginY * 2)) * sizeof(pixel));
-                if (param->rc.aqMode == X265_AQ_EDGE)
-                    edgeFilter(curFrame, edgePic, gaussianPic, thetaPic, stride, maxRow, maxCol);
-
                 int blockXY = 0, inclinedEdge = 0;
                 double avg_adj_pow2 = 0, avg_adj = 0, qp_adj = 0;
                 double bias_strength = 0.f;
                 double strength = 0.f;
+
+                if (param->rc.aqMode == X265_AQ_EDGE)
+                    edgeFilter(curFrame, param);
+
                 if (param->rc.aqMode == X265_AQ_AUTO_VARIANCE || param->rc.aqMode == X265_AQ_AUTO_VARIANCE_BIASED || param->rc.aqMode == X265_AQ_EDGE)
                 {
                     double bit_depth_correction = 1.f / (1 << (2 * (X265_DEPTH - 8)));
@@ -507,9 +530,7 @@ void LookaheadTLD::calcAdaptiveQuantFram
                             energy = acEnergyCu(curFrame, blockX, blockY, param->internalCsp, param->rc.qgSize);
                             if (param->rc.aqMode == X265_AQ_EDGE)
                             {
-                                pixel *edgeImage = edgePic + curFrame->m_fencPic->m_lumaMarginY * stride + curFrame->m_fencPic->m_lumaMarginX;
-                                pixel *edgeTheta = thetaPic + curFrame->m_fencPic->m_lumaMarginY * stride + curFrame->m_fencPic->m_lumaMarginX;
-                                edgeDensity = edgeDensityCu(curFrame, edgeImage, edgeTheta, avgAngle, blockX, blockY, param->rc.qgSize);
+                                edgeDensity = edgeDensityCu(curFrame, avgAngle, blockX, blockY, param->rc.qgSize);
                                 if (edgeDensity)
                                 {
                                     qp_adj = pow(edgeDensity * bit_depth_correction + 1, 0.1);
@@ -542,9 +563,6 @@ void LookaheadTLD::calcAdaptiveQuantFram
                 else
                     strength = param->rc.aqStrength * 1.0397f;
 
-                X265_FREE(edgePic);
-                X265_FREE(gaussianPic);
-                X265_FREE(thetaPic);
                 blockXY = 0;
                 for (int blockY = 0; blockY < maxRow; blockY += loopIncr)
                 {
@@ -575,7 +593,7 @@ void LookaheadTLD::calcAdaptiveQuantFram
                             qp_adj = strength * (X265_LOG2(X265_MAX(energy, 1)) - (modeOneConst + 2 * (X265_DEPTH - 8)));
                         }
 
-                        if (param->bHDROpt)
+                        if (param->bHDR10Opt)
                         {
                             uint32_t sum = lumaSumCu(curFrame, blockX, blockY, param->rc.qgSize);
                             uint32_t lumaAvg = sum / (loopIncr * loopIncr);
@@ -1474,7 +1492,7 @@ void Lookahead::slicetypeDecide()
 
     if (m_lastNonB && !m_param->rc.bStatRead &&
         ((m_param->bFrameAdaptive && m_param->bframes) ||
-         m_param->rc.cuTree || m_param->scenecutThreshold ||
+         m_param->rc.cuTree || m_param->scenecutThreshold || m_param->bHistBasedSceneCut ||
          (m_param->lookaheadDepth && m_param->rc.vbvBufferSize)))
     {
         slicetypeAnalyse(frames, false);
@@ -1534,12 +1552,15 @@ void Lookahead::slicetypeDecide()
             if (frm.bIsFadeEnd){
                 frm.sliceType = m_param->bOpenGOP && m_lastKeyframe >= 0 ? X265_TYPE_I : X265_TYPE_IDR;
             }
-            for (int i = 0; i < m_param->rc.zonefileCount; i++)
+            if (m_param->bResetZoneConfig)
             {
-                int curZoneStart = m_param->rc.zones[i].startFrame;
-                curZoneStart += curZoneStart ? m_param->rc.zones[i].zoneParam->radl : 0;
-                if (curZoneStart == frm.frameNum)
-                    frm.sliceType = X265_TYPE_IDR;
+                for (int i = 0; i < m_param->rc.zonefileCount; i++)
+                {
+                    int curZoneStart = m_param->rc.zones[i].startFrame;
+                    curZoneStart += curZoneStart ? m_param->rc.zones[i].zoneParam->radl : 0;
+                    if (curZoneStart == frm.frameNum)
+                        frm.sliceType = X265_TYPE_IDR;
+                }
             }
             if ((frm.sliceType == X265_TYPE_I && frm.frameNum - m_lastKeyframe >= m_param->keyframeMin) || (frm.frameNum == (m_param->chunkStart - 1)) || (frm.frameNum == m_param->chunkEnd))
             {
@@ -1557,16 +1578,19 @@ void Lookahead::slicetypeDecide()
                 m_lastKeyframe = frm.frameNum;
                 frm.bKeyframe = true;
                 int zoneRadl = 0;
-                for (int i = 0; i < m_param->rc.zonefileCount; i++)
+                if (m_param->bResetZoneConfig)
                 {
-                    int zoneStart = m_param->rc.zones[i].startFrame;
-                    zoneStart += zoneStart ? m_param->rc.zones[i].zoneParam->radl : 0;
-                    if (zoneStart == frm.frameNum)
+                    for (int i = 0; i < m_param->rc.zonefileCount; i++)
                     {
-                        zoneRadl = m_param->rc.zones[i].zoneParam->radl;
-                        m_param->radl = 0;
-                        m_param->rc.zones->zoneParam->radl = i < m_param->rc.zonefileCount - 1? m_param->rc.zones[i + 1].zoneParam->radl : 0;
-                        break;
+                        int zoneStart = m_param->rc.zones[i].startFrame;
+                        zoneStart += zoneStart ? m_param->rc.zones[i].zoneParam->radl : 0;
+                        if (zoneStart == frm.frameNum)
+                        {
+                            zoneRadl = m_param->rc.zones[i].zoneParam->radl;
+                            m_param->radl = 0;
+                            m_param->rc.zones->zoneParam->radl = i < m_param->rc.zonefileCount - 1 ? m_param->rc.zones[i + 1].zoneParam->radl : 0;
+                            break;
+                        }
                     }
                 }
                 if (bframes > 0 && !m_param->radl && !zoneRadl)
@@ -1751,7 +1775,7 @@ void Lookahead::vbvLookahead(Lowres **fr
     if (m_param->bBPyramid && curNonB - prevNonB > 1)
         curBRef = (prevNonB + curNonB + 1) / 2;
     int miniGopEnd = keyframe ? prevNonB : curNonB;
-    while (curNonB < numFrames + !keyframe)
+    while (curNonB <= numFrames)
     {
         /* P/I cost: This shouldn't include the cost of nextNonB */
         if (nextNonB != curNonB)
@@ -1857,13 +1881,16 @@ void Lookahead::slicetypeAnalyse(Lowres 
     }
     frames[framecnt + 1] = NULL;
 
-    for (int i = 0; i < m_param->rc.zonefileCount; i++)
+    if (m_param->bResetZoneConfig)
     {
-        int curZoneStart = m_param->rc.zones[i].startFrame, nextZoneStart = 0;
-        curZoneStart += curZoneStart ? m_param->rc.zones[i].zoneParam->radl : 0;
-        nextZoneStart += (i + 1 < m_param->rc.zonefileCount) ? m_param->rc.zones[i + 1].startFrame + m_param->rc.zones[i + 1].zoneParam->radl : m_param->totalFrames;
-        if (curZoneStart <= frames[0]->frameNum && nextZoneStart > frames[0]->frameNum)
-            m_param->keyframeMax = nextZoneStart - curZoneStart;
+        for (int i = 0; i < m_param->rc.zonefileCount; i++)
+        {
+            int curZoneStart = m_param->rc.zones[i].startFrame, nextZoneStart = 0;
+            curZoneStart += curZoneStart ? m_param->rc.zones[i].zoneParam->radl : 0;
+            nextZoneStart += (i + 1 < m_param->rc.zonefileCount) ? m_param->rc.zones[i + 1].startFrame + m_param->rc.zones[i + 1].zoneParam->radl : m_param->totalFrames;
+            if (curZoneStart <= frames[0]->frameNum && nextZoneStart > frames[0]->frameNum)
+                m_param->keyframeMax = nextZoneStart - curZoneStart;
+        }
     }
     int keylimit = m_param->keyframeMax;
     if (frames[0]->frameNum < m_param->chunkEnd)
@@ -1965,10 +1992,15 @@ void Lookahead::slicetypeAnalyse(Lowres 
 
     int numBFrames = 0;
     int numAnalyzed = numFrames;
-    bool isScenecut = scenecut(frames, 0, 1, true, origNumFrames);
+    bool isScenecut = false;
 
     /* When scenecut threshold is set, use scenecut detection for I frame placements */
-    if (m_param->scenecutThreshold && isScenecut)
+    if (m_param->bHistBasedSceneCut)
+        isScenecut = frames[1]->bScenecut;
+    else
+        isScenecut = scenecut(frames, 0, 1, true, origNumFrames);
+
+    if (isScenecut && (m_param->bHistBasedSceneCut || m_param->scenecutThreshold))
     {
         frames[1]->sliceType = X265_TYPE_I;
         return;
@@ -1979,14 +2011,17 @@ void Lookahead::slicetypeAnalyse(Lowres 
         m_extendGopBoundary = false;
         for (int i = m_param->bframes + 1; i < origNumFrames; i += m_param->bframes + 1)
         {
-            scenecut(frames, i, i + 1, true, origNumFrames);
+            if (!m_param->bHistBasedSceneCut)
+                scenecut(frames, i, i + 1, true, origNumFrames);
+
             for (int j = i + 1; j <= X265_MIN(i + m_param->bframes + 1, origNumFrames); j++)
             {
-                if (frames[j]->bScenecut && scenecutInternal(frames, j - 1, j, true) )
-                {
-                    m_extendGopBoundary = true;
-                    break;
-                }
+                if ((!m_param->bHistBasedSceneCut && frames[j]->bScenecut && scenecutInternal(frames, j - 1, j, true)) || 
+                    (m_param->bHistBasedSceneCut && frames[j]->bScenecut))
+                    {
+                        m_extendGopBoundary = true;
+                        break;
+                    }
             }
             if (m_extendGopBoundary)
                 break;
@@ -2074,7 +2109,7 @@ void Lookahead::slicetypeAnalyse(Lowres 
             frames[numFrames]->sliceType = X265_TYPE_P;
         }
 
-        int zoneRadl = m_param->rc.zonefileCount ? m_param->rc.zones->zoneParam->radl : 0;
+        int zoneRadl = m_param->rc.zonefileCount && m_param->bResetZoneConfig ? m_param->rc.zones->zoneParam->radl : 0;
         bool bForceRADL = (m_param->radl || zoneRadl) && !m_param->bOpenGOP;
         bool bLastMiniGop = (framecnt >= m_param->bframes + 1) ? false : true;
         int radl = m_param->radl ? m_param->radl : zoneRadl;
@@ -2091,13 +2126,14 @@ void Lookahead::slicetypeAnalyse(Lowres 
         {
             for (int j = 1; j < numBFrames + 1; j++)
             {
-                if (scenecut(frames, j, j + 1, false, origNumFrames) || 
+                if ((!m_param->bHistBasedSceneCut && scenecut(frames, j, j + 1, false, origNumFrames)) ||
+                    (m_param->bHistBasedSceneCut && frames[j + 1]->bScenecut) ||
                     (bForceRADL && (frames[j]->frameNum == preRADL)))
-                {
-                    frames[j]->sliceType = X265_TYPE_P;
-                    numAnalyzed = j;
-                    break;
-                }
+                    {
+                        frames[j]->sliceType = X265_TYPE_P;
+                        numAnalyzed = j;
+                        break;
+                    }
             }
         }
         resetStart = bKeyframe ? 1 : X265_MIN(numBFrames + 2, numAnalyzed + 1);
@@ -3204,12 +3240,13 @@ void CostEstimateGroup::estimateCUCost(L
             }
         }
 
+        int searchRange = m_lookahead.m_param->bEnableHME ? (hme ? m_lookahead.m_param->hmeRange[0] : m_lookahead.m_param->hmeRange[1]) : s_merange;
         /* ME will never return a cost larger than the cost @MVP, so we do not
          * have to check that ME cost is more than the estimated merge cost */
         if(!hme)
-            fencCost = tld.me.motionEstimate(fref, mvmin, mvmax, mvp, 0, NULL, s_merange, *fencMV, m_lookahead.m_param->maxSlices);
+            fencCost = tld.me.motionEstimate(fref, mvmin, mvmax, mvp, 0, NULL, searchRange, *fencMV, m_lookahead.m_param->maxSlices);
         else
-            fencCost = tld.me.motionEstimate(fref, mvmin, mvmax, mvp, 0, NULL, s_merange, *fencMV, m_lookahead.m_param->maxSlices, fref->lowerResPlane[0]);
+            fencCost = tld.me.motionEstimate(fref, mvmin, mvmax, mvp, 0, NULL, searchRange, *fencMV, m_lookahead.m_param->maxSlices, fref->lowerResPlane[0]);
         if (skipCost < 64 && skipCost < fencCost && bBidir)
         {
             fencCost = skipCost;
@@ -3283,3 +3320,5 @@ void CostEstimateGroup::estimateCUCost(L
     fenc->rowSatds[b - p0][p1 - b][cuY] += bcostAq;
     fenc->lowresCosts[b - p0][p1 - b][cuXY] = (uint16_t)(X265_MIN(bcost, LOWRES_COST_MASK) | (listused << LOWRES_COST_SHIFT));
 }
+
+}
--- a/source/encoder/slicetype.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/encoder/slicetype.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *          Min Chen <chenm003@163.com>
@@ -40,6 +40,15 @@ class Lookahead;
 
 #define LOWRES_COST_MASK  ((1 << 14) - 1)
 #define LOWRES_COST_SHIFT 14
+#define AQ_EDGE_BIAS 0.5
+#define EDGE_INCLINATION 45
+
+#if HIGH_BIT_DEPTH
+#define edgeThreshold 1023.0
+#else
+#define edgeThreshold 255.0
+#endif
+#define PI 3.14159265
 
 /* Thread local data for lookahead tasks */
 struct LookaheadTLD
@@ -92,7 +101,7 @@ struct LookaheadTLD
 protected:
 
     uint32_t acEnergyCu(Frame* curFrame, uint32_t blockX, uint32_t blockY, int csp, uint32_t qgSize);
-    uint32_t edgeDensityCu(Frame*curFrame, pixel *edgeImage, pixel *edgeTheta, uint32_t &avgAngle, uint32_t blockX, uint32_t blockY, uint32_t qgSize);
+    uint32_t edgeDensityCu(Frame*curFrame, uint32_t &avgAngle, uint32_t blockX, uint32_t blockY, uint32_t qgSize);
     uint32_t lumaSumCu(Frame* curFrame, uint32_t blockX, uint32_t blockY, uint32_t qgSize);
     uint32_t weightCostLuma(Lowres& fenc, Lowres& ref, WeightParam& wp);
     bool     allocWeightedRef(Lowres& fenc);
@@ -256,6 +265,7 @@ protected:
     CostEstimateGroup& operator=(const CostEstimateGroup&);
 };
 
+bool computeEdge(pixel *edgePic, pixel *refPic, pixel *edgeTheta, intptr_t stride, int height, int width, bool bcalcTheta);
+
 }
-
 #endif // ifndef X265_SLICETYPE_H
--- a/source/encoder/svt.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/encoder/svt.h	Fri Jan 31 00:40:19 2020 +0530
@@ -29,7 +29,6 @@
 
 #include "EbApi.h"
 #include "EbErrorCodes.h"
-#include "EbTime.h"
 
 namespace X265_NS {
 
@@ -41,7 +40,7 @@ namespace X265_NS {
 #define EB_OUTPUTSTREAMBUFFERSIZE_MACRO(ResolutionSize)    ((ResolutionSize) < (INPUT_SIZE_1080i_TH) ? 0x1E8480 : (ResolutionSize) < (INPUT_SIZE_1080p_TH) ? 0x2DC6C0 : (ResolutionSize) < (INPUT_SIZE_4K_TH) ? 0x2DC6C0 : 0x2DC6C0)
 
 void svt_param_default(x265_param* param);
-int svt_set_preset_tune(x265_param* param, const char* preset, const char* tune);
+int svt_set_preset(x265_param* param, const char* preset);
 int svt_param_parse(x265_param* param, const char* name, const char* value);
 void svt_initialise_app_context(x265_encoder *enc);
 int svt_initialise_input_buffer(x265_encoder *enc);
@@ -49,4 +48,4 @@ int svt_initialise_input_buffer(x265_enc
 
 #endif // ifdef SVT_HEVC
 
-#endif // ifndef SVT_H
\ No newline at end of file
+#endif // ifndef SVT_H
--- a/source/encoder/weightPrediction.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/encoder/weightPrediction.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Author: Shazeb Nawaz Khan <shazeb@multicorewareinc.com>
  *         Steve Borho <steve@borho.org>
--- a/source/input/input.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/input/input.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *
--- a/source/input/input.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/input/input.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *
--- a/source/input/y4m.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/input/y4m.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *
@@ -388,6 +388,7 @@ bool Y4MInput::readPicture(x265_picture&
         pic.bitDepth = depth;
         pic.framesize = framesize;
         pic.height = height;
+        pic.width = width;
         pic.colorSpace = colorSpace;
         pic.stride[0] = width * pixelbytes;
         pic.stride[1] = pic.stride[0] >> x265_cli_csps[colorSpace].width[1];
--- a/source/input/y4m.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/input/y4m.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *
--- a/source/input/yuv.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/input/yuv.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *
@@ -204,6 +204,7 @@ bool YUVInput::readPicture(x265_picture&
         pic.bitDepth = depth;
         pic.framesize = framesize;
         pic.height = height;
+        pic.width = width;
         pic.stride[0] = width * pixelbytes;
         pic.stride[1] = pic.stride[0] >> x265_cli_csps[colorSpace].width[1];
         pic.stride[2] = pic.stride[0] >> x265_cli_csps[colorSpace].width[2];
--- a/source/input/yuv.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/input/yuv.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *
--- a/source/output/output.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/output/output.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *          Xinyue Lu <i@7086.in>
--- a/source/output/output.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/output/output.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *          Xinyue Lu <i@7086.in>
--- a/source/output/raw.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/output/raw.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *          Xinyue Lu <i@7086.in>
--- a/source/output/raw.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/output/raw.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *          Xinyue Lu <i@7086.in>
--- a/source/output/reconplay.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/output/reconplay.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Peixuan Zhang <zhangpeixuancn@gmail.com>
  *          Chunli Zhang <chunli@multicorewareinc.com>
--- a/source/output/reconplay.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/output/reconplay.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Peixuan Zhang <zhangpeixuancn@gmail.com>
  *          Chunli Zhang <chunli@multicorewareinc.com>
--- a/source/output/y4m.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/output/y4m.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *
--- a/source/output/y4m.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/output/y4m.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *
--- a/source/output/yuv.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/output/yuv.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *
--- a/source/output/yuv.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/output/yuv.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *
--- a/source/profile/PPA/ppa.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/profile/PPA/ppa.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *
--- a/source/profile/PPA/ppa.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/profile/PPA/ppa.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *
--- a/source/profile/PPA/ppaApi.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/profile/PPA/ppaApi.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *
--- a/source/profile/vtune/vtune.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/profile/vtune/vtune.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *
--- a/source/profile/vtune/vtune.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/profile/vtune/vtune.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *
--- a/source/test/checkasm-a.asm	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/test/checkasm-a.asm	Fri Jan 31 00:40:19 2020 +0530
@@ -2,7 +2,7 @@
 ;* checkasm-a.asm: assembly check tool
 ;*****************************************************************************
 ;* Copyright (C) 2003-2013 x264 project
-;* Copyright (C) 2013-2017 MulticoreWare, Inc
+;* Copyright (C) 2013-2020 MulticoreWare, Inc
 ;*
 ;* Authors: Loren Merritt <lorenm@u.washington.edu>
 ;*          Henrik Gramner <henrik@gramner.com>
--- a/source/test/checkasm-arm.S	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/test/checkasm-arm.S	Fri Jan 31 00:40:19 2020 +0530
@@ -1,7 +1,7 @@
 /****************************************************************************
  * checkasm-arm.S: assembly check tool
  *****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Martin Storsjo <martin@martin.st>
  *          Dnyaneshwar Gorade <dnyaneshwar@multicorewareinc.com>
--- a/source/test/intrapredharness.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/test/intrapredharness.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Min Chen <chenm003@163.com>
  *
--- a/source/test/intrapredharness.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/test/intrapredharness.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Min Chen <chenm003@163.com>
  *
--- a/source/test/ipfilterharness.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/test/ipfilterharness.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Deepthi Devaki <deepthidevaki@multicorewareinc.com>,
  *          Rajesh Paulraj <rajesh@multicorewareinc.com>
--- a/source/test/ipfilterharness.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/test/ipfilterharness.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Deepthi Devaki <deepthidevaki@multicorewareinc.com>,
  *          Rajesh Paulraj <rajesh@multicorewareinc.com>
--- a/source/test/mbdstharness.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/test/mbdstharness.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *          Min Chen <min.chen@multicorewareinc.com>
--- a/source/test/mbdstharness.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/test/mbdstharness.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *          Min Chen <min.chen@multicorewareinc.com>
--- a/source/test/pixelharness.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/test/pixelharness.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *          Min Chen <chenm003@163.com>
--- a/source/test/pixelharness.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/test/pixelharness.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *          Min Chen <chenm003@163.com>
--- a/source/test/regression-tests.txt	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/test/regression-tests.txt	Fri Jan 31 00:40:19 2020 +0530
@@ -18,17 +18,17 @@ BasketballDrive_1920x1080_50.y4m,--prese
 BasketballDrive_1920x1080_50.y4m,--preset faster --aq-strength 2 --merange 190 --slices 3
 BasketballDrive_1920x1080_50.y4m,--preset medium --ctu 16 --max-tu-size 8 --subme 7 --qg-size 16 --cu-lossless --tu-inter-depth 3 --limit-tu 1
 BasketballDrive_1920x1080_50.y4m,--preset medium --keyint -1 --nr-inter 100 -F4 --no-sao
-BasketballDrive_1920x1080_50.y4m,--preset medium --no-cutree --analysis-save x265_analysis.dat --analysis-reuse-level 2 --bitrate 7000 --limit-modes::--preset medium --no-cutree --analysis-load x265_analysis.dat --analysis-reuse-level 2 --bitrate 7000 --limit-modes
+BasketballDrive_1920x1080_50.y4m,--preset medium --no-cutree --analysis-save x265_analysis.dat --analysis-save-reuse-level 2 --bitrate 7000 --limit-modes::--preset medium --no-cutree --analysis-load x265_analysis.dat --analysis-load-reuse-level 2 --bitrate 7000 --limit-modes
 BasketballDrive_1920x1080_50.y4m,--preset slow --nr-intra 100 -F4 --aq-strength 3 --qg-size 16 --limit-refs 1
 BasketballDrive_1920x1080_50.y4m,--preset slower --lossless --chromaloc 3 --subme 0 --limit-tu 4
-BasketballDrive_1920x1080_50.y4m,--preset slower --no-cutree --analysis-save x265_analysis.dat --analysis-reuse-level 10 --bitrate 7000 --limit-tu 0::--preset slower --no-cutree --analysis-load x265_analysis.dat --analysis-reuse-level 10 --bitrate 7000 --limit-tu 0
+BasketballDrive_1920x1080_50.y4m,--preset slower --no-cutree --analysis-save x265_analysis.dat --analysis-save-reuse-level 10 --bitrate 7000 --limit-tu 0::--preset slower --no-cutree --analysis-load x265_analysis.dat --analysis-load-reuse-level 10 --bitrate 7000 --limit-tu 0
 BasketballDrive_1920x1080_50.y4m,--preset veryslow --crf 4 --cu-lossless --pmode --limit-refs 1 --aq-mode 3 --limit-tu 3
-BasketballDrive_1920x1080_50.y4m,--preset veryslow --no-cutree --analysis-save x265_analysis.dat --crf 18 --tskip-fast --limit-tu 2::--preset veryslow --no-cutree --analysis-load x265_analysis.dat --crf 18 --tskip-fast --limit-tu 2
+BasketballDrive_1920x1080_50.y4m,--preset veryslow --no-cutree --analysis-save x265_analysis.dat --analysis-save-reuse-level 5 --crf 18 --tskip-fast --limit-tu 2::--preset veryslow --no-cutree --analysis-load x265_analysis.dat  --analysis-save-reuse-level 5 --crf 18 --tskip-fast --limit-tu 2
 BasketballDrive_1920x1080_50.y4m,--preset veryslow --recon-y4m-exec "ffplay -i pipe:0 -autoexit"
 Coastguard-4k.y4m,--preset ultrafast --recon-y4m-exec "ffplay -i pipe:0 -autoexit"
 Coastguard-4k.y4m,--preset superfast --tune grain --overscan=crop
 Coastguard-4k.y4m,--preset superfast --tune grain --pme --aq-strength 2 --merange 190
-Coastguard-4k.y4m,--preset veryfast --no-cutree --analysis-save x265_analysis.dat --analysis-reuse-level 1 --qp 35::--preset veryfast --no-cutree --analysis-load x265_analysis.dat --analysis-reuse-level 1 --qp 35
+Coastguard-4k.y4m,--preset veryfast --no-cutree --analysis-save x265_analysis.dat --analysis-save-reuse-level 1 --qp 35::--preset veryfast --no-cutree --analysis-load x265_analysis.dat --analysis-load-reuse-level 1 --qp 35
 Coastguard-4k.y4m,--preset medium --rdoq-level 1 --tune ssim --no-signhide --me umh --slices 2
 Coastguard-4k.y4m,--preset slow --tune psnr --cbqpoffs -1 --crqpoffs 1 --limit-refs 1
 CrowdRun_1920x1080_50_10bit_422.yuv,--preset ultrafast --weightp --tune zerolatency --qg-size 16
@@ -53,7 +53,7 @@ DucksAndLegs_1920x1080_60_10bit_422.yuv,
 DucksAndLegs_1920x1080_60_10bit_444.yuv,--preset veryfast --weightp --nr-intra 1000 -F4
 DucksAndLegs_1920x1080_60_10bit_444.yuv,--preset medium --nr-inter 500 -F4 --no-psy-rdoq
 DucksAndLegs_1920x1080_60_10bit_444.yuv,--preset slower --no-weightp --rdoq-level 0 --limit-refs 3 --tu-inter-depth 4 --limit-tu 3
-DucksAndLegs_1920x1080_60_10bit_422.yuv,--preset fast --no-cutree --analysis-save x265_analysis.dat --bitrate 3000 --early-skip --tu-inter-depth 3 --limit-tu 1::--preset fast --no-cutree --analysis-load x265_analysis.dat --bitrate 3000 --early-skip --tu-inter-depth 3 --limit-tu 1
+DucksAndLegs_1920x1080_60_10bit_422.yuv,--preset fast --no-cutree --analysis-save x265_analysis.dat --analysis-save-reuse-level 5 --bitrate 3000 --early-skip --tu-inter-depth 3 --limit-tu 1::--preset fast --no-cutree --analysis-load x265_analysis.dat  --analysis-load-reuse-level 5 --bitrate 3000 --early-skip --tu-inter-depth 3 --limit-tu 1
 FourPeople_1280x720_60.y4m,--preset superfast --no-wpp --lookahead-slices 2
 FourPeople_1280x720_60.y4m,--preset veryfast --aq-mode 2 --aq-strength 1.5 --qg-size 8
 FourPeople_1280x720_60.y4m,--preset medium --qp 38 --no-psy-rd
@@ -70,8 +70,8 @@ KristenAndSara_1280x720_60.y4m,--preset 
 KristenAndSara_1280x720_60.y4m,--preset slower --pmode --max-tu-size 8 --limit-refs 0 --limit-modes --limit-tu 1
 NebutaFestival_2560x1600_60_10bit_crop.yuv,--preset superfast --tune psnr
 NebutaFestival_2560x1600_60_10bit_crop.yuv,--preset medium --tune grain --limit-refs 2
-NebutaFestival_2560x1600_60_10bit_crop.yuv,--preset slow --no-cutree --analysis-save x265_analysis.dat --rd 5 --analysis-reuse-level 10 --bitrate 9000 --vbv-maxrate 9000 --vbv-bufsize 9000::--preset slow --no-cutree --analysis-load x265_analysis.dat --rd 5 --analysis-reuse-level 10 --bitrate 9000 --vbv-maxrate 9000 --vbv-bufsize 9000
-News-4k.y4m,--preset ultrafast --no-cutree --analysis-save x265_analysis.dat --analysis-reuse-level 2 --bitrate 15000::--preset ultrafast --no-cutree --analysis-load x265_analysis.dat --analysis-reuse-level 2 --bitrate 15000
+NebutaFestival_2560x1600_60_10bit_crop.yuv,--preset slow --no-cutree --analysis-save x265_analysis.dat --rd 5 --analysis-save-reuse-level 10 --bitrate 9000 --vbv-maxrate 9000 --vbv-bufsize 9000::--preset slow --no-cutree --analysis-load x265_analysis.dat --rd 5 --analysis-load-reuse-level 10 --bitrate 9000 --vbv-maxrate 9000 --vbv-bufsize 9000
+News-4k.y4m,--preset ultrafast --no-cutree --analysis-save x265_analysis.dat --analysis-save-reuse-level 2 --bitrate 15000::--preset ultrafast --no-cutree --analysis-load x265_analysis.dat --analysis-load-reuse-level 2 --bitrate 15000
 News-4k.y4m,--preset superfast --lookahead-slices 6 --aq-mode 0
 News-4k.y4m,--preset superfast --slices 4 --aq-mode 0 
 News-4k.y4m,--preset medium --tune ssim --no-sao --qg-size 16
@@ -125,7 +125,7 @@ old_town_cross_444_720p50.y4m,--preset u
 old_town_cross_444_720p50.y4m,--preset superfast --weightp --min-cu 16 --limit-modes
 old_town_cross_444_720p50.y4m,--preset veryfast --qp 1 --tune ssim
 old_town_cross_444_720p50.y4m,--preset faster --rd 1 --tune zero-latency
-old_town_cross_444_720p50.y4m,--preset fast --no-cutree --analysis-save pass1_analysis.dat --analysis-reuse-level 1 --bitrate 3000 --early-skip::--preset fast --no-cutree --analysis-load pass1_analysis.dat --analysis-save pass2_analysis.dat --analysis-reuse-level 1 --bitrate 3000 --early-skip::--preset fast --no-cutree --analysis-load pass2_analysis.dat --analysis-reuse-level 1 --bitrate 3000 --early-skip
+old_town_cross_444_720p50.y4m,--preset fast --no-cutree --analysis-save pass1_analysis.dat --analysis-save-reuse-level 1 --bitrate 3000 --early-skip::--preset fast --no-cutree --analysis-load pass1_analysis.dat --analysis-save pass2_analysis.dat --analysis-load-reuse-level 1 --analysis-save-reuse-level 1 --bitrate 3000 --early-skip::--preset fast --no-cutree --analysis-load pass2_analysis.dat --analysis-load-reuse-level 1 --bitrate 3000 --early-skip
 old_town_cross_444_720p50.y4m,--preset medium --keyint -1 --no-weightp --ref 6
 old_town_cross_444_720p50.y4m,--preset slow --rdoq-level 1 --early-skip --ref 7 --no-b-pyramid
 old_town_cross_444_720p50.y4m,--preset slower --crf 4 --cu-lossless
@@ -154,8 +154,14 @@ big_buck_bunny_360p24.y4m, --keyint 60 -
 BasketballDrive_1920x1080_50.y4m, --preset medium --no-open-gop --keyint 50 --min-keyint 50 --radl 2 --vbv-maxrate 5000 --vbv-bufsize 5000
 big_buck_bunny_360p24.y4m, --bitrate 500 --fades
 720p50_parkrun_ter.y4m,--preset medium --bitrate 400 --hme
-ducks_take_off_420_1_720p50.y4m,--preset medium --aq-mode 4 --crf 22 --no-cutree
+ducks_take_off_420_720p50.y4m,--preset medium --aq-mode 4 --crf 22 --no-cutree
 ducks_take_off_420_1_720p50.y4m,--preset medium --selective-sao 4 --sao --crf 20
+Traffic_4096x2048_30p.y4m, --preset medium --frame-dup --dup-threshold 60 --hrd --bitrate 10000 --vbv-bufsize 15000 --vbv-maxrate 12000
+Kimono1_1920x1080_24_400.yuv,--preset superfast --qp 28 --zones 0,139,q=32
+Island_960x540_24.yuv,--no-cutree --aq-mode 0 --bitrate 6000 --scenecut-aware-qp
+sintel_trailer_2k_1920x1080_24.yuv, --preset medium --hist-scenecut --hist-threshold 0.02 --frame-dup --dup-threshold 60 --hrd --bitrate 10000 --vbv-bufsize 15000 --vbv-maxrate 12000
+sintel_trailer_2k_1920x1080_24.yuv, --preset medium --hist-scenecut --hist-threshold 0.02
+sintel_trailer_2k_1920x1080_24.yuv, --preset ultrafast --hist-scenecut --hist-threshold 0.02
 
 # Main12 intraCost overflow bug test
 720p50_parkrun_ter.y4m,--preset medium
@@ -172,15 +178,14 @@ big_buck_bunny_360p24.y4m,--preset super
 720p50_parkrun_ter.y4m,--preset medium --lowpass-dct
 
 #scaled save/load test
-crowd_run_1080p50.y4m,--preset ultrafast --no-cutree --analysis-save x265_analysis.dat  --analysis-reuse-level 1 --scale-factor 2 --crf 26 --vbv-maxrate 8000 --vbv-bufsize 8000::crowd_run_2160p50.y4m, --preset ultrafast --no-cutree --analysis-load x265_analysis.dat  --analysis-reuse-level 1 --scale-factor 2 --crf 26 --vbv-maxrate 12000 --vbv-bufsize 12000 
-crowd_run_1080p50.y4m,--preset superfast --no-cutree --analysis-save x265_analysis.dat  --analysis-reuse-level 2 --scale-factor 2 --crf 22 --vbv-maxrate 5000 --vbv-bufsize 5000::crowd_run_2160p50.y4m, --preset superfast --no-cutree --analysis-load x265_analysis.dat  --analysis-reuse-level 2 --scale-factor 2 --crf 22 --vbv-maxrate 10000 --vbv-bufsize 10000 
-crowd_run_1080p50.y4m,--preset fast --no-cutree --analysis-save x265_analysis.dat  --analysis-reuse-level 5 --scale-factor 2 --qp 18::crowd_run_2160p50.y4m, --preset fast --no-cutree --analysis-load x265_analysis.dat  --analysis-reuse-level 5 --scale-factor 2 --qp 18
-crowd_run_1080p50.y4m,--preset medium --no-cutree --analysis-save x265_analysis.dat  --analysis-reuse-level 10 --scale-factor 2 --bitrate 5000  --vbv-maxrate 5000 --vbv-bufsize 5000 --early-skip --tu-inter-depth 3::crowd_run_2160p50.y4m, --preset medium --no-cutree --analysis-load x265_analysis.dat  --analysis-reuse-level 10 --scale-factor 2 --bitrate 10000 --vbv-maxrate 10000 --vbv-bufsize 10000 --early-skip --tu-inter-depth 3 --refine-intra 4 --dynamic-refine::crowd_run_2160p50.y4m, --preset medium --no-cutree --analysis-load x265_analysis.dat  --analysis-reuse-level 10 --scale-factor 2 --bitrate 10000 --vbv-maxrate 10000 --vbv-bufsize 10000 --early-skip --tu-inter-depth 3 --refine-intra 3 --refine-inter 3
-RaceHorses_416x240_30.y4m,--preset slow --no-cutree --ctu 16 --analysis-save x265_analysis.dat --analysis-reuse-level 10 --scale-factor 2 --crf 22  --vbv-maxrate 1000 --vbv-bufsize 1000::RaceHorses_832x480_30.y4m, --preset slow --no-cutree --ctu 32 --analysis-load x265_analysis.dat  --analysis-save x265_analysis_2.dat --analysis-reuse-level 10 --scale-factor 2 --crf 16 --vbv-maxrate 4000 --vbv-bufsize 4000 --refine-intra 0 --refine-inter 1::RaceHorses_1664x960_30.y4m,--preset slow --no-cutree --ctu 64 --analysis-load x265_analysis_2.dat  --analysis-reuse-level 10 --scale-factor 2 --crf 12 --vbv-maxrate 7000 --vbv-bufsize 7000 --refine-intra 2 --refine-inter 2
-ElFunete_960x540_60.yuv,--colorprim bt709 --transfer bt709 --chromaloc 2 --aud --repeat-headers --no-opt-qp-pps --no-opt-ref-list-length-pps --wpp --no-interlace --sar 1:1 --min-keyint 60 --no-open-gop --rc-lookahead 180 --bframes 5 --b-intra --ref 4 --cbqpoffs -2 --crqpoffs -2 --lookahead-threads 0 --weightb --qg-size 8 --me star --preset veryslow --frame-threads 1 --b-adapt 2 --aq-mode 3 --rd 6 --pools 15 --colormatrix bt709 --keyint 120 --high-tier --ctu 64 --tune psnr --bitrate 10000 --vbv-bufsize 30000 --vbv-maxrate 17500 --analysis-reuse-level 10 --analysis-save elfuente_960x540.dat --scale-factor 2::ElFunete_1920x1080_60.yuv,--colorprim bt709 --transfer bt709 --chromaloc 2 --aud --repeat-headers --no-opt-qp-pps --no-opt-ref-list-length-pps --wpp --no-interlace --sar 1:1 --min-keyint 60 --no-open-gop --rc-lookahead 180 --bframes 5 --b-intra --ref 4 --cbqpoffs -2 --crqpoffs -2 --lookahead-threads 0 --weightb --qg-size 8 --me star --preset veryslow --frame-threads 1 --b-adapt 2 --aq-mode 3 --rd 6 --pools 15 --colormatrix bt709 --keyint 120 --high-tier --ctu 64 --tune psnr --bitrate 10000 --vbv-bufsize 30000 --vbv-maxrate 17500 --analysis-reuse-level 10 --analysis-save elfuente_1920x1080.dat --limit-tu 0 --scale-factor 2 --analysis-load elfuente_960x540.dat --refine-intra 4 --refine-inter 2::ElFuente_3840x2160_60.yuv,--colorprim bt709 --transfer bt709 --chromaloc 2 --aud --repeat-headers --no-opt-qp-pps --no-opt-ref-list-length-pps --wpp --no-interlace --sar 1:1 --min-keyint 60 --no-open-gop --rc-lookahead 180 --bframes 5 --b-intra --ref 4 --cbqpoffs -2 --crqpoffs -2 --lookahead-threads 0 --weightb --qg-size 8 --me star --preset veryslow --frame-threads 1 --b-adapt 2 --aq-mode 3 --rd 6 --pools 15 --colormatrix bt709 --keyint 120 --high-tier --ctu 64 --tune=psnr --bitrate 24000 --vbv-bufsize 84000 --vbv-maxrate 49000 --analysis-reuse-level 10 --limit-tu 0 --scale-factor 2 --analysis-load elfuente_1920x1080.dat --refine-intra 4 --refine-inter 2
+crowd_run_1080p50.y4m,--preset ultrafast --no-cutree --analysis-save x265_analysis.dat  --analysis-save-reuse-level 1 --scale-factor 2 --crf 26 --vbv-maxrate 8000 --vbv-bufsize 8000::crowd_run_2160p50.y4m, --preset ultrafast --no-cutree --analysis-load x265_analysis.dat  --analysis-load-reuse-level 1 --scale-factor 2 --crf 26 --vbv-maxrate 12000 --vbv-bufsize 12000 
+crowd_run_1080p50.y4m,--preset superfast --no-cutree --analysis-save x265_analysis.dat  --analysis-save-reuse-level 2 --scale-factor 2 --crf 22 --vbv-maxrate 5000 --vbv-bufsize 5000::crowd_run_2160p50.y4m, --preset superfast --no-cutree --analysis-load x265_analysis.dat  --analysis-load-reuse-level 2 --scale-factor 2 --crf 22 --vbv-maxrate 10000 --vbv-bufsize 10000 
+crowd_run_1080p50.y4m,--preset fast --no-cutree --analysis-save x265_analysis.dat  --analysis-save-reuse-level 5 --scale-factor 2 --qp 18::crowd_run_2160p50.y4m, --preset fast --no-cutree --analysis-load x265_analysis.dat  --analysis-load-reuse-level 5 --scale-factor 2 --qp 18
+crowd_run_1080p50.y4m,--preset medium --no-cutree --analysis-save x265_analysis.dat  --analysis-save-reuse-level 10 --scale-factor 2 --bitrate 5000  --vbv-maxrate 5000 --vbv-bufsize 5000 --early-skip --tu-inter-depth 3::crowd_run_2160p50.y4m, --preset medium --no-cutree --analysis-load x265_analysis.dat  --analysis-load-reuse-level 10 --scale-factor 2 --bitrate 10000 --vbv-maxrate 10000 --vbv-bufsize 10000 --early-skip --tu-inter-depth 3 --refine-intra 4 --dynamic-refine::crowd_run_2160p50.y4m, --preset medium --no-cutree --analysis-load x265_analysis.dat  --analysis-load-reuse-level 10 --scale-factor 2 --bitrate 10000 --vbv-maxrate 10000 --vbv-bufsize 10000 --early-skip --tu-inter-depth 3 --refine-intra 3 --refine-inter 3
+RaceHorses_416x240_30.y4m,--preset slow --no-cutree --ctu 16 --analysis-save x265_analysis.dat --analysis-save-reuse-level 10 --scale-factor 2 --crf 22  --vbv-maxrate 1000 --vbv-bufsize 1000::RaceHorses_832x480_30.y4m, --preset slow --no-cutree --ctu 32 --analysis-load x265_analysis.dat  --analysis-save x265_analysis_2.dat --analysis-load-reuse-level 10 --analysis-save-reuse-level 0 --scale-factor 2 --crf 16 --vbv-maxrate 4000 --vbv-bufsize 4000 --refine-intra 0 --refine-inter 1::RaceHorses_1664x960_30.y4m,--preset slow --no-cutree --ctu 64 --analysis-load x265_analysis_2.dat  --analysis-load-reuse-level 10 --scale-factor 2 --crf 12 --vbv-maxrate 7000 --vbv-bufsize 7000 --refine-intra 2 --refine-inter 2
+ElFunete_960x540_60.yuv,--colorprim bt709 --transfer bt709 --chromaloc 2 --aud --repeat-headers --no-opt-qp-pps --no-opt-ref-list-length-pps --wpp --no-interlace --sar 1:1 --min-keyint 60 --no-open-gop --rc-lookahead 180 --bframes 5 --b-intra --ref 4 --cbqpoffs -2 --crqpoffs -2 --lookahead-threads 0 --weightb --qg-size 8 --me star --preset veryslow --frame-threads 1 --b-adapt 2 --aq-mode 3 --rd 6 --pools 15 --colormatrix bt709 --keyint 120 --high-tier --ctu 64 --tune psnr --bitrate 10000 --vbv-bufsize 30000 --vbv-maxrate 17500 --analysis-save-reuse-level 10 --analysis-save elfuente_960x540.dat --scale-factor 2::ElFunete_1920x1080_60.yuv,--colorprim bt709 --transfer bt709 --chromaloc 2 --aud --repeat-headers --no-opt-qp-pps --no-opt-ref-list-length-pps --wpp --no-interlace --sar 1:1 --min-keyint 60 --no-open-gop --rc-lookahead 180 --bframes 5 --b-intra --ref 4 --cbqpoffs -2 --crqpoffs -2 --lookahead-threads 0 --weightb --qg-size 8 --me star --preset veryslow --frame-threads 1 --b-adapt 2 --aq-mode 3 --rd 6 --pools 15 --colormatrix bt709 --keyint 120 --high-tier --ctu 64 --tune psnr --bitrate 10000 --vbv-bufsize 30000 --vbv-maxrate 17500 --analysis-load-reuse-level 10 --analysis-save-reuse-level 10 --analysis-save elfuente_1920x1080.dat --limit-tu 0 --scale-factor 2 --analysis-load elfuente_960x540.dat --refine-intra 4 --refine-inter 2::ElFuente_3840x2160_60.yuv,--colorprim bt709 --transfer bt709 --chromaloc 2 --aud --repeat-headers --no-opt-qp-pps --no-opt-ref-list-length-pps --wpp --no-interlace --sar 1:1 --min-keyint 60 --no-open-gop --rc-lookahead 180 --bframes 5 --b-intra --ref 4 --cbqpoffs -2 --crqpoffs -2 --lookahead-threads 0 --weightb --qg-size 8 --me star --preset veryslow --frame-threads 1 --b-adapt 2 --aq-mode 3 --rd 6 --pools 15 --colormatrix bt709 --keyint 120 --high-tier --ctu 64 --tune=psnr --bitrate 24000 --vbv-bufsize 84000 --vbv-maxrate 49000 --analysis-load-reuse-level 10 --limit-tu 0 --scale-factor 2 --analysis-load elfuente_1920x1080.dat --refine-intra 4 --refine-inter 2
 #save/load with ctu distortion refinement
-CrowdRun_1920x1080_50_10bit_422.yuv,--no-cutree --analysis-save x265_analysis.dat --refine-ctu-distortion 1 --bitrate 7000::--no-cutree --analysis-load x265_analysis.dat --refine-ctu-distortion 1 --bitrate 7000
-
+CrowdRun_1920x1080_50_10bit_422.yuv,--no-cutree --analysis-save x265_analysis.dat --analysis-save-reuse-level 5 --refine-ctu-distortion 1 --bitrate 7000::--no-cutree --analysis-load x265_analysis.dat --refine-ctu-distortion 1 --bitrate 7000 --analysis-load-reuse-level 5
 #segment encoding
 BasketballDrive_1920x1080_50.y4m, --preset ultrafast --no-open-gop --chunk-start 100 --chunk-end 200
 
--- a/source/test/save-load-tests.txt	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/test/save-load-tests.txt	Fri Jan 31 00:40:19 2020 +0530
@@ -10,10 +10,11 @@
 # outputs for different frame encoder counts. In order for outputs to be
 # consistent across many machines, you must force a certain -FN so it is
 # not auto-detected.
-crowd_run_1080p50.y4m, --preset ultrafast --no-cutree --analysis-save x265_analysis.dat  --analysis-reuse-level 1 --scale-factor 2 --crf 26 --vbv-maxrate 8000 --vbv-bufsize 8000::crowd_run_2160p50.y4m, --preset ultrafast --no-cutree --analysis-load x265_analysis.dat  --analysis-reuse-level 1 --scale-factor 2 --crf 26 --vbv-maxrate 12000 --vbv-bufsize 12000
-crowd_run_1080p50.y4m, --preset superfast --no-cutree --analysis-save x265_analysis.dat  --analysis-reuse-level 2 --scale-factor 2 --crf 22 --vbv-maxrate 5000 --vbv-bufsize 5000::crowd_run_2160p50.y4m,   --preset superfast --no-cutree --analysis-load x265_analysis.dat  --analysis-reuse-level 2 --scale-factor 2 --crf 22 --vbv-maxrate 10000 --vbv-bufsize 10000
-crowd_run_1080p50.y4m,  --preset fast --no-cutree --analysis-save x265_analysis.dat  --analysis-reuse-level 5 --scale-factor 2 --qp 18::crowd_run_2160p50.y4m,   --preset fast --no-cutree --analysis-load x265_analysis.dat  --analysis-reuse-level 5 --scale-factor 2 --qp 18
-crowd_run_1080p50.y4m,   --preset medium --no-cutree --analysis-save x265_analysis.dat  --analysis-reuse-level 10 --scale-factor 2 --bitrate 5000  --vbv-maxrate 5000 --vbv-bufsize 5000 --early-skip --tu-inter-depth 3::crowd_run_2160p50.y4m,    --preset medium --no-cutree --analysis-load x265_analysis.dat  --analysis-reuse-level 10 --scale-factor 2 --bitrate 10000 --vbv-maxrate 10000 --vbv-bufsize 10000 --early-skip --tu-inter-depth 3 --refine-intra 4 --dynamic-refine::crowd_run_2160p50.y4m,    --preset medium --no-cutree --analysis-load x265_analysis.dat  --analysis-reuse-level 10 --scale-factor 2 --bitrate 10000 --vbv-maxrate 10000 --vbv-bufsize 10000 --early-skip --tu-inter-depth 3 --refine-intra 3 --refine-inter 3
-RaceHorses_416x240_30.y4m,   --preset slow --no-cutree --ctu 16 --analysis-save x265_analysis.dat --analysis-reuse-level 10 --scale-factor 2 --crf 22  --vbv-maxrate 1000 --vbv-bufsize 1000::RaceHorses_832x480_30.y4m,    --preset slow --no-cutree --ctu 32 --analysis-load x265_analysis.dat  --analysis-save x265_analysis_2.dat --analysis-reuse-level 10 --scale-factor 2 --crf 16 --vbv-maxrate 4000 --vbv-bufsize 4000 --refine-intra 0 --refine-inter 1::RaceHorses_1664x960_30.y4m,   --preset slow --no-cutree --ctu 64 --analysis-load x265_analysis_2.dat  --analysis-reuse-level 10 --scale-factor 2 --crf 12 --vbv-maxrate 7000 --vbv-bufsize 7000 --refine-intra 2 --refine-inter 2
-crowd_run_540p50.y4m,   --preset veryslow --no-cutree --analysis-save x265_analysis_540.dat  --analysis-reuse-level 10 --scale-factor 2 --bitrate 5000 --vbv-bufsize 15000 --vbv-maxrate 9000::crowd_run_1080p50.y4m,   --preset veryslow --no-cutree --analysis-save x265_analysis_1080.dat  --analysis-reuse-level 10 --scale-factor 2 --bitrate 10000 --vbv-bufsize 30000 --vbv-maxrate 17500::crowd_run_1080p50.y4m,  --preset veryslow --no-cutree --analysis-save x265_analysis_1080.dat --analysis-load x265_analysis_540.dat --refine-intra 4 --dynamic-refine --analysis-reuse-level 10 --scale-factor 2 --bitrate 10000 --vbv-bufsize 30000 --vbv-maxrate 17500::crowd_run_2160p50.y4m,  --preset veryslow --no-cutree --analysis-save x265_analysis_2160.dat --analysis-load x265_analysis_1080.dat --refine-intra 3 --dynamic-refine --analysis-reuse-level 10 --scale-factor 2 --bitrate 24000 --vbv-bufsize 84000 --vbv-maxrate 49000::crowd_run_2160p50.y4m,  --preset veryslow --no-cutree --analysis-load x265_analysis_2160.dat --refine-intra 2 --dynamic-refine --analysis-reuse-level 10 --scale-factor 1 --bitrate 24000 --vbv-bufsize 84000 --vbv-maxrate 49000
-crowd_run_540p50.y4m,  --preset medium --no-cutree --analysis-save x265_analysis_540.dat  --analysis-reuse-level 10 --scale-factor 2 --bitrate 5000 --vbv-bufsize 15000 --vbv-maxrate 9000::crowd_run_1080p50.y4m,  --preset medium --no-cutree --analysis-save x265_analysis_1080.dat  --analysis-reuse-level 10 --scale-factor 2 --bitrate 10000 --vbv-bufsize 30000 --vbv-maxrate 17500::crowd_run_1080p50.y4m,  --preset medium --no-cutree --analysis-save x265_analysis_1080.dat --analysis-load x265_analysis_540.dat --refine-intra 4 --dynamic-refine --analysis-reuse-level 10 --scale-factor 2 --bitrate 10000 --vbv-bufsize 30000 --vbv-maxrate 17500::crowd_run_2160p50.y4m,  --preset medium --no-cutree --analysis-save x265_analysis_2160.dat --analysis-load x265_analysis_1080.dat --refine-intra 3 --dynamic-refine --analysis-reuse-level 10 --scale-factor 2 --bitrate 24000 --vbv-bufsize 84000 --vbv-maxrate 49000::crowd_run_2160p50.y4m,  --preset medium --no-cutree --analysis-load x265_analysis_2160.dat --refine-intra 2 --dynamic-refine --analysis-reuse-level 10 --scale-factor 1 --bitrate 24000 --vbv-bufsize 84000 --vbv-maxrate 49000
+crowd_run_1080p50.y4m, --preset ultrafast --no-cutree --analysis-save x265_analysis.dat  --analysis-save-reuse-level 1 --scale-factor 2 --crf 26 --vbv-maxrate 8000 --vbv-bufsize 8000::crowd_run_2160p50.y4m, --preset ultrafast --no-cutree --analysis-load x265_analysis.dat  --analysis-load-reuse-level 1 --scale-factor 2 --crf 26 --vbv-maxrate 12000 --vbv-bufsize 12000
+crowd_run_540p50.y4m, --preset ultrafast --no-cutree --analysis-save x265_analysis.dat --scale-factor 2 --crf 26 --vbv-maxrate 8000 --vbv-bufsize 8000::crowd_run_1080p50.y4m, --preset ultrafast --no-cutree --analysis-load x265_analysis.dat --scale-factor 2 --crf 26 --vbv-maxrate 12000 --vbv-bufsize 12000
+crowd_run_1080p50.y4m, --preset superfast --no-cutree --analysis-save x265_analysis.dat  --analysis-save-reuse-level 2 --scale-factor 2 --crf 22 --vbv-maxrate 5000 --vbv-bufsize 5000::crowd_run_2160p50.y4m,   --preset superfast --no-cutree --analysis-load x265_analysis.dat  --analysis-load-reuse-level 2 --scale-factor 2 --crf 22 --vbv-maxrate 10000 --vbv-bufsize 10000
+crowd_run_1080p50.y4m,  --preset fast --no-cutree --analysis-save x265_analysis.dat  --analysis-save-reuse-level 5 --scale-factor 2 --qp 18::crowd_run_2160p50.y4m,   --preset fast --no-cutree --analysis-load x265_analysis.dat  --analysis-load-reuse-level 5 --scale-factor 2 --qp 18
+crowd_run_1080p50.y4m,   --preset medium --no-cutree --analysis-save x265_analysis.dat  --analysis-save-reuse-level 10 --scale-factor 2 --bitrate 5000  --vbv-maxrate 5000 --vbv-bufsize 5000 --early-skip --tu-inter-depth 3::crowd_run_2160p50.y4m,    --preset medium --no-cutree --analysis-load x265_analysis.dat  --analysis-load-reuse-level 10 --scale-factor 2 --bitrate 10000 --vbv-maxrate 10000 --vbv-bufsize 10000 --early-skip --tu-inter-depth 3 --refine-intra 4 --dynamic-refine::crowd_run_2160p50.y4m,    --preset medium --no-cutree --analysis-load x265_analysis.dat  --analysis-load-reuse-level 10 --scale-factor 2 --bitrate 10000 --vbv-maxrate 10000 --vbv-bufsize 10000 --early-skip --tu-inter-depth 3 --refine-intra 3 --refine-inter 3
+RaceHorses_416x240_30.y4m,   --preset slow --no-cutree --ctu 16 --analysis-save x265_analysis.dat --analysis-save-reuse-level 10 --scale-factor 2 --crf 22  --vbv-maxrate 1000 --vbv-bufsize 1000::RaceHorses_832x480_30.y4m,    --preset slow --no-cutree --ctu 32 --analysis-load x265_analysis.dat  --analysis-save x265_analysis_2.dat --analysis-load-reuse-level 10 --analysis-save-reuse-level 10 --scale-factor 2 --crf 16 --vbv-maxrate 4000 --vbv-bufsize 4000 --refine-intra 0 --refine-inter 1::RaceHorses_1664x960_30.y4m,   --preset slow --no-cutree --ctu 64 --analysis-load x265_analysis_2.dat  --analysis-load-reuse-level 10 --scale-factor 2 --crf 12 --vbv-maxrate 7000 --vbv-bufsize 7000 --refine-intra 2 --refine-inter 2
+crowd_run_540p50.y4m,   --preset veryslow --no-cutree --analysis-save x265_analysis_540.dat  --analysis-save-reuse-level 10 --scale-factor 2 --bitrate 5000 --vbv-bufsize 15000 --vbv-maxrate 9000::crowd_run_1080p50.y4m,   --preset veryslow --no-cutree --analysis-save x265_analysis_1080.dat  --analysis-save-reuse-level 10 --scale-factor 2 --bitrate 10000 --vbv-bufsize 30000 --vbv-maxrate 17500::crowd_run_1080p50.y4m,  --preset veryslow --no-cutree --analysis-save x265_analysis_1080.dat --analysis-load x265_analysis_540.dat --refine-intra 4 --dynamic-refine --analysis-load-reuse-level 10 --analysis-save-reuse-level 10 --scale-factor 2 --bitrate 10000 --vbv-bufsize 30000 --vbv-maxrate 17500::crowd_run_2160p50.y4m,  --preset veryslow --no-cutree --analysis-save x265_analysis_2160.dat --analysis-load x265_analysis_1080.dat --refine-intra 3 --dynamic-refine --analysis-load-reuse-level 10 --analysis-save-reuse-level 10 --scale-factor 2 --bitrate 24000 --vbv-bufsize 84000 --vbv-maxrate 49000::crowd_run_2160p50.y4m,  --preset veryslow --no-cutree --analysis-load x265_analysis_2160.dat --refine-intra 2 --dynamic-refine --analysis-load-reuse-level 10 --scale-factor 1 --bitrate 24000 --vbv-bufsize 84000 --vbv-maxrate 49000
+crowd_run_540p50.y4m,  --preset medium --no-cutree --analysis-save x265_analysis_540.dat  --analysis-save-reuse-level 10 --scale-factor 2 --bitrate 5000 --vbv-bufsize 15000 --vbv-maxrate 9000::crowd_run_1080p50.y4m,  --preset medium --no-cutree --analysis-save x265_analysis_1080.dat  --analysis-save-reuse-level 10 --scale-factor 2 --bitrate 10000 --vbv-bufsize 30000 --vbv-maxrate 17500::crowd_run_1080p50.y4m,  --preset medium --no-cutree --analysis-save x265_analysis_1080.dat --analysis-load x265_analysis_540.dat --refine-intra 4 --dynamic-refine --analysis-load-reuse-level 10 --analysis-save-reuse-level 10 --scale-factor 2 --bitrate 10000 --vbv-bufsize 30000 --vbv-maxrate 17500::crowd_run_2160p50.y4m,  --preset medium --no-cutree --analysis-save x265_analysis_2160.dat --analysis-load x265_analysis_1080.dat --refine-intra 3 --dynamic-refine --analysis-load-reuse-level 10 --analysis-save-reuse-level 10 --scale-factor 2 --bitrate 24000 --vbv-bufsize 84000 --vbv-maxrate 49000::crowd_run_2160p50.y4m,  --preset medium --no-cutree --analysis-load x265_analysis_2160.dat --refine-intra 2 --dynamic-refine --analysis-load-reuse-level 10 --scale-factor 1 --bitrate 24000 --vbv-bufsize 84000 --vbv-maxrate 49000
--- a/source/test/testbench.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/test/testbench.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Gopu Govindaswamy <gopu@govindaswamy.org>
  *          Mandar Gurav <mandar@multicorewareinc.com>
--- a/source/test/testharness.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/test/testharness.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *          Min Chen <chenm003@163.com>
--- a/source/x265.cpp	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/x265.cpp	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *
@@ -541,10 +541,11 @@ bool CLIOptions::parse(int argc, char **
         return true;
     }
 
-    /* Unconditionally accept height/width/csp from file info */
+    /* Unconditionally accept height/width/csp/bitDepth from file info */
     param->sourceWidth = info.width;
     param->sourceHeight = info.height;
     param->internalCsp = info.csp;
+    param->sourceBitDepth = info.depth;
 
     /* Accept fps and sar from file info if not specified by user */
     if (param->fpsDenom == 0 || param->fpsNum == 0)
--- a/source/x265.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/x265.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *          Min Chen <chenm003@163.com>
@@ -132,6 +132,8 @@ typedef struct x265_analysis_validate
     int     chunkEnd;
     int     cuTree;
     int     ctuDistortionRefine;
+    int     rightOffset;
+    int     bottomOffset;
 }x265_analysis_validate;
 
 /* Stores intra analysis data for a single frame. This struct needs better packing */
@@ -200,6 +202,7 @@ typedef struct x265_analysis_distortion_
 
 }x265_analysis_distortion_data;
 
+#define MAX_NUM_REF 16
 /* Stores all analysis data for a single frame */
 typedef struct x265_analysis_data
 {
@@ -219,6 +222,10 @@ typedef struct x265_analysis_data
     uint8_t*                          modeFlag[2];
     x265_analysis_validate            saveParam;
     x265_analysis_distortion_data*    distortionData;
+    uint64_t                          frameBits;
+    int                               list0POC[MAX_NUM_REF];
+    int                               list1POC[MAX_NUM_REF];
+    double                            totalIntraPercent;
 } x265_analysis_data;
 
 /* cu statistics */
@@ -274,8 +281,8 @@ typedef struct x265_frame_stats
     int              encoderOrder;
     int              poc;
     int              countRowBlocks;
-    int              list0POC[16];
-    int              list1POC[16];
+    int              list0POC[MAX_NUM_REF];
+    int              list1POC[MAX_NUM_REF];
     uint16_t         maxLumaLevel;
     uint16_t         minLumaLevel;
 
@@ -315,7 +322,7 @@ typedef enum
 
 typedef enum
 {
-    NO_INFO = 0,
+    DEFAULT = 0,
     AVC_INFO = 1,
     HEVC_INFO = 2,
 }AnalysisRefineType;
@@ -455,7 +462,7 @@ typedef struct x265_picture
      * multi pass ratecontrol mode. */
     void*  rcData;
 
-    uint64_t framesize;
+    size_t framesize;
 
     int    height;
 
@@ -464,8 +471,13 @@ typedef struct x265_picture
 
     //Dolby Vision RPU metadata
     x265_dolby_vision_rpu rpu;
- 
+
     int fieldNum;
+
+    //SEI picture structure message
+    uint32_t picStruct;
+
+    int    width;
 } x265_picture;
 
 typedef enum
@@ -674,6 +686,7 @@ typedef struct x265_zone
     int   qp;
     float bitrateFactor;
     struct x265_param* zoneParam;
+    double* relativeComplexity;
 } x265_zone;
     
 /* data to calculate aggregate VMAF score */
@@ -1013,7 +1026,8 @@ typedef struct x265_param
     int       lookaheadSlices;
 
     /* An arbitrary threshold which determines how aggressively the lookahead
-     * should detect scene cuts. The default (40) is recommended. */
+     * should detect scene cuts for cost based scenecut detection. 
+     * The default (40) is recommended. */
     int       scenecutThreshold;
 
     /* Replace keyframes by using a column of intra blocks that move across the video
@@ -1635,16 +1649,16 @@ typedef struct x265_param
 
     /* Enables the emitting of HDR SEI packets which contains HDR-specific params.
      * Auto-enabled when max-cll, max-fall, or mastering display info is specified.
-     * Default is disabled */
+     * Default is disabled. Now deprecated.*/
     int       bEmitHDRSEI;
 
     /* Enable luma and chroma offsets for HDR/WCG content.
-     * Default is disabled */
+     * Default is disabled. Now deprecated.*/
     int       bHDROpt;
 
     /* A value between 1 and 10 (both inclusive) determines the level of
     * information stored/reused in analysis save/load. Higher the refine
-    * level higher the information stored/reused. Default is 5 */
+    * level higher the information stored/reused. Default is 5. Now deprecated. */
     int       analysisReuseLevel;
 
      /* Limit Sample Adaptive Offset filter computation by early terminating SAO
@@ -1798,7 +1812,97 @@ typedef struct x265_param
 
     /*Emit content light level info SEI*/
     int         bEmitCLL;
+
+    /*
+    * Signals picture structure SEI timing message for every frame
+    * picture structure 7 is signalled for frame doubling
+    * picture structure 8 is signalled for frame tripling
+    * */
+    int       bEnableFrameDuplication;
+
+    /*
+    * For adaptive frame duplication, a threshold is set above which the frames are similar.
+    * User can set a variable threshold. Default 70.
+    * */
+    int       dupThreshold;
+
+    /*Input sequence bit depth. It can be either 8bit, 10bit or 12bit.*/
+    int       sourceBitDepth;
+
+    /*Size of the zone to be reconfigured in frames. Default 0. API only. */
+    uint32_t  reconfigWindowSize;
+
+    /*Flag to indicate if rate-control history has to be reset during zone reconfiguration.
+      Default 1 (Enabled). API only. */
+    int       bResetZoneConfig;
+
+    /* Enables a ratecontrol algorithm for reducing the bits spent on the inter-frames
+     * within the scenecutWindow after a scenecut by increasing their QP without
+     * any deterioration in visual quality. It also increases the quality of scenecut I-Frames by reducing their QP.
+     * Default is disabled. */
+    int       bEnableSceneCutAwareQp;
+
+    /* The duration(in milliseconds) for which there is a reduction in the bits spent on the inter-frames after a scenecut
+     * by increasing their QP, when bEnableSceneCutAwareQp is set. Default is 500ms.*/
+    int       scenecutWindow;
+
+    /* The offset by which QP is incremented for inter-frames when bEnableSceneCutAwareQp is set.
+     * Default is +5. */
+    int       maxQpDelta;
+
+    /* A genuine threshold used for histogram based scene cut detection.
+     * This threshold determines whether a frame is a scenecut or not
+     * when compared against the edge and chroma histogram sad values.
+     * Default 0.01. Range: Real number in the interval (0,2). */
+    double    edgeTransitionThreshold;
+
+    /* Enables histogram based scenecut detection algorithm to detect scenecuts. Default disabled */
+    int      bHistBasedSceneCut;
+
+    /* Enable HME search ranges for L0, L1 and L2 respectively. */
+    int       hmeRange[3];
+
+    /* Block-level QP optimization for HDR10 content. Default is disabled.*/
+    int       bHDR10Opt;
+
+    /* Enables the emitting of HDR10 SEI packets which contains HDR10-specific params.
+    * Auto-enabled when max-cll, max-fall, or mastering display info is specified.
+    * Default is disabled */
+    int       bEmitHDR10SEI;
+
+    /* A value between 1 and 10 (both inclusive) determines the level of
+    * analysis information stored in analysis-save. Higher the refine level higher
+    * the information stored. Default is 5 */
+    int       analysisSaveReuseLevel;
+    
+    /* A value between 1 and 10 (both inclusive) determines the level of
+    * analysis information reused in analysis-load. Higher the refine level higher
+    * the information reused. Default is 5 */
+    int       analysisLoadReuseLevel;
+
+    /* Conformance window right offset specifies the padding offset to the
+    * right side of the internal copy of the input pictures in the library.
+    * The decoded picture will be cropped based on conformance window right offset
+    * signaled in the SPS before output. Default is 0.
+    * Recommended to set this during non-file based analysis-load.
+    * This is to inform the encoder about the conformace window right offset 
+    * to be added to match the number of CUs across the width for which analysis
+    * info is available from the corresponding analysis-save. */
+
+    int       confWinRightOffset;
+
+    /* Conformance window bottom offset specifies the padding offset to the
+    * bottom side of the internal copy of the input pictures in the library.
+    * The decoded picture will be cropped based on conformance window bottom offset
+    * signaled in the SPS before output. Default is 0. 
+    * Recommended to set this during non-file based analysis-load.
+    * This is to inform the encoder about the conformace window bottom offset
+    * to be added to match the number of CUs across the height for which analysis
+    * info is available from the corresponding analysis-save. */
+
+    int      confWinBottomOffset;
 } x265_param;
+
 /* x265_param_alloc:
  *  Allocates an x265_param instance. The returned param structure is not
  *  special in any way, but using this method together with x265_param_free()
@@ -1974,6 +2078,12 @@ int x265_encoder_encode(x265_encoder *en
  *      parameters to take this into account. */
 int x265_encoder_reconfig(x265_encoder *, x265_param *);
 
+/* x265_encoder_reconfig_zone:
+*       zone settings are copied to the encoder's param.
+*       Properties of the zone will be used only to re-configure rate-control settings
+*       of the zone mid-encode. Returns 0 on success on successful copy, negative on failure.*/
+int x265_encoder_reconfig_zone(x265_encoder *, x265_zone *);
+
 /* x265_encoder_get_stats:
  *       returns encoder statistics */
 void x265_encoder_get_stats(x265_encoder *encoder, x265_stats *, uint32_t statsSizeBytes);
@@ -2102,6 +2212,7 @@ typedef struct x265_api
     x265_encoder* (*encoder_open)(x265_param*);
     void          (*encoder_parameters)(x265_encoder*, x265_param*);
     int           (*encoder_reconfig)(x265_encoder*, x265_param*);
+    int           (*encoder_reconfig_zone)(x265_encoder*, x265_zone*);
     int           (*encoder_headers)(x265_encoder*, x265_nal**, uint32_t*);
     int           (*encoder_encode)(x265_encoder*, x265_nal**, uint32_t*, x265_picture*, x265_picture*);
     void          (*encoder_get_stats)(x265_encoder*, x265_stats*, uint32_t);
--- a/source/x265_config.h.in	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/x265_config.h.in	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *
--- a/source/x265cli.h	Wed Sep 25 17:57:51 2019 +0530
+++ b/source/x265cli.h	Fri Jan 31 00:40:19 2020 +0530
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2013-2017 MulticoreWare, Inc
+ * Copyright (C) 2013-2020 MulticoreWare, Inc
  *
  * Authors: Steve Borho <steve@borho.org>
  *          Min Chen <chenm003@163.com>
@@ -129,8 +129,15 @@ static const struct option long_options[
     { "scenecut",       required_argument, NULL, 0 },
     { "no-scenecut",          no_argument, NULL, 0 },
     { "scenecut-bias",  required_argument, NULL, 0 },
+    { "hist-scenecut",        no_argument, NULL, 0},
+    { "no-hist-scenecut",     no_argument, NULL, 0},
+    { "hist-threshold", required_argument, NULL, 0},
     { "fades",                no_argument, NULL, 0 },
     { "no-fades",             no_argument, NULL, 0 },
+    { "scenecut-aware-qp",    no_argument, NULL, 0 },
+    { "no-scenecut-aware-qp", no_argument, NULL, 0 },
+    { "scenecut-window",required_argument, NULL, 0 },
+    { "max-qp-delta",   required_argument, NULL, 0 },
     { "radl",           required_argument, NULL, 0 },
     { "ctu-info",       required_argument, NULL, 0 },
     { "intra-refresh",        no_argument, NULL, 0 },
@@ -268,7 +275,9 @@ static const struct option long_options[
     { "no-multi-pass-opt-rps", no_argument, NULL, 0 },
     { "analysis-reuse-mode", required_argument, NULL, 0 }, /* DEPRECATED */
     { "analysis-reuse-file", required_argument, NULL, 0 },
-    { "analysis-reuse-level", required_argument, NULL, 0 },
+    { "analysis-reuse-level", required_argument, NULL, 0 }, /* DEPRECATED */
+    { "analysis-save-reuse-level", required_argument, NULL, 0 },
+    { "analysis-load-reuse-level", required_argument, NULL, 0 },
     { "analysis-save",  required_argument, NULL, 0 },
     { "analysis-load",  required_argument, NULL, 0 },
     { "scale-factor",   required_argument, NULL, 0 },
@@ -290,8 +299,12 @@ static const struct option long_options[
     { "no-ssim-rd",           no_argument, NULL, 0 },
     { "hdr",                  no_argument, NULL, 0 },
     { "no-hdr",               no_argument, NULL, 0 },
+    { "hdr10",                no_argument, NULL, 0 },
+    { "no-hdr10",             no_argument, NULL, 0 },
     { "hdr-opt",              no_argument, NULL, 0 },
     { "no-hdr-opt",           no_argument, NULL, 0 },
+    { "hdr10-opt",            no_argument, NULL, 0 },
+    { "no-hdr10-opt",         no_argument, NULL, 0 },
     { "limit-sao",            no_argument, NULL, 0 },
     { "no-limit-sao",         no_argument, NULL, 0 },
     { "dhdr10-info",    required_argument, NULL, 0 },
@@ -321,6 +334,9 @@ static const struct option long_options[
     { "hevc-aq", no_argument, NULL, 0 },
     { "no-hevc-aq", no_argument, NULL, 0 },
     { "qp-adaptation-range", required_argument, NULL, 0 },
+    { "frame-dup",            no_argument, NULL, 0 },
+    { "no-frame-dup", no_argument, NULL, 0 },
+    { "dup-threshold", required_argument, NULL, 0 },
 #ifdef SVT_HEVC
     { "svt",     no_argument, NULL, 0 },
     { "no-svt",  no_argument, NULL, 0 },
@@ -341,6 +357,7 @@ static const struct option long_options[
 #endif
     { "cll", no_argument, NULL, 0 },
     { "no-cll", no_argument, NULL, 0 },
+    { "hme-range", required_argument, NULL, 0 },
     { 0, 0, 0, 0 },
     { 0, 0, 0, 0 },
     { 0, 0, 0, 0 },
@@ -469,6 +486,7 @@ static void showHelp(x265_param *param)
     H1("   --[no-]temporal-mvp           Enable temporal MV predictors. Default %s\n", OPT(param->bEnableTemporalMvp));
     H1("   --[no-]hme                    Enable Hierarchical Motion Estimation. Default %s\n", OPT(param->bEnableHME));
     H1("   --hme-search <string>         Motion search-method for HME L0,L1 and L2. Default(L0,L1,L2) is %d,%d,%d\n", param->hmeSearchMethod[0], param->hmeSearchMethod[1], param->hmeSearchMethod[2]);
+    H1("   --hme-range <int>,<int>,<int> Motion search-range for HME L0,L1 and L2. Default(L0,L1,L2) is %d,%d,%d\n", param->hmeRange[0], param->hmeRange[1], param->hmeRange[2]);
     H0("\nSpatial / intra options:\n");
     H0("   --[no-]strong-intra-smoothing Enable strong intra smoothing for 32x32 blocks. Default %s\n", OPT(param->bEnableStrongIntraSmoothing));
     H0("   --[no-]constrained-intra      Constrained intra prediction (use only intra coded reference pixels) Default %s\n", OPT(param->bEnableConstrainedIntra));
@@ -482,8 +500,14 @@ static void showHelp(x265_param *param)
     H0("   --gop-lookahead <integer>     Extends gop boundary if a scenecut is found within this from keyint boundary. Default 0\n");
     H0("   --no-scenecut                 Disable adaptive I-frame decision\n");
     H0("   --scenecut <integer>          How aggressively to insert extra I-frames. Default %d\n", param->scenecutThreshold);
-    H1("   --scenecut-bias <0..100.0>    Bias for scenecut detection. Default %.2f\n", param->scenecutBias);
+    H1("   --scenecut-bias <0..100.0>    Bias for scenecut detection. Default %.2f\n", param->scenecutBias); 
+    H0("   --hist-scenecut               Enables histogram based scene-cut detection using histogram based algorithm.\n");
+    H0("   --no-hist-scenecut            Disables histogram based scene-cut detection using histogram based algorithm.\n");
+    H1("   --hist-threshold <0.0..2.0>   Luma Edge histogram's Normalized SAD threshold for histogram based scenecut detection Default %.2f\n", param->edgeTransitionThreshold);
     H0("   --[no-]fades                  Enable detection and handling of fade-in regions. Default %s\n", OPT(param->bEnableFades));
+    H1("   --[no-]scenecut-aware-qp      Enable increasing QP for frames inside the scenecut window after scenecut. Default %s\n", OPT(param->bEnableSceneCutAwareQp));
+    H1("   --scenecut-window <0..1000>   QP incremental duration(in milliseconds) when scenecut-aware-qp is enabled. Default %d\n", param->scenecutWindow);
+    H1("   --max-qp-delta <0..10>        QP offset to increment with base QP for inter-frames. Default %d\n", param->maxQpDelta);
     H0("   --radl <integer>              Number of RADL pictures allowed in front of IDR. Default %d\n", param->radl);
     H0("   --intra-refresh               Use Periodic Intra Refresh instead of IDR frames\n");
     H0("   --rc-lookahead <integer>      Number of frames for frame-type lookahead (determines encoder latency) Default %d\n", param->lookaheadDepth);
@@ -531,7 +555,9 @@ static void showHelp(x265_param *param)
     H0("   --analysis-save <filename>    Dump analysis info into the specified file. Default Disabled\n");
     H0("   --analysis-load <filename>    Load analysis buffers from the file specified. Default Disabled\n");
     H0("   --analysis-reuse-file <filename>    Specify file name used for either dumping or reading analysis data. Deault x265_analysis.dat\n");
-    H0("   --analysis-reuse-level <1..10>      Level of analysis reuse indicates amount of info stored/reused in save/load mode, 1:least..10:most. Default %d\n", param->analysisReuseLevel);
+    H0("   --analysis-reuse-level <1..10>      Level of analysis reuse indicates amount of info stored/reused in save/load mode, 1:least..10:most. Now deprecated. Default %d\n", param->analysisReuseLevel);
+    H0("   --analysis-save-reuse-level <1..10> Indicates the amount of analysis info stored in save mode, 1:least..10:most. Default %d\n", param->analysisSaveReuseLevel);
+    H0("   --analysis-load-reuse-level <1..10> Indicates the amount of analysis info reused in load mode, 1:least..10:most. Default %d\n", param->analysisLoadReuseLevel);
     H0("   --refine-analysis-type <string>     Reuse anlaysis information received through API call. Supported options are avc and hevc. Default disabled - %d\n", param->bAnalysisType);
     H0("   --scale-factor <int>          Specify factor by which input video is scaled down for analysis save mode. Default %d\n", param->scaleFactor);
     H0("   --refine-intra <0..4>         Enable intra refinement for encode that uses analysis-load.\n"
@@ -612,8 +638,9 @@ static void showHelp(x265_param *param)
     H0("                                    format: G(x,y)B(x,y)R(x,y)WP(x,y)L(max,min)\n");
     H0("   --max-cll <string>            Specify content light level info SEI as \"cll,fall\" (HDR).\n");
     H0("   --[no-]cll                    Emit content light level info SEI. Default %s\n", OPT(param->bEmitCLL));
-    H0("   --[no-]hdr                    Control dumping of HDR SEI packet. If max-cll or master-display has non-zero values, this is enabled. Default %s\n", OPT(param->bEmitHDRSEI));
-    H0("   --[no-]hdr-opt                Add luma and chroma offsets for HDR/WCG content. Default %s\n", OPT(param->bHDROpt));
+    H0("   --[no-]hdr10                  Control dumping of HDR10 SEI packet. If max-cll or master-display has non-zero values, this is enabled. Default %s\n", OPT(param->bEmitHDR10SEI));
+    H0("   --[no-]hdr-opt                Add luma and chroma offsets for HDR/WCG content. Default %s. Now deprecated.\n", OPT(param->bHDROpt));
+    H0("   --[no-]hdr10-opt              Block-level QP optimization for HDR10 content. Default %s.\n", OPT(param->bHDR10Opt));
     H0("   --min-luma <integer>          Minimum luma plane value of input source picture\n");
     H0("   --max-luma <integer>          Maximum luma plane value of input source picture\n");
     H0("\nBitstream options:\n");
@@ -638,6 +665,8 @@ static void showHelp(x265_param *param)
     H1("   --recon-depth <integer>       Bit-depth of reconstructed raw image file. Defaults to input bit depth, or 8 if Y4M\n");
     H1("   --recon-y4m-exec <string>     pipe reconstructed frames to Y4M viewer, ex:\"ffplay -i pipe:0 -autoexit\"\n");
     H0("   --lowpass-dct                 Use low-pass subband dct approximation. Default %s\n", OPT(param->bLowPassDct));
+    H0("   --[no-]frame-dup              Enable Frame duplication. Default %s\n", OPT(param->bEnableFrameDuplication));
+    H0("   --dup-threshold <integer>     PSNR threshold for Frame duplication. Default %d\n", param->dupThreshold);
 #ifdef SVT_HEVC
     H0("   --[no]svt                     Enable SVT HEVC encoder %s\n", OPT(param->bEnableSvtHevc));
     H0("   --[no-]svt-hme                Enable Hierarchial motion estimation(HME) in SVT HEVC encoder \n");