[x265] [PATCH] Slicetype: Modified Lookahead structure and Added slicetype_cu_cost()
Steve Borho
steve at borho.org
Thu Aug 8 20:13:50 CEST 2013
On Thu, Aug 8, 2013 at 6:33 AM, <gopu at multicorewareinc.com> wrote:
> # HG changeset patch
> # User ggopu
> # Date 1375961599 -19800
> # Node ID fe327a9a7a1b695b2363eecd3dc1c8939f303c6c
> # Parent 33b0a6829d01735e137b0aadb1b276928a1d8fa4
> Slicetype: Modified Lookahead structure and Added slicetype_cu_cost()
>
> diff -r 33b0a6829d01 -r fe327a9a7a1b source/common/lookahead.h
> --- a/source/common/lookahead.h Thu Aug 08 16:19:22 2013 +0530
> +++ b/source/common/lookahead.h Thu Aug 08 17:03:19 2013 +0530
> @@ -24,11 +24,13 @@
> #include "x265.h"
> #include "common.h"
> #include "mv.h"
> +#include "reference.h"
>
> namespace x265 {
> class ReferencePlanes;
>
> #define X265_BFRAME_MAX 16
> +#define FDEC_STRIDE 32
>
> struct LookaheadFrame : public ReferencePlanes
> {
> @@ -45,6 +47,8 @@
> uint16_t(*lowresCosts[X265_BFRAME_MAX + 2][X265_BFRAME_MAX + 2]);
> int *lowresMvCosts[2][X265_BFRAME_MAX + 1];
> MV *lowresMvs[2][X265_BFRAME_MAX + 1];
> + int cuWidth;
> + int cuHeight;
> };
>
> struct Lookahead
> @@ -57,5 +61,4 @@
> TComList<TComPic*> inputQueue; // input pictures in order
> received
> TComList<TComPic*> outputQueue; // pictures to be encoded, in
> encode order
> };
> -
> }
> diff -r 33b0a6829d01 -r fe327a9a7a1b source/encoder/slicetype.cpp
> --- a/source/encoder/slicetype.cpp Thu Aug 08 16:19:22 2013 +0530
> +++ b/source/encoder/slicetype.cpp Thu Aug 08 17:03:19 2013 +0530
> @@ -1,12 +1,10 @@
>
> /*****************************************************************************
> - * slicetype.c: lookahead analysis
> -
> *****************************************************************************
> - * Copyright (C) 2005-2013 x264 project
> + * Copyright (C) 2013 x265 project
> *
> - * Authors: Jason Garrett-Glaser <darkshikari at gmail.com>
> - * Loren Merritt <lorenm at u.washington.edu>
> - * Dylan Yudaken <dyudaken at gmail.com>
> - *
> + * Authors: Steve Borho <steve at borho.org>
> + * Gopu Govindaswamy <gopu at multicorewareinc.com>
> + * Mandar Gurav<mandar at multicorewareinc.com>
>
Removing authors is generally considered bad form.
> * This program is free software; you can redistribute it and/or modify
> * it under the terms of the GNU General Public License as published by
> * the Free Software Foundation; either version 2 of the License, or
> @@ -22,27 +20,149 @@
> * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111,
> USA.
> *
> * This program is also available under a commercial proprietary license.
> - * For more information, contact us at licensing at x264.com.
> + * For more information, contact us at licensing at multicorewareinc.com.
>
> *****************************************************************************/
>
> -// Short history:
> -//
> -// This file was originally borrowed from x264 source tree circa Dec 4,
> 2012
> -// with x264 bug fixes applied from Dec 11th and Jan 8th 2013. But
> without
> -// taking any of the threading changes because we will eventually use the
> x265
> -// thread pool and wavefront processing.
> +#include "x265.h"
> +#include "lookahead.h"
> +#include "primitives.h"
>
> -#include "common/common.h"
> -#include "macroblock.h"
> -#include "me.h"
> +int slicetype_frame_cost(x265::LookaheadFrame **frames, int p0, int p1,
> int b, int bIntraPenalty)
> +{
> + int score = 0;
> + int do_search[2];
> + x265::LookaheadFrame *fenc;
>
> + fenc = frames[b];
> +
> + /* Currently Default set as 0 this should be param->bframebias */
> + int bframe_bias = 0;
> +
> + if (fenc->costEst[b - p0][p1 - b] >= 0 && fenc->rowSatds[b - p0][p1 -
> b][0] != -1)
> + score = fenc->costEst[b - p0][p1 - b];
> + else
> + {
> + int dist_scale_factor = 128;
> +
> + /* 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])
> + {
> + fenc->lowresMvs[0][b - p0 - 1][0].x = 0;
> + }
> +
> + if (do_search[1]) fenc->lowresMvs[1][p1 - b - 1][0].x = 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;
> +
> + /* 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.
> */
> +
> + for (int i = fenc->cuWidth - 1; i >= 0; i--)
> + {
> + for (int j = fenc->cuHeight - 1; j >= 0; j--)
> + {
> + slicetype_cu_cost(frames, p0, p1, b, dist_scale_factor,
> do_search);
> + }
> + }
> +
> + score = fenc->costEst[b - p0][p1 - b];
> +
> + if (b != p1) /* have to check use of 120 magical number but
> followed by x264 used here */
> + score = (uint64_t)score * 100 / (120) + bframe_bias;
> +
> + fenc->costEst[b - p0][p1 - b] = score;
> + x265_emms();
> + }
> +
> + if (bIntraPenalty)
> + {
> + // arbitrary penalty for I-blocks after B-frames
> + int nmb = fenc->cuWidth * fenc->cuHeight;
> + score += (uint64_t)score * fenc->intraMbs[b - p0] / (nmb * 8);
> + }
> + return score;
> +}
> +
> +int slicetype_cu_cost(x265::LookaheadFrame **frames, int p0, int p1, int
> b, int dist_scale_factor, int do_search[2])
> +{
> + x265::LookaheadFrame *fref0 = frames[p0];
> + x265::LookaheadFrame *fref1 = frames[p1];
> + x265::LookaheadFrame *fenc = frames[b];
> +
> + /* TODO : need clarifications how can be initialized motion vector in
> this function */
> + x265::MV *pmv;
> +
> + const int b_bidir = (b < p1);
> + const int cu_x = pmv->x;
> + const int cu_y = pmv->y;
> +
> + const int cu_stride = fenc->cuWidth;
> + const int cu_xy = cu_x + cu_y * cu_stride;
> + const int stride = fenc->stride;
> + const int pel_offset = 8 * (cu_x + cu_y * stride);
> +
> + x265::MV(*fenc_mvs[2][2]) = { &fenc->lowresMvs[0][b - p0 - 1][cu_xy],
> &fenc->lowresMvs[1][p1 - b - 1][cu_xy] };
> +
> + int(*fenc_costs[2]) = { &fenc->lowresMvCosts[0][b - p0 - 1][cu_xy],
> &fenc->lowresMvCosts[1][p1 - b - 1][cu_xy] };
> +
> + int b_frame_score_mb = (cu_x > 0 && cu_x < fenc->cuWidth - 1 &&
> + cu_y > 0 && cu_y < fenc->cuHeight - 1) ||
> + fenc->cuWidth <= 2 || fenc->cuHeight <= 2;
> +
> + ALIGN_VAR_16(pixel, *pix1, [9 * FDEC_STRIDE]);
> + pixel *pix2 = pix1 + 8;
> + int i_bcost = 0;
> + int list_used = 0;
> +
> + /* A small, arbitrary bias to avoid VBV problems caused by
> zero-residual lookahead blocks. */
> + int lowres_penalty = 4;
> + pixel *buffer[4];
> + buffer[0] = fenc->buffer[0];
> +
> + /* TODO : need confirmation, in x264 copying square block 8 x 8
> followed same way here 32 x 32 in our cu max size is 64 x 64 */
> + x265::primitives.blockcpy_pp(32, 32, buffer[0], FENC_STRIDE,
> fenc->m_lumaPlane[0][pel_offset], stride);
> +
> + if (p0 == p1)
> + goto lowres_intra_mb;
> +
> +lowres_intra_mb:
> +
> + /* Need to check how can get this lambda */
> + int lambda;
> +
> + ALIGN_VAR_16(pixel, edge, [36]);
> + pixel *pix = &pix1[8 + FDEC_STRIDE - 1];
> + pixel *src = fenc->m_lumaPlane[0][pel_offset - 1];
> + const int intra_penalty = 5 * lambda;
> + int satds[3];
> +
> + memcpy(pix - FDEC_STRIDE, src - stride, 17 * sizeof(pixel));
> + for (int i = 0; i < 32; i++)
> + {
> + pix[i * FDEC_STRIDE] = src[i * stride];
> + }
> +
> + pix++;
> +
> + //TODO: Calculate the x3_satd costs
> +
> + return 0;
> +}
> +
> +#if 0
> // Indexed by pic_struct values
> static const uint8_t delta_tfi_divisor[10] = { 0, 2, 1, 1, 2, 2, 3, 3, 4,
> 6 };
>
> -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);
> -
> static void x264_lowres_context_init(x264_t *h, x264_mb_analysis_t *a)
> {
> a->i_qp = X264_LOOKAHEAD_QP;
> @@ -677,103 +797,6 @@
> (h->mb.i_mb_width - 2) * (h->mb.i_mb_height - 2) : \
> h->mb.i_mb_width * h->mb.i_mb_height)
>
> -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)
> -{
> - 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. */
> - 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;
> -}
> -
> static void x264_macroblock_tree_finish(x264_t *h, x264_frame_t *frame,
> float average_duration, int ref0_distance)
> {
> int fps_factor = round(CLIP_DURATION(average_duration) /
> CLIP_DURATION(frame->f_duration) * 256);
> @@ -1624,3 +1647,5 @@
> h->sps->vui.i_num_units_in_tick / h->sps->vui.i_time_scale;
> }
> }
> +
> +#endif // if 0
> _______________________________________________
> 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/20130808/879a08be/attachment-0001.html>
More information about the x265-devel
mailing list