[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