[x265] [PATCH] lookahead: Implementation of slicetype_frame_cost

Steve Borho steve at borho.org
Wed Aug 7 20:11:19 CEST 2013


On Wed, Aug 7, 2013 at 2:27 AM, <gopu at multicorewareinc.com> wrote:

> # HG changeset patch
> # User ggopu
> # Date 1375860344 -19800
> # Node ID d2a629c78efdebc317ba1aa96f40e2a7635660c5
> # Parent  e8fed4725b02d17c4a7b9489e383044ca129e162
> lookahead: Implementation of slicetype_frame_cost
>
> diff -r e8fed4725b02 -r d2a629c78efd source/encoder/slicetype.cpp
> --- a/source/encoder/slicetype.cpp      Tue Aug 06 14:20:43 2013 -0500
> +++ b/source/encoder/slicetype.cpp      Wed Aug 07 12:55:44 2013 +0530
> @@ -32,9 +32,197 @@
>  // taking any of the threading changes because we will eventually use the
> x265
>  // thread pool and wavefront processing.
>
> -#include "common/common.h"
> -#include "macroblock.h"
> -#include "me.h"
> +
> +#include "lookahead.h"
> +#include "primitives.h"
> +#include <string.h>
> +#include <stdio.h>
> +#include <assert.h>
> +#include "mv.h"
> +#include "TLibCommon/TComPic.h"
>

includes should be grouped by the folders the headers are included from,
and system headers should be included last


> +
> +
> +#define NUM_MBS\
> +   (pic->getFrameWidthInCU() > 2 && pic->getFrameHeightInCU() > 2 ?\
> +   (pic->getFrameWidthInCU() - 2) * (pic->getFrameHeightInCU() - 2) :\
> +    pic->getFrameWidthInCU() * pic->getFrameHeightInCU())
> +
> +int slicetype_frame_cost(x265::Lookahead *&l, int p0, int p1, int b, int
> bIntraPenalty);
>

why are you using a pointer reference?  Instead of passing the lookahead
struct you should just pass in the frames array


> +int slicetype_frame_cost(x265::Lookahead *&l,
> +                            int p0, int p1, int b,
> +                                                int bIntraPenalty,
> +                                                TComPic *pic)
>

I'm hoping it is unnecessary to pass in pic, the cu width and height should
be added to LookaheadFrame


