/src/x265/source/encoder/frameencoder.h
Line | Count | Source (jump to first uncovered line) |
1 | | /***************************************************************************** |
2 | | * Copyright (C) 2013-2020 MulticoreWare, Inc |
3 | | * |
4 | | * Authors: Shin Yee <shinyee@multicorewareinc.com> |
5 | | * Min Chen <chenm003@163.com> |
6 | | * |
7 | | * This program is free software; you can redistribute it and/or modify |
8 | | * it under the terms of the GNU General Public License as published by |
9 | | * the Free Software Foundation; either version 2 of the License, or |
10 | | * (at your option) any later version. |
11 | | * |
12 | | * This program is distributed in the hope that it will be useful, |
13 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | | * GNU General Public License for more details. |
16 | | * |
17 | | * You should have received a copy of the GNU General Public License |
18 | | * along with this program; if not, write to the Free Software |
19 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA. |
20 | | * |
21 | | * This program is also available under a commercial proprietary license. |
22 | | * For more information, contact us at license @ x265.com. |
23 | | *****************************************************************************/ |
24 | | |
25 | | #ifndef X265_FRAMEENCODER_H |
26 | | #define X265_FRAMEENCODER_H |
27 | | |
28 | | #include "common.h" |
29 | | #include "wavefront.h" |
30 | | #include "bitstream.h" |
31 | | #include "frame.h" |
32 | | #include "picyuv.h" |
33 | | #include "md5.h" |
34 | | |
35 | | #include "analysis.h" |
36 | | #include "sao.h" |
37 | | |
38 | | #include "entropy.h" |
39 | | #include "framefilter.h" |
40 | | #include "ratecontrol.h" |
41 | | #include "reference.h" |
42 | | #include "nal.h" |
43 | | #include "temporalfilter.h" |
44 | | |
45 | | namespace X265_NS { |
46 | | // private x265 namespace |
47 | | |
48 | | class ThreadPool; |
49 | | class Encoder; |
50 | | |
51 | 0 | #define ANGULAR_MODE_ID 2 |
52 | 0 | #define AMP_ID 3 |
53 | | |
54 | | struct StatisticLog |
55 | | { |
56 | | uint64_t cntInter[4]; |
57 | | uint64_t cntIntra[4]; |
58 | | uint64_t cuInterDistribution[4][INTER_MODES]; |
59 | | uint64_t cuIntraDistribution[4][INTRA_MODES]; |
60 | | uint64_t cntIntraNxN; |
61 | | uint64_t cntSkipCu[4]; |
62 | | uint64_t cntTotalCu[4]; |
63 | | uint64_t totalCu; |
64 | | |
65 | | StatisticLog() |
66 | 0 | { |
67 | 0 | memset(this, 0, sizeof(StatisticLog)); |
68 | 0 | } |
69 | | }; |
70 | | |
71 | | /* manages the state of encoding one row of CTU blocks. When |
72 | | * WPP is active, several rows will be simultaneously encoded. */ |
73 | | struct CTURow |
74 | | { |
75 | | Entropy bufferedEntropy; /* store CTU2 context for next row CTU0 */ |
76 | | Entropy rowGoOnCoder; /* store context between CTUs, code bitstream if !SAO */ |
77 | | unsigned int sliceId; /* store current row slice id */ |
78 | | |
79 | | FrameStats rowStats; |
80 | | |
81 | | /* Threading variables */ |
82 | | |
83 | | /* This lock must be acquired when reading or writing m_active or m_busy */ |
84 | | Lock lock; |
85 | | |
86 | | /* row is ready to run, has no neighbor dependencies. The row may have |
87 | | * external dependencies (reference frame pixels) that prevent it from being |
88 | | * processed, so it may stay with m_active=true for some time before it is |
89 | | * encoded by a worker thread. */ |
90 | | volatile bool active; |
91 | | |
92 | | /* row is being processed by a worker thread. This flag is only true when a |
93 | | * worker thread is within the context of FrameEncoder::processRow(). This |
94 | | * flag is used to detect multiple possible wavefront problems. */ |
95 | | volatile bool busy; |
96 | | |
97 | | /* count of completed CUs in this row */ |
98 | | volatile uint32_t completed; |
99 | | volatile uint32_t avgQPComputed; |
100 | | |
101 | | volatile int reEncode; |
102 | | |
103 | | /* called at the start of each frame to initialize state */ |
104 | | void init(Entropy& initContext, unsigned int sid) |
105 | 0 | { |
106 | 0 | active = false; |
107 | 0 | busy = false; |
108 | 0 | completed = 0; |
109 | 0 | avgQPComputed = 0; |
110 | 0 | sliceId = sid; |
111 | 0 | reEncode = 0; |
112 | 0 | memset(&rowStats, 0, sizeof(rowStats)); |
113 | 0 | rowGoOnCoder.load(initContext); |
114 | 0 | } |
115 | | }; |
116 | | |
117 | | /*Film grain characteristics*/ |
118 | | struct FilmGrain |
119 | | { |
120 | | bool m_filmGrainCharacteristicsCancelFlag; |
121 | | bool m_filmGrainCharacteristicsPersistenceFlag; |
122 | | bool m_separateColourDescriptionPresentFlag; |
123 | | uint8_t m_filmGrainModelId; |
124 | | uint8_t m_blendingModeId; |
125 | | uint8_t m_log2ScaleFactor; |
126 | | }; |
127 | | |
128 | | struct ColourDescription |
129 | | { |
130 | | bool m_filmGrainFullRangeFlag; |
131 | | uint8_t m_filmGrainBitDepthLumaMinus8; |
132 | | uint8_t m_filmGrainBitDepthChromaMinus8; |
133 | | uint8_t m_filmGrainColourPrimaries; |
134 | | uint8_t m_filmGrainTransferCharacteristics; |
135 | | uint8_t m_filmGrainMatrixCoeffs; |
136 | | }; |
137 | | |
138 | | struct FGPresent |
139 | | { |
140 | | uint8_t m_blendingModeId; |
141 | | uint8_t m_log2ScaleFactor; |
142 | | bool m_presentFlag[3]; |
143 | | }; |
144 | | |
145 | | struct AomFilmGrain |
146 | | { |
147 | | int32_t m_apply_grain; |
148 | | int32_t m_update_grain; |
149 | | int32_t m_scaling_points_y[14][2]; |
150 | | int32_t m_num_y_points; |
151 | | int32_t m_scaling_points_cb[10][2]; |
152 | | int32_t m_num_cb_points; |
153 | | int32_t m_scaling_points_cr[10][2]; |
154 | | int32_t m_num_cr_points; |
155 | | int32_t m_scaling_shift; |
156 | | int32_t m_ar_coeff_lag; |
157 | | int32_t m_ar_coeffs_y[24]; |
158 | | int32_t m_ar_coeffs_cb[25]; |
159 | | int32_t m_ar_coeffs_cr[25]; |
160 | | int32_t m_ar_coeff_shift; |
161 | | int32_t m_cb_mult; |
162 | | int32_t m_cb_luma_mult; |
163 | | int32_t m_cb_offset; |
164 | | int32_t m_cr_mult; |
165 | | int32_t m_cr_luma_mult; |
166 | | int32_t m_cr_offset; |
167 | | int32_t m_overlap_flag; |
168 | | int32_t m_clip_to_restricted_range; |
169 | | int32_t m_bitDepth; |
170 | | int32_t m_chroma_scaling_from_luma; |
171 | | int32_t m_grain_scale_shift; |
172 | | uint16_t m_grain_seed; |
173 | | }; |
174 | | |
175 | | // Manages the wave-front processing of a single encoding frame |
176 | | class FrameEncoder : public WaveFront, public Thread |
177 | | { |
178 | | public: |
179 | | |
180 | | FrameEncoder(); |
181 | | |
182 | 0 | virtual ~FrameEncoder() {} |
183 | | |
184 | | virtual bool init(Encoder *top, int numRows, int numCols); |
185 | | |
186 | | void destroy(); |
187 | | |
188 | | /* triggers encode of a new frame by the worker thread */ |
189 | | bool startCompressFrame(Frame* curFrame[MAX_LAYERS]); |
190 | | |
191 | | /* blocks until worker thread is done, returns access unit */ |
192 | | Frame **getEncodedPicture(NALList& list); |
193 | | |
194 | | void initDecodedPictureHashSEI(int row, int cuAddr, int height, int layer); |
195 | | |
196 | | Event m_enable; |
197 | | Event m_done; |
198 | | Event m_completionEvent; |
199 | | int m_localTldIdx; |
200 | | bool m_reconfigure; /* reconfigure in progress */ |
201 | | volatile bool m_threadActive; |
202 | | volatile bool *m_bAllRowsStop; |
203 | | volatile int m_completionCount; |
204 | | volatile int *m_vbvResetTriggerRow; |
205 | | volatile int m_sliceCnt; |
206 | | |
207 | | uint32_t m_numRows; |
208 | | uint32_t m_numCols; |
209 | | uint32_t m_filterRowDelay; |
210 | | uint32_t m_filterRowDelayCus; |
211 | | uint32_t m_refLagRows; |
212 | | bool m_bUseSao; |
213 | | |
214 | | CTURow* m_rows; |
215 | | uint16_t m_sliceAddrBits; |
216 | | uint32_t m_sliceGroupSize; |
217 | | uint32_t* m_sliceBaseRow; |
218 | | uint32_t* m_sliceMaxBlockRow; |
219 | | int64_t m_rowSliceTotalBits[2]; |
220 | | RateControlEntry m_rce; |
221 | | SEIDecodedPictureHash m_seiReconPictureDigest; |
222 | | |
223 | | uint64_t m_SSDY[MAX_LAYERS]; |
224 | | uint64_t m_SSDU[MAX_LAYERS]; |
225 | | uint64_t m_SSDV[MAX_LAYERS]; |
226 | | double m_ssim[MAX_LAYERS]; |
227 | | uint64_t m_accessUnitBits[MAX_LAYERS]; |
228 | | uint32_t m_ssimCnt[MAX_LAYERS]; |
229 | | |
230 | | volatile int m_activeWorkerCount; // count of workers currently encoding or filtering CTUs |
231 | | volatile int m_totalActiveWorkerCount; // sum of m_activeWorkerCount sampled at end of each CTU |
232 | | volatile int m_activeWorkerCountSamples; // count of times m_activeWorkerCount was sampled (think vbv restarts) |
233 | | volatile int m_countRowBlocks; // count of workers forced to abandon a row because of top dependency |
234 | | int64_t m_startCompressTime[MAX_LAYERS]; // timestamp when frame encoder is given a frame |
235 | | int64_t m_row0WaitTime[MAX_LAYERS]; // timestamp when row 0 is allowed to start |
236 | | int64_t m_allRowsAvailableTime[MAX_LAYERS]; // timestamp when all reference dependencies are resolved |
237 | | int64_t m_endCompressTime[MAX_LAYERS]; // timestamp after all CTUs are compressed |
238 | | int64_t m_endFrameTime[MAX_LAYERS]; // timestamp after RCEnd, NR updates, etc |
239 | | int64_t m_stallStartTime[MAX_LAYERS]; // timestamp when worker count becomes 0 |
240 | | int64_t m_prevOutputTime[MAX_LAYERS]; // timestamp when prev frame was retrieved by API thread |
241 | | int64_t m_slicetypeWaitTime[MAX_LAYERS]; // total elapsed time waiting for decided frame |
242 | | int64_t m_totalWorkerElapsedTime[MAX_LAYERS]; // total elapsed time spent by worker threads processing CTUs |
243 | | int64_t m_totalNoWorkerTime[MAX_LAYERS]; // total elapsed time without any active worker threads |
244 | | #if DETAILED_CU_STATS |
245 | | CUStats m_cuStats; |
246 | | #endif |
247 | | |
248 | | Encoder* m_top; |
249 | | x265_param* m_param; |
250 | | Frame* m_frame[MAX_LAYERS]; |
251 | | Frame** m_retFrameBuffer; |
252 | | NoiseReduction* m_nr; |
253 | | ThreadLocalData* m_tld; /* for --no-wpp */ |
254 | | Bitstream* m_outStreams; |
255 | | Bitstream* m_backupStreams; |
256 | | uint32_t* m_substreamSizes; |
257 | | |
258 | | CUGeom* m_cuGeoms; |
259 | | uint32_t* m_ctuGeomMap; |
260 | | |
261 | | Bitstream m_bs; |
262 | | MotionReference m_mref[2][MAX_NUM_REF + 1]; |
263 | | Entropy m_entropyCoder; |
264 | | Entropy m_initSliceContext; |
265 | | FrameFilter m_frameFilter; |
266 | | NALList m_nalList; |
267 | | |
268 | | int m_sLayerId; |
269 | | |
270 | | class WeightAnalysis : public BondedTaskGroup |
271 | | { |
272 | | public: |
273 | | |
274 | | FrameEncoder& master; |
275 | | |
276 | 0 | WeightAnalysis(FrameEncoder& fe) : master(fe) {} |
277 | | |
278 | | void processTasks(int workerThreadId); |
279 | | |
280 | | protected: |
281 | | |
282 | | WeightAnalysis operator=(const WeightAnalysis&); |
283 | | }; |
284 | | |
285 | | protected: |
286 | | |
287 | | bool initializeGeoms(); |
288 | | |
289 | | /* analyze / compress frame, can be run in parallel within reference constraints */ |
290 | | void compressFrame(int layer); |
291 | | |
292 | | /* called by compressFrame to generate final per-row bitstreams */ |
293 | | void encodeSlice(uint32_t sliceAddr, int layer); |
294 | | |
295 | | void threadMain(); |
296 | | int collectCTUStatistics(const CUData& ctu, FrameStats* frameLog); |
297 | | void noiseReductionUpdate(); |
298 | | void writeTrailingSEIMessages(int layer); |
299 | | bool writeToneMapInfo(x265_sei_payload *payload); |
300 | | |
301 | | /* Called by WaveFront::findJob() */ |
302 | | virtual void processRow(int row, int threadId, int layer); |
303 | | virtual void processRowEncoder(int row, ThreadLocalData& tld, int layer); |
304 | | |
305 | 0 | void enqueueRowEncoder(int row) { WaveFront::enqueueRow(row * 2 + 0); } |
306 | 0 | void enqueueRowFilter(int row) { WaveFront::enqueueRow(row * 2 + 1); } |
307 | 0 | void enableRowEncoder(int row) { WaveFront::enableRow(row * 2 + 0); } |
308 | 0 | void enableRowFilter(int row) { WaveFront::enableRow(row * 2 + 1); } |
309 | | #if ENABLE_LIBVMAF |
310 | | void vmafFrameLevelScore(); |
311 | | #endif |
312 | | void collectDynDataFrame(int layer); |
313 | | void computeAvgTrainingData(int layer); |
314 | | void collectDynDataRow(CUData& ctu, FrameStats* rowStats); |
315 | | void readModel(FilmGrainCharacteristics* m_filmGrain, FILE* filmgrain); |
316 | | void readAomModel(AomFilmGrainCharacteristics* m_aomFilmGrain, FILE* Aomfilmgrain); |
317 | | }; |
318 | | } |
319 | | |
320 | | #endif // ifndef X265_FRAMEENCODER_H |