Overview

Request 4371 (accepted)

- Support 10 and 12 bit color depths
- Update to version 3.0
New features
* option:: '--dolby-vision-profile ' generates
bitstreams confirming to the specified Dolby Vision profile.
Currently profile 5, profile 8.1 and profile 8.2 enabled,
Default 0 (disabled)
* option:: '--dolby-vision-rpu' File containing Dolby Vision RPU
metadata. If given, x265's Dolby Vision metadata parser will
fill the RPU field of input pictures with the metadata read
from the file. The library will interleave access units with
RPUs in the bitstream. Default NULL (disabled).
* option:: '--zonefile ' specifies a text file which
contains the boundaries of the zones where each of zones are
configurable.
* option:: '--qp-adaptation-range' Delta-QP range by QP
adaptation based on a psycho-visual model. Default 1.0.
* option:: '--refine-ctu-distortion <0/1>' store/normalize ctu
distortion in analysis-save/load. Default 0.
* Experimental feature option:: '--hevc-aq' enables adaptive
quantization. It scales the quantization step size according
to the spatial activity of one coding unit relative to frame
average spatial activity. This AQ method utilizes the minimum
variance of sub-unit in each coding unit to represent the
coding unit's spatial complexity.
Encoder enhancements
* Preset: change param defaults for veryslow and slower preset.
Replace slower preset with defaults used in veryslow preset
and change param defaults in veryslow preset as per
experimental results.

Submit package home:antlarr:branches:Essentials / x265 to package Essentials / x265

x265.changes Changed
x
 
1
@@ -1,4 +1,53 @@
2
 -------------------------------------------------------------------
3
+Fri Feb  1 00:32:50 UTC 2019 - antonio.larrosa@gmail.com
4
+
5
+- Support 10 and 12 bit color depths
6
+
7
+- Update to version 3.0
8
+  New features
9
+  * option:: '--dolby-vision-profile <integer|float>' generates
10
+    bitstreams confirming to the specified Dolby Vision profile.
11
+    Currently profile 5, profile 8.1 and profile 8.2 enabled,
12
+    Default 0 (disabled)
13
+  * option:: '--dolby-vision-rpu' File containing Dolby Vision RPU
14
+    metadata. If given, x265's Dolby Vision metadata parser will
15
+    fill the RPU field of input pictures with the metadata read
16
+    from the file. The library will interleave access units with
17
+    RPUs in the bitstream. Default NULL (disabled).
18
+  * option:: '--zonefile <filename>' specifies a text file which
19
+    contains the boundaries of the zones where each of zones are
20
+    configurable.
21
+  * option:: '--qp-adaptation-range' Delta-QP range by QP
22
+    adaptation based on a psycho-visual model. Default 1.0.
23
+  * option:: '--refine-ctu-distortion <0/1>' store/normalize ctu
24
+    distortion in analysis-save/load. Default 0.
25
+  * Experimental feature option:: '--hevc-aq' enables adaptive
26
+    quantization. It scales the quantization step size according
27
+    to the spatial activity of one coding unit relative to frame
28
+    average spatial activity. This AQ method utilizes the minimum
29
+    variance of sub-unit in each coding unit to represent the
30
+    coding unit's spatial complexity.
31
+  Encoder enhancements
32
+  * Preset: change param defaults for veryslow and slower preset.
33
+    Replace slower preset with defaults used in veryslow preset
34
+    and change param defaults in veryslow preset as per
35
+    experimental results.
36
+  * AQ: change default AQ mode to auto-variance
37
+  * Cutree offset reuse: restricted to analysis reuse-level 10 for
38
+    analysis-save -> analysis-load
39
+  * Tune: introduce --tune animation option which improves encode
40
+    quality for animated content
41
+  * Reuse CU depth for B frame and allow I, P frame to follow
42
+    x265 depth decision
43
+  Bug fixes
44
+  * RC: fix rowStat computation in const-vbv
45
+  * Dynamic-refine: fix memory reset size.
46
+  * Fix linking issue on non x86 platform
47
+  * Encoder: Do not include CLL SEI message if empty
48
+  * Fix build error in VMAF lib
49
+- Rebase x265-fix_enable512.patch
50
+
51
+-------------------------------------------------------------------
52
 Tue Oct  9 20:03:53 UTC 2018 - aloisio@gmx.com
53
 
54
 - Update to version 2.9
55
x265.spec Changed
72
 
1
@@ -1,10 +1,10 @@
2
 # based on the spec file from https://build.opensuse.org/package/view_file/home:Simmphonie/libx265/
3
 
4
 Name:           x265
5
-%define soname  165
6
+%define soname  169
7
 %define libname lib%{name}
8
 %define libsoname %{libname}-%{soname}
9
-Version:        2.9
10
+Version:        3.0
11
 Release:        0
12
 License:        GPL-2.0+
13
 Summary:        A free h265/HEVC encoder - encoder binary
14
@@ -57,14 +57,52 @@
15
 
16
 
17
 %build
18
-%if 0%{?suse_version} < 1500
19
-cd source
20
-%else
21
-%define __builddir ./source/build
22
+SOURCE_DIR="$PWD"/source
23
+COMMON_FLAGS="-DENABLE_TESTS=OFF -DENABLE_PIC=ON"
24
+HIGH_BIT_DEPTH_FLAGS="-DENABLE_CLI=OFF -DENABLE_SHARED=OFF -DEXPORT_C_API=OFF -DHIGH_BIT_DEPTH=ON"
25
+
26
+%if 0%{?suse_version} >= 1500
27
 %define __sourcedir ./source
28
+
29
+# Build 10bit depth version of the library
30
+%define __builddir ./source/build-10bit
31
+%cmake $COMMON_FLAGS $HIGH_BIT_DEPTH_FLAGS \
32
+%ifarch i586
33
+      -DENABLE_ASSEMBLY=OFF
34
+%endif
35
+
36
+make %{?_smp_mflags}
37
+cd ../..
38
+
39
+# Build 12bit depth version of the library
40
+%define __builddir ./source/build-12bit
41
+%cmake $COMMON_FLAGS $HIGH_BIT_DEPTH_FLAGS -DMAIN12=ON \
42
+%ifarch i586
43
+      -DENABLE_ASSEMBLY=OFF
44
+%endif
45
+
46
+make %{?_smp_mflags}
47
+cd ../..
48
+
49
+mv source/build-10bit/libx265.a source/build-10bit/libx265_main10.a
50
+mv source/build-12bit/libx265.a source/build-12bit/libx265_main12.a
51
+
52
+# Build general version of the library linking in the 10/12bit depth versions
53
+%define __builddir ./source/build
54
+%cmake -DENABLE_TESTS=OFF \
55
+       -DENABLE_PIC=ON \
56
+       -DENABLE_CLI=ON \
57
+       -DLINKED_10BIT=ON \
58
+       -DLINKED_12BIT=ON \
59
+       -DEXTRA_LINK_FLAGS="-L$SOURCE_DIR/build-10bit -L$SOURCE_DIR/build-12bit" \
60
+       -DEXTRA_LIB="x265_main10.a;x265_main12.a"
61
+
62
+%else
63
+cd source
64
+%cmake $COMMON_FLAGS
65
 %endif
66
-%cmake -DENABLE_TESTS=OFF
67
 make %{?_smp_mflags}
68
+cd ../../
69
 
70
 %install
71
 %if 0%{?suse_version} < 1500
72
x265-fix_enable512.patch Changed
18
 
1
@@ -12,7 +12,7 @@
2
  #if X265_ARCH_X86
3
  
4
  extern "C" {
5
-@@ -123,10 +128,6 @@ uint64_t PFX(cpu_xgetbv)(int xcr);
6
+@@ -123,11 +128,6 @@ uint64_t PFX(cpu_xgetbv)(int xcr);
7
  #pragma warning(disable: 4309) // truncation of constant value
8
  #endif
9
  
10
@@ -20,6 +20,7 @@
11
 -{
12
 -    return(enable512);
13
 -}
14
+-
15
  uint32_t cpu_detect(bool benableavx512 )
16
  {
17
  
18
baselibs.conf Changed
4
 
1
@@ -1,1 +1,1 @@
2
-libx265-151
3
+libx265-169
4
x265_2.9.tar.gz/.hg_archival.txt -> x265_3.0.tar.gz/.hg_archival.txt Changed
8
 
1
@@ -1,4 +1,4 @@
2
 repo: 09fe40627f03a0f9c3e6ac78b22ac93da23f9fdf
3
-node: f9681d731f2e56c2ca185cec10daece5939bee07
4
+node: 72188bd2f03447e71e789a5fd2f10364bb232c2c
5
 branch: stable
6
-tag: 2.9
7
+tag: 3.0
8
x265_2.9.tar.gz/.hgtags -> x265_3.0.tar.gz/.hgtags Changed
10
 
1
@@ -27,3 +27,8 @@
2
 0e9ea76945c89962cd46cee6537586e2054b2935 2.6
3
 e41a9bf2bac4a7af2bec2bbadf91e63752d320ef 2.7
4
 a158a3a029663133455268e2a63ae6b0af2df720 2.8
5
+f9681d731f2e56c2ca185cec10daece5939bee07 2.9
6
+bad4e598cac7cdd3df4623c68c91299c620471bd 3.0-rc
7
+bad4e598cac7cdd3df4623c68c91299c620471bd 3.0-rc
8
+0000000000000000000000000000000000000000 3.0-rc
9
+1307fd7b2b9984f45179db01432305a416713049 3.0_RC
10
x265_2.9.tar.gz/doc/reST/cli.rst -> x265_3.0.tar.gz/doc/reST/cli.rst Changed
125
 
1
@@ -388,7 +388,7 @@
2
    be applied after :option:`--preset` but before all other parameters. Default none.
3
    See :ref:`tunings <tunings>` for more detail.
4
 
5
-   **Values:** psnr, ssim, grain, zero-latency, fast-decode.
6
+   **Values:** psnr, ssim, grain, zero-latency, fast-decode, animation.
7
 
8
 .. option:: --slices <integer>
9
 
10
@@ -930,6 +930,14 @@
11
    Reuse MV information received through API call. Currently receives information for AVC size and the accepted 
12
    string input is "avc". Default is disabled.
13
 
14
+.. option:: --refine-ctu-distortion <0/1>
15
+
16
+    Store/normalize ctu distortion in analysis-save/load.
17
+    0 - Disabled.
18
+    1 - Save ctu distortion to the analysis file specified during analysis-save.
19
+        Load CTU distortion from the analysis file and normalize it across every frame during analysis-load.
20
+    Default 0.
21
+
22
 .. option:: --scale-factor
23
 
24
    Factor by which input video is scaled down for analysis save mode.
25
@@ -1506,7 +1514,7 @@
26
    0 - flush the encoder only when all the input pictures are over.
27
    1 - flush all the frames even when the input is not over. 
28
        slicetype decision may change with this option.
29
-   2 - flush the slicetype decided frames only.     
30
+   2 - flush the slicetype decided frames only.   
31
 
32
 Quality, rate control and rate distortion options
33
 =================================================
34
@@ -1622,8 +1630,8 @@
35
    and not enough in flat areas.
36
 
37
    0. disabled
38
-   1. AQ enabled **(default)**
39
-   2. AQ enabled with auto-variance
40
+   1. AQ enabled 
41
+   2. AQ enabled with auto-variance **(default)**
42
    3. AQ enabled with auto-variance and bias to dark scenes. This is 
43
    recommended for 8-bit encodes or low-bitrate 10-bit encodes, to 
44
    prevent color banding/blocking. 
45
@@ -1638,6 +1646,21 @@
46
    Default 1.0.
47
    **Range of values:** 0.0 to 3.0
48
 
49
+.. option:: --hevc-aq
50
+
51
+   Enable adaptive quantization
52
+   It scales the quantization step size according to the spatial activity of one
53
+   coding unit relative to frame average spatial activity. This AQ method utilizes
54
+   the minimum variance of sub-unit in each coding unit to represent the coding
55
+   unit’s spatial complexity.
56
+
57
+.. option:: --qp-adaptation-range
58
+
59
+   Delta-QP range by QP adaptation based on a psycho-visual model.
60
+
61
+   Default 1.0.
62
+   **Range of values:** 1.0 to 6.0
63
+
64
 .. option:: --aq-motion, --no-aq-motion
65
 
66
    Adjust the AQ offsets based on the relative motion of each block with
67
@@ -1818,6 +1841,20 @@
68
 
69
    If zones overlap, whichever comes later in the list takes precedence.
70
    Default none
71
+   
72
+   
73
+.. option:: --zonefile <filename>
74
+
75
+   Specify a text file which contains the boundaries of the zones where 
76
+   each of zones are configurable. The format of each line is:
77
+
78
+   <frame number> <options to be configured>
79
+
80
+   The frame number indicates the beginning of a zone. The options 
81
+   following this is applied until another zone begins. The reconfigurable 
82
+   options can be spcified as --<feature name> <feature value>
83
+   
84
+   **CLI ONLY**
85
 
86
 Quantization Options
87
 ====================
88
@@ -2195,6 +2232,36 @@
89
    Picture Timing SEI messages providing timing information to the
90
    decoder. Default disabled
91
 
92
+       
93
+.. option:: --hrd-concat, --no-hrd-concat
94
+
95
+    Set concantenation flag for the first keyframe in the HRD buffering period SEI. This
96
+    is to signal the decoder if splicing is performed during bitstream generation. 
97
+    Recommended to enable this option during chunked encoding, except for the first chunk.
98
+    Default disabled.
99
+
100
+.. option:: --dolby-vision-profile <integer|float>
101
+
102
+    Generate bitstreams confirming to the specified Dolby Vision profile,
103
+    note that 0x7C01 makes RPU appear to be an unspecified NAL type in
104
+    HEVC stream. If BL is backward compatible, Dolby Vision single
105
+    layer VES will be equivalent to a backward compatible BL VES on legacy
106
+    device as RPU will be ignored.
107
+    
108
+    The value is specified as a float or as an integer with the profile times 10,
109
+    for example profile 5 is specified as "5" or "5.0" or "50".
110
+    
111
+    Currently only profile 5, profile 8.1 and profile 8.2 enabled, Default 0 (disabled)
112
+
113
+.. option:: --dolby-vision-rpu <filename>
114
+
115
+    File containing Dolby Vision RPU metadata. If given, x265's Dolby Vision 
116
+    metadata parser will fill the RPU field of input pictures with the metadata
117
+    read from the file. The library will interleave access units with RPUs in the 
118
+    bitstream. Default NULL (disabled).
119
+   
120
+    **CLI ONLY**
121
+
122
 .. option:: --info, --no-info
123
 
124
    Emit an informational SEI with the stream headers which describes
125
x265_2.9.tar.gz/doc/reST/presets.rst -> x265_3.0.tar.gz/doc/reST/presets.rst Changed
92
 
1
@@ -43,33 +43,33 @@
2
 +-----------------+-----+-----+-----+-----+-----+-----+------+------+------+------+
3
 | b-adapt         |  0  |  0  |  0  |   0 |   0 |   2 |   2  |   2  |   2  |  2   |
4
 +-----------------+-----+-----+-----+-----+-----+-----+------+------+------+------+
5
-| rc-lookahead    |  5  | 10  | 15  |  15 |  15 |  20 |  25  |  30  |  40  | 60   |
6
+| rc-lookahead    |  5  | 10  | 15  |  15 |  15 |  20 |  25  |  40  |  40  | 60   |
7
 +-----------------+-----+-----+-----+-----+-----+-----+------+------+------+------+
8
-| lookahead-slices|  8  |  8  |  8  |   8 |   8 |   8 |   4  |   4  |   1  |  1   |
9
+| lookahead-slices|  8  |  8  |  8  |   8 |   8 |   8 |   4  |   1  |   1  |  1   |
10
 +-----------------+-----+-----+-----+-----+-----+-----+------+------+------+------+
11
 | scenecut        |  0  | 40  | 40  |  40 |  40 |  40 |  40  |  40  |  40  | 40   |
12
 +-----------------+-----+-----+-----+-----+-----+-----+------+------+------+------+
13
-| ref             |  1  |  1  |  2  |   2 |   3 |   3 |   4  |   4  |   5  |  5   |
14
+| ref             |  1  |  1  |  2  |   2 |   3 |   3 |   4  |   5  |   5  |  5   |
15
 +-----------------+-----+-----+-----+-----+-----+-----+------+------+------+------+
16
-| limit-refs      |  0  |  0  |  3  |   3 |   3 |   3 |   3  |   2  |   1  |  0   |
17
+| limit-refs      |  0  |  0  |  3  |   3 |   3 |   3 |   3  |   1  |   0  |  0   |
18
 +-----------------+-----+-----+-----+-----+-----+-----+------+------+------+------+
19
 | me              | dia | hex | hex | hex | hex | hex | star | star | star | star |
20
 +-----------------+-----+-----+-----+-----+-----+-----+------+------+------+------+
21
 | merange         | 57  | 57  | 57  |  57 |  57 |  57 |  57  |  57  |  57  | 92   |
22
 +-----------------+-----+-----+-----+-----+-----+-----+------+------+------+------+
23
-| subme           |  0  |  1  |  1  |   2 |   2 |   2 |   3  |   3  |   4  |  5   |
24
+| subme           |  0  |  1  |  1  |   2 |   2 |   2 |   3  |   4  |   4  |  5   |
25
 +-----------------+-----+-----+-----+-----+-----+-----+------+------+------+------+
26
 | rect            |  0  |  0  |  0  |   0 |   0 |   0 |   1  |   1  |   1  |  1   |
27
 +-----------------+-----+-----+-----+-----+-----+-----+------+------+------+------+
28
 | amp             |  0  |  0  |  0  |   0 |   0 |   0 |   0  |   1  |   1  |  1   |
29
 +-----------------+-----+-----+-----+-----+-----+-----+------+------+------+------+
30
-| limit-modes     |  0  |  0  |  0  |   0 |   0 |   0 |   1  |   1  |   1  |  0   |
31
+| limit-modes     |  0  |  0  |  0  |   0 |   0 |   0 |   1  |   1  |   0  |  0   |
32
 +-----------------+-----+-----+-----+-----+-----+-----+------+------+------+------+
33
-| max-merge       |  2  |  2  |  2  |   2 |   2 |   2 |   3  |   3  |   4  |  5   |
34
+| max-merge       |  2  |  2  |  2  |   2 |   2 |   2 |   3  |   4  |   5  |  5   |
35
 +-----------------+-----+-----+-----+-----+-----+-----+------+------+------+------+
36
 | early-skip      |  1  |  1  |  1  |   1 |   0 |   0 |   0  |   0  |   0  |  0   |
37
 +-----------------+-----+-----+-----+-----+-----+-----+------+------+------+------+
38
-| recursion-skip  |  1  |  1  |  1  |   1 |   1 |   1 |   1  |   1  |   0  |  0   |
39
+| recursion-skip  |  1  |  1  |  1  |   1 |   1 |   1 |   1  |   0  |   0  |  0   |
40
 +-----------------+-----+-----+-----+-----+-----+-----+------+------+------+------+
41
 | fast-intra      |  1  |  1  |  1  |   1 |   1 |   0 |   0  |   0  |   0  |  0   |
42
 +-----------------+-----+-----+-----+-----+-----+-----+------+------+------+------+
43
@@ -83,7 +83,7 @@
44
 +-----------------+-----+-----+-----+-----+-----+-----+------+------+------+------+
45
 | weightb         |  0  |  0  |  0  |   0 |   0 |   0 |   0  |   1  |   1  |  1   |
46
 +-----------------+-----+-----+-----+-----+-----+-----+------+------+------+------+
47
-| aq-mode         |  0  |  0  |  1  |   1 |   1 |   1 |   1  |   1  |   1  |  1   |
48
+| aq-mode         |  0  |  0  |  2  |   2 |   2 |   2 |   2  |   2  |   2  |  2   |
49
 +-----------------+-----+-----+-----+-----+-----+-----+------+------+------+------+
50
 | cuTree          |  1  |  1  |  1  |   1 |   1 |   1 |   1  |   1  |   1  |  1   |
51
 +-----------------+-----+-----+-----+-----+-----+-----+------+------+------+------+
52
@@ -91,11 +91,11 @@
53
 +-----------------+-----+-----+-----+-----+-----+-----+------+------+------+------+
54
 | rdoq-level      |  0  |  0  |  0  |   0 |   0 |   0 |   2  |   2  |   2  |  2   |
55
 +-----------------+-----+-----+-----+-----+-----+-----+------+------+------+------+
56
-| tu-intra        |  1  |  1  |  1  |   1 |   1 |   1 |   1  |   2  |   3  |  4   |
57
+| tu-intra        |  1  |  1  |  1  |   1 |   1 |   1 |   1  |   3  |   3  |  4   |
58
 +-----------------+-----+-----+-----+-----+-----+-----+------+------+------+------+
59
-| tu-inter        |  1  |  1  |  1  |   1 |   1 |   1 |   1  |   2  |   3  |  4   |
60
+| tu-inter        |  1  |  1  |  1  |   1 |   1 |   1 |   1  |   3  |   3  |  4   |
61
 +-----------------+-----+-----+-----+-----+-----+-----+------+------+------+------+
62
-| limit-tu        |  0  |  0  |  0  |   0 |   0 |   0 |   0  |   4  |   4  |  0   |
63
+| limit-tu        |  0  |  0  |  0  |   0 |   0 |   0 |   0  |   4  |   0  |  0   |
64
 +-----------------+-----+-----+-----+-----+-----+-----+------+------+------+------+
65
 
66
 .. _tunings:
67
@@ -128,6 +128,8 @@
68
 +--------------+-----------------------------------------------------+
69
 | zerolatency  | no lookahead, no B frames, no cutree                |
70
 +--------------+-----------------------------------------------------+
71
+| animation    | improves encode quality for animated content        |
72
++--------------+-----------------------------------------------------+
73
 
74
 
75
 
76
@@ -203,3 +205,14 @@
77
 x265 performance. If you can tolerate any latency on the encoder, you
78
 can increase performance by increasing the number of frame threads. Each
79
 additional frame thread adds one frame of latency.
80
+
81
+Animation
82
+~~~~~~~~~
83
+
84
+:option:`--tune` *animation* adjusts encoder settings to optimize the encode 
85
+quality for animation content without impacting the encode speed. This is done by:
86
+
87
+    * :option:`--psy-rd` 0.4
88
+    * :option:`--aq-strength` 0.4
89
+    * :option:`--deblock` 1:1
90
+    * :option:`--bframes` Increase by 2
91
\ No newline at end of file
92
x265_2.9.tar.gz/doc/reST/releasenotes.rst -> x265_3.0.tar.gz/doc/reST/releasenotes.rst Changed
45
 
1
@@ -1,6 +1,43 @@
2
 *************
3
 Release Notes
4
 *************
5
+Version 3.0
6
+===========
7
+
8
+Release date - 23/01/2019 
9
+
10
+New features
11
+-------------
12
+1. option:: '--dolby-vision-profile <integer|float>' generates bitstreams confirming to the specified Dolby Vision profile. Currently profile 5, profile 8.1 and profile 8.2 enabled, Default 0 (disabled)
13
+
14
+2. option:: '--dolby-vision-rpu' File containing Dolby Vision RPU metadata. If given, x265's Dolby Vision metadata parser will fill the RPU field of input pictures with the metadata
15
+    read from the file. The library will interleave access units with RPUs in the bitstream. Default NULL (disabled).  
16
+
17
+3. option:: '--zonefile <filename>' specifies a text file which contains the boundaries of the zones where each of zones are configurable.
18
+
19
+4. option:: '--qp-adaptation-range'    Delta-QP range by QP adaptation based on a psycho-visual model. Default 1.0. 
20
+
21
+5. option:: '--refine-ctu-distortion <0/1>' store/normalize ctu distortion in analysis-save/load. Default 0. 
22
+
23
+6. Experimental feature option:: '--hevc-aq' enables adaptive quantization
24
+   It scales the quantization step size according to the spatial activity of one coding unit relative to frame average spatial activity. This AQ method utilizes
25
+   the minimum variance of sub-unit in each coding unit to represent the coding unit’s spatial complexity. 
26
+
27
+Encoder enhancements
28
+--------------------
29
+1. Preset: change param defaults for veryslow and slower preset. Replace slower preset with defaults used in veryslow preset and change param defaults in veryslow preset as per experimental results.
30
+2. AQ: change default AQ mode to auto-variance
31
+3. Cutree offset reuse: restricted to analysis reuse-level 10 for analysis-save -> analysis-load 
32
+4. Tune: introduce --tune animation option which improves encode quality for animated content 
33
+5. Reuse CU depth for B frame and allow I, P frame to follow x265 depth decision
34
+
35
+Bug fixes
36
+---------
37
+1. RC: fix rowStat computation in const-vbv
38
+2. Dynamic-refine: fix memory reset size.
39
+3. Fix Issue #442: linking issue on non x86 platform
40
+4. Encoder: Do not include CLL SEI message if empty
41
+5. Fix issue #441 build error in VMAF lib
42
 
43
 Version 2.9
44
 ===========
45
x265_2.9.tar.gz/source/CMakeLists.txt -> x265_3.0.tar.gz/source/CMakeLists.txt Changed
32
 
1
@@ -29,7 +29,7 @@
2
 option(STATIC_LINK_CRT "Statically link C runtime for release builds" OFF)
3
 mark_as_advanced(FPROFILE_USE FPROFILE_GENERATE NATIVE_BUILD)
4
 # X265_BUILD must be incremented each time the public API is changed
5
-set(X265_BUILD 165)
6
+set(X265_BUILD 169)
7
 configure_file("${PROJECT_SOURCE_DIR}/x265.def.in"
8
                "${PROJECT_BINARY_DIR}/x265.def")
9
 configure_file("${PROJECT_SOURCE_DIR}/x265_config.h.in"
10
@@ -200,6 +200,9 @@
11
 if(GCC)
12
     add_definitions(-Wall -Wextra -Wshadow)
13
     add_definitions(-D__STDC_LIMIT_MACROS=1)
14
+    if(NOT INTEL_CXX AND NOT CLANG AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 8.0)
15
+        add_definitions(-Wno-class-memaccess)
16
+    endif()
17
     if(ENABLE_HDR10_PLUS)
18
         if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.8")
19
             message(FATAL_ERROR "gcc version above 4.8 required to support hdr10plus")
20
@@ -572,10 +575,9 @@
21
     # often breaks them
22
     string(REPLACE "<FLAGS>" "" CMAKE_RC_COMPILE_OBJECT "${CMAKE_RC_COMPILE_OBJECT}")
23
     string(REPLACE "<DEFINES>" "" CMAKE_RC_COMPILE_OBJECT "${CMAKE_RC_COMPILE_OBJECT}")
24
-
25
     # convert X265_LATEST_TAG (ex: 0.7) and X265_TAG_DISTANCE (ex: 103) to
26
     # @X265_VERSION_MAJOR@,@X265_VERSION_MINOR@,@X265_BRANCH_ID@,@X265_TAG_DISTANCE@
27
-    string(REPLACE "." ";" VERSION_LIST "${X265_LATEST_TAG}")
28
+    string(REGEX MATCHALL "([0-9]+)" VERSION_LIST "${X265_LATEST_TAG}")
29
     list(GET VERSION_LIST 0 X265_VERSION_MAJOR)
30
     list(GET VERSION_LIST 1 X265_VERSION_MINOR)
31
     set(X265_BRANCH_ID 0) # TODO: 0 - stable, 1 - default or other
32
x265_2.9.tar.gz/source/common/cpu.cpp -> x265_3.0.tar.gz/source/common/cpu.cpp Changed
9
 
1
@@ -127,6 +127,7 @@
2
 {
3
     return(enable512);
4
 }
5
+
6
 uint32_t cpu_detect(bool benableavx512 )
7
 {
8
 
9
x265_2.9.tar.gz/source/common/cudata.cpp -> x265_3.0.tar.gz/source/common/cudata.cpp Changed
88
 
1
@@ -193,6 +193,7 @@
2
         uint8_t *charBuf = dataPool.charMemBlock + (m_numPartitions * (BytesPerPartition - 4)) * instance;
3
 
4
         m_qp        = (int8_t*)charBuf; charBuf += m_numPartitions;
5
+        m_qpAnalysis = (int8_t*)charBuf; charBuf += m_numPartitions;
6
         m_log2CUSize         = charBuf; charBuf += m_numPartitions;
7
         m_lumaIntraDir       = charBuf; charBuf += m_numPartitions;
8
         m_tqBypass           = charBuf; charBuf += m_numPartitions;
9
@@ -233,6 +234,7 @@
10
         uint8_t *charBuf = dataPool.charMemBlock + (m_numPartitions * BytesPerPartition) * instance;
11
 
12
         m_qp        = (int8_t*)charBuf; charBuf += m_numPartitions;
13
+        m_qpAnalysis = (int8_t*)charBuf; charBuf += m_numPartitions;
14
         m_log2CUSize         = charBuf; charBuf += m_numPartitions;
15
         m_lumaIntraDir       = charBuf; charBuf += m_numPartitions;
16
         m_tqBypass           = charBuf; charBuf += m_numPartitions;
17
@@ -291,6 +293,7 @@
18
 
19
     /* sequential memsets */
20
     m_partSet((uint8_t*)m_qp, (uint8_t)qp);
21
+    m_partSet((uint8_t*)m_qpAnalysis, (uint8_t)qp);
22
     m_partSet(m_log2CUSize,   (uint8_t)m_slice->m_param->maxLog2CUSize);
23
     m_partSet(m_lumaIntraDir, (uint8_t)ALL_IDX);
24
     m_partSet(m_chromaIntraDir, (uint8_t)ALL_IDX);
25
@@ -304,7 +307,7 @@
26
     X265_CHECK(!(frame.m_encData->m_param->bLossless && !m_slice->m_pps->bTransquantBypassEnabled), "lossless enabled without TQbypass in PPS\n");
27
 
28
     /* initialize the remaining CU data in one memset */
29
-    memset(m_cuDepth, 0, (frame.m_param->internalCsp == X265_CSP_I400 ? BytesPerPartition - 11 : BytesPerPartition - 7) * m_numPartitions);
30
+    memset(m_cuDepth, 0, (frame.m_param->internalCsp == X265_CSP_I400 ? BytesPerPartition - 12 : BytesPerPartition - 8) * m_numPartitions);
31
 
32
     for (int8_t i = 0; i < NUM_TU_DEPTH; i++)
33
         m_refTuDepth[i] = -1;
34
@@ -344,6 +347,7 @@
35
     X265_CHECK(m_numPartitions == cuGeom.numPartitions, "initSubCU() size mismatch\n");
36
 
37
     m_partSet((uint8_t*)m_qp, (uint8_t)qp);
38
+    m_partSet((uint8_t*)m_qpAnalysis, (uint8_t)qp);
39
 
40
     m_partSet(m_log2CUSize,   (uint8_t)cuGeom.log2CUSize);
41
     m_partSet(m_lumaIntraDir, (uint8_t)ALL_IDX);
42
@@ -354,7 +358,7 @@
43
     m_partSet(m_cuDepth,      (uint8_t)cuGeom.depth);
44
 
45
     /* initialize the remaining CU data in one memset */
46
-    memset(m_predMode, 0, (ctu.m_chromaFormat == X265_CSP_I400 ? BytesPerPartition - 12 : BytesPerPartition - 8) * m_numPartitions);
47
+    memset(m_predMode, 0, (ctu.m_chromaFormat == X265_CSP_I400 ? BytesPerPartition - 13 : BytesPerPartition - 9) * m_numPartitions);
48
     memset(m_distortion, 0, m_numPartitions * sizeof(sse_t));
49
 }
50
 
51
@@ -369,6 +373,7 @@
52
     m_bLastCuInSlice = subCU.m_bLastCuInSlice;
53
 
54
     m_subPartCopy((uint8_t*)m_qp + offset, (uint8_t*)subCU.m_qp);
55
+    m_subPartCopy((uint8_t*)m_qpAnalysis + offset, (uint8_t*)subCU.m_qpAnalysis);
56
     m_subPartCopy(m_log2CUSize + offset, subCU.m_log2CUSize);
57
     m_subPartCopy(m_lumaIntraDir + offset, subCU.m_lumaIntraDir);
58
     m_subPartCopy(m_tqBypass + offset, subCU.m_tqBypass);
59
@@ -469,6 +474,7 @@
60
     CUData& ctu = *m_encData->getPicCTU(m_cuAddr);
61
 
62
     m_partCopy((uint8_t*)ctu.m_qp + m_absIdxInCTU, (uint8_t*)m_qp);
63
+    m_partCopy((uint8_t*)ctu.m_qpAnalysis + m_absIdxInCTU, (uint8_t*)m_qpAnalysis);
64
     m_partCopy(ctu.m_log2CUSize + m_absIdxInCTU, m_log2CUSize);
65
     m_partCopy(ctu.m_lumaIntraDir + m_absIdxInCTU, m_lumaIntraDir);
66
     m_partCopy(ctu.m_tqBypass + m_absIdxInCTU, m_tqBypass);
67
@@ -523,7 +529,11 @@
68
     m_numPartitions = cuGeom.numPartitions;
69
 
70
     /* copy out all prediction info for this part */
71
-    if (copyQp) m_partCopy((uint8_t*)m_qp, (uint8_t*)ctu.m_qp + m_absIdxInCTU);
72
+    if (copyQp)
73
+    {
74
+        m_partCopy((uint8_t*)m_qp, (uint8_t*)ctu.m_qp + m_absIdxInCTU);
75
+        m_partCopy((uint8_t*)m_qpAnalysis, (uint8_t*)ctu.m_qpAnalysis + m_absIdxInCTU);
76
+    }
77
 
78
     m_partCopy(m_log2CUSize,   ctu.m_log2CUSize + m_absIdxInCTU);
79
     m_partCopy(m_lumaIntraDir, ctu.m_lumaIntraDir + m_absIdxInCTU);
80
@@ -566,6 +576,7 @@
81
     CUData& ctu = *m_encData->getPicCTU(m_cuAddr);
82
 
83
     m_partCopy((uint8_t*)ctu.m_qp + m_absIdxInCTU, (uint8_t*)m_qp);
84
+    m_partCopy((uint8_t*)ctu.m_qpAnalysis + m_absIdxInCTU, (uint8_t*)m_qpAnalysis);
85
     m_partCopy(ctu.m_transformSkip[0] + m_absIdxInCTU, m_transformSkip[0]);
86
     m_partCopy(ctu.m_predMode + m_absIdxInCTU, m_predMode);
87
     m_partCopy(ctu.m_tuDepth + m_absIdxInCTU, m_tuDepth);
88
x265_2.9.tar.gz/source/common/cudata.h -> x265_3.0.tar.gz/source/common/cudata.h Changed
18
 
1
@@ -191,6 +191,7 @@
2
 
3
     /* Per-part data, stored contiguously */
4
     int8_t*       m_qp;               // array of QP values
5
+    int8_t*       m_qpAnalysis;       // array of QP values for analysis reuse
6
     uint8_t*      m_log2CUSize;       // array of cu log2Size TODO: seems redundant to depth
7
     uint8_t*      m_lumaIntraDir;     // array of intra directions (luma)
8
     uint8_t*      m_tqBypass;         // array of CU lossless flags
9
@@ -206,7 +207,7 @@
10
     uint8_t*      m_transformSkip[3]; // array of transform skipping flags per plane
11
     uint8_t*      m_cbf[3];           // array of coded block flags (CBF) per plane
12
     uint8_t*      m_chromaIntraDir;   // array of intra directions (chroma)
13
-    enum { BytesPerPartition = 23 };  // combined sizeof() of all per-part data
14
+    enum { BytesPerPartition = 24 };  // combined sizeof() of all per-part data
15
 
16
     sse_t*        m_distortion;
17
     coeff_t*      m_trCoeff[3];       // transformed coefficient buffer per plane
18
x265_2.9.tar.gz/source/common/frame.cpp -> x265_3.0.tar.gz/source/common/frame.cpp Changed
19
 
1
@@ -44,6 +44,8 @@
2
     m_param = NULL;
3
     m_userSEI.numPayloads = 0;
4
     m_userSEI.payloads = NULL;
5
+    m_rpu.payloadSize = 0;
6
+    m_rpu.payload = NULL;
7
     memset(&m_lowres, 0, sizeof(m_lowres));
8
     m_rcData = NULL;
9
     m_encodeStartTime = 0;
10
@@ -78,7 +80,7 @@
11
         }
12
     }
13
 
14
-    if (param->bMVType == AVC_INFO)
15
+    if (param->bAnalysisType == AVC_INFO)
16
     {
17
         m_analysisData.wt = NULL;
18
         m_analysisData.intraData = NULL;
19
x265_2.9.tar.gz/source/common/frame.h -> x265_3.0.tar.gz/source/common/frame.h Changed
9
 
1
@@ -98,6 +98,7 @@
2
 
3
     float*                 m_quantOffsets;       // points to quantOffsets in x265_picture
4
     x265_sei               m_userSEI;
5
+    x265_dolby_vision_rpu            m_rpu;
6
 
7
     /* Frame Parallelism - notification between FrameEncoders of available motion reference rows */
8
     ThreadSafeInteger*     m_reconRowFlag;       // flag of CTU rows completely reconstructed and extended for motion reference
9
x265_2.9.tar.gz/source/common/framedata.cpp -> x265_3.0.tar.gz/source/common/framedata.cpp Changed
14
 
1
@@ -83,9 +83,9 @@
2
     memset(m_rowStat, 0, sps.numCuInHeight * sizeof(*m_rowStat));
3
     if (m_param->bDynamicRefine)
4
     {
5
-        memset(m_picCTU->m_collectCURd, 0, MAX_NUM_DYN_REFINE * sizeof(uint64_t));
6
-        memset(m_picCTU->m_collectCUVariance, 0, MAX_NUM_DYN_REFINE * sizeof(uint32_t));
7
-        memset(m_picCTU->m_collectCUCount, 0, MAX_NUM_DYN_REFINE * sizeof(uint32_t));
8
+        memset(m_picCTU->m_collectCURd, 0, MAX_NUM_DYN_REFINE * sps.numCUsInFrame * sizeof(uint64_t));
9
+        memset(m_picCTU->m_collectCUVariance, 0, MAX_NUM_DYN_REFINE * sps.numCUsInFrame * sizeof(uint32_t));
10
+        memset(m_picCTU->m_collectCUCount, 0, MAX_NUM_DYN_REFINE * sps.numCUsInFrame * sizeof(uint32_t));
11
     }
12
 }
13
 
14
x265_2.9.tar.gz/source/common/lowres.cpp -> x265_3.0.tar.gz/source/common/lowres.cpp Changed
127
 
1
@@ -2,6 +2,7 @@
2
  * Copyright (C) 2013-2017 MulticoreWare, Inc
3
  *
4
  * Authors: Gopu Govindaswamy <gopu@multicorewareinc.com>
5
+ *          Ashok Kumar Mishra <ashok@multicorewareinc.com>
6
  *
7
  * This program is free software; you can redistribute it and/or modify
8
  * it under the terms of the GNU General Public License as published by
9
@@ -27,10 +28,31 @@
10
 
11
 using namespace X265_NS;
12
 
13
+bool PicQPAdaptationLayer::create(uint32_t width, uint32_t height, uint32_t partWidth, uint32_t partHeight, uint32_t numAQPartInWidthExt, uint32_t numAQPartInHeightExt)
14
+{
15
+    aqPartWidth = partWidth;
16
+    aqPartHeight = partHeight;
17
+    numAQPartInWidth = (width + partWidth - 1) / partWidth;
18
+    numAQPartInHeight = (height + partHeight - 1) / partHeight;
19
+
20
+    CHECKED_MALLOC_ZERO(dActivity, double, numAQPartInWidthExt * numAQPartInHeightExt);
21
+    CHECKED_MALLOC_ZERO(dQpOffset, double, numAQPartInWidthExt * numAQPartInHeightExt);
22
+    CHECKED_MALLOC_ZERO(dCuTreeOffset, double, numAQPartInWidthExt * numAQPartInHeightExt);
23
+
24
+    if (bQpSize)
25
+        CHECKED_MALLOC_ZERO(dCuTreeOffset8x8, double, numAQPartInWidthExt * numAQPartInHeightExt);
26
+
27
+    return true;
28
+fail:
29
+    return false;
30
+}
31
+
32
 bool Lowres::create(x265_param* param, PicYuv *origPic, uint32_t qgSize)
33
 {
34
     isLowres = true;
35
     bframes = param->bframes;
36
+    widthFullRes = origPic->m_picWidth;
37
+    heightFullRes = origPic->m_picHeight;
38
     width = origPic->m_picWidth / 2;
39
     lines = origPic->m_picHeight / 2;
40
     lumaStride = width + 2 * origPic->m_lumaMarginX;
41
@@ -49,7 +71,7 @@
42
 
43
     size_t planesize = lumaStride * (lines + 2 * origPic->m_lumaMarginY);
44
     size_t padoffset = lumaStride * origPic->m_lumaMarginY + origPic->m_lumaMarginX;
45
-    if (!!param->rc.aqMode)
46
+    if (!!param->rc.aqMode || !!param->rc.hevcAq)
47
     {
48
         CHECKED_MALLOC_ZERO(qpAqOffset, double, cuCountFullRes);
49
         CHECKED_MALLOC_ZERO(invQscaleFactor, int, cuCountFullRes);
50
@@ -57,10 +79,50 @@
51
         if (qgSize == 8)
52
             CHECKED_MALLOC_ZERO(invQscaleFactor8x8, int, cuCount);
53
     }
54
+
55
     if (origPic->m_param->bAQMotion)
56
         CHECKED_MALLOC_ZERO(qpAqMotionOffset, double, cuCountFullRes);
57
     if (origPic->m_param->bDynamicRefine)
58
         CHECKED_MALLOC_ZERO(blockVariance, uint32_t, cuCountFullRes);
59
+
60
+    if (!!param->rc.hevcAq)
61
+    {
62
+        m_maxCUSize = param->maxCUSize;
63
+        m_qgSize = qgSize;
64
+
65
+        uint32_t partWidth, partHeight, nAQPartInWidth, nAQPartInHeight;
66
+
67
+        pAQLayer = new PicQPAdaptationLayer[4];
68
+        maxAQDepth = 0;
69
+        for (uint32_t d = 0; d < 4; d++)
70
+        {
71
+            int ctuSizeIdx = 6 - g_log2Size[param->maxCUSize];
72
+            int aqDepth = g_log2Size[param->maxCUSize] - g_log2Size[qgSize];
73
+            if (!aqLayerDepth[ctuSizeIdx][aqDepth][d])
74
+                continue;
75
+
76
+            pAQLayer->minAQDepth = d;
77
+            partWidth = param->maxCUSize >> d;
78
+            partHeight = param->maxCUSize >> d;
79
+
80
+            if (minAQSize[ctuSizeIdx] == d)
81
+            {
82
+                pAQLayer[d].bQpSize = true;
83
+                nAQPartInWidth = maxBlocksInRow * 2;
84
+                nAQPartInHeight = maxBlocksInCol * 2;
85
+            }
86
+            else
87
+            {
88
+                pAQLayer[d].bQpSize = false;
89
+                nAQPartInWidth = (origPic->m_picWidth + partWidth - 1) / partWidth;
90
+                nAQPartInHeight = (origPic->m_picHeight + partHeight - 1) / partHeight;
91
+            }
92
+
93
+            maxAQDepth++;
94
+
95
+            pAQLayer[d].create(origPic->m_picWidth, origPic->m_picHeight, partWidth, partHeight, nAQPartInWidth, nAQPartInHeight);
96
+        }
97
+    }
98
     CHECKED_MALLOC(propagateCost, uint16_t, cuCount);
99
 
100
     /* allocate lowres buffers */
101
@@ -130,6 +192,25 @@
102
     X265_FREE(invQscaleFactor8x8);
103
     X265_FREE(qpAqMotionOffset);
104
     X265_FREE(blockVariance);
105
+    if (maxAQDepth > 0)
106
+    {
107
+        for (uint32_t d = 0; d < 4; d++)
108
+        {
109
+            int ctuSizeIdx = 6 - g_log2Size[m_maxCUSize];
110
+            int aqDepth = g_log2Size[m_maxCUSize] - g_log2Size[m_qgSize];
111
+            if (!aqLayerDepth[ctuSizeIdx][aqDepth][d])
112
+                continue;
113
+
114
+            X265_FREE(pAQLayer[d].dActivity);
115
+            X265_FREE(pAQLayer[d].dQpOffset);
116
+            X265_FREE(pAQLayer[d].dCuTreeOffset);
117
+
118
+            if (pAQLayer[d].bQpSize == true)
119
+                X265_FREE(pAQLayer[d].dCuTreeOffset8x8);
120
+        }
121
+
122
+        delete[] pAQLayer;
123
+    }
124
 }
125
 // (re) initialize lowres state
126
 void Lowres::init(PicYuv *origPic, int poc)
127
x265_2.9.tar.gz/source/common/lowres.h -> x265_3.0.tar.gz/source/common/lowres.h Changed
65
 
1
@@ -103,6 +103,49 @@
2
     }