> +
> +{
> +
> +    int i_score = 0;
>

drop the i_ prefix from x264 variables


> +    int do_search[2];
> +       x265::LookaheadFrame fenc;
> +       fenc = l->frames[b];
> +
> +       if( fenc.costEst[b-p0][p1-b] >= 0 && fenc.rowSatds[b-p0][p1-b][0]
> != -1)
> +               i_score = fenc.costEst[b-p0][p1-b];
> +       else
> +       {
> +               int dist_scale_factor = 128;
> +               //x265::MV *we = fenc.lowresMvs[0][b-p0-1];
> +               int *row_satd = fenc.rowSatds[b-p0][p1-b];
> +        //int *row_satd_intra = fenc.rowSatds[0][0];
> +
> +               /* For each list, check to see whether we have lowres
> motion-searched this reference frame before. */
> +               do_search[0] = b != p0 && fenc.lowresMvs[0][b-p0-1][0].x
> == 0x7FFF;
> +               do_search[1] = b != p1 && fenc.lowresMvs[1][p1-b-1][0].x
> == 0x7FFF;
> +
> +               if( do_search[0] )
> +               {
> +                       /* if weighted is enable then do the weight
> analyse */
> +                       if( fenc.m_isWeighted  && b == p1 )
> +                       {
> +                               x265_emms();
> +                               //TODO weights_analyse for Current frame
> +                       }
>

ignore weightp for now. remove this if {} expression


> +                       fenc.lowresMvs[0][b-p0-1][0] = 0;
> +               }
> +               if( do_search[1] ) fenc.lowresMvs[1][p1-b-1][0] = 0;
> +
> +               if( p1 != p0 )
> +                       dist_scale_factor = ( ((b-p0) << 8) + ((p1-p0) >>
> 1) ) / (p1-p0);
> +
> +               fenc.costEst[b-p0][p1-b] = 0;
> +        fenc.costEst[b-p0][p1-b] = 0;
>

tabs, white-space


> +
> +               if( b == p1 )
> +                       fenc.intraMbs[b-p0] = 0;
>

Remove this hack that ignores the edge blocks.  We have no idea how well
that will map to HEVC, so it shouldn't be tried until after everything else
is solid.


> +               if(pic->getFrameWidthInCU() <= 2 ||
> pic->getFrameHeightInCU() <= 2)
> +               {
> +                       for(int i = pic->getFrameWidthInCU() - 1; i >= 0;
> i--)
> +                               row_satd[i]= 0;
> +
> +                       for(int j = pic->getFrameHeightInCU() - 1; j >= 0;
> j--)
> +                               ;//call slicetype_mb_cost()
> +               }
> +               else
> +               {
> +                       for(int i = pic->getFrameWidthInCU() - 1; i >= 0;
> i--)
> +                               for(int j = pic->getFrameHeightInCU() - 1;
> j >= 0; j--)
> +                                       ;//call slicetype_mb_cost()
> +               }
> +
> +               i_score = fenc.costEst[b-p0][p1-b];
> +
> +                if( b != p1 )
> +            i_score = (uint64_t)i_score * 100 / (120 );//+
> h->param.i_bframe_bias);
>

we need to add bframeBias to x265_param_t and default it to 0


> +                fenc.costEst[b-p0][p1-b] = i_score;
> +         x265_emms();
> +       }
> +
> +       if( bIntraPenalty )
> +    {
> +        // arbitrary penalty for I-blocks after B-frames
> +        int nmb = NUM_MBS;
> +               i_score += (uint64_t)i_score * fenc.intraMbs[b-p0] / (nmb
> * 8);
> +    }
> +    return i_score;
> +
> +}
> +
> +#if 0
> +static int x264_slicetype_frame_cost( x264_t *h, x264_mb_analysis_t *a,
> +                                      x264_frame_t **frames, int p0, int
> p1, int b,
> +                                      int b_intra_penalty )
>

this copy of the function should be removed


