[x265] [PATCH 3 of 3] Using weighted lowres ref frames in cost estimation in lookahead

shazeb at multicorewareinc.com shazeb at multicorewareinc.com
Tue Nov 12 12:49:45 CET 2013


# HG changeset patch
# User Shazeb Nawaz Khan <shazeb at multicorewareinc.com>
# Date 1384256810 -19800
#      Tue Nov 12 17:16:50 2013 +0530
# Node ID 37998a9d21f35a85b7328b514bda337a99b1b831
# Parent  21596a519ba8cc521dbc81f693c867cbca03fd3f
Using weighted lowres ref frames in cost estimation in lookahead

diff -r 21596a519ba8 -r 37998a9d21f3 source/common/lowres.cpp
--- a/source/common/lowres.cpp	Tue Nov 12 17:07:27 2013 +0530
+++ b/source/common/lowres.cpp	Tue Nov 12 17:16:50 2013 +0530
@@ -40,6 +40,7 @@
     int cuWidth = (width + X265_LOWRES_CU_SIZE - 1) >> X265_LOWRES_CU_BITS;
     int cuHeight = (lines + X265_LOWRES_CU_SIZE - 1) >> X265_LOWRES_CU_BITS;
     int cuCount = cuWidth * cuHeight;
+    bufferSize = lumaStride * (lines + 2 * orig->getLumaMarginY());
 
     /* rounding the width to multiple of lowres CU size */
     width = cuWidth * X265_LOWRES_CU_SIZE;
@@ -115,6 +116,51 @@
     X265_FREE(invQscaleFactor);
 }
 
+void Lowres::initWeighted(Lowres *ref, int bframes, wpScalingParam *w)
+{
+    bScenecut = true;
+    bIntraCalculated = false;
+    bLastMiniGopBFrame = false;
+    bKeyframe = false; // Not a keyframe unless identified by lookahead
+    sliceType = ref->sliceType;
+    frameNum = ref->frameNum;
+    leadingBframes = 0;
+    satdCost = -1;
+    isWeighted = true;
+    memset(costEst, -1, sizeof(costEst));
+
+    if (qpAqOffset && invQscaleFactor)
+        memset(costEstAq, -1, sizeof(costEstAq));
+
+    for (int y = 0; y < bframes + 2; y++)
+    {
+        for (int x = 0; x < bframes + 2; x++)
+        {
+            rowSatds[y][x][0] = -1;
+        }
+    }
+
+    for (int i = 0; i < bframes + 1; i++)
+    {
+        lowresMvs[0][i][0].x = 0x7FFF;
+        lowresMvs[1][i][0].x = 0x7FFF;
+    }
+
+    for (int i = 0; i < bframes + 2; i++)
+    {
+        intraMbs[i] = 0;
+    }
+
+    int corection = (IF_INTERNAL_PREC - X265_DEPTH);
+    for(int i = 0; i < 4; i++)
+    {
+        //Adding (IF_INTERNAL_PREC - X265_DEPTH) to cancel effect of pixel to short conversion inside the primitive
+        primitives.weightpUniPixel(ref->buffer[i], this->buffer[i], lumaStride, lumaStride, lumaStride, (int) bufferSize / lumaStride, w->inputWeight, (1<<(w->log2WeightDenom - 1 + corection)), (w->log2WeightDenom + corection), w->inputOffset);
+    }
+
+    fpelPlane = lowresPlane[0];
+}
+
 // (re) initialize lowres state
 void Lowres::init(TComPicYuv *orig, int poc, int type, int bframes)
 {
@@ -126,6 +172,7 @@
     frameNum = poc;
     leadingBframes = 0;
     satdCost = -1;
+    isWeighted = false;
     memset(costEst, -1, sizeof(costEst));
 
     if (qpAqOffset && invQscaleFactor)
diff -r 21596a519ba8 -r 37998a9d21f3 source/common/lowres.h
--- a/source/common/lowres.h	Tue Nov 12 17:07:27 2013 +0530
+++ b/source/common/lowres.h	Tue Nov 12 17:16:50 2013 +0530
@@ -26,6 +26,7 @@
 
 #include "primitives.h"
 #include "common.h"
+#include "Lib\TLibCommon\TComSlice.h"
 #include "mv.h"
 
 namespace x265 {
@@ -100,6 +101,7 @@
 struct Lowres : public ReferencePlanes
 {
     pixel *buffer[4];
+    int bufferSize;
 
     int    frameNum;         // Presentation frame number
     int    sliceType;        // Slice type decided by lookahead
@@ -132,6 +134,7 @@
     void create(TComPic *pic, int bframes, int32_t *aqMode);
     void destroy(int bframes);
     void init(TComPicYuv *orig, int poc, int sliceType, int bframes);
+    void initWeighted(Lowres *ref, int bframes, wpScalingParam *w);
 };
 }
 
diff -r 21596a519ba8 -r 37998a9d21f3 source/encoder/slicetype.cpp
--- a/source/encoder/slicetype.cpp	Tue Nov 12 17:07:27 2013 +0530
+++ b/source/encoder/slicetype.cpp	Tue Nov 12 17:16:50 2013 +0530
@@ -79,17 +79,23 @@
     widthInCU = ((cfg->param.sourceWidth / 2) + X265_LOWRES_CU_SIZE - 1) >> X265_LOWRES_CU_BITS;
     heightInCU = ((cfg->param.sourceHeight / 2) + X265_LOWRES_CU_SIZE - 1) >> X265_LOWRES_CU_BITS;
 
+    weightedRef = new Lowres();
+    weightedRef->buffer[0] = NULL;
+
     lhrows = new LookaheadRow[heightInCU];
     for (int i = 0; i < heightInCU; i++)
     {
         lhrows[i].widthInCU = widthInCU;
         lhrows[i].heightInCU = heightInCU;
         lhrows[i].frames = frames;
+        lhrows[i].weightedRef = weightedRef;
+        lhrows[i].cfg = cfg;
     }
 }
 
 Lookahead::~Lookahead()
 {
+    delete weightedRef;
 }
 
 void Lookahead::init()
@@ -128,6 +134,12 @@
 {
     pic->m_lowres.init(pic->getPicYuvOrg(), pic->getSlice()->getPOC(), sliceType, cfg->param.bframes);
 
+    if( weightedRef->buffer[0] == NULL)
+    {
+        // Just using width/height data from the pic to create a standalone Lowres object
+        weightedRef->create(pic, cfg->param.bframes, &cfg->param.rc.aqMode);
+    }
+
     inputQueue.pushBack(*pic);
     if (inputQueue.size() >= cfg->param.lookaheadDepth)
         slicetypeDecide();
@@ -537,6 +549,14 @@
                 wp.bPresentFlag = false;
                 wp.inputWeight = 0;
                 weightsAnalyse(b, p0, 1, &wp);
+                if(wp.bPresentFlag)
+                {
+                    weightedRef->initWeighted(frames[p0], cfg->param.bframes, &wp);
+                }
+                else
+                {
+                    weightedRef->isWeighted = false;
+                }
             }
         bDoSearch[0] = b != p0 && fenc->lowresMvs[0][b - p0 - 1][0].x == 0x7FFF;
         bDoSearch[1] = b != p1 && fenc->lowresMvs[1][p1 - b - 1][0].x == 0x7FFF;
@@ -627,6 +647,11 @@
     Lowres *fref1 = frames[p1];
     Lowres *fenc  = frames[b];
 
+    if (cfg->param.bEnableWeightedPred && weightedRef->isWeighted)
+    {
+        fref0 = weightedRef;
+    }
+
     const int bBidir = (b < p1);
     const int cuXY = cux + cuy * widthInCU;
     const int cuSize = X265_LOWRES_CU_SIZE;


More information about the x265-devel mailing list