3
 };
4
 
5
+static const uint32_t aqLayerDepth[3][4][4] = {
6
+    {  // ctu size 64
7
+        { 1, 0, 1, 0 },
8
+        { 1, 1, 1, 0 },
9
+        { 1, 1, 1, 0 },
10
+        { 1, 1, 1, 1 }
11
+    },
12
+    {  // ctu size 32
13
+        { 1, 1, 0, 0 },
14
+        { 1, 1, 0, 0 },
15
+        { 1, 1, 1, 0 },
16
+        { 0, 0, 0, 0 },
17
+    },
18
+    {  // ctu size 16
19
+        { 1, 0, 0, 0 },
20
+        { 1, 1, 0, 0 },
21
+        { 0, 0, 0, 0 },
22
+        { 0, 0, 0, 0 }
23
+    }
24
+};
25
+
26
+// min aq size for ctu size 64, 32 and 16
27
+static const uint32_t minAQSize[3] = { 3, 2, 1 };
28
+
29
+struct PicQPAdaptationLayer
30
+{
31
+    uint32_t aqPartWidth;
32
+    uint32_t aqPartHeight;
33
+    uint32_t numAQPartInWidth;
34
+    uint32_t numAQPartInHeight;
35
+    uint32_t minAQDepth;
36
+    double*  dActivity;
37
+    double*  dQpOffset;
38
+
39
+    double*  dCuTreeOffset;
40
+    double*  dCuTreeOffset8x8;
41
+    double   dAvgActivity;
42
+    bool     bQpSize;
43
+
44
+    bool  create(uint32_t width, uint32_t height, uint32_t aqPartWidth, uint32_t aqPartHeight, uint32_t numAQPartInWidthExt, uint32_t numAQPartInHeightExt);
45
+    void  destroy();
46
+};
47
+
48
 /* lowres buffers, sizes and strides */
49
 struct Lowres : public ReferencePlanes
50
 {
51
@@ -154,6 +197,13 @@
52
     uint64_t  wp_sum[3];
53
 
54
     /* cutree intermediate data */
55
+    PicQPAdaptationLayer* pAQLayer;
56
+    uint32_t maxAQDepth;
57
+    uint32_t widthFullRes;
58
+    uint32_t heightFullRes;
59
+    uint32_t m_maxCUSize;
60
+    uint32_t m_qgSize;
61
+    
62
     uint16_t* propagateCost;
63
     double    weightedCostDelta[X265_BFRAME_MAX + 2];
64
     ReferencePlanes weightedRef[X265_BFRAME_MAX + 2];
65
x265_2.9.tar.gz/source/common/param.cpp -> x265_3.0.tar.gz/source/common/param.cpp Changed
383
 
1
@@ -158,6 +158,7 @@
2
     param->radl = 0;
3
     param->chunkStart = 0;
4
     param->chunkEnd = 0;
5
+    param->bEnableHRDConcatFlag = 0;
6
 
7
     /* Intra Coding Tools */
8
     param->bEnableConstrainedIntra = 0;
9
@@ -231,9 +232,11 @@
10
     param->rc.qpStep = 4;
11
     param->rc.rateControlMode = X265_RC_CRF;
12
     param->rc.qp = 32;
13
-    param->rc.aqMode = X265_AQ_VARIANCE;
14
+    param->rc.aqMode = X265_AQ_AUTO_VARIANCE;
15
+    param->rc.hevcAq = 0;
16
     param->rc.qgSize = 32;
17
     param->rc.aqStrength = 1.0;
18
+    param->rc.qpAdaptationRange = 1.0;
19
     param->rc.cuTree = 1;
20
     param->rc.rfConstantMax = 0;
21
     param->rc.rfConstantMin = 0;
22
@@ -243,6 +246,7 @@
23
     param->rc.complexityBlur = 20;
24
     param->rc.qblur = 0.5;
25
     param->rc.zoneCount = 0;
26
+    param->rc.zonefileCount = 0;
27
     param->rc.zones = NULL;
28
     param->rc.bEnableSlowFirstPass = 1;
29
     param->rc.bStrictCbr = 0;
30
@@ -286,9 +290,9 @@
31
     param->bAQMotion = 0;
32
     param->bHDROpt = 0;
33
     param->analysisReuseLevel = 5;
34
-
35
     param->toneMapFile = NULL;
36
     param->bDhdr10opt = 0;
37
+    param->dolbyProfile = 0;
38
     param->bCTUInfo = 0;
39
     param->bUseRcStats = 0;
40
     param->scaleFactor = 0;
41
@@ -296,6 +300,7 @@
42
     param->interRefine = 0;
43
     param->bDynamicRefine = 0;
44
     param->mvRefine = 0;
45
+    param->ctuDistortionRefine = 0;
46
     param->bUseAnalysisFile = 1;
47
     param->csvfpt = NULL;
48
     param->forceFlush = 0;
49
@@ -306,7 +311,7 @@
50
 
51
     /* DCT Approximations */
52
     param->bLowPassDct = 0;
53
-    param->bMVType = 0;
54
+    param->bAnalysisType = 0;
55
     param->bSingleSeiNal = 0;
56
 
57
     /* SEI messages */
58
@@ -348,6 +353,7 @@
59
             param->limitReferences = 0;
60
             param->rc.aqStrength = 0.0;
61
             param->rc.aqMode = X265_AQ_NONE;
62
+            param->rc.hevcAq = 0;
63
             param->rc.qgSize = 32;
64
             param->bEnableFastIntra = 1;
65
         }
66
@@ -365,6 +371,7 @@
67
             param->limitReferences = 0;
68
             param->rc.aqStrength = 0.0;
69
             param->rc.aqMode = X265_AQ_NONE;
70
+            param->rc.hevcAq = 0;
71
             param->rc.qgSize = 32;
72
             param->bEnableSAO = 0;
73
             param->bEnableFastIntra = 1;
74
@@ -420,21 +427,21 @@
75
             param->bEnableWeightedBiPred = 1;
76
             param->bEnableAMP = 1;
77
             param->bEnableRectInter = 1;
78
-            param->lookaheadDepth = 30;
79
+            param->lookaheadDepth = 40;
80
             param->bframes = 8;
81
-            param->tuQTMaxInterDepth = 2;
82
-            param->tuQTMaxIntraDepth = 2;
83
+            param->tuQTMaxInterDepth = 3;
84
+            param->tuQTMaxIntraDepth = 3;
85
             param->rdLevel = 6;
86
             param->rdoqLevel = 2;
87
             param->psyRdoq = 1.0;
88
-            param->subpelRefine = 3;
89
-            param->maxNumMergeCand = 3;
90
+            param->subpelRefine = 4;
91
+            param->maxNumMergeCand = 4;
92
             param->searchMethod = X265_STAR_SEARCH;
93
-            param->maxNumReferences = 4;
94
-            param->limitReferences = 2;
95
+            param->maxNumReferences = 5;
96
+            param->limitReferences = 1;
97
             param->limitModes = 1;
98
             param->bIntraInBFrames = 1;
99
-            param->lookaheadSlices = 4; // limit parallelism as already enough work exists
100
+            param->lookaheadSlices = 0; // disabled for best quality
101
             param->limitTU = 4;
102
         }
103
         else if (!strcmp(preset, "veryslow"))
104
@@ -450,14 +457,14 @@
105
             param->rdoqLevel = 2;
106
             param->psyRdoq = 1.0;
107
             param->subpelRefine = 4;
108
-            param->maxNumMergeCand = 4;
109
+            param->maxNumMergeCand = 5;
110
             param->searchMethod = X265_STAR_SEARCH;
111
             param->maxNumReferences = 5;
112
-            param->limitReferences = 1;
113
-            param->limitModes = 1;
114
+            param->limitReferences = 0;
115
+            param->limitModes = 0;
116
             param->bIntraInBFrames = 1;
117
             param->lookaheadSlices = 0; // disabled for best quality
118
-            param->limitTU = 4;
119
+            param->limitTU = 0;
120
         }
121
         else if (!strcmp(preset, "placebo"))
122
         {
123
@@ -525,6 +532,7 @@
124
             param->rc.pbFactor = 1.0;
125
             param->rc.cuTree = 0;
126
             param->rc.aqMode = 0;
127
+            param->rc.hevcAq = 0;
128
             param->rc.qpStep = 1;
129
             param->rc.bEnableGrain = 1;
130
             param->bEnableRecursionSkip = 0;
131
@@ -533,6 +541,14 @@
132
             param->bEnableSAO = 0;
133
             param->rc.bEnableConstVbv = 1;
134
         }
135
+        else if (!strcmp(tune, "animation"))
136
+        {
137
+            param->bframes = (param->bframes + 2) >= param->lookaheadDepth? param->bframes : param->bframes + 2;
138
+            param->psyRd = 0.4;
139
+            param->rc.aqStrength = 0.4;
140
+            param->deblockingFilterBetaOffset = 1;
141
+            param->deblockingFilterTCOffset = 1;
142
+        }
143
         else
144
             return -1;
145
     }
146
@@ -562,6 +578,120 @@
147
 
148
     return x265_atoi(arg, bError);
149
 }
150
+/* internal versions of string-to-int with additional error checking */
151
+#undef atoi
152
+#undef atof
153
+#define atoi(str) x265_atoi(str, bError)
154
+#define atof(str) x265_atof(str, bError)
155
+#define atobool(str) (x265_atobool(str, bError))
156
+
157
+int x265_zone_param_parse(x265_param* p, const char* name, const char* value)
158
+{
159
+    bool bError = false;
160
+    char nameBuf[64];
161
+
162
+    if (!name)
163
+        return X265_PARAM_BAD_NAME;
164
+
165
+    // skip -- prefix if provided
166
+    if (name[0] == '-' && name[1] == '-')
167
+        name += 2;
168
+
169
+    // s/_/-/g
170
+    if (strlen(name) + 1 < sizeof(nameBuf) && strchr(name, '_'))
171
+    {
172
+        char *c;
173
+        strcpy(nameBuf, name);
174
+        while ((c = strchr(nameBuf, '_')) != 0)
175
+            *c = '-';
176
+
177
+        name = nameBuf;
178
+    }
179
+
180
+    if (!strncmp(name, "no-", 3))
181
+    {
182
+        name += 3;
183
+        value = !value || x265_atobool(value, bError) ? "false" : "true";
184
+    }
185
+    else if (!strncmp(name, "no", 2))
186
+    {
187
+        name += 2;
188
+        value = !value || x265_atobool(value, bError) ? "false" : "true";
189
+    }
190
+    else if (!value)
191
+        value = "true";
192
+    else if (value[0] == '=')
193
+        value++;
194
+
195
+#define OPT(STR) else if (!strcmp(name, STR))
196
+#define OPT2(STR1, STR2) else if (!strcmp(name, STR1) || !strcmp(name, STR2))
197
+
198
+    if (0);
199
+    OPT("ref") p->maxNumReferences = atoi(value);
200
+    OPT("fast-intra") p->bEnableFastIntra = atobool(value);
201
+    OPT("early-skip") p->bEnableEarlySkip = atobool(value);
202
+    OPT("rskip") p->bEnableRecursionSkip = atobool(value);
203
+    OPT("me")p->searchMethod = parseName(value, x265_motion_est_names, bError);
204
+    OPT("subme") p->subpelRefine = atoi(value);
205
+    OPT("merange") p->searchRange = atoi(value);
206
+    OPT("rect") p->bEnableRectInter = atobool(value);
207
+    OPT("amp") p->bEnableAMP = atobool(value);
208
+    OPT("max-merge") p->maxNumMergeCand = (uint32_t)atoi(value);
209
+    OPT("rd") p->rdLevel = atoi(value);
210
+    OPT("radl") p->radl = atoi(value);
211
+    OPT2("rdoq", "rdoq-level")
212
+    {
213
+        int bval = atobool(value);
214
+        if (bError || bval)
215
+        {
216
+            bError = false;
217
+            p->rdoqLevel = atoi(value);
218
+        }
219
+        else
220
+            p->rdoqLevel = 0;
221
+    }
222
+    OPT("b-intra") p->bIntraInBFrames = atobool(value);
223
+    OPT("scaling-list") p->scalingLists = strdup(value);
224
+    OPT("crf")
225
+    {
226
+        p->rc.rfConstant = atof(value);
227
+        p->rc.rateControlMode = X265_RC_CRF;
228
+    }
229
+    OPT("qp")
230
+    {
231
+        p->rc.qp = atoi(value);
232
+        p->rc.rateControlMode = X265_RC_CQP;
233
+    }
234
+    OPT("bitrate")
235
+    {
236
+        p->rc.bitrate = atoi(value);
237
+        p->rc.rateControlMode = X265_RC_ABR;
238
+    }
239
+    OPT("aq-mode") p->rc.aqMode = atoi(value);
240
+    OPT("aq-strength") p->rc.aqStrength = atof(value);
241
+    OPT("nr-intra") p->noiseReductionIntra = atoi(value);
242
+    OPT("nr-inter") p->noiseReductionInter = atoi(value);
243
+    OPT("limit-modes") p->limitModes = atobool(value);
244
+    OPT("splitrd-skip") p->bEnableSplitRdSkip = atobool(value);
245
+    OPT("cu-lossless") p->bCULossless = atobool(value);
246
+    OPT("rd-refine") p->bEnableRdRefine = atobool(value);
247
+    OPT("limit-tu") p->limitTU = atoi(value);
248
+    OPT("tskip") p->bEnableTransformSkip = atobool(value);
249
+    OPT("tskip-fast") p->bEnableTSkipFast = atobool(value);
250
+    OPT("rdpenalty") p->rdPenalty = atoi(value);
251
+    OPT("dynamic-rd") p->dynamicRd = atof(value);
252
+    else
253
+        return X265_PARAM_BAD_NAME;
254
+
255
+#undef OPT
256
+#undef OPT2
257
+
258
+    return bError ? X265_PARAM_BAD_VALUE : 0;
259
+}
260
+
261
+#undef atobool
262
+#undef atoi
263
+#undef atof
264
 
265
 /* internal versions of string-to-int with additional error checking */
266
 #undef atoi
267
@@ -1023,15 +1153,19 @@
268
         OPT("vbv-end") p->vbvBufferEnd = atof(value);
269
         OPT("vbv-end-fr-adj") p->vbvEndFrameAdjust = atof(value);
270
         OPT("copy-pic") p->bCopyPicToFrame = atobool(value);
271
-        OPT("refine-mv-type")
272
+        OPT("refine-analysis-type")
273
         {
274
             if (strcmp(strdup(value), "avc") == 0)
275
             {
276
-                p->bMVType = AVC_INFO;
277
+                p->bAnalysisType = AVC_INFO;
278
+            }
279
+            else if (strcmp(strdup(value), "hevc") == 0)
280
+            {
281
+                p->bAnalysisType = HEVC_INFO;
282
             }
283
             else if (strcmp(strdup(value), "off") == 0)
284
             {
285
-                p->bMVType = NO_INFO;
286
+                p->bAnalysisType = NO_INFO;
287
             }
288
             else
289
             {
290
@@ -1050,6 +1184,19 @@
291
         OPT("chunk-start") p->chunkStart = atoi(value);
292
         OPT("chunk-end") p->chunkEnd = atoi(value);
293
         OPT("nalu-file") p->naluFile = strdup(value);
294
+        OPT("dolby-vision-profile")
295
+        {
296
+            if (atof(value) < 10)
297
+                p->dolbyProfile = (int)(10 * atof(value) + .5);
298
+            else if (atoi(value) < 100)
299
+                p->dolbyProfile = atoi(value);
300
+            else
301
+                bError = true;
302
+        }
303
+        OPT("hrd-concat") p->bEnableHRDConcatFlag = atobool(value);
304
+        OPT("refine-ctu-distortion") p->ctuDistortionRefine = atoi(value);
305
+        OPT("hevc-aq") p->rc.hevcAq = atobool(value);
306
+        OPT("qp-adaptation-range") p->rc.qpAdaptationRange = atof(value);
307
         else
308
             return X265_PARAM_BAD_NAME;
309
     }
310
@@ -1294,6 +1441,8 @@
311
           "Aq-Mode is out of range");
312
     CHECK(param->rc.aqStrength < 0 || param->rc.aqStrength > 3,
313
           "Aq-Strength is out of range");
314
+    CHECK(param->rc.qpAdaptationRange < 1.0f || param->rc.qpAdaptationRange > 6.0f,
315
+        "qp adaptation range is out of range");
316
     CHECK(param->deblockingFilterTCOffset < -6 || param->deblockingFilterTCOffset > 6,
317
           "deblocking filter tC offset must be in the range of -6 to +6");
318
     CHECK(param->deblockingFilterBetaOffset < -6 || param->deblockingFilterBetaOffset > 6,
319
@@ -1405,8 +1554,21 @@
320
         "Invalid refine-inter value, refine-inter levels 0 to 3 supported");
321
     CHECK(param->intraRefine > 4 || param->intraRefine < 0,
322
         "Invalid refine-intra value, refine-intra levels 0 to 3 supported");
323
+    CHECK(param->ctuDistortionRefine < 0 || param->ctuDistortionRefine > 1,
324
+        "Invalid refine-ctu-distortion value, must be either 0 or 1");
325
     CHECK(param->maxAUSizeFactor < 0.5 || param->maxAUSizeFactor > 1.0,
326
         "Supported factor for controlling max AU size is from 0.5 to 1");
327
+    CHECK((param->dolbyProfile != 0) && (param->dolbyProfile != 50) && (param->dolbyProfile != 81) && (param->dolbyProfile != 82),
328
+        "Unsupported Dolby Vision profile, only profile 5, profile 8.1 and profile 8.2 enabled");
329
+    if (param->dolbyProfile)
330
+    {
331
+        CHECK((param->rc.vbvMaxBitrate <= 0 || param->rc.vbvBufferSize <= 0), "Dolby Vision requires VBV settings to enable HRD.\n");
332
+        CHECK((param->internalBitDepth != 10), "Dolby Vision profile - 5, profile - 8.1 and profile - 8.2 is Main10 only\n");
333
+        CHECK((param->internalCsp != X265_CSP_I420), "Dolby Vision profile - 5, profile - 8.1 and profile - 8.2 requires YCbCr 4:2:0 color space\n");
334
+
335
+        if (param->dolbyProfile == 81)
336
+            CHECK(!(param->masteringDisplayColorVolume), "Dolby Vision profile - 8.1 requires Mastering display color volume information\n");
337
+    }
338
 #if !X86_64
339
     CHECK(param->searchMethod == X265_SEA && (param->sourceWidth > 840 || param->sourceHeight > 480),
340
         "SEA motion search does not support resolutions greater than 480p in 32 bit build");
341
@@ -1557,8 +1719,12 @@
342
     TOOLVAL(param->lookaheadSlices, "lslices=%d");
343
     TOOLVAL(param->lookaheadThreads, "lthreads=%d")
344
     TOOLVAL(param->bCTUInfo, "ctu-info=%d");
345
-    if (param->bMVType == AVC_INFO)
346
-        TOOLOPT(param->bMVType, "refine-mv-type=avc");
347
+    if (param->bAnalysisType == AVC_INFO)
348
+    {
349
+        TOOLOPT(param->bAnalysisType, "refine-analysis-type=avc");
350
+    }
351
+    else if (param->bAnalysisType == HEVC_INFO)
352
+        TOOLOPT(param->bAnalysisType, "refine-analysis-type=hevc");
353
     TOOLOPT(param->bDynamicRefine, "dynamic-refine");
354
     if (param->maxSlices > 1)
355
         TOOLVAL(param->maxSlices, "slices=%d");
356
@@ -1645,6 +1811,7 @@
357
     s += sprintf(s, " lookahead-slices=%d", p->lookaheadSlices);
358
     s += sprintf(s, " scenecut=%d", p->scenecutThreshold);
359
     s += sprintf(s, " radl=%d", p->radl);
360
+    BOOL(p->bEnableHRDConcatFlag, "splice");
361
     BOOL(p->bIntraRefresh, "intra-refresh");
362
     s += sprintf(s, " ctu=%d", p->maxCUSize);
363
     s += sprintf(s, " min-cu-size=%d", p->minCUSize);
364
@@ -1797,14 +1964,17 @@
365
     s += sprintf(s, " refine-intra=%d", p->intraRefine);
366
     s += sprintf(s, " refine-inter=%d", p->interRefine);
367
     s += sprintf(s, " refine-mv=%d", p->mvRefine);
368
+    s += sprintf(s, " refine-ctu-distortion=%d", p->ctuDistortionRefine);
369
     BOOL(p->bLimitSAO, "limit-sao");
370
     s += sprintf(s, " ctu-info=%d", p->bCTUInfo);
371
     BOOL(p->bLowPassDct, "lowpass-dct");
372
-    s += sprintf(s, " refine-mv-type=%d", p->bMVType);
373
+    s += sprintf(s, " refine-analysis-type=%d", p->bAnalysisType);
374
     s += sprintf(s, " copy-pic=%d", p->bCopyPicToFrame);
375
     s += sprintf(s, " max-ausize-factor=%.1f", p->maxAUSizeFactor);
376
     BOOL(p->bDynamicRefine, "dynamic-refine");
377
     BOOL(p->bSingleSeiNal, "single-sei");
378
+    BOOL(p->rc.hevcAq, "hevc-aq");
379
+    s += sprintf(s, " qp-adaptation-range=%.2f", p->rc.qpAdaptationRange);
380
 #undef BOOL
381
     return buf;
382
 }
383
x265_2.9.tar.gz/source/common/param.h -> x265_3.0.tar.gz/source/common/param.h Changed
9
 
1
@@ -51,6 +51,7 @@
2
 int x265_param_default_preset(x265_param *, const char *preset, const char *tune);
3
 int x265_param_apply_profile(x265_param *, const char *profile);
4
 int x265_param_parse(x265_param *p, const char *name, const char *value);
5
+int x265_zone_param_parse(x265_param* p, const char* name, const char* value);
6
 #define PARAM_NS X265_NS
7
 #endif
8
 }
9
x265_2.9.tar.gz/source/common/quant.cpp -> x265_3.0.tar.gz/source/common/quant.cpp Changed
41
 
1
@@ -723,6 +723,7 @@
2
             X265_CHECK(coeffNum[cgScanPos] == 0, "count of coeff failure\n");
3
             uint32_t scanPosBase = (cgScanPos << MLS_CG_SIZE);
4
             uint32_t blkPos      = codeParams.scan[scanPosBase];
5
+#if X265_ARCH_X86
6
             bool enable512 = detect512();
7
             if (enable512)
8
                 primitives.cu[log2TrSize - 2].psyRdoQuant(m_resiDctCoeff, m_fencDctCoeff, costUncoded, &totalUncodedCost, &totalRdCost, &psyScale, blkPos);
9
@@ -731,6 +732,10 @@
10
                 primitives.cu[log2TrSize - 2].psyRdoQuant_1p(m_resiDctCoeff,  costUncoded, &totalUncodedCost, &totalRdCost,blkPos);
11
                 primitives.cu[log2TrSize - 2].psyRdoQuant_2p(m_resiDctCoeff, m_fencDctCoeff, costUncoded, &totalUncodedCost, &totalRdCost, &psyScale, blkPos);
12
             }
