X-Git-Url: https://git.piment-noir.org/?p=deb_x265.git;a=blobdiff_plain;f=source%2Fencoder%2Fsearch.h;h=a59fbf35c0ba4fd32ba1c82dc73d526d84529f6f;hp=79ed94a79e8e1f44b6e81d8db2b1126d69a29508;hb=b53f7c52d8280ab63876efd6eb292c21430ac607;hpb=5c9b45285dd64723ad1dac380b98a7b1f3095674 diff --git a/source/encoder/search.h b/source/encoder/search.h index 79ed94a..a59fbf3 100644 --- a/source/encoder/search.h +++ b/source/encoder/search.h @@ -35,9 +35,6 @@ #include "entropy.h" #include "motion.h" -#define MVP_IDX_BITS 1 -#define NUM_LAYERS 4 - namespace x265 { // private namespace @@ -68,6 +65,64 @@ struct RQTData Yuv bidirPredYuv[2]; }; +struct MotionData +{ + MV mv; + MV mvp; + int mvpIdx; + int ref; + uint32_t cost; + int bits; + bool costZero; +}; + +struct Mode +{ + CUData cu; + const Yuv* fencYuv; + Yuv predYuv; + Yuv reconYuv; + Entropy contexts; + + enum { MAX_INTER_PARTS = 2 }; + + MotionData bestME[MAX_INTER_PARTS][2]; + MV amvpCand[2][MAX_NUM_REF][AMVP_NUM_CANDS]; + + uint64_t rdCost; // sum of partition (psy) RD costs (sse(fenc, recon) + lambda2 * bits) + uint64_t sa8dCost; // sum of partition sa8d distortion costs (sa8d(fenc, pred) + lambda * bits) + uint32_t sa8dBits; // signal bits used in sa8dCost calculation + uint32_t psyEnergy; // sum of partition psycho-visual energy difference + uint32_t distortion; // sum of partition SSE distortion + uint32_t totalBits; // sum of partition bits (mv + coeff) + uint32_t mvBits; // Mv bits + Ref + block type (or intra mode) + uint32_t coeffBits; // Texture bits (DCT Coeffs) + + void initCosts() + { + rdCost = 0; + sa8dCost = 0; + sa8dBits = 0; + psyEnergy = 0; + distortion = 0; + totalBits = 0; + mvBits = 0; + coeffBits = 0; + } + + void addSubCosts(const Mode& subMode) + { + rdCost += subMode.rdCost; + sa8dCost += subMode.sa8dCost; + sa8dBits += subMode.sa8dBits; + psyEnergy += subMode.psyEnergy; + distortion += subMode.distortion; + totalBits += subMode.totalBits; + mvBits += subMode.mvBits; + coeffBits += subMode.coeffBits; + } +}; + inline int getTUBits(int idx, int numIdx) { return idx + (idx < numIdx - 1); @@ -98,58 +153,6 @@ public: uint32_t m_numLayers; uint32_t m_refLagPixels; - struct Mode - { - CUData cu; - const Yuv* fencYuv; - Yuv predYuv; - Yuv reconYuv; - Entropy contexts; - - uint64_t rdCost; // sum of partition (psy) RD costs (sse(fenc, recon) + lambda2 * bits) - uint64_t sa8dCost; // sum of partition sa8d distortion costs (sa8d(fenc, pred) + lambda * bits) - uint32_t sa8dBits; // signal bits used in sa8dCost calculation - uint32_t psyEnergy; // sum of partition psycho-visual energy difference - uint32_t distortion; // sum of partition SSE distortion - uint32_t totalBits; // sum of partition bits (mv + coeff) - uint32_t mvBits; // Mv bits + Ref + block type (or intra mode) - uint32_t coeffBits; // Texture bits (DCT Coeffs) - - void initCosts() - { - rdCost = 0; - sa8dCost = 0; - sa8dBits = 0; - psyEnergy = 0; - distortion = 0; - totalBits = 0; - mvBits = 0; - coeffBits = 0; - } - - void addSubCosts(const Mode& subMode) - { - rdCost += subMode.rdCost; - sa8dCost += subMode.sa8dCost; - sa8dBits += subMode.sa8dBits; - psyEnergy += subMode.psyEnergy; - distortion += subMode.distortion; - totalBits += subMode.totalBits; - mvBits += subMode.mvBits; - coeffBits += subMode.coeffBits; - } - }; - - struct MotionData - { - MV mv; - MV mvp; - int mvpIdx; - int ref; - uint32_t cost; - int bits; - }; - Search(); ~Search(); @@ -162,6 +165,11 @@ public: // full RD search of intra modes. if sharedModes is not NULL, it directly uses them void checkIntra(Mode& intraMode, const CUGeom& cuGeom, PartSize partSize, uint8_t* sharedModes); + // select best intra mode using only sa8d costs, cannot measure NxN intra + void checkIntraInInter(Mode& intraMode, const CUGeom& cuGeom); + // encode luma mode selected by checkIntraInInter, then pick and encode a chroma mode + void encodeIntraInInter(Mode& intraMode, const CUGeom& cuGeom); + // estimation inter prediction (non-skip) bool predInterSearch(Mode& interMode, const CUGeom& cuGeom, bool bMergeOnly, bool bChroma); @@ -169,38 +177,41 @@ public: void encodeResAndCalcRdInterCU(Mode& interMode, const CUGeom& cuGeom); void encodeResAndCalcRdSkipCU(Mode& interMode); - void generateCoeffRecon(Mode& mode, const CUGeom& cuGeom); - void residualTransformQuantInter(Mode& mode, const CUGeom& cuGeom, uint32_t absPartIdx, uint32_t depth, uint32_t depthRange[2]); + // encode residual without rd-cost + void residualTransformQuantInter(Mode& mode, const CUGeom& cuGeom, uint32_t absPartIdx, uint32_t depth, const uint32_t depthRange[2]); + void residualTransformQuantIntra(Mode& mode, const CUGeom& cuGeom, uint32_t tuDepth, uint32_t absPartIdx, const uint32_t depthRange[2]); + void residualQTIntraChroma(Mode& mode, const CUGeom& cuGeom, uint32_t tuDepth, uint32_t absPartIdx); - uint32_t getIntraRemModeBits(CUData & cu, uint32_t absPartIdx, uint32_t preds[3], uint64_t& mpms) const; + // pick be chroma mode from available using just sa8d costs + void getBestIntraModeChroma(Mode& intraMode, const CUGeom& cuGeom); protected: /* motion estimation distribution */ ThreadLocalData* m_tld; - CUData* m_curMECu; + Mode* m_curInterMode; const CUGeom* m_curGeom; int m_curPart; - MotionData m_bestME[2]; uint32_t m_listSelBits[3]; int m_totalNumME; volatile int m_numAcquiredME; volatile int m_numCompletedME; Event m_meCompletionEvent; - Lock m_outputLock; + Lock m_meLock; bool m_bJobsQueued; - void singleMotionEstimation(Search& master, const CUData& cu, const CUGeom& cuGeom, int part, int list, int ref); + void singleMotionEstimation(Search& master, Mode& interMode, const CUGeom& cuGeom, int part, int list, int ref); void saveResidualQTData(CUData& cu, ShortYuv& resiYuv, uint32_t absPartIdx, uint32_t depth); // RDO search of luma intra modes; result is fully encoded luma. luma distortion is returned - uint32_t estIntraPredQT(Mode &intraMode, const CUGeom& cuGeom, uint32_t depthRange[2], uint8_t* sharedModes); + uint32_t estIntraPredQT(Mode &intraMode, const CUGeom& cuGeom, const uint32_t depthRange[2], uint8_t* sharedModes); // RDO select best chroma mode from luma; result is fully encode chroma. chroma distortion is returned uint32_t estIntraPredChromaQT(Mode &intraMode, const CUGeom& cuGeom); - void codeSubdivCbfQTChroma(const CUData& cu, uint32_t trDepth, uint32_t absPartIdx, uint32_t absPartIdxStep, uint32_t width, uint32_t height); - void codeCoeffQTChroma(const CUData& cu, uint32_t trDepth, uint32_t absPartIdx, TextType ttype); + void codeSubdivCbfQTChroma(const CUData& cu, uint32_t tuDepth, uint32_t absPartIdx); + void codeInterSubdivCbfQT(CUData& cu, uint32_t absPartIdx, const uint32_t depth, const uint32_t depthRange[2]); + void codeCoeffQTChroma(const CUData& cu, uint32_t tuDepth, uint32_t absPartIdx, TextType ttype); struct Cost { @@ -211,24 +222,24 @@ protected: Cost() { rdcost = 0; bits = 0; distortion = 0; energy = 0; } }; - void estimateResidualQT(Mode& mode, const CUGeom& cuGeom, uint32_t absPartIdx, uint32_t depth, ShortYuv& resiYuv, Cost& costs, uint32_t depthRange[2]); + uint64_t estimateNullCbfCost(uint32_t &dist, uint32_t &psyEnergy, uint32_t tuDepth, TextType compId); + void estimateResidualQT(Mode& mode, const CUGeom& cuGeom, uint32_t absPartIdx, uint32_t depth, ShortYuv& resiYuv, Cost& costs, const uint32_t depthRange[2]); - void encodeResidualQT(CUData& cu, uint32_t absPartIdx, uint32_t depth, bool bSubdivAndCbf, TextType ttype, uint32_t depthRange[2]); + // estimate bit cost of residual QT + void encodeResidualQT(CUData& cu, uint32_t absPartIdx, uint32_t depth, TextType ttype, const uint32_t depthRange[2]); // generate prediction, generate residual and recon. if bAllowSplit, find optimal RQT splits - void codeIntraLumaQT(Mode& mode, const CUGeom& cuGeom, uint32_t trDepth, uint32_t absPartIdx, bool bAllowSplit, Cost& costs, uint32_t depthRange[2]); - void codeIntraLumaTSkip(Mode& mode, const CUGeom& cuGeom, uint32_t trDepth, uint32_t absPartIdx, Cost& costs); - void extractIntraResultQT(CUData& cu, Yuv& reconYuv, uint32_t trDepth, uint32_t absPartIdx); + void codeIntraLumaQT(Mode& mode, const CUGeom& cuGeom, uint32_t tuDepth, uint32_t absPartIdx, bool bAllowSplit, Cost& costs, const uint32_t depthRange[2]); + void codeIntraLumaTSkip(Mode& mode, const CUGeom& cuGeom, uint32_t tuDepth, uint32_t absPartIdx, Cost& costs); + void extractIntraResultQT(CUData& cu, Yuv& reconYuv, uint32_t tuDepth, uint32_t absPartIdx); // generate chroma prediction, generate residual and recon - uint32_t codeIntraChromaQt(Mode& mode, const CUGeom& cuGeom, uint32_t trDepth, uint32_t absPartIdx, uint32_t& psyEnergy); - uint32_t codeIntraChromaTSkip(Mode& mode, const CUGeom& cuGeom, uint32_t trDepth, uint32_t trDepthC, uint32_t absPartIdx, uint32_t& psyEnergy); - void extractIntraResultChromaQT(CUData& cu, Yuv& reconYuv, uint32_t absPartIdx, uint32_t trDepth, bool tuQuad); - - void residualTransformQuantIntra(Mode& mode, const CUGeom& cuGeom, uint32_t trDepth, uint32_t absPartIdx, uint32_t depthRange[2]); - void residualQTIntraChroma(Mode& mode, const CUGeom& cuGeom, uint32_t trDepth, uint32_t absPartIdx); + uint32_t codeIntraChromaQt(Mode& mode, const CUGeom& cuGeom, uint32_t tuDepth, uint32_t absPartIdx, uint32_t& psyEnergy); + uint32_t codeIntraChromaTSkip(Mode& mode, const CUGeom& cuGeom, uint32_t tuDepth, uint32_t tuDepthC, uint32_t absPartIdx, uint32_t& psyEnergy); + void extractIntraResultChromaQT(CUData& cu, Yuv& reconYuv, uint32_t absPartIdx, uint32_t tuDepth); - void offsetSubTUCBFs(CUData& cu, TextType ttype, uint32_t trDepth, uint32_t absPartIdx); + // reshuffle CBF flags after coding a pair of 4:2:2 chroma blocks + void offsetSubTUCBFs(CUData& cu, TextType ttype, uint32_t tuDepth, uint32_t absPartIdx); struct MergeData { @@ -258,7 +269,9 @@ protected: /* intra helper functions */ enum { MAX_RD_INTRA_MODES = 16 }; static void updateCandList(uint32_t mode, uint64_t cost, int maxCandCount, uint32_t* candModeList, uint64_t* candCostList); - void getBestIntraModeChroma(Mode& intraMode, const CUGeom& cuGeom); + + // get most probable luma modes for CU part, and bit cost of all non mpm modes + uint32_t getIntraRemModeBits(CUData & cu, uint32_t absPartIdx, uint32_t preds[3], uint64_t& mpms) const; void updateModeCost(Mode& m) const { m.rdCost = m_rdCost.m_psyRd ? m_rdCost.calcPsyRdCost(m.distortion, m.totalBits, m.psyEnergy) : m_rdCost.calcRdCost(m.distortion, m.totalBits); } };