Mercurial > hg > forks > libbpg
diff x265/source/encoder/frameencoder.h @ 0:772086c29cc7
Initial import.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Wed, 16 Nov 2016 11:16:33 +0200 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/x265/source/encoder/frameencoder.h Wed Nov 16 11:16:33 2016 +0200 @@ -0,0 +1,234 @@ +/***************************************************************************** + * Copyright (C) 2013 x265 project + * + * Authors: Shin Yee <shinyee@multicorewareinc.com> + * Min Chen <chenm003@163.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA. + * + * This program is also available under a commercial proprietary license. + * For more information, contact us at license @ x265.com. + *****************************************************************************/ + +#ifndef X265_FRAMEENCODER_H +#define X265_FRAMEENCODER_H + +#include "common.h" +#include "wavefront.h" +#include "bitstream.h" +#include "frame.h" +#include "picyuv.h" +#include "md5.h" + +#include "analysis.h" +#include "sao.h" + +#include "entropy.h" +#include "framefilter.h" +#include "ratecontrol.h" +#include "reference.h" +#include "nal.h" + +namespace X265_NS { +// private x265 namespace + +class ThreadPool; +class Encoder; + +#define ANGULAR_MODE_ID 2 +#define AMP_ID 3 + +struct StatisticLog +{ + uint64_t cntInter[4]; + uint64_t cntIntra[4]; + uint64_t cuInterDistribution[4][INTER_MODES]; + uint64_t cuIntraDistribution[4][INTRA_MODES]; + uint64_t cntIntraNxN; + uint64_t cntSkipCu[4]; + uint64_t cntTotalCu[4]; + uint64_t totalCu; + + StatisticLog() + { + memset(this, 0, sizeof(StatisticLog)); + } +}; + +/* manages the state of encoding one row of CTU blocks. When + * WPP is active, several rows will be simultaneously encoded. */ +struct CTURow +{ + Entropy bufferedEntropy; /* store CTU2 context for next row CTU0 */ + Entropy rowGoOnCoder; /* store context between CTUs, code bitstream if !SAO */ + + FrameStats rowStats; + + /* Threading variables */ + + /* This lock must be acquired when reading or writing m_active or m_busy */ + Lock lock; + + /* row is ready to run, has no neighbor dependencies. The row may have + * external dependencies (reference frame pixels) that prevent it from being + * processed, so it may stay with m_active=true for some time before it is + * encoded by a worker thread. */ + volatile bool active; + + /* row is being processed by a worker thread. This flag is only true when a + * worker thread is within the context of FrameEncoder::processRow(). This + * flag is used to detect multiple possible wavefront problems. */ + volatile bool busy; + + /* count of completed CUs in this row */ + volatile uint32_t completed; + + /* called at the start of each frame to initialize state */ + void init(Entropy& initContext) + { + active = false; + busy = false; + completed = 0; + memset(&rowStats, 0, sizeof(rowStats)); + rowGoOnCoder.load(initContext); + } +}; + +// Manages the wave-front processing of a single encoding frame +class FrameEncoder : public WaveFront, public Thread +{ +public: + + FrameEncoder(); + + virtual ~FrameEncoder() {} + + virtual bool init(Encoder *top, int numRows, int numCols); + + void destroy(); + + /* triggers encode of a new frame by the worker thread */ + bool startCompressFrame(Frame* curFrame); + + /* blocks until worker thread is done, returns access unit */ + Frame *getEncodedPicture(NALList& list); + + Event m_enable; + Event m_done; + Event m_completionEvent; + int m_localTldIdx; + + volatile bool m_threadActive; + volatile bool m_bAllRowsStop; + volatile int m_completionCount; + volatile int m_vbvResetTriggerRow; + + uint32_t m_numRows; + uint32_t m_numCols; + uint32_t m_filterRowDelay; + uint32_t m_filterRowDelayCus; + uint32_t m_refLagRows; + + CTURow* m_rows; + RateControlEntry m_rce; + SEIDecodedPictureHash m_seiReconPictureDigest; + + uint64_t m_SSDY; + uint64_t m_SSDU; + uint64_t m_SSDV; + double m_ssim; + uint64_t m_accessUnitBits; + uint32_t m_ssimCnt; + MD5Context m_state[3]; + uint32_t m_crc[3]; + uint32_t m_checksum[3]; + + volatile int m_activeWorkerCount; // count of workers currently encoding or filtering CTUs + volatile int m_totalActiveWorkerCount; // sum of m_activeWorkerCount sampled at end of each CTU + volatile int m_activeWorkerCountSamples; // count of times m_activeWorkerCount was sampled (think vbv restarts) + volatile int m_countRowBlocks; // count of workers forced to abandon a row because of top dependency + int64_t m_startCompressTime; // timestamp when frame encoder is given a frame + int64_t m_row0WaitTime; // timestamp when row 0 is allowed to start + int64_t m_allRowsAvailableTime; // timestamp when all reference dependencies are resolved + int64_t m_endCompressTime; // timestamp after all CTUs are compressed + int64_t m_endFrameTime; // timestamp after RCEnd, NR updates, etc + int64_t m_stallStartTime; // timestamp when worker count becomes 0 + int64_t m_prevOutputTime; // timestamp when prev frame was retrieved by API thread + int64_t m_slicetypeWaitTime; // total elapsed time waiting for decided frame + int64_t m_totalWorkerElapsedTime; // total elapsed time spent by worker threads processing CTUs + int64_t m_totalNoWorkerTime; // total elapsed time without any active worker threads +#if DETAILED_CU_STATS + CUStats m_cuStats; +#endif + + Encoder* m_top; + x265_param* m_param; + Frame* m_frame; + NoiseReduction* m_nr; + ThreadLocalData* m_tld; /* for --no-wpp */ + Bitstream* m_outStreams; + uint32_t* m_substreamSizes; + + CUGeom* m_cuGeoms; + uint32_t* m_ctuGeomMap; + + Bitstream m_bs; + MotionReference m_mref[2][MAX_NUM_REF + 1]; + Entropy m_entropyCoder; + Entropy m_initSliceContext; + FrameFilter m_frameFilter; + NALList m_nalList; + + class WeightAnalysis : public BondedTaskGroup + { + public: + + FrameEncoder& master; + + WeightAnalysis(FrameEncoder& fe) : master(fe) {} + + void processTasks(int workerThreadId); + + protected: + + WeightAnalysis operator=(const WeightAnalysis&); + }; + +protected: + + bool initializeGeoms(); + + /* analyze / compress frame, can be run in parallel within reference constraints */ + void compressFrame(); + + /* called by compressFrame to generate final per-row bitstreams */ + void encodeSlice(); + + void threadMain(); + int collectCTUStatistics(const CUData& ctu, FrameStats* frameLog); + void noiseReductionUpdate(); + + /* Called by WaveFront::findJob() */ + virtual void processRow(int row, int threadId); + virtual void processRowEncoder(int row, ThreadLocalData& tld); + + void enqueueRowEncoder(int row) { WaveFront::enqueueRow(row * 2 + 0); } + void enqueueRowFilter(int row) { WaveFront::enqueueRow(row * 2 + 1); } + void enableRowEncoder(int row) { WaveFront::enableRow(row * 2 + 0); } + void enableRowFilter(int row) { WaveFront::enableRow(row * 2 + 1); } +}; +} + +#endif // ifndef X265_FRAMEENCODER_H