[x265] [PATCH] dpb: select best TMVP candidate from among all of the reference frames
Steve Borho
steve at borho.org
Tue Sep 9 13:44:06 CEST 2014
On 09/09, gopu at multicorewareinc.com wrote:
> # HG changeset patch
> # User Gopu Govindaswamy <gopu at multicorewareinc.com>
> # Date 1410236940 -19800
> # Tue Sep 09 09:59:00 2014 +0530
> # Node ID 88b0307c69c39c1dc9829922d6fcf37d828bd63d
> # Parent b5f81a83940396c241d33c8f15a5ef48de9cd62e
> dpb: select best TMVP candidate from among all of the reference frames
>
> diff -r b5f81a839403 -r 88b0307c69c3 source/encoder/dpb.cpp
> --- a/source/encoder/dpb.cpp Mon Sep 08 22:40:00 2014 +0200
> +++ b/source/encoder/dpb.cpp Tue Sep 09 09:59:00 2014 +0530
> @@ -87,7 +87,7 @@
> }
> }
>
> -void DPB::prepareEncode(Frame *pic)
> +void DPB::prepareEncode(Frame *pic, x265_param *param)
> {
> Slice* slice = pic->m_picSym->m_slice;
> slice->m_pic = pic;
> @@ -142,35 +142,69 @@
>
> X265_CHECK(slice->m_sliceType != B_SLICE || slice->m_numRefIdx[1], "B slice without L1 references (non-fatal)\n");
>
> - if (slice->m_sliceType == B_SLICE)
> + if (param->bFrameAdaptive == X265_B_ADAPT_TRELLIS)
it might be cleaner to simply check for I_SLICE here and bypass all this
below. slice->m_colFromL0Flag and friends aren't signaled for I slices
> {
> - /* TODO: the lookahead should be able to tell which reference picture
> - * had the least motion residual. We should be able to use that here to
> - * select a colocation reference list and index */
> - slice->m_colFromL0Flag = false;
> - slice->m_colRefIdx = 0;
> - slice->m_bCheckLDC = false;
> + int64_t bestCost = MAX_INT64;
> + int32_t refIdx = 0, lIdx = 0;
> + for (int ref = 0; ref < slice->m_numRefIdx[lIdx]; ref++)
> + {
> + Frame *refpic = slice->m_refPicList[lIdx][ref];
> + int64_t cost = refpic->m_lowres.costEst[slice->m_poc - refpic->m_POC][lIdx];
it's possible for cost to be negative (un-measured) and also for the POC
diff to be out-of-range for the lookahead B frame distance. distance
must be checked before dereferencing, and negative cost needs to be
checked before comparison
also, I don't think it should be using the refpic' lowres costs. if so,
the indices should be in the other direction.
> + if (bestCost > cost)
> + {
> + bestCost = cost;
> + refIdx = ref;
> + }
> + ATOMIC_INC(&refpic->m_countRefEncoders);
> + }
> + if (slice->m_sliceType == B_SLICE)
> + {
> + refIdx = 0, lIdx = 1;
> + for (int ref = 0; ref < slice->m_numRefIdx[lIdx]; ref++)
> + {
> + Frame *refpic = slice->m_refPicList[lIdx][ref];
> + int64_t cost = refpic->m_lowres.costEst[lIdx][refpic->m_POC - slice->m_poc];
this indexing is very squirrely. I think what you want is the P frame
cost from this ref back to the current picture, under the assumption
that P(ref, pic) is a good estimator of cost from pic -> ref
ditto the details about distance and cost checks here
> + if (bestCost > cost)
> + {
> + bestCost = cost;
> + refIdx = ref;
> + }
> + ATOMIC_INC(&refpic->m_countRefEncoders);
> + }
> + }
> + Frame *refpic = slice->m_refPicList[lIdx][refIdx];
> + if (refpic)
> + {
> + slice->m_colFromL0Flag = refpic->m_picSym->m_slice->m_colFromL0Flag;
> + slice->m_colRefIdx = refpic->m_picSym->m_slice->m_colRefIdx;
this is a double-indirection; I don't follow the logic here. I would
think you would just assign slice->m_colFromL0Flag to !bestList and
slice->m_colRefIdx to bestRef in bestList
> + }
> + else
> + {
> + slice->m_colFromL0Flag = !B_SLICE;
> + slice->m_colRefIdx = 0;
> + }
> }
> else
> {
> - slice->m_bCheckLDC = true;
> - slice->m_colFromL0Flag = true;
> + slice->m_colFromL0Flag = !B_SLICE;
> slice->m_colRefIdx = 0;
> - }
> - slice->m_sLFaseFlag = (SLFASE_CONSTANT & (1 << (pocCurr % 31))) > 0;
>
> - /* Increment reference count of all motion-referenced frames to prevent them
> - * from being recycled. These counts are decremented at the end of
> - * compressFrame() */
> - int numPredDir = slice->isInterP() ? 1 : slice->isInterB() ? 2 : 0;
> - for (int l = 0; l < numPredDir; l++)
> - {
> - for (int ref = 0; ref < slice->m_numRefIdx[l]; ref++)
> + /* Increment reference count of all motion-referenced frames to prevent them
> + * from being recycled. These counts are decremented at the end of
> + * compressFrame() */
> + int numPredDir = slice->isInterP() ? 1 : slice->isInterB() ? 2 : 0;
> + for (int l = 0; l < numPredDir; l++)
> {
> - Frame *refpic = slice->m_refPicList[l][ref];
> - ATOMIC_INC(&refpic->m_countRefEncoders);
> + for (int ref = 0; ref < slice->m_numRefIdx[l]; ref++)
> + {
> + Frame *refpic = slice->m_refPicList[l][ref];
> + ATOMIC_INC(&refpic->m_countRefEncoders);
> + }
> }
> }
> +
> + slice->m_bCheckLDC = slice->m_sliceType != B_SLICE;
> + slice->m_sLFaseFlag = (SLFASE_CONSTANT & (1 << (pocCurr % 31))) > 0;
> }
>
> void DPB::computeRPS(int curPoc, bool isRAP, RPS * rps, unsigned int maxDecPicBuffer)
> diff -r b5f81a839403 -r 88b0307c69c3 source/encoder/dpb.h
> --- a/source/encoder/dpb.h Mon Sep 08 22:40:00 2014 +0200
> +++ b/source/encoder/dpb.h Tue Sep 09 09:59:00 2014 +0530
> @@ -61,7 +61,7 @@
>
> ~DPB();
>
> - void prepareEncode(Frame*);
> + void prepareEncode(Frame*, x265_param*);
>
> void recycleUnreferenced();
>
> diff -r b5f81a839403 -r 88b0307c69c3 source/encoder/encoder.cpp
> --- a/source/encoder/encoder.cpp Mon Sep 08 22:40:00 2014 +0200
> +++ b/source/encoder/encoder.cpp Tue Sep 09 09:59:00 2014 +0530
> @@ -460,7 +460,7 @@
> fenc->m_dts = fenc->m_reorderedPts;
>
> // determine references, setup RPS, etc
> - m_dpb->prepareEncode(fenc);
> + m_dpb->prepareEncode(fenc, m_param);
>
> if (m_param->rc.rateControlMode != X265_RC_CQP)
> m_lookahead->getEstimatedPictureCost(fenc);
> _______________________________________________
> x265-devel mailing list
> x265-devel at videolan.org
> https://mailman.videolan.org/listinfo/x265-devel
--
Steve Borho
More information about the x265-devel
mailing list