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