File: analysis.h

package info (click to toggle)
x265 4.1-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 15,408 kB
  • sloc: asm: 187,063; cpp: 118,996; ansic: 741; makefile: 146; sh: 91; python: 11
file content (260 lines) | stat: -rw-r--r-- 8,514 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
/*****************************************************************************
* Copyright (C) 2013-2020 MulticoreWare, Inc
*
* Authors: Deepthi Nandakumar <deepthi@multicorewareinc.com>
*          Steve Borho <steve@borho.org>
*          Min Chen <chenm003@163.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
*
* This program is also available under a commercial proprietary license.
* For more information, contact us at license @ x265.com.
*****************************************************************************/

#ifndef X265_ANALYSIS_H
#define X265_ANALYSIS_H

#include "common.h"
#include "predict.h"
#include "quant.h"
#include "yuv.h"
#include "shortyuv.h"
#include "cudata.h"

#include "entropy.h"
#include "search.h"

namespace X265_NS {
// private namespace

class Entropy;

struct SplitData
{
    uint32_t splitRefs;
    uint32_t mvCost[2];
    uint64_t sa8dCost;

    void initSplitCUData()
    {
        splitRefs = 0;
        mvCost[0] = 0; // L0
        mvCost[1] = 0; // L1
        sa8dCost  = 0;
    }
};

class Analysis : public Search
{
public:

    enum {
        PRED_MERGE,
        PRED_SKIP,
        PRED_INTRA,
        PRED_2Nx2N,
        PRED_BIDIR,
        PRED_Nx2N,
        PRED_2NxN,
        PRED_SPLIT,
        PRED_2NxnU,
        PRED_2NxnD,
        PRED_nLx2N,
        PRED_nRx2N,
        PRED_INTRA_NxN, /* 4x4 intra PU blocks for 8x8 CU */
        PRED_LOSSLESS,  /* lossless encode of best mode */
#if ENABLE_SCC_EXT
        PRED_IBC_2Nx2N,
        PRED_IBC_Nx2N,
        PRED_IBC_2NxN,
        PRED_MIXED_IBC_NX2N,
        PRED_MIXED_IBC_2NXN,
        PRED_MERGE_IBC,
#endif
        MAX_PRED_TYPES
    };

    struct ModeDepth
    {
        Mode           pred[MAX_PRED_TYPES];
        Mode*          bestMode;
        Yuv            fencYuv;
        CUDataMemPool  cuMemPool;
    };

    class PMODE : public BondedTaskGroup
    {
    public:

        Analysis&     master;
        const CUGeom& cuGeom;
        int           modes[MAX_PRED_TYPES];

        PMODE(Analysis& m, const CUGeom& g) : master(m), cuGeom(g) {}

        void processTasks(int workerThreadId);

    protected:

        PMODE operator=(const PMODE&);
    };

    void processPmode(PMODE& pmode, Analysis& slave);

    ModeDepth m_modeDepth[NUM_CU_DEPTH];
    bool      m_bTryLossless;
    bool      m_bChromaSa8d;
    bool      m_bHD;

    bool      m_modeFlag[2];
    bool      m_checkMergeAndSkipOnly[2];

    IBC       m_ibc;
    Analysis();

    bool create(ThreadLocalData* tld);
    void destroy();

    Mode& compressCTU(CUData& ctu, Frame& frame, const CUGeom& cuGeom, const Entropy& initialContext);
    int32_t loadTUDepth(CUGeom cuGeom, CUData parentCTU);

protected:
    /* Analysis data for save/load mode, writes/reads data based on absPartIdx */
    x265_analysis_inter_data*  m_reuseInterDataCTU;
    int32_t*                   m_reuseRef;
    uint8_t*                   m_reuseDepth;
    uint8_t*                   m_reuseModes;
    uint8_t*                   m_reusePartSize;
    uint8_t*                   m_reuseMergeFlag;
    x265_analysis_MV*          m_reuseMv[2];
    uint8_t*             m_reuseMvpIdx[2];

    uint32_t             m_splitRefIdx[4];
    uint64_t*            cacheCost;

    uint8_t                 m_evaluateInter;
    int32_t                 m_refineLevel;

    uint8_t*                m_additionalCtuInfo;
    int*                    m_prevCtuInfoChange;

    struct TrainingData
    {
        uint32_t cuVariance;
        uint8_t predMode;
        uint8_t partSize;
        uint8_t mergeFlag;
        int split;

        void init(const CUData& parentCTU, const CUGeom& cuGeom)
        {
            cuVariance = 0;
            predMode = parentCTU.m_predMode[cuGeom.absPartIdx];
            partSize = parentCTU.m_partSize[cuGeom.absPartIdx];
            mergeFlag = parentCTU.m_mergeFlag[cuGeom.absPartIdx];
            split = 0;
        }
    };

    /* refine RD based on QP for rd-levels 5 and 6 */
    void qprdRefine(const CUData& parentCTU, const CUGeom& cuGeom, int32_t qp, int32_t lqp);

    /* full analysis for an I-slice CU */
#if ENABLE_SCC_EXT
    uint64_t compressIntraCU(const CUData& parentCTU, const CUGeom& cuGeom, int32_t qp, IBC* ibc = NULL);
#else
    uint64_t compressIntraCU(const CUData& parentCTU, const CUGeom& cuGeom, int32_t qp);
#endif

    /* full analysis for a P or B slice CU */
    uint32_t compressInterCU_dist(const CUData& parentCTU, const CUGeom& cuGeom, int32_t qp);
    SplitData compressInterCU_rd0_4(const CUData& parentCTU, const CUGeom& cuGeom, int32_t qp);
#if ENABLE_SCC_EXT
    SplitData compressInterCU_rd5_6(const CUData& parentCTU, const CUGeom& cuGeom, int32_t qp, IBC* ibc = NULL);
#else
    SplitData compressInterCU_rd5_6(const CUData& parentCTU, const CUGeom& cuGeom, int32_t qp);
#endif

    void recodeCU(const CUData& parentCTU, const CUGeom& cuGeom, int32_t qp, int32_t origqp = -1);

    /* measure merge and skip */
    void checkMerge2Nx2N_rd0_4(Mode& skip, Mode& merge, const CUGeom& cuGeom);
    void checkMerge2Nx2N_rd5_6(Mode& skip, Mode& merge, const CUGeom& cuGeom);

    /* measure inter options */
    void checkInter_rd0_4(Mode& interMode, const CUGeom& cuGeom, PartSize partSize, uint32_t refmask[2]);
#if !ENABLE_SCC_EXT
    void checkInter_rd5_6(Mode& interMode, const CUGeom& cuGeom, PartSize partSize, uint32_t refmask[2]);
#endif
    void checkBidir2Nx2N(Mode& inter2Nx2N, Mode& bidir2Nx2N, const CUGeom& cuGeom);

#if ENABLE_SCC_EXT
    void checkInter_rd5_6(Mode& interMode, const CUGeom& cuGeom, PartSize partSize, uint32_t refmask[2], MV* iMVCandList = NULL);

    void checkRDCostIntraBCMerge2Nx2N(Mode& merge, const CUGeom& cuGeom);
    void checkIntraBC_rd5_6(Mode& intraBCMode, const CUGeom& cuGeom, PartSize ePartSize, bool testOnlyPred, bool bUse1DSearchFor8x8, IBC& ibc, MV* iMVCandList = NULL);
#endif

    /* encode current bestMode losslessly, pick best RD cost */
    void tryLossless(const CUGeom& cuGeom);

    /* add the RD cost of coding a split flag (0 or 1) to the given mode */
    void addSplitFlagCost(Mode& mode, uint32_t depth);

    /* work-avoidance heuristics for RD levels < 5 */
    uint32_t topSkipMinDepth(const CUData& parentCTU, const CUGeom& cuGeom);
    bool recursionDepthCheck(const CUData& parentCTU, const CUGeom& cuGeom, const Mode& bestMode);
    bool complexityCheckCU(const Mode& bestMode);

    /* generate residual and recon pixels for an entire CTU recursively (RD0) */
    void encodeResidue(const CUData& parentCTU, const CUGeom& cuGeom);

    int calculateQpforCuSize(const CUData& ctu, const CUGeom& cuGeom, int32_t complexCheck = 0, double baseQP = -1);
    uint32_t calculateCUVariance(const CUData& ctu, const CUGeom& cuGeom);

    void classifyCU(const CUData& ctu, const CUGeom& cuGeom, const Mode& bestMode, TrainingData& trainData);
    void trainCU(const CUData& ctu, const CUGeom& cuGeom, const Mode& bestMode, TrainingData& trainData);
    double aqQPOffset(const CUData& ctu, const CUGeom& cuGeom);
    double cuTreeQPOffset(const CUData& ctu, const CUGeom& cuGeom);
    void calculateNormFactor(CUData& ctu, int qp);
    void normFactor(const pixel* src, uint32_t blockSize, CUData& ctu, int qp, TextType ttype);

    void collectPUStatistics(const CUData& ctu, const CUGeom& cuGeom);

    /* check whether current mode is the new best */
    inline void checkBestMode(Mode& mode, uint32_t depth)
    {
        ModeDepth& md = m_modeDepth[depth];
        if (md.bestMode)
        {
            if (mode.rdCost < md.bestMode->rdCost)
                md.bestMode = &mode;
        }
        else
            md.bestMode = &mode;
    }
    int findSameContentRefCount(const CUData& parentCTU, const CUGeom& cuGeom);
};

struct ThreadLocalData
{
    Analysis analysis;

    void destroy() { analysis.destroy(); }
};

}

#endif // ifndef X265_ANALYSIS_H