Overview
x265.changes
Changed
x
1
2
-------------------------------------------------------------------
3
+Tue Oct 01 12:21:19 UTC 2019 - enzokiel@kabelmail.de
4
+
5
+- Update to version 3.2
6
+ New features
7
+ * 3-level hierarchical motion estimation using --hme and
8
+ --hme-search.
9
+ * New AQ mode (--aq-mode 4) with variance and edge information.
10
+ * selective-sao to selectively enable SAO at slice level.
11
+ Enhancements to existing features
12
+ * New implementation of --refine-mv with 3 refinement levels.
13
+ Encoder enhancements
14
+ * Improved quality in the frames following dark scenes in ABR
15
+ mode.
16
+ API changes
17
+ * Additions to x265_param structure to support the newly added
18
+ features --hme, --hme-search and selective-sao.
19
+ Bug fixes
20
+ * Fixed encoder crash with --zonefile during failures in
21
+ encoder_open().
22
+ * Fixed JSON11 build errors with HDR10+ on MacOS high sierra.
23
+ * Signalling out of range scaling list data fixed.
24
+ * Inconsistent output fix for 2-pass rate-control with cutree ON.
25
+ Known issues
26
+ * Build dependency on changeset cf37911 of SVT-HEVC.
27
+
28
+-------------------------------------------------------------------
29
Sun Aug 11 09:32:37 UTC 2019 - Luigi Baldoni <aloisio@gmx.com>
30
31
- Update to version 3.1.2
32
x265.spec
Changed
15
1
2
#
3
4
5
-%define soname 176
6
+%define soname 179
7
%define libname lib%{name}
8
%define libsoname %{libname}-%{soname}
9
Name: x265
10
-Version: 3.1.2
11
+Version: 3.2
12
Release: 0
13
Summary: A free h265/HEVC encoder - encoder binary
14
License: GPL-2.0-or-later
15
baselibs.conf
Changed
4
1
2
-libx265-176
3
+libx265-179
4
x265_3.1.2.tar.gz/.hg_archival.txt -> x265_3.2.tar.gz/.hg_archival.txt
Changed
11
1
2
repo: 09fe40627f03a0f9c3e6ac78b22ac93da23f9fdf
3
-node: 76650bab70f9ef9f06b91ba51926ef560d6fa6ff
4
-branch: Release_3.1
5
-latesttag: 3.1.2
6
-latesttagdistance: 1
7
-changessincelatesttag: 1
8
+node: 353572437201d551381002aebf20d244bd49ef17
9
+branch: Release_3.2
10
+tag: 3.2
11
x265_3.1.2.tar.gz/.hgtags -> x265_3.2.tar.gz/.hgtags
Changed
9
1
2
72188bd2f03447e71e789a5fd2f10364bb232c2c 3.0
3
113518629fa54ffb491dd479e15c1f00dd39d376 3.1_RC1
4
b4e38ce16d7c4b37a6482dc7ae61fd31071b6ff1 3.1_RC2
5
-acce27790559b68f93319cd21b588f90aa93c0b1 3.1
6
-6f7c2ae0d5bd46506b7a772abebd7eff3fa3bbcb 3.1.1
7
-4472578f9adfb383e4a479491218f37251c8ab60 3.1.2
8
+20c9994e8bfbeb9443851b2b3a050cd98c8b147b 3.2_RC1
9
x265_3.1.2.tar.gz/doc/reST/cli.rst -> x265_3.2.tar.gz/doc/reST/cli.rst
Changed
89
1
2
+
3
*********************
4
Command Line Options
5
*********************
6
7
the encoder settings. It is recommended to use :option:`--refine-intra` 4 with dynamic
8
refinement. Default disabled.
9
10
-.. option:: --refine-mv
11
-
12
+.. option:: --refine-mv <1..3>
13
+
14
Enables refinement of motion vector for scaled video. Evaluates the best
15
- motion vector by searching the surrounding eight integer and subpel pixel
16
- positions.
17
+ motion vector based on the level selected. Default 1.
18
+
19
+ Level 1 - Search around scaled MV.
20
+
21
+ Level 2 - Level 1 + Search around best AMVP cand.
22
+
23
+ Level 3 - Level 2 + Search around the other AMVP cand.
24
25
Options which affect the transform unit quad-tree, sometimes referred to
26
as the residual quad-tree (RQT).
27
28
Enable motion estimation with source frame pixels, in this mode,
29
motion estimation can be computed independently. Default disabled.
30
31
+.. option:: --hme, --no-hme
32
+
33
+ Enable 3-level Hierarchical motion estimation at One-Sixteenth,
34
+ Quarter and Full resolution. Default disabled.
35
+
36
+.. option:: --hme-search <integer|string>,<integer|string>,<integer|string>
37
+
38
+ Motion search method for HME Level 0, 1 and 2. Refer to :option:`--me` for values.
39
+ Specify search method for each level. Alternatively, specify a single value
40
+ which will apply to all levels. Default is hex,umh,umh for
41
+ levels 0,1,2 respectively.
42
+
43
Spatial/intra options
44
=====================
45
46
47
ignored. Slower presets will generally achieve better compression
48
efficiency (and generate smaller bitstreams). Default disabled.
49
50
-.. option:: --aq-mode <0|1|2|3>
51
+.. option:: --aq-mode <0|1|2|3|4>
52
53
Adaptive Quantization operating mode. Raise or lower per-block
54
quantization based on complexity analysis of the source image. The
55
56
3. AQ enabled with auto-variance and bias to dark scenes. This is
57
recommended for 8-bit encodes or low-bitrate 10-bit encodes, to
58
prevent color banding/blocking.
59
+ 4. AQ enabled with auto-variance and edge information.
60
61
.. option:: --aq-strength <float>
62
63
64
on inter prediction mode, CTU spatial-domain correlations, and relations
65
between luma and chroma.
66
Default disabled
67
+
68
+.. option:: --selective-sao <0..4>
69
+
70
+ Toggles SAO at slice level. Default 0.
71
+
72
+ +--------------+------------------------------------------+
73
+ | Level | Description |
74
+ +==============+==========================================+
75
+ | 0 | Disable SAO for all slices |
76
+ +--------------+------------------------------------------+
77
+ | 1 | Enable SAO only for I-slices |
78
+ +--------------+------------------------------------------+
79
+ | 2 | Enable SAO for I-slices & P-slices |
80
+ +--------------+------------------------------------------+
81
+ | 3 | Enable SAO for all reference slices |
82
+ +--------------+------------------------------------------+
83
+ | 4 | Enable SAO for all slices |
84
+ +--------------+------------------------------------------+
85
+
86
87
VUI (Video Usability Information) options
88
=========================================
89
x265_3.1.2.tar.gz/doc/reST/releasenotes.rst -> x265_3.2.tar.gz/doc/reST/releasenotes.rst
Changed
42
1
2
Release Notes
3
*************
4
5
+Version 3.2
6
+===========
7
+
8
+Release date - 25th September, 2019.
9
+
10
+New features
11
+------------
12
+1. 3-level hierarchical motion estimation using :option:`--hme` and :option:`--hme-search`.
13
+2. New AQ mode (:option:`--aq-mode` 4) with variance and edge information.
14
+3. :option:`selective-sao` to selectively enable SAO at slice level.
15
+
16
+Enhancements to existing features
17
+---------------------------------
18
+1. New implementation of :option:`--refine-mv` with 3 refinement levels.
19
+
20
+Encoder enhancements
21
+--------------------
22
+1. Improved quality in the frames following dark scenes in ABR mode.
23
+
24
+API changes
25
+-----------
26
+1. Additions to x265_param structure to support the newly added features :option:`--hme`, :option:`--hme-search` and :option:`selective-sao`.
27
+
28
+Bug fixes
29
+---------
30
+1. Fixed encoder crash with :option:`--zonefile` during failures in encoder_open().
31
+2. Fixed JSON11 build errors with HDR10+ on MacOS high sierra.
32
+3. Signalling out of range scaling list data fixed.
33
+4. Inconsistent output fix for 2-pass rate-control with cutree ON.
34
+
35
+Known issues
36
+------------
37
+1. Build dependency on changeset cf37911 of SVT-HEVC.
38
+
39
Version 3.1
40
===========
41
42
x265_3.1.2.tar.gz/source/CMakeLists.txt -> x265_3.2.tar.gz/source/CMakeLists.txt
Changed
10
1
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 176)
6
+set(X265_BUILD 179)
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
x265_3.1.2.tar.gz/source/common/lowres.cpp -> x265_3.2.tar.gz/source/common/lowres.cpp
Changed
118
1
2
heightFullRes = origPic->m_picHeight;
3
width = origPic->m_picWidth / 2;
4
lines = origPic->m_picHeight / 2;
5
+ bEnableHME = param->bEnableHME ? 1 : 0;
6
lumaStride = width + 2 * origPic->m_lumaMarginX;
7
if (lumaStride & 31)
8
lumaStride += 32 - (lumaStride & 31);
9
10
maxBlocksInColFullRes = maxBlocksInCol * 2;
11
int cuCount = maxBlocksInRow * maxBlocksInCol;
12
int cuCountFullRes = (qgSize > 8) ? cuCount : cuCount << 2;
13
+ isHMELowres = param->bEnableHME ? 1 : 0;
14
15
/* rounding the width to multiple of lowres CU size */
16
width = maxBlocksInRow * X265_LOWRES_CU_SIZE;
17
18
CHECKED_MALLOC_ZERO(qpCuTreeOffset, double, cuCountFullRes);
19
if (qgSize == 8)
20
CHECKED_MALLOC_ZERO(invQscaleFactor8x8, int, cuCount);
21
+ CHECKED_MALLOC_ZERO(edgeInclined, int, cuCountFullRes);
22
}
23
24
if (origPic->m_param->bAQMotion)
25
26
lowresPlane[2] = buffer[2] + padoffset;
27
lowresPlane[3] = buffer[3] + padoffset;
28
29
+ if (bEnableHME)
30
+ {
31
+ intptr_t lumaStrideHalf = lumaStride / 2;
32
+ if (lumaStrideHalf & 31)
33
+ lumaStrideHalf += 32 - (lumaStrideHalf & 31);
34
+ size_t planesizeHalf = planesize / 2;
35
+ size_t padoffsetHalf = padoffset / 2;
36
+ /* allocate lower-res buffers */
37
+ CHECKED_MALLOC_ZERO(lowerResBuffer[0], pixel, 4 * planesizeHalf);
38
+
39
+ lowerResBuffer[1] = lowerResBuffer[0] + planesizeHalf;
40
+ lowerResBuffer[2] = lowerResBuffer[1] + planesizeHalf;
41
+ lowerResBuffer[3] = lowerResBuffer[2] + planesizeHalf;
42
+
43
+ lowerResPlane[0] = lowerResBuffer[0] + padoffsetHalf;
44
+ lowerResPlane[1] = lowerResBuffer[1] + padoffsetHalf;
45
+ lowerResPlane[2] = lowerResBuffer[2] + padoffsetHalf;
46
+ lowerResPlane[3] = lowerResBuffer[3] + padoffsetHalf;
47
+ }
48
+
49
CHECKED_MALLOC(intraCost, int32_t, cuCount);
50
CHECKED_MALLOC(intraMode, uint8_t, cuCount);
51
52
53
CHECKED_MALLOC(lowresMvs[1][i], MV, cuCount);
54
CHECKED_MALLOC(lowresMvCosts[0][i], int32_t, cuCount);
55
CHECKED_MALLOC(lowresMvCosts[1][i], int32_t, cuCount);
56
+ if (bEnableHME)
57
+ {
58
+ int maxBlocksInRowLowerRes = ((width/2) + X265_LOWRES_CU_SIZE - 1) >> X265_LOWRES_CU_BITS;
59
+ int maxBlocksInColLowerRes = ((lines/2) + X265_LOWRES_CU_SIZE - 1) >> X265_LOWRES_CU_BITS;
60
+ int cuCountLowerRes = maxBlocksInRowLowerRes * maxBlocksInColLowerRes;
61
+ CHECKED_MALLOC(lowerResMvs[0][i], MV, cuCountLowerRes);
62
+ CHECKED_MALLOC(lowerResMvs[1][i], MV, cuCountLowerRes);
63
+ CHECKED_MALLOC(lowerResMvCosts[0][i], int32_t, cuCountLowerRes);
64
+ CHECKED_MALLOC(lowerResMvCosts[1][i], int32_t, cuCountLowerRes);
65
+ }
66
}
67
68
return true;
69
70
void Lowres::destroy()
71
{
72
X265_FREE(buffer[0]);
73
+ if(bEnableHME)
74
+ X265_FREE(lowerResBuffer[0]);
75
X265_FREE(intraCost);
76
X265_FREE(intraMode);
77
78
79
X265_FREE(lowresMvs[1][i]);
80
X265_FREE(lowresMvCosts[0][i]);
81
X265_FREE(lowresMvCosts[1][i]);
82
+ if (bEnableHME)
83
+ {
84
+ X265_FREE(lowerResMvs[0][i]);
85
+ X265_FREE(lowerResMvs[1][i]);
86
+ X265_FREE(lowerResMvCosts[0][i]);
87
+ X265_FREE(lowerResMvCosts[1][i]);
88
+ }
89
}
90
X265_FREE(qpAqOffset);
91
X265_FREE(invQscaleFactor);
92
X265_FREE(qpCuTreeOffset);
93
X265_FREE(propagateCost);
94
X265_FREE(invQscaleFactor8x8);
95
+ X265_FREE(edgeInclined);
96
X265_FREE(qpAqMotionOffset);
97
X265_FREE(blockVariance);
98
if (maxAQDepth > 0)
99
100
extendPicBorder(lowresPlane[1], lumaStride, width, lines, origPic->m_lumaMarginX, origPic->m_lumaMarginY);
101
extendPicBorder(lowresPlane[2], lumaStride, width, lines, origPic->m_lumaMarginX, origPic->m_lumaMarginY);
102
extendPicBorder(lowresPlane[3], lumaStride, width, lines, origPic->m_lumaMarginX, origPic->m_lumaMarginY);
103
+
104
+ if (origPic->m_param->bEnableHME)
105
+ {
106
+ primitives.frameInitLowerRes(lowresPlane[0],
107
+ lowerResPlane[0], lowerResPlane[1], lowerResPlane[2], lowerResPlane[3],
108
+ lumaStride, lumaStride/2, (width / 2), (lines / 2));
109
+ extendPicBorder(lowerResPlane[0], lumaStride/2, width/2, lines/2, origPic->m_lumaMarginX/2, origPic->m_lumaMarginY/2);
110
+ extendPicBorder(lowerResPlane[1], lumaStride/2, width/2, lines/2, origPic->m_lumaMarginX/2, origPic->m_lumaMarginY/2);
111
+ extendPicBorder(lowerResPlane[2], lumaStride/2, width/2, lines/2, origPic->m_lumaMarginX/2, origPic->m_lumaMarginY/2);
112
+ extendPicBorder(lowerResPlane[3], lumaStride/2, width/2, lines/2, origPic->m_lumaMarginX/2, origPic->m_lumaMarginY/2);
113
+ fpelLowerResPlane[0] = lowerResPlane[0];
114
+ }
115
+
116
fpelPlane[0] = lowresPlane[0];
117
}
118
x265_3.1.2.tar.gz/source/common/lowres.h -> x265_3.2.tar.gz/source/common/lowres.h
Changed
115
1
2
pixel* lowresPlane[4];
3
PicYuv* reconPic;
4
5
+ /* 1/16th resolution : Level-0 HME planes */
6
+ pixel* fpelLowerResPlane[3];
7
+ pixel* lowerResPlane[4];
8
+
9
bool isWeighted;
10
bool isLowres;
11
+ bool isHMELowres;
12
13
intptr_t lumaStride;
14
intptr_t chromaStride;
15
16
17
/* lowres motion compensation, you must provide a buffer and stride for QPEL averaged pixels
18
* in case QPEL is required. Else it returns a pointer to the HPEL pixels */
19
- inline pixel *lowresMC(intptr_t blockOffset, const MV& qmv, pixel *buf, intptr_t& outstride)
20
+ inline pixel *lowresMC(intptr_t blockOffset, const MV& qmv, pixel *buf, intptr_t& outstride, bool hme)
21
{
22
+ intptr_t YStride = hme ? lumaStride / 2 : lumaStride;
23
+ pixel *plane[4];
24
+ for (int i = 0; i < 4; i++)
25
+ {
26
+ plane[i] = hme ? lowerResPlane[i] : lowresPlane[i];
27
+ }
28
if ((qmv.x | qmv.y) & 1)
29
{
30
int hpelA = (qmv.y & 2) | ((qmv.x & 2) >> 1);
31
- pixel *frefA = lowresPlane[hpelA] + blockOffset + (qmv.x >> 2) + (qmv.y >> 2) * lumaStride;
32
+ pixel *frefA = plane[hpelA] + blockOffset + (qmv.x >> 2) + (qmv.y >> 2) * YStride;
33
int qmvx = qmv.x + (qmv.x & 1);
34
int qmvy = qmv.y + (qmv.y & 1);
35
int hpelB = (qmvy & 2) | ((qmvx & 2) >> 1);
36
- pixel *frefB = lowresPlane[hpelB] + blockOffset + (qmvx >> 2) + (qmvy >> 2) * lumaStride;
37
- primitives.pu[LUMA_8x8].pixelavg_pp[(outstride % 64 == 0) && (lumaStride % 64 == 0)](buf, outstride, frefA, lumaStride, frefB, lumaStride, 32);
38
+ pixel *frefB = plane[hpelB] + blockOffset + (qmvx >> 2) + (qmvy >> 2) * YStride;
39
+ primitives.pu[LUMA_8x8].pixelavg_pp[(outstride % 64 == 0) && (YStride % 64 == 0)](buf, outstride, frefA, YStride, frefB, YStride, 32);
40
return buf;
41
}
42
else
43
{
44
- outstride = lumaStride;
45
+ outstride = YStride;
46
int hpel = (qmv.y & 2) | ((qmv.x & 2) >> 1);
47
- return lowresPlane[hpel] + blockOffset + (qmv.x >> 2) + (qmv.y >> 2) * lumaStride;
48
+ return plane[hpel] + blockOffset + (qmv.x >> 2) + (qmv.y >> 2) * YStride;
49
}
50
}
51
52
- inline int lowresQPelCost(pixel *fenc, intptr_t blockOffset, const MV& qmv, pixelcmp_t comp)
53
+ inline int lowresQPelCost(pixel *fenc, intptr_t blockOffset, const MV& qmv, pixelcmp_t comp, bool hme)
54
{
55
+ intptr_t YStride = hme ? lumaStride / 2 : lumaStride;
56
+ pixel *plane[4];
57
+ for (int i = 0; i < 4; i++)
58
+ {
59
+ plane[i] = hme ? lowerResPlane[i] : lowresPlane[i];
60
+ }
61
if ((qmv.x | qmv.y) & 1)
62
{
63
ALIGN_VAR_16(pixel, subpelbuf[8 * 8]);
64
int hpelA = (qmv.y & 2) | ((qmv.x & 2) >> 1);
65
- pixel *frefA = lowresPlane[hpelA] + blockOffset + (qmv.x >> 2) + (qmv.y >> 2) * lumaStride;
66
+ pixel *frefA = plane[hpelA] + blockOffset + (qmv.x >> 2) + (qmv.y >> 2) * YStride;
67
int qmvx = qmv.x + (qmv.x & 1);
68
int qmvy = qmv.y + (qmv.y & 1);
69
int hpelB = (qmvy & 2) | ((qmvx & 2) >> 1);
70
- pixel *frefB = lowresPlane[hpelB] + blockOffset + (qmvx >> 2) + (qmvy >> 2) * lumaStride;
71
- primitives.pu[LUMA_8x8].pixelavg_pp[NONALIGNED](subpelbuf, 8, frefA, lumaStride, frefB, lumaStride, 32);
72
+ pixel *frefB = plane[hpelB] + blockOffset + (qmvx >> 2) + (qmvy >> 2) * YStride;
73
+ primitives.pu[LUMA_8x8].pixelavg_pp[NONALIGNED](subpelbuf, 8, frefA, YStride, frefB, YStride, 32);
74
return comp(fenc, FENC_STRIDE, subpelbuf, 8);
75
}
76
else
77
{
78
int hpel = (qmv.y & 2) | ((qmv.x & 2) >> 1);
79
- pixel *fref = lowresPlane[hpel] + blockOffset + (qmv.x >> 2) + (qmv.y >> 2) * lumaStride;
80
- return comp(fenc, FENC_STRIDE, fref, lumaStride);
81
+ pixel *fref = plane[hpel] + blockOffset + (qmv.x >> 2) + (qmv.y >> 2) * YStride;
82
+ return comp(fenc, FENC_STRIDE, fref, YStride);
83
}
84
}
85
};
86
87
struct Lowres : public ReferencePlanes
88
{
89
pixel *buffer[4];
90
+ pixel *lowerResBuffer[4]; // Level-0 buffer
91
92
int frameNum; // Presentation frame number
93
int sliceType; // Slice type decided by lookahead
94
95
uint32_t maxBlocksInRowFullRes;
96
uint32_t maxBlocksInColFullRes;
97
98
+ /* Hierarchical Motion Estimation */
99
+ bool bEnableHME;
100
+ int32_t* lowerResMvCosts[2][X265_BFRAME_MAX + 2];
101
+ MV* lowerResMvs[2][X265_BFRAME_MAX + 2];
102
+
103
/* used for vbvLookahead */
104
int plannedType[X265_LOOKAHEAD_MAX + 1];
105
int64_t plannedSatd[X265_LOOKAHEAD_MAX + 1];
106
107
uint64_t wp_ssd[3]; // This is different than SSDY, this is sum(pixel^2) - sum(pixel)^2 for entire frame
108
uint64_t wp_sum[3];
109
double frameVariance;
110
+ int* edgeInclined;
111
+
112
113
/* cutree intermediate data */
114
PicQPAdaptationLayer* pAQLayer;
115
x265_3.1.2.tar.gz/source/common/param.cpp -> x265_3.2.tar.gz/source/common/param.cpp
Changed
261
1
2
param->searchMethod = X265_HEX_SEARCH;
3
param->subpelRefine = 2;
4
param->searchRange = 57;
5
- param->maxNumMergeCand = 3;
6
- param->limitReferences = 1;
7
+ param->maxNumMergeCand = 3;
8
+ param->limitReferences = 1;
9
param->limitModes = 0;
10
param->bEnableWeightedPred = 1;
11
param->bEnableWeightedBiPred = 0;
12
- param->bEnableEarlySkip = 1;
13
+ param->bEnableEarlySkip = 1;
14
param->bEnableRecursionSkip = 1;
15
param->bEnableAMP = 0;
16
param->bEnableRectInter = 0;
17
18
param->bEnableTSkipFast = 0;
19
param->maxNumReferences = 3;
20
param->bEnableTemporalMvp = 1;
21
+ param->bEnableHME = 0;
22
+ param->hmeSearchMethod[0] = X265_HEX_SEARCH;
23
+ param->hmeSearchMethod[1] = param->hmeSearchMethod[2] = X265_UMH_SEARCH;
24
param->bSourceReferenceEstimation = 0;
25
param->limitTU = 0;
26
param->dynamicRd = 0;
27
28
param->bEnableSAO = 1;
29
param->bSaoNonDeblocked = 0;
30
param->bLimitSAO = 0;
31
+ param->selectiveSAO = 0;
32
33
/* Coding Quality */
34
param->cbQpOffset = 0;
35
36
param->analysisReuseFileName = NULL;
37
param->analysisSave = NULL;
38
param->analysisLoad = NULL;
39
- param->bIntraInBFrames = 1;
40
+ param->bIntraInBFrames = 1;
41
param->bLossless = 0;
42
param->bCULossless = 0;
43
param->bEnableTemporalSubLayers = 0;
44
45
param->intraRefine = 0;
46
param->interRefine = 0;
47
param->bDynamicRefine = 0;
48
- param->mvRefine = 0;
49
+ param->mvRefine = 1;
50
param->ctuDistortionRefine = 0;
51
param->bUseAnalysisFile = 1;
52
param->csvfpt = NULL;
53
54
55
if (!strcmp(preset, "ultrafast"))
56
{
57
- param->maxNumMergeCand = 2;
58
+ param->maxNumMergeCand = 2;
59
param->bIntraInBFrames = 0;
60
param->lookaheadDepth = 5;
61
param->scenecutThreshold = 0; // disable lookahead
62
63
}
64
else if (!strcmp(preset, "superfast"))
65
{
66
- param->maxNumMergeCand = 2;
67
+ param->maxNumMergeCand = 2;
68
param->bIntraInBFrames = 0;
69
param->lookaheadDepth = 10;
70
param->maxCUSize = 32;
71
72
}
73
else if (!strcmp(preset, "veryfast"))
74
{
75
- param->maxNumMergeCand = 2;
76
- param->limitReferences = 3;
77
+ param->maxNumMergeCand = 2;
78
+ param->limitReferences = 3;
79
param->bIntraInBFrames = 0;
80
param->lookaheadDepth = 15;
81
param->bFrameAdaptive = 0;
82
83
}
84
else if (!strcmp(preset, "faster"))
85
{
86
- param->maxNumMergeCand = 2;
87
- param->limitReferences = 3;
88
+ param->maxNumMergeCand = 2;
89
+ param->limitReferences = 3;
90
param->bIntraInBFrames = 0;
91
param->lookaheadDepth = 15;
92
param->bFrameAdaptive = 0;
93
94
}
95
else if (!strcmp(preset, "fast"))
96
{
97
- param->maxNumMergeCand = 2;
98
- param->limitReferences = 3;
99
- param->bEnableEarlySkip = 0;
100
+ param->maxNumMergeCand = 2;
101
+ param->limitReferences = 3;
102
+ param->bEnableEarlySkip = 0;
103
param->bIntraInBFrames = 0;
104
param->lookaheadDepth = 15;
105
param->bFrameAdaptive = 0;
106
107
}
108
else if (!strcmp(preset, "slow"))
109
{
110
- param->limitReferences = 3;
111
- param->bEnableEarlySkip = 0;
112
+ param->limitReferences = 3;
113
+ param->bEnableEarlySkip = 0;
114
param->bIntraInBFrames = 0;
115
param->bEnableRectInter = 1;
116
param->lookaheadDepth = 25;
117
118
OPT("scale-factor") p->scaleFactor = atoi(value);
119
OPT("refine-intra")p->intraRefine = atoi(value);
120
OPT("refine-inter")p->interRefine = atoi(value);
121
- OPT("refine-mv")p->mvRefine = atobool(value);
122
+ OPT("refine-mv")p->mvRefine = atoi(value);
123
OPT("force-flush")p->forceFlush = atoi(value);
124
OPT("splitrd-skip") p->bEnableSplitRdSkip = atobool(value);
125
OPT("lowpass-dct") p->bLowPassDct = atobool(value);
126
127
OPT("svt-pred-struct") x265_log(p, X265_LOG_WARNING, "Option %s is SVT-HEVC Encoder specific; Disabling it here \n", name);
128
OPT("svt-fps-in-vps") x265_log(p, X265_LOG_WARNING, "Option %s is SVT-HEVC Encoder specific; Disabling it here \n", name);
129
#endif
130
+ OPT("selective-sao")
131
+ {
132
+ p->selectiveSAO = atoi(value);
133
+ }
134
OPT("fades") p->bEnableFades = atobool(value);
135
OPT("field") p->bField = atobool( value );
136
OPT("cll") p->bEmitCLL = atobool(value);
137
+ OPT("hme") p->bEnableHME = atobool(value);
138
+ OPT("hme-search")
139
+ {
140
+ char search[3][5];
141
+ memset(search, '\0', 15 * sizeof(char));
142
+ if(3 == sscanf(value, "%d,%d,%d", &p->hmeSearchMethod[0], &p->hmeSearchMethod[1], &p->hmeSearchMethod[2]) ||
143
+ 3 == sscanf(value, "%4[^,],%4[^,],%4[^,]", search[0], search[1], search[2]))
144
+ {
145
+ if(search[0][0])
146
+ for(int level = 0; level < 3; level++)
147
+ p->hmeSearchMethod[level] = parseName(search[level], x265_motion_est_names, bError);
148
+ }
149
+ else if (sscanf(value, "%d", &p->hmeSearchMethod[0]) || sscanf(value, "%s", search[0]))
150
+ {
151
+ if (search[0][0]) {
152
+ p->hmeSearchMethod[0] = parseName(search[0], x265_motion_est_names, bError);
153
+ p->hmeSearchMethod[1] = p->hmeSearchMethod[2] = p->hmeSearchMethod[0];
154
+ }
155
+ }
156
+ p->bEnableHME = true;
157
+ }
158
else
159
return X265_PARAM_BAD_NAME;
160
}
161
162
"Lookahead depth must be less than 256");
163
CHECK(param->lookaheadSlices > 16 || param->lookaheadSlices < 0,
164
"Lookahead slices must between 0 and 16");
165
- CHECK(param->rc.aqMode < X265_AQ_NONE || X265_AQ_AUTO_VARIANCE_BIASED < param->rc.aqMode,
166
+ CHECK(param->rc.aqMode < X265_AQ_NONE || X265_AQ_EDGE < param->rc.aqMode,
167
"Aq-Mode is out of range");
168
CHECK(param->rc.aqStrength < 0 || param->rc.aqStrength > 3,
169
"Aq-Strength is out of range");
170
171
"Strict-cbr cannot be applied without specifying target bitrate or vbv bufsize");
172
CHECK((param->analysisSave || param->analysisLoad) && (param->analysisReuseLevel < 1 || param->analysisReuseLevel > 10),
173
"Invalid analysis refine level. Value must be between 1 and 10 (inclusive)");
174
+ CHECK(param->analysisLoad && (param->mvRefine < 1 || param->mvRefine > 3),
175
+ "Invalid mv refinement level. Value must be between 1 and 3 (inclusive)");
176
CHECK(param->scaleFactor > 2, "Invalid scale-factor. Supports factor <= 2");
177
CHECK(param->rc.qpMax < QP_MIN || param->rc.qpMax > QP_MAX_MAX,
178
"qpmax exceeds supported range (0 to 69)");
179
180
CHECK( (param->bFrameAdaptive==0), "Adaptive B-frame decision method should be closed for field feature.\n" );
181
// to do
182
}
183
+ CHECK(param->selectiveSAO < 0 || param->selectiveSAO > 4,
184
+ "Invalid SAO tune level. Value must be between 0 and 4 (inclusive)");
185
#if !X86_64
186
CHECK(param->searchMethod == X265_SEA && (param->sourceWidth > 840 || param->sourceHeight > 480),
187
"SEA motion search does not support resolutions greater than 480p in 32 bit build");
188
189
x265_log(param, X265_LOG_INFO, "Residual QT: max TU size, max depth : %d / %d inter / %d intra\n",
190
param->maxTUSize, param->tuQTMaxInterDepth, param->tuQTMaxIntraDepth);
191
192
- x265_log(param, X265_LOG_INFO, "ME / range / subpel / merge : %s / %d / %d / %d\n",
193
- x265_motion_est_names[param->searchMethod], param->searchRange, param->subpelRefine, param->maxNumMergeCand);
194
+ if (param->bEnableHME)
195
+ x265_log(param, X265_LOG_INFO, "HME L0,1,2 / range / subpel / merge : %s, %s, %s / %d / %d / %d\n",
196
+ x265_motion_est_names[param->hmeSearchMethod[0]], x265_motion_est_names[param->hmeSearchMethod[1]], x265_motion_est_names[param->hmeSearchMethod[2]], param->searchRange, param->subpelRefine, param->maxNumMergeCand);
197
+ else
198
+ x265_log(param, X265_LOG_INFO, "ME / range / subpel / merge : %s / %d / %d / %d\n",
199
+ x265_motion_est_names[param->searchMethod], param->searchRange, param->subpelRefine, param->maxNumMergeCand);
200
+
201
if (param->keyframeMax != INT_MAX || param->scenecutThreshold)
202
x265_log(param, X265_LOG_INFO, "Keyframe min / max / scenecut / bias: %d / %d / %d / %.2lf\n", param->keyframeMin, param->keyframeMax, param->scenecutThreshold, param->scenecutBias * 100);
203
else
204
205
}
206
TOOLOPT(param->bSaoNonDeblocked, "sao-non-deblock");
207
TOOLOPT(!param->bSaoNonDeblocked && param->bEnableSAO, "sao");
208
+ if (param->selectiveSAO && param->selectiveSAO != 4)
209
+ TOOLOPT(param->selectiveSAO, "selective-sao");
210
TOOLOPT(param->rc.bStatWrite, "stats-write");
211
TOOLOPT(param->rc.bStatRead, "stats-read");
212
TOOLOPT(param->bSingleSeiNal, "single-sei");
213
214
s += sprintf(s, " subme=%d", p->subpelRefine);
215
s += sprintf(s, " merange=%d", p->searchRange);
216
BOOL(p->bEnableTemporalMvp, "temporal-mvp");
217
+ BOOL(p->bEnableHME, "hme");
218
+ if (p->bEnableHME)
219
+ s += sprintf(s, " Level 0,1,2=%d,%d,%d", p->hmeSearchMethod[0], p->hmeSearchMethod[1], p->hmeSearchMethod[2]);
220
BOOL(p->bEnableWeightedPred, "weightp");
221
BOOL(p->bEnableWeightedBiPred, "weightb");
222
BOOL(p->bSourceReferenceEstimation, "analyze-src-pics");
223
224
BOOL(p->bEnableSAO, "sao");
225
BOOL(p->bSaoNonDeblocked, "sao-non-deblock");
226
s += sprintf(s, " rd=%d", p->rdLevel);
227
+ s += sprintf(s, " selective-sao=%d", p->selectiveSAO);
228
BOOL(p->bEnableEarlySkip, "early-skip");
229
BOOL(p->bEnableRecursionSkip, "rskip");
230
BOOL(p->bEnableFastIntra, "fast-intra");
231
232
if (p->masteringDisplayColorVolume)
233
s += sprintf(s, " master-display=%s", p->masteringDisplayColorVolume);
234
if (p->bEmitCLL)
235
- s += sprintf(s, "cll=%hu,%hu", p->maxCLL, p->maxFALL);
236
+ s += sprintf(s, " cll=%hu,%hu", p->maxCLL, p->maxFALL);
237
s += sprintf(s, " min-luma=%hu", p->minLuma);
238
s += sprintf(s, " max-luma=%hu", p->maxLuma);
239
s += sprintf(s, " log2-max-poc-lsb=%d", p->log2MaxPocLsb);
240
241
dst->subpelRefine = src->subpelRefine;
242
dst->searchRange = src->searchRange;
243
dst->bEnableTemporalMvp = src->bEnableTemporalMvp;
244
+ dst->bEnableHME = src->bEnableHME;
245
+ if (src->bEnableHME)
246
+ {
247
+ for (int level = 0; level < 3; level++)
248
+ dst->hmeSearchMethod[level] = src->hmeSearchMethod[level];
249
+ }
250
dst->bEnableWeightedBiPred = src->bEnableWeightedBiPred;
251
dst->bEnableWeightedPred = src->bEnableWeightedPred;
252
dst->bSourceReferenceEstimation = src->bSourceReferenceEstimation;
253
254
else dst->analysisLoad = NULL;
255
dst->gopLookahead = src->gopLookahead;
256
dst->radl = src->radl;
257
+ dst->selectiveSAO = src->selectiveSAO;
258
dst->maxAUSizeFactor = src->maxAUSizeFactor;
259
dst->bEmitIDRRecoverySEI = src->bEmitIDRRecoverySEI;
260
dst->bDynamicRefine = src->bDynamicRefine;
261
x265_3.1.2.tar.gz/source/common/pixel.cpp -> x265_3.2.tar.gz/source/common/pixel.cpp
Changed
9
1
2
p.scale1D_128to64[NONALIGNED] = p.scale1D_128to64[ALIGNED] = scale1D_128to64;
3
p.scale2D_64to32 = scale2D_64to32;
4
p.frameInitLowres = frame_init_lowres_core;
5
+ p.frameInitLowerRes = frame_init_lowres_core;
6
p.ssim_4x4x2_core = ssim_4x4x2_core;
7
p.ssim_end_4 = ssim_end_4;
8
9
x265_3.1.2.tar.gz/source/common/primitives.h -> x265_3.2.tar.gz/source/common/primitives.h
Changed
9
1
2
saoCuStatsE3_t saoCuStatsE3;
3
4
downscale_t frameInitLowres;
5
+ downscale_t frameInitLowerRes;
6
cutree_propagate_cost propagateCost;
7
cutree_fix8_unpack fix8Unpack;
8
cutree_fix8_pack fix8Pack;
9
x265_3.1.2.tar.gz/source/common/slice.h -> x265_3.2.tar.gz/source/common/slice.h
Changed
9
1
2
bool m_bCheckLDC; // TODO: is this necessary?
3
bool m_sLFaseFlag; // loop filter boundary flag
4
bool m_colFromL0Flag; // collocated picture from List0 or List1 flag
5
+ int m_bUseSao;
6
7
int m_iPPSQpMinus26;
8
int numRefIdxDefault[2];
9
x265_3.1.2.tar.gz/source/common/x86/asm-primitives.cpp -> x265_3.2.tar.gz/source/common/x86/asm-primitives.cpp
Changed
82
1
2
LUMA_VSS_FILTERS(sse2);
3
4
p.frameInitLowres = PFX(frame_init_lowres_core_sse2);
5
+ p.frameInitLowerRes = PFX(frame_init_lowres_core_sse2);
6
// TODO: the planecopy_sp is really planecopy_SC now, must be fix it
7
//p.planecopy_sp = PFX(downShift_16_sse2);
8
p.planecopy_sp_shl = PFX(upShift_16_sse2);
9
10
p.cu[BLOCK_8x8].idct = PFX(idct8_ssse3);
11
12
p.frameInitLowres = PFX(frame_init_lowres_core_ssse3);
13
+ p.frameInitLowerRes = PFX(frame_init_lowres_core_ssse3);
14
15
ALL_LUMA_PU(convert_p2s[ALIGNED], filterPixelToShort, ssse3);
16
ALL_LUMA_PU(convert_p2s[NONALIGNED], filterPixelToShort, ssse3);
17
18
p.cu[BLOCK_64x64].copy_sp = (copy_sp_t)PFX(blockcopy_ss_64x64_avx);
19
20
p.frameInitLowres = PFX(frame_init_lowres_core_avx);
21
+ p.frameInitLowerRes = PFX(frame_init_lowres_core_avx);
22
23
p.pu[LUMA_64x16].copy_pp = (copy_pp_t)PFX(blockcopy_ss_64x16_avx);
24
p.pu[LUMA_64x32].copy_pp = (copy_pp_t)PFX(blockcopy_ss_64x32_avx);
25
26
#endif
27
LUMA_VAR(xop);
28
p.frameInitLowres = PFX(frame_init_lowres_core_xop);
29
+ p.frameInitLowerRes = PFX(frame_init_lowres_core_xop);
30
}
31
if (cpuMask & X265_CPU_AVX2)
32
{
33
34
p.chroma[X265_CSP_I444].pu[LUMA_64x64].filter_vsp = PFX(interp_4tap_vert_sp_64x64_avx2);
35
36
p.frameInitLowres = PFX(frame_init_lowres_core_avx2);
37
+ p.frameInitLowerRes = PFX(frame_init_lowres_core_avx2);
38
p.propagateCost = PFX(mbtree_propagate_cost_avx2);
39
p.fix8Unpack = PFX(cutree_fix8_unpack_avx2);
40
p.fix8Pack = PFX(cutree_fix8_pack_avx2);
41
42
43
//p.frameInitLowres = PFX(frame_init_lowres_core_mmx2);
44
p.frameInitLowres = PFX(frame_init_lowres_core_sse2);
45
+ p.frameInitLowerRes = PFX(frame_init_lowres_core_sse2);
46
47
ALL_LUMA_TU(blockfill_s[NONALIGNED], blockfill_s, sse2);
48
ALL_LUMA_TU(blockfill_s[ALIGNED], blockfill_s, sse2);
49
50
p.pu[LUMA_8x8].luma_hvpp = PFX(interp_8tap_hv_pp_8x8_ssse3);
51
52
p.frameInitLowres = PFX(frame_init_lowres_core_ssse3);
53
+ p.frameInitLowerRes = PFX(frame_init_lowres_core_ssse3);
54
ASSIGN2(p.scale1D_128to64, scale1D_128to64_ssse3);
55
p.scale2D_64to32 = PFX(scale2D_64to32_ssse3);
56
57
58
p.pu[LUMA_48x64].copy_pp = PFX(blockcopy_pp_48x64_avx);
59
60
p.frameInitLowres = PFX(frame_init_lowres_core_avx);
61
+ p.frameInitLowerRes = PFX(frame_init_lowres_core_avx);
62
p.propagateCost = PFX(mbtree_propagate_cost_avx);
63
}
64
if (cpuMask & X265_CPU_XOP)
65
66
p.cu[BLOCK_8x8].sse_pp = PFX(pixel_ssd_8x8_xop);
67
p.cu[BLOCK_16x16].sse_pp = PFX(pixel_ssd_16x16_xop);
68
p.frameInitLowres = PFX(frame_init_lowres_core_xop);
69
+ p.frameInitLowerRes = PFX(frame_init_lowres_core_xop);
70
+
71
}
72
#if X86_64
73
if (cpuMask & X265_CPU_AVX2)
74
75
p.chroma[X265_CSP_I444].pu[LUMA_64x16].filter_vpp = PFX(interp_4tap_vert_pp_64x16_avx2);
76
77
p.frameInitLowres = PFX(frame_init_lowres_core_avx2);
78
+ p.frameInitLowerRes = PFX(frame_init_lowres_core_avx2);
79
p.propagateCost = PFX(mbtree_propagate_cost_avx2);
80
p.saoCuStatsE0 = PFX(saoCuStatsE0_avx2);
81
p.saoCuStatsE1 = PFX(saoCuStatsE1_avx2);
82
x265_3.1.2.tar.gz/source/dynamicHDR10/json11/json11.cpp -> x265_3.2.tar.gz/source/dynamicHDR10/json11/json11.cpp
Changed
35
1
2
using std::initializer_list;
3
using std::move;
4
5
+ /* Helper for representing null - just a do-nothing struct, plus comparison
6
+ * operators so the helpers in JsonValue work. We can't use nullptr_t because
7
+ * it may not be orderable.
8
+ */
9
+ struct NullStruct {
10
+ bool operator==(NullStruct) const { return true; }
11
+ bool operator<(NullStruct) const { return false; }
12
+ };
13
+
14
/* * * * * * * * * * * * * * * * * * * *
15
* Serialization
16
*/
17
18
-static void dump(std::nullptr_t, string &out) {
19
+static void dump(NullStruct, string &out) {
20
out += "null";
21
}
22
23
24
explicit JsonObject(Json::object &&value) : Value(move(value)) {}
25
};
26
27
-class JsonNull final : public Value<Json::NUL, std::nullptr_t> {
28
+class JsonNull final : public Value<Json::NUL, NullStruct> {
29
public:
30
- JsonNull() : Value(nullptr) {}
31
+ JsonNull() : Value({}) {}
32
};
33
34
/* * * * * * * * * * * * * * * * * * * *
35
x265_3.1.2.tar.gz/source/encoder/analysis.cpp -> x265_3.2.tar.gz/source/encoder/analysis.cpp
Changed
26
1
2
MV mvp;
3
4
int numMvc = mode.cu.getPMV(mode.interNeighbours, list, ref, mode.amvpCand[list][ref], mvc);
5
- if (m_param->interRefine != 1)
6
- mvp = mode.amvpCand[list][ref][mode.cu.m_mvpIdx[list][pu.puAbsPartIdx]];
7
- else
8
- mvp = interDataCTU->mv[list][cuIdx + part].word;
9
+ mvp = mode.amvpCand[list][ref][mode.cu.m_mvpIdx[list][pu.puAbsPartIdx]];
10
if (m_param->mvRefine || m_param->interRefine == 1)
11
{
12
- MV outmv;
13
- searchMV(mode, pu, list, ref, outmv, mvp, numMvc, mvc);
14
+ MV outmv, mvpSelect[3];
15
+ mvpSelect[0] = interDataCTU->mv[list][cuIdx + part].word;
16
+ if (m_param->mvRefine > 1)
17
+ {
18
+ mvpSelect[1] = mvp;
19
+ if(m_param->mvRefine > 2)
20
+ mvpSelect[2] = mode.amvpCand[list][ref][!(mode.cu.m_mvpIdx[list][pu.puAbsPartIdx])];
21
+ }
22
+ searchMV(mode, list, ref, outmv, mvpSelect, numMvc, mvc);
23
mode.cu.setPUMv(list, outmv, pu.puAbsPartIdx, part);
24
}
25
mode.cu.m_mvd[list][pu.puAbsPartIdx] = mode.cu.m_mv[list][pu.puAbsPartIdx] - mode.amvpCand[list][ref][mode.cu.m_mvpIdx[list][pu.puAbsPartIdx]]/*mvp*/;
26
x265_3.1.2.tar.gz/source/encoder/api.cpp -> x265_3.2.tar.gz/source/encoder/api.cpp
Changed
46
1
2
x265_param* param = PARAM_NS::x265_param_alloc();
3
x265_param* latestParam = PARAM_NS::x265_param_alloc();
4
x265_param* zoneParam = PARAM_NS::x265_param_alloc();
5
- if (!param || !latestParam)
6
+
7
+ if(param) PARAM_NS::x265_param_default(param);
8
+ if(latestParam) PARAM_NS::x265_param_default(latestParam);
9
+ if(zoneParam) PARAM_NS::x265_param_default(zoneParam);
10
+
11
+ if (!param || !latestParam || !zoneParam)
12
goto fail;
13
if (p->rc.zoneCount || p->rc.zonefileCount)
14
{
15
16
}
17
18
x265_copy_params(param, p);
19
+ x265_copy_params(latestParam, p);
20
+ x265_copy_params(zoneParam, p);
21
x265_log(param, X265_LOG_INFO, "HEVC encoder version %s\n", PFX(version_str));
22
x265_log(param, X265_LOG_INFO, "build info %s\n", PFX(build_info_str));
23
24
25
delete encoder;
26
PARAM_NS::x265_param_free(param);
27
PARAM_NS::x265_param_free(latestParam);
28
+ PARAM_NS::x265_param_free(zoneParam);
29
return NULL;
30
}
31
32
33
34
void x265_zone_free(x265_param *param)
35
{
36
- if (param->rc.zonefileCount) {
37
+ if (param && param->rc.zonefileCount) {
38
for (int i = 0; i < param->rc.zonefileCount; i++)
39
x265_free(param->rc.zones[i].zoneParam);
40
}
41
- if (param->rc.zoneCount || param->rc.zonefileCount)
42
+ if (param && (param->rc.zoneCount || param->rc.zonefileCount))
43
x265_free(param->rc.zones);
44
}
45
46
x265_3.1.2.tar.gz/source/encoder/encoder.cpp -> x265_3.2.tar.gz/source/encoder/encoder.cpp
Changed
86
1
2
}
3
/* determine references, setup RPS, etc */
4
m_dpb->prepareEncode(frameEnc);
5
+ if (!!m_param->selectiveSAO)
6
+ {
7
+ Slice* slice = frameEnc->m_encData->m_slice;
8
+ slice->m_bUseSao = curEncoder->m_frameFilter.m_useSao = 1;
9
+ switch (m_param->selectiveSAO)
10
+ {
11
+ case 3: if (!IS_REFERENCED(frameEnc))
12
+ slice->m_bUseSao = curEncoder->m_frameFilter.m_useSao = 0;
13
+ break;
14
+ case 2: if (!!m_param->bframes && slice->m_sliceType == B_SLICE)
15
+ slice->m_bUseSao = curEncoder->m_frameFilter.m_useSao = 0;
16
+ break;
17
+ case 1: if (slice->m_sliceType != I_SLICE)
18
+ slice->m_bUseSao = curEncoder->m_frameFilter.m_useSao = 0;
19
+ break;
20
+ }
21
+ }
22
+ else
23
+ {
24
+ Slice* slice = frameEnc->m_encData->m_slice;
25
+ slice->m_bUseSao = curEncoder->m_frameFilter.m_useSao = 0;
26
+ }
27
28
if (m_param->rc.rateControlMode != X265_RC_CQP)
29
m_lookahead->getEstimatedPictureCost(frameEnc);
30
31
32
}
33
34
+ if (p->selectiveSAO && !p->bEnableSAO)
35
+ {
36
+ p->bEnableSAO = 1;
37
+ x265_log(p, X265_LOG_WARNING, "SAO turned ON when selective-sao is ON\n");
38
+ }
39
+
40
+ if (!p->selectiveSAO && p->bEnableSAO)
41
+ p->selectiveSAO = 4;
42
43
if (p->interlaceMode)
44
x265_log(p, X265_LOG_WARNING, "Support for interlaced video is experimental\n");
45
46
p->limitTU = 0;
47
}
48
49
- if (p->mvRefine)
50
- {
51
- if (!p->analysisLoad || p->analysisReuseLevel < 10)
52
- {
53
- x265_log(p, X265_LOG_WARNING, "MV refinement requires analysis load, analysis-reuse-level 10. Disabling MV refine.\n");
54
- p->mvRefine = 0;
55
- }
56
- else if (p->interRefine >= 2)
57
- {
58
- x265_log(p, X265_LOG_WARNING, "MVs are recomputed when refine-inter >= 2. MV refinement not applicable. Disabling MV refine\n");
59
- p->mvRefine = 0;
60
- }
61
- }
62
-
63
if (p->ctuDistortionRefine == CTU_DISTORTION_INTERNAL)
64
{
65
if (!p->analysisLoad && !p->analysisSave)
66
67
p->bRepeatHeaders = 1;
68
x265_log(p, X265_LOG_WARNING, "Turning on repeat - headers for zone encoding\n");
69
}
70
+
71
+ if (m_param->bEnableHME)
72
+ {
73
+ if (m_param->sourceHeight < 540)
74
+ {
75
+ x265_log(p, X265_LOG_WARNING, "Source height < 540p is too low for HME. Disabling HME.\n");
76
+ p->bEnableHME = 0;
77
+ }
78
+ if (m_param->bEnableHME && m_param->searchMethod != m_param->hmeSearchMethod[2])
79
+ {
80
+ m_param->searchMethod = m_param->hmeSearchMethod[2];
81
+ }
82
+ }
83
}
84
85
void Encoder::readAnalysisFile(x265_analysis_data* analysis, int curPoc, const x265_picture* picIn, int paramBytes)
86
x265_3.1.2.tar.gz/source/encoder/entropy.cpp -> x265_3.2.tar.gz/source/encoder/entropy.cpp
Changed
41
1
2
for (int i = 0; i < coefNum; i++)
3
{
4
data = src[scan[i]] - nextCoef;
5
+ if (data < -128)
6
+ data += 256;
7
+ if (data > 127)
8
+ data -= 256;
9
nextCoef = (nextCoef + data + 256) % 256;
10
WRITE_SVLC(data, "scaling_list_delta_coef");
11
}
12
13
WRITE_FLAG(1, "slice_temporal_mvp_enable_flag");
14
}
15
const SAOParam *saoParam = encData.m_saoParam;
16
- if (slice.m_sps->bUseSAO)
17
+ if (slice.m_bUseSao)
18
{
19
WRITE_FLAG(saoParam->bSaoFlag[0], "slice_sao_luma_flag");
20
if (encData.m_param->internalCsp != X265_CSP_I400)
21
WRITE_FLAG(saoParam->bSaoFlag[1], "slice_sao_chroma_flag");
22
}
23
+ else if(encData.m_param->selectiveSAO)
24
+ {
25
+ WRITE_FLAG(0, "slice_sao_luma_flag");
26
+ if (encData.m_param->internalCsp != X265_CSP_I400)
27
+ WRITE_FLAG(0, "slice_sao_chroma_flag");
28
+ }
29
30
// check if numRefIdx match the defaults (1, hard-coded in PPS). If not, override
31
// TODO: this might be a place to optimize a few bits per slice, by using param->refs for L0 default
32
33
34
if (encData.m_param->maxSlices <= 1)
35
{
36
- bool isSAOEnabled = slice.m_sps->bUseSAO ? saoParam->bSaoFlag[0] || saoParam->bSaoFlag[1] : false;
37
+ bool isSAOEnabled = slice.m_sps->bUseSAO && slice.m_bUseSao ? saoParam->bSaoFlag[0] || saoParam->bSaoFlag[1] : false;
38
bool isDBFEnabled = !slice.m_pps->bPicDisableDeblockingFilter;
39
40
if (isSAOEnabled || isDBFEnabled)
41
x265_3.1.2.tar.gz/source/encoder/frameencoder.cpp -> x265_3.2.tar.gz/source/encoder/frameencoder.cpp
Changed
73
1
2
if (!m_param->bEnableWavefront)
3
m_backupStreams = new Bitstream[numSubstreams];
4
m_substreamSizes = X265_MALLOC(uint32_t, numSubstreams);
5
- if (!m_param->bEnableSAO)
6
+ if (!slice->m_bUseSao)
7
+ {
8
for (uint32_t i = 0; i < numSubstreams; i++)
9
m_rows[i].rowGoOnCoder.setBitstream(&m_outStreams[i]);
10
+ }
11
}
12
else
13
{
14
for (uint32_t i = 0; i < numSubstreams; i++)
15
+ {
16
m_outStreams[i].resetBits();
17
+ if (!slice->m_bUseSao)
18
+ m_rows[i].rowGoOnCoder.setBitstream(&m_outStreams[i]);
19
+ else
20
+ m_rows[i].rowGoOnCoder.setBitstream(NULL);
21
+ }
22
}
23
24
m_rce.encodeOrder = m_frame->m_encodeOrder;
25
26
m_entropyCoder.setBitstream(&m_bs);
27
28
// finish encode of each CTU row, only required when SAO is enabled
29
- if (m_param->bEnableSAO)
30
+ if (slice->m_bUseSao)
31
encodeSlice(0);
32
33
m_entropyCoder.setBitstream(&m_bs);
34
35
const uint32_t lastCUAddr = (slice->m_endCUAddr + m_param->num4x4Partitions - 1) / m_param->num4x4Partitions;
36
const uint32_t numSubstreams = m_param->bEnableWavefront ? slice->m_sps->numCuInHeight : 1;
37
38
- SAOParam* saoParam = slice->m_sps->bUseSAO ? m_frame->m_encData->m_saoParam : NULL;
39
+ SAOParam* saoParam = slice->m_sps->bUseSAO && slice->m_bUseSao ? m_frame->m_encData->m_saoParam : NULL;
40
for (uint32_t cuAddr = sliceAddr; cuAddr < lastCUAddr; cuAddr++)
41
{
42
uint32_t col = cuAddr % widthInLCUs;
43
44
curRow.bufferedEntropy.loadContexts(rowCoder);
45
46
/* SAO parameter estimation using non-deblocked pixels for CTU bottom and right boundary areas */
47
- if (m_param->bEnableSAO && m_param->bSaoNonDeblocked)
48
+ if (slice->m_bUseSao && m_param->bSaoNonDeblocked)
49
m_frameFilter.m_parallelFilter[row].m_sao.calcSaoStatsCu_BeforeDblk(m_frame, col, row);
50
51
/* Deblock with idle threading */
52
- if (m_param->bEnableLoopFilter | m_param->bEnableSAO)
53
+ if (m_param->bEnableLoopFilter | slice->m_bUseSao)
54
{
55
// NOTE: in VBV mode, we may reencode anytime, so we can't do Deblock stage-Horizon and SAO
56
if (!bIsVbv)
57
58
59
/* flush row bitstream (if WPP and no SAO) or flush frame if no WPP and no SAO */
60
/* end_of_sub_stream_one_bit / end_of_slice_segment_flag */
61
- if (!m_param->bEnableSAO && (m_param->bEnableWavefront || bLastRowInSlice))
62
- rowCoder.finishSlice();
63
+ if (!slice->m_bUseSao && (m_param->bEnableWavefront || bLastRowInSlice))
64
+ rowCoder.finishSlice();
65
66
67
/* Processing left Deblock block with current threading */
68
- if ((m_param->bEnableLoopFilter | m_param->bEnableSAO) & (rowInSlice >= 2))
69
+ if ((m_param->bEnableLoopFilter | slice->m_bUseSao) & (rowInSlice >= 2))
70
{
71
/* Check conditional to start previous row process with current threading */
72
if (m_frameFilter.m_parallelFilter[row - 2].m_lastDeblocked.get() == (int)numCols)
73
x265_3.1.2.tar.gz/source/encoder/frameencoder.h -> x265_3.2.tar.gz/source/encoder/frameencoder.h
Changed
9
1
2
uint32_t m_filterRowDelay;
3
uint32_t m_filterRowDelayCus;
4
uint32_t m_refLagRows;
5
+ bool m_bUseSao;
6
7
CTURow* m_rows;
8
uint16_t m_sliceAddrBits;
9
x265_3.1.2.tar.gz/source/encoder/framefilter.cpp -> x265_3.2.tar.gz/source/encoder/framefilter.cpp
Changed
107
1
2
3
if (m_parallelFilter)
4
{
5
- if (m_param->bEnableSAO)
6
+ if (m_useSao)
7
{
8
for(int row = 0; row < m_numRows; row++)
9
m_parallelFilter[row].m_sao.destroy((row == 0 ? 1 : 0));
10
11
{
12
m_param = frame->m_param;
13
m_frameEncoder = frame;
14
+ m_useSao = 1;
15
m_numRows = numRows;
16
m_numCols = numCols;
17
m_hChromaShift = CHROMA_H_SHIFT(m_param->internalCsp);
18
19
20
if (m_parallelFilter)
21
{
22
- if (m_param->bEnableSAO)
23
+ if (m_useSao)
24
{
25
for(int row = 0; row < numRows; row++)
26
{
27
if (!m_parallelFilter[row].m_sao.create(m_param, (row == 0 ? 1 : 0)))
28
- m_param->bEnableSAO = 0;
29
+ m_useSao = 0;
30
else
31
{
32
if (row != 0)
33
34
{
35
for(int row = 0; row < m_numRows; row++)
36
{
37
- if (m_param->bEnableSAO)
38
+ if (m_useSao)
39
m_parallelFilter[row].m_sao.startSlice(frame, initState);
40
41
m_parallelFilter[row].m_lastCol.set(0);
42
43
}
44
45
// Reset SAO common statistics
46
- if (m_param->bEnableSAO)
47
+ if (m_useSao)
48
m_parallelFilter[0].m_sao.resetStats();
49
}
50
}
51
52
deblockCTU(ctuPrev, cuGeoms[ctuGeomMap[cuAddr - 1]], Deblock::EDGE_HOR);
53
54
// When SAO Disable, setting column counter here
55
- if (!m_frameFilter->m_param->bEnableSAO & !ctuPrev->m_bFirstRowInSlice)
56
+ if (!m_frameFilter->m_useSao & !ctuPrev->m_bFirstRowInSlice)
57
m_prevRow->processPostCu(col - 1);
58
}
59
60
- if (m_frameFilter->m_param->bEnableSAO)
61
+ if (m_frameFilter->m_useSao)
62
{
63
// Save SAO bottom row reference pixels
64
copySaoAboveRef(ctuPrev, reconPic, cuAddr - 1, col - 1);
65
66
deblockCTU(ctuPrev, cuGeoms[ctuGeomMap[cuAddr]], Deblock::EDGE_HOR);
67
68
// When SAO Disable, setting column counter here
69
- if (!m_frameFilter->m_param->bEnableSAO & !ctuPrev->m_bFirstRowInSlice)
70
+ if (!m_frameFilter->m_useSao & !ctuPrev->m_bFirstRowInSlice)
71
m_prevRow->processPostCu(numCols - 1);
72
}
73
74
// TODO: move processPostCu() into processSaoUnitCu()
75
- if (m_frameFilter->m_param->bEnableSAO)
76
+ if (m_frameFilter->m_useSao)
77
{
78
const CUData* ctu = m_encData->getPicCTU(m_rowAddr + numCols - 2);
79
80
81
m_frameEncoder->m_cuStats.countLoopFilter++;
82
#endif
83
84
- if (!m_param->bEnableLoopFilter && !m_param->bEnableSAO)
85
+ if (!m_param->bEnableLoopFilter && !m_useSao)
86
{
87
processPostRow(row);
88
return;
89
90
x265_log(m_param, X265_LOG_WARNING, "detected ParallelFilter race condition on last row\n");
91
92
/* Apply SAO on last row of CUs, because we always apply SAO on row[X-1] */
93
- if (m_param->bEnableSAO)
94
+ if (m_useSao)
95
{
96
for(int col = 0; col < m_numCols; col++)
97
{
98
99
100
if (numRowFinished == m_numRows)
101
{
102
- if (m_param->bEnableSAO)
103
+ if (m_useSao)
104
{
105
// Merge numNoSao into RootNode (Node0)
106
for(int i = 1; i < m_numRows; i++)
107
x265_3.1.2.tar.gz/source/encoder/framefilter.h -> x265_3.2.tar.gz/source/encoder/framefilter.h
Changed
9
1
2
3
x265_param* m_param;
4
Frame* m_frame;
5
+ int m_useSao;
6
FrameEncoder* m_frameEncoder;
7
int m_hChromaShift;
8
int m_vChromaShift;
9
x265_3.1.2.tar.gz/source/encoder/motion.cpp -> x265_3.2.tar.gz/source/encoder/motion.cpp
Changed
142
1
2
ctuAddr = -1;
3
absPartIdx = -1;
4
searchMethod = X265_HEX_SEARCH;
5
+ searchMethodL0 = X265_HEX_SEARCH;
6
+ searchMethodL1 = X265_HEX_SEARCH;
7
subpelRefine = 2;
8
blockwidth = blockheight = 0;
9
blockOffset = 0;
10
11
}
12
13
/* Called by lookahead, luma only, no use of PicYuv */
14
-void MotionEstimate::setSourcePU(pixel *fencY, intptr_t stride, intptr_t offset, int pwidth, int pheight, const int method, const int refine)
15
+void MotionEstimate::setSourcePU(pixel *fencY, intptr_t stride, intptr_t offset, int pwidth, int pheight, const int method, const int searchL0, const int searchL1, const int refine)
16
{
17
partEnum = partitionFromSizes(pwidth, pheight);
18
X265_CHECK(LUMA_4x4 != partEnum, "4x4 inter partition detected!\n");
19
20
21
/* Search params */
22
searchMethod = method;
23
+ searchMethodL0 = searchL0;
24
+ searchMethodL1 = searchL1;
25
subpelRefine = refine;
26
27
/* copy PU block into cache */
28
29
int & bPointNr,
30
int & bDistance,
31
int earlyExitIters,
32
- int merange)
33
+ int merange,
34
+ int hme)
35
{
36
ALIGN_VAR_16(int, costs[16]);
37
pixel* fenc = fencPUYuv.m_buf[0];
38
- pixel* fref = ref->fpelPlane[0] + blockOffset;
39
- intptr_t stride = ref->lumaStride;
40
+ pixel* fref = (hme? ref->fpelLowerResPlane[0] : ref->fpelPlane[0]) + blockOffset;
41
+ intptr_t stride = hme? ref->lumaStride / 2 : ref->lumaStride;
42
43
MV omv = bmv;
44
int saved = bcost;
45
46
pixel * srcReferencePlane)
47
{
48
ALIGN_VAR_16(int, costs[16]);
49
+ bool hme = srcReferencePlane && srcReferencePlane == ref->fpelLowerResPlane[0];
50
if (ctuAddr >= 0)
51
blockOffset = ref->reconPic->getLumaAddr(ctuAddr, absPartIdx) - ref->reconPic->getLumaAddr(0);
52
- intptr_t stride = ref->lumaStride;
53
+ intptr_t stride = hme ? ref->lumaStride / 2 : ref->lumaStride;
54
pixel* fenc = fencPUYuv.m_buf[0];
55
pixel* fref = srcReferencePlane == 0 ? ref->fpelPlane[0] + blockOffset : srcReferencePlane + blockOffset;
56
57
58
int bprecost;
59
60
if (ref->isLowres)
61
- bprecost = ref->lowresQPelCost(fenc, blockOffset, pmv, sad);
62
+ bprecost = ref->lowresQPelCost(fenc, blockOffset, pmv, sad, hme);
63
else
64
bprecost = subpelCompare(ref, pmv, sad);
65
66
67
pmv = pmv.roundToFPel();
68
MV omv = bmv; // current search origin or starting point
69
70
- switch (searchMethod)
71
+ int search = ref->isHMELowres ? (hme ? searchMethodL0 : searchMethodL1) : searchMethod;
72
+ switch (search)
73
{
74
case X265_DIA_SEARCH:
75
{
76
77
int bDistance = 0;
78
79
const int EarlyExitIters = 3;
80
- StarPatternSearch(ref, mvmin, mvmax, bmv, bcost, bPointNr, bDistance, EarlyExitIters, merange);
81
+ StarPatternSearch(ref, mvmin, mvmax, bmv, bcost, bPointNr, bDistance, EarlyExitIters, merange, hme);
82
if (bDistance == 1)
83
{
84
// if best distance was only 1, check two missing points. If no new point is found, stop
85
86
bDistance = 0;
87
bPointNr = 0;
88
const int MaxIters = 32;
89
- StarPatternSearch(ref, mvmin, mvmax, bmv, bcost, bPointNr, bDistance, MaxIters, merange);
90
+ StarPatternSearch(ref, mvmin, mvmax, bmv, bcost, bPointNr, bDistance, MaxIters, merange, hme);
91
92
if (bDistance == 1)
93
{
94
95
{
96
// dead slow exhaustive search, but at least it uses sad_x4()
97
MV tmv;
98
- for (tmv.y = mvmin.y; tmv.y <= mvmax.y; tmv.y++)
99
+ int32_t mvmin_y = mvmin.y, mvmin_x = mvmin.x, mvmax_y = mvmax.y, mvmax_x = mvmax.x;
100
+ if (ref->isHMELowres)
101
+ {
102
+ merange = (merange < 0 ? -merange : merange);
103
+ mvmin_y = X265_MAX(mvmin.y, -merange);
104
+ mvmin_x = X265_MAX(mvmin.x, -merange);
105
+ mvmax_y = X265_MIN(mvmax.y, merange);
106
+ mvmax_x = X265_MIN(mvmax.x, merange);
107
+ }
108
+ for (tmv.y = mvmin_y; tmv.y <= mvmax_y; tmv.y++)
109
{
110
- for (tmv.x = mvmin.x; tmv.x <= mvmax.x; tmv.x++)
111
+ for (tmv.x = mvmin_x; tmv.x <= mvmax_x; tmv.x++)
112
{
113
- if (tmv.x + 3 <= mvmax.x)
114
+ if (tmv.x + 3 <= mvmax_x)
115
{
116
pixel *pix_base = fref + tmv.y * stride + tmv.x;
117
sad_x4(fenc,
118
119
if ((qmv.y < qmvmin.y) | (qmv.y > qmvmax.y))
120
continue;
121
122
- int cost = ref->lowresQPelCost(fenc, blockOffset, qmv, sad) + mvcost(qmv);
123
+ int cost = ref->lowresQPelCost(fenc, blockOffset, qmv, sad, hme) + mvcost(qmv);
124
COPY2_IF_LT(bcost, cost, bdir, i);
125
}
126
127
bmv += square1[bdir] * 2;
128
- bcost = ref->lowresQPelCost(fenc, blockOffset, bmv, satd) + mvcost(bmv);
129
+ bcost = ref->lowresQPelCost(fenc, blockOffset, bmv, satd, hme) + mvcost(bmv);
130
131
bdir = 0;
132
for (int i = 1; i <= wl.qpel_dirs; i++)
133
134
if ((qmv.y < qmvmin.y) | (qmv.y > qmvmax.y))
135
continue;
136
137
- int cost = ref->lowresQPelCost(fenc, blockOffset, qmv, satd) + mvcost(qmv);
138
+ int cost = ref->lowresQPelCost(fenc, blockOffset, qmv, satd, hme) + mvcost(qmv);
139
COPY2_IF_LT(bcost, cost, bdir, i);
140
}
141
142
x265_3.1.2.tar.gz/source/encoder/motion.h -> x265_3.2.tar.gz/source/encoder/motion.h
Changed
29
1
2
int absPartIdx; // part index of PU, including CU offset within CTU
3
4
int searchMethod;
5
+ int searchMethodL0;
6
+ int searchMethodL1;
7
int subpelRefine;
8
9
int blockwidth;
10
11
12
/* Methods called at slice setup */
13
14
- void setSourcePU(pixel *fencY, intptr_t stride, intptr_t offset, int pwidth, int pheight, const int searchMethod, const int subpelRefine);
15
+ void setSourcePU(pixel *fencY, intptr_t stride, intptr_t offset, int pwidth, int pheight, const int searchMethod, const int searchL0, const int searchL1, const int subpelRefine);
16
void setSourcePU(const Yuv& srcFencYuv, int ctuAddr, int cuPartIdx, int puPartIdx, int pwidth, int pheight, const int searchMethod, const int subpelRefine, bool bChroma);
17
18
/* buf*() and motionEstimate() methods all use cached fenc pixels and thus
19
20
int & bPointNr,
21
int & bDistance,
22
int earlyExitIters,
23
- int merange);
24
+ int merange,
25
+ int hme);
26
};
27
}
28
29
x265_3.1.2.tar.gz/source/encoder/ratecontrol.cpp -> x265_3.2.tar.gz/source/encoder/ratecontrol.cpp
Changed
11
1
2
if ((underflow < epsilon || rce->isFadeEnd) && !isFrameDone)
3
{
4
init(*m_curSlice->m_sps);
5
+ // Reduce tune complexity factor for scenes that follow blank frames
6
+ 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;
7
+ m_cplxrSum /= tuneCplxFactor;
8
m_shortTermCplxSum = rce->lastSatd / (CLIP_DURATION(m_frameDuration) / BASE_FRAME_DURATION);
9
m_shortTermCplxCount = 1;
10
m_isAbrReset = true;
11
x265_3.1.2.tar.gz/source/encoder/search.cpp -> x265_3.2.tar.gz/source/encoder/search.cpp
Changed
225
1
2
3
const MV* amvp = interMode.amvpCand[list][ref];
4
int mvpIdx = selectMVP(interMode.cu, pu, amvp, list, ref);
5
- MV mvmin, mvmax, outmv, mvp = amvp[mvpIdx];
6
+ bool bLowresMVP = false;
7
+ MV mvmin, mvmax, outmv, mvp = amvp[mvpIdx], mvp_lowres;
8
9
if (!m_param->analysisSave && !m_param->analysisLoad) /* Prevents load/save outputs from diverging if lowresMV is not available */
10
{
11
MV lmv = getLowresMV(interMode.cu, pu, list, ref);
12
if (lmv.notZero())
13
mvc[numMvc++] = lmv;
14
+ if (m_param->bEnableHME)
15
+ mvp_lowres = lmv;
16
}
17
18
setSearchRange(interMode.cu, mvp, m_param->searchRange, mvmin, mvmax);
19
20
int satdCost = m_me.motionEstimate(&m_slice->m_mref[list][ref], mvmin, mvmax, mvp, numMvc, mvc, m_param->searchRange, outmv, m_param->maxSlices,
21
m_param->bSourceReferenceEstimation ? m_slice->m_refFrameList[list][ref]->m_fencPic->getLumaAddr(0) : 0);
22
23
+ if (m_param->bEnableHME && mvp_lowres.notZero() && mvp_lowres != mvp)
24
+ {
25
+ MV outmv_lowres;
26
+ setSearchRange(interMode.cu, mvp_lowres, m_param->searchRange, mvmin, mvmax);
27
+ int lowresMvCost = m_me.motionEstimate(&m_slice->m_mref[list][ref], mvmin, mvmax, mvp_lowres, numMvc, mvc, m_param->searchRange, outmv_lowres, m_param->maxSlices,
28
+ m_param->bSourceReferenceEstimation ? m_slice->m_refFrameList[list][ref]->m_fencPic->getLumaAddr(0) : 0);
29
+ if (lowresMvCost < satdCost)
30
+ {
31
+ outmv = outmv_lowres;
32
+ satdCost = lowresMvCost;
33
+ bLowresMVP = true;
34
+ }
35
+ }
36
/* Get total cost of partition, but only include MV bit cost once */
37
bits += m_me.bitcost(outmv);
38
uint32_t mvCost = m_me.mvcost(outmv);
39
uint32_t cost = (satdCost - mvCost) + m_rdCost.getCost(bits);
40
41
+ /* Update LowresMVP to best AMVP cand*/
42
+ if (bLowresMVP)
43
+ updateMVP(amvp[mvpIdx], outmv, bits, cost, mvp_lowres);
44
+
45
/* Refine MVP selection, updates: mvpIdx, bits, cost */
46
mvp = checkBestMVP(amvp, outmv, mvpIdx, bits, cost);
47
48
49
bestME[list].mvCost = mvCost;
50
}
51
}
52
-void Search::searchMV(Mode& interMode, const PredictionUnit& pu, int list, int ref, MV& outmv, MV mvp, int numMvc, MV* mvc)
53
+void Search::searchMV(Mode& interMode, int list, int ref, MV& outmv, MV mvp[3], int numMvc, MV* mvc)
54
{
55
CUData& cu = interMode.cu;
56
- const Slice *slice = m_slice;
57
- MV mv;
58
- if (m_param->interRefine == 1)
59
- mv = mvp;
60
- else
61
- mv = cu.m_mv[list][pu.puAbsPartIdx];
62
+ MV mv, mvmin, mvmax;
63
cu.clipMv(mv);
64
- MV mvmin, mvmax;
65
- setSearchRange(cu, mv, m_param->searchRange, mvmin, mvmax);
66
- if (m_param->interRefine == 1)
67
- m_me.motionEstimate(&m_slice->m_mref[list][ref], mvmin, mvmax, mv, numMvc, mvc, m_param->searchRange, outmv, m_param->maxSlices,
68
+ int cand = 0, bestcost = INT_MAX;
69
+ do
70
+ {
71
+ if (cand && (mvp[cand] == mvp[cand - 1] || (cand == 2 && mvp[cand] == mvp[cand - 2])))
72
+ continue;
73
+ MV bestMV;
74
+ mv = mvp[cand];
75
+ setSearchRange(cu, mv, m_param->searchRange, mvmin, mvmax);
76
+ int cost = m_me.motionEstimate(&m_slice->m_mref[list][ref], mvmin, mvmax, mv, numMvc, mvc, m_param->searchRange, bestMV, m_param->maxSlices,
77
m_param->bSourceReferenceEstimation ? m_slice->m_refFrameList[list][ref]->m_fencPic->getLumaAddr(0) : 0);
78
- else
79
- m_me.refineMV(&slice->m_mref[list][ref], mvmin, mvmax, mv, outmv);
80
+ if (bestcost > cost)
81
+ {
82
+ bestcost = cost;
83
+ outmv = bestMV;
84
+ }
85
+ }while (++cand < m_param->mvRefine);
86
}
87
/* find the best inter prediction for each PU of specified mode */
88
void Search::predInterSearch(Mode& interMode, const CUGeom& cuGeom, bool bChromaMC, uint32_t refMasks[2])
89
90
int ref = -1;
91
if (useAsMVP)
92
ref = interDataCTU->refIdx[list][cuIdx + puIdx];
93
-
94
else
95
ref = bestME[list].ref;
96
if (ref < 0)
97
98
const MV* amvp = interMode.amvpCand[list][ref];
99
int mvpIdx = selectMVP(cu, pu, amvp, list, ref);
100
MV mvmin, mvmax, outmv, mvp;
101
- if (useAsMVP)
102
- {
103
- mvp = interDataCTU->mv[list][cuIdx + puIdx].word;
104
- mvpIdx = interDataCTU->mvpIdx[list][cuIdx + puIdx];
105
- }
106
- else
107
- mvp = amvp[mvpIdx];
108
+ mvp = amvp[mvpIdx];
109
if (m_param->searchMethod == X265_SEA)
110
{
111
int puX = puIdx & 1;
112
113
}
114
setSearchRange(cu, mvp, m_param->searchRange, mvmin, mvmax);
115
MV mvpIn = mvp;
116
+ int satdCost;
117
if (m_param->analysisMultiPassRefine && m_param->rc.bStatRead && mvpIdx == bestME[list].mvpIdx)
118
mvpIn = bestME[list].mv;
119
-
120
- int satdCost = m_me.motionEstimate(&slice->m_mref[list][ref], mvmin, mvmax, mvpIn, numMvc, mvc, m_param->searchRange, outmv, m_param->maxSlices,
121
- m_param->bSourceReferenceEstimation ? m_slice->m_refFrameList[list][ref]->m_fencPic->getLumaAddr(0) : 0);
122
+ if (useAsMVP)
123
+ {
124
+ MV bestmv, mvpSel[3];
125
+ int mvpIdxSel[3];
126
+ satdCost = m_me.COST_MAX;
127
+ mvpSel[0] = interDataCTU->mv[list][cuIdx + puIdx].word;
128
+ mvpIdxSel[0] = interDataCTU->mvpIdx[list][cuIdx + puIdx];
129
+ if (m_param->mvRefine > 1)
130
+ {
131
+ mvpSel[1] = interMode.amvpCand[list][ref][mvpIdx];
132
+ mvpIdxSel[1] = mvpIdx;
133
+ if (m_param->mvRefine > 2)
134
+ {
135
+ mvpSel[2] = interMode.amvpCand[list][ref][!mvpIdx];
136
+ mvpIdxSel[2] = !mvpIdx;
137
+ }
138
+ }
139
+ for (int cand = 0; cand < m_param->mvRefine; cand++)
140
+ {
141
+ if (cand && (mvpSel[cand] == mvpSel[cand - 1] || (cand == 2 && mvpSel[cand] == mvpSel[cand - 2])))
142
+ continue;
143
+ setSearchRange(cu, mvp, m_param->searchRange, mvmin, mvmax);
144
+ int bcost = m_me.motionEstimate(&m_slice->m_mref[list][ref], mvmin, mvmax, mvpSel[cand], numMvc, mvc, m_param->searchRange, bestmv, m_param->maxSlices,
145
+ m_param->bSourceReferenceEstimation ? m_slice->m_refFrameList[list][ref]->m_fencPic->getLumaAddr(0) : 0);
146
+ if (satdCost > bcost)
147
+ {
148
+ satdCost = bcost;
149
+ outmv = bestmv;
150
+ mvp = mvpSel[cand];
151
+ mvpIdx = mvpIdxSel[cand];
152
+ }
153
+ }
154
+ }
155
+ else
156
+ {
157
+ satdCost = m_me.motionEstimate(&slice->m_mref[list][ref], mvmin, mvmax, mvpIn, numMvc, mvc, m_param->searchRange, outmv, m_param->maxSlices,
158
+ m_param->bSourceReferenceEstimation ? m_slice->m_refFrameList[list][ref]->m_fencPic->getLumaAddr(0) : 0);
159
+ }
160
161
/* Get total cost of partition, but only include MV bit cost once */
162
bits += m_me.bitcost(outmv);
163
164
165
const MV* amvp = interMode.amvpCand[list][ref];
166
int mvpIdx = selectMVP(cu, pu, amvp, list, ref);
167
- MV mvmin, mvmax, outmv, mvp = amvp[mvpIdx];
168
+ MV mvmin, mvmax, outmv, mvp = amvp[mvpIdx], mvp_lowres;
169
+ bool bLowresMVP = false;
170
171
if (!m_param->analysisSave && !m_param->analysisLoad) /* Prevents load/save outputs from diverging when lowresMV is not available */
172
{
173
MV lmv = getLowresMV(cu, pu, list, ref);
174
if (lmv.notZero())
175
mvc[numMvc++] = lmv;
176
+ if (m_param->bEnableHME)
177
+ mvp_lowres = lmv;
178
}
179
if (m_param->searchMethod == X265_SEA)
180
{
181
182
int satdCost = m_me.motionEstimate(&slice->m_mref[list][ref], mvmin, mvmax, mvp, numMvc, mvc, m_param->searchRange, outmv, m_param->maxSlices,
183
m_param->bSourceReferenceEstimation ? m_slice->m_refFrameList[list][ref]->m_fencPic->getLumaAddr(0) : 0);
184
185
+ if (m_param->bEnableHME && mvp_lowres.notZero() && mvp_lowres != mvp)
186
+ {
187
+ MV outmv_lowres;
188
+ setSearchRange(cu, mvp_lowres, m_param->searchRange, mvmin, mvmax);
189
+ int lowresMvCost = m_me.motionEstimate(&slice->m_mref[list][ref], mvmin, mvmax, mvp_lowres, numMvc, mvc, m_param->searchRange, outmv_lowres, m_param->maxSlices,
190
+ m_param->bSourceReferenceEstimation ? m_slice->m_refFrameList[list][ref]->m_fencPic->getLumaAddr(0) : 0);
191
+ if (lowresMvCost < satdCost)
192
+ {
193
+ outmv = outmv_lowres;
194
+ satdCost = lowresMvCost;
195
+ bLowresMVP = true;
196
+ }
197
+ }
198
+
199
/* Get total cost of partition, but only include MV bit cost once */
200
bits += m_me.bitcost(outmv);
201
uint32_t mvCost = m_me.mvcost(outmv);
202
uint32_t cost = (satdCost - mvCost) + m_rdCost.getCost(bits);
203
+ /* Update LowresMVP to best AMVP cand*/
204
+ if (bLowresMVP)
205
+ updateMVP(amvp[mvpIdx], outmv, bits, cost, mvp_lowres);
206
207
/* Refine MVP selection, updates: mvpIdx, bits, cost */
208
mvp = checkBestMVP(amvp, outmv, mvpIdx, bits, cost);
209
210
return amvpCand[mvpIdx];
211
}
212
213
+/* Update to default MVP when using an alternative mvp */
214
+void Search::updateMVP(const MV amvp, const MV& mv, uint32_t& outBits, uint32_t& outCost, const MV& alterMVP)
215
+{
216
+ int diffBits = m_me.bitcost(mv, amvp) - m_me.bitcost(mv, alterMVP);
217
+ uint32_t origOutBits = outBits;
218
+ outBits = origOutBits + diffBits;
219
+ outCost = (outCost - m_rdCost.getCost(origOutBits)) + m_rdCost.getCost(outBits);
220
+}
221
+
222
void Search::setSearchRange(const CUData& cu, const MV& mvp, int merange, MV& mvmin, MV& mvmax) const
223
{
224
MV dist((int32_t)merange << 2, (int32_t)merange << 2);
225
x265_3.1.2.tar.gz/source/encoder/search.h -> x265_3.2.tar.gz/source/encoder/search.h
Changed
18
1
2
3
// estimation inter prediction (non-skip)
4
void predInterSearch(Mode& interMode, const CUGeom& cuGeom, bool bChromaMC, uint32_t masks[2]);
5
- void searchMV(Mode& interMode, const PredictionUnit& pu, int list, int ref, MV& outmv, MV mvp, int numMvc, MV* mvc);
6
+ void searchMV(Mode& interMode, int list, int ref, MV& outmv, MV mvp[3], int numMvc, MV* mvc);
7
// encode residual and compute rd-cost for inter mode
8
void encodeResAndCalcRdInterCU(Mode& interMode, const CUGeom& cuGeom);
9
void encodeResAndCalcRdSkipCU(Mode& interMode);
10
11
void setSearchRange(const CUData& cu, const MV& mvp, int merange, MV& mvmin, MV& mvmax) const;
12
uint32_t mergeEstimation(CUData& cu, const CUGeom& cuGeom, const PredictionUnit& pu, int puIdx, MergeData& m);
13
static void getBlkBits(PartSize cuMode, bool bPSlice, int puIdx, uint32_t lastMode, uint32_t blockBit[3]);
14
+ void updateMVP(const MV amvp, const MV& mv, uint32_t& outBits, uint32_t& outCost, const MV& alterMVP);
15
16
/* intra helper functions */
17
enum { MAX_RD_INTRA_MODES = 16 };
18
x265_3.1.2.tar.gz/source/encoder/slicetype.cpp -> x265_3.2.tar.gz/source/encoder/slicetype.cpp
Changed
652
1
2
3
} // end anonymous namespace
4
5
+void edgeFilter(Frame *curFrame, pixel *pic1, pixel *pic2, pixel *pic3, intptr_t stride, int height, int width)
6
+{
7
+ pixel *src = (pixel*)curFrame->m_fencPic->m_picOrg[0];
8
+ pixel *edgePic = pic1 + curFrame->m_fencPic->m_lumaMarginY * stride + curFrame->m_fencPic->m_lumaMarginX;
9
+ pixel *refPic = pic2 + curFrame->m_fencPic->m_lumaMarginY * stride + curFrame->m_fencPic->m_lumaMarginX;
10
+ pixel *edgeTheta = pic3 + curFrame->m_fencPic->m_lumaMarginY * stride + curFrame->m_fencPic->m_lumaMarginX;
11
+
12
+ for (int i = 0; i < height; i++)
13
+ {
14
+ memcpy(edgePic, src, width * sizeof(pixel));
15
+ memcpy(refPic, src, width * sizeof(pixel));
16
+ src += stride;
17
+ edgePic += stride;
18
+ refPic += stride;
19
+ }
20
+
21
+ //Applying Gaussian filter on the picture
22
+ src = (pixel*)curFrame->m_fencPic->m_picOrg[0];
23
+ refPic = pic2 + curFrame->m_fencPic->m_lumaMarginY * stride + curFrame->m_fencPic->m_lumaMarginX;
24
+ pixel pixelValue = 0;
25
+
26
+ for (int rowNum = 0; rowNum < height; rowNum++)
27
+ {
28
+ for (int colNum = 0; colNum < width; colNum++)
29
+ {
30
+ if ((rowNum >= 2) && (colNum >= 2) && (rowNum != height - 2) && (colNum != width - 2)) //Ignoring the border pixels of the picture
31
+ {
32
+ /* 5x5 Gaussian filter
33
+ [2 4 5 4 2]
34
+ 1 [4 9 12 9 4]
35
+ --- [5 12 15 12 5]
36
+ 159 [4 9 12 9 4]
37
+ [2 4 5 4 2]*/
38
+
39
+ const intptr_t rowOne = (rowNum - 2)*stride, colOne = colNum - 2;
40
+ const intptr_t rowTwo = (rowNum - 1)*stride, colTwo = colNum - 1;
41
+ const intptr_t rowThree = rowNum * stride, colThree = colNum;
42
+ const intptr_t rowFour = (rowNum + 1)*stride, colFour = colNum + 1;
43
+ const intptr_t rowFive = (rowNum + 2)*stride, colFive = colNum + 2;
44
+ const intptr_t index = (rowNum*stride) + colNum;
45
+
46
+ pixelValue = ((2 * src[rowOne + colOne] + 4 * src[rowOne + colTwo] + 5 * src[rowOne + colThree] + 4 * src[rowOne + colFour] + 2 * src[rowOne + colFive] +
47
+ 4 * src[rowTwo + colOne] + 9 * src[rowTwo + colTwo] + 12 * src[rowTwo + colThree] + 9 * src[rowTwo + colFour] + 4 * src[rowTwo + colFive] +
48
+ 5 * src[rowThree + colOne] + 12 * src[rowThree + colTwo] + 15 * src[rowThree + colThree] + 12 * src[rowThree + colFour] + 5 * src[rowThree + colFive] +
49
+ 4 * src[rowFour + colOne] + 9 * src[rowFour + colTwo] + 12 * src[rowFour + colThree] + 9 * src[rowFour + colFour] + 4 * src[rowFour + colFive] +
50
+ 2 * src[rowFive + colOne] + 4 * src[rowFive + colTwo] + 5 * src[rowFive + colThree] + 4 * src[rowFive + colFour] + 2 * src[rowFive + colFive]) / 159);
51
+ refPic[index] = pixelValue;
52
+ }
53
+ }
54
+ }
55
+
56
+#if HIGH_BIT_DEPTH //10-bit build
57
+ float threshold = 1023;
58
+ pixel whitePixel = 1023;
59
+#else
60
+ float threshold = 255;
61
+ pixel whitePixel = 255;
62
+#endif
63
+#define PI 3.14159265
64
+
65
+ float gradientH = 0, gradientV = 0, radians = 0, theta = 0;
66
+ float gradientMagnitude = 0;
67
+ pixel blackPixel = 0;
68
+ edgePic = pic1 + curFrame->m_fencPic->m_lumaMarginY * stride + curFrame->m_fencPic->m_lumaMarginX;
69
+ //Applying Sobel filter on the gaussian filtered picture
70
+ for (int rowNum = 0; rowNum < height; rowNum++)
71
+ {
72
+ for (int colNum = 0; colNum < width; colNum++)
73
+ {
74
+ edgeTheta[(rowNum*stride) + colNum] = 0;
75
+ if ((rowNum != 0) && (colNum != 0) && (rowNum != height - 1) && (colNum != width - 1)) //Ignoring the border pixels of the picture
76
+ {
77
+ /*Horizontal and vertical gradients
78
+ [ -3 0 3 ] [-3 -10 -3 ]
79
+ gH = [ -10 0 10] gV = [ 0 0 0 ]
80
+ [ -3 0 3 ] [ 3 10 3 ]*/
81
+
82
+ const intptr_t rowOne = (rowNum - 1)*stride, colOne = colNum -1;
83
+ const intptr_t rowTwo = rowNum * stride, colTwo = colNum;
84
+ const intptr_t rowThree = (rowNum + 1)*stride, colThree = colNum + 1;
85
+ const intptr_t index = (rowNum*stride) + colNum;
86
+
87
+ gradientH = (float)(-3 * refPic[rowOne + colOne] + 3 * refPic[rowOne + colThree] - 10 * refPic[rowTwo + colOne] + 10 * refPic[rowTwo + colThree] - 3 * refPic[rowThree + colOne] + 3 * refPic[rowThree + colThree]);
88
+ gradientV = (float)(-3 * refPic[rowOne + colOne] - 10 * refPic[rowOne + colTwo] - 3 * refPic[rowOne + colThree] + 3 * refPic[rowThree + colOne] + 10 * refPic[rowThree + colTwo] + 3 * refPic[rowThree + colThree]);
89
+
90
+ gradientMagnitude = sqrtf(gradientH * gradientH + gradientV * gradientV);
91
+ radians = atan2(gradientV, gradientH);
92
+ theta = (float)((radians * 180) / PI);
93
+ if (theta < 0)
94
+ theta = 180 + theta;
95
+ edgeTheta[(rowNum*stride) + colNum] = (pixel)theta;
96
+
97
+ edgePic[index] = gradientMagnitude >= threshold ? whitePixel : blackPixel;
98
+ }
99
+ }
100
+ }
101
+}
102
+
103
+//Find the angle of a block by averaging the pixel angles
104
+inline void findAvgAngle(const pixel* block, intptr_t stride, uint32_t size, uint32_t &angle)
105
+{
106
+ int sum = 0;
107
+ for (uint32_t y = 0; y < size; y++)
108
+ {
109
+ for (uint32_t x = 0; x < size; x++)
110
+ {
111
+ sum += block[x];
112
+ }
113
+ block += stride;
114
+ }
115
+ angle = sum / (size*size);
116
+}
117
+
118
+uint32_t LookaheadTLD::edgeDensityCu(Frame* curFrame,pixel *edgeImage, pixel *edgeTheta, uint32_t &avgAngle, uint32_t blockX, uint32_t blockY, uint32_t qgSize)
119
+{
120
+ intptr_t srcStride = curFrame->m_fencPic->m_stride;
121
+ intptr_t blockOffsetLuma = blockX + (blockY * srcStride);
122
+ int plane = 0; // Sobel filter is applied only on Y component
123
+ uint32_t var;
124
+
125
+ if (qgSize == 8)
126
+ {
127
+ findAvgAngle(edgeTheta + blockOffsetLuma, srcStride, qgSize, avgAngle);
128
+ var = acEnergyVar(curFrame, primitives.cu[BLOCK_8x8].var(edgeImage + blockOffsetLuma, srcStride), 6, plane);
129
+ }
130
+ else
131
+ {
132
+ findAvgAngle(edgeTheta + blockOffsetLuma, srcStride, 16, avgAngle);
133
+ var = acEnergyVar(curFrame, primitives.cu[BLOCK_16x16].var(edgeImage + blockOffsetLuma, srcStride), 8, plane);
134
+ }
135
+ x265_emms();
136
+ return var;
137
+}
138
+
139
/* Find the total AC energy of each block in all planes */
140
uint32_t LookaheadTLD::acEnergyCu(Frame* curFrame, uint32_t blockX, uint32_t blockY, int csp, uint32_t qgSize)
141
{
142
143
curFrame->m_lowres.wp_sum[y] = 0;
144
}
145
146
- /* Calculate Qp offset for each 16x16 or 8x8 block in the frame */
147
- if ((param->rc.aqMode == X265_AQ_NONE || param->rc.aqStrength == 0) || (param->rc.bStatRead && param->rc.cuTree && IS_REFERENCED(curFrame)))
148
+ if (!(param->rc.bStatRead && param->rc.cuTree && IS_REFERENCED(curFrame)))
149
{
150
- if (param->rc.aqMode && param->rc.aqStrength == 0)
151
+ /* Calculate Qp offset for each 16x16 or 8x8 block in the frame */
152
+ if (param->rc.aqMode == X265_AQ_NONE || param->rc.aqStrength == 0)
153
{
154
- if (quantOffsets)
155
+ if (param->rc.aqMode && param->rc.aqStrength == 0)
156
{
157
- for (int cuxy = 0; cuxy < blockCount; cuxy++)
158
+ if (quantOffsets)
159
+ {
160
+ for (int cuxy = 0; cuxy < blockCount; cuxy++)
161
+ {
162
+ curFrame->m_lowres.qpCuTreeOffset[cuxy] = curFrame->m_lowres.qpAqOffset[cuxy] = quantOffsets[cuxy];
163
+ curFrame->m_lowres.invQscaleFactor[cuxy] = x265_exp2fix8(curFrame->m_lowres.qpCuTreeOffset[cuxy]);
164
+ }
165
+ }
166
+ else
167
{
168
- curFrame->m_lowres.qpCuTreeOffset[cuxy] = curFrame->m_lowres.qpAqOffset[cuxy] = quantOffsets[cuxy];
169
- curFrame->m_lowres.invQscaleFactor[cuxy] = x265_exp2fix8(curFrame->m_lowres.qpCuTreeOffset[cuxy]);
170
+ memset(curFrame->m_lowres.qpCuTreeOffset, 0, blockCount * sizeof(double));
171
+ memset(curFrame->m_lowres.qpAqOffset, 0, blockCount * sizeof(double));
172
+ for (int cuxy = 0; cuxy < blockCount; cuxy++)
173
+ curFrame->m_lowres.invQscaleFactor[cuxy] = 256;
174
}
175
}
176
- else
177
+
178
+ /* Need variance data for weighted prediction and dynamic refinement*/
179
+ if (param->bEnableWeightedPred || param->bEnableWeightedBiPred)
180
{
181
- memset(curFrame->m_lowres.qpCuTreeOffset, 0, blockCount * sizeof(double));
182
- memset(curFrame->m_lowres.qpAqOffset, 0, blockCount * sizeof(double));
183
- for (int cuxy = 0; cuxy < blockCount; cuxy++)
184
- curFrame->m_lowres.invQscaleFactor[cuxy] = 256;
185
+ for (int blockY = 0; blockY < maxRow; blockY += loopIncr)
186
+ for (int blockX = 0; blockX < maxCol; blockX += loopIncr)
187
+ acEnergyCu(curFrame, blockX, blockY, param->internalCsp, param->rc.qgSize);
188
}
189
}
190
-
191
- /* Need variance data for weighted prediction and dynamic refinement*/
192
- if (param->bEnableWeightedPred || param->bEnableWeightedBiPred)
193
- {
194
- for (int blockY = 0; blockY < maxRow; blockY += loopIncr)
195
- for (int blockX = 0; blockX < maxCol; blockX += loopIncr)
196
- acEnergyCu(curFrame, blockX, blockY, param->internalCsp, param->rc.qgSize);
197
- }
198
- }
199
- else
200
- {
201
- if (param->rc.hevcAq)
202
- {
203
- // New method for calculating variance and qp offset
204
- xPreanalyze(curFrame);
205
- }
206
else
207
{
208
- int blockXY = 0;
209
- double avg_adj_pow2 = 0, avg_adj = 0, qp_adj = 0;
210
- double bias_strength = 0.f;
211
- double strength = 0.f;
212
- if (param->rc.aqMode == X265_AQ_AUTO_VARIANCE || param->rc.aqMode == X265_AQ_AUTO_VARIANCE_BIASED)
213
+ if (param->rc.hevcAq)
214
+ {
215
+ // New method for calculating variance and qp offset
216
+ xPreanalyze(curFrame);
217
+ }
218
+ else
219
{
220
- double bit_depth_correction = 1.f / (1 << (2 * (X265_DEPTH - 8)));
221
+#define AQ_EDGE_BIAS 0.5
222
+#define EDGE_INCLINATION 45
223
+ uint32_t numCuInHeight = (maxRow + param->maxCUSize - 1) / param->maxCUSize;
224
+ int maxHeight = numCuInHeight * param->maxCUSize;
225
+ intptr_t stride = curFrame->m_fencPic->m_stride;
226
+ pixel *edgePic = X265_MALLOC(pixel, stride * (maxHeight + (curFrame->m_fencPic->m_lumaMarginY * 2)));
227
+ pixel *gaussianPic = X265_MALLOC(pixel, stride * (maxHeight + (curFrame->m_fencPic->m_lumaMarginY * 2)));
228
+ pixel *thetaPic = X265_MALLOC(pixel, stride * (maxHeight + (curFrame->m_fencPic->m_lumaMarginY * 2)));
229
+ memset(edgePic, 0, stride * (maxHeight + (curFrame->m_fencPic->m_lumaMarginY * 2)) * sizeof(pixel));
230
+ memset(gaussianPic, 0, stride * (maxHeight + (curFrame->m_fencPic->m_lumaMarginY * 2)) * sizeof(pixel));
231
+ memset(thetaPic, 0, stride * (maxHeight + (curFrame->m_fencPic->m_lumaMarginY * 2)) * sizeof(pixel));
232
+ if (param->rc.aqMode == X265_AQ_EDGE)
233
+ edgeFilter(curFrame, edgePic, gaussianPic, thetaPic, stride, maxRow, maxCol);
234
+
235
+ int blockXY = 0, inclinedEdge = 0;
236
+ double avg_adj_pow2 = 0, avg_adj = 0, qp_adj = 0;
237
+ double bias_strength = 0.f;
238
+ double strength = 0.f;
239
+ if (param->rc.aqMode == X265_AQ_AUTO_VARIANCE || param->rc.aqMode == X265_AQ_AUTO_VARIANCE_BIASED || param->rc.aqMode == X265_AQ_EDGE)
240
+ {
241
+ double bit_depth_correction = 1.f / (1 << (2 * (X265_DEPTH - 8)));
242
+ for (int blockY = 0; blockY < maxRow; blockY += loopIncr)
243
+ {
244
+ for (int blockX = 0; blockX < maxCol; blockX += loopIncr)
245
+ {
246
+ uint32_t energy, edgeDensity, avgAngle;
247
+ energy = acEnergyCu(curFrame, blockX, blockY, param->internalCsp, param->rc.qgSize);
248
+ if (param->rc.aqMode == X265_AQ_EDGE)
249
+ {
250
+ pixel *edgeImage = edgePic + curFrame->m_fencPic->m_lumaMarginY * stride + curFrame->m_fencPic->m_lumaMarginX;
251
+ pixel *edgeTheta = thetaPic + curFrame->m_fencPic->m_lumaMarginY * stride + curFrame->m_fencPic->m_lumaMarginX;
252
+ edgeDensity = edgeDensityCu(curFrame, edgeImage, edgeTheta, avgAngle, blockX, blockY, param->rc.qgSize);
253
+ if (edgeDensity)
254
+ {
255
+ qp_adj = pow(edgeDensity * bit_depth_correction + 1, 0.1);
256
+ //Increasing the QP of a block if its edge orientation lies around the multiples of 45 degree
257
+ if ((avgAngle >= EDGE_INCLINATION - 15 && avgAngle <= EDGE_INCLINATION + 15) || (avgAngle >= EDGE_INCLINATION + 75 && avgAngle <= EDGE_INCLINATION + 105))
258
+ curFrame->m_lowres.edgeInclined[blockXY] = 1;
259
+ else
260
+ curFrame->m_lowres.edgeInclined[blockXY] = 0;
261
+ }
262
+ else
263
+ {
264
+ qp_adj = pow(energy * bit_depth_correction + 1, 0.1);
265
+ curFrame->m_lowres.edgeInclined[blockXY] = 0;
266
+ }
267
+ }
268
+ else
269
+ qp_adj = pow(energy * bit_depth_correction + 1, 0.1);
270
+ curFrame->m_lowres.qpCuTreeOffset[blockXY] = qp_adj;
271
+ avg_adj += qp_adj;
272
+ avg_adj_pow2 += qp_adj * qp_adj;
273
+ blockXY++;
274
+ }
275
+ }
276
+ avg_adj /= blockCount;
277
+ avg_adj_pow2 /= blockCount;
278
+ strength = param->rc.aqStrength * avg_adj;
279
+ avg_adj = avg_adj - 0.5f * (avg_adj_pow2 - modeTwoConst) / avg_adj;
280
+ bias_strength = param->rc.aqStrength;
281
+ }
282
+ else
283
+ strength = param->rc.aqStrength * 1.0397f;
284
285
+ X265_FREE(edgePic);
286
+ X265_FREE(gaussianPic);
287
+ X265_FREE(thetaPic);
288
+ blockXY = 0;
289
for (int blockY = 0; blockY < maxRow; blockY += loopIncr)
290
{
291
for (int blockX = 0; blockX < maxCol; blockX += loopIncr)
292
{
293
- uint32_t energy = acEnergyCu(curFrame, blockX, blockY, param->internalCsp, param->rc.qgSize);
294
- qp_adj = pow(energy * bit_depth_correction + 1, 0.1);
295
+ if (param->rc.aqMode == X265_AQ_AUTO_VARIANCE_BIASED)
296
+ {
297
+ qp_adj = curFrame->m_lowres.qpCuTreeOffset[blockXY];
298
+ qp_adj = strength * (qp_adj - avg_adj) + bias_strength * (1.f - modeTwoConst / (qp_adj * qp_adj));
299
+ }
300
+ else if (param->rc.aqMode == X265_AQ_AUTO_VARIANCE)
301
+ {
302
+ qp_adj = curFrame->m_lowres.qpCuTreeOffset[blockXY];
303
+ qp_adj = strength * (qp_adj - avg_adj);
304
+ }
305
+ else if (param->rc.aqMode == X265_AQ_EDGE)
306
+ {
307
+ inclinedEdge = curFrame->m_lowres.edgeInclined[blockXY];
308
+ qp_adj = curFrame->m_lowres.qpCuTreeOffset[blockXY];
309
+ if(inclinedEdge && (qp_adj - avg_adj > 0))
310
+ qp_adj = ((strength + AQ_EDGE_BIAS) * (qp_adj - avg_adj));
311
+ else
312
+ qp_adj = strength * (qp_adj - avg_adj);
313
+ }
314
+ else
315
+ {
316
+ uint32_t energy = acEnergyCu(curFrame, blockX, blockY, param->internalCsp, param->rc.qgSize);
317
+ qp_adj = strength * (X265_LOG2(X265_MAX(energy, 1)) - (modeOneConst + 2 * (X265_DEPTH - 8)));
318
+ }
319
+
320
+ if (param->bHDROpt)
321
+ {
322
+ uint32_t sum = lumaSumCu(curFrame, blockX, blockY, param->rc.qgSize);
323
+ uint32_t lumaAvg = sum / (loopIncr * loopIncr);
324
+ if (lumaAvg < 301)
325
+ qp_adj += 3;
326
+ else if (lumaAvg >= 301 && lumaAvg < 367)
327
+ qp_adj += 2;
328
+ else if (lumaAvg >= 367 && lumaAvg < 434)
329
+ qp_adj += 1;
330
+ else if (lumaAvg >= 501 && lumaAvg < 567)
331
+ qp_adj -= 1;
332
+ else if (lumaAvg >= 567 && lumaAvg < 634)
333
+ qp_adj -= 2;
334
+ else if (lumaAvg >= 634 && lumaAvg < 701)
335
+ qp_adj -= 3;
336
+ else if (lumaAvg >= 701 && lumaAvg < 767)
337
+ qp_adj -= 4;
338
+ else if (lumaAvg >= 767 && lumaAvg < 834)
339
+ qp_adj -= 5;
340
+ else if (lumaAvg >= 834)
341
+ qp_adj -= 6;
342
+ }
343
+ if (quantOffsets != NULL)
344
+ qp_adj += quantOffsets[blockXY];
345
+ curFrame->m_lowres.qpAqOffset[blockXY] = qp_adj;
346
curFrame->m_lowres.qpCuTreeOffset[blockXY] = qp_adj;
347
- avg_adj += qp_adj;
348
- avg_adj_pow2 += qp_adj * qp_adj;
349
+ curFrame->m_lowres.invQscaleFactor[blockXY] = x265_exp2fix8(qp_adj);
350
blockXY++;
351
}
352
}
353
- avg_adj /= blockCount;
354
- avg_adj_pow2 /= blockCount;
355
- strength = param->rc.aqStrength * avg_adj;
356
- avg_adj = avg_adj - 0.5f * (avg_adj_pow2 - modeTwoConst) / avg_adj;
357
- bias_strength = param->rc.aqStrength;
358
}
359
- else
360
- strength = param->rc.aqStrength * 1.0397f;
361
+ }
362
363
- blockXY = 0;
364
- for (int blockY = 0; blockY < maxRow; blockY += loopIncr)
365
+ if (param->rc.qgSize == 8)
366
+ {
367
+ for (int cuY = 0; cuY < heightInCU; cuY++)
368
{
369
- for (int blockX = 0; blockX < maxCol; blockX += loopIncr)
370
+ for (int cuX = 0; cuX < widthInCU; cuX++)
371
{
372
- if (param->rc.aqMode == X265_AQ_AUTO_VARIANCE_BIASED)
373
- {
374
- qp_adj = curFrame->m_lowres.qpCuTreeOffset[blockXY];
375
- qp_adj = strength * (qp_adj - avg_adj) + bias_strength * (1.f - modeTwoConst / (qp_adj * qp_adj));
376
- }
377
- else if (param->rc.aqMode == X265_AQ_AUTO_VARIANCE)
378
- {
379
- qp_adj = curFrame->m_lowres.qpCuTreeOffset[blockXY];
380
- qp_adj = strength * (qp_adj - avg_adj);
381
- }
382
- else
383
- {
384
- uint32_t energy = acEnergyCu(curFrame, blockX, blockY, param->internalCsp, param->rc.qgSize);
385
- qp_adj = strength * (X265_LOG2(X265_MAX(energy, 1)) - (modeOneConst + 2 * (X265_DEPTH - 8)));
386
- }
387
-
388
- if (param->bHDROpt)
389
- {
390
- uint32_t sum = lumaSumCu(curFrame, blockX, blockY, param->rc.qgSize);
391
- uint32_t lumaAvg = sum / (loopIncr * loopIncr);
392
- if (lumaAvg < 301)
393
- qp_adj += 3;
394
- else if (lumaAvg >= 301 && lumaAvg < 367)
395
- qp_adj += 2;
396
- else if (lumaAvg >= 367 && lumaAvg < 434)
397
- qp_adj += 1;
398
- else if (lumaAvg >= 501 && lumaAvg < 567)
399
- qp_adj -= 1;
400
- else if (lumaAvg >= 567 && lumaAvg < 634)
401
- qp_adj -= 2;
402
- else if (lumaAvg >= 634 && lumaAvg < 701)
403
- qp_adj -= 3;
404
- else if (lumaAvg >= 701 && lumaAvg < 767)
405
- qp_adj -= 4;
406
- else if (lumaAvg >= 767 && lumaAvg < 834)
407
- qp_adj -= 5;
408
- else if (lumaAvg >= 834)
409
- qp_adj -= 6;
410
- }
411
- if (quantOffsets != NULL)
412
- qp_adj += quantOffsets[blockXY];
413
- curFrame->m_lowres.qpAqOffset[blockXY] = qp_adj;
414
- curFrame->m_lowres.qpCuTreeOffset[blockXY] = qp_adj;
415
- curFrame->m_lowres.invQscaleFactor[blockXY] = x265_exp2fix8(qp_adj);
416
- blockXY++;
417
+ const int cuXY = cuX + cuY * widthInCU;
418
+ curFrame->m_lowres.invQscaleFactor8x8[cuXY] = (curFrame->m_lowres.invQscaleFactor[cuX * 2 + cuY * widthInCU * 4] +
419
+ curFrame->m_lowres.invQscaleFactor[cuX * 2 + cuY * widthInCU * 4 + 1] +
420
+ curFrame->m_lowres.invQscaleFactor[cuX * 2 + cuY * widthInCU * 4 + curFrame->m_lowres.maxBlocksInRowFullRes] +
421
+ curFrame->m_lowres.invQscaleFactor[cuX * 2 + cuY * widthInCU * 4 + curFrame->m_lowres.maxBlocksInRowFullRes + 1]) / 4;
422
}
423
}
424
}
425
}
426
427
- if (param->rc.qgSize == 8)
428
+ if (param->bEnableWeightedPred || param->bEnableWeightedBiPred)
429
{
430
- for (int cuY = 0; cuY < heightInCU; cuY++)
431
+ if (param->rc.bStatRead && param->rc.cuTree && IS_REFERENCED(curFrame))
432
{
433
- for (int cuX = 0; cuX < widthInCU; cuX++)
434
- {
435
- const int cuXY = cuX + cuY * widthInCU;
436
- curFrame->m_lowres.invQscaleFactor8x8[cuXY] = (curFrame->m_lowres.invQscaleFactor[cuX * 2 + cuY * widthInCU * 4] +
437
- curFrame->m_lowres.invQscaleFactor[cuX * 2 + cuY * widthInCU * 4 + 1] +
438
- curFrame->m_lowres.invQscaleFactor[cuX * 2 + cuY * widthInCU * 4 + curFrame->m_lowres.maxBlocksInRowFullRes] +
439
- curFrame->m_lowres.invQscaleFactor[cuX * 2 + cuY * widthInCU * 4 + curFrame->m_lowres.maxBlocksInRowFullRes + 1]) / 4;
440
- }
441
+ for (int blockY = 0; blockY < maxRow; blockY += loopIncr)
442
+ for (int blockX = 0; blockX < maxCol; blockX += loopIncr)
443
+ acEnergyCu(curFrame, blockX, blockY, param->internalCsp, param->rc.qgSize);
444
}
445
- }
446
447
- if (param->bEnableWeightedPred || param->bEnableWeightedBiPred)
448
- {
449
int hShift = CHROMA_H_SHIFT(param->internalCsp);
450
int vShift = CHROMA_V_SHIFT(param->internalCsp);
451
maxCol = ((maxCol + 8) >> 4) << 4;
452
453
weightedRef.lumaStride = fenc.lumaStride;
454
weightedRef.isLowres = true;
455
weightedRef.isWeighted = false;
456
+ weightedRef.isHMELowres = ref.bEnableHME;
457
458
/* epsilon is chosen to require at least a numerator of 127 (with denominator = 128) */
459
float guessScale, fencMean, refMean;
460
461
m_extendGopBoundary = false;
462
m_8x8Height = ((m_param->sourceHeight / 2) + X265_LOWRES_CU_SIZE - 1) >> X265_LOWRES_CU_BITS;
463
m_8x8Width = ((m_param->sourceWidth / 2) + X265_LOWRES_CU_SIZE - 1) >> X265_LOWRES_CU_BITS;
464
+ m_4x4Height = ((m_param->sourceHeight / 4) + X265_LOWRES_CU_SIZE - 1) >> X265_LOWRES_CU_BITS;
465
+ m_4x4Width = ((m_param->sourceWidth / 4) + X265_LOWRES_CU_SIZE - 1) >> X265_LOWRES_CU_BITS;
466
m_cuCount = m_8x8Width * m_8x8Height;
467
m_8x8Blocks = m_8x8Width > 2 && m_8x8Height > 2 ? (m_cuCount + 4 - 2 * (m_8x8Width + m_8x8Height)) : m_cuCount;
468
m_isFadeIn = false;
469
470
ProfileScopeEvent(prelookahead);
471
m_lock.release();
472
preFrame->m_lowres.init(preFrame->m_fencPic, preFrame->m_poc);
473
- if (m_lookahead.m_param->rc.bStatRead && m_lookahead.m_param->rc.cuTree && IS_REFERENCED(preFrame))
474
- /* cu-tree offsets were read from stats file */;
475
- else if (m_lookahead.m_bAdaptiveQuant)
476
+ if (m_lookahead.m_bAdaptiveQuant)
477
tld.calcAdaptiveQuantFrame(preFrame, m_lookahead.m_param);
478
tld.lowresIntraEstimate(preFrame->m_lowres, m_lookahead.m_param->rc.qgSize);
479
preFrame->m_lowresInit = true;
480
481
482
X265_CHECK(i < MAX_COOP_SLICES, "impossible number of coop slices\n");
483
484
- int firstY = m_lookahead.m_numRowsPerSlice * i;
485
- int lastY = (i == m_jobTotal - 1) ? m_lookahead.m_8x8Height - 1 : m_lookahead.m_numRowsPerSlice * (i + 1) - 1;
486
+ int firstY, lastY;
487
+ bool lastRow;
488
+ if (m_lookahead.m_param->bEnableHME)
489
+ {
490
+ int numRowsPerSlice = m_lookahead.m_4x4Height / m_lookahead.m_param->lookaheadSlices;
491
+ numRowsPerSlice = X265_MIN(X265_MAX(numRowsPerSlice, 5), m_lookahead.m_4x4Height);
492
+ firstY = numRowsPerSlice * i;
493
+ lastY = (i == m_jobTotal - 1) ? m_lookahead.m_4x4Height - 1 : numRowsPerSlice * (i + 1) - 1;
494
+ lastRow = true;
495
+ for (int cuY = lastY; cuY >= firstY; cuY--)
496
+ {
497
+ for (int cuX = m_lookahead.m_4x4Width - 1; cuX >= 0; cuX--)
498
+ estimateCUCost(tld, cuX, cuY, m_coop.p0, m_coop.p1, m_coop.b, m_coop.bDoSearch, lastRow, i, 1);
499
+ lastRow = false;
500
+ }
501
+ }
502
503
- bool lastRow = true;
504
+ firstY = m_lookahead.m_numRowsPerSlice * i;
505
+ lastY = (i == m_jobTotal - 1) ? m_lookahead.m_8x8Height - 1 : m_lookahead.m_numRowsPerSlice * (i + 1) - 1;
506
+ lastRow = true;
507
for (int cuY = lastY; cuY >= firstY; cuY--)
508
{
509
m_frames[m_coop.b]->rowSatds[m_coop.b - m_coop.p0][m_coop.p1 - m_coop.b][cuY] = 0;
510
511
for (int cuX = m_lookahead.m_8x8Width - 1; cuX >= 0; cuX--)
512
- estimateCUCost(tld, cuX, cuY, m_coop.p0, m_coop.p1, m_coop.b, m_coop.bDoSearch, lastRow, i);
513
+ estimateCUCost(tld, cuX, cuY, m_coop.p0, m_coop.p1, m_coop.b, m_coop.bDoSearch, lastRow, i, 0);
514
515
lastRow = false;
516
}
517
518
}
519
else
520
{
521
- bool lastRow = true;
522
+ /* Calculate MVs for 1/16th resolution*/
523
+ bool lastRow;
524
+ if (param->bEnableHME)
525
+ {
526
+ lastRow = true;
527
+ for (int cuY = m_lookahead.m_4x4Height - 1; cuY >= 0; cuY--)
528
+ {
529
+ for (int cuX = m_lookahead.m_4x4Width - 1; cuX >= 0; cuX--)
530
+ estimateCUCost(tld, cuX, cuY, p0, p1, b, bDoSearch, lastRow, -1, 1);
531
+ lastRow = false;
532
+ }
533
+ }
534
+ lastRow = true;
535
for (int cuY = m_lookahead.m_8x8Height - 1; cuY >= 0; cuY--)
536
{
537
fenc->rowSatds[b - p0][p1 - b][cuY] = 0;
538
539
for (int cuX = m_lookahead.m_8x8Width - 1; cuX >= 0; cuX--)
540
- estimateCUCost(tld, cuX, cuY, p0, p1, b, bDoSearch, lastRow, -1);
541
+ estimateCUCost(tld, cuX, cuY, p0, p1, b, bDoSearch, lastRow, -1, 0);
542
543
lastRow = false;
544
}
545
546
return score;
547
}
548
549
-void CostEstimateGroup::estimateCUCost(LookaheadTLD& tld, int cuX, int cuY, int p0, int p1, int b, bool bDoSearch[2], bool lastRow, int slice)
550
+void CostEstimateGroup::estimateCUCost(LookaheadTLD& tld, int cuX, int cuY, int p0, int p1, int b, bool bDoSearch[2], bool lastRow, int slice, bool hme)
551
{
552
Lowres *fref0 = m_frames[p0];
553
Lowres *fref1 = m_frames[p1];
554
Lowres *fenc = m_frames[b];
555
556
- ReferencePlanes *wfref0 = fenc->weightedRef[b - p0].isWeighted ? &fenc->weightedRef[b - p0] : fref0;
557
+ ReferencePlanes *wfref0 = fenc->weightedRef[b - p0].isWeighted && !hme ? &fenc->weightedRef[b - p0] : fref0;
558
559
- const int widthInCU = m_lookahead.m_8x8Width;
560
- const int heightInCU = m_lookahead.m_8x8Height;
561
+ const int widthInCU = hme ? m_lookahead.m_4x4Width : m_lookahead.m_8x8Width;
562
+ const int heightInCU = hme ? m_lookahead.m_4x4Height : m_lookahead.m_8x8Height;
563
const int bBidir = (b < p1);
564
const int cuXY = cuX + cuY * widthInCU;
565
+ const int cuXY_4x4 = (cuX / 2) + (cuY / 2) * widthInCU / 2;
566
const int cuSize = X265_LOWRES_CU_SIZE;
567
- const intptr_t pelOffset = cuSize * cuX + cuSize * cuY * fenc->lumaStride;
568
+ const intptr_t pelOffset = cuSize * cuX + cuSize * cuY * (hme ? fenc->lumaStride/2 : fenc->lumaStride);
569
+
570
+ if ((bBidir || bDoSearch[0] || bDoSearch[1]) && hme)
571
+ tld.me.setSourcePU(fenc->lowerResPlane[0], fenc->lumaStride / 2, pelOffset, cuSize, cuSize, X265_HEX_SEARCH, m_lookahead.m_param->hmeSearchMethod[0], m_lookahead.m_param->hmeSearchMethod[1], 1);
572
+ else if((bBidir || bDoSearch[0] || bDoSearch[1]) && !hme)
573
+ tld.me.setSourcePU(fenc->lowresPlane[0], fenc->lumaStride, pelOffset, cuSize, cuSize, X265_HEX_SEARCH, m_lookahead.m_param->hmeSearchMethod[0], m_lookahead.m_param->hmeSearchMethod[1], 1);
574
575
- if (bBidir || bDoSearch[0] || bDoSearch[1])
576
- tld.me.setSourcePU(fenc->lowresPlane[0], fenc->lumaStride, pelOffset, cuSize, cuSize, X265_HEX_SEARCH, 1);
577
578
/* A small, arbitrary bias to avoid VBV problems caused by zero-residual lookahead blocks. */
579
int lowresPenalty = 4;
580
581
582
for (int i = 0; i < 1 + bBidir; i++)
583
{
584
- int& fencCost = fenc->lowresMvCosts[i][listDist[i]][cuXY];
585
+ int& fencCost = hme ? fenc->lowerResMvCosts[i][listDist[i]][cuXY] : fenc->lowresMvCosts[i][listDist[i]][cuXY];
586
int skipCost = INT_MAX;
587
588
if (!bDoSearch[i])
589
590
}
591
592
int numc = 0;
593
- MV mvc[4], mvp;
594
- MV* fencMV = &fenc->lowresMvs[i][listDist[i]][cuXY];
595
+ MV mvc[5], mvp;
596
+ MV* fencMV = hme ? &fenc->lowerResMvs[i][listDist[i]][cuXY] : &fenc->lowresMvs[i][listDist[i]][cuXY];
597
ReferencePlanes* fref = i ? fref1 : wfref0;
598
599
/* Reverse-order MV prediction */
600
601
if (cuX < widthInCU - 1)
602
MVC(fencMV[widthInCU + 1]);
603
}
604
+ if (fenc->lowerResMvs[0][0] && !hme && fenc->lowerResMvCosts[i][listDist[i]][cuXY_4x4] > 0)
605
+ {
606
+ MVC((fenc->lowerResMvs[i][listDist[i]][cuXY_4x4]) * 2);
607
+ }
608
#undef MVC
609
610
if (!numc)
611
612
for (int idx = 0; idx < numc; idx++)
613
{
614
intptr_t stride = X265_LOWRES_CU_SIZE;
615
- pixel *src = fref->lowresMC(pelOffset, mvc[idx], subpelbuf, stride);
616
+ pixel *src = fref->lowresMC(pelOffset, mvc[idx], subpelbuf, stride, hme);
617
int cost = tld.me.bufSATD(src, stride);
618
COPY2_IF_LT(mvpcost, cost, mvp, mvc[idx]);
619
/* Except for mv0 case, everyting else is likely to have enough residual to not trigger the skip. */
620
621
622
/* ME will never return a cost larger than the cost @MVP, so we do not
623
* have to check that ME cost is more than the estimated merge cost */
624
- fencCost = tld.me.motionEstimate(fref, mvmin, mvmax, mvp, 0, NULL, s_merange, *fencMV, m_lookahead.m_param->maxSlices);
625
+ if(!hme)
626
+ fencCost = tld.me.motionEstimate(fref, mvmin, mvmax, mvp, 0, NULL, s_merange, *fencMV, m_lookahead.m_param->maxSlices);
627
+ else
628
+ fencCost = tld.me.motionEstimate(fref, mvmin, mvmax, mvp, 0, NULL, s_merange, *fencMV, m_lookahead.m_param->maxSlices, fref->lowerResPlane[0]);
629
if (skipCost < 64 && skipCost < fencCost && bBidir)
630
{
631
fencCost = skipCost;
632
633
}
634
COPY2_IF_LT(bcost, fencCost, listused, i + 1);
635
}
636
+ if (hme)
637
+ return;
638
639
if (bBidir) /* B, also consider bidir */
640
{
641
642
ALIGN_VAR_32(pixel, subpelbuf0[X265_LOWRES_CU_SIZE * X265_LOWRES_CU_SIZE]);
643
ALIGN_VAR_32(pixel, subpelbuf1[X265_LOWRES_CU_SIZE * X265_LOWRES_CU_SIZE]);
644
intptr_t stride0 = X265_LOWRES_CU_SIZE, stride1 = X265_LOWRES_CU_SIZE;
645
- pixel *src0 = fref0->lowresMC(pelOffset, fenc->lowresMvs[0][listDist[0]][cuXY], subpelbuf0, stride0);
646
- pixel *src1 = fref1->lowresMC(pelOffset, fenc->lowresMvs[1][listDist[1]][cuXY], subpelbuf1, stride1);
647
+ pixel *src0 = fref0->lowresMC(pelOffset, fenc->lowresMvs[0][listDist[0]][cuXY], subpelbuf0, stride0, 0);
648
+ pixel *src1 = fref1->lowresMC(pelOffset, fenc->lowresMvs[1][listDist[1]][cuXY], subpelbuf1, stride1, 0);
649
ALIGN_VAR_32(pixel, ref[X265_LOWRES_CU_SIZE * X265_LOWRES_CU_SIZE]);
650
primitives.pu[LUMA_8x8].pixelavg_pp[NONALIGNED](ref, X265_LOWRES_CU_SIZE, src0, stride0, src1, stride1, 32);
651
int bicost = tld.me.bufSATD(ref, X265_LOWRES_CU_SIZE);
652
x265_3.1.2.tar.gz/source/encoder/slicetype.h -> x265_3.2.tar.gz/source/encoder/slicetype.h
Changed
29
1
2
protected:
3
4
uint32_t acEnergyCu(Frame* curFrame, uint32_t blockX, uint32_t blockY, int csp, uint32_t qgSize);
5
+ uint32_t edgeDensityCu(Frame*curFrame, pixel *edgeImage, pixel *edgeTheta, uint32_t &avgAngle, uint32_t blockX, uint32_t blockY, uint32_t qgSize);
6
uint32_t lumaSumCu(Frame* curFrame, uint32_t blockX, uint32_t blockY, uint32_t qgSize);
7
uint32_t weightCostLuma(Lowres& fenc, Lowres& ref, WeightParam& wp);
8
bool allocWeightedRef(Lowres& fenc);
9
10
int m_inputCount;
11
double m_cuTreeStrength;
12
13
+ /* HME */
14
+ int m_4x4Width;
15
+ int m_4x4Height;
16
+
17
bool m_isActive;
18
bool m_sliceTypeBusy;
19
bool m_bAdaptiveQuant;
20
21
void processTasks(int workerThreadID);
22
23
int64_t estimateFrameCost(LookaheadTLD& tld, int p0, int p1, int b, bool intraPenalty);
24
- void estimateCUCost(LookaheadTLD& tld, int cux, int cuy, int p0, int p1, int b, bool bDoSearch[2], bool lastRow, int slice);
25
+ void estimateCUCost(LookaheadTLD& tld, int cux, int cuy, int p0, int p1, int b, bool bDoSearch[2], bool lastRow, int slice, bool hme);
26
27
CostEstimateGroup& operator=(const CostEstimateGroup&);
28
};
29
x265_3.1.2.tar.gz/source/encoder/weightPrediction.cpp -> x265_3.2.tar.gz/source/encoder/weightPrediction.cpp
Changed
10
1
2
/* clip MV to available pixels */
3
MV mv = mvs[cu];
4
mv = mv.clipped(mvmin, mvmax);
5
- pixel *tmp = ref.lowresMC(pixoff, mv, buf8x8, bstride);
6
+ pixel *tmp = ref.lowresMC(pixoff, mv, buf8x8, bstride, 0);
7
primitives.cu[BLOCK_8x8].copy_pp(mcout + pixoff, stride, tmp, bstride);
8
}
9
}
10
x265_3.1.2.tar.gz/source/test/regression-tests.txt -> x265_3.2.tar.gz/source/test/regression-tests.txt
Changed
11
1
2
big_buck_bunny_360p24.y4m, --keyint 60 --min-keyint 40 --gop-lookahead 14
3
BasketballDrive_1920x1080_50.y4m, --preset medium --no-open-gop --keyint 50 --min-keyint 50 --radl 2 --vbv-maxrate 5000 --vbv-bufsize 5000
4
big_buck_bunny_360p24.y4m, --bitrate 500 --fades
5
+720p50_parkrun_ter.y4m,--preset medium --bitrate 400 --hme
6
+ducks_take_off_420_1_720p50.y4m,--preset medium --aq-mode 4 --crf 22 --no-cutree
7
+ducks_take_off_420_1_720p50.y4m,--preset medium --selective-sao 4 --sao --crf 20
8
9
# Main12 intraCost overflow bug test
10
720p50_parkrun_ter.y4m,--preset medium
11
x265_3.1.2.tar.gz/source/x265.h -> x265_3.2.tar.gz/source/x265.h
Changed
37
1
2
#define X265_AQ_VARIANCE 1
3
#define X265_AQ_AUTO_VARIANCE 2
4
#define X265_AQ_AUTO_VARIANCE_BIASED 3
5
+#define X265_AQ_EDGE 4
6
#define x265_ADAPT_RD_STRENGTH 4
7
#define X265_REFINE_INTER_LEVELS 3
8
/* NOTE! For this release only X265_CSP_I420 and X265_CSP_I444 are supported */
9
10
/* Enable availability of temporal motion vector for AMVP, default is enabled */
11
int bEnableTemporalMvp;
12
13
+ /* Enable 3-level Hierarchical motion estimation at One-Sixteenth, Quarter and Full resolution.
14
+ * Default is disabled */
15
+ int bEnableHME;
16
+
17
+ /* Enable HME search method (DIA, HEX, UMH, STAR, SEA, FULL) for level 0, 1 and 2.
18
+ * Default is hex, umh, umh for L0, L1 and L2 respectively. */
19
+ int hmeSearchMethod[3];
20
+
21
/* Enable weighted prediction in P slices. This enables weighting analysis
22
* in the lookahead, which influences slice decisions, and enables weighting
23
* analysis in the main encoder which allows P reference samples to have a
24
25
* non-deblocked pixels are used entirely. Default is disabled */
26
int bSaoNonDeblocked;
27
28
+ /* Select tune rate in which SAO has to be applied.
29
+ 1 - Filtering applied only on I-frames(I) [Light tune]
30
+ 2 - No Filtering on B frames (I, P) [Medium tune]
31
+ 3 - No Filtering on non-ref b frames (I, P, B) [Strong tune] */
32
+ int selectiveSAO;
33
+
34
/*== Analysis tools ==*/
35
36
/* A value between 1 and 6 (both inclusive) which determines the level of
37
x265_3.1.2.tar.gz/source/x265cli.h -> x265_3.2.tar.gz/source/x265cli.h
Changed
66
1
2
{ "max-merge", required_argument, NULL, 0 },
3
{ "no-temporal-mvp", no_argument, NULL, 0 },
4
{ "temporal-mvp", no_argument, NULL, 0 },
5
+ { "hme", no_argument, NULL, 0 },
6
+ { "no-hme", no_argument, NULL, 0 },
7
+ { "hme-search", required_argument, NULL, 0 },
8
{ "rdpenalty", required_argument, NULL, 0 },
9
{ "no-rect", no_argument, NULL, 0 },
10
{ "rect", no_argument, NULL, 0 },
11
12
{ "no-deblock", no_argument, NULL, 0 },
13
{ "deblock", required_argument, NULL, 0 },
14
{ "no-sao", no_argument, NULL, 0 },
15
+ { "selective-sao", required_argument, NULL, 0 },
16
{ "sao", no_argument, NULL, 0 },
17
{ "no-sao-non-deblock", no_argument, NULL, 0 },
18
{ "sao-non-deblock", no_argument, NULL, 0 },
19
20
{ "dhdr10-opt", no_argument, NULL, 0},
21
{ "no-dhdr10-opt", no_argument, NULL, 0},
22
{ "dolby-vision-profile", required_argument, NULL, 0 },
23
- { "refine-mv", no_argument, NULL, 0 },
24
- { "no-refine-mv", no_argument, NULL, 0 },
25
+ { "refine-mv", required_argument, NULL, 0 },
26
{ "refine-ctu-distortion", required_argument, NULL, 0 },
27
{ "force-flush", required_argument, NULL, 0 },
28
{ "splitrd-skip", no_argument, NULL, 0 },
29
30
H0(" --[no-]amp Enable asymmetric motion partitions, requires --rect. Default %s\n", OPT(param->bEnableAMP));
31
H0(" --[no-]limit-modes Limit rectangular and asymmetric motion predictions. Default %d\n", param->limitModes);
32
H1(" --[no-]temporal-mvp Enable temporal MV predictors. Default %s\n", OPT(param->bEnableTemporalMvp));
33
+ H1(" --[no-]hme Enable Hierarchical Motion Estimation. Default %s\n", OPT(param->bEnableHME));
34
+ H1(" --hme-search <string> Motion search-method for HME L0,L1 and L2. Default(L0,L1,L2) is %d,%d,%d\n", param->hmeSearchMethod[0], param->hmeSearchMethod[1], param->hmeSearchMethod[2]);
35
H0("\nSpatial / intra options:\n");
36
H0(" --[no-]strong-intra-smoothing Enable strong intra smoothing for 32x32 blocks. Default %s\n", OPT(param->bEnableStrongIntraSmoothing));
37
H0(" --[no-]constrained-intra Constrained intra prediction (use only intra coded reference pixels) Default %s\n", OPT(param->bEnableConstrainedIntra));
38
39
" - 3 : Functionality of (1) + irrespective of size evaluate all inter modes.\n"
40
" Default:%d\n", param->interRefine);
41
H0(" --[no-]dynamic-refine Dynamically changes refine-inter level for each CU. Default %s\n", OPT(param->bDynamicRefine));
42
- H0(" --[no-]refine-mv Enable mv refinement for load mode. Default %s\n", OPT(param->mvRefine));
43
+ H0(" --refine-mv <1..3> Enable mv refinement for load mode. Default %d\n", param->mvRefine);
44
H0(" --refine-ctu-distortion Store/normalize ctu distortion in analysis-save/load.\n"
45
" - 0 : Disabled.\n"
46
" - 1 : Store/Load ctu distortion to/from the file specified in analysis-save/load.\n"
47
" Default 0 - Disabled\n");
48
- 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);
49
+ H0(" --aq-mode <integer> Mode for Adaptive Quantization - 0:none 1:uniform AQ 2:auto variance 3:auto variance with bias to dark scenes 4:auto variance with edge information. Default %d\n", param->rc.aqMode);
50
H0(" --[no-]hevc-aq Mode for HEVC Adaptive Quantization. Default %s\n", OPT(param->rc.hevcAq));
51
H0(" --aq-strength <float> Reduces blocking and blurring in flat and textured areas (0 to 3.0). Default %.2f\n", param->rc.aqStrength);
52
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);
53
- H0(" --[no-]aq-motion Adaptive Quantization based on the relative motion of each CU w.r.t., frame. Default %s\n", OPT(param->bOptCUDeltaQP));
54
+ H0(" --[no-]aq-motion Block level QP adaptation based on the relative motion between the block and the frame. Default %s\n", OPT(param->bAQMotion));
55
H0(" --qg-size <int> Specifies the size of the quantization group (64, 32, 16, 8). Default %d\n", param->rc.qgSize);
56
H0(" --[no-]cutree Enable cutree for Adaptive Quantization. Default %s\n", OPT(param->rc.cuTree));
57
H0(" --[no-]rc-grain Enable ratecontrol mode to handle grains specifically. turned on with tune grain. Default %s\n", OPT(param->rc.bEnableGrain));
58
59
H0(" --[no-]sao Enable Sample Adaptive Offset. Default %s\n", OPT(param->bEnableSAO));
60
H1(" --[no-]sao-non-deblock Use non-deblocked pixels, else right/bottom boundary areas skipped. Default %s\n", OPT(param->bSaoNonDeblocked));
61
H0(" --[no-]limit-sao Limit Sample Adaptive Offset types. Default %s\n", OPT(param->bLimitSAO));
62
+ H0(" --selective-sao <int> Enable slice-level SAO filter. Default %d\n", param->selectiveSAO);
63
H0("\nVUI options:\n");
64
H0(" --sar <width:height|int> Sample Aspect Ratio, the ratio of width to height of an individual pixel.\n");
65
H0(" Choose from 0=undef, 1=1:1(\"square\"), 2=12:11, 3=10:11, 4=16:11,\n");
66
Refresh
x265
x86_64
aarch64
x86_64
aarch64
armv7l
Refresh
Login required, please
login
or
signup
in order to comment