> +{
> +    int i_score = 0;
> +    int do_search[2];
> +    const x264_weight_t *w = x264_weight_none;
> +    /* Check whether we already evaluated this frame
> +     * If we have tried this frame as P, then we have also tried
> +     * the preceding frames as B. (is this still true?) */
> +    /* Also check that we already calculated the row SATDs for the
> current frame. */
> +    if( frames[b]->i_cost_est[b-p0][p1-b] >= 0 &&
> (!h->param.rc.i_vbv_buffer_size || frames[b]->i_row_satds[b-p0][p1-b][0] !=
> -1) )
> +        i_score = frames[b]->i_cost_est[b-p0][p1-b];
> +    else
> +    {
> +        int dist_scale_factor = 128;
> +        int *row_satd = frames[b]->i_row_satds[b-p0][p1-b];
> +        int *row_satd_intra = frames[b]->i_row_satds[0][0];
> +
> +        /* For each list, check to see whether we have lowres
> motion-searched this reference frame before. */
> +        do_search[0] = b != p0 && frames[b]->lowres_mvs[0][b-p0-1][0][0]
> == 0x7FFF;
> +        do_search[1] = b != p1 && frames[b]->lowres_mvs[1][p1-b-1][0][0]
> == 0x7FFF;
> +        if( do_search[0] )
> +        {
> +            if( h->param.analyse.i_weighted_pred && b == p1 )
> +            {
> +                x264_emms();
> +                x264_weights_analyse( h, frames[b], frames[p0], 1 );
> +                w = frames[b]->weight[0];
> +            }
> +            frames[b]->lowres_mvs[0][b-p0-1][0][0] = 0;
> +        }
> +        if( do_search[1] ) frames[b]->lowres_mvs[1][p1-b-1][0][0] = 0;
> +
> +        if( b == p1 )
> +            frames[b]->i_intra_mbs[b-p0] = 0;
> +        if( !frames[b]->b_intra_calculated )
> +        {
> +            frames[b]->i_cost_est[0][0] = 0;
> +            frames[b]->i_cost_est_aq[0][0] = 0;
> +        }
> +        if( p1 != p0 )
> +            dist_scale_factor = ( ((b-p0) << 8) + ((p1-p0) >> 1) ) /
> (p1-p0);
> +
> +        frames[b]->i_cost_est[b-p0][p1-b] = 0;
> +        frames[b]->i_cost_est_aq[b-p0][p1-b] = 0;
> +
> +        /* Lowres lookahead goes backwards because the MVs are used as
> predictors in the main encode.
> +         * This considerably improves MV prediction overall. */
> +
> +        /* The edge mbs seem to reduce the predictive quality of the
> +         * whole frame's score, but are needed for a spatial
> distribution. */
>

but these two comments should be preserved in the new function


> +        if( h->param.rc.b_mb_tree || h->param.rc.i_vbv_buffer_size ||
> +            h->mb.i_mb_width <= 2 || h->mb.i_mb_height <= 2 )
> +        {
> +            for( h->mb.i_mb_y = h->mb.i_mb_height - 1; h->mb.i_mb_y >= 0;
> h->mb.i_mb_y-- )
> +            {
> +                row_satd[h->mb.i_mb_y] = 0;
> +                if( !frames[b]->b_intra_calculated )
> +                    row_satd_intra[h->mb.i_mb_y] = 0;
> +                for( h->mb.i_mb_x = h->mb.i_mb_width - 1; h->mb.i_mb_x >=
> 0; h->mb.i_mb_x-- )
> +                    x264_slicetype_mb_cost( h, a, frames, p0, p1, b,
> dist_scale_factor, do_search, w );
> +            }
> +        }
> +        else
> +        {
> +            for( h->mb.i_mb_y = h->mb.i_mb_height - 2; h->mb.i_mb_y >= 1;
> h->mb.i_mb_y-- )
> +                for( h->mb.i_mb_x = h->mb.i_mb_width - 2; h->mb.i_mb_x >=
> 1; h->mb.i_mb_x-- )
> +                    x264_slicetype_mb_cost( h, a, frames, p0, p1, b,
> dist_scale_factor, do_search, w );
> +        }
> +
> +        i_score = frames[b]->i_cost_est[b-p0][p1-b];
> +        if( b != p1 )
> +            i_score = (uint64_t)i_score * 100 / (120 +
> h->param.i_bframe_bias);
> +        else
> +            frames[b]->b_intra_calculated = 1;
> +
> +        frames[b]->i_cost_est[b-p0][p1-b] = i_score;
> +        x264_emms();
> +    }
> +
> +    if( b_intra_penalty )
> +    {
> +        // arbitrary penalty for I-blocks after B-frames
> +        int nmb = NUM_MBS;
> +        i_score += (uint64_t)i_score * frames[b]->i_intra_mbs[b-p0] /
> (nmb * 8);
> +    }
> +    return i_score;
> +}
> +
> +
> +
> +
>
>  // Indexed by pic_struct values
>  static const uint8_t delta_tfi_divisor[10] = { 0, 2, 1, 1, 2, 2, 3, 3, 4,
> 6 };
> @@ -1518,3 +1706,5 @@
>
>  h->sps->vui.i_num_units_in_tick / h->sps->vui.i_time_scale;
>      }
>  }
> +
> +#endif
> \ No newline at end of file
> _______________________________________________
> x265-devel mailing list
> x265-devel at videolan.org
> http://mailman.videolan.org/listinfo/x265-devel
>



-- 
Steve Borho
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/private/x265-devel/attachments/20130807/c7913749/attachment-0001.html>


More information about the x265-devel mailing list