1 /*****************************************************************************
2  * Copyright (C) 2013-2020 MulticoreWare, Inc
3  *
4  * Authors: Steve Borho <steve@borho.org>
5  *          Min Chen <chenm003@163.com>
6  *          Praveen Kumar Tiwari <praveen@multicorewareinc.com>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * 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_SAO_H
27 #define X265_SAO_H
28 
29 #include "common.h"
30 #include "frame.h"
31 #include "entropy.h"
32 
33 namespace X265_NS {
34 // private namespace
35 
36 enum SAOType
37 {
38     SAO_EO_0 = 0,
39     SAO_EO_1,
40     SAO_EO_2,
41     SAO_EO_3,
42     SAO_BO,
43     MAX_NUM_SAO_TYPE
44 };
45 
46 class SAO
47 {
48 public:
49 
50     enum { SAO_MAX_DEPTH = 4 };
51     enum { SAO_BO_BITS  = 5 };
52     enum { MAX_NUM_SAO_CLASS = 32 };
53     enum { SAO_BIT_INC = 0 }; /* in HM12.0, it wrote as X265_MAX(X265_DEPTH - 10, 0) */
54     enum { OFFSET_THRESH = 1 << X265_MIN(X265_DEPTH - 5, 5) };
55     enum { NUM_EDGETYPE = 5 };
56     enum { NUM_PLANE = 3 };
57     enum { SAO_DEPTHRATE_SIZE = 4 };
58     static const uint32_t s_eoTable[NUM_EDGETYPE];
59     typedef int32_t PerClass[MAX_NUM_SAO_TYPE][MAX_NUM_SAO_CLASS];
60     typedef int32_t PerPlane[NUM_PLANE][MAX_NUM_SAO_TYPE][MAX_NUM_SAO_CLASS];
61 protected:
62 
63     /* allocated per part */
64     PerPlane    m_count;
65     PerPlane    m_offset;
66     PerPlane    m_offsetOrg;
67 
68     /* allocated per CTU */
69     PerPlane*   m_countPreDblk;
70     PerPlane*   m_offsetOrgPreDblk;
71 
72     double*     m_depthSaoRate;
73     int8_t      m_offsetBo[NUM_PLANE][MAX_NUM_SAO_CLASS];
74     int8_t      m_offsetEo[NUM_PLANE][NUM_EDGETYPE];
75 
76     int         m_chromaFormat;
77     int         m_numCuInWidth;
78     int         m_numCuInHeight;
79     int         m_hChromaShift;
80     int         m_vChromaShift;
81 
82     pixel*      m_clipTable;
83     pixel*      m_clipTableBase;
84 
85     pixel*      m_tmpU[3];
86     pixel*      m_tmpL1[3];
87     pixel*      m_tmpL2[3];
88 
89 public:
90 
91     struct SAOContexts
92     {
93         Entropy cur;
94         Entropy next;
95         Entropy temp;
96     };
97 
98     Frame*      m_frame;
99     Entropy     m_entropyCoder;
100     SAOContexts m_rdContexts;
101 
102     x265_param* m_param;
103     int         m_refDepth;
104     int         m_numNoSao[2];
105 
106     SAO();
107 
108     bool create(x265_param* param, int initCommon);
109     void createFromRootNode(SAO *root);
110     void destroy(int destoryCommon);
111 
112     void allocSaoParam(SAOParam* saoParam) const;
113 
114     void startSlice(Frame* pic, Entropy& initState);
115     void resetStats();
116 
117     // CTU-based SAO process without slice granularity
118     void applyPixelOffsets(int addr, int typeIdx, int plane);
119     void processSaoUnitRow(SaoCtuParam* ctuParam, int idxY, int plane);
120     void generateLumaOffsets(SaoCtuParam* ctuParam, int idxY, int idxX);
121     void generateChromaOffsets(SaoCtuParam* ctuParam[3], int idxY, int idxX);
122 
123     void calcSaoStatsCTU(int addr, int plane);
124     void calcSaoStatsCu_BeforeDblk(Frame* pic, int idxX, int idxY);
125 
126     void saoLumaComponentParamDist(SAOParam* saoParam, int addr, int64_t& rateDist, int64_t* lambda, int64_t& bestCost);
127     void saoChromaComponentParamDist(SAOParam* saoParam, int addr, int64_t& rateDist, int64_t* lambda, int64_t& bestCost);
128 
129     void estIterOffset(int typeIdx, int64_t lambda, int32_t count, int32_t offsetOrg, int32_t& offset, int32_t& distClasses, int64_t& costClasses);
130     void rdoSaoUnitRowEnd(const SAOParam* saoParam, int numctus);
131     void rdoSaoUnitCu(SAOParam* saoParam, int rowBaseAddr, int idxX, int addr);
132     int64_t calcSaoRdoCost(int64_t distortion, uint32_t bits, int64_t lambda);
133     void saoStatsInitialOffset(int addr, int planes);
134     friend class FrameFilter;
135 };
136 
137 }
138 
139 #endif // ifndef X265_SAO_H
140