13
+#else
14
+            primitives.cu[log2TrSize - 2].psyRdoQuant_1p(m_resiDctCoeff, costUncoded, &totalUncodedCost, &totalRdCost, blkPos);
15
+            primitives.cu[log2TrSize - 2].psyRdoQuant_2p(m_resiDctCoeff, m_fencDctCoeff, costUncoded, &totalUncodedCost, &totalRdCost, &psyScale, blkPos);
16
+#endif
17
         }
18
     }
19
     else
20
@@ -805,8 +810,8 @@
21
             uint32_t blkPos = codeParams.scan[scanPosBase];
22
             if (usePsyMask)
23
             {
24
+#if X265_ARCH_X86
25
                 bool enable512 = detect512();
26
-
27
                 if (enable512)
28
                     primitives.cu[log2TrSize - 2].psyRdoQuant(m_resiDctCoeff, m_fencDctCoeff, costUncoded, &totalUncodedCost, &totalRdCost, &psyScale, blkPos);
29
                 else
30
@@ -814,6 +819,10 @@
31
                     primitives.cu[log2TrSize - 2].psyRdoQuant_1p(m_resiDctCoeff, costUncoded, &totalUncodedCost, &totalRdCost, blkPos);
32
                     primitives.cu[log2TrSize - 2].psyRdoQuant_2p(m_resiDctCoeff, m_fencDctCoeff, costUncoded, &totalUncodedCost, &totalRdCost, &psyScale, blkPos);
33
                 }
34
+#else
35
+                primitives.cu[log2TrSize - 2].psyRdoQuant_1p(m_resiDctCoeff, costUncoded, &totalUncodedCost, &totalRdCost, blkPos);
36
+                primitives.cu[log2TrSize - 2].psyRdoQuant_2p(m_resiDctCoeff, m_fencDctCoeff, costUncoded, &totalUncodedCost, &totalRdCost, &psyScale, blkPos);
37
+#endif
38
                 blkPos = codeParams.scan[scanPosBase];
39
                 for (int y = 0; y < MLS_CG_SIZE; y++)
40
                 {
41
x265_2.9.tar.gz/source/encoder/analysis.cpp -> x265_3.0.tar.gz/source/encoder/analysis.cpp Changed
346
 
1
@@ -140,6 +140,7 @@
2
     m_slice = ctu.m_slice;
3
     m_frame = &frame;
4
     m_bChromaSa8d = m_param->rdLevel >= 3;
5
+    m_param = m_frame->m_param;
6
 
7
 #if _DEBUG || CHECKED_BUILD
8
     invalidateContexts(0);
9
@@ -233,9 +234,9 @@
10
     }
11
     else
12
     {
13
-        bool bCopyAnalysis = ((m_param->analysisLoad && m_param->analysisReuseLevel == 10) || (m_param->bMVType && m_param->analysisReuseLevel >= 7 && ctu.m_numPartitions <= 16));
14
-        bool BCompressInterCUrd0_4 = (m_param->bMVType && m_param->analysisReuseLevel >= 7 && m_param->rdLevel <= 4);
15
-        bool BCompressInterCUrd5_6 = (m_param->bMVType && m_param->analysisReuseLevel >= 7 && m_param->rdLevel >= 5 && m_param->rdLevel <= 6);
16
+        bool bCopyAnalysis = ((m_param->analysisLoad && m_param->analysisReuseLevel == 10) || (m_param->bAnalysisType == AVC_INFO && m_param->analysisReuseLevel >= 7 && ctu.m_numPartitions <= 16));
17
+        bool BCompressInterCUrd0_4 = (m_param->bAnalysisType == AVC_INFO && m_param->analysisReuseLevel >= 7 && m_param->rdLevel <= 4);
18
+        bool BCompressInterCUrd5_6 = (m_param->bAnalysisType == AVC_INFO && m_param->analysisReuseLevel >= 7 && m_param->rdLevel >= 5 && m_param->rdLevel <= 6);
19
         bCopyAnalysis = bCopyAnalysis || BCompressInterCUrd0_4 || BCompressInterCUrd5_6;
20
 
21
         if (bCopyAnalysis)
22
@@ -248,7 +249,7 @@
23
             for (int list = 0; list < m_slice->isInterB() + 1; list++)
24
                 memcpy(ctu.m_skipFlag[list], &m_frame->m_analysisData.modeFlag[list][posCTU], sizeof(uint8_t) * numPartition);
25
 
26
-            if ((m_slice->m_sliceType == P_SLICE || m_param->bIntraInBFrames) && !m_param->bMVType)
27
+            if ((m_slice->m_sliceType == P_SLICE || m_param->bIntraInBFrames) && !(m_param->bAnalysisType == AVC_INFO))
28
             {
29
                 x265_analysis_intra_data* intraDataCTU = m_frame->m_analysisData.intraData;
30
                 memcpy(ctu.m_lumaIntraDir, &intraDataCTU->modes[posCTU], sizeof(uint8_t) * numPartition);
31
@@ -274,14 +275,15 @@
32
             /* generate residual for entire CTU at once and copy to reconPic */
33
             encodeResidue(ctu, cuGeom);
34
         }
35
-        else if ((m_param->analysisLoad && m_param->analysisReuseLevel == 10) || ((m_param->bMVType == AVC_INFO) && m_param->analysisReuseLevel >= 7 && ctu.m_numPartitions <= 16))
36
+        else if ((m_param->analysisLoad && m_param->analysisReuseLevel == 10 && (!(m_param->bAnalysisType == HEVC_INFO) || m_slice->m_sliceType != P_SLICE)) ||
37
+                 ((m_param->bAnalysisType == AVC_INFO) && m_param->analysisReuseLevel >= 7 && ctu.m_numPartitions <= 16))
38
         {
39
             x265_analysis_inter_data* interDataCTU = m_frame->m_analysisData.interData;
40
             int posCTU = ctu.m_cuAddr * numPartition;
41
             memcpy(ctu.m_cuDepth, &interDataCTU->depth[posCTU], sizeof(uint8_t) * numPartition);
42
             memcpy(ctu.m_predMode, &interDataCTU->modes[posCTU], sizeof(uint8_t) * numPartition);
43
             memcpy(ctu.m_partSize, &interDataCTU->partSize[posCTU], sizeof(uint8_t) * numPartition);
44
-            if ((m_slice->m_sliceType == P_SLICE || m_param->bIntraInBFrames) && !(m_param->bMVType == AVC_INFO))
45
+            if ((m_slice->m_sliceType == P_SLICE || m_param->bIntraInBFrames) && !(m_param->bAnalysisType == AVC_INFO))
46
             {
47
                 x265_analysis_intra_data* intraDataCTU = m_frame->m_analysisData.intraData;
48
                 memcpy(ctu.m_lumaIntraDir, &intraDataCTU->modes[posCTU], sizeof(uint8_t) * numPartition);
49
@@ -515,7 +517,7 @@
50
     bool mightSplit = !(cuGeom.flags & CUGeom::LEAF);
51
     bool mightNotSplit = !(cuGeom.flags & CUGeom::SPLIT_MANDATORY);
52
 
53
-    bool bAlreadyDecided = m_param->intraRefine != 4 && parentCTU.m_lumaIntraDir[cuGeom.absPartIdx] != (uint8_t)ALL_IDX;
54
+    bool bAlreadyDecided = m_param->intraRefine != 4 && parentCTU.m_lumaIntraDir[cuGeom.absPartIdx] != (uint8_t)ALL_IDX && !(m_param->bAnalysisType == HEVC_INFO);
55
     bool bDecidedDepth = m_param->intraRefine != 4 && parentCTU.m_cuDepth[cuGeom.absPartIdx] == depth;
56
     int split = 0;
57
     if (m_param->intraRefine && m_param->intraRefine != 4)
58
@@ -1161,9 +1163,9 @@
59
     PicYuv& reconPic = *m_frame->m_reconPic;
60
     SplitData splitCUData;
61
 
62
-    bool bHEVCBlockAnalysis = (m_param->bMVType && cuGeom.numPartitions > 16);
63
+    bool bHEVCBlockAnalysis = (m_param->bAnalysisType == AVC_INFO && cuGeom.numPartitions > 16);
64
     bool bRefineAVCAnalysis = (m_param->analysisReuseLevel == 7 && (m_modeFlag[0] || m_modeFlag[1]));
65
-    bool bNooffloading = !m_param->bMVType;
66
+    bool bNooffloading = !(m_param->bAnalysisType == AVC_INFO);
67
 
68
     if (bHEVCBlockAnalysis || bRefineAVCAnalysis || bNooffloading)
69
     {
70
@@ -1298,7 +1300,7 @@
71
             }
72
         }
73
         /* Step 1. Evaluate Merge/Skip candidates for likely early-outs, if skip mode was not set above */
74
-        if ((mightNotSplit && depth >= minDepth && !md.bestMode && !bCtuInfoCheck) || (m_param->bMVType && m_param->analysisReuseLevel == 7 && (m_modeFlag[0] || m_modeFlag[1]))) /* TODO: Re-evaluate if analysis load/save still works */
75
+        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 */
76
         {
77
             /* Compute Merge Cost */
78
             md.pred[PRED_MERGE].cu.initSubCU(parentCTU, cuGeom, qp);
79
@@ -1308,7 +1310,7 @@
80
                 skipModes = (m_param->bEnableEarlySkip || m_refineLevel == 2)
81
                 && md.bestMode && md.bestMode->cu.isSkipped(0); // TODO: sa8d threshold per depth
82
         }
83
-        if (md.bestMode && m_param->bEnableRecursionSkip && !bCtuInfoCheck && !(m_param->bMVType && m_param->analysisReuseLevel == 7 && (m_modeFlag[0] || m_modeFlag[1])))
84
+        if (md.bestMode && m_param->bEnableRecursionSkip && !bCtuInfoCheck && !(m_param->bAnalysisType == AVC_INFO && m_param->analysisReuseLevel == 7 && (m_modeFlag[0] || m_modeFlag[1])))
85
         {
86
             skipRecursion = md.bestMode->cu.isSkipped(0);
87
             if (mightSplit && depth >= minDepth && !skipRecursion)
88
@@ -1319,7 +1321,7 @@
89
                     skipRecursion = complexityCheckCU(*md.bestMode);
90
             }
91
         }
92
-        if (m_param->bMVType && md.bestMode && cuGeom.numPartitions <= 16 && m_param->analysisReuseLevel == 7)
93
+        if (m_param->bAnalysisType == AVC_INFO && md.bestMode && cuGeom.numPartitions <= 16 && m_param->analysisReuseLevel == 7)
94
             skipRecursion = true;
95
         /* Step 2. Evaluate each of the 4 split sub-blocks in series */
96
         if (mightSplit && !skipRecursion)
97
@@ -1376,7 +1378,7 @@
98
                 splitPred->sa8dCost = m_rdCost.calcRdSADCost((uint32_t)splitPred->distortion, splitPred->sa8dBits);
99
         }
100
         /* If analysis mode is simple do not Evaluate other modes */
101
-        if (m_param->bMVType && m_param->analysisReuseLevel == 7)
102
+        if (m_param->bAnalysisType == AVC_INFO && m_param->analysisReuseLevel == 7)
103
         {
104
             if (m_slice->m_sliceType == P_SLICE)
105
             {
106
@@ -1793,7 +1795,7 @@
107
     }
108
     else
109
     {
110
-        if (m_param->bMVType && cuGeom.numPartitions <= 16)
111
+        if (m_param->bAnalysisType == AVC_INFO && cuGeom.numPartitions <= 16)
112
         {
113
             qprdRefine(parentCTU, cuGeom, qp, qp);
114
 
115
@@ -1854,9 +1856,9 @@
116
 
117
     SplitData splitCUData;
118
 
119
-    bool bHEVCBlockAnalysis = (m_param->bMVType && cuGeom.numPartitions > 16);
120
+    bool bHEVCBlockAnalysis = (m_param->bAnalysisType == AVC_INFO && cuGeom.numPartitions > 16);
121
     bool bRefineAVCAnalysis = (m_param->analysisReuseLevel == 7 && (m_modeFlag[0] || m_modeFlag[1]));
122
-    bool bNooffloading = !m_param->bMVType;
123
+    bool bNooffloading = !(m_param->bAnalysisType == AVC_INFO);
124
 
125
     if (bHEVCBlockAnalysis || bRefineAVCAnalysis || bNooffloading)
126
     {
127
@@ -1997,7 +1999,7 @@
128
         }
129
         /* Step 1. Evaluate Merge/Skip candidates for likely early-outs */
130
         if ((mightNotSplit && !md.bestMode && !bCtuInfoCheck) ||
131
-            (m_param->bMVType && m_param->analysisReuseLevel == 7 && (m_modeFlag[0] || m_modeFlag[1])))
132
+            (m_param->bAnalysisType == AVC_INFO && m_param->analysisReuseLevel == 7 && (m_modeFlag[0] || m_modeFlag[1])))
133
         {
134
             md.pred[PRED_SKIP].cu.initSubCU(parentCTU, cuGeom, qp);
135
             md.pred[PRED_MERGE].cu.initSubCU(parentCTU, cuGeom, qp);
136
@@ -2012,7 +2014,7 @@
137
             if (m_param->bEnableRecursionSkip && depth && m_modeDepth[depth - 1].bestMode)
138
                 skipRecursion = md.bestMode && !md.bestMode->cu.getQtRootCbf(0);
139
         }
140
-        if (m_param->bMVType && md.bestMode && cuGeom.numPartitions <= 16 && m_param->analysisReuseLevel == 7)
141
+        if (m_param->bAnalysisType == AVC_INFO && md.bestMode && cuGeom.numPartitions <= 16 && m_param->analysisReuseLevel == 7)
142
             skipRecursion = true;
143
         // estimate split cost
144
         /* Step 2. Evaluate each of the 4 split sub-blocks in series */
145
@@ -2066,7 +2068,7 @@
146
             checkDQPForSplitPred(*splitPred, cuGeom);
147
         }
148
         /* If analysis mode is simple do not Evaluate other modes */
149
-        if (m_param->bMVType && m_param->analysisReuseLevel == 7)
150
+        if (m_param->bAnalysisType == AVC_INFO && m_param->analysisReuseLevel == 7)
151
         {
152
             if (m_slice->m_sliceType == P_SLICE)
153
             {
154
@@ -2361,7 +2363,7 @@
155
     }
156
     else
157
     {
158
-        if (m_param->bMVType && cuGeom.numPartitions <= 16)
159
+        if (m_param->bAnalysisType == AVC_INFO && cuGeom.numPartitions <= 16)
160
         {
161
             qprdRefine(parentCTU, cuGeom, qp, qp);
162
 
163
@@ -2422,7 +2424,7 @@
164
         (m_refineLevel && cuGeom.log2CUSize == (uint32_t)(g_log2Size[m_param->minCUSize] + 1))));
165
     td.split = split;
166
 
167
-    if (bDecidedDepth && mightNotSplit)
168
+    if ((bDecidedDepth && mightNotSplit) || (m_param->bAnalysisType == HEVC_INFO && parentCTU.m_cuDepth[cuGeom.absPartIdx] == 4))
169
     {
170
         setLambdaFromQP(parentCTU, qp, lqp);
171
 
172
@@ -2453,7 +2455,7 @@
173
             for (uint32_t part = 0; part < numPU; part++)
174
             {
175
                 PredictionUnit pu(mode.cu, cuGeom, part);
176
-                if ((m_param->analysisLoad && m_param->analysisReuseLevel == 10) || (m_param->bMVType == AVC_INFO && m_param->analysisReuseLevel >= 7))
177
+                if ((m_param->analysisLoad && m_param->analysisReuseLevel == 10) || (m_param->bAnalysisType == AVC_INFO && m_param->analysisReuseLevel >= 7))
178
                 {
179
                     x265_analysis_inter_data* interDataCTU = m_frame->m_analysisData.interData;
180
                     int cuIdx = (mode.cu.m_cuAddr * parentCTU.m_numPartitions) + cuGeom.absPartIdx;
181
@@ -2540,7 +2542,7 @@
182
                 checkDQPForSplitPred(*md.bestMode, cuGeom);
183
         }
184
 
185
-        if (m_param->bMVType && m_param->analysisReuseLevel == 7)
186
+        if (m_param->bAnalysisType == AVC_INFO && m_param->analysisReuseLevel == 7)
187
         {
188
             for (int list = 0; list < m_slice->isInterB() + 1; list++)
189
             {
190
@@ -2561,7 +2563,10 @@
191
 
192
         if (m_refineLevel > 1 || (m_refineLevel && parentCTU.m_predMode[cuGeom.absPartIdx] == MODE_SKIP  && !mode.cu.isSkipped(0)))
193
         {
194
-            m_evaluateInter = 1;
195
+            if (parentCTU.m_cuDepth[cuGeom.absPartIdx] < 4 && mightNotSplit)
196
+                m_evaluateInter = 1;
197
+            else
198
+                bDecidedDepth = true;
199
             m_param->rdLevel > 4 ? compressInterCU_rd5_6(parentCTU, cuGeom, qp) : compressInterCU_rd0_4(parentCTU, cuGeom, qp);
200
             m_evaluateInter = 0;
201
         }
202
@@ -3555,12 +3560,41 @@
203
     return cuVariance / cnt;
204
 }
205
 
206
+double Analysis::aqQPOffset(const CUData& ctu, const CUGeom& cuGeom)
207
+{
208
+    uint32_t aqDepth = X265_MIN(cuGeom.depth, m_frame->m_lowres.maxAQDepth - 1);
209
+    PicQPAdaptationLayer* pQPLayer = &m_frame->m_lowres.pAQLayer[aqDepth];
210
+
211
+    uint32_t aqPosX = (ctu.m_cuPelX + g_zscanToPelX[cuGeom.absPartIdx]) / pQPLayer->aqPartWidth;
212
+    uint32_t aqPosY = (ctu.m_cuPelY + g_zscanToPelY[cuGeom.absPartIdx]) / pQPLayer->aqPartHeight;
213
+
214
+    uint32_t aqStride = pQPLayer->numAQPartInWidth;
215
+
216
+    double dQpOffset = pQPLayer->dQpOffset[aqPosY * aqStride + aqPosX];
217
+    return dQpOffset;
218
+}
219
+
220
+double Analysis::cuTreeQPOffset(const CUData& ctu, const CUGeom& cuGeom)
221
+{
222
+    uint32_t aqDepth = X265_MIN(cuGeom.depth, m_frame->m_lowres.maxAQDepth - 1);
223
+    PicQPAdaptationLayer* pcAQLayer = &m_frame->m_lowres.pAQLayer[aqDepth];
224
+
225
+    uint32_t aqPosX = (ctu.m_cuPelX + g_zscanToPelX[cuGeom.absPartIdx]) / pcAQLayer->aqPartWidth;
226
+    uint32_t aqPosY = (ctu.m_cuPelY + g_zscanToPelY[cuGeom.absPartIdx]) / pcAQLayer->aqPartHeight;
227
+
228
+    uint32_t aqStride = pcAQLayer->numAQPartInWidth;
229
+
230
+    double dQpOffset = pcAQLayer->dCuTreeOffset[aqPosY * aqStride + aqPosX];
231
+    return dQpOffset;
232
+}
233
+
234
 int Analysis::calculateQpforCuSize(const CUData& ctu, const CUGeom& cuGeom, int32_t complexCheck, double baseQp)
235
 {
236
     FrameData& curEncData = *m_frame->m_encData;
237
     double qp = baseQp >= 0 ? baseQp : curEncData.m_cuStat[ctu.m_cuAddr].baseQp;
238
+    bool bCuTreeOffset = IS_REFERENCED(m_frame) && m_param->rc.cuTree && !complexCheck;
239
 
240
-    if (m_param->analysisMultiPassDistortion && m_param->rc.bStatRead)
241
+    if ((m_param->analysisMultiPassDistortion && m_param->rc.bStatRead) || (m_param->ctuDistortionRefine && m_param->analysisLoad))
242
     {
243
         x265_analysis_distortion_data* distortionData = m_frame->m_analysisData.distortionData;
244
         if ((distortionData->threshold[ctu.m_cuAddr] < 0.9 || distortionData->threshold[ctu.m_cuAddr] > 1.1)
245
@@ -3568,40 +3602,68 @@
246
             qp += distortionData->offset[ctu.m_cuAddr];
247
     }
248
 
249
-    int loopIncr = (m_param->rc.qgSize == 8) ? 8 : 16;
250
-
251
-    /* Use cuTree offsets if cuTree enabled and frame is referenced, else use AQ offsets */
252
-    bool isReferenced = IS_REFERENCED(m_frame);
253
-    double *qpoffs = (isReferenced && m_param->rc.cuTree && !complexCheck) ? m_frame->m_lowres.qpCuTreeOffset :
254
-                                                                             m_frame->m_lowres.qpAqOffset;
255
-    if (qpoffs)
256
-    {
257
-        uint32_t width = m_frame->m_fencPic->m_picWidth;
258
-        uint32_t height = m_frame->m_fencPic->m_picHeight;
259
-        uint32_t block_x = ctu.m_cuPelX + g_zscanToPelX[cuGeom.absPartIdx];
260
-        uint32_t block_y = ctu.m_cuPelY + g_zscanToPelY[cuGeom.absPartIdx];
261
-        uint32_t maxCols = (m_frame->m_fencPic->m_picWidth + (loopIncr - 1)) / loopIncr;
262
-        uint32_t blockSize = m_param->maxCUSize >> cuGeom.depth;
263
-        double qp_offset = 0;
264
-        uint32_t cnt = 0;
265
-        for (uint32_t block_yy = block_y; block_yy < block_y + blockSize && block_yy < height; block_yy += loopIncr)
266
-        {
267
-            for (uint32_t block_xx = block_x; block_xx < block_x + blockSize && block_xx < width; block_xx += loopIncr)
268
-            {
269
-                uint32_t idx = ((block_yy / loopIncr) * (maxCols)) + (block_xx / loopIncr);
270
-                qp_offset += qpoffs[idx];
271
-                cnt++;
272
+    if (m_param->analysisLoad && m_param->analysisReuseLevel == 10 && m_param->rc.cuTree)
273
+    {
274
+        int cuIdx = (ctu.m_cuAddr * ctu.m_numPartitions) + cuGeom.absPartIdx;
275
+        if (ctu.m_slice->m_sliceType == I_SLICE)
276
+            return x265_clip3(m_param->rc.qpMin, m_param->rc.qpMax, (int32_t)(qp + 0.5 + ((x265_analysis_intra_data*)m_frame->m_analysisData.intraData)->cuQPOff[cuIdx]));
277
+        else
278
+            return x265_clip3(m_param->rc.qpMin, m_param->rc.qpMax, (int32_t)(qp + 0.5 + ((x265_analysis_inter_data*)m_frame->m_analysisData.interData)->cuQPOff[cuIdx]));
279
+    }
280
+    if (m_param->rc.hevcAq)
281
+    {
282
+        /* Use cuTree offsets if cuTree enabled and frame is referenced, else use AQ offsets */
283
+        double dQpOffset = 0;
284
+        if (bCuTreeOffset)
285
+        {
286
+            dQpOffset = cuTreeQPOffset(ctu, cuGeom);
287
+        }
288
+        else
289
+        {
290
+            dQpOffset = aqQPOffset(ctu, cuGeom);
291
+            if (complexCheck)
292
+            {
293
+                int32_t offset = (int32_t)(dQpOffset * 100 + .5);
294
+                double threshold = (1 - ((x265_ADAPT_RD_STRENGTH - m_param->dynamicRd) * 0.5));
295
+                int32_t max_threshold = (int32_t)(threshold * 100 + .5);
296
+                return (offset < max_threshold);
297
             }
298
         }
299
-
300
-        qp_offset /= cnt;
301
-        qp += qp_offset;
302
-        if (complexCheck)
303
-        {
304
-            int32_t offset = (int32_t)(qp_offset * 100 + .5);
305
-            double threshold = (1 - ((x265_ADAPT_RD_STRENGTH - m_param->dynamicRd) * 0.5));
306
-            int32_t max_threshold = (int32_t)(threshold * 100 + .5);
307
-            return (offset < max_threshold);
308
+        qp += dQpOffset;
309
+    }
310
+    else
311
+    {
312
+        int loopIncr = (m_param->rc.qgSize == 8) ? 8 : 16;
313
+        /* Use cuTree offsets if cuTree enabled and frame is referenced, else use AQ offsets */
314
+        double *qpoffs = bCuTreeOffset ? m_frame->m_lowres.qpCuTreeOffset : m_frame->m_lowres.qpAqOffset;
315
+        if (qpoffs)
316
+        {
317
+            uint32_t width = m_frame->m_fencPic->m_picWidth;
318
+            uint32_t height = m_frame->m_fencPic->m_picHeight;
319
+            uint32_t block_x = ctu.m_cuPelX + g_zscanToPelX[cuGeom.absPartIdx];
320
+            uint32_t block_y = ctu.m_cuPelY + g_zscanToPelY[cuGeom.absPartIdx];
321
+            uint32_t maxCols = (m_frame->m_fencPic->m_picWidth + (loopIncr - 1)) / loopIncr;
322
+            uint32_t blockSize = m_param->maxCUSize >> cuGeom.depth;
323
+            double dQpOffset = 0;
324
+            uint32_t cnt = 0;
325
+            for (uint32_t block_yy = block_y; block_yy < block_y + blockSize && block_yy < height; block_yy += loopIncr)
326
+            {
327
+                for (uint32_t block_xx = block_x; block_xx < block_x + blockSize && block_xx < width; block_xx += loopIncr)
328
+                {
329
+                    uint32_t idx = ((block_yy / loopIncr) * (maxCols)) + (block_xx / loopIncr);
330
+                    dQpOffset += qpoffs[idx];
331
+                    cnt++;
332
+                }
333
+            }
334
+            dQpOffset /= cnt;
335
+            qp += dQpOffset;
336
+            if (complexCheck)
337
+            {
338
+                int32_t offset = (int32_t)(dQpOffset * 100 + .5);
339
+                double threshold = (1 - ((x265_ADAPT_RD_STRENGTH - m_param->dynamicRd) * 0.5));
340
+                int32_t max_threshold = (int32_t)(threshold * 100 + .5);
341
+                return (offset < max_threshold);
342
+            }
343
         }
344
     }
345
 
346
x265_2.9.tar.gz/source/encoder/analysis.h -> x265_3.0.tar.gz/source/encoder/analysis.h Changed
11
 
1
@@ -201,7 +201,8 @@
2
 
3
     void classifyCU(const CUData& ctu, const CUGeom& cuGeom, const Mode& bestMode, TrainingData& trainData);
4
     void trainCU(const CUData& ctu, const CUGeom& cuGeom, const Mode& bestMode, TrainingData& trainData);
5
-
6
+    double aqQPOffset(const CUData& ctu, const CUGeom& cuGeom);
7
+    double cuTreeQPOffset(const CUData& ctu, const CUGeom& cuGeom);
8
     void calculateNormFactor(CUData& ctu, int qp);
9
     void normFactor(const pixel* src, uint32_t blockSize, CUData& ctu, int qp, TextType ttype);
10
 
11
x265_2.9.tar.gz/source/encoder/api.cpp -> x265_3.0.tar.gz/source/encoder/api.cpp Changed
310
 
1
@@ -94,6 +94,7 @@
2
     Encoder* encoder = NULL;
3
     x265_param* param = PARAM_NS::x265_param_alloc();
4
     x265_param* latestParam = PARAM_NS::x265_param_alloc();
5
+    x265_param* zoneParam = PARAM_NS::x265_param_alloc();
6
     if (!param || !latestParam)
7
         goto fail;
8
 
9
@@ -126,6 +127,13 @@
10
     }
11
 
12
     encoder->create();
13
+
14
+    memcpy(zoneParam, param, sizeof(x265_param));
15
+    for (int i = 0; i < param->rc.zonefileCount; i++)
16
+    {
17
+        encoder->configureZone(zoneParam, param->rc.zones[i].zoneParam);
18
+    }
19
+
20
     /* Try to open CSV file handle */
21
     if (encoder->m_param->csvfn)
22
     {
23
@@ -213,6 +221,7 @@
24
     }
25
     else
26
     {
27
+        encoder->configure(encoder->m_latestParam);
28
         if (encoder->m_latestParam->scalingLists && encoder->m_latestParam->scalingLists != encoder->m_param->scalingLists)
29
         {
30
             if (encoder->m_param->bRepeatHeaders)
31
@@ -251,6 +260,9 @@
32
         }
33
         encoder->printReconfigureParams();
34
     }
35
+    /* Zones support modifying num of Refs. Requires determining level at each zone start*/
36
+    if (encoder->m_param->rc.zonefileCount)
37
+        determineLevel(*encoder->m_latestParam, encoder->m_vps);
38
     return ret;
39
 }
40
 
41
@@ -408,6 +420,7 @@
42
     x265_analysis_inter_data *interData = analysis->interData = NULL;
43
     x265_analysis_intra_data *intraData = analysis->intraData = NULL;
44
     x265_analysis_distortion_data *distortionData = analysis->distortionData = NULL;
45
+
46
     bool isVbv = param->rc.vbvMaxBitrate > 0 && param->rc.vbvBufferSize > 0;
47
     int numDir = 2; //irrespective of P or B slices set direction as 2
48
     uint32_t numPlanes = param->internalCsp == X265_CSP_I400 ? 1 : 3;
49
@@ -419,18 +432,19 @@
50
 #else
51
     uint32_t numCUs_sse_t = analysis->numCUsInFrame;
52
 #endif
53
-
54
-    //Allocate memory for distortionData pointer
55
-    CHECKED_MALLOC_ZERO(distortionData, x265_analysis_distortion_data, 1);
56
-    CHECKED_MALLOC_ZERO(distortionData->distortion, sse_t, analysis->numPartitions * numCUs_sse_t);
57
-    if (param->rc.bStatRead)
58
+    if (param->analysisMultiPassRefine || param->analysisMultiPassDistortion || param->ctuDistortionRefine)
59
     {
60
-        CHECKED_MALLOC_ZERO(distortionData->ctuDistortion, sse_t, numCUs_sse_t);
61
-        CHECKED_MALLOC_ZERO(distortionData->scaledDistortion, double, analysis->numCUsInFrame);
62
-        CHECKED_MALLOC_ZERO(distortionData->offset, double, analysis->numCUsInFrame);
63
-        CHECKED_MALLOC_ZERO(distortionData->threshold, double, analysis->numCUsInFrame);
64
+        //Allocate memory for distortionData pointer
65
+        CHECKED_MALLOC_ZERO(distortionData, x265_analysis_distortion_data, 1);
66
+        CHECKED_MALLOC_ZERO(distortionData->ctuDistortion, sse_t, analysis->numPartitions * numCUs_sse_t);
67
+        if (param->analysisLoad || param->rc.bStatRead)
68
+        {
69
+            CHECKED_MALLOC_ZERO(distortionData->scaledDistortion, double, analysis->numCUsInFrame);
70
+            CHECKED_MALLOC_ZERO(distortionData->offset, double, analysis->numCUsInFrame);
71
+            CHECKED_MALLOC_ZERO(distortionData->threshold, double, analysis->numCUsInFrame);
72
+        }
73
+        analysis->distortionData = distortionData;
74
     }
75
-    analysis->distortionData = distortionData;
76
 
77
     if (param->bDisableLookahead && isVbv)
78
     {
79
@@ -441,7 +455,7 @@
80
     }
81
 
82
     //Allocate memory for weightParam pointer
83
-    if (!(param->bMVType == AVC_INFO))
84
+    if (!(param->bAnalysisType == AVC_INFO))
85
         CHECKED_MALLOC_ZERO(analysis->wt, x265_weight_param, numPlanes * numDir);
86
 
87
     if (param->analysisReuseLevel < 2)
88
@@ -450,16 +464,20 @@
89
     //Allocate memory for intraData pointer
90
     CHECKED_MALLOC_ZERO(intraData, x265_analysis_intra_data, 1);
91
     CHECKED_MALLOC(intraData->depth, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
92
-    CHECKED_MALLOC(intraData->modes, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
93
-    CHECKED_MALLOC(intraData->partSizes, char, analysis->numPartitions * analysis->numCUsInFrame);
94
-    CHECKED_MALLOC(intraData->chromaModes, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
95
+    CHECKED_MALLOC_ZERO(intraData->modes, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
96
+    CHECKED_MALLOC_ZERO(intraData->partSizes, char, analysis->numPartitions * analysis->numCUsInFrame);
97
+    CHECKED_MALLOC_ZERO(intraData->chromaModes, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
98
+    if (param->rc.cuTree)
99
+        CHECKED_MALLOC_ZERO(intraData->cuQPOff, int8_t, analysis->numPartitions * analysis->numCUsInFrame);
100
     analysis->intraData = intraData;
101
 
102
     //Allocate memory for interData pointer based on ReuseLevels
103
     CHECKED_MALLOC_ZERO(interData, x265_analysis_inter_data, 1);
104
     CHECKED_MALLOC(interData->depth, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
105
-    CHECKED_MALLOC(interData->modes, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
106
+    CHECKED_MALLOC_ZERO(interData->modes, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
107
 
108
+    if (param->rc.cuTree)
109
+        CHECKED_MALLOC_ZERO(interData->cuQPOff, int8_t, analysis->numPartitions * analysis->numCUsInFrame);
110
     CHECKED_MALLOC_ZERO(interData->mvpIdx[0], uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
111
     CHECKED_MALLOC_ZERO(interData->mvpIdx[1], uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
112
     CHECKED_MALLOC_ZERO(interData->mv[0], x265_analysis_MV, analysis->numPartitions * analysis->numCUsInFrame);
113
@@ -467,16 +485,16 @@
114
 
115
     if (param->analysisReuseLevel > 4)
116
     {
117
-        CHECKED_MALLOC(interData->partSize, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
118
+        CHECKED_MALLOC_ZERO(interData->partSize, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
119
         CHECKED_MALLOC_ZERO(interData->mergeFlag, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
120
     }
121
     if (param->analysisReuseLevel >= 7)
122
     {
123
-        CHECKED_MALLOC(interData->interDir, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
124
-        CHECKED_MALLOC(interData->sadCost, int64_t, analysis->numPartitions * analysis->numCUsInFrame);
125
+        CHECKED_MALLOC_ZERO(interData->interDir, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
126
+        CHECKED_MALLOC_ZERO(interData->sadCost, int64_t, analysis->numPartitions * analysis->numCUsInFrame);
127
         for (int dir = 0; dir < numDir; dir++)
128
         {
129
-            CHECKED_MALLOC(interData->refIdx[dir], int8_t, analysis->numPartitions * analysis->numCUsInFrame);
130
+            CHECKED_MALLOC_ZERO(interData->refIdx[dir], int8_t, analysis->numPartitions * analysis->numCUsInFrame);
131
             CHECKED_MALLOC_ZERO(analysis->modeFlag[dir], uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
132
         }
133
     }
134
@@ -512,10 +530,9 @@
135
     //Free memory for distortionData pointers
136
     if (analysis->distortionData)
137
     {
138
-        X265_FREE((analysis->distortionData)->distortion);
139
-        if (param->rc.bStatRead)
140
+        X265_FREE((analysis->distortionData)->ctuDistortion);
141
+        if (param->rc.bStatRead || param->analysisLoad)
142
         {
143
-            X265_FREE((analysis->distortionData)->ctuDistortion);
144
             X265_FREE((analysis->distortionData)->scaledDistortion);
145
             X265_FREE((analysis->distortionData)->offset);
146
             X265_FREE((analysis->distortionData)->threshold);
147
@@ -524,7 +541,7 @@
148
     }
149
 
150
     /* Early exit freeing weights alone if level is 1 (when there is no analysis inter/intra) */
151
-    if (analysis->wt && !(param->bMVType == AVC_INFO))
152
+    if (analysis->wt && !(param->bAnalysisType == AVC_INFO))
153
         X265_FREE(analysis->wt);
154
 
155
     if (param->analysisReuseLevel < 2)
156
@@ -537,6 +554,8 @@
157
         X265_FREE((analysis->intraData)->modes);
158
         X265_FREE((analysis->intraData)->partSizes);
159
         X265_FREE((analysis->intraData)->chromaModes);
160
+        if (param->rc.cuTree)
161
+            X265_FREE((analysis->intraData)->cuQPOff);
162
         X265_FREE(analysis->intraData);
163
         analysis->intraData = NULL;
164
     }
165
@@ -546,6 +565,8 @@
166
     {
167
         X265_FREE((analysis->interData)->depth);
168
         X265_FREE((analysis->interData)->modes);
169
+        if (param->rc.cuTree)
170
+            X265_FREE((analysis->interData)->cuQPOff);
171
         X265_FREE((analysis->interData)->mvpIdx[0]);
172
         X265_FREE((analysis->interData)->mvpIdx[1]);
173
         X265_FREE((analysis->interData)->mv[0]);
174
@@ -598,8 +619,10 @@
175
     pic->quantOffsets = NULL;
176
     pic->userSEI.payloads = NULL;
177
     pic->userSEI.numPayloads = 0;
178
+    pic->rpu.payloadSize = 0;
179
+    pic->rpu.payload = NULL;
180
 
181
-    if ((param->analysisSave || param->analysisLoad) || (param->bMVType == AVC_INFO))
182
+    if ((param->analysisSave || param->analysisLoad) || (param->bAnalysisType == AVC_INFO))
183
     {
184
         uint32_t widthInCU = (param->sourceWidth + param->maxCUSize - 1) >> param->maxLog2CUSize;
185
         uint32_t heightInCU = (param->sourceHeight + param->maxCUSize - 1) >> param->maxLog2CUSize;
186
@@ -612,6 +635,8 @@
187
 
188
 void x265_picture_free(x265_picture *p)
189
 {
190
+    if (p->rpu.payload)
191
+        X265_FREE(p->rpu.payload);
192
     return x265_free(p);
193
 }
194
 
195
@@ -661,9 +686,9 @@
196
 #if ENABLE_LIBVMAF
197
     &x265_calculate_vmafscore,
198
     &x265_calculate_vmaf_framelevelscore,
199
-    &x265_vmaf_encoder_log
200
+    &x265_vmaf_encoder_log,
201
 #endif
202
-
203
+    &PARAM_NS::x265_zone_param_parse
204
 };
205
 
206
 typedef const x265_api* (*api_get_func)(int bitDepth);
207
@@ -681,9 +706,11 @@
208
 #include <dlfcn.h>
209
 #define ext ".so"
210
 #endif
211
+#if defined(__GNUC__) && __GNUC__ >= 8
212
+#pragma GCC diagnostic ignored "-Wcast-function-type"
213
+#endif
214
 
215
 static int g_recursion /* = 0 */;
216
-
217
 const x265_api* x265_api_get(int bitDepth)
218
 {
219
     if (bitDepth && bitDepth != X265_DEPTH)
220
@@ -1483,11 +1510,11 @@
221
 double x265_calculate_vmafscore(x265_param *param, x265_vmaf_data *data)
222
 {
223
     double score;
224
-    
225
+
226
     data->width = param->sourceWidth;
227
     data->height = param->sourceHeight;
228
     data->internalBitDepth = param->internalBitDepth;
229
-   
230
+
231
     if (param->internalCsp == X265_CSP_I420)
232
     {
233
         if ((param->sourceWidth * param->sourceHeight) % 2 != 0)
234
@@ -1500,8 +1527,8 @@
235
         data->offset = param->sourceWidth * param->sourceHeight * 2;
236
     else
237
         x265_log(NULL, X265_LOG_ERROR, "Invalid format\n");
238
-  
239
-    compute_vmaf(&score, vcd->format, data->width, data->height, read_frame, data, vcd->model_path, vcd->log_path, vcd->log_fmt, vcd->disable_clip, vcd->disable_avx, vcd->enable_transform, vcd->phone_model, vcd->psnr, vcd->ssim, vcd->ms_ssim, vcd->pool); 
240
+
241
+    compute_vmaf(&score, vcd->format, data->width, data->height, read_frame, data, vcd->model_path, vcd->log_path, vcd->log_fmt, vcd->disable_clip, vcd->disable_avx, vcd->enable_transform, vcd->phone_model, vcd->psnr, vcd->ssim, vcd->ms_ssim, vcd->pool, vcd->thread, vcd->subsample, vcd->enable_conf_interval);
242
 
243
     return score;
244
 }
245
@@ -1514,11 +1541,11 @@
246
     PicYuv *distorted_frame = (PicYuv *)user_data->distorted_frame;
247
 
248
     if(!user_data->frame_set) {
249
- 
250
+
251
         int reference_stride = reference_frame->m_stride;
252
         int distorted_stride = distorted_frame->m_stride;
253
 
254
-        const uint16_t *reference_ptr = (const uint16_t *)reference_frame->m_picOrg[0]; 
255
+        const uint16_t *reference_ptr = (const uint16_t *)reference_frame->m_picOrg[0];
256
         const uint16_t *distorted_ptr = (const uint16_t *)distorted_frame->m_picOrg[0];
257
 
258
         temp_data = reference_data;
259
@@ -1534,7 +1561,7 @@
260
             reference_ptr += reference_stride;
261
             temp_data += stride / sizeof(*temp_data);
262
         }
263
-        
264
+
265
         temp_data = distorted_data;
266
         for (i = 0; i < height; i++) {
267
             for (j = 0; j < width; j++) {
268
@@ -1546,8 +1573,8 @@
269
 
270
         user_data->frame_set = 1;
271
         return 0;
272
-    }                                                             
273
-    return 2;                                                               
274
+    }
275
+    return 2;
276
 }
277
 
278
 int read_frame_8bit(float *reference_data, float *distorted_data, float *temp_data, int stride, void *s)
279
@@ -1578,7 +1605,7 @@
280
             reference_ptr += reference_stride;
281
             temp_data += stride / sizeof(*temp_data);
282
         }
283
-        
284
+
285
         temp_data = distorted_data;
286
         for (i = 0; i < height; i++) {
287
             for (j = 0; j < width; j++) {
288
@@ -1590,8 +1617,8 @@
289
 
290
         user_data->frame_set = 1;
291
         return 0;
292
-    }                                                             
293
-    return 2;                                                               
294
+    }
295
+    return 2;
296
 }
297
 
298
 double x265_calculate_vmaf_framelevelscore(x265_vmaf_framedata *vmafframedata)
299
@@ -1603,8 +1630,8 @@
300
         read_frame = read_frame_8bit;
301
     else
302
         read_frame = read_frame_10bit;
303
-    compute_vmaf(&score, vcd->format, vmafframedata->width, vmafframedata->height, read_frame, vmafframedata, vcd->model_path, vcd->log_path, vcd->log_fmt, vcd->disable_clip, vcd->disable_avx, vcd->enable_transform, vcd->phone_model, vcd->psnr, vcd->ssim, vcd->ms_ssim, vcd->pool);
304
- 
305
+    compute_vmaf(&score, vcd->format, vmafframedata->width, vmafframedata->height, read_frame, vmafframedata, vcd->model_path, vcd->log_path, vcd->log_fmt, vcd->disable_clip, vcd->disable_avx, vcd->enable_transform, vcd->phone_model, vcd->psnr, vcd->ssim, vcd->ms_ssim, vcd->pool, vcd->thread, vcd->subsample, vcd->enable_conf_interval);
306
+
307
     return score;
308
 }
309
 #endif
310
x265_2.9.tar.gz/source/encoder/dpb.h -> x265_3.0.tar.gz/source/encoder/dpb.h Changed
16
 
1
@@ -52,6 +52,14 @@
2
         m_lastIDR = 0;
3
         m_pocCRA = 0;
4
         m_bhasLeadingPicture = param->radl;
5
+        for (int i = 0; i < param->rc.zonefileCount; i++)
6
+        {
7
+            if (param->rc.zones[i].zoneParam->radl)
8
+            {
9
+                m_bhasLeadingPicture = param->rc.zones[i].zoneParam->radl;
10
+                break;
11
+            }
12
+        }
13
         m_bRefreshPending = false;
14
         m_frameDataFreeList = NULL;
15
         m_bOpenGOP = param->bOpenGOP;
16
x265_2.9.tar.gz/source/encoder/encoder.cpp -> x265_3.0.tar.gz/source/encoder/encoder.cpp Changed
1037
 
1
@@ -3,6 +3,8 @@
2
  *
3
  * Authors: Steve Borho <steve@borho.org>
4
  *          Min Chen <chenm003@163.com>
5
+ *          Praveen Kumar Tiwari <praveen@multicorewareinc.com>
6
+ *          Aruna Matheswaran <aruna@multicorewareinc.com>
7
  *
8
  * This program is free software; you can redistribute it and/or modify
9
  * it under the terms of the GNU General Public License as published by
10
@@ -46,6 +48,32 @@
11
 
12
 namespace X265_NS {
13
 const char g_sliceTypeToChar[] = {'B', 'P', 'I'};
14
+
15
+/* Dolby Vision profile specific settings */
16
+typedef struct
17
+{
18
+    int bEmitHRDSEI;
19
+    int bEnableVideoSignalTypePresentFlag;
20
+    int bEnableColorDescriptionPresentFlag;
21
+    int bEnableAccessUnitDelimiters;
22
+    int bAnnexB;
23
+
24
+    /* VUI parameters specific to Dolby Vision Profile */
25
+    int videoFormat;
26
+    int bEnableVideoFullRangeFlag;
27
+    int transferCharacteristics;
28
+    int colorPrimaries;
29
+    int matrixCoeffs;
30
+
31
+    int doviProfileId;
32
+}DolbyVisionProfileSpec;
33
+
34
+DolbyVisionProfileSpec dovi[] =
35
+{
36
+    { 1, 1, 1, 1, 1, 5, 1,  2, 2, 2, 50 },
37
+    { 1, 1, 1, 1, 1, 5, 0, 16, 9, 9, 81 },
38
+    { 1, 1, 1, 1, 1, 5, 0,  1, 1, 1, 82 }
39
+};
40
 }
41
 
42
 /* Threshold for motion vection, based on expermental result.
43
@@ -411,7 +439,7 @@
44
 
45
     m_nalList.m_annexB = !!m_param->bAnnexB;
46
 
47
-    m_emitCLLSEI = p->maxCLL || p->maxFALL;
48
+    m_emitCLLSEI = p->maxCLL || p->maxFALL || (p->dolbyProfile == 81);
49
 
50
     if (m_param->naluFile)
51
     {
52
@@ -998,11 +1026,11 @@
53
         }
54
 
55
         Frame *inFrame;
56
+        x265_param* p = (m_reconfigure || m_reconfigureRc) ? m_latestParam : m_param;
57
         if (m_dpb->m_freeList.empty())
58
         {
59
             inFrame = new Frame;
60
             inFrame->m_encodeStartTime = x265_mdate();
61
-            x265_param* p = (m_reconfigure || m_reconfigureRc) ? m_latestParam : m_param;
62
             if (inFrame->create(p, pic_in->quantOffsets))
63
             {
64
                 /* the first PicYuv created is asked to generate the CU and block unit offset
65
@@ -1073,6 +1101,14 @@
66
 
67
         copyUserSEIMessages(inFrame, pic_in);
68
 
69
+        /*Copy Dolby Vision RPU from pic_in to frame*/
70
+        if (pic_in->rpu.payloadSize)
71
+        {
72
+            inFrame->m_rpu.payloadSize = pic_in->rpu.payloadSize;
73
+            inFrame->m_rpu.payload = new uint8_t[pic_in->rpu.payloadSize];
74
+            memcpy(inFrame->m_rpu.payload, pic_in->rpu.payload, pic_in->rpu.payloadSize);
75
+        }
76
+
77
         if (pic_in->quantOffsets != NULL)
78
         {
79
             int cuCount;
80
@@ -1110,7 +1146,7 @@
81
         {
82
             /* reads analysis data for the frame and allocates memory based on slicetype */
83
             static int paramBytes = 0;
84
-            if (!inFrame->m_poc)
85
+            if (!inFrame->m_poc && m_param->bAnalysisType != HEVC_INFO)
86
             {
87
                 x265_analysis_data analysisData = pic_in->analysisData;
88
                 paramBytes = validateAnalysisData(&analysisData, 0);
89
@@ -1218,7 +1254,7 @@
90
             x265_frame_stats* frameData = NULL;
91
 
92
             /* Free up pic_in->analysisData since it has already been used */
93
-            if ((m_param->analysisLoad && !m_param->analysisSave) || (m_param->bMVType && slice->m_sliceType != I_SLICE))
94
+            if ((m_param->analysisLoad && !m_param->analysisSave) || ((m_param->bAnalysisType == AVC_INFO) && slice->m_sliceType != I_SLICE))
95
                 x265_free_analysis_data(m_param, &outFrame->m_analysisData);
96
 
97
             if (pic_out)
98
@@ -1256,9 +1292,9 @@
99
                     pic_out->analysisData.wt = outFrame->m_analysisData.wt;
100
                     pic_out->analysisData.interData = outFrame->m_analysisData.interData;
101
                     pic_out->analysisData.intraData = outFrame->m_analysisData.intraData;
102
+                    pic_out->analysisData.distortionData = outFrame->m_analysisData.distortionData;
103
                     pic_out->analysisData.modeFlag[0] = outFrame->m_analysisData.modeFlag[0];
104
                     pic_out->analysisData.modeFlag[1] = outFrame->m_analysisData.modeFlag[1];
105
-                    pic_out->analysisData.distortionData = outFrame->m_analysisData.distortionData;
106
                     if (m_param->bDisableLookahead)
107
                     {
108
                         int factor = 1;
109
@@ -1427,6 +1463,12 @@
110
                     readAnalysisFile(&frameEnc->m_analysisData, frameEnc->m_poc, frameEnc->m_lowres.sliceType);
111
              }
112
 
113
+            for (int i = 0; i < m_param->rc.zonefileCount; i++)
114
+            {
115
+                if (m_param->rc.zones[i].startFrame == frameEnc->m_poc)
116
+                    x265_encoder_reconfig(this, m_param->rc.zones[i].zoneParam);
117
+            }
118
+
119
             if (frameEnc->m_reconfigureRc && m_reconfigureRc)
120
             {
121
                 memcpy(m_param, m_latestParam, sizeof(x265_param));
122
@@ -1631,6 +1673,27 @@
123
         encParam->bIntraInBFrames = param->bIntraInBFrames;
124
         if (param->scalingLists && !encParam->scalingLists)
125
             encParam->scalingLists = strdup(param->scalingLists);
126
+
127
+        encParam->rc.aqMode = param->rc.aqMode;
128
+        encParam->rc.aqStrength = param->rc.aqStrength;
129
+        encParam->noiseReductionInter = param->noiseReductionInter;
130
+        encParam->noiseReductionIntra = param->noiseReductionIntra;
131
+
132
+        encParam->limitModes = param->limitModes;
133
+        encParam->bEnableSplitRdSkip = param->bEnableSplitRdSkip;
134
+        encParam->bCULossless = param->bCULossless;
135
+        encParam->bEnableRdRefine = param->bEnableRdRefine;
136
+        encParam->limitTU = param->limitTU;
137
+        encParam->bEnableTSkipFast = param->bEnableTSkipFast;
138
+        encParam->rdPenalty = param->rdPenalty;
139
+        encParam->dynamicRd = param->dynamicRd;
140
+        encParam->bEnableTransformSkip = param->bEnableTransformSkip;
141
+        encParam->bEnableAMP = param->bEnableAMP;
142
+
143
+        /* Resignal changes in params in Parameter Sets */
144
+        m_sps.maxAMPDepth = (m_sps.bUseAMP = param->bEnableAMP && param->bEnableAMP) ? param->maxCUDepth : 0;
145
+        m_pps.bTransformSkipEnabled = param->bEnableTransformSkip ? 1 : 0;
146
+
147
     }
148
     encParam->forceFlush = param->forceFlush;
149
     /* To add: Loop Filter/deblocking controls, transform skip, signhide require PPS to be resent */
150
@@ -2360,6 +2423,13 @@
151
 {
152
     sbacCoder.setBitstream(&bs);
153
 
154
+    if (m_param->dolbyProfile && !m_param->bRepeatHeaders)
155
+    {
156
+        bs.resetBits();
157
+        bs.write(0x10, 8);
158
+        list.serialize(NAL_UNIT_ACCESS_UNIT_DELIMITER, bs);
159
+    }
160
+    
161
     /* headers for start of bitstream */
162
     bs.resetBits();
163
     sbacCoder.codeVPS(m_vps);
164
@@ -2381,10 +2451,13 @@
165
 
166
     if (m_param->bEmitHDRSEI)
167
     {
168
-        SEIContentLightLevel cllsei;
169
-        cllsei.max_content_light_level = m_param->maxCLL;
170
-        cllsei.max_pic_average_light_level = m_param->maxFALL;
171
-        cllsei.writeSEImessages(bs, m_sps, NAL_UNIT_PREFIX_SEI, list, m_param->bSingleSeiNal);
172
+        if (m_emitCLLSEI)
173
+        {
174
+            SEIContentLightLevel cllsei;
175
+            cllsei.max_content_light_level = m_param->maxCLL;
176
+            cllsei.max_pic_average_light_level = m_param->maxFALL;
177
+            cllsei.writeSEImessages(bs, m_sps, NAL_UNIT_PREFIX_SEI, list, m_param->bSingleSeiNal);
178
+        }
179
 
180
         if (m_param->masteringDisplayColorVolume)
181
         {
182
@@ -2564,20 +2637,91 @@
183
     pps->numRefIdxDefault[1] = 1;
184
 }
185
 
186
+void Encoder::configureZone(x265_param *p, x265_param *zone)
187
+{
188
+    p->maxNumReferences = zone->maxNumReferences;
189
+    p->bEnableFastIntra = zone->bEnableFastIntra;
190
+    p->bEnableEarlySkip = zone->bEnableEarlySkip;
191
+    p->bEnableRecursionSkip = zone->bEnableRecursionSkip;
192
+    p->searchMethod = zone->searchMethod;
193
+    p->searchRange = zone->searchRange;
194
+    p->subpelRefine = zone->subpelRefine;
195
+    p->rdoqLevel = zone->rdoqLevel;
196
+    p->rdLevel = zone->rdLevel;
197
+    p->bEnableRectInter = zone->bEnableRectInter;
198
+    p->maxNumMergeCand = zone->maxNumMergeCand;
199
+    p->bIntraInBFrames = zone->bIntraInBFrames;
200
+    p->scalingLists = strdup(zone->scalingLists);
201
+
202
+    p->rc.aqMode = zone->rc.aqMode;
203
+    p->rc.aqStrength = zone->rc.aqStrength;
204
+    p->noiseReductionInter = zone->noiseReductionInter;
205
+    p->noiseReductionIntra = zone->noiseReductionIntra;
206
+
207
+    p->limitModes = zone->limitModes;
208
+    p->bEnableSplitRdSkip = zone->bEnableSplitRdSkip;
209
+    p->bCULossless = zone->bCULossless;
210
+    p->bEnableRdRefine = zone->bEnableRdRefine;
211
+    p->limitTU = zone->limitTU;
212
+    p->bEnableTSkipFast = zone->bEnableTSkipFast;
213
+    p->rdPenalty = zone->rdPenalty;
214
+    p->dynamicRd = zone->dynamicRd;
215
+    p->bEnableTransformSkip = zone->bEnableTransformSkip;
216
+    p->bEnableAMP = zone->bEnableAMP;
217
+
218
+    if (m_param->rc.rateControlMode == X265_RC_ABR)
219
+        p->rc.bitrate = zone->rc.bitrate;
220
+    if (m_param->rc.rateControlMode == X265_RC_CRF)
221
+        p->rc.rfConstant = zone->rc.rfConstant;
222
+    if (m_param->rc.rateControlMode == X265_RC_CQP)
223
+    {
224
+        p->rc.qp = zone->rc.qp;
225
+        p->rc.aqMode = X265_AQ_NONE;
226
+        p->rc.hevcAq = 0;
227
+    }
228
+    p->radl = zone->radl;
229
+    memcpy(zone, p, sizeof(x265_param));
230
+}
231
+
232
+void Encoder::configureDolbyVisionParams(x265_param* p)
233
+{
234
+    uint32_t doviProfile = 0;
235
+
236
+    while (dovi[doviProfile].doviProfileId != p->dolbyProfile && doviProfile + 1 < sizeof(dovi) / sizeof(dovi[0]))
237
+        doviProfile++;
238
+
239
+    p->bEmitHRDSEI = dovi[doviProfile].bEmitHRDSEI;
240
+    p->vui.bEnableVideoSignalTypePresentFlag = dovi[doviProfile].bEnableVideoSignalTypePresentFlag;
241
+    p->vui.bEnableColorDescriptionPresentFlag = dovi[doviProfile].bEnableColorDescriptionPresentFlag;
242
+    p->bEnableAccessUnitDelimiters = dovi[doviProfile].bEnableAccessUnitDelimiters;
243
+    p->bAnnexB = dovi[doviProfile].bAnnexB;
244
+    p->vui.videoFormat = dovi[doviProfile].videoFormat;
245
+    p->vui.bEnableVideoFullRangeFlag = dovi[doviProfile].bEnableVideoFullRangeFlag;
246
+    p->vui.transferCharacteristics = dovi[doviProfile].transferCharacteristics;
247
+    p->vui.colorPrimaries = dovi[doviProfile].colorPrimaries;
248
+    p->vui.matrixCoeffs = dovi[doviProfile].matrixCoeffs;
249
+
250
+    if (dovi[doviProfile].doviProfileId == 81)
251
+        p->bEmitHDRSEI = 1;
252
+
253
+    if (dovi[doviProfile].doviProfileId == 50 && p->noiseReductionIntra && p->noiseReductionInter)
254
+        p->crQpOffset = 4;
255
+}
256
+
257
 void Encoder::configure(x265_param *p)
258
 {
259
     this->m_param = p;
260
-    if (p->bMVType == AVC_INFO)
261
+    if (p->bAnalysisType == AVC_INFO)
262
         this->m_externalFlush = true;
263
     else 
264
         this->m_externalFlush = false;
265
 
266
-    if (p->bMVType == AVC_INFO && (p->limitTU == 3 || p->limitTU == 4))
267
+    if (p->bAnalysisType == AVC_INFO && (p->limitTU == 3 || p->limitTU == 4))
268
     {
269
         x265_log(p, X265_LOG_WARNING, "limit TU = 3 or 4 with MVType AVCINFO produces inconsistent output\n");
270
     }
271
 
272
-    if (p->bMVType == AVC_INFO && p->minCUSize != 8)
273
+    if (p->bAnalysisType == AVC_INFO && p->minCUSize != 8)
274
     {
275
         p->minCUSize = 8;
276
         x265_log(p, X265_LOG_WARNING, "Setting minCuSize = 8, AVCINFO expects 8x8 blocks\n");
277
@@ -2667,6 +2811,7 @@
278
     if (p->rc.rateControlMode == X265_RC_CQP)
279
     {
280
         p->rc.aqMode = X265_AQ_NONE;
281
+        p->rc.hevcAq = 0;
282
         p->rc.bitrate = 0;
283
         p->rc.cuTree = 0;
284
         p->rc.aqStrength = 0;
285
@@ -2689,12 +2834,17 @@
286
         x265_log(p, X265_LOG_WARNING, "Max TU size should be less than or equal to max CU size, setting max TU size = %d\n", p->maxCUSize);
287
         p->maxTUSize = p->maxCUSize;
288
     }
289
-
290
     if (p->rc.aqStrength == 0 && p->rc.cuTree == 0)
291
+    {
292
         p->rc.aqMode = X265_AQ_NONE;
293
-
294
+        p->rc.hevcAq = 0;
295
+    }
296
     if (p->rc.aqMode == X265_AQ_NONE && p->rc.cuTree == 0)
297
         p->rc.aqStrength = 0;
298
+    if (p->rc.hevcAq && p->rc.aqMode)
299
+    {
300
+        x265_log(p, X265_LOG_WARNING, "hevc-aq enabled, disabling other aq-modes\n");
301
+    }
302
 
303
     if (p->totalFrames && p->totalFrames <= 2 * ((float)p->fpsNum) / p->fpsDenom && p->rc.bStrictCbr)
304
         p->lookaheadDepth = p->totalFrames;
305
@@ -2736,16 +2886,16 @@
306
         p->rc.rfConstantMin = 0;
307
     }
308
 
309
-    if ((p->analysisLoad || p->analysisSave) && (p->bDistributeModeAnalysis || p->bDistributeMotionEstimation))
310
+    if (!(p->bAnalysisType == HEVC_INFO) && (p->analysisLoad || p->analysisSave) && p->rc.cuTree && p->analysisReuseLevel < 10)
311
     {
312
-        x265_log(p, X265_LOG_WARNING, "Analysis load/save options incompatible with pmode/pme, Disabling pmode/pme\n");
313
-        p->bDistributeMotionEstimation = p->bDistributeModeAnalysis = 0;
314
+        x265_log(p, X265_LOG_WARNING, "cu-tree works only with analysis reuse level 10, Disabling cu-tree\n");
315
+        p->rc.cuTree = 0;
316
     }
317
 
318
-    if ((p->analysisLoad || p->analysisSave) && p->rc.cuTree)
319
+    if ((p->analysisLoad || p->analysisSave) && (p->bDistributeModeAnalysis || p->bDistributeMotionEstimation))
320
     {
321
-        x265_log(p, X265_LOG_WARNING, "Analysis load/save options works only with cu-tree off, Disabling cu-tree\n");
322
-        p->rc.cuTree = 0;
323
+        x265_log(p, X265_LOG_WARNING, "Analysis load/save options incompatible with pmode/pme, Disabling pmode/pme\n");
324
+        p->bDistributeMotionEstimation = p->bDistributeModeAnalysis = 0;
325
     }
326
 
327
     if ((p->analysisLoad || p->analysisSave) && (p->analysisMultiPassRefine || p->analysisMultiPassDistortion))
328
@@ -2805,7 +2955,7 @@
329
         p->interRefine = 1;
330
     }
331
 
332
-    if (p->limitTU && (p->interRefine || p->bDynamicRefine))
333
+    if (!(p->bAnalysisType == HEVC_INFO) && p->limitTU && (p->interRefine || p->bDynamicRefine))
334
     {
335
         x265_log(p, X265_LOG_WARNING, "Inter refinement does not support limitTU. Disabling limitTU.\n");
336
         p->limitTU = 0;
337
@@ -2825,6 +2975,20 @@
338
         }
339
     }
340
 
341
+    if (p->ctuDistortionRefine == CTU_DISTORTION_INTERNAL)
342
+    {
343
+        if (!p->analysisLoad && !p->analysisSave)
344
+        {
345
+            x265_log(p, X265_LOG_WARNING, "refine-ctu-distortion 1 requires analysis save/load. Disabling refine-ctu-distortion\n");
346
+            p->ctuDistortionRefine = 0;
347
+        }
348
+        if (p->scaleFactor && p->analysisLoad)
349
+        {
350
+            x265_log(p, X265_LOG_WARNING, "refine-ctu-distortion 1 cannot be enabled along with multi resolution analysis refinement. Disabling refine-ctu-distortion\n");
351
+            p->ctuDistortionRefine = 0;
352
+        }
353
+    }
354
+
355
     if ((p->analysisMultiPassRefine || p->analysisMultiPassDistortion) && (p->bDistributeModeAnalysis || p->bDistributeMotionEstimation))
356
     {
357
         x265_log(p, X265_LOG_WARNING, "multi-pass-opt-analysis/multi-pass-opt-distortion incompatible with pmode/pme, Disabling pmode/pme\n");
358
@@ -3180,6 +3344,20 @@
359
         x265_log(p, X265_LOG_WARNING, "chunk-end cannot be less than chunk-start. Disabling chunking.\n");
360
     }
361
 
362
+    if (p->dolbyProfile)     // Default disabled.
363
+        configureDolbyVisionParams(p);
364
+
365
+    if (m_param->rc.zonefileCount && p->bOpenGOP)
366
+    {
367
+        p->bOpenGOP = 0;
368
+        x265_log(p, X265_LOG_WARNING, "Zone encoding requires closed gop structure. Enabling closed GOP.\n");
369
+    }
370
+
371
+    if (m_param->rc.zonefileCount && !p->bRepeatHeaders)
372
+    {
373
+        p->bRepeatHeaders = 1;
374
+        x265_log(p, X265_LOG_WARNING, "Turning on repeat - headers for zone encoding\n");
375
+    }
376
 }
377
 
378
 void Encoder::readAnalysisFile(x265_analysis_data* analysis, int curPoc, const x265_picture* picIn, int paramBytes)
379
@@ -3205,6 +3383,7 @@
380
     const x265_analysis_data *picData = &(picIn->analysisData);
381
     x265_analysis_intra_data *intraPic = picData->intraData;
382
     x265_analysis_inter_data *interPic = picData->interData;
383
+    x265_analysis_distortion_data *picDistortion = picData->distortionData;
384
 
385
     int poc; uint32_t frameRecordSize;
386
     X265_FREAD(&frameRecordSize, sizeof(uint32_t), 1, m_analysisFileIn, &(picData->frameRecordSize));
387
@@ -3240,6 +3419,7 @@
388
     X265_FREAD(&analysis->satdCost, sizeof(int64_t), 1, m_analysisFileIn, &(picData->satdCost));
389
     X265_FREAD(&analysis->numCUsInFrame, sizeof(int), 1, m_analysisFileIn, &(picData->numCUsInFrame));
390
     X265_FREAD(&analysis->numPartitions, sizeof(int), 1, m_analysisFileIn, &(picData->numPartitions));
391
+
392
     if (m_param->bDisableLookahead)
393
     {
394
         X265_FREAD(&analysis->numCuInHeight, sizeof(uint32_t), 1, m_analysisFileIn, &(picData->numCuInHeight));
395
@@ -3252,6 +3432,12 @@
396
         analysis->numPartitions *= factor;
397
     /* Memory is allocated for inter and intra analysis data based on the slicetype */
398
     x265_alloc_analysis_data(m_param, analysis);
399
+
400
+    if (m_param->ctuDistortionRefine == CTU_DISTORTION_INTERNAL)
401
+    {
402
+        X265_FREAD((analysis->distortionData)->ctuDistortion, sizeof(sse_t), analysis->numCUsInFrame, m_analysisFileIn, picDistortion);
403
+        computeDistortionOffset(analysis);
404
+    }
405
     if (m_param->bDisableLookahead && m_rateControl->m_isVbv)
406
     {
407
         size_t vbvCount = m_param->lookaheadDepth + m_param->bframes + 2;
408
@@ -3280,19 +3466,25 @@
409
     }
410
     if (analysis->sliceType == X265_TYPE_IDR || analysis->sliceType == X265_TYPE_I)
411
     {
412
+        if (m_param->bAnalysisType == HEVC_INFO)
413
+            return;
414
         if (m_param->analysisReuseLevel < 2)
415
             return;
416
 
417
         uint8_t *tempBuf = NULL, *depthBuf = NULL, *modeBuf = NULL, *partSizes = NULL;
418
+        int8_t *cuQPBuf = NULL;
419
 
420
         tempBuf = X265_MALLOC(uint8_t, depthBytes * 3);
421
         depthBuf = tempBuf;
422
         modeBuf = tempBuf + depthBytes;
423
         partSizes = tempBuf + 2 * depthBytes;
424
+        if (m_param->rc.cuTree)
425
+            cuQPBuf = X265_MALLOC(int8_t, depthBytes);
426
 
427
         X265_FREAD(depthBuf, sizeof(uint8_t), depthBytes, m_analysisFileIn, intraPic->depth);
428
         X265_FREAD(modeBuf, sizeof(uint8_t), depthBytes, m_analysisFileIn, intraPic->chromaModes);
429
         X265_FREAD(partSizes, sizeof(uint8_t), depthBytes, m_analysisFileIn, intraPic->partSizes);
430
+        if (m_param->rc.cuTree) { X265_FREAD(cuQPBuf, sizeof(int8_t), depthBytes, m_analysisFileIn, intraPic->cuQPOff); }
431
 
432
         size_t count = 0;
433
         for (uint32_t d = 0; d < depthBytes; d++)
434
@@ -3308,6 +3500,8 @@
435
             memset(&(analysis->intraData)->depth[count], depthBuf[d], bytes);
436
             memset(&(analysis->intraData)->chromaModes[count], modeBuf[d], bytes);
437
             memset(&(analysis->intraData)->partSizes[count], partSizes[d], bytes);
438
+            if (m_param->rc.cuTree)
439
+                memset(&(analysis->intraData)->cuQPOff[count], cuQPBuf[d], bytes);
440
             count += bytes;
441
         }
442
 
443
@@ -3323,6 +3517,8 @@
444
                 memset(&(analysis->intraData)->modes[cnt], tempLumaBuf[ctu32Idx], factor);
445
             X265_FREE(tempLumaBuf);
446
         }
447
+        if (m_param->rc.cuTree)
448
+            X265_FREE(cuQPBuf);
449
         X265_FREE(tempBuf);
450
         consumedBytes += frameRecordSize;
451
     }
452
@@ -3339,6 +3535,7 @@
453
         uint8_t *interDir = NULL, *chromaDir = NULL, *mvpIdx[2];
454
         MV* mv[2];
455
         int8_t* refIdx[2];
456
+        int8_t* cuQPBuf = NULL;
457
 
458
         int numBuf = m_param->analysisReuseLevel > 4 ? 4 : 2;
459
         bool bIntraInInter = false;
460
@@ -3348,91 +3545,107 @@
461
             bIntraInInter = (analysis->sliceType == X265_TYPE_P || m_param->bIntraInBFrames);
462
             if (bIntraInInter) numBuf++;
463
         }
464
-
465
-        tempBuf = X265_MALLOC(uint8_t, depthBytes * numBuf);
466
-        depthBuf = tempBuf;
467
-        modeBuf = tempBuf + depthBytes;
468
-
469
-        X265_FREAD(depthBuf, sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->depth);
470
-        X265_FREAD(modeBuf, sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->modes);
471
-
472
-        if (m_param->analysisReuseLevel > 4)
473
+        if (m_param->bAnalysisType == HEVC_INFO)
474
         {
475
-            partSize = modeBuf + depthBytes;
476
-            mergeFlag = partSize + depthBytes;
477
-            X265_FREAD(partSize, sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->partSize);
478
-            X265_FREAD(mergeFlag, sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->mergeFlag);
479
+            depthBytes = analysis->numCUsInFrame * analysis->numPartitions;
480
+            memcpy(((x265_analysis_inter_data *)analysis->interData)->depth, interPic->depth, depthBytes);
481
+        }
482
+        else
483
+        {
484
+            tempBuf = X265_MALLOC(uint8_t, depthBytes * numBuf);
485
+            depthBuf = tempBuf;
486
+            modeBuf = tempBuf + depthBytes;
487
+            if (m_param->rc.cuTree)
488
+                cuQPBuf = X265_MALLOC(int8_t, depthBytes);
489
+
490
+            X265_FREAD(depthBuf, sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->depth);
491
+            X265_FREAD(modeBuf, sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->modes);
492
+            if (m_param->rc.cuTree) { X265_FREAD(cuQPBuf, sizeof(int8_t), depthBytes, m_analysisFileIn, interPic->cuQPOff); }
493
 
494
-            if (m_param->analysisReuseLevel == 10)
495
+            if (m_param->analysisReuseLevel > 4)
496
             {
497
-                interDir = mergeFlag + depthBytes;
498
-                X265_FREAD(interDir, sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->interDir);
499
-                if (bIntraInInter)
500
-                {
501
-                    chromaDir = interDir + depthBytes;
502
-                    X265_FREAD(chromaDir, sizeof(uint8_t), depthBytes, m_analysisFileIn, intraPic->chromaModes);
503
-                }
504
-                for (uint32_t i = 0; i < numDir; i++)
505
-                {
506
-                    mvpIdx[i] = X265_MALLOC(uint8_t, depthBytes);
507
-                    refIdx[i] = X265_MALLOC(int8_t, depthBytes);
508
-                    mv[i] = X265_MALLOC(MV, depthBytes);
509
-                    X265_FREAD(mvpIdx[i], sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->mvpIdx[i]);
510
-                    X265_FREAD(refIdx[i], sizeof(int8_t), depthBytes, m_analysisFileIn, interPic->refIdx[i]);
511
-                    X265_FREAD(mv[i], sizeof(MV), depthBytes, m_analysisFileIn, interPic->mv[i]);
512
+                partSize = modeBuf + depthBytes;
513
+                mergeFlag = partSize + depthBytes;
514
+                X265_FREAD(partSize, sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->partSize);
515
+                X265_FREAD(mergeFlag, sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->mergeFlag);
516
+
517
+                if (m_param->analysisReuseLevel == 10)
518
+                {
519
+                    interDir = mergeFlag + depthBytes;
520
+                    X265_FREAD(interDir, sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->interDir);
521
+                    if (bIntraInInter)
522
+                    {
523
+                        chromaDir = interDir + depthBytes;
524
+                        X265_FREAD(chromaDir, sizeof(uint8_t), depthBytes, m_analysisFileIn, intraPic->chromaModes);
525
+                    }
526
+                    for (uint32_t i = 0; i < numDir; i++)
527
+                    {
528
+                        mvpIdx[i] = X265_MALLOC(uint8_t, depthBytes);
529
+                        refIdx[i] = X265_MALLOC(int8_t, depthBytes);
530
+                        mv[i] = X265_MALLOC(MV, depthBytes);
531
+                        X265_FREAD(mvpIdx[i], sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->mvpIdx[i]);
532
+                        X265_FREAD(refIdx[i], sizeof(int8_t), depthBytes, m_analysisFileIn, interPic->refIdx[i]);
533
+                        X265_FREAD(mv[i], sizeof(MV), depthBytes, m_analysisFileIn, interPic->mv[i]);
534
+                    }
535
                 }
536
             }
537
-        }
538
 
539
-        size_t count = 0;
540
-        for (uint32_t d = 0; d < depthBytes; d++)
541
-        {
542
-            int bytes = analysis->numPartitions >> (depthBuf[d] * 2);
543
-            if (m_param->scaleFactor && modeBuf[d] == MODE_INTRA && depthBuf[d] == 0)
544
-                depthBuf[d] = 1;
545
-            memset(&(analysis->interData)->depth[count], depthBuf[d], bytes);
546
-            memset(&(analysis->interData)->modes[count], modeBuf[d], bytes);
547
-            if (m_param->analysisReuseLevel > 4)
548
+            size_t count = 0;
549
+            for (uint32_t d = 0; d < depthBytes; d++)
550
             {
551
-                if (m_param->scaleFactor && modeBuf[d] == MODE_INTRA && partSize[d] == SIZE_NxN)
552
-                    partSize[d] = SIZE_2Nx2N;
553
-                memset(&(analysis->interData)->partSize[count], partSize[d], bytes);
554
-                int numPU = (modeBuf[d] == MODE_INTRA) ? 1 : nbPartsTable[(int)partSize[d]];
555
-                for (int pu = 0; pu < numPU; pu++)
556
-                {
557
-                    if (pu) d++;
558
-                    (analysis->interData)->mergeFlag[count + pu] = mergeFlag[d];
559
-                    if (m_param->analysisReuseLevel == 10)
560
+                int bytes = analysis->numPartitions >> (depthBuf[d] * 2);
561
+                if (m_param->scaleFactor && modeBuf[d] == MODE_INTRA && depthBuf[d] == 0)
562
+                    depthBuf[d] = 1;
563
+                memset(&(analysis->interData)->depth[count], depthBuf[d], bytes);
564
+                memset(&(analysis->interData)->modes[count], modeBuf[d], bytes);
565
+                if (m_param->rc.cuTree)
566
+                    memset(&(analysis->interData)->cuQPOff[count], cuQPBuf[d], bytes);
567
+                if (m_param->analysisReuseLevel > 4)
568
+                {
569
+                    if (m_param->scaleFactor && modeBuf[d] == MODE_INTRA && partSize[d] == SIZE_NxN)
570
+                        partSize[d] = SIZE_2Nx2N;
571
+                    memset(&(analysis->interData)->partSize[count], partSize[d], bytes);
572
+                    int numPU = (modeBuf[d] == MODE_INTRA) ? 1 : nbPartsTable[(int)partSize[d]];
573
+                    for (int pu = 0; pu < numPU; pu++)
574
                     {
575
-                        (analysis->interData)->interDir[count + pu] = interDir[d];
576
-                        for (uint32_t i = 0; i < numDir; i++)
577
+                        if (pu) d++;
578
+                        (analysis->interData)->mergeFlag[count + pu] = mergeFlag[d];
579
+                        if (m_param->analysisReuseLevel == 10)
580
                         {
581
-                            (analysis->interData)->mvpIdx[i][count + pu] = mvpIdx[i][d];
582
-                            (analysis->interData)->refIdx[i][count + pu] = refIdx[i][d];
583
-                            if (m_param->scaleFactor)
584
+                            (analysis->interData)->interDir[count + pu] = interDir[d];
585
+                            for (uint32_t i = 0; i < numDir; i++)
586
                             {
587
-                                mv[i][d].x *= (int16_t)m_param->scaleFactor;
588
-                                mv[i][d].y *= (int16_t)m_param->scaleFactor;
589
+                                (analysis->interData)->mvpIdx[i][count + pu] = mvpIdx[i][d];
590
+                                (analysis->interData)->refIdx[i][count + pu] = refIdx[i][d];
591
+                                if (m_param->scaleFactor)
592
+                                {
593
+                                    mv[i][d].x *= (int16_t)m_param->scaleFactor;
594
+                                    mv[i][d].y *= (int16_t)m_param->scaleFactor;
595
+                                }
596
+                                memcpy(&(analysis->interData)->mv[i][count + pu], &mv[i][d], sizeof(MV));
597
                             }
598
-                            memcpy(&(analysis->interData)->mv[i][count + pu], &mv[i][d], sizeof(MV));
599
                         }
600
                     }
601
+                    if (m_param->analysisReuseLevel == 10 && bIntraInInter)
602
+                        memset(&(analysis->intraData)->chromaModes[count], chromaDir[d], bytes);
603
                 }
604
-                if (m_param->analysisReuseLevel == 10 && bIntraInInter)
605
-                    memset(&(analysis->intraData)->chromaModes[count], chromaDir[d], bytes);
606
+                count += bytes;
607
             }
608
-            count += bytes;
609
-        }
610
-
611
-        X265_FREE(tempBuf);
612
 
613
+            if (m_param->rc.cuTree)
614
+                X265_FREE(cuQPBuf);
615
+            X265_FREE(tempBuf);
616
+        }
617
         if (m_param->analysisReuseLevel == 10)
618
         {
619
-            for (uint32_t i = 0; i < numDir; i++)
620
+            if (m_param->bAnalysisType != HEVC_INFO)
621
             {
622
-                X265_FREE(mvpIdx[i]);
623
-                X265_FREE(refIdx[i]);
624
-                X265_FREE(mv[i]);
625
+                for (uint32_t i = 0; i < numDir; i++)
626
+                {
627
+                    X265_FREE(mvpIdx[i]);
628
+                    X265_FREE(refIdx[i]);
629
+                    X265_FREE(mv[i]);
630
+                }
631
             }
632
             if (bIntraInInter)
633
             {
634
@@ -3484,6 +3697,7 @@
635
     const x265_analysis_data *picData = &(picIn->analysisData);
636
     x265_analysis_intra_data *intraPic = picData->intraData;
637
     x265_analysis_inter_data *interPic = picData->interData;
638
+    x265_analysis_distortion_data *picDistortion = picData->distortionData;
639
 
640
     int poc; uint32_t frameRecordSize;
641
     X265_FREAD(&frameRecordSize, sizeof(uint32_t), 1, m_analysisFileIn, &(picData->frameRecordSize));
642
@@ -3519,6 +3733,7 @@
643
     X265_FREAD(&analysis->satdCost, sizeof(int64_t), 1, m_analysisFileIn, &(picData->satdCost));
644
     X265_FREAD(&analysis->numCUsInFrame, sizeof(int), 1, m_analysisFileIn, &(picData->numCUsInFrame));
645
     X265_FREAD(&analysis->numPartitions, sizeof(int), 1, m_analysisFileIn, &(picData->numPartitions));
646
+    
647
     if (m_param->bDisableLookahead)
648
     {
649
         X265_FREAD(&analysis->numCuInHeight, sizeof(uint32_t), 1, m_analysisFileIn, &(picData->numCuInHeight));
650
@@ -3538,6 +3753,12 @@
651
     /* Memory is allocated for inter and intra analysis data based on the slicetype */
652
     x265_alloc_analysis_data(m_param, analysis);
653
 
654
+    if (m_param->ctuDistortionRefine == CTU_DISTORTION_INTERNAL)
655
+    {
656
+        X265_FREAD((analysis->distortionData)->ctuDistortion, sizeof(sse_t), analysis->numCUsInFrame, m_analysisFileIn, picDistortion);
657
+        computeDistortionOffset(analysis);
658
+    }
659
+
660
     analysis->numPartitions = numPartitions * factor;
661
     analysis->numCUsInFrame = numCUsInFrame;
662
     analysis->numCuInHeight = numCuInHeight;
663
@@ -3602,15 +3823,19 @@
664
             return;
665
 
666
         uint8_t *tempBuf = NULL, *depthBuf = NULL, *modeBuf = NULL, *partSizes = NULL;
667
+        int8_t *cuQPBuf = NULL;
668
 
669
         tempBuf = X265_MALLOC(uint8_t, depthBytes * 3);
670
         depthBuf = tempBuf;
671
         modeBuf = tempBuf + depthBytes;
672
         partSizes = tempBuf + 2 * depthBytes;
673
+        if (m_param->rc.cuTree)
674
+            cuQPBuf = X265_MALLOC(int8_t, depthBytes);
675
 
676
         X265_FREAD(depthBuf, sizeof(uint8_t), depthBytes, m_analysisFileIn, intraPic->depth);
677
         X265_FREAD(modeBuf, sizeof(uint8_t), depthBytes, m_analysisFileIn, intraPic->chromaModes);
678
         X265_FREAD(partSizes, sizeof(uint8_t), depthBytes, m_analysisFileIn, intraPic->partSizes);
679
+        if (m_param->rc.cuTree) { X265_FREAD(cuQPBuf, sizeof(int8_t), depthBytes, m_analysisFileIn, intraPic->cuQPOff); }
680
 
681
         uint32_t count = 0;
682
         for (uint32_t d = 0; d < depthBytes; d++)
683
@@ -3632,6 +3857,8 @@
684
                 memset(&(analysis->intraData)->depth[count], depthBuf[d], bytes);
685
                 memset(&(analysis->intraData)->chromaModes[count], modeBuf[d], bytes);
686
                 memset(&(analysis->intraData)->partSizes[count], partSizes[d], bytes);
687
+                if (m_param->rc.cuTree)
688
+                    memset(&(analysis->intraData)->cuQPOff[count], cuQPBuf[d], bytes);
689
                 count += bytes;
690
                 d += getCUIndex(&cuLoc, &count, bytes, 1);
691
             }
692
@@ -3650,6 +3877,8 @@
693
             ctu32Idx += getCUIndex(&cuLoc, &cnt, factor, 0);
694
         }
695
         X265_FREE(tempLumaBuf);
696
+        if (m_param->rc.cuTree)
697
+            X265_FREE(cuQPBuf);
698
         X265_FREE(tempBuf);
699
         consumedBytes += frameRecordSize;
700
     }
701
@@ -3666,6 +3895,7 @@
702
         uint8_t *interDir = NULL, *chromaDir = NULL, *mvpIdx[2];
703
         MV* mv[2];
704
         int8_t* refIdx[2];
705
+        int8_t* cuQPBuf = NULL;
706
 
707
         int numBuf = m_param->analysisReuseLevel > 4 ? 4 : 2;
708
         bool bIntraInInter = false;
709
@@ -3679,9 +3909,12 @@
710
         tempBuf = X265_MALLOC(uint8_t, depthBytes * numBuf);
711
         depthBuf = tempBuf;
712
         modeBuf = tempBuf + depthBytes;
713
+        if (m_param->rc.cuTree)
714
+            cuQPBuf = X265_MALLOC(int8_t, depthBytes);
715
 
716
         X265_FREAD(depthBuf, sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->depth);
717
         X265_FREAD(modeBuf, sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->modes);
718
+        if (m_param->rc.cuTree) { X265_FREAD(cuQPBuf, sizeof(int8_t), depthBytes, m_analysisFileIn, interPic->cuQPOff); }
719
         if (m_param->analysisReuseLevel > 4)
720
         {
721
             partSize = modeBuf + depthBytes;
722
@@ -3730,6 +3963,8 @@
723
             {
724
                 memset(&(analysis->interData)->depth[count], writeDepth, bytes);
725
                 memset(&(analysis->interData)->modes[count], modeBuf[d], bytes);
726
+                if (m_param->rc.cuTree)
727
+                    memset(&(analysis->interData)->cuQPOff[count], cuQPBuf[d], bytes);
728
                 if (m_param->analysisReuseLevel == 10 && bIntraInInter)
729
                     memset(&(analysis->intraData)->chromaModes[count], chromaDir[d], bytes);
730
 
731
@@ -3790,6 +4025,8 @@
732
             }
733
         }
734
 
735
+        if (m_param->rc.cuTree)
736
+            X265_FREE(cuQPBuf);
737
         X265_FREE(tempBuf);
738
 
739
         if (m_param->analysisReuseLevel == 10)
740
@@ -3891,6 +4128,8 @@
741
     X265_PARAM_VALIDATE(saveParam->lookaheadDepth, sizeof(int), 1, &m_param->lookaheadDepth, rc - lookahead);
742
     X265_PARAM_VALIDATE(saveParam->chunkStart, sizeof(int), 1, &m_param->chunkStart, chunk-start);
743
     X265_PARAM_VALIDATE(saveParam->chunkEnd, sizeof(int), 1, &m_param->chunkEnd, chunk-end);
744
+    X265_PARAM_VALIDATE(saveParam->cuTree,sizeof(int),1,&m_param->rc.cuTree, cutree - offset);
745
+    X265_PARAM_VALIDATE(saveParam->ctuDistortionRefine, sizeof(int), 1, &m_param->ctuDistortionRefine, ctu - distortion);
746
 
747
     int sourceHeight, sourceWidth;
748
     if (writeFlag)
749
@@ -4042,7 +4281,31 @@
750
     }
751
     return SIZE_2Nx2N;
752
 }
753
+void Encoder::computeDistortionOffset(x265_analysis_data* analysis)
754
+{
755
+    x265_analysis_distortion_data *distortionData = analysis->distortionData;
756
 
757
+    double sum = 0.0, sqrSum = 0.0;
758
+    for (uint32_t i = 0; i < analysis->numCUsInFrame; ++i)
759
+    {
760
+        distortionData->scaledDistortion[i] = X265_LOG2(X265_MAX(distortionData->ctuDistortion[i], 1));
761
+        sum += distortionData->scaledDistortion[i];
762
+        sqrSum += distortionData->scaledDistortion[i] * distortionData->scaledDistortion[i];
763
+    }
764
+    double avg = sum / analysis->numCUsInFrame;
765
+    distortionData->sdDistortion = pow(((sqrSum / analysis->numCUsInFrame) - (avg * avg)), 0.5);
766
+    distortionData->averageDistortion = avg;
767
+    distortionData->highDistortionCtuCount = distortionData->lowDistortionCtuCount = 0;
768
+    for (uint32_t i = 0; i < analysis->numCUsInFrame; ++i)
769
+    {
770
+        distortionData->threshold[i] = distortionData->scaledDistortion[i] / distortionData->averageDistortion;
771
+        distortionData->offset[i] = (distortionData->averageDistortion - distortionData->scaledDistortion[i]) / distortionData->sdDistortion;
772
+        if (distortionData->threshold[i] < 0.9 && distortionData->offset[i] >= 1)
773
+            distortionData->lowDistortionCtuCount++;
774
+        else if (distortionData->threshold[i] > 1.1 && distortionData->offset[i] <= -1)
775
+            distortionData->highDistortionCtuCount++;
776
+    }
777
+}
778
 void Encoder::readAnalysisFile(x265_analysis_data* analysis, int curPoc, int sliceType)
779
 {
780
 
781
@@ -4070,21 +4333,16 @@
782
     /* Now arrived at the right frame, read the record */
783
     analysis->frameRecordSize = frameRecordSize;
784
     uint8_t* tempBuf = NULL, *depthBuf = NULL;
785
-    sse_t *tempdistBuf = NULL, *distortionBuf = NULL;
786
+    X265_FREAD((analysis->distortionData)->ctuDistortion, sizeof(sse_t), analysis->numCUsInFrame, m_analysisFileIn);
787
     tempBuf = X265_MALLOC(uint8_t, depthBytes);
788
     X265_FREAD(tempBuf, sizeof(uint8_t), depthBytes, m_analysisFileIn);
789
-    tempdistBuf = X265_MALLOC(sse_t, depthBytes);
790
-    X265_FREAD(tempdistBuf, sizeof(sse_t), depthBytes, m_analysisFileIn);
791
     depthBuf = tempBuf;
792
-    distortionBuf = tempdistBuf;
793
     x265_analysis_data *analysisData = (x265_analysis_data*)analysis;
794
     x265_analysis_intra_data *intraData = analysisData->intraData;
795
     x265_analysis_inter_data *interData = analysisData->interData;
796
-    x265_analysis_distortion_data *distortionData = analysisData->distortionData;
797
 
798
+    computeDistortionOffset(analysis);
799
     size_t count = 0;
800
-    uint32_t ctuCount = 0;
801
-    double sum = 0, sqrSum = 0;
802
     for (uint32_t d = 0; d < depthBytes; d++)
803
     {
804
         int bytes = analysis->numPartitions >> (depthBuf[d] * 2);
805
@@ -4092,30 +4350,10 @@
806
             memset(&intraData->depth[count], depthBuf[d], bytes);
807
         else
808
             memset(&interData->depth[count], depthBuf[d], bytes);
809
-        distortionData->distortion[count] = distortionBuf[d];
810
-        distortionData->ctuDistortion[ctuCount] += distortionData->distortion[count];
811
         count += bytes;
812
-        if ((count % (unsigned)analysis->numPartitions) == 0)
813
-        {
814
-            distortionData->scaledDistortion[ctuCount] = X265_LOG2(X265_MAX(distortionData->ctuDistortion[ctuCount], 1));
815
-            sum += distortionData->scaledDistortion[ctuCount];
816
-            sqrSum += distortionData->scaledDistortion[ctuCount] * distortionData->scaledDistortion[ctuCount];
817
-            ctuCount++;
818
-        }
819
-    }
820
-    double avg = sum / analysis->numCUsInFrame;
821
-    distortionData->sdDistortion = pow(((sqrSum / analysis->numCUsInFrame) - (avg * avg)), 0.5);
822
-    distortionData->averageDistortion = avg;
823
-    distortionData->highDistortionCtuCount = distortionData->lowDistortionCtuCount = 0;
824
-    for (uint32_t i = 0; i < analysis->numCUsInFrame; ++i)
825
-    {
826
-        distortionData->threshold[i] = distortionData->scaledDistortion[i] / distortionData->averageDistortion;
827
-        distortionData->offset[i] = (distortionData->averageDistortion - distortionData->scaledDistortion[i]) / distortionData->sdDistortion;
828
-        if (distortionData->threshold[i] < 0.9 && distortionData->offset[i] >= 1)
829
-            distortionData->lowDistortionCtuCount++;
830
-        else if (distortionData->threshold[i] > 1.1 && distortionData->offset[i] <= -1)
831
-            distortionData->highDistortionCtuCount++;
832
     }
833
+
834
+
835
     if (!IS_X265_TYPE_I(sliceType))
836
     {
837
         MV *tempMVBuf[2], *MVBuf[2];
838
@@ -4168,11 +4406,27 @@
839
         X265_FREE(tempModeBuf);
840
     }
841
     X265_FREE(tempBuf);
842
-    X265_FREE(tempdistBuf);
843
 
844
 #undef X265_FREAD
845
 }
846
 
847
+void Encoder::copyDistortionData(x265_analysis_data* analysis, FrameData &curEncData)
848
+{
849
+    for (uint32_t cuAddr = 0; cuAddr < analysis->numCUsInFrame; cuAddr++)
850
+    {
851
+        uint8_t depth = 0;
852
+        CUData* ctu = curEncData.getPicCTU(cuAddr);
853
+        x265_analysis_distortion_data *distortionData = (x265_analysis_distortion_data *)analysis->distortionData;
854
+        distortionData->ctuDistortion[cuAddr] = 0;
855
+        for (uint32_t absPartIdx = 0; absPartIdx < ctu->m_numPartitions;)
856
+        {
857
+            depth = ctu->m_cuDepth[absPartIdx];
858
+            distortionData->ctuDistortion[cuAddr] += ctu->m_distortion[absPartIdx];
859
+            absPartIdx += ctu->m_numPartitions >> (depth * 2);
860
+        }
861
+    }
862
+}
863
+
864
 void Encoder::writeAnalysisFile(x265_analysis_data* analysis, FrameData &curEncData)
865
 {
866
 
867
@@ -4208,8 +4462,15 @@
868
         analysis->frameRecordSize += sizeof(WeightParam) * numPlanes * numDir;
869
     }
870
 
871
+    if (m_param->ctuDistortionRefine == CTU_DISTORTION_INTERNAL)
872
+    {
873
+        copyDistortionData(analysis, curEncData);
874
+        analysis->frameRecordSize += analysis->numCUsInFrame * sizeof(sse_t);
875
+    }
876
+
877
     if (m_param->analysisReuseLevel > 1)
878
     {
879
+
880
         if (analysis->sliceType == X265_TYPE_IDR || analysis->sliceType == X265_TYPE_I)
881
         {
882
             for (uint32_t cuAddr = 0; cuAddr < analysis->numCUsInFrame; cuAddr++)
883
@@ -4220,6 +4481,7 @@
884
 
885
                 CUData* ctu = curEncData.getPicCTU(cuAddr);
886
                 x265_analysis_intra_data* intraDataCTU = analysis->intraData;
887
+                int baseQP = (int)(ctu->m_encData->m_cuStat[cuAddr].baseQp + 0.5);
888
 
889
                 for (uint32_t absPartIdx = 0; absPartIdx < ctu->m_numPartitions; depthBytes++)
890
                 {
891
@@ -4232,6 +4494,8 @@
892
                     partSize = ctu->m_partSize[absPartIdx];
893
                     intraDataCTU->partSizes[depthBytes] = partSize;
894
 
895
+                    if (m_param->rc.cuTree)
896
+                        intraDataCTU->cuQPOff[depthBytes] = (int8_t)(ctu->m_qpAnalysis[absPartIdx] - baseQP);
897
                     absPartIdx += ctu->m_numPartitions >> (depth * 2);
898
                 }
899
                 memcpy(&intraDataCTU->modes[ctu->m_cuAddr * ctu->m_numPartitions], ctu->m_lumaIntraDir, sizeof(uint8_t)* ctu->m_numPartitions);
900
@@ -4249,6 +4513,7 @@
901
                 CUData* ctu = curEncData.getPicCTU(cuAddr);
902
                 x265_analysis_inter_data* interDataCTU = analysis->interData;
903
                 x265_analysis_intra_data* intraDataCTU = analysis->intraData;
904
+                int baseQP = (int)(ctu->m_encData->m_cuStat[cuAddr].baseQp + 0.5);
905
 
906
                 for (uint32_t absPartIdx = 0; absPartIdx < ctu->m_numPartitions; depthBytes++)
907
                 {
908
@@ -4257,9 +4522,11 @@
909
 
910
                     predMode = ctu->m_predMode[absPartIdx];
911
                     if (m_param->analysisReuseLevel != 10 && ctu->m_refIdx[1][absPartIdx] != -1)
912
-                        predMode = 4; // used as indiacator if the block is coded as bidir
913
+                        predMode = 4; // used as indicator if the block is coded as bidir
914
 
915
                     interDataCTU->modes[depthBytes] = predMode;
916
+                    if (m_param->rc.cuTree)
917
+                        interDataCTU->cuQPOff[depthBytes] = (int8_t)(ctu->m_qpAnalysis[absPartIdx] - baseQP);
918
 
919
                     if (m_param->analysisReuseLevel > 4)
920
                     {
921
@@ -4295,12 +4562,16 @@
922
             }
923
         }
924
 
925
-        if (analysis->sliceType == X265_TYPE_IDR || analysis->sliceType == X265_TYPE_I)
926
+        if ((analysis->sliceType == X265_TYPE_IDR || analysis->sliceType == X265_TYPE_I) && m_param->rc.cuTree)
927
+            analysis->frameRecordSize += sizeof(uint8_t)* analysis->numCUsInFrame * analysis->numPartitions + depthBytes * 3 + (sizeof(int8_t) * depthBytes);
928
+        else if (analysis->sliceType == X265_TYPE_IDR || analysis->sliceType == X265_TYPE_I)
929
             analysis->frameRecordSize += sizeof(uint8_t)* analysis->numCUsInFrame * analysis->numPartitions + depthBytes * 3;
930
         else
931
         {
932
-            /* Add sizeof depth, modes, partSize, mergeFlag */
933
+            /* Add sizeof depth, modes, partSize, cuQPOffset, mergeFlag */
934
             analysis->frameRecordSize += depthBytes * 2;
935
+            if (m_param->rc.cuTree)
936
+            analysis->frameRecordSize += (sizeof(int8_t) * depthBytes);
937
             if (m_param->analysisReuseLevel > 4)
938
                 analysis->frameRecordSize += (depthBytes * 2);
939
 
940
@@ -4331,6 +4602,8 @@
941
     X265_FWRITE(&analysis->satdCost, sizeof(int64_t), 1, m_analysisFileOut);
942
     X265_FWRITE(&analysis->numCUsInFrame, sizeof(int), 1, m_analysisFileOut);
943
     X265_FWRITE(&analysis->numPartitions, sizeof(int), 1, m_analysisFileOut);
944
+    if (m_param->ctuDistortionRefine == CTU_DISTORTION_INTERNAL)
945
+        X265_FWRITE((analysis->distortionData)->ctuDistortion, sizeof(sse_t), analysis->numCUsInFrame, m_analysisFileOut);
946
     if (analysis->sliceType > X265_TYPE_I)
947
         X265_FWRITE((WeightParam*)analysis->wt, sizeof(WeightParam), numPlanes * numDir, m_analysisFileOut);
948
 
949
@@ -4342,12 +4615,16 @@
950
         X265_FWRITE((analysis->intraData)->depth, sizeof(uint8_t), depthBytes, m_analysisFileOut);
951
         X265_FWRITE((analysis->intraData)->chromaModes, sizeof(uint8_t), depthBytes, m_analysisFileOut);
952
         X265_FWRITE((analysis->intraData)->partSizes, sizeof(char), depthBytes, m_analysisFileOut);
953
+        if (m_param->rc.cuTree)
954
+            X265_FWRITE((analysis->intraData)->cuQPOff, sizeof(int8_t), depthBytes, m_analysisFileOut);
955
         X265_FWRITE((analysis->intraData)->modes, sizeof(uint8_t), analysis->numCUsInFrame * analysis->numPartitions, m_analysisFileOut);
956
     }
957
     else
958
     {
959
         X265_FWRITE((analysis->interData)->depth, sizeof(uint8_t), depthBytes, m_analysisFileOut);
960
         X265_FWRITE((analysis->interData)->modes, sizeof(uint8_t), depthBytes, m_analysisFileOut);
961
+        if (m_param->rc.cuTree)
962
+            X265_FWRITE((analysis->interData)->cuQPOff, sizeof(int8_t), depthBytes, m_analysisFileOut);
963
         if (m_param->analysisReuseLevel > 4)
964
         {
965
             X265_FWRITE((analysis->interData)->partSize, sizeof(uint8_t), depthBytes, m_analysisFileOut);
966
@@ -4390,25 +4667,24 @@
967
     x265_analysis_inter_data *interData = analysisData->interData;
968
     x265_analysis_distortion_data *distortionData = analysisData->distortionData;
969
 
970
-    for (uint32_t cuAddr = 0; cuAddr < analysis->numCUsInFrame; cuAddr++)
971
-    {
972
-        uint8_t depth = 0;
973
-
974
-        CUData* ctu = curEncData.getPicCTU(cuAddr);
975
+    copyDistortionData(analysis, curEncData);
976
 
977
-        for (uint32_t absPartIdx = 0; absPartIdx < ctu->m_numPartitions; depthBytes++)
978
+    if (curEncData.m_slice->m_sliceType == I_SLICE)
979
+    {
980
+        for (uint32_t cuAddr = 0; cuAddr < analysis->numCUsInFrame; cuAddr++)
981
         {
982
-            depth = ctu->m_cuDepth[absPartIdx];
983
-            if (curEncData.m_slice->m_sliceType == I_SLICE)
984
+            uint8_t depth = 0;
985
+            CUData* ctu = curEncData.getPicCTU(cuAddr);
986
+            for (uint32_t absPartIdx = 0; absPartIdx < ctu->m_numPartitions; depthBytes++)
987
+            {
988
+                depth = ctu->m_cuDepth[absPartIdx];
989
                 intraData->depth[depthBytes] = depth;
990
-            else
991
-                interData->depth[depthBytes] = depth;
992
-            distortionData->distortion[depthBytes] = ctu->m_distortion[absPartIdx];
993
-            absPartIdx += ctu->m_numPartitions >> (depth * 2);
994
+                absPartIdx += ctu->m_numPartitions >> (depth * 2);
995
+            }
996
         }
997
     }
998
 
999
-    if (curEncData.m_slice->m_sliceType != I_SLICE)
1000
+    else
1001
     {
1002
         int32_t* ref[2];
1003
         ref[0] = (analysis->interData)->ref;
1004
@@ -4423,6 +4699,7 @@
1005
             for (uint32_t absPartIdx = 0; absPartIdx < ctu->m_numPartitions; depthBytes++)
1006
             {
1007
                 depth = ctu->m_cuDepth[absPartIdx];
1008
+                interData->depth[depthBytes] = depth;
1009
                 interData->mv[0][depthBytes].word = ctu->m_mv[0][absPartIdx].word;
1010
                 interData->mvpIdx[0][depthBytes] = ctu->m_mvpIdx[0][absPartIdx];
1011
                 ref[0][depthBytes] = ctu->m_refIdx[0][absPartIdx];
1012
@@ -4444,7 +4721,7 @@
1013
     /* calculate frameRecordSize */
1014
     analysis->frameRecordSize = sizeof(analysis->frameRecordSize) + sizeof(depthBytes) + sizeof(analysis->poc);
1015
     analysis->frameRecordSize += depthBytes * sizeof(uint8_t);
1016
-    analysis->frameRecordSize += depthBytes * sizeof(sse_t);
1017
+    analysis->frameRecordSize += analysis->numCUsInFrame * sizeof(sse_t);
1018
     if (curEncData.m_slice->m_sliceType != I_SLICE)
1019
     {
1020
         int numDir = (curEncData.m_slice->m_sliceType == P_SLICE) ? 1 : 2;
1021
@@ -4456,6 +4733,7 @@
1022
     X265_FWRITE(&analysis->frameRecordSize, sizeof(uint32_t), 1, m_analysisFileOut);
1023
     X265_FWRITE(&depthBytes, sizeof(uint32_t), 1, m_analysisFileOut);
1024
     X265_FWRITE(&analysis->poc, sizeof(uint32_t), 1, m_analysisFileOut);
1025
+    X265_FWRITE(distortionData->ctuDistortion, sizeof(sse_t), analysis->numCUsInFrame, m_analysisFileOut);
1026
     if (curEncData.m_slice->m_sliceType == I_SLICE)
1027
     {
1028
         X265_FWRITE((analysis->intraData)->depth, sizeof(uint8_t), depthBytes, m_analysisFileOut);
1029
@@ -4464,7 +4742,6 @@
1030
     {
1031
         X265_FWRITE((analysis->interData)->depth, sizeof(uint8_t), depthBytes, m_analysisFileOut);
1032
     }
1033
-    X265_FWRITE(distortionData->distortion, sizeof(sse_t), depthBytes, m_analysisFileOut);
1034
     if (curEncData.m_slice->m_sliceType != I_SLICE)
1035
     {
1036
         int numDir = curEncData.m_slice->m_sliceType == P_SLICE ? 1 : 2;
1037
x265_2.9.tar.gz/source/encoder/encoder.h -> x265_3.0.tar.gz/source/encoder/encoder.h Changed
47
 
1
@@ -193,6 +193,9 @@
2
     bool               m_aborted;          // fatal error detected
3
     bool               m_reconfigure;      // Encoder reconfigure in progress
4
     bool               m_reconfigureRc;
5
+    bool               m_reconfigureZone;
6
+
7
+    int               m_saveCtuDistortionLevel;
8
 
9
     /* Begin intra refresh when one not in progress or else begin one as soon as the current 
10
      * one is done. Requires bIntraRefresh to be set.*/
11
@@ -273,6 +276,8 @@
12
 
13
     void configure(x265_param *param);
14
 
15
+    void configureZone(x265_param *p, x265_param *zone);
16
+
17
     void updateVbvPlan(RateControl* rc);
18
 
19
     void readAnalysisFile(x265_analysis_data* analysis, int poc, int sliceType);
20
@@ -281,6 +286,8 @@
21
 
22
     void readAnalysisFile(x265_analysis_data* analysis, int poc, const x265_picture* picIn, int paramBytes, cuLocation cuLoc);
23
 
24
+    void computeDistortionOffset(x265_analysis_data* analysis);
25
+
26
     int getCUIndex(cuLocation* cuLoc, uint32_t* count, int bytes, int flag);
27
 
28
     int getPuShape(puOrientation* puOrient, int partSize, int numCTU);
29
@@ -289,6 +296,8 @@
30
 
31
     void writeAnalysisFileRefine(x265_analysis_data* analysis, FrameData &curEncData);
32
 
33
+    void copyDistortionData(x265_analysis_data* analysis, FrameData &curEncData);
34
+
35
     void finishFrameStats(Frame* pic, FrameEncoder *curEncoder, x265_frame_stats* frameStats, int inPoc);
36
 
37
     int validateAnalysisData(x265_analysis_data* analysis, int readWriteFlag);
38
@@ -304,6 +313,8 @@
39
 
40
     void copyUserSEIMessages(Frame *frame, const x265_picture* pic_in);
41
 
42
+    void configureDolbyVisionParams(x265_param* p);
43
+
44
 protected:
45
 
46
     void initVPS(VPS *vps);
47
x265_2.9.tar.gz/source/encoder/frameencoder.cpp -> x265_3.0.tar.gz/source/encoder/frameencoder.cpp Changed
70
 
1
@@ -335,7 +335,7 @@
2
             while (!m_frame->m_ctuInfo)
3
                 m_frame->m_copied.wait();
4
         }
5
-        if ((m_param->bMVType == AVC_INFO) && !m_param->analysisSave && !m_param->analysisLoad && !(IS_X265_TYPE_I(m_frame->m_lowres.sliceType)))
6
+        if ((m_param->bAnalysisType == AVC_INFO) && !m_param->analysisSave && !m_param->analysisLoad && !(IS_X265_TYPE_I(m_frame->m_lowres.sliceType)))
7
         {
8
             while (((m_frame->m_analysisData.interData == NULL && m_frame->m_analysisData.intraData == NULL) || (uint32_t)m_frame->m_poc != m_frame->m_analysisData.poc))
9
                 m_frame->m_copyMVType.wait();
10
@@ -657,6 +657,8 @@
11
             bpSei->m_auCpbRemovalDelayDelta = 1;
12
             bpSei->m_cpbDelayOffset = 0;
13
             bpSei->m_dpbDelayOffset = 0;
14
+            bpSei->m_concatenationFlag = (m_param->bEnableHRDConcatFlag && !m_frame->m_poc) ? true : false;
15
+
16
             // hrdFullness() calculates the initial CPB removal delay and offset
17
             m_top->m_rateControl->hrdFullness(bpSei);
18
             bpSei->writeSEImessages(m_bs, *slice->m_sps, NAL_UNIT_PREFIX_SEI, m_nalList, m_param->bSingleSeiNal);
19
@@ -1063,6 +1065,14 @@
20
         m_accessUnitBits = bytes << 3;
21
     }
22
 
23
+    if (m_frame->m_rpu.payloadSize)
24
+    {
25
+        m_bs.resetBits();
26
+        for (int i = 0; i < m_frame->m_rpu.payloadSize; i++)
27
+            m_bs.write(m_frame->m_rpu.payload[i], 8);
28
+        m_nalList.serialize(NAL_UNIT_UNSPECIFIED, m_bs);
29
+    }
30
+
31
     m_endCompressTime = x265_mdate();
32
 
33
     /* Decrement referenced frame reference counts, allow them to be recycled */
34
@@ -1599,11 +1609,11 @@
35
             if (!m_param->bEnableWavefront && col == numCols - 1)
36
             {
37
                 double qpBase = curEncData.m_cuStat[cuAddr].baseQp;
38
-                int reEncode = m_top->m_rateControl->rowVbvRateControl(m_frame, row, &m_rce, qpBase, m_sliceBaseRow, sliceId);
39
+                curRow.reEncode = m_top->m_rateControl->rowVbvRateControl(m_frame, row, &m_rce, qpBase, m_sliceBaseRow, sliceId);
40
                 qpBase = x265_clip3((double)m_param->rc.qpMin, (double)m_param->rc.qpMax, qpBase);
41
                 curEncData.m_rowStat[row].rowQp = qpBase;
42
                 curEncData.m_rowStat[row].rowQpScale = x265_qp2qScale(qpBase);
43
-                if (reEncode < 0)
44
+                if (curRow.reEncode < 0)
45
                 {
46
                     x265_log(m_param, X265_LOG_DEBUG, "POC %d row %d - encode restart required for VBV, to %.2f from %.2f\n",
47
                         m_frame->m_poc, row, qpBase, curEncData.m_cuStat[cuAddr].baseQp);
48
@@ -1642,17 +1652,19 @@
49
                             curEncData.m_rowStat[r].sumQpRc += curEncData.m_cuStat[c].baseQp;
50
                             curEncData.m_rowStat[r].numEncodedCUs = c;
51
                         }
52
+                        if (curRow.reEncode < 0)
53
+                            break;
54
                         startCuAddr = EndCuAddr - numCols;
55
                         EndCuAddr = startCuAddr + 1;
56
                     }
57
                 }
58
                 double qpBase = curEncData.m_cuStat[cuAddr].baseQp;
59
-                int reEncode = m_top->m_rateControl->rowVbvRateControl(m_frame, row, &m_rce, qpBase, m_sliceBaseRow, sliceId);
60
+                curRow.reEncode = m_top->m_rateControl->rowVbvRateControl(m_frame, row, &m_rce, qpBase, m_sliceBaseRow, sliceId);
61
                 qpBase = x265_clip3((double)m_param->rc.qpMin, (double)m_param->rc.qpMax, qpBase);
62
                 curEncData.m_rowStat[row].rowQp = qpBase;
63
                 curEncData.m_rowStat[row].rowQpScale = x265_qp2qScale(qpBase);
64
 
65
-                if (reEncode < 0)
66
+                if (curRow.reEncode < 0)
67
                 {
68
                     x265_log(m_param, X265_LOG_DEBUG, "POC %d row %d - encode restart required for VBV, to %.2f from %.2f\n",
69
                              m_frame->m_poc, row, qpBase, curEncData.m_cuStat[cuAddr].baseQp);
70
x265_2.9.tar.gz/source/encoder/frameencoder.h -> x265_3.0.tar.gz/source/encoder/frameencoder.h Changed
18
 
1
@@ -97,6 +97,8 @@
2
     volatile uint32_t completed;
3
     volatile uint32_t avgQPComputed;
4
 
5
+    volatile int      reEncode;
6
+
7
     /* called at the start of each frame to initialize state */
8
     void init(Entropy& initContext, unsigned int sid)
9
     {
10
@@ -105,6 +107,7 @@
11
         completed = 0;
12
         avgQPComputed = 0;
13
         sliceId = sid;
14
+        reEncode = 0;
15
         memset(&rowStats, 0, sizeof(rowStats));
16
         rowGoOnCoder.load(initContext);
17
     }
18
x265_2.9.tar.gz/source/encoder/nal.cpp -> x265_3.0.tar.gz/source/encoder/nal.cpp Changed
19
 
1
@@ -97,7 +97,7 @@
2
         /* Will write size later */
3
         bytes += 4;
4
     }
5
-    else if (!m_numNal || nalUnitType == NAL_UNIT_VPS || nalUnitType == NAL_UNIT_SPS || nalUnitType == NAL_UNIT_PPS)
6
+    else if (!m_numNal || nalUnitType == NAL_UNIT_VPS || nalUnitType == NAL_UNIT_SPS || nalUnitType == NAL_UNIT_PPS || nalUnitType == NAL_UNIT_UNSPECIFIED)
7
     {
8
         memcpy(out, startCodePrefix, 4);
9
         bytes += 4;
10
@@ -124,7 +124,7 @@
11
      *  - 0x000002 */
12
     for (uint32_t i = 0; i < payloadSize; i++)
13
     {
14
-        if (i > 2 && !out[bytes - 2] && !out[bytes - 3] && out[bytes - 1] <= 0x03)
15
+        if (i > 2 && !out[bytes - 2] && !out[bytes - 3] && out[bytes - 1] <= 0x03 && nalUnitType != NAL_UNIT_UNSPECIFIED)
16
         {
17
             /* inject 0x03 to prevent emulating a start code */
18
             out[bytes] = out[bytes - 1];
19
x265_2.9.tar.gz/source/encoder/ratecontrol.cpp -> x265_3.0.tar.gz/source/encoder/ratecontrol.cpp Changed
87
 
1
@@ -153,10 +153,7 @@
2
     int lowresCuHeight = ((m_param->sourceHeight / 2) + X265_LOWRES_CU_SIZE - 1) >> X265_LOWRES_CU_BITS;
3
     m_ncu = lowresCuWidth * lowresCuHeight;
4
 
5
-    if (m_param->rc.cuTree)
6
-        m_qCompress = 1;
7
-    else
8
-        m_qCompress = m_param->rc.qCompress;
9
+    m_qCompress = (m_param->rc.cuTree && !m_param->rc.hevcAq) ? 1 : m_param->rc.qCompress;
10
 
11
     // validate for param->rc, maybe it is need to add a function like x265_parameters_valiate()
12
     m_residualFrames = 0;
13
@@ -381,13 +378,14 @@
14
 
15
     m_isGrainEnabled = false;
16
     if(m_param->rc.bEnableGrain) // tune for grainy content OR equal p-b frame sizes
17
-    m_isGrainEnabled = true;
18
+        m_isGrainEnabled = true;
19
     for (int i = 0; i < 3; i++)
20
-    m_lastQScaleFor[i] = x265_qp2qScale(m_param->rc.rateControlMode == X265_RC_CRF ? CRF_INIT_QP : ABR_INIT_QP_MIN);
21
+        m_lastQScaleFor[i] = x265_qp2qScale(m_param->rc.rateControlMode == X265_RC_CRF ? CRF_INIT_QP : ABR_INIT_QP_MIN);
22
     m_avgPFrameQp = 0 ;
23
 
24
     /* 720p videos seem to be a good cutoff for cplxrSum */
25
-    double tuneCplxFactor = (m_ncu > 3600 && m_param->rc.cuTree) ? 2.5 : m_isGrainEnabled ? 1.9 : 1;
26
+    double tuneCplxFactor = (m_ncu > 3600 && m_param->rc.cuTree && !m_param->rc.hevcAq) ? 2.5 : m_param->rc.hevcAq ? 1.5 : m_isGrainEnabled ? 1.9 : 1.0;
27
+
28
     /* estimated ratio that produces a reasonable QP for the first I-frame */
29
     m_cplxrSum = .01 * pow(7.0e5, m_qCompress) * pow(m_ncu, 0.5) * tuneCplxFactor;
30
     m_wantedBitsWindow = m_bitrate * m_frameDuration;
31
@@ -741,6 +739,20 @@
32
         if (m_param->rc.rfConstantMin)
33
             m_rateFactorMaxDecrement = m_param->rc.rfConstant - m_param->rc.rfConstantMin;
34
     }
35
+    if (m_param->rc.rateControlMode == X265_RC_CQP)
36
+    {
37
+        m_qp = m_param->rc.qp;
38
+        if (m_qp && !m_param->bLossless)
39
+        {
40
+            m_qpConstant[P_SLICE] = m_qp;
41
+            m_qpConstant[I_SLICE] = x265_clip3(QP_MIN, QP_MAX_MAX, (int)(m_qp - m_ipOffset + 0.5));
42
+            m_qpConstant[B_SLICE] = x265_clip3(QP_MIN, QP_MAX_MAX, (int)(m_qp + m_pbOffset + 0.5));
43
+        }
44
+        else
45
+        {
46
+            m_qpConstant[P_SLICE] = m_qpConstant[I_SLICE] = m_qpConstant[B_SLICE] = m_qp;
47
+        }
48
+    }
49
     m_bitrate = m_param->rc.bitrate * 1000;
50
 }
51
 
52
@@ -1231,6 +1243,17 @@
53
         rce->keptAsRef = IS_REFERENCED(curFrame);
54
     m_predType = getPredictorType(curFrame->m_lowres.sliceType, m_sliceType);
55
     rce->poc = m_curSlice->m_poc;
56
+
57
+    /* change ratecontrol stats for next zone if specified */
58
+    for (int i = 0; i < m_param->rc.zonefileCount; i++)
59
+    {
60
+        if (m_param->rc.zones[i].startFrame == curFrame->m_encodeOrder)
61
+        {
62
+            m_param = m_param->rc.zones[i].zoneParam;
63
+            reconfigureRC();
64
+            init(*m_curSlice->m_sps);
65
+        }
66
+    }
67
     if (m_param->rc.bStatRead)
68
     {
69
         X265_CHECK(rce->poc >= 0 && rce->poc < m_numEntries, "bad encode ordinal\n");
70
@@ -2538,7 +2561,7 @@
71
 {
72
     double q;
73
 
74
-    if (m_param->rc.cuTree)
75
+    if (m_param->rc.cuTree && !m_param->rc.hevcAq)
76
     {
77
         // Scale and units are obtained from rateNum and rateDenom for videos with fixed frame rates.
78
         double timescale = (double)m_param->fpsDenom / (2 * m_param->fpsNum);
79
@@ -2546,6 +2569,7 @@
80
     }
81
     else
82
         q = pow(rce->blurredComplexity, 1 - m_param->rc.qCompress);
83
+
84
     // avoid NaN's in the Rceq
85
     if (rce->coeffBits + rce->mvBits == 0)
86
         q = m_lastQScaleFor[rce->sliceType];
87
x265_2.9.tar.gz/source/encoder/search.cpp -> x265_3.0.tar.gz/source/encoder/search.cpp Changed
10
 
1
@@ -2201,7 +2201,7 @@
2
         cu.getNeighbourMV(puIdx, pu.puAbsPartIdx, interMode.interNeighbours);
3
         /* Uni-directional prediction */
4
         if ((m_param->analysisLoad && m_param->analysisReuseLevel > 1 && m_param->analysisReuseLevel != 10)
5
-            || (m_param->analysisMultiPassRefine && m_param->rc.bStatRead) || (m_param->bMVType == AVC_INFO) || (useAsMVP))
6
+            || (m_param->analysisMultiPassRefine && m_param->rc.bStatRead) || (m_param->bAnalysisType == AVC_INFO) || (useAsMVP))
7
         {
8
             for (int list = 0; list < numPredDir; list++)
9
             {
10
x265_2.9.tar.gz/source/encoder/sei.cpp -> x265_3.0.tar.gz/source/encoder/sei.cpp Changed
11
 
1
@@ -66,7 +66,8 @@
2
 
3
     if (!isNested)
4
     {
5
-        bs.writeByteAlignment();
6
+        if (nalUnitType != NAL_UNIT_UNSPECIFIED)
7
+            bs.writeByteAlignment();
8
         list.serialize(nalUnitType, bs);
9
     }
10
 }
11
x265_2.9.tar.gz/source/encoder/sei.h -> x265_3.0.tar.gz/source/encoder/sei.h Changed
26
 
1
@@ -220,6 +220,7 @@
2
     SEIBufferingPeriod()
3
         : m_cpbDelayOffset(0)
4
         , m_dpbDelayOffset(0)
5
+        , m_concatenationFlag(0)
6
         , m_auCpbRemovalDelayDelta(1)
7
     {
8
         m_payloadType = BUFFERING_PERIOD;
9
@@ -227,6 +228,7 @@
10
     }
11
     bool     m_cpbDelayOffset;
12
     bool     m_dpbDelayOffset;
13
+    bool     m_concatenationFlag;
14
     uint32_t m_initialCpbRemovalDelay;
15
     uint32_t m_initialCpbRemovalDelayOffset;
16
     uint32_t m_auCpbRemovalDelayDelta;
17
@@ -237,7 +239,7 @@
18
 
19
         WRITE_UVLC(0, "bp_seq_parameter_set_id");
20
         WRITE_FLAG(0, "rap_cpb_params_present_flag");
21
-        WRITE_FLAG(0, "concatenation_flag");
22
+        WRITE_FLAG(m_concatenationFlag, "concatenation_flag");
23
         WRITE_CODE(m_auCpbRemovalDelayDelta - 1,   hrd.cpbRemovalDelayLength,       "au_cpb_removal_delay_delta_minus1");
24
         WRITE_CODE(m_initialCpbRemovalDelay,       hrd.initialCpbRemovalDelayLength,        "initial_cpb_removal_delay");
25
         WRITE_CODE(m_initialCpbRemovalDelayOffset, hrd.initialCpbRemovalDelayLength, "initial_cpb_removal_delay_offset");
26
x265_2.9.tar.gz/source/encoder/slicetype.cpp -> x265_3.0.tar.gz/source/encoder/slicetype.cpp Changed
788
 
1
@@ -3,6 +3,7 @@
2
  *
3
  * Authors: Gopu Govindaswamy <gopu@multicorewareinc.com>
4
  *          Steve Borho <steve@borho.org>
5
+ *          Ashok Kumar Mishra <ashok@multicorewareinc.com>
6
  *
7
  * This program is free software; you can redistribute it and/or modify
8
  * it under the terms of the GNU General Public License as published by
9
@@ -105,6 +106,7 @@
10
     x265_emms();
11
     return var;
12
 }
13
+
14
 /* Find the sum of pixels of each block for luma plane */
15
 uint32_t LookaheadTLD::lumaSumCu(Frame* curFrame, uint32_t blockX, uint32_t blockY, uint32_t qgSize)
16
 {
17
@@ -121,6 +123,157 @@
18
     return (uint32_t)sum_ssd;
19
 }
20
 
21
+void LookaheadTLD::xPreanalyzeQp(Frame* curFrame)
22
+{
23
+    const uint32_t width = curFrame->m_fencPic->m_picWidth;
24
+    const uint32_t height = curFrame->m_fencPic->m_picHeight;
25
+
26
+    for (uint32_t d = 0; d < 4; d++)
27
+    {
28
+        int ctuSizeIdx = 6 - g_log2Size[curFrame->m_param->maxCUSize];
29
+        int aqDepth = g_log2Size[curFrame->m_param->maxCUSize] - g_log2Size[curFrame->m_param->rc.qgSize];
30
+        if (!aqLayerDepth[ctuSizeIdx][aqDepth][d])
31
+            continue;
32
+
33
+        PicQPAdaptationLayer* pcAQLayer = &curFrame->m_lowres.pAQLayer[d];
34
+        const uint32_t aqPartWidth = pcAQLayer->aqPartWidth;
35
+        const uint32_t aqPartHeight = pcAQLayer->aqPartHeight;
36
+        double* pcAQU = pcAQLayer->dActivity;
37
+        double* pcQP = pcAQLayer->dQpOffset;
38
+        double* pcCuTree = pcAQLayer->dCuTreeOffset;
39
+
40
+        for (uint32_t y = 0; y < height; y += aqPartHeight)
41
+        {
42
+            for (uint32_t x = 0; x < width; x += aqPartWidth, pcAQU++, pcQP++, pcCuTree++)
43
+            {
44
+                double dMaxQScale = pow(2.0, curFrame->m_param->rc.qpAdaptationRange / 6.0);
45
+                double dCUAct = *pcAQU;
46
+                double dAvgAct = pcAQLayer->dAvgActivity;
47
+
48
+                double dNormAct = (dMaxQScale*dCUAct + dAvgAct) / (dCUAct + dMaxQScale*dAvgAct);
49
+                double dQpOffset = (X265_LOG2(dNormAct) / X265_LOG2(2.0)) * 6.0;
50
+                *pcQP = dQpOffset;
51
+                *pcCuTree = dQpOffset;
52
+            }
53
+        }
54
+    }
55
+}
56
+
57
+void LookaheadTLD::xPreanalyze(Frame* curFrame)
58
+{
59
+    const uint32_t width = curFrame->m_fencPic->m_picWidth;
60
+    const uint32_t height = curFrame->m_fencPic->m_picHeight;
61
+    const intptr_t stride = curFrame->m_fencPic->m_stride;
62
+
63
+    for (uint32_t d = 0; d < 4; d++)
64
+    {
65
+        int ctuSizeIdx = 6 - g_log2Size[curFrame->m_param->maxCUSize];
66
+        int aqDepth = g_log2Size[curFrame->m_param->maxCUSize] - g_log2Size[curFrame->m_param->rc.qgSize];
67
+        if (!aqLayerDepth[ctuSizeIdx][aqDepth][d])
68
+            continue;
69
+
70
+        const pixel* src = curFrame->m_fencPic->m_picOrg[0];;
71
+        PicQPAdaptationLayer* pQPLayer = &curFrame->m_lowres.pAQLayer[d];
72
+        const uint32_t aqPartWidth = pQPLayer->aqPartWidth;
73
+        const uint32_t aqPartHeight = pQPLayer->aqPartHeight;
74
+        double* pcAQU = pQPLayer->dActivity;
75
+
76
+        double dSumAct = 0.0;
77
+        for (uint32_t y = 0; y < height; y += aqPartHeight)
78
+        {
79
+            const uint32_t currAQPartHeight = X265_MIN(aqPartHeight, height - y);
80
+            for (uint32_t x = 0; x < width; x += aqPartWidth, pcAQU++)
81
+            {
82
+                const uint32_t currAQPartWidth = X265_MIN(aqPartWidth, width - x);
83
+                const pixel* pBlkY = &src[x];
84
+                uint64_t sum[4] = { 0, 0, 0, 0 };
85
+                uint64_t sumSq[4] = { 0, 0, 0, 0 };
86
+                uint32_t by = 0;
87
+                for (; by < currAQPartHeight >> 1; by++)
88
+                {
89
+                    uint32_t bx = 0;
90
+                    for (; bx < currAQPartWidth >> 1; bx++)
91
+                    {
92
+                        sum[0] += pBlkY[bx];
93
+                        sumSq[0] += pBlkY[bx] * pBlkY[bx];
94
+                    }
95
+                    for (; bx < currAQPartWidth; bx++)
96
+                    {
97
+                        sum[1] += pBlkY[bx];
98
+                        sumSq[1] += pBlkY[bx] * pBlkY[bx];
99
+                    }
100
+                    pBlkY += stride;
101
+                }
102
+                for (; by < currAQPartHeight; by++)
103
+                {
104
+                    uint32_t bx = 0;
105
+                    for (; bx < currAQPartWidth >> 1; bx++)
106
+                    {
107
+                        sum[2] += pBlkY[bx];
108
+                        sumSq[2] += pBlkY[bx] * pBlkY[bx];
109
+                    }
110
+                    for (; bx < currAQPartWidth; bx++)
111
+                    {
112
+                        sum[3] += pBlkY[bx];
113
+                        sumSq[3] += pBlkY[bx] * pBlkY[bx];
114
+                    }
115
+                    pBlkY += stride;
116
+                }
117
+
118
+                assert((currAQPartWidth & 1) == 0);
119
+                assert((currAQPartHeight & 1) == 0);
120
+                const uint32_t pixelWidthOfQuadrants = currAQPartWidth >> 1;
121
+                const uint32_t pixelHeightOfQuadrants = currAQPartHeight >> 1;
122
+                const uint32_t numPixInAQPart = pixelWidthOfQuadrants * pixelHeightOfQuadrants;
123
+
124
+                double dMinVar = MAX_DOUBLE;
125
+                if (numPixInAQPart != 0)
126
+                {
127
+                    for (int i = 0; i < 4; i++)
128
+                    {
129
+                        const double dAverage = double(sum[i]) / numPixInAQPart;
130
+                        const double dVariance = double(sumSq[i]) / numPixInAQPart - dAverage * dAverage;
131
+                        dMinVar = X265_MIN(dMinVar, dVariance);
132
+                    }
133
+                }
134
+                else
135
+                {
136
+                    dMinVar = 0.0;
137
+                }
138
+                double dActivity = 1.0 + dMinVar;
139
+                *pcAQU = dActivity;
140
+                dSumAct += dActivity;
141
+            }
142
+            src += stride * currAQPartHeight;
143
+        }
144
+
145
+        const double dAvgAct = dSumAct / (pQPLayer->numAQPartInWidth * pQPLayer->numAQPartInHeight);
146
+        pQPLayer->dAvgActivity = dAvgAct;
147
+    }
148
+
149
+    xPreanalyzeQp(curFrame);
150
+
151
+    int minAQDepth = curFrame->m_lowres.pAQLayer->minAQDepth;
152
+
153
+    PicQPAdaptationLayer* pQPLayer = &curFrame->m_lowres.pAQLayer[minAQDepth];
154
+    const uint32_t aqPartWidth = pQPLayer->aqPartWidth;
155
+    const uint32_t aqPartHeight = pQPLayer->aqPartHeight;
156
+    double* pcQP = pQPLayer->dQpOffset;
157
+
158
+    // Use new qp offset values for qpAqOffset, qpCuTreeOffset and invQscaleFactor buffer
159
+    int blockXY = 0;
160
+    for (uint32_t y = 0; y < height; y += aqPartHeight)
161
+    {
162
+        for (uint32_t x = 0; x < width; x += aqPartWidth, pcQP++)
163
+        {
164
+            curFrame->m_lowres.invQscaleFactor[blockXY] = x265_exp2fix8(*pcQP);
165
+            blockXY++;
166
+
167
+            acEnergyCu(curFrame, x, y, curFrame->m_param->internalCsp, curFrame->m_param->rc.qgSize);
168
+        }
169
+    }
170
+}
171
+
172
 void LookaheadTLD::calcAdaptiveQuantFrame(Frame *curFrame, x265_param* param)
173
 {
174
     /* Actual adaptive quantization */
175
@@ -176,90 +329,99 @@
176
         if (param->bEnableWeightedPred || param->bEnableWeightedBiPred)
177
         {
178
             for (int blockY = 0; blockY < maxRow; blockY += loopIncr)
179
-                for (int blockX = 0; blockX < maxCol; blockX += loopIncr)                
180
-                    acEnergyCu(curFrame, blockX, blockY, param->internalCsp, param->rc.qgSize);                
181
+                for (int blockX = 0; blockX < maxCol; blockX += loopIncr)
182
+                    acEnergyCu(curFrame, blockX, blockY, param->internalCsp, param->rc.qgSize);
183
         }
184
     }
185
     else
186
     {
187
-        int blockXY = 0;
188
-        double avg_adj_pow2 = 0.f, avg_adj = 0.f, qp_adj = 0.f;
189
-        double bias_strength = 0.f, strength = 0.f;
190
-        if (param->rc.aqMode == X265_AQ_AUTO_VARIANCE || param->rc.aqMode == X265_AQ_AUTO_VARIANCE_BIASED)
191
+        if (param->rc.hevcAq)
192
         {
193
-            double bit_depth_correction = 1.f / (1 << (2*(X265_DEPTH-8)));            
194
-            
195
-            for (int blockY = 0; blockY < maxRow; blockY += loopIncr)
196
-            {                
197
-                for (int blockX = 0; blockX < maxCol; blockX += loopIncr)
198
-                {
199
-                    uint32_t energy = acEnergyCu(curFrame, blockX, blockY, param->internalCsp, param->rc.qgSize);                    
200
-                    qp_adj = pow(energy * bit_depth_correction + 1, 0.1);
201
-                    curFrame->m_lowres.qpCuTreeOffset[blockXY] = qp_adj;
202
-                    avg_adj += qp_adj;
203
-                    avg_adj_pow2 += qp_adj * qp_adj;
204
-                    blockXY++;
205
-                }
206
-            }
207
-            avg_adj /= blockCount;
208
-            avg_adj_pow2 /= blockCount;
209
-            strength = param->rc.aqStrength * avg_adj;
210
-            avg_adj = avg_adj - 0.5f * (avg_adj_pow2 - modeTwoConst) / avg_adj;
211
-            bias_strength = param->rc.aqStrength;
212
+            // New method for calculating variance and qp offset
213
+            xPreanalyze(curFrame);
214
         }
215
         else
216
-            strength = param->rc.aqStrength * 1.0397f;
217
-
218
-        blockXY = 0;
219
-        for (int blockY = 0; blockY < maxRow; blockY += loopIncr)
220
         {
221
-            for (int blockX = 0; blockX < maxCol; blockX += loopIncr)
222
+            int blockXY = 0;
223
+            double avg_adj_pow2 = 0, avg_adj = 0, qp_adj = 0;
224
+            double bias_strength = 0.f;
225
+            double strength = 0.f;
226
+            if (param->rc.aqMode == X265_AQ_AUTO_VARIANCE || param->rc.aqMode == X265_AQ_AUTO_VARIANCE_BIASED)
227
             {
228
-                if (param->rc.aqMode == X265_AQ_AUTO_VARIANCE_BIASED)
229
-                {
230
-                    qp_adj = curFrame->m_lowres.qpCuTreeOffset[blockXY];
231
-                    qp_adj = strength * (qp_adj - avg_adj) + bias_strength * (1.f - modeTwoConst / (qp_adj * qp_adj));
232
-                }
233
-                else if (param->rc.aqMode == X265_AQ_AUTO_VARIANCE)
234
-                {
235
-                    qp_adj = curFrame->m_lowres.qpCuTreeOffset[blockXY];
236
-                    qp_adj = strength * (qp_adj - avg_adj);
237
-                }
238
-                else
239
+                double bit_depth_correction = 1.f / (1 << (2 * (X265_DEPTH - 8)));
240
+
241
+                for (int blockY = 0; blockY < maxRow; blockY += loopIncr)
242
                 {
243
-                    uint32_t energy = acEnergyCu(curFrame, blockX, blockY, param->internalCsp,param->rc.qgSize);
244
-                    qp_adj = strength * (X265_LOG2(X265_MAX(energy, 1)) - (modeOneConst + 2 * (X265_DEPTH - 8)));                    
245
+                    for (int blockX = 0; blockX < maxCol; blockX += loopIncr)
246
+                    {
247
+                        uint32_t energy = acEnergyCu(curFrame, blockX, blockY, param->internalCsp, param->rc.qgSize);
248
+                        qp_adj = pow(energy * bit_depth_correction + 1, 0.1);
249
+                        curFrame->m_lowres.qpCuTreeOffset[blockXY] = qp_adj;
250
+                        avg_adj += qp_adj;
251
+                        avg_adj_pow2 += qp_adj * qp_adj;
252
+                        blockXY++;
253
+                    }
254
                 }
255
+                avg_adj /= blockCount;
256
+                avg_adj_pow2 /= blockCount;
257
+                strength = param->rc.aqStrength * avg_adj;
258
+                avg_adj = avg_adj - 0.5f * (avg_adj_pow2 - modeTwoConst) / avg_adj;
259
+                bias_strength = param->rc.aqStrength;
260
+            }
261
+            else
262
+                strength = param->rc.aqStrength * 1.0397f;
263
 
264
-                if (param->bHDROpt)
265
+            blockXY = 0;
266
+            for (int blockY = 0; blockY < maxRow; blockY += loopIncr)
267
+            {
268
+                for (int blockX = 0; blockX < maxCol; blockX += loopIncr)
269
                 {
270
-                    uint32_t sum = lumaSumCu(curFrame, blockX, blockY, param->rc.qgSize);
271
-                    uint32_t lumaAvg = sum / (loopIncr * loopIncr);
272
-                    if (lumaAvg < 301)
273
-                        qp_adj += 3;
274
-                    else if (lumaAvg >= 301 && lumaAvg < 367)
275
-                        qp_adj += 2;
276
-                    else if (lumaAvg >= 367 && lumaAvg < 434)
277
-                        qp_adj += 1;
278
-                    else if (lumaAvg >= 501 && lumaAvg < 567)
279
-                        qp_adj -= 1;
280
-                    else if (lumaAvg >= 567 && lumaAvg < 634)
281
-                        qp_adj -= 2;
282
-                    else if (lumaAvg >= 634 && lumaAvg < 701)
283
-                        qp_adj -= 3;
284
-                    else if (lumaAvg >= 701 && lumaAvg < 767)
285
-                        qp_adj -= 4;
286
-                    else if (lumaAvg >= 767 && lumaAvg < 834)
287
-                        qp_adj -= 5;
288
-                    else if (lumaAvg >= 834)
289
-                        qp_adj -= 6;
290
-                }
291
-                if (quantOffsets != NULL)
292
-                    qp_adj += quantOffsets[blockXY];
293
-                curFrame->m_lowres.qpAqOffset[blockXY] = qp_adj;
294
-                curFrame->m_lowres.qpCuTreeOffset[blockXY] = qp_adj;
295
-                curFrame->m_lowres.invQscaleFactor[blockXY] = x265_exp2fix8(qp_adj);
296
-                blockXY++;
297
+                    if (param->rc.aqMode == X265_AQ_AUTO_VARIANCE_BIASED)
298
+                    {
299
+                        qp_adj = curFrame->m_lowres.qpCuTreeOffset[blockXY];
300
+                        qp_adj = strength * (qp_adj - avg_adj) + bias_strength * (1.f - modeTwoConst / (qp_adj * qp_adj));
301
+                    }
302
+                    else if (param->rc.aqMode == X265_AQ_AUTO_VARIANCE)
303
+                    {
304
+                        qp_adj = curFrame->m_lowres.qpCuTreeOffset[blockXY];
305
+                        qp_adj = strength * (qp_adj - avg_adj);
306
+                    }
307
+                    else
308
+                    {
309
+                        uint32_t energy = acEnergyCu(curFrame, blockX, blockY, param->internalCsp, param->rc.qgSize);
310
+                        qp_adj = strength * (X265_LOG2(X265_MAX(energy, 1)) - (modeOneConst + 2 * (X265_DEPTH - 8)));
311
+                    }
312
+
313
+                    if (param->bHDROpt)
314
+                    {
315
+                        uint32_t sum = lumaSumCu(curFrame, blockX, blockY, param->rc.qgSize);
316
+                        uint32_t lumaAvg = sum / (loopIncr * loopIncr);
317
+                        if (lumaAvg < 301)
318
+                            qp_adj += 3;
319
+                        else if (lumaAvg >= 301 && lumaAvg < 367)
320
+                            qp_adj += 2;
321
+                        else if (lumaAvg >= 367 && lumaAvg < 434)
322
+                            qp_adj += 1;
323
+                        else if (lumaAvg >= 501 && lumaAvg < 567)
324
+                            qp_adj -= 1;
325
+                        else if (lumaAvg >= 567 && lumaAvg < 634)
326
+                            qp_adj -= 2;
327
+                        else if (lumaAvg >= 634 && lumaAvg < 701)
328
+                            qp_adj -= 3;
329
+                        else if (lumaAvg >= 701 && lumaAvg < 767)
330
+                            qp_adj -= 4;
331
+                        else if (lumaAvg >= 767 && lumaAvg < 834)
332
+                            qp_adj -= 5;
333
+                        else if (lumaAvg >= 834)
334
+                            qp_adj -= 6;
335
+                    }
336
+                    if (quantOffsets != NULL)
337
+                        qp_adj += quantOffsets[blockXY];
338
+                    curFrame->m_lowres.qpAqOffset[blockXY] = qp_adj;
339
+                    curFrame->m_lowres.qpCuTreeOffset[blockXY] = qp_adj;
340
+                    curFrame->m_lowres.invQscaleFactor[blockXY] = x265_exp2fix8(qp_adj);
341
+                    blockXY++;
342
+                }
343
             }
344
         }
345
     }
346
@@ -301,11 +463,13 @@
347
     {
348
         int blockXY = 0;
349
         for (int blockY = 0; blockY < maxRow; blockY += loopIncr)
350
+        {
351
             for (int blockX = 0; blockX < maxCol; blockX += loopIncr)
352
             {
353
                 curFrame->m_lowres.blockVariance[blockXY] = acEnergyCu(curFrame, blockX, blockY, param->internalCsp, param->rc.qgSize);
354
                 blockXY++;
355
             }
356
+        }
357
     }
358
 }
359
 
360
@@ -596,13 +760,16 @@
361
 
362
     /* Allow the strength to be adjusted via qcompress, since the two concepts
363
      * are very similar. */
364
-
365
-    m_cuTreeStrength = 5.0 * (1.0 - m_param->rc.qCompress);
366
+    m_cuTreeStrength = (m_param->rc.hevcAq ? 6.0 : 5.0) * (1.0 - m_param->rc.qCompress);
367
 
368
     m_lastKeyframe = -m_param->keyframeMax;
369
     m_sliceTypeBusy = false;
370
     m_fullQueueSize = X265_MAX(1, m_param->lookaheadDepth);
371
-    m_bAdaptiveQuant = m_param->rc.aqMode || m_param->bEnableWeightedPred || m_param->bEnableWeightedBiPred || m_param->bAQMotion;
372
+    m_bAdaptiveQuant = m_param->rc.aqMode ||
373
+                       m_param->bEnableWeightedPred ||
374
+                       m_param->bEnableWeightedBiPred ||
375
+                       m_param->bAQMotion ||
376
+                       m_param->rc.hevcAq;
377
 
378
     /* If we have a thread pool and are using --b-adapt 2, it is generally
379
      * preferable to perform all motion searches for each lowres frame in large
380
@@ -919,10 +1086,11 @@
381
     if (!m_param->analysisLoad || !m_param->bDisableLookahead)
382
     {
383
         X265_CHECK(curFrame->m_lowres.costEst[b - p0][p1 - b] > 0, "Slice cost not estimated\n")
384
+
385
         if (m_param->rc.cuTree && !m_param->rc.bStatRead)
386
             /* update row satds based on cutree offsets */
387
             curFrame->m_lowres.satdCost = frameCostRecalculate(frames, p0, p1, b);
388
-        else if (!m_param->analysisLoad || m_param->scaleFactor)
389
+        else if (!m_param->analysisLoad || m_param->scaleFactor || m_param->bAnalysisType == HEVC_INFO)
390
         {
391
             if (m_param->rc.aqMode)
392
                 curFrame->m_lowres.satdCost = curFrame->m_lowres.costEstAq[b - p0][p1 - b];
393
@@ -1077,7 +1245,7 @@
394
     }
395
 
396
     int bframes, brefs;
397
-    if (!m_param->analysisLoad)
398
+    if (!m_param->analysisLoad || m_param->bAnalysisType == HEVC_INFO)
399
     {
400
         for (bframes = 0, brefs = 0;; bframes++)
401
         {
402
@@ -1115,6 +1283,13 @@
403
                     frm.sliceType = m_param->bOpenGOP && m_lastKeyframe >= 0 ? X265_TYPE_I : X265_TYPE_IDR;
404
                 }
405
             }
406
+            for (int i = 0; i < m_param->rc.zonefileCount; i++)
407
+            {
408
+                int curZoneStart = m_param->rc.zones[i].startFrame;
409
+                curZoneStart += curZoneStart ? m_param->rc.zones[i].zoneParam->radl : 0;
410
+                if (curZoneStart == frm.frameNum)
411
+                    frm.sliceType = X265_TYPE_IDR;
412
+            }
413
             if ((frm.sliceType == X265_TYPE_I && frm.frameNum - m_lastKeyframe >= m_param->keyframeMin) || (frm.frameNum == (m_param->chunkStart - 1)) || (frm.frameNum == m_param->chunkEnd))
414
             {
415
                 if (m_param->bOpenGOP)
416
@@ -1130,7 +1305,20 @@
417
                 /* Closed GOP */
418
                 m_lastKeyframe = frm.frameNum;
419
                 frm.bKeyframe = true;
420
-                if (bframes > 0 && !m_param->radl)
421
+                int zoneRadl = 0;
422
+                for (int i = 0; i < m_param->rc.zonefileCount; i++)
423
+                {
424
+                    int zoneStart = m_param->rc.zones[i].startFrame;
425
+                    zoneStart += zoneStart ? m_param->rc.zones[i].zoneParam->radl : 0;
426
+                    if (zoneStart == frm.frameNum)
427
+                    {
428
+                        zoneRadl = m_param->rc.zones[i].zoneParam->radl;
429
+                        m_param->radl = 0;
430
+                        m_param->rc.zones->zoneParam->radl = i < m_param->rc.zonefileCount - 1? m_param->rc.zones[i + 1].zoneParam->radl : 0;
431
+                        break;
432
+                    }
433
+                }
434
+                if (bframes > 0 && !m_param->radl && !zoneRadl)
435
                 {
436
                     list[bframes - 1]->m_lowres.sliceType = X265_TYPE_P;
437
                     bframes--;
438
@@ -1418,6 +1606,14 @@
439
     }
440
     frames[framecnt + 1] = NULL;
441
 
442
+    for (int i = 0; i < m_param->rc.zonefileCount; i++)
443
+    {
444
+        int curZoneStart = m_param->rc.zones[i].startFrame, nextZoneStart = 0;
445
+        curZoneStart += curZoneStart ? m_param->rc.zones[i].zoneParam->radl : 0;
446
+        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;
447
+        if (curZoneStart <= frames[0]->frameNum && nextZoneStart > frames[0]->frameNum)
448
+            m_param->keyframeMax = nextZoneStart - curZoneStart;
449
+    }
450
     int keylimit = m_param->keyframeMax;
451
     if (frames[0]->frameNum < m_param->chunkEnd)
452
     {
453
@@ -1627,14 +1823,16 @@
454
             frames[numFrames]->sliceType = X265_TYPE_P;
455
         }
456
 
457
-        bool bForceRADL = m_param->radl && !m_param->bOpenGOP;
458
+        int zoneRadl = m_param->rc.zonefileCount ? m_param->rc.zones->zoneParam->radl : 0;
459
+        bool bForceRADL = (m_param->radl || zoneRadl) && !m_param->bOpenGOP;
460
         bool bLastMiniGop = (framecnt >= m_param->bframes + 1) ? false : true;
461
-        int preRADL = m_lastKeyframe + m_param->keyframeMax - m_param->radl - 1; /*Frame preceeding RADL in POC order*/
462
+        int radl = m_param->radl ? m_param->radl : zoneRadl;
463
+        int preRADL = m_lastKeyframe + m_param->keyframeMax - radl - 1; /*Frame preceeding RADL in POC order*/
464
         if (bForceRADL && (frames[0]->frameNum == preRADL) && !bLastMiniGop)
465
         {
466
             int j = 1;
467
-            numBFrames = m_param->radl;
468
-            for (; j <= m_param->radl; j++)
469
+            numBFrames = m_param->radl ? m_param->radl : zoneRadl;
470
+            for (; j <= numBFrames; j++)
471
                 frames[j]->sliceType = X265_TYPE_B;
472
             frames[j]->sliceType = X265_TYPE_I;
473
         }
474
@@ -1665,6 +1863,7 @@
475
 
476
     if (m_param->rc.cuTree)
477
         cuTree(frames, X265_MIN(numFrames, m_param->keyframeMax), bKeyframe);
478
+
479
     if (m_param->gopLookahead && (keyFrameLimit >= 0) && (keyFrameLimit <= m_param->bframes + 1) && !m_extendGopBoundary)
480
         keyintLimit = keyFrameLimit;
481
 
482
@@ -1898,6 +2097,7 @@
483
 
484
     return cost;
485
 }
486
+
487
 void Lookahead::aqMotion(Lowres **frames, bool bIntra)
488
 {
489
     if (!bIntra)
490
@@ -2193,44 +2393,191 @@
491
         cuTreeFinish(frames[b], averageDuration, b == p1 ? b - p0 : 0);
492
 }
493
 
494
-void Lookahead::cuTreeFinish(Lowres *frame, double averageDuration, int ref0Distance)
495
+void Lookahead::computeCUTreeQpOffset(Lowres *frame, double averageDuration, int ref0Distance)
496
 {
497
     int fpsFactor = (int)(CLIP_DURATION(averageDuration) / CLIP_DURATION((double)m_param->fpsDenom / m_param->fpsNum) * 256);
498
-    double weightdelta = 0.0;
499
+    uint32_t loopIncr = (m_param->rc.qgSize == 8) ? 8 : 16;
500
 
501
+    double weightdelta = 0.0;
502
     if (ref0Distance && frame->weightedCostDelta[ref0Distance - 1] > 0)
503
         weightdelta = (1.0 - frame->weightedCostDelta[ref0Distance - 1]);
504
 
505
+    uint32_t widthFullRes = frame->widthFullRes;
506
+    uint32_t heightFullRes = frame->heightFullRes;
507
+
508
     if (m_param->rc.qgSize == 8)
509
     {
510
+        int minAQDepth = frame->pAQLayer->minAQDepth;
511
+
512
+        PicQPAdaptationLayer* pQPLayerMin = &frame->pAQLayer[minAQDepth];
513
+        double* pcCuTree8x8 = pQPLayerMin->dCuTreeOffset8x8;
514
+
515
         for (int cuY = 0; cuY < m_8x8Height; cuY++)
516
         {
517
             for (int cuX = 0; cuX < m_8x8Width; cuX++)
518
             {
519
                 const int cuXY = cuX + cuY * m_8x8Width;
520
-                int intracost = ((frame->intraCost[cuXY]) / 4 * frame->invQscaleFactor8x8[cuXY] + 128) >> 8;
521
+                int intracost = ((frame->intraCost[cuXY] / 4) * frame->invQscaleFactor8x8[cuXY] + 128) >> 8;
522
                 if (intracost)
523
                 {
524
-                    int propagateCost = ((frame->propagateCost[cuXY]) / 4 * fpsFactor + 128) >> 8;
525
+                    int propagateCost = ((frame->propagateCost[cuXY] / 4)  * fpsFactor + 128) >> 8;
526
                     double log2_ratio = X265_LOG2(intracost + propagateCost) - X265_LOG2(intracost) + weightdelta;
527
-                    frame->qpCuTreeOffset[cuX * 2 + cuY * m_8x8Width * 4] = frame->qpAqOffset[cuX * 2 + cuY * m_8x8Width * 4] - m_cuTreeStrength * (log2_ratio);
528
-                    frame->qpCuTreeOffset[cuX * 2 + cuY * m_8x8Width * 4 + 1] = frame->qpAqOffset[cuX * 2 + cuY * m_8x8Width * 4 + 1] - m_cuTreeStrength * (log2_ratio);
529
-                    frame->qpCuTreeOffset[cuX * 2 + cuY * m_8x8Width * 4 + frame->maxBlocksInRowFullRes] = frame->qpAqOffset[cuX * 2 + cuY * m_8x8Width * 4 + frame->maxBlocksInRowFullRes] - m_cuTreeStrength * (log2_ratio);
530
-                    frame->qpCuTreeOffset[cuX * 2 + cuY * m_8x8Width * 4 + frame->maxBlocksInRowFullRes + 1] = frame->qpAqOffset[cuX * 2 + cuY * m_8x8Width * 4 + frame->maxBlocksInRowFullRes + 1] - m_cuTreeStrength * (log2_ratio);
531
+
532
+                    pcCuTree8x8[cuX * 2 + cuY * m_8x8Width * 4] = log2_ratio;
533
+                    pcCuTree8x8[cuX * 2 + cuY * m_8x8Width * 4 + 1] = log2_ratio;
534
+                    pcCuTree8x8[cuX * 2 + cuY * m_8x8Width * 4 + frame->maxBlocksInRowFullRes] = log2_ratio;
535
+                    pcCuTree8x8[cuX * 2 + cuY * m_8x8Width * 4 + frame->maxBlocksInRowFullRes + 1] = log2_ratio;
536
+                }
537
+            }
538
+        }
539
+
540
+        for (uint32_t d = 0; d < 4; d++)
541
+        {
542
+            int ctuSizeIdx = 6 - g_log2Size[m_param->maxCUSize];
543
+            int aqDepth = g_log2Size[m_param->maxCUSize] - g_log2Size[m_param->rc.qgSize];
544
+            if (!aqLayerDepth[ctuSizeIdx][aqDepth][d])
545
+                continue;
546
+
547
+            PicQPAdaptationLayer* pQPLayer = &frame->pAQLayer[d];
548
+            const uint32_t aqPartWidth = pQPLayer->aqPartWidth;
549
+            const uint32_t aqPartHeight = pQPLayer->aqPartHeight;
550
+
551
+            const uint32_t numAQPartInWidth = pQPLayer->numAQPartInWidth;
552
+            const uint32_t numAQPartInHeight = pQPLayer->numAQPartInHeight;
553
+
554
+            double* pcQP = pQPLayer->dQpOffset;
555
+            double* pcCuTree = pQPLayer->dCuTreeOffset;
556
+
557
+            uint32_t maxCols = frame->maxBlocksInRowFullRes;
558
+
559
+            for (uint32_t y = 0; y < numAQPartInHeight; y++)
560
+            {
561
+                for (uint32_t x = 0; x < numAQPartInWidth; x++, pcQP++, pcCuTree++)
562
+                {
563
+                    uint32_t block_x = x * aqPartWidth;
564
+                    uint32_t block_y = y * aqPartHeight;
565
+
566
+                    uint32_t blockXY = 0;
567
+                    double log2_ratio = 0;
568
+                    for (uint32_t block_yy = block_y; block_yy < block_y + aqPartHeight && block_yy < heightFullRes; block_yy += loopIncr)
569
+                    {
570
+                        for (uint32_t block_xx = block_x; block_xx < block_x + aqPartWidth && block_xx < widthFullRes; block_xx += loopIncr)
571
+                        {
572
+                            uint32_t idx = ((block_yy / loopIncr) * (maxCols)) + (block_xx / loopIncr);
573
+
574
+                            log2_ratio += *(pcCuTree8x8 + idx);
575
+                            
576
+                            blockXY++;
577
+                        }
578
+                    }
579
+
580
+                    double qp_offset = (m_cuTreeStrength * log2_ratio) / blockXY;
581
+
582
+                    *pcCuTree = *pcQP - qp_offset;
583
                 }
584
             }
585
         }
586
     }
587
     else
588
     {
589
-        for (int cuIndex = 0; cuIndex < m_cuCount; cuIndex++)
590
+        for (uint32_t d = 0; d < 4; d++)
591
         {
592
-            int intracost = (frame->intraCost[cuIndex] * frame->invQscaleFactor[cuIndex] + 128) >> 8;
593
-            if (intracost)
594
+            int ctuSizeIdx = 6 - g_log2Size[m_param->maxCUSize];
595
+            int aqDepth = g_log2Size[m_param->maxCUSize] - g_log2Size[m_param->rc.qgSize];
596
+            if (!aqLayerDepth[ctuSizeIdx][aqDepth][d])
597
+                continue;
598
+
599
+            PicQPAdaptationLayer* pQPLayer = &frame->pAQLayer[d];
600
+            const uint32_t aqPartWidth = pQPLayer->aqPartWidth;
601
+            const uint32_t aqPartHeight = pQPLayer->aqPartHeight;
602
+
603
+            const uint32_t numAQPartInWidth = pQPLayer->numAQPartInWidth;
604
+            const uint32_t numAQPartInHeight = pQPLayer->numAQPartInHeight;
605
+
606
+            double* pcQP = pQPLayer->dQpOffset;
607
+            double* pcCuTree = pQPLayer->dCuTreeOffset;
608
+
609
+            uint32_t maxCols = frame->maxBlocksInRow;
610
+
611
+            for (uint32_t y = 0; y < numAQPartInHeight; y++)
612
             {
613
-                int propagateCost = (frame->propagateCost[cuIndex] * fpsFactor + 128) >> 8;
614
-                double log2_ratio = X265_LOG2(intracost + propagateCost) - X265_LOG2(intracost) + weightdelta;
615
-                frame->qpCuTreeOffset[cuIndex] = frame->qpAqOffset[cuIndex] - m_cuTreeStrength * log2_ratio;
616
+                for (uint32_t x = 0; x < numAQPartInWidth; x++, pcQP++, pcCuTree++)
617
+                {
618
+                    uint32_t block_x = x * aqPartWidth;
619
+                    uint32_t block_y = y * aqPartHeight;
620
+
621
+                    uint32_t blockXY = 0;
622
+                    double log2_ratio = 0;
623
+                    for (uint32_t block_yy = block_y; block_yy < block_y + aqPartHeight && block_yy < heightFullRes; block_yy += loopIncr)
624
+                    {
625
+                        for (uint32_t block_xx = block_x; block_xx < block_x + aqPartWidth && block_xx < widthFullRes; block_xx += loopIncr)
626
+                        {
627
+                            uint32_t idx = ((block_yy / loopIncr) * (maxCols)) + (block_xx / loopIncr);
628
+
629
+                            int intraCost = (frame->intraCost[idx] * frame->invQscaleFactor[idx] + 128) >> 8;
630
+                            int propagateCost = (frame->propagateCost[idx] * fpsFactor + 128) >> 8;
631
+
632
+                            log2_ratio += (X265_LOG2(intraCost + propagateCost) - X265_LOG2(intraCost) + weightdelta);
633
+
634
+                            blockXY++;
635
+                        }
636
+                    }
637
+
638
+                    double qp_offset = (m_cuTreeStrength * log2_ratio) / blockXY;
639
+
640
+                    *pcCuTree = *pcQP - qp_offset;
641
+
642
+                }
643
+            }
644
+        }
645
+    }
646
+}
647
+
648
+void Lookahead::cuTreeFinish(Lowres *frame, double averageDuration, int ref0Distance)
649
+{
650
+    if (m_param->rc.hevcAq)
651
+    {
652
+        computeCUTreeQpOffset(frame, averageDuration, ref0Distance);
653
+    }
654
+    else
655
+    {
656
+        int fpsFactor = (int)(CLIP_DURATION(averageDuration) / CLIP_DURATION((double)m_param->fpsDenom / m_param->fpsNum) * 256);
657
+        double weightdelta = 0.0;
658
+
659
+        if (ref0Distance && frame->weightedCostDelta[ref0Distance - 1] > 0)
660
+            weightdelta = (1.0 - frame->weightedCostDelta[ref0Distance - 1]);
661
+
662
+        if (m_param->rc.qgSize == 8)
663
+        {
664
+            for (int cuY = 0; cuY < m_8x8Height; cuY++)
665
+            {
666
+                for (int cuX = 0; cuX < m_8x8Width; cuX++)
667
+                {
668
+                    const int cuXY = cuX + cuY * m_8x8Width;
669
+                    int intracost = ((frame->intraCost[cuXY]) / 4 * frame->invQscaleFactor8x8[cuXY] + 128) >> 8;
670
+                    if (intracost)
671
+                    {
672
+                        int propagateCost = ((frame->propagateCost[cuXY]) / 4 * fpsFactor + 128) >> 8;
673
+                        double log2_ratio = X265_LOG2(intracost + propagateCost) - X265_LOG2(intracost) + weightdelta;
674
+                        frame->qpCuTreeOffset[cuX * 2 + cuY * m_8x8Width * 4] = frame->qpAqOffset[cuX * 2 + cuY * m_8x8Width * 4] - m_cuTreeStrength * (log2_ratio);
675
+                        frame->qpCuTreeOffset[cuX * 2 + cuY * m_8x8Width * 4 + 1] = frame->qpAqOffset[cuX * 2 + cuY * m_8x8Width * 4 + 1] - m_cuTreeStrength * (log2_ratio);
676
+                        frame->qpCuTreeOffset[cuX * 2 + cuY * m_8x8Width * 4 + frame->maxBlocksInRowFullRes] = frame->qpAqOffset[cuX * 2 + cuY * m_8x8Width * 4 + frame->maxBlocksInRowFullRes] - m_cuTreeStrength * (log2_ratio);
677
+                        frame->qpCuTreeOffset[cuX * 2 + cuY * m_8x8Width * 4 + frame->maxBlocksInRowFullRes + 1] = frame->qpAqOffset[cuX * 2 + cuY * m_8x8Width * 4 + frame->maxBlocksInRowFullRes + 1] - m_cuTreeStrength * (log2_ratio);
678
+                    }
679
+                }
680
+            }
681
+        }
682
+        else
683
+        {
684
+            for (int cuIndex = 0; cuIndex < m_cuCount; cuIndex++)
685
+            {
686
+                int intracost = (frame->intraCost[cuIndex] * frame->invQscaleFactor[cuIndex] + 128) >> 8;
687
+                if (intracost)
688
+                {
689
+                    int propagateCost = (frame->propagateCost[cuIndex] * fpsFactor + 128) >> 8;
690
+                    double log2_ratio = X265_LOG2(intracost + propagateCost) - X265_LOG2(intracost) + weightdelta;
691
+                    frame->qpCuTreeOffset[cuIndex] = frame->qpAqOffset[cuIndex] - m_cuTreeStrength * log2_ratio;
692
+                }
693
             }
694
         }
695
     }
696
@@ -2245,31 +2592,71 @@
697
 
698
     int64_t score = 0;
699
     int *rowSatd = frames[b]->rowSatds[b - p0][p1 - b];
700
-    double *qp_offset = frames[b]->qpCuTreeOffset;
701
 
702
     x265_emms();
703
-    for (int cuy = m_8x8Height - 1; cuy >= 0; cuy--)
704
+
705
+    if (m_param->rc.hevcAq)
706
+    {
707
+        int minAQDepth = frames[b]->pAQLayer->minAQDepth;
708
+        PicQPAdaptationLayer* pQPLayer = &frames[b]->pAQLayer[minAQDepth];
709
+        double* pcQPCuTree = pQPLayer->dCuTreeOffset;
710
+
711
+        // Use new qp offset values for qpAqOffset, qpCuTreeOffset and invQscaleFactor buffer
712
+        for (int cuy = m_8x8Height - 1; cuy >= 0; cuy--)
713
+        {
714
+            rowSatd[cuy] = 0;
715
+            for (int cux = m_8x8Width - 1; cux >= 0; cux--)
716
+            {
717
+                int cuxy = cux + cuy * m_8x8Width;
718
+                int cuCost = frames[b]->lowresCosts[b - p0][p1 - b][cuxy] & LOWRES_COST_MASK;
719
+                double qp_adj;
720
+
721
+                if (m_param->rc.qgSize == 8)
722
+                    qp_adj = (pcQPCuTree[cux * 2 + cuy * m_8x8Width * 4] +
723
+                    pcQPCuTree[cux * 2 + cuy * m_8x8Width * 4 + 1] +
724
+                    pcQPCuTree[cux * 2 + cuy * m_8x8Width * 4 + frames[b]->maxBlocksInRowFullRes] +
725
+                    pcQPCuTree[cux * 2 + cuy * m_8x8Width * 4 + frames[b]->maxBlocksInRowFullRes + 1]) / 4;
726
+                else
727
+                    qp_adj = *(pcQPCuTree + cuxy);
728
+
729
+                cuCost = (cuCost * x265_exp2fix8(qp_adj) + 128) >> 8;
730
+                rowSatd[cuy] += cuCost;
731
+                if ((cuy > 0 && cuy < m_8x8Height - 1 &&
732
+                    cux > 0 && cux < m_8x8Width - 1) ||
733
+                    m_8x8Width <= 2 || m_8x8Height <= 2)
734
+                {
735
+                    score += cuCost;
736
+                }
737
+            }
738
+        }
739
+    }
740
+    else
741
     {
742
-        rowSatd[cuy] = 0;
743
-        for (int cux = m_8x8Width - 1; cux >= 0; cux--)
744
+        double *qp_offset = frames[b]->qpCuTreeOffset;
745
+
746
+        for (int cuy = m_8x8Height - 1; cuy >= 0; cuy--)
747
         {
748
-            int cuxy = cux + cuy * m_8x8Width;
749
-            int cuCost = frames[b]->lowresCosts[b - p0][p1 - b][cuxy] & LOWRES_COST_MASK;
750
-            double qp_adj;
751
-            if (m_param->rc.qgSize == 8)
752
-                qp_adj = (qp_offset[cux * 2 + cuy * m_8x8Width * 4] +
753
-                          qp_offset[cux * 2 + cuy * m_8x8Width * 4 + 1] +
754
-                          qp_offset[cux * 2 + cuy * m_8x8Width * 4 + frames[b]->maxBlocksInRowFullRes] +
755
-                          qp_offset[cux * 2 + cuy * m_8x8Width * 4 + frames[b]->maxBlocksInRowFullRes + 1]) / 4;
756
-            else 
757
-                qp_adj = qp_offset[cuxy];
758
-            cuCost = (cuCost * x265_exp2fix8(qp_adj) + 128) >> 8;
759
-            rowSatd[cuy] += cuCost;
760
-            if ((cuy > 0 && cuy < m_8x8Height - 1 &&
761
-                 cux > 0 && cux < m_8x8Width - 1) ||
762
-                m_8x8Width <= 2 || m_8x8Height <= 2)
763
+            rowSatd[cuy] = 0;
764
+            for (int cux = m_8x8Width - 1; cux >= 0; cux--)
765
             {
766
-                score += cuCost;
767
+                int cuxy = cux + cuy * m_8x8Width;
768
+                int cuCost = frames[b]->lowresCosts[b - p0][p1 - b][cuxy] & LOWRES_COST_MASK;
769
+                double qp_adj;
770
+                if (m_param->rc.qgSize == 8)
771
+                    qp_adj = (qp_offset[cux * 2 + cuy * m_8x8Width * 4] +
772
+                    qp_offset[cux * 2 + cuy * m_8x8Width * 4 + 1] +
773
+                    qp_offset[cux * 2 + cuy * m_8x8Width * 4 + frames[b]->maxBlocksInRowFullRes] +
774
+                    qp_offset[cux * 2 + cuy * m_8x8Width * 4 + frames[b]->maxBlocksInRowFullRes + 1]) / 4;
775
+                else 
776
+                    qp_adj = qp_offset[cuxy];
777
+                cuCost = (cuCost * x265_exp2fix8(qp_adj) + 128) >> 8;
778
+                rowSatd[cuy] += cuCost;
779
+                if ((cuy > 0 && cuy < m_8x8Height - 1 &&
780
+                    cux > 0 && cux < m_8x8Width - 1) ||
781
+                    m_8x8Width <= 2 || m_8x8Height <= 2)
782
+                {
783
+                    score += cuCost;
784
+                }
785
             }
786
         }
787
     }
788
x265_2.9.tar.gz/source/encoder/slicetype.h -> x265_3.0.tar.gz/source/encoder/slicetype.h Changed
19
 
1
@@ -87,7 +87,8 @@
2
     void lowresIntraEstimate(Lowres& fenc, uint32_t qgSize);
3
 
4
     void weightsAnalyse(Lowres& fenc, Lowres& ref);
5
-
6
+    void xPreanalyze(Frame* curFrame);
7
+    void xPreanalyzeQp(Frame* curFrame);
8
 protected:
9
 
10
     uint32_t acEnergyCu(Frame* curFrame, uint32_t blockX, uint32_t blockY, int csp, uint32_t qgSize);
11
@@ -175,6 +176,7 @@
12
     void    cuTree(Lowres **frames, int numframes, bool bintra);
13
     void    estimateCUPropagate(Lowres **frames, double average_duration, int p0, int p1, int b, int referenced);
14
     void    cuTreeFinish(Lowres *frame, double averageDuration, int ref0Distance);
15
+    void    computeCUTreeQpOffset(Lowres *frame, double averageDuration, int ref0Distance);
16
 
17
     /* called by getEstimatedPictureCost() to finalize cuTree costs */
18
     int64_t frameCostRecalculate(Lowres **frames, int p0, int p1, int b);
19
x265_2.9.tar.gz/source/test/regression-tests.txt -> x265_3.0.tar.gz/source/test/regression-tests.txt Changed
18
 
1
@@ -46,6 +46,7 @@
2
 CrowdRun_1920x1080_50_10bit_444.yuv,--preset veryslow --tskip --tskip-fast --no-scenecut --limit-tu 1
3
 CrowdRun_1920x1080_50_10bit_444.yuv,--preset veryslow --aq-mode 3 --aq-strength 1.5 --aq-motion --bitrate 5000
4
 CrowdRun_1920x1080_50_10bit_444.yuv,--preset veryslow --aq-mode 3 --aq-strength 1.5 --no-psy-rd --ssim-rd
5
+CrowdRun_1920x1080_50_10bit_444.yuv,--preset veryslow --hevc-aq --no-cutree --qg-size 16
6
 DucksAndLegs_1920x1080_60_10bit_422.yuv,--preset superfast --weightp --qg-size 16
7
 DucksAndLegs_1920x1080_60_10bit_422.yuv,--preset medium --tune psnr --bframes 16 --limit-modes
8
 DucksAndLegs_1920x1080_60_10bit_422.yuv,--preset slow --temporal-layers --no-psy-rd --qg-size 32 --limit-refs 0 --cu-lossless
9
@@ -172,6 +173,8 @@
10
 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
11
 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
12
 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
13
+#save/load with ctu distortion refinement
14
+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
15
 
16
 #segment encoding
17
 BasketballDrive_1920x1080_50.y4m, --preset ultrafast --no-open-gop --chunk-start 100 --chunk-end 200
18
x265_3.0.tar.gz/source/test/save-load-tests.txt Added
21
 
1
@@ -0,0 +1,19 @@
2
+# List of command lines to be run by regression tests, see https://bitbucket.org/sborho/test-harness
3
+
4
+# the vast majority of the commands are tested for results matching the
5
+# most recent commit which was known to change outputs. The output
6
+# bitstream must be bit-exact or the test fails. If no golden outputs
7
+# are available the bitstream is validated (decoded) and then saved as a
8
+# new golden output
9
+
10
+# Note: --nr-intra, --nr-inter, and --bitrate (ABR) give different
11
+# outputs for different frame encoder counts. In order for outputs to be
12
+# consistent across many machines, you must force a certain -FN so it is
13
+# not auto-detected.
14
+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
15
+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
16
+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
17
+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
18
+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
19
+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
20
+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
21
x265_2.9.tar.gz/source/test/smoke-tests.txt -> x265_3.0.tar.gz/source/test/smoke-tests.txt Changed
6
 
1
@@ -22,3 +22,4 @@
2
 CrowdRun_1920x1080_50_10bit_444.yuv,--preset=superfast --bitrate 7000 --sao --limit-sao
3
 # Main12 intraCost overflow bug test
4
 720p50_parkrun_ter.y4m,--preset medium
5
+720p50_parkrun_ter.y4m,--preset=fast --hevc-aq --no-cutree
6
x265_2.9.tar.gz/source/test/testharness.h -> x265_3.0.tar.gz/source/test/testharness.h Changed
14
 
1
@@ -93,9 +93,9 @@
2
 
3
 #define BENCH_RUNS 2000
4
 
5
-// Adapted from checkasm.c, runs each optimized primitive four times, measures rdtsc
6
-// and discards invalid times.  Repeats 1000 times to get a good average.  Then measures
7
-// the C reference with fewer runs and reports X factor and average cycles.
8
+/* Adapted from checkasm.c, runs each optimized primitive four times, measures rdtsc
9
+ * and discards invalid times. Repeats BENCH_RUNS times to get a good average.
10
+ * Then measures the C reference with BENCH_RUNS / 4 runs and reports X factor and average cycles.*/
11
 #define REPORT_SPEEDUP(RUNOPT, RUNREF, ...) \
12
     { \
13
         uint32_t cycles = 0; int runs = 0; \
14
x265_2.9.tar.gz/source/x265.cpp -> x265_3.0.tar.gz/source/x265.cpp Changed
375
 
1
@@ -65,6 +65,8 @@
2
 {
3
     b_ctrl_c = 1;
4
 }
5
+#define START_CODE 0x00000001
6
+#define START_CODE_BYTES 4
7
 
8
 struct CLIOptions
9
 {
10
@@ -72,6 +74,8 @@
11
     ReconFile* recon;
12
     OutputFile* output;
13
     FILE*       qpfile;
14
+    FILE*       zoneFile;
15
+    FILE*    dolbyVisionRpu;    /* File containing Dolby Vision BL RPU metadata */
16
     const char* reconPlayCmd;
17
     const x265_api* api;
18
     x265_param* param;
19
@@ -94,6 +98,8 @@
20
         recon = NULL;
21
         output = NULL;
22
         qpfile = NULL;
23
+        zoneFile = NULL;
24
+        dolbyVisionRpu = NULL;
25
         reconPlayCmd = NULL;
26
         api = NULL;
27
         param = NULL;
28
@@ -110,7 +116,9 @@
29
     void destroy();
30
     void printStatus(uint32_t frameNum);
31
     bool parse(int argc, char **argv);
32
+    bool parseZoneParam(int argc, char **argv, x265_param* globalParam, int zonefileCount);
33
     bool parseQPFile(x265_picture &pic_org);
34
+    bool parseZoneFile();
35
 };
36
 
37
 void CLIOptions::destroy()
38
@@ -124,6 +132,12 @@
39
     if (qpfile)
40
         fclose(qpfile);
41
     qpfile = NULL;
42
+    if (zoneFile)
43
+        fclose(zoneFile);
44
+    zoneFile = NULL;
45
+    if (dolbyVisionRpu)
46
+        fclose(dolbyVisionRpu);
47
+    dolbyVisionRpu = NULL;
48
     if (output)
49
         output->release();
50
     output = NULL;
51
@@ -156,6 +170,110 @@
52
     prevUpdateTime = time;
53
 }
54
 
55
+bool CLIOptions::parseZoneParam(int argc, char **argv, x265_param* globalParam, int zonefileCount)
56
+{
57
+    bool bError = false;
58
+    int bShowHelp = false;
59
+    int outputBitDepth = 0;
60
+    const char *profile = NULL;
61
+
62
+    /* Presets are applied before all other options. */
63
+    for (optind = 0;;)
64
+    {
65
+        int c = getopt_long(argc, argv, short_options, long_options, NULL);
66
+        if (c == -1)
67
+            break;
68
+        else if (c == 'D')
69
+            outputBitDepth = atoi(optarg);
70
+        else if (c == 'P')
71
+            profile = optarg;
72
+        else if (c == '?')
73
+            bShowHelp = true;
74
+    }
75
+
76
+    if (!outputBitDepth && profile)
77
+    {
78
+        /* try to derive the output bit depth from the requested profile */
79
+        if (strstr(profile, "10"))
80
+            outputBitDepth = 10;
81
+        else if (strstr(profile, "12"))
82
+            outputBitDepth = 12;
83
+        else
84
+            outputBitDepth = 8;
85
+    }
86
+
87
+    api = x265_api_get(outputBitDepth);
88
+    if (!api)
89
+    {
90
+        x265_log(NULL, X265_LOG_WARNING, "falling back to default bit-depth\n");
91
+        api = x265_api_get(0);
92
+    }
93
+
94
+    if (bShowHelp)
95
+    {
96
+        printVersion(globalParam, api);
97
+        showHelp(globalParam);
98
+    }
99
+
100
+    globalParam->rc.zones[zonefileCount].zoneParam = api->param_alloc();
101
+    if (!globalParam->rc.zones[zonefileCount].zoneParam)
102
+    {
103
+        x265_log(NULL, X265_LOG_ERROR, "param alloc failed\n");
104
+        return true;
105
+    }
106
+
107
+    memcpy(globalParam->rc.zones[zonefileCount].zoneParam, globalParam, sizeof(x265_param));
108
+
109
+    for (optind = 0;;)
110
+    {
111
+        int long_options_index = -1;
112
+        int c = getopt_long(argc, argv, short_options, long_options, &long_options_index);
113
+        if (c == -1)
114
+            break;
115
+
116
+        if (long_options_index < 0 && c > 0)
117
+        {
118
+            for (size_t i = 0; i < sizeof(long_options) / sizeof(long_options[0]); i++)
119
+            {
120
+                if (long_options[i].val == c)
121
+                {
122
+                    long_options_index = (int)i;
123
+                    break;
124
+                }
125
+            }
126
+
127
+            if (long_options_index < 0)
128
+            {
129
+                /* getopt_long might have already printed an error message */
130
+                if (c != 63)
131
+                    x265_log(NULL, X265_LOG_WARNING, "internal error: short option '%c' has no long option\n", c);
132
+                return true;
133
+            }
134
+        }
135
+        if (long_options_index < 0)
136
+        {
137
+            x265_log(NULL, X265_LOG_WARNING, "short option '%c' unrecognized\n", c);
138
+            return true;
139
+        }
140
+
141
+        bError |= !!api->zone_param_parse(globalParam->rc.zones[zonefileCount].zoneParam, long_options[long_options_index].name, optarg);
142
+
143
+        if (bError)
144
+        {
145
+            const char *name = long_options_index > 0 ? long_options[long_options_index].name : argv[optind - 2];
146
+            x265_log(NULL, X265_LOG_ERROR, "invalid argument: %s = %s\n", name, optarg);
147
+            return true;
148
+        }
149
+    }
150
+
151
+    if (optind < argc)
152
+    {
153
+        x265_log(param, X265_LOG_WARNING, "extra unused command arguments given <%s>\n", argv[optind]);
154
+        return true;
155
+    }
156
+    return false;
157
+}
158
+
159
 bool CLIOptions::parse(int argc, char **argv)
160
 {
161
     bool bError = false;
162
@@ -311,6 +429,21 @@
163
                 if (!this->qpfile)
164
                     x265_log_file(param, X265_LOG_ERROR, "%s qpfile not found or error in opening qp file\n", optarg);
165
             }
166
+            OPT("dolby-vision-rpu")
167
+            {
168
+                this->dolbyVisionRpu = x265_fopen(optarg, "rb");
169
+                if (!this->dolbyVisionRpu)
170
+                {
171
+                    x265_log_file(param, X265_LOG_ERROR, "Dolby Vision RPU metadata file %s not found or error in opening file\n", optarg);
172
+                    return true;
173
+                }
174
+            }
175
+            OPT("zonefile")
176
+            {
177
+                this->zoneFile = x265_fopen(optarg, "rb");
178
+                if (!this->zoneFile)
179
+                    x265_log_file(param, X265_LOG_ERROR, "%s zone file not found or error in opening zone file\n", optarg);
180
+            }
181
             OPT("fullhelp")
182
             {
183
                 param->logLevel = X265_LOG_FULL;
184
@@ -519,6 +652,59 @@
185
     return 1;
186
 }
187
 
188
+bool CLIOptions::parseZoneFile()
189
+{
190
+    char line[256];
191
+    char* argLine;
192
+    param->rc.zonefileCount = 0;
193
+
194
+    while (fgets(line, sizeof(line), zoneFile))
195
+    {
196
+        if (!((*line == '#') || (strcmp(line, "\r\n") == 0)))
197
+            param->rc.zonefileCount++;
198
+    }
199
+
200
+    rewind(zoneFile);
201
+    param->rc.zones = X265_MALLOC(x265_zone, param->rc.zonefileCount);
202
+    for (int i = 0; i < param->rc.zonefileCount; i++)
203
+    {
204
+        while (fgets(line, sizeof(line), zoneFile))
205
+        {
206
+            if (*line == '#' || (strcmp(line, "\r\n") == 0))
207
+                continue;
208
+            param->rc.zones[i].zoneParam = X265_MALLOC(x265_param, 1);
209
+            int index = (int)strcspn(line, "\r\n");
210
+            line[index] = '\0';
211
+            argLine = line;
212
+            while (isspace((unsigned char)*argLine)) argLine++;
213
+            char* start = strchr(argLine, ' ');
214
+            start++;
215
+            param->rc.zones[i].startFrame = atoi(argLine);
216
+            int argCount = 0;
217
+            char **args = (char**)malloc(256 * sizeof(char *));
218
+            // Adding a dummy string to avoid file parsing error
219
+            args[argCount++] = (char *)"x265";
220
+            char* token = strtok(start, " ");
221
+            while (token) 
222
+            {
223
+                args[argCount++] = token;
224
+                token = strtok(NULL, " ");
225
+            }
226
+            args[argCount] = NULL;
227
+            CLIOptions cliopt;
228
+            if (cliopt.parseZoneParam(argCount, args,param, i))
229
+            {
230
+                cliopt.destroy();
231
+                if (cliopt.api)
232
+                    cliopt.api->param_free(cliopt.param);
233
+                exit(1);
234
+            }
235
+            break;
236
+        }
237
+    }
238
+    return 1;
239
+}
240
+
241
 #ifdef _WIN32
242
 /* Copy of x264 code, which allows for Unicode characters in the command line.
243
  * Retrieve command line arguments as UTF-8. */
244
@@ -552,6 +738,59 @@
245
 }
246
 #endif
247
 
248
+/* Parse the RPU file and extract the RPU corresponding to the current picture 
249
+ * and fill the rpu field of the input picture */
250
+static int rpuParser(x265_picture * pic, FILE * ptr)
251
+{
252
+    uint8_t byteVal;
253
+    uint32_t code = 0;
254
+    int bytesRead = 0;
255
+    pic->rpu.payloadSize = 0;
256
+
257
+    if (!pic->pts)
258
+    {
259
+        while (bytesRead++ < 4 && fread(&byteVal, sizeof(uint8_t), 1, ptr))
260
+            code = (code << 8) | byteVal;
261
+      
262
+        if (code != START_CODE)
263
+        {
264
+            x265_log(NULL, X265_LOG_ERROR, "Invalid Dolby Vision RPU startcode in POC %d\n", pic->pts);
265
+            return 1;
266
+        }
267
+    } 
268
+
269
+    bytesRead = 0;
270
+    while (fread(&byteVal, sizeof(uint8_t), 1, ptr))
271
+    {
272
+        code = (code << 8) | byteVal;
273
+        if (bytesRead++ < 3)
274
+            continue;
275
+        if (bytesRead >= 1024)
276
+        {
277
+            x265_log(NULL, X265_LOG_ERROR, "Invalid Dolby Vision RPU size in POC %d\n", pic->pts);
278
+            return 1;
279
+        }
280
+        
281
+        if (code != START_CODE)
282
+            pic->rpu.payload[pic->rpu.payloadSize++] = (code >> (3 * 8)) & 0xFF;
283
+        else
284
+            return 0;       
285
+    }
286
+
287
+    int ShiftBytes = START_CODE_BYTES - (bytesRead - pic->rpu.payloadSize);
288
+    int bytesLeft = bytesRead - pic->rpu.payloadSize;
289
+    code = (code << ShiftBytes * 8);
290
+    for (int i = 0; i < bytesLeft; i++)
291
+    {
292
+        pic->rpu.payload[pic->rpu.payloadSize++] = (code >> (3 * 8)) & 0xFF;
293
+        code = (code << 8);
294
+    }
295
+    if (!pic->rpu.payloadSize)
296
+        x265_log(NULL, X265_LOG_WARNING, "Dolby Vision RPU not found for POC %d\n", pic->pts);
297
+    return 0;
298
+}
299
+
300
+
301
 /* CLI return codes:
302
  *
303
  * 0 - encode successful
304
@@ -598,6 +837,16 @@
305
     if (cliopt.reconPlayCmd)
306
         reconPlay = new ReconPlay(cliopt.reconPlayCmd, *param);
307
 
308
+    if (cliopt.zoneFile)
309
+    {
310
+        if (!cliopt.parseZoneFile())
311
+        {
312
+            x265_log(NULL, X265_LOG_ERROR, "Unable to parse zonefile\n");
313
+            fclose(cliopt.zoneFile);
314
+            cliopt.zoneFile = NULL;
315
+        }
316
+    }
317
+
318
     /* note: we could try to acquire a different libx265 API here based on
319
      * the profile found during option parsing, but it must be done before
320
      * opening an encoder */
321
@@ -630,8 +879,10 @@
322
     x265_stats stats;
323
     uint32_t nal;
324
     int16_t *errorBuf = NULL;
325
+    bool bDolbyVisionRPU = false;
326
     int ret = 0;
327
 
328
+
329
     if (!param->bRepeatHeaders)
330
     {
331
         if (api->encoder_headers(encoder, &p_nal, &nal) < 0)
332
@@ -646,6 +897,13 @@
333
 
334
     api->picture_init(param, pic_in);
335
 
336
+    if (param->dolbyProfile && cliopt.dolbyVisionRpu)
337
+    {
338
+        pic_in->rpu.payload = X265_MALLOC(uint8_t, 1024);
339
+        if (pic_in->rpu.payload)
340
+            bDolbyVisionRPU = true;
341
+    }
342
+    
343
     if (cliopt.bDither)
344
     {
345
         errorBuf = X265_MALLOC(int16_t, param->sourceWidth + 1);
346
@@ -685,8 +943,13 @@
347
             }
348
             /* Overwrite PTS */
349
             pic_in->pts = pic_in->poc;
350
-        }
351
 
352
+            if (bDolbyVisionRPU)
353
+            {
354
+                if (rpuParser(pic_in, cliopt.dolbyVisionRpu) > 0)
355
+                    goto fail;
356
+            }
357
+        }
358
         int numEncoded = api->encoder_encode(encoder, &p_nal, &nal, pic_in, pic_recon);
359
         if (numEncoded < 0)
360
         {
361
@@ -749,6 +1012,13 @@
362
             break;
363
     }
364
   
365
+    if (bDolbyVisionRPU)
366
+    {
367
+        if(fgetc(cliopt.dolbyVisionRpu) != EOF)
368
+            x265_log(NULL, X265_LOG_WARNING, "Dolby Vision RPU count is greater than frame count\n");
369
+        x265_log(NULL, X265_LOG_INFO, "VES muxing with Dolby Vision RPU file successful\n");
370
+    }
371
+
372
     /* clear progress report */
373
     if (cliopt.bProgress)
374
         fprintf(stderr, "%*s\r", 80, " ");
375
x265_2.9.tar.gz/source/x265.h -> x265_3.0.tar.gz/source/x265.h Changed
207
 
1
@@ -81,6 +81,7 @@
2
     NAL_UNIT_FILLER_DATA,
3
     NAL_UNIT_PREFIX_SEI,
4
     NAL_UNIT_SUFFIX_SEI,
5
+    NAL_UNIT_UNSPECIFIED = 62,
6
     NAL_UNIT_INVALID = 64,
7
 } NalUnitType;
8
 
9
@@ -129,6 +130,8 @@
10
     int     lookaheadDepth;
11
     int     chunkStart;
12
     int     chunkEnd;
13
+    int     cuTree;
14
+    int     ctuDistortionRefine;
15
 }x265_analysis_validate;
16
 
17
 /* Stores intra analysis data for a single frame. This struct needs better packing */
18
@@ -138,6 +141,7 @@
19
     uint8_t*  modes;
20
     char*     partSizes;
21
     uint8_t*  chromaModes;
22
+    int8_t*    cuQPOff;
23
 }x265_analysis_intra_data;
24
 
25
 typedef struct x265_analysis_MV
26
@@ -162,6 +166,7 @@
27
     int8_t*     refIdx[2];
28
     x265_analysis_MV*         mv[2];
29
     int64_t*     sadCost;
30
+    int8_t*    cuQPOff;
31
 }x265_analysis_inter_data;
32
 
33
 typedef struct x265_weight_param
34
@@ -178,9 +183,12 @@
35
 typedef uint64_t sse_t;
36
 #endif
37
 
38
+#define CTU_DISTORTION_OFF 0
39
+#define CTU_DISTORTION_INTERNAL 1
40
+#define CTU_DISTORTION_EXTERNAL 2
41
+
42
 typedef struct x265_analysis_distortion_data
43
 {
44
-    sse_t*        distortion;
45
     sse_t*        ctuDistortion;
46
     double*       scaledDistortion;
47
     double        averageDistortion;
48
@@ -189,6 +197,7 @@
49
     uint32_t      lowDistortionCtuCount;
50
     double*       offset;
51
     double*       threshold;
52
+
53
 }x265_analysis_distortion_data;
54
 
55
 /* Stores all analysis data for a single frame */
56
@@ -308,7 +317,8 @@
57
 {
58
     NO_INFO = 0,
59
     AVC_INFO = 1,
60
-}MVRefineType;
61
+    HEVC_INFO = 2,
62
+}AnalysisRefineType;
63
 
64
 /* Arbitrary User SEI
65
  * Payload size is in bytes and the payload pointer must be non-NULL. 
66
@@ -360,6 +370,12 @@
67
     x265_sei_payload *payloads;
68
 } x265_sei;
69
 
70
+typedef struct x265_dolby_vision_rpu
71
+{
72
+    int payloadSize;
73
+    uint8_t* payload;
74
+}x265_dolby_vision_rpu;
75
+
76
 /* Used to pass pictures into the encoder, and to get picture data back out of
77
  * the encoder.  The input and output semantics are different */
78
 typedef struct x265_picture
79
@@ -445,6 +461,9 @@
80
 
81
     // pts is reordered in the order of encoding.
82
     int64_t reorderedPts;
83
+
84
+    //Dolby Vision RPU metadata
85
+    x265_dolby_vision_rpu rpu;
86
 } x265_picture;
87
 
88
 typedef enum
89
@@ -641,6 +660,8 @@
90
 static const char * const x265_interlace_names[] = { "prog", "tff", "bff", 0 };
91
 static const char * const x265_analysis_names[] = { "off", "save", "load", 0 };
92
 
93
+struct x265_zone;
94
+struct x265_param;
95
 /* Zones: override ratecontrol for specific sections of the video.
96
  * If zones overlap, whichever comes later in the list takes precedence. */
97
 typedef struct x265_zone
98
@@ -649,6 +670,7 @@
99
     int   bForceQp;             /* whether to use qp vs bitrate factor */
100
     int   qp;
101
     float bitrateFactor;
102
+    struct x265_param* zoneParam;
103
 } x265_zone;
104
     
105
 /* data to calculate aggregate VMAF score */
106
@@ -688,9 +710,12 @@
107
     int ssim;
108
     int ms_ssim;
109
     char *pool;
110
+    int thread;
111
+    int subsample;
112
+    int enable_conf_interval;
113
 }x265_vmaf_commondata;
114
 
115
-static const x265_vmaf_commondata vcd[] = { { NULL, (char *)"/usr/local/share/model/vmaf_v0.6.1.pkl", NULL, NULL, 0, 0, 0, 0, 0, 0, 0, NULL } };
116
+static const x265_vmaf_commondata vcd[] = { { NULL, (char *)"/usr/local/share/model/vmaf_v0.6.1.pkl", NULL, NULL, 0, 0, 0, 0, 0, 0, 0, NULL, 0, 1, 0 } };
117
 
118
 /* x265 input parameters
119
  *
120
@@ -1320,13 +1345,25 @@
121
         /* Enable adaptive quantization. This mode distributes available bits between all
122
          * CTUs of a frame, assigning more bits to low complexity areas. Turning
123
          * this ON will usually affect PSNR negatively, however SSIM and visual quality
124
-         * generally improves. Default: X265_AQ_VARIANCE */
125
+         * generally improves. Default: X265_AQ_AUTO_VARIANCE */
126
         int       aqMode;
127
 
128
+        /*
129
+         * Enable adaptive quantization.
130
+         * It scales the quantization step size according to the spatial activity of one
131
+         * coding unit relative to frame average spatial activity. This AQ method utilizes
132
+         * the minimum variance of sub-unit in each coding unit to represent the coding
133
+         * unit’s spatial complexity. */
134
+        int       hevcAq;
135
+
136
         /* Sets the strength of AQ bias towards low detail CTUs. Valid only if
137
          * AQ is enabled. Default value: 1.0. Acceptable values between 0.0 and 3.0 */
138
         double    aqStrength;
139
 
140
+        /* Delta QP range by QP adaptation based on a psycho-visual model.
141
+         * Acceptable values between 1.0 to 6.0 */
142
+        double    qpAdaptationRange;
143
+
144
         /* Sets the maximum rate the VBV buffer should be assumed to refill at
145
          * Default is zero */
146
         int       vbvMaxBitrate;
147
@@ -1374,6 +1411,9 @@
148
         int        zoneCount;
149
         x265_zone* zones;
150
 
151
+        /* number of zones in zone-file*/
152
+        int        zonefileCount;
153
+
154
         /* specify a text file which contains MAX_MAX_QP + 1 floating point
155
          * values to be copied into x265_lambda_tab and a second set of
156
          * MAX_MAX_QP + 1 floating point values for x265_lambda2_tab. All values
157
@@ -1662,7 +1702,7 @@
158
     double    vbvEndFrameAdjust;
159
 
160
     /* Reuse MV information obtained through API */
161
-    int       bMVType;
162
+    int       bAnalysisType;
163
     /* Allow the encoder to have a copy of the planes of x265_picture in Frame */
164
     int       bCopyPicToFrame;
165
 
166
@@ -1710,8 +1750,22 @@
167
     /* File containing base64 encoded SEI messages in POC order */
168
     const char*    naluFile;
169
 
170
-} x265_param;
171
+    /* Generate bitstreams confirming to the specified dolby vision profile,
172
+     * note that 0x7C01 makes RPU appear to be an unspecified NAL type in
173
+     * HEVC stream. if BL is backward compatible, Dolby Vision single
174
+     * layer VES will be equivalent to a backward compatible BL VES on legacy
175
+     * device as RPU will be ignored. Default 0 (disabled) */
176
+    int dolbyProfile;
177
+
178
+    /* Set concantenation flag for the first keyframe in the HRD buffering period SEI. */
179
+    int bEnableHRDConcatFlag;
180
 
181
+
182
+    /* Store/normalize ctu distortion in analysis-save/load. Ranges from 0 - 1.
183
+    *  0 - Disabled. 1 - Save/Load ctu distortion to/from the file specified 
184
+    * analysis-save/load. Default 0. */
185
+    int       ctuDistortionRefine;
186
+} x265_param;
187
 /* x265_param_alloc:
188
  *  Allocates an x265_param instance. The returned param structure is not
189
  *  special in any way, but using this method together with x265_param_free()
190
@@ -1738,6 +1792,8 @@
191
 #define X265_PARAM_BAD_VALUE (-2)
192
 int x265_param_parse(x265_param *p, const char *name, const char *value);
193
 
194
+int x265_zone_param_parse(x265_param* p, const char* name, const char* value);
195
+
196
 static const char * const x265_profile_names[] = {
197
     /* HEVC v1 */
198
     "main", "main10", "mainstillpicture", /* alias */ "msp",
199
@@ -2031,6 +2087,7 @@
200
     double        (*calculate_vmaf_framelevelscore)(x265_vmaf_framedata *);
201
     void          (*vmaf_encoder_log)(x265_encoder*, int, char**, x265_param *, x265_vmaf_data *);
202
 #endif
203
+    int           (*zone_param_parse)(x265_param*, const char*, const char*);
204
     /* add new pointers to the end, or increment X265_MAJOR_VERSION */
205
 } x265_api;
206
 
207
x265_2.9.tar.gz/source/x265cli.h -> x265_3.0.tar.gz/source/x265cli.h Changed
89
 
1
@@ -242,6 +242,7 @@
2
     { "no-info",              no_argument, NULL, 0 },
3
     { "zones",          required_argument, NULL, 0 },
4
     { "qpfile",         required_argument, NULL, 0 },
5
+    { "zonefile",       required_argument, NULL, 0 },
6
     { "lambda-file",    required_argument, NULL, 0 },
7
     { "b-intra",              no_argument, NULL, 0 },
8
     { "no-b-intra",           no_argument, NULL, 0 },
9
@@ -288,13 +289,15 @@
10
     { "dhdr10-info",    required_argument, NULL, 0 },
11
     { "dhdr10-opt",           no_argument, NULL, 0},
12
     { "no-dhdr10-opt",        no_argument, NULL, 0},
13
+    { "dolby-vision-profile",  required_argument, NULL, 0 },
14
     { "refine-mv",            no_argument, NULL, 0 },
15
     { "no-refine-mv",         no_argument, NULL, 0 },
16
+    { "refine-ctu-distortion", required_argument, NULL, 0 },
17
     { "force-flush",    required_argument, NULL, 0 },
18
     { "splitrd-skip",         no_argument, NULL, 0 },
19
     { "no-splitrd-skip",      no_argument, NULL, 0 },
20
     { "lowpass-dct",          no_argument, NULL, 0 },
21
-    { "refine-mv-type", required_argument, NULL, 0 },
22
+    { "refine-analysis-type", required_argument, NULL, 0 },
23
     { "copy-pic",             no_argument, NULL, 0 },
24
     { "no-copy-pic",          no_argument, NULL, 0 },
25
     { "max-ausize-factor", required_argument, NULL, 0 },
26
@@ -305,6 +308,12 @@
27
     { "atc-sei", required_argument, NULL, 0 },
28
     { "pic-struct", required_argument, NULL, 0 },
29
     { "nalu-file", required_argument, NULL, 0 },
30
+    { "dolby-vision-rpu", required_argument, NULL, 0 },
31
+    { "hrd-concat",          no_argument, NULL, 0},
32
+    { "no-hrd-concat",       no_argument, NULL, 0 },
33
+    { "hevc-aq", no_argument, NULL, 0 },
34
+    { "no-hevc-aq", no_argument, NULL, 0 },
35
+    { "qp-adaptation-range", required_argument, NULL, 0 },
36
     { 0, 0, 0, 0 },
37
     { 0, 0, 0, 0 },
38
     { 0, 0, 0, 0 },
39
@@ -355,6 +364,9 @@
40
     H0("   --dhdr10-info <filename>      JSON file containing the Creative Intent Metadata to be encoded as Dynamic Tone Mapping\n");
41
     H0("   --[no-]dhdr10-opt             Insert tone mapping SEI only for IDR frames and when the tone mapping information changes. Default disabled\n");
42
 #endif
43
+    H0("   --dolby-vision-profile <float|integer> Specifies Dolby Vision profile ID. Currently only profile 5, profile 8.1 and profile 8.2 enabled. Specified as '5' or '50'. Default 0 (disabled).\n");
44
+    H0("   --dolby-vision-rpu <filename> File containing Dolby Vision RPU metadata.\n"
45
+       "                                 If given, x265's Dolby Vision metadata parser will fill the RPU field of input pictures with the metadata read from the file. Default NULL(disabled).\n");
46
     H0("   --nalu-file <filename>        Text file containing SEI messages in the following format : <POC><space><PREFIX><space><NAL UNIT TYPE>/<SEI TYPE><space><SEI Payload>\n");
47
     H0("-f/--frames <integer>            Maximum number of frames to encode. Default all\n");
48
     H0("   --seek <integer>              First frame to encode\n");
49
@@ -458,6 +470,7 @@
50
     H1("                                 0 - flush the encoder only when all the input pictures are over.\n");
51
     H1("                                 1 - flush all the frames even when the input is not over. Slicetype decision may change with this option.\n");
52
     H1("                                 2 - flush the slicetype decided frames only.\n");
53
+    H0("   --[no-]-hrd-concat            Set HRD concatenation flag for the first keyframe in the buffering period SEI. Default %s\n", OPT(param->bEnableHRDConcatFlag));
54
     H0("\nRate control, Adaptive Quantization:\n");
55
     H0("   --bitrate <integer>           Target bitrate (kbps) for ABR (implied). Default %d\n", param->rc.bitrate);
56
     H1("-q/--qp <integer>                QP for P slices in CQP mode (implied). --ipratio and --pbration determine other slice QPs\n");
57
@@ -488,7 +501,7 @@
58
     H0("   --analysis-load <filename>    Load analysis buffers from the file specified. Default Disabled\n");
59
     H0("   --analysis-reuse-file <filename>    Specify file name used for either dumping or reading analysis data. Deault x265_analysis.dat\n");
60
     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);
61
-    H0("   --refine-mv-type <string>     Reuse MV information received through API call. Supported option is avc. Default disabled - %d\n", param->bMVType);
62
+    H0("   --refine-analysis-type <string>     Reuse anlaysis information received through API call. Supported options are avc and hevc. Default disabled - %d\n", param->bAnalysisType);
63
     H0("   --scale-factor <int>          Specify factor by which input video is scaled down for analysis save mode. Default %d\n", param->scaleFactor);
64
     H0("   --refine-intra <0..4>         Enable intra refinement for encode that uses analysis-load.\n"
65
         "                                    - 0 : Forces both mode and depth from the save encode.\n"
66
@@ -506,8 +519,14 @@
67
         "                                Default:%d\n", param->interRefine);
68
     H0("   --[no-]dynamic-refine         Dynamically changes refine-inter level for each CU. Default %s\n", OPT(param->bDynamicRefine));
69
     H0("   --[no-]refine-mv              Enable mv refinement for load mode. Default %s\n", OPT(param->mvRefine));
70
+    H0("   --refine-ctu-distortion       Store/normalize ctu distortion in analysis-save/load.\n"
71
+        "                                    - 0 : Disabled.\n"
72
+        "                                    - 1 : Store/Load ctu distortion to/from the file specified in analysis-save/load.\n"
73
+        "                                Default 0 - Disabled\n");
74
     H0("   --aq-mode <integer>           Mode for Adaptive Quantization - 0:none 1:uniform AQ 2:auto variance 3:auto variance with bias to dark scenes. Default %d\n", param->rc.aqMode);
75
+    H0("   --[no-]hevc-aq                Mode for HEVC Adaptive Quantization. Default %s\n", OPT(param->rc.hevcAq));
76
     H0("   --aq-strength <float>         Reduces blocking and blurring in flat and textured areas (0 to 3.0). Default %.2f\n", param->rc.aqStrength);
77
+    H0("   --qp-adaptation-range <float> Delta QP range by QP adaptation based on a psycho-visual model (1.0 to 6.0). Default %.2f\n", param->rc.qpAdaptationRange);
78
     H0("   --[no-]aq-motion              Adaptive Quantization based on the relative motion of each CU w.r.t., frame. Default %s\n", OPT(param->bOptCUDeltaQP));
79
     H0("   --qg-size <int>               Specifies the size of the quantization group (64, 32, 16, 8). Default %d\n", param->rc.qgSize);
80
     H0("   --[no-]cutree                 Enable cutree for Adaptive Quantization. Default %s\n", OPT(param->rc.cuTree));
81
@@ -528,6 +547,7 @@
82
     H1("                                   where <option> is either\n");
83
     H1("                                       q=<integer> (force QP)\n");
84
     H1("                                   or  b=<float> (bitrate multiplier)\n");
85
+    H0("   --zonefile <filename>         Zone file containing the zone boundaries and the parameters to be reconfigured.\n");
86
     H1("   --lambda-file <string>        Specify a file containing replacement values for the lambda tables\n");
87
     H1("                                 MAX_MAX_QP+1 floats for lambda table, then again for lambda2 table\n");
88
     H1("                                 Blank lines and lines starting with hash(#) are ignored\n");
89
Refresh

No build results available

Refresh

No rpmlint results available

Request History
antlarr's avatar

antlarr created request about 6 years ago

- Support 10 and 12 bit color depths
- Update to version 3.0
New features
* option:: '--dolby-vision-profile ' generates
bitstreams confirming to the specified Dolby Vision profile.
Currently profile 5, profile 8.1 and profile 8.2 enabled,
Default 0 (disabled)
* option:: '--dolby-vision-rpu' File containing Dolby Vision RPU
metadata. If given, x265's Dolby Vision metadata parser will
fill the RPU field of input pictures with the metadata read
from the file. The library will interleave access units with
RPUs in the bitstream. Default NULL (disabled).
* option:: '--zonefile ' specifies a text file which
contains the boundaries of the zones where each of zones are
configurable.
* option:: '--qp-adaptation-range' Delta-QP range by QP
adaptation based on a psycho-visual model. Default 1.0.
* option:: '--refine-ctu-distortion <0/1>' store/normalize ctu
distortion in analysis-save/load. Default 0.
* Experimental feature option:: '--hevc-aq' enables adaptive
quantization. It scales the quantization step size according
to the spatial activity of one coding unit relative to frame
average spatial activity. This AQ method utilizes the minimum
variance of sub-unit in each coding unit to represent the
coding unit's spatial complexity.
Encoder enhancements
* Preset: change param defaults for veryslow and slower preset.
Replace slower preset with defaults used in veryslow preset
and change param defaults in veryslow preset as per
experimental results.


enzokiel's avatar

enzokiel accepted request about 6 years ago