/src/x265/source/encoder/encoder.h
Line | Count | Source (jump to first uncovered line) |
1 | | /***************************************************************************** |
2 | | * Copyright (C) 2013-2020 MulticoreWare, Inc |
3 | | * |
4 | | * Authors: Steve Borho <steve@borho.org> |
5 | | * |
6 | | * This program is free software; you can redistribute it and/or modify |
7 | | * it under the terms of the GNU General Public License as published by |
8 | | * the Free Software Foundation; either version 2 of the License, or |
9 | | * (at your option) any later version. |
10 | | * |
11 | | * This program is distributed in the hope that it will be useful, |
12 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | | * GNU General Public License for more details. |
15 | | * |
16 | | * You should have received a copy of the GNU General Public License |
17 | | * along with this program; if not, write to the Free Software |
18 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA. |
19 | | * |
20 | | * This program is also available under a commercial proprietary license. |
21 | | * For more information, contact us at license @ x265.com. |
22 | | *****************************************************************************/ |
23 | | |
24 | | #ifndef X265_ENCODER_H |
25 | | #define X265_ENCODER_H |
26 | | |
27 | | #include "common.h" |
28 | | #include "slice.h" |
29 | | #include "threading.h" |
30 | | #include "scalinglist.h" |
31 | | #include "x265.h" |
32 | | #include "nal.h" |
33 | | #include "framedata.h" |
34 | | #include "svt.h" |
35 | | #include "temporalfilter.h" |
36 | | #ifdef ENABLE_HDR10_PLUS |
37 | | #include "dynamicHDR10/hdr10plus.h" |
38 | | #endif |
39 | | struct x265_encoder {}; |
40 | | namespace X265_NS { |
41 | | // private namespace |
42 | | extern const char g_sliceTypeToChar[3]; |
43 | | |
44 | | class Entropy; |
45 | | |
46 | | #ifdef SVT_HEVC |
47 | | typedef struct SvtAppContext |
48 | | { |
49 | | EB_COMPONENTTYPE* svtEncoderHandle; |
50 | | EB_H265_ENC_CONFIGURATION* svtHevcParams; |
51 | | |
52 | | // Buffer Pools |
53 | | EB_BUFFERHEADERTYPE* inputPictureBuffer; |
54 | | uint64_t byteCount; |
55 | | uint64_t outFrameCount; |
56 | | |
57 | | }SvtAppContext; |
58 | | #endif |
59 | | |
60 | | struct EncStats |
61 | | { |
62 | | double m_psnrSumY; |
63 | | double m_psnrSumU; |
64 | | double m_psnrSumV; |
65 | | double m_globalSsim; |
66 | | double m_totalQp; |
67 | | double m_maxFALL; |
68 | | uint64_t m_accBits; |
69 | | uint32_t m_numPics; |
70 | | uint16_t m_maxCLL; |
71 | | |
72 | | EncStats() |
73 | 0 | { |
74 | 0 | m_psnrSumY = m_psnrSumU = m_psnrSumV = m_globalSsim = 0; |
75 | 0 | m_accBits = 0; |
76 | 0 | m_numPics = 0; |
77 | 0 | m_totalQp = 0; |
78 | 0 | m_maxCLL = 0; |
79 | 0 | m_maxFALL = 0; |
80 | 0 | } |
81 | | |
82 | | void addQP(double aveQp); |
83 | | |
84 | | void addPsnr(double psnrY, double psnrU, double psnrV); |
85 | | |
86 | | void addBits(uint64_t bits); |
87 | | |
88 | | void addSsim(double ssim); |
89 | | }; |
90 | | |
91 | 0 | #define MAX_NUM_REF_IDX 64 |
92 | 0 | #define DUP_BUFFER 2 |
93 | 0 | #define doubling 7 |
94 | 0 | #define tripling 8 |
95 | | |
96 | | struct RefIdxLastGOP |
97 | | { |
98 | | int numRefIdxDefault[2]; |
99 | | int numRefIdxl0[MAX_NUM_REF_IDX]; |
100 | | int numRefIdxl1[MAX_NUM_REF_IDX]; |
101 | | }; |
102 | | |
103 | | struct RPSListNode |
104 | | { |
105 | | int idx; |
106 | | int count; |
107 | | RPS* rps; |
108 | | RPSListNode* next; |
109 | | RPSListNode* prior; |
110 | | }; |
111 | | |
112 | | struct cuLocation |
113 | | { |
114 | | bool skipWidth; |
115 | | bool skipHeight; |
116 | | uint32_t heightInCU; |
117 | | uint32_t widthInCU; |
118 | | uint32_t oddRowIndex; |
119 | | uint32_t evenRowIndex; |
120 | | uint32_t switchCondition; |
121 | | |
122 | | void init(x265_param* param) |
123 | 0 | { |
124 | 0 | skipHeight = false; |
125 | 0 | skipWidth = false; |
126 | 0 | heightInCU = (param->sourceHeight + param->maxCUSize - 1) >> param->maxLog2CUSize; |
127 | 0 | widthInCU = (param->sourceWidth + param->maxCUSize - 1) >> param->maxLog2CUSize; |
128 | 0 | evenRowIndex = 0; |
129 | 0 | oddRowIndex = param->num4x4Partitions * widthInCU; |
130 | 0 | switchCondition = 0; // To switch between odd and even rows |
131 | 0 | } |
132 | | }; |
133 | | |
134 | | struct puOrientation |
135 | | { |
136 | | bool isVert; |
137 | | bool isRect; |
138 | | bool isAmp; |
139 | | |
140 | | void init() |
141 | 0 | { |
142 | 0 | isRect = false; |
143 | 0 | isAmp = false; |
144 | 0 | isVert = false; |
145 | 0 | } |
146 | | }; |
147 | | |
148 | | struct AdaptiveFrameDuplication |
149 | | { |
150 | | x265_picture* dupPic; |
151 | | char* dupPlane; |
152 | | |
153 | | //Flag to denote the availability of the picture buffer. |
154 | | bool bOccupied; |
155 | | |
156 | | //Flag to check whether the picture has duplicated. |
157 | | bool bDup; |
158 | | }; |
159 | | |
160 | | class FrameEncoder; |
161 | | class DPB; |
162 | | class Lookahead; |
163 | | class RateControl; |
164 | | class ThreadPool; |
165 | | class FrameData; |
166 | | |
167 | | #define MAX_SCENECUT_THRESHOLD 1.0 |
168 | | #define SCENECUT_STRENGTH_FACTOR 2.0 |
169 | | #define MIN_EDGE_FACTOR 0.5 |
170 | | #define MAX_EDGE_FACTOR 1.5 |
171 | | #define SCENECUT_CHROMA_FACTOR 10.0 |
172 | | |
173 | | class Encoder : public x265_encoder |
174 | | { |
175 | | public: |
176 | | |
177 | | uint32_t m_residualSumEmergency[MAX_NUM_TR_CATEGORIES][MAX_NUM_TR_COEFFS]; |
178 | | uint32_t m_countEmergency[MAX_NUM_TR_CATEGORIES]; |
179 | | uint16_t (*m_offsetEmergency)[MAX_NUM_TR_CATEGORIES][MAX_NUM_TR_COEFFS]; |
180 | | |
181 | | int64_t m_firstPts; |
182 | | int64_t m_bframeDelayTime; |
183 | | int64_t m_prevReorderedPts[2]; |
184 | | int64_t m_encodeStartTime; |
185 | | |
186 | | int m_pocLast; // time index (POC) |
187 | | int m_encodedFrameNum; |
188 | | int m_outputCount; |
189 | | int m_bframeDelay; |
190 | | int m_numPools; |
191 | | int m_curEncoder; |
192 | | |
193 | | // weighted prediction |
194 | | int m_numLumaWPFrames; // number of P frames with weighted luma reference |
195 | | int m_numChromaWPFrames; // number of P frames with weighted chroma reference |
196 | | int m_numLumaWPBiFrames; // number of B frames with weighted luma reference |
197 | | int m_numChromaWPBiFrames; // number of B frames with weighted chroma reference |
198 | | int m_conformanceMode; |
199 | | int m_lastBPSEI; |
200 | | uint32_t m_numDelayedPic; |
201 | | |
202 | | ThreadPool* m_threadPool; |
203 | | FrameEncoder* m_frameEncoder[X265_MAX_FRAME_THREADS]; |
204 | | DPB* m_dpb; |
205 | | Frame* m_exportedPic[MAX_LAYERS]; |
206 | | FILE* m_analysisFileIn; |
207 | | FILE* m_analysisFileOut; |
208 | | FILE* m_naluFile; |
209 | | x265_param* m_paramBase[3]; |
210 | | x265_param* m_param; |
211 | | x265_param* m_latestParam; // Holds latest param during a reconfigure |
212 | | x265_param* m_zoneParam; |
213 | | RateControl* m_rateControl; |
214 | | Lookahead* m_lookahead; |
215 | | AdaptiveFrameDuplication* m_dupBuffer[DUP_BUFFER]; // picture buffer of size 2 |
216 | | /*Frame duplication: Two pictures used to compute PSNR */ |
217 | | pixel* m_dupPicOne[3]; |
218 | | pixel* m_dupPicTwo[3]; |
219 | | |
220 | | bool m_externalFlush; |
221 | | /* Collect statistics globally */ |
222 | | EncStats m_analyzeAll[MAX_LAYERS]; |
223 | | EncStats m_analyzeI[MAX_LAYERS]; |
224 | | EncStats m_analyzeP[MAX_LAYERS]; |
225 | | EncStats m_analyzeB[MAX_LAYERS]; |
226 | | VPS m_vps; |
227 | | SPS m_sps; |
228 | | PPS m_pps; |
229 | | NALList m_nalList; |
230 | | ScalingList m_scalingList; // quantization matrix information |
231 | | Window m_conformanceWindow; |
232 | | |
233 | | bool m_bZeroLatency; // x265_encoder_encode() returns NALs for the input picture, zero lag |
234 | | bool m_aborted; // fatal error detected |
235 | | bool m_reconfigure; // Encoder reconfigure in progress |
236 | | bool m_reconfigureRc; |
237 | | bool m_reconfigureZone; |
238 | | |
239 | | int m_saveCtuDistortionLevel; |
240 | | |
241 | | /* Begin intra refresh when one not in progress or else begin one as soon as the current |
242 | | * one is done. Requires bIntraRefresh to be set.*/ |
243 | | int m_bQueuedIntraRefresh; |
244 | | |
245 | | /* For optimising slice QP */ |
246 | | Lock m_sliceQpLock; |
247 | | int m_iFrameNum; |
248 | | int m_iPPSQpMinus26; |
249 | | int64_t m_iBitsCostSum[QP_MAX_MAX + 1]; |
250 | | Lock m_sliceRefIdxLock; |
251 | | RefIdxLastGOP m_refIdxLastGOP; |
252 | | |
253 | | Lock m_rpsInSpsLock; |
254 | | int m_rpsInSpsCount; |
255 | | /* For HDR*/ |
256 | | double m_cB; |
257 | | double m_cR; |
258 | | |
259 | | int m_bToneMap; // Enables tone-mapping |
260 | | int m_enableNal; |
261 | | |
262 | | #ifdef ENABLE_HDR10_PLUS |
263 | | const hdr10plus_api *m_hdr10plus_api; |
264 | | uint8_t **m_cim; |
265 | | int m_numCimInfo; |
266 | | #endif |
267 | | |
268 | | #ifdef SVT_HEVC |
269 | | SvtAppContext* m_svtAppData; |
270 | | #endif |
271 | | |
272 | | x265_sei_payload m_prevTonemapPayload; |
273 | | |
274 | | int m_zoneIndex; |
275 | | |
276 | | /* Collect frame level feature data */ |
277 | | uint64_t* m_rdCost; |
278 | | uint64_t* m_variance; |
279 | | uint32_t* m_trainingCount; |
280 | | int32_t m_startPoint; |
281 | | Lock m_dynamicRefineLock; |
282 | | |
283 | | bool m_saveCTUSize; |
284 | | |
285 | | |
286 | | ThreadSafeInteger* zoneReadCount; |
287 | | ThreadSafeInteger* zoneWriteCount; |
288 | | /* Film grain model file */ |
289 | | FILE* m_filmGrainIn; |
290 | | /* Aom film grain model file*/ |
291 | | FILE* m_aomFilmGrainIn; |
292 | | |
293 | | Encoder(); |
294 | | ~Encoder() |
295 | 0 | { |
296 | | #ifdef ENABLE_HDR10_PLUS |
297 | | if (m_prevTonemapPayload.payload != NULL) |
298 | | X265_FREE(m_prevTonemapPayload.payload); |
299 | | #endif |
300 | 0 | }; |
301 | | |
302 | | void create(); |
303 | | void stopJobs(); |
304 | | void destroy(); |
305 | | |
306 | | int encode(const x265_picture* pic, x265_picture *pic_out); |
307 | | |
308 | | int reconfigureParam(x265_param* encParam, x265_param* param); |
309 | | |
310 | | bool isReconfigureRc(x265_param* latestParam, x265_param* param_in); |
311 | | |
312 | | void copyCtuInfo(x265_ctu_info_t** frameCtuInfo, int poc); |
313 | | |
314 | | int copySlicetypePocAndSceneCut(int *slicetype, int *poc, int *sceneCut, int sLayer); |
315 | | |
316 | | int getRefFrameList(PicYuv** l0, PicYuv** l1, int sliceType, int poc, int* pocL0, int* pocL1); |
317 | | |
318 | | int setAnalysisDataAfterZScan(x265_analysis_data *analysis_data, Frame* curFrame); |
319 | | |
320 | | int setAnalysisData(x265_analysis_data *analysis_data, int poc, uint32_t cuBytes); |
321 | | |
322 | | void getStreamHeaders(NALList& list, Entropy& sbacCoder, Bitstream& bs); |
323 | | |
324 | | void getEndNalUnits(NALList& list, Bitstream& bs); |
325 | | |
326 | | void fetchStats(x265_stats* stats, size_t statsSizeBytes, int layer = 0); |
327 | | |
328 | | void printSummary(); |
329 | | |
330 | | void printReconfigureParams(); |
331 | | |
332 | | char* statsString(EncStats&, char* , size_t bufferSize); |
333 | | |
334 | | void configure(x265_param *param); |
335 | | |
336 | | void configureZone(x265_param *p, x265_param *zone); |
337 | | |
338 | | void updateVbvPlan(RateControl* rc); |
339 | | |
340 | | void readAnalysisFile(x265_analysis_data* analysis, int poc, int sliceType); |
341 | | |
342 | | void readAnalysisFile(x265_analysis_data* analysis, int poc, const x265_picture* picIn, int paramBytes); |
343 | | |
344 | | void readAnalysisFile(x265_analysis_data* analysis, int poc, const x265_picture* picIn, int paramBytes, cuLocation cuLoc); |
345 | | |
346 | | void computeDistortionOffset(x265_analysis_data* analysis); |
347 | | |
348 | | int getCUIndex(cuLocation* cuLoc, uint32_t* count, int bytes, int flag); |
349 | | |
350 | | int getPuShape(puOrientation* puOrient, int partSize, int numCTU); |
351 | | |
352 | | void writeAnalysisFile(x265_analysis_data* analysis, FrameData &curEncData); |
353 | | |
354 | | void writeAnalysisFileRefine(x265_analysis_data* analysis, FrameData &curEncData); |
355 | | |
356 | | void copyDistortionData(x265_analysis_data* analysis, FrameData &curEncData); |
357 | | |
358 | | void finishFrameStats(Frame* pic, FrameEncoder *curEncoder, x265_frame_stats* frameStats, int inPoc, int layer); |
359 | | |
360 | | int validateAnalysisData(x265_analysis_validate* param, int readWriteFlag); |
361 | | |
362 | | void readUserSeiFile(x265_sei_payload& seiMsg, int poc); |
363 | | |
364 | | void calcRefreshInterval(Frame* frameEnc); |
365 | | |
366 | | uint64_t computeSSD(pixel *fenc, pixel *rec, intptr_t stride, uint32_t width, uint32_t height, x265_param *param); |
367 | | |
368 | | double ComputePSNR(x265_picture *firstPic, x265_picture *secPic, x265_param *param); |
369 | | |
370 | | void copyPicture(x265_picture *dest, const x265_picture *src); |
371 | | |
372 | | void initRefIdx(); |
373 | | void analyseRefIdx(int *numRefIdx); |
374 | | void updateRefIdx(); |
375 | | bool computeSPSRPSIndex(); |
376 | | |
377 | | void copyUserSEIMessages(Frame *frame, const x265_picture* pic_in); |
378 | | |
379 | | void configureDolbyVisionParams(x265_param* p); |
380 | | |
381 | | void configureVideoSignalTypePreset(x265_param* p); |
382 | | |
383 | | bool isFilterThisframe(uint8_t sliceTypeConfig, int curSliceType); |
384 | | bool generateMcstfRef(Frame* frameEnc, FrameEncoder* currEncoder); |
385 | | |
386 | | protected: |
387 | | |
388 | | void initVPS(VPS *vps); |
389 | | void initSPS(SPS *sps); |
390 | | void initPPS(PPS *pps); |
391 | | }; |
392 | | } |
393 | | |
394 | | #endif // ifndef X265_ENCODER_H |