#include "entropy.h"
#include "motion.h"
-#define MVP_IDX_BITS 1
-#define NUM_LAYERS 4
-
namespace x265 {
// private namespace
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);
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();
// 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);
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
{
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
{
/* 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); }
};