Update changelog.
[deb_x265.git] / source / encoder / frameencoder.h
CommitLineData
72b9787e
JB
1/*****************************************************************************
2 * Copyright (C) 2013 x265 project
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
44namespace x265 {
45// private x265 namespace
46
47class ThreadPool;
48class Encoder;
49
50#define ANGULAR_MODE_ID 2
51#define AMP_ID 3
52#define INTER_MODES 4
53#define INTRA_MODES 3
54
55struct StatisticLog
56{
57 uint64_t cntInter[4];
58 uint64_t cntIntra[4];
59 uint64_t cuInterDistribution[4][INTER_MODES];
60 uint64_t cuIntraDistribution[4][INTRA_MODES];
61 uint64_t cntIntraNxN;
62 uint64_t cntSkipCu[4];
63 uint64_t cntTotalCu[4];
64 uint64_t totalCu;
65
66 /* These states store the count of inter,intra and skip ctus within quad tree structure of each CU */
67 uint32_t qTreeInterCnt[4];
68 uint32_t qTreeIntraCnt[4];
69 uint32_t qTreeSkipCnt[4];
70
71 StatisticLog()
72 {
73 memset(this, 0, sizeof(StatisticLog));
74 }
75};
76
77/* manages the state of encoding one row of CTU blocks. When
78 * WPP is active, several rows will be simultaneously encoded. */
79struct CTURow
80{
81 Entropy bufferedEntropy; /* store CTU2 context for next row CTU0 */
82 Entropy rowGoOnCoder; /* store context between CTUs, code bitstream if !SAO */
83
84 FrameStats rowStats;
85
86 /* Threading variables */
87
88 /* This lock must be acquired when reading or writing m_active or m_busy */
89 Lock lock;
90
91 /* row is ready to run, has no neighbor dependencies. The row may have
92 * external dependencies (reference frame pixels) that prevent it from being
93 * processed, so it may stay with m_active=true for some time before it is
94 * encoded by a worker thread. */
95 volatile bool active;
96
97 /* row is being processed by a worker thread. This flag is only true when a
98 * worker thread is within the context of FrameEncoder::processRow(). This
99 * flag is used to detect multiple possible wavefront problems. */
100 volatile bool busy;
101
102 /* count of completed CUs in this row */
103 volatile uint32_t completed;
104
105 /* called at the start of each frame to initialize state */
106 void init(Entropy& initContext)
107 {
108 active = false;
109 busy = false;
110 completed = 0;
111 memset(&rowStats, 0, sizeof(rowStats));
112 rowGoOnCoder.load(initContext);
113 }
114};
115
116// Manages the wave-front processing of a single encoding frame
117class FrameEncoder : public WaveFront, public Thread
118{
119public:
120
121 FrameEncoder();
122
123 virtual ~FrameEncoder() {}
124
125 bool init(Encoder *top, int numRows, int numCols, int id);
126
127 void destroy();
128
129 /* triggers encode of a new frame by the worker thread */
130 bool startCompressFrame(Frame* curFrame);
131
132 /* blocks until worker thread is done, returns access unit */
133 Frame *getEncodedPicture(NALList& list);
134
135 Event m_enable;
136 Event m_done;
137 bool m_threadActive;
138
139 int m_numRows;
140 uint32_t m_numCols;
141 int m_refLagRows;
142 CTURow* m_rows;
143 RateControlEntry m_rce;
144 SEIDecodedPictureHash m_seiReconPictureDigest;
145
146 uint64_t m_SSDY;
147 uint64_t m_SSDU;
148 uint64_t m_SSDV;
149 double m_ssim;
150 uint32_t m_ssimCnt;
151 MD5Context m_state[3];
152 uint32_t m_crc[3];
153 uint32_t m_checksum[3];
154 double m_elapsedCompressTime; // elapsed time spent in worker threads
155 double m_frameTime; // wall time from frame start to finish
156 StatisticLog m_sliceTypeLog[3]; // per-slice type CU statistics
157 FrameStats m_frameStats; // stats of current frame for multi-pass encodes
158 volatile bool m_bAllRowsStop;
159 volatile int m_vbvResetTriggerRow;
160 uint64_t m_accessUnitBits;
161
162 Encoder* m_top;
163 x265_param* m_param;
164 Frame* m_frame;
165 NoiseReduction* m_nr;
166 ThreadLocalData* m_tld; /* for --no-wpp */
167 Bitstream* m_outStreams;
168 uint32_t* m_substreamSizes;
169
170 CUGeom* m_cuGeoms;
171 uint32_t* m_ctuGeomMap;
172
173 Bitstream m_bs;
174 MotionReference m_mref[2][MAX_NUM_REF + 1];
175 Entropy m_entropyCoder;
176 Entropy m_initSliceContext;
177 FrameFilter m_frameFilter;
178 NALList m_nalList;
179
180 int m_filterRowDelay;
181 int m_filterRowDelayCus;
182 Event m_completionEvent;
183 int64_t m_totalTime;
184 int m_frameEncoderID;
185
186protected:
187
188 bool initializeGeoms(const FrameData& encData);
189
190 /* analyze / compress frame, can be run in parallel within reference constraints */
191 void compressFrame();
192
193 /* called by compressFrame to perform wave-front compression analysis */
194 void compressCTURows();
195
196 /* called by compressFrame to generate final per-row bitstreams */
197 void encodeSlice();
198
199 void threadMain();
200 int calcQpForCu(uint32_t cuAddr, double baseQp);
201 void collectCTUStatistics(CUData& ctu);
202 void noiseReductionUpdate();
203
204 /* Called by WaveFront::findJob() */
205 void processRow(int row, int threadId);
206 void processRowEncoder(int row, ThreadLocalData& tld);
207 void processRowFilter(int row) { m_frameFilter.processRow(row); }
208
209 void enqueueRowEncoder(int row) { WaveFront::enqueueRow(row * 2 + 0); }
210 void enqueueRowFilter(int row) { WaveFront::enqueueRow(row * 2 + 1); }
211 void enableRowEncoder(int row) { WaveFront::enableRow(row * 2 + 0); }
212 void enableRowFilter(int row) { WaveFront::enableRow(row * 2 + 1); }
213};
214}
215
216#endif // ifndef X265_FRAMEENCODER_H