[x265] [PATCH] Slicetype: Modified Lookahead structure and Added slicetype_cu_cost()

gopu at multicorewareinc.com gopu at multicorewareinc.com
Thu Aug 8 13:33:54 CEST 2013


# 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>
+ * 
  * 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


More information about the x265-devel mailing list