Coverage Report

Created: 2022-08-24 06:17

/src/x265/source/encoder/analysis.h
Line
Count
Source (jump to first uncovered line)
1
/*****************************************************************************
2
* Copyright (C) 2013-2020 MulticoreWare, Inc
3
*
4
* Authors: Deepthi Nandakumar <deepthi@multicorewareinc.com>
5
*          Steve Borho <steve@borho.org>
6
*          Min Chen <chenm003@163.com>
7
*
8
* This program is free software; you can redistribute it and/or modify
9
* it under the terms of the GNU General Public License as published by
10
* the Free Software Foundation; either version 2 of the License, or
11
* (at your option) any later version.
12
*
13
* This program is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
* GNU General Public License for more details.
17
*
18
* You should have received a copy of the GNU General Public License
19
* along with this program; if not, write to the Free Software
20
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
21
*
22
* This program is also available under a commercial proprietary license.
23
* For more information, contact us at license @ x265.com.
24
*****************************************************************************/
25
26
#ifndef X265_ANALYSIS_H
27
#define X265_ANALYSIS_H
28
29
#include "common.h"
30
#include "predict.h"
31
#include "quant.h"
32
#include "yuv.h"
33
#include "shortyuv.h"
34
#include "cudata.h"
35
36
#include "entropy.h"
37
#include "search.h"
38
39
namespace X265_NS {
40
// private namespace
41
42
class Entropy;
43
44
struct SplitData
45
{
46
    uint32_t splitRefs;
47
    uint32_t mvCost[2];
48
    uint64_t sa8dCost;
49
50
    void initSplitCUData()
51
0
    {
52
0
        splitRefs = 0;
53
0
        mvCost[0] = 0; // L0
54
0
        mvCost[1] = 0; // L1
55
0
        sa8dCost  = 0;
56
0
    }
57
};
58
59
class Analysis : public Search
60
{
61
public:
62
63
    enum {
64
        PRED_MERGE,
65
        PRED_SKIP,
66
        PRED_INTRA,
67
        PRED_2Nx2N,
68
        PRED_BIDIR,
69
        PRED_Nx2N,
70
        PRED_2NxN,
71
        PRED_SPLIT,
72
        PRED_2NxnU,
73
        PRED_2NxnD,
74
        PRED_nLx2N,
75
        PRED_nRx2N,
76
        PRED_INTRA_NxN, /* 4x4 intra PU blocks for 8x8 CU */
77
        PRED_LOSSLESS,  /* lossless encode of best mode */
78
        MAX_PRED_TYPES
79
    };
80
81
    struct ModeDepth
82
    {
83
        Mode           pred[MAX_PRED_TYPES];
84
        Mode*          bestMode;
85
        Yuv            fencYuv;
86
        CUDataMemPool  cuMemPool;
87
    };
88
89
    class PMODE : public BondedTaskGroup
90
    {
91
    public:
92
93
        Analysis&     master;
94
        const CUGeom& cuGeom;
95
        int           modes[MAX_PRED_TYPES];
96
97
0
        PMODE(Analysis& m, const CUGeom& g) : master(m), cuGeom(g) {}
98
99
        void processTasks(int workerThreadId);
100
101
    protected:
102
103
        PMODE operator=(const PMODE&);
104
    };
105
106
    void processPmode(PMODE& pmode, Analysis& slave);
107
108
    ModeDepth m_modeDepth[NUM_CU_DEPTH];
109
    bool      m_bTryLossless;
110
    bool      m_bChromaSa8d;
111
    bool      m_bHD;
112
113
    bool      m_modeFlag[2];
114
    bool      m_checkMergeAndSkipOnly[2];
115
116
    Analysis();
117
118
    bool create(ThreadLocalData* tld);
119
    void destroy();
120
121
    Mode& compressCTU(CUData& ctu, Frame& frame, const CUGeom& cuGeom, const Entropy& initialContext);
122
    int32_t loadTUDepth(CUGeom cuGeom, CUData parentCTU);
123
protected:
124
    /* Analysis data for save/load mode, writes/reads data based on absPartIdx */
125
    x265_analysis_inter_data*  m_reuseInterDataCTU;
126
    int32_t*                   m_reuseRef;
127
    uint8_t*                   m_reuseDepth;
128
    uint8_t*                   m_reuseModes;
129
    uint8_t*                   m_reusePartSize;
130
    uint8_t*                   m_reuseMergeFlag;
131
    x265_analysis_MV*          m_reuseMv[2];
132
    uint8_t*             m_reuseMvpIdx[2];
133
134
    uint32_t             m_splitRefIdx[4];
135
    uint64_t*            cacheCost;
136
137
    uint8_t                 m_evaluateInter;
138
    int32_t                 m_refineLevel;
139
140
    uint8_t*                m_additionalCtuInfo;
141
    int*                    m_prevCtuInfoChange;
142
143
    struct TrainingData
144
    {
145
        uint32_t cuVariance;
146
        uint8_t predMode;
147
        uint8_t partSize;
148
        uint8_t mergeFlag;
149
        int split;
150
151
        void init(const CUData& parentCTU, const CUGeom& cuGeom)
152
0
        {
153
0
            cuVariance = 0;
154
0
            predMode = parentCTU.m_predMode[cuGeom.absPartIdx];
155
0
            partSize = parentCTU.m_partSize[cuGeom.absPartIdx];
156
0
            mergeFlag = parentCTU.m_mergeFlag[cuGeom.absPartIdx];
157
0
            split = 0;
158
0
        }
159
    };
160
161
    /* refine RD based on QP for rd-levels 5 and 6 */
162
    void qprdRefine(const CUData& parentCTU, const CUGeom& cuGeom, int32_t qp, int32_t lqp);
163
164
    /* full analysis for an I-slice CU */
165
    uint64_t compressIntraCU(const CUData& parentCTU, const CUGeom& cuGeom, int32_t qp);
166
167
    /* full analysis for a P or B slice CU */
168
    uint32_t compressInterCU_dist(const CUData& parentCTU, const CUGeom& cuGeom, int32_t qp);
169
    SplitData compressInterCU_rd0_4(const CUData& parentCTU, const CUGeom& cuGeom, int32_t qp);
170
    SplitData compressInterCU_rd5_6(const CUData& parentCTU, const CUGeom& cuGeom, int32_t qp);
171
172
    void recodeCU(const CUData& parentCTU, const CUGeom& cuGeom, int32_t qp, int32_t origqp = -1);
173
174
    /* measure merge and skip */
175
    void checkMerge2Nx2N_rd0_4(Mode& skip, Mode& merge, const CUGeom& cuGeom);
176
    void checkMerge2Nx2N_rd5_6(Mode& skip, Mode& merge, const CUGeom& cuGeom);
177
178
    /* measure inter options */
179
    void checkInter_rd0_4(Mode& interMode, const CUGeom& cuGeom, PartSize partSize, uint32_t refmask[2]);
180
    void checkInter_rd5_6(Mode& interMode, const CUGeom& cuGeom, PartSize partSize, uint32_t refmask[2]);
181
182
    void checkBidir2Nx2N(Mode& inter2Nx2N, Mode& bidir2Nx2N, const CUGeom& cuGeom);
183
184
    /* encode current bestMode losslessly, pick best RD cost */
185
    void tryLossless(const CUGeom& cuGeom);
186
187
    /* add the RD cost of coding a split flag (0 or 1) to the given mode */
188
    void addSplitFlagCost(Mode& mode, uint32_t depth);
189
190
    /* work-avoidance heuristics for RD levels < 5 */
191
    uint32_t topSkipMinDepth(const CUData& parentCTU, const CUGeom& cuGeom);
192
    bool recursionDepthCheck(const CUData& parentCTU, const CUGeom& cuGeom, const Mode& bestMode);
193
    bool complexityCheckCU(const Mode& bestMode);
194
195
    /* generate residual and recon pixels for an entire CTU recursively (RD0) */
196
    void encodeResidue(const CUData& parentCTU, const CUGeom& cuGeom);
197
198
    int calculateQpforCuSize(const CUData& ctu, const CUGeom& cuGeom, int32_t complexCheck = 0, double baseQP = -1);
199
    uint32_t calculateCUVariance(const CUData& ctu, const CUGeom& cuGeom);
200
201
    void classifyCU(const CUData& ctu, const CUGeom& cuGeom, const Mode& bestMode, TrainingData& trainData);
202
    void trainCU(const CUData& ctu, const CUGeom& cuGeom, const Mode& bestMode, TrainingData& trainData);
203
    double aqQPOffset(const CUData& ctu, const CUGeom& cuGeom);
204
    double cuTreeQPOffset(const CUData& ctu, const CUGeom& cuGeom);
205
    void calculateNormFactor(CUData& ctu, int qp);
206
    void normFactor(const pixel* src, uint32_t blockSize, CUData& ctu, int qp, TextType ttype);
207
208
    void collectPUStatistics(const CUData& ctu, const CUGeom& cuGeom);
209
210
    /* check whether current mode is the new best */
211
    inline void checkBestMode(Mode& mode, uint32_t depth)
212
891k
    {
213
891k
        ModeDepth& md = m_modeDepth[depth];
214
891k
        if (md.bestMode)
215
437k
        {
216
437k
            if (mode.rdCost < md.bestMode->rdCost)
217
699
                md.bestMode = &mode;
218
437k
        }
219
453k
        else
220
453k
            md.bestMode = &mode;
221
891k
    }
222
    int findSameContentRefCount(const CUData& parentCTU, const CUGeom& cuGeom);
223
};
224
225
struct ThreadLocalData
226
{
227
    Analysis analysis;
228
229
22.6k
    void destroy() { analysis.destroy(); }
230
};
231
232
}
233
234
#endif // ifndef X265_ANALYSIS_H