[x265] [PATCH 2 of 4] search: introduce selectMVP helper method
Steve Borho
steve at borho.org
Thu Apr 30 03:09:48 CEST 2015
# HG changeset patch
# User Steve Borho <steve at borho.org>
# Date 1430336448 18000
# Wed Apr 29 14:40:48 2015 -0500
# Node ID cfa2dc688db15171115684527a174252237ed85c
# Parent 03d98ec0612a7ebf8d7fb2ceb1c0b6da797fb914
search: introduce selectMVP helper method
diff -r 03d98ec0612a -r cfa2dc688db1 source/encoder/search.cpp
--- a/source/encoder/search.cpp Wed Apr 29 12:36:21 2015 -0500
+++ b/source/encoder/search.cpp Wed Apr 29 14:40:48 2015 -0500
@@ -1979,6 +1979,32 @@
}
}
+/* Pick between the two AMVP candidates which is the best one to use as
+ * MVP for the motion search, based on SAD cost */
+int Search::selectMVP(const CUData& cu, const PredictionUnit& pu, const MV amvp[AMVP_NUM_CANDS], int list, int ref)
+{
+ if (amvp[0] == amvp[1])
+ return 0;
+
+ Yuv& tmpPredYuv = m_rqt[cu.m_cuDepth[0]].tmpPredYuv;
+ uint32_t costs[AMVP_NUM_CANDS];
+
+ for (int i = 0; i < AMVP_NUM_CANDS; i++)
+ {
+ MV mvCand = amvp[i];
+
+ // NOTE: skip mvCand if Y is > merange and -FN>1
+ if (m_bFrameParallel && (mvCand.y >= (m_param->searchRange + 1) * 4))
+ continue;
+
+ cu.clipMv(mvCand);
+ predInterLumaPixel(pu, tmpPredYuv, *m_slice->m_refPicList[list][ref]->m_reconPic, mvCand);
+ costs[i] = m_me.bufSAD(tmpPredYuv.getLumaAddr(pu.puAbsPartIdx), tmpPredYuv.m_size);
+ }
+
+ return costs[0] <= costs[1] ? 0 : 1;
+}
+
/* find the best inter prediction for each PU of specified mode */
void Search::predInterSearch(Mode& interMode, const CUGeom& cuGeom, bool bMergeOnly, bool bChromaSA8D)
{
@@ -2053,39 +2079,12 @@
int numMvc = cu.getPMV(interMode.interNeighbours, list, ref, interMode.amvpCand[list][ref], mvc);
- // Pick the best possible MVP from AMVP candidates based on least residual
- int mvpIdx = 0;
- int merange = m_param->searchRange;
const MV* amvp = interMode.amvpCand[list][ref];
-
- if (amvp[0] != amvp[1])
- {
- uint32_t bestCost = MAX_INT;
- for (int i = 0; i < AMVP_NUM_CANDS; i++)
- {
- MV mvCand = amvp[i];
-
- // NOTE: skip mvCand if Y is > merange and -FN>1
- if (m_bFrameParallel && (mvCand.y >= (merange + 1) * 4))
- continue;
-
- cu.clipMv(mvCand);
- predInterLumaPixel(pu, tmpPredYuv, *slice->m_refPicList[list][ref]->m_reconPic, mvCand);
- uint32_t cost = m_me.bufSAD(tmpPredYuv.getLumaAddr(pu.puAbsPartIdx), tmpPredYuv.m_size);
-
- if (bestCost > cost)
- {
- bestCost = cost;
- mvpIdx = i;
- }
- }
- }
-
+ int mvpIdx = selectMVP(cu, pu, amvp, list, ref);
MV mvmin, mvmax, outmv, mvp = amvp[mvpIdx];
- int satdCost;
- setSearchRange(cu, mvp, merange, mvmin, mvmax);
- satdCost = m_me.motionEstimate(&slice->m_mref[list][ref], mvmin, mvmax, mvp, numMvc, mvc, merange, outmv);
+ setSearchRange(cu, mvp, m_param->searchRange, mvmin, mvmax);
+ int satdCost = m_me.motionEstimate(&slice->m_mref[list][ref], mvmin, mvmax, mvp, numMvc, mvc, m_param->searchRange, outmv);
/* Get total cost of partition, but only include MV bit cost once */
bits += m_me.bitcost(outmv);
@@ -2137,38 +2136,12 @@
int numMvc = cu.getPMV(interMode.interNeighbours, list, ref, interMode.amvpCand[list][ref], mvc);
- // Pick the best possible MVP from AMVP candidates based on least residual
- int mvpIdx = 0;
- int merange = m_param->searchRange;
const MV* amvp = interMode.amvpCand[list][ref];
-
- if (amvp[0] != amvp[1])
- {
- uint32_t bestCost = MAX_INT;
- for (int i = 0; i < AMVP_NUM_CANDS; i++)
- {
- MV mvCand = amvp[i];
-
- // NOTE: skip mvCand if Y is > merange and -FN>1
- if (m_bFrameParallel && (mvCand.y >= (merange + 1) * 4))
- continue;
-
- cu.clipMv(mvCand);
- predInterLumaPixel(pu, tmpPredYuv, *slice->m_refPicList[list][ref]->m_reconPic, mvCand);
- uint32_t cost = m_me.bufSAD(tmpPredYuv.getLumaAddr(pu.puAbsPartIdx), tmpPredYuv.m_size);
-
- if (bestCost > cost)
- {
- bestCost = cost;
- mvpIdx = i;
- }
- }
- }
-
+ int mvpIdx = selectMVP(cu, pu, amvp, list, ref);
MV mvmin, mvmax, outmv, mvp = amvp[mvpIdx];
- setSearchRange(cu, mvp, merange, mvmin, mvmax);
- int satdCost = m_me.motionEstimate(&slice->m_mref[list][ref], mvmin, mvmax, mvp, numMvc, mvc, merange, outmv);
+ setSearchRange(cu, mvp, m_param->searchRange, mvmin, mvmax);
+ int satdCost = m_me.motionEstimate(&slice->m_mref[list][ref], mvmin, mvmax, mvp, numMvc, mvc, m_param->searchRange, outmv);
/* Get total cost of partition, but only include MV bit cost once */
bits += m_me.bitcost(outmv);
diff -r 03d98ec0612a -r cfa2dc688db1 source/encoder/search.h
--- a/source/encoder/search.h Wed Apr 29 12:36:21 2015 -0500
+++ b/source/encoder/search.h Wed Apr 29 14:40:48 2015 -0500
@@ -396,6 +396,7 @@
};
/* inter/ME helper functions */
+ int selectMVP(const CUData& cu, const PredictionUnit& pu, const MV amvp[AMVP_NUM_CANDS], int list, int ref);
const MV& checkBestMVP(const MV amvpCand[2], const MV& mv, int& mvpIdx, uint32_t& outBits, uint32_t& outCost) const;
void setSearchRange(const CUData& cu, MV mvp, int merange, MV& mvmin, MV& mvmax) const;
uint32_t mergeEstimation(CUData& cu, const CUGeom& cuGeom, const PredictionUnit& pu, int puIdx, MergeData& m);
More information about the x265-devel
mailing list