#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 {
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));
}
};
struct CTURow
{
Entropy bufferedEntropy;
Entropy rowGoOnCoder;
unsigned int sliceId;
FrameStats rowStats;
Lock lock;
volatile bool active;
volatile bool busy;
volatile uint32_t completed;
volatile uint32_t avgQPComputed;
void init(Entropy& initContext, unsigned int sid)
{
active = false;
busy = false;
completed = 0;
avgQPComputed = 0;
sliceId = sid;
memset(&rowStats, 0, sizeof(rowStats));
rowGoOnCoder.load(initContext);
}
};
class FrameEncoder : public WaveFront, public Thread
{
public:
FrameEncoder();
virtual ~FrameEncoder() {}
virtual bool init(Encoder *top, int numRows, int numCols);
void destroy();
bool startCompressFrame(Frame* curFrame);
Frame *getEncodedPicture(NALList& list);
Event m_enable;
Event m_done;
Event m_completionEvent;
int m_localTldIdx;
bool m_reconfigure;
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;
uint16_t m_sliceAddrBits;
uint16_t m_sliceGroupSize;
uint32_t* m_sliceBaseRow;
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;
volatile int m_totalActiveWorkerCount;
volatile int m_activeWorkerCountSamples;
volatile int m_countRowBlocks;
int64_t m_startCompressTime;
int64_t m_row0WaitTime;
int64_t m_allRowsAvailableTime;
int64_t m_endCompressTime;
int64_t m_endFrameTime;
int64_t m_stallStartTime;
int64_t m_prevOutputTime;
int64_t m_slicetypeWaitTime;
int64_t m_totalWorkerElapsedTime;
int64_t m_totalNoWorkerTime;
#if DETAILED_CU_STATS
CUStats m_cuStats;
#endif
Encoder* m_top;
x265_param* m_param;
Frame* m_frame;
NoiseReduction* m_nr;
ThreadLocalData* m_tld;
Bitstream* m_outStreams;
Bitstream* m_backupStreams;
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();
void compressFrame();
void encodeSlice(uint32_t sliceAddr);
void threadMain();
int collectCTUStatistics(const CUData& ctu, FrameStats* frameLog);
void noiseReductionUpdate();
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