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