[x265] [PATCH] lookahead: Implementation of slicetype_frame_cost

gopu at multicorewareinc.com gopu at multicorewareinc.com
Wed Aug 7 09:27:05 CEST 2013


# 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"
+
+
+#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);
+
+int slicetype_frame_cost(x265::Lookahead *&l, 
+	                     int p0, int p1, int b, 
+						 int bIntraPenalty,
+						 TComPic *pic)
+						 
+{	
+	
+    int i_score = 0;
+    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				
+			}
+			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;
+
+		if( b == p1 )
+			fenc.intraMbs[b-p0] = 0;
+
+		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);
+        
+		 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 )
+{
+    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;
+}
+
+
+
+
 
 // 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


More information about the x265-devel mailing list