<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Nov 13, 2013 at 7:29 PM, Steve Borho <span dir="ltr"><<a href="mailto:steve@borho.org" target="_blank">steve@borho.org</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote"><div class="im">On Wed, Nov 13, 2013 at 6:40 AM, <span dir="ltr"><<a href="mailto:shazeb@multicorewareinc.com" target="_blank">shazeb@multicorewareinc.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"># HG changeset patch<br>
# User Shazeb Nawaz Khan <<a href="mailto:shazeb@multicorewareinc.com" target="_blank">shazeb@multicorewareinc.com</a>><br>
# Date 1384345982 -19800<br>
# Wed Nov 13 18:03:02 2013 +0530<br>
# Node ID 213808a2069d21c49a4d5e99d71ad71b8af344b8<br>
# Parent c4ca80d19105ccf1ba2ec14dd65915f2820a660d<br>
Pulling x264 weight decision into/for x265 lookahead<br>
<br>
diff -r c4ca80d19105 -r 213808a2069d source/Lib/TLibCommon/TComSlice.h<br>
--- a/source/Lib/TLibCommon/TComSlice.h Tue Nov 12 19:10:23 2013 +0530<br>
+++ b/source/Lib/TLibCommon/TComSlice.h Wed Nov 13 18:03:02 2013 +0530<br>
@@ -42,6 +42,7 @@<br>
#include "TComRom.h"<br>
#include "x265.h" // NAL type enums<br>
#include "piclist.h"<br>
+#include "common.h"<br>
<br>
#include <cstring><br>
#include <assert.h><br>
@@ -1256,6 +1257,20 @@<br>
<br>
// Weighted prediction scaling values built from above parameters (bitdepth scaled):<br>
int w, o, offset, shift, round;<br>
+<br>
+ /* makes a non-h265 weight (i.e. fix7), into an h265 weight */<br>
+ void setFromWeightAndOffset( int weight_nonh264, int offset )<br></blockquote><div><br></div></div><div>white-space; x264 paren style is not the same as ours</div><div class="im"><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+ {<br>
+ inputOffset = offset;<br>
+ log2WeightDenom = 7;<br>
+ inputWeight = weight_nonh264;<br></blockquote><div><br></div></div><div>drop the _nonh264 suffix</div><div><div class="h5"><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+ while( log2WeightDenom > 0 && (inputWeight > 127) )<br>
+ {<br>
+ log2WeightDenom--;<br>
+ inputWeight >>= 1;<br>
+ }<br>
+ inputWeight = X265_MIN( inputWeight, 127 );<br>
+ }<br>
};<br>
<br>
typedef WpScalingParam wpScalingParam;<br>
diff -r c4ca80d19105 -r 213808a2069d source/encoder/slicetype.cpp<br>
--- a/source/encoder/slicetype.cpp Tue Nov 12 19:10:23 2013 +0530<br>
+++ b/source/encoder/slicetype.cpp Wed Nov 13 18:03:02 2013 +0530<br>
@@ -45,6 +45,14 @@<br>
<br>
using namespace x265;<br>
<br>
+#define SET_WEIGHT(w, b, s, d, o)\<br>
+{\<br>
+ (w).inputWeight = (s);\<br>
+ (w).log2WeightDenom = (d);\<br>
+ (w).inputOffset = (o);\<br>
+ (w).bPresentFlag = b;\<br>
+}<br>
+<br>
static inline int16_t median(int16_t a, int16_t b, int16_t c)<br>
{<br>
int16_t t = (a - b) & ((a - b) >> 31);<br>
@@ -190,16 +198,141 @@<br>
return pic->m_lowres.satdCost;<br>
}<br>
<br>
+static void mcWeight(pixel *dst, intptr_t dstStride, pixel *src, intptr_t srcStride,<br>
+ const wpScalingParam *weight, int width, int height)<br>
+{<br>
+ int offset = weight->inputOffset << (X265_DEPTH - 8);<br>
+ int scale = weight->inputWeight;<br>
+ int denom = weight->log2WeightDenom;<br>
+ int correction = (IF_INTERNAL_PREC - X265_DEPTH);<br></blockquote><div><br></div></div></div><div>should these terms be moved into the primitive itself? this function feels like it should not exist.</div><div><br></div>
<div>is the correction term part of the actual weight algorithm?</div></div></div></div></blockquote><div><br></div><div>The correction term is just used to adjust round, shift so that the weight primitive, which simulates pixel to short conversion can be reused in its existing form.</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><div class="h5">
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+ if (denom >= 1)<br>
+ {<br>
+ primitives.weightpUniPixel(src, dst, srcStride, dstStride, width, height, scale, (1<<(denom - 1 + correction)), (denom + correction), offset);<br>
+ }<br>
+ else<br>
+ {<br>
+ primitives.weightpUniPixel(src, dst, srcStride, dstStride, width, height, scale, 0 + correction, 0 + correction, offset);<br>
+ }<br>
+}<br>
+<br>
+unsigned int Lookahead::weightCostLuma(int b, pixel *src, wpScalingParam *w)<br>
+{<br>
+ Lowres *fenc = frames[b];<br>
+ unsigned int cost = 0;<br>
+ int stride = fenc->lumaStride;<br>
+ int lines = fenc->lines;<br>
+ int width = fenc->width;<br>
+ pixel *fenc_plane = fenc->lowresPlane[0];<br>
+ ALIGN_VAR_16( pixel, buf[8*8]);<br>
+ int pixoff = 0;<br>
+ int mb = 0;<br>
+<br>
+ if (w)<br>
+ {<br>
+ for (int y = 0; y < lines; y += 8, pixoff = y * stride)<br>
+ for (int x = 0; x < width; x += 8, mb++, pixoff += 8)<br>
+ {<br>
+ // TO DO prepare full weighted plane<br>
+ mcWeight(buf, 8, &src[pixoff], stride, w, 8, 8);<br>
+ int cmp = primitives.satd[LUMA_8x8]( buf, 8, &fenc_plane[pixoff], stride );<br>
+ cost += X265_MIN( cmp, fenc->intraCost[mb] );<br>
+ }<br>
+ }<br>
+ else<br>
+ for (int y = 0; y < lines; y += 8, pixoff = y * stride)<br>
+ for (int x = 0; x < width; x += 8, mb++, pixoff += 8)<br>
+ {<br>
+ int cmp = primitives.satd[LUMA_8x8](&src[pixoff], stride, &fenc_plane[pixoff], stride);<br>
+ cost += X265_MIN(cmp, fenc->intraCost[mb]);<br>
+ }<br>
+ x265_emms();<br>
+ return cost;<br>
+}<br>
+<br>
+void Lookahead::weightsAnalyse(int b, int p0, int b_lookahead, wpScalingParam* weights)<br>
+{<br></blockquote><div><br></div></div></div><div>drop the b_lookahead argument</div><div class="im"><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+ Lowres *fenc, *ref;<br>
+ fenc = frames[b];<br>
+ ref = frames[p0];<br>
+ /* epsilon is chosen to require at least a numerator of 127 (with denominator = 128) */<br>
+ const float epsilon = 1.f/128.f;<br>
+ SET_WEIGHT( weights[0], 0, 1, 0, 0 );<br>
+ float guess_scale, fenc_mean, ref_mean;<br>
+ guess_scale = sqrtf( (float) fenc->wp_ssd[0] / ref->wp_ssd[0]);<br>
+ fenc_mean = (float)fenc->wp_sum[0] / (fenc->lines * fenc->width) / (1 << (X265_DEPTH - 8));<br>
+ ref_mean = (float) ref->wp_sum[0] / (fenc->lines * fenc->width) / (1 << (X265_DEPTH - 8));<br>
+<br>
+ /* Don't check chroma in lookahead, or if there wasn't a luma weight. */<br>
+ int minoff = 0, minscale, mindenom;<br>
+ unsigned int minscore = 0, origscore = 1;<br>
+ int found = 0;<br>
+<br>
+ //early termination<br></blockquote><div><br></div></div><div>space after //</div><div class="im"><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+ if( fabsf( ref_mean - fenc_mean ) < 0.5f && fabsf( 1.f - guess_scale ) < epsilon )<br></blockquote><div><br></div></div><div>white-space</div><div class="im"><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+ {<br>
+ SET_WEIGHT( *weights, 0, 1, 0, 0 );<br>
+ return;<br>
+ }<br>
+<br>
+ weights->setFromWeightAndOffset( (int)( guess_scale * 128 + 0.5), 0 );<br>
+<br>
+ mindenom = weights->log2WeightDenom;<br>
+ minscale = weights->inputWeight;<br>
+<br>
+ pixel *mcbuf = NULL;<br>
+ if (!fenc->bIntraCalculated)<br>
+ {<br>
+ estimateFrameCost(b,b,b,0);<br>
+ }<br>
+ mcbuf = frames[p0]->lowresPlane[0];<br>
+ origscore = minscore = weightCostLuma( b, mcbuf, NULL );<br>
+<br>
+ if( !minscore )<br></blockquote><div><br></div></div><div>lots of white-space issues in this function still</div><div class="im"><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+ return;<br>
+<br>
+ unsigned int s=0;<br>
+ int cur_scale = minscale;<br>
+ int cur_offset = (int) (fenc_mean - ref_mean * cur_scale / (1 << mindenom) + 0.5f * b_lookahead);<br>
+ if( cur_offset < - 128 || cur_offset > 127 )<br>
+ {<br>
+ /* Rescale considering the constraints on cur_offset. We do it in this order<br>
+ * because scale has a much wider range than offset (because of denom), so<br>
+ * it should almost never need to be clamped. */<br>
+ cur_offset = Clip3( -128, 127, cur_offset );<br>
+ cur_scale = (int) ((1 << mindenom) * (fenc_mean - cur_offset) / ref_mean + 0.5f);<br>
+ cur_scale = Clip3( 0, 127, cur_scale );<br>
+ }<br>
+ SET_WEIGHT(*weights, 1, cur_scale, mindenom, cur_offset);<br>
+ s = weightCostLuma(b, mcbuf, weights);<br>
+ COPY4_IF_LT( minscore, s, minscale, cur_scale, minoff, cur_offset, found, 1 );<br></blockquote><div><br></div></div><div>this emms is redundant</div><div><div class="h5"><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+ x265_emms();<br>
+<br>
+ /* Use a smaller denominator if possible */<br>
+ while( mindenom > 0 && !(minscale&1) )<br>
+ {<br>
+ mindenom--;<br>
+ minscale >>= 1;<br>
+ }<br>
+<br>
+ if( !found || (minscale == 1 << mindenom && minoff == 0) || (float)minscore / origscore > 0.998f )<br>
+ {<br>
+ SET_WEIGHT( *weights, 0, 1, 0, 0 );<br>
+ return;<br>
+ }<br>
+ else<br>
+ {<br>
+ SET_WEIGHT( *weights, 1, minscale, mindenom, minoff );<br>
+ }<br>
+}<br>
+<br>
#define NUM_CUS (widthInCU > 2 && heightInCU > 2 ? (widthInCU - 2) * (heightInCU - 2) : widthInCU * heightInCU)<br>
<br>
int Lookahead::estimateFrameCost(int p0, int p1, int b, bool bIntraPenalty)<br>
{<br>
int score = 0;<br>
Lowres *fenc = frames[b];<br>
-<br>
- curb = b;<br>
- curp0 = p0;<br>
- curp1 = p1;<br>
+ wpScalingParam wp;<br>
+ wp.bPresentFlag = false;<br>
<br>
if (fenc->costEst[b - p0][p1 - b] >= 0 && fenc->rowSatds[b - p0][p1 - b][0] != -1)<br>
score = fenc->costEst[b - p0][p1 - b];<br>
@@ -209,9 +342,21 @@<br>
bDoSearch[0] = b != p0 && fenc->lowresMvs[0][b - p0 - 1][0].x == 0x7FFF;<br>
bDoSearch[1] = b != p1 && fenc->lowresMvs[1][p1 - b - 1][0].x == 0x7FFF;<br>
<br>
- if (bDoSearch[0]) fenc->lowresMvs[0][b - p0 - 1][0].x = 0;<br>
+ if (bDoSearch[0])<br>
+ {<br>
+ if( cfg->param.bEnableWeightedPred && b==p1)<br>
+ {<br>
+ weightsAnalyse(b, p0, 1, &wp);<br>
+ }<br>
+ bDoSearch[0] = b != p0 && fenc->lowresMvs[0][b - p0 - 1][0].x == 0x7FFF;<br>
+ bDoSearch[1] = b != p1 && fenc->lowresMvs[1][p1 - b - 1][0].x == 0x7FFF;<br></blockquote><div><br></div></div></div><div>the above two lines should be removed</div></div></div></div></blockquote><div>
</div><div>the weightsAnalyse function makes a recursive call to estimateFrameCost, which alters the bDoSearch, curb, curp0, curp1, variables, hence they need to be initialized here </div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div class="im"><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+ fenc->lowresMvs[0][b - p0 - 1][0].x = 0;<br>
+ }<br>
if (bDoSearch[1]) fenc->lowresMvs[1][p1 - b - 1][0].x = 0;<br>
<br>
+ curb = b;<br>
+ curp0 = p0;<br>
+ curp1 = p1;<br></blockquote><div><br></div></div><div>the above three lines should be removed</div><div><div class="h5"><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
fenc->costEst[b - p0][p1 - b] = 0;<br>
fenc->costEstAq[b - p0][p1 - b] = 0;<br>
// TODO: use lowres MVs as motion candidates in full-res search<br>
@@ -613,14 +758,6 @@<br>
} */<br>
}<br>
<br>
- /* Analyse for weighted P frames<br>
- if (!h->param.rc.b_stat_read && h->lookahead->next.list[bframes]->i_type == X264_TYPE_P<br>
- && h->param.analyse.i_weighted_pred >= X264_WEIGHTP_SIMPLE)<br>
- {<br>
- x265_emms();<br>
- x264_weights_analyse(h, h->lookahead->next.list[bframes], h->lookahead->last_nonb, 0);<br>
- }*/<br>
-<br>
/* dequeue all frames from inputQueue that are about to be enqueued<br>
* in the output queue. The order is important because TComPic can<br>
* only be in one list at a time */<br>
diff -r c4ca80d19105 -r 213808a2069d source/encoder/slicetype.h<br>
--- a/source/encoder/slicetype.h Tue Nov 12 19:10:23 2013 +0530<br>
+++ b/source/encoder/slicetype.h Wed Nov 13 18:03:02 2013 +0530<br>
@@ -47,11 +47,13 @@<br>
int costIntra; // Estimated Intra cost for all CUs in a row<br>
int costIntraAq; // Estimated weighted Aq Intra cost for all CUs in a row<br>
int intraMbs; // Number of Intra CUs<br>
+ TEncCfg *cfg;<br>
<br>
Lowres** frames;<br>
int widthInCU;<br>
int heightInCU;<br>
int merange;<br>
+ Lowres *weightedRef;<br>
<br>
LookaheadRow()<br>
{<br>
@@ -82,6 +84,9 @@<br>
int widthInCU; // width of lowres frame in downscale CUs<br>
int heightInCU; // height of lowres frame in downscale CUs<br>
<br>
+ Lowres weightedRef;<br>
+ int numWRefs;<br>
+<br>
PicList inputQueue; // input pictures in order received<br>
PicList outputQueue; // pictures to be encoded, in encode order<br>
<br>
@@ -110,6 +115,11 @@<br>
int slicetypePathCost(char *path, int threshold);<br>
<br>
void processRow(int row);<br>
+<br>
+ void weightsAnalyse(int b, int p0, int b_lookahead, wpScalingParam *w);<br>
+ unsigned int weightCostLuma(int b, pixel *src, wpScalingParam *w);<br>
+ pixel* weightCostInit(int b, int p0, pixel *dest);<br>
+ int x265_weight_slice_header_cost(wpScalingParam *w, int b_chroma);<br></blockquote><div><br></div></div></div><div>this last function doesn't exist</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
};<br>
}<br>
<br>
_______________________________________________<br>
x265-devel mailing list<br>
<a href="mailto:x265-devel@videolan.org" target="_blank">x265-devel@videolan.org</a><br>
<a href="https://mailman.videolan.org/listinfo/x265-devel" target="_blank">https://mailman.videolan.org/listinfo/x265-devel</a><span class="HOEnZb"><font color="#888888"><br>
</font></span></blockquote></div><span class="HOEnZb"><font color="#888888"><br><br clear="all"><div><br></div>-- <br>Steve Borho
</font></span></div></div>
<br>_______________________________________________<br>
x265-devel mailing list<br>
<a href="mailto:x265-devel@videolan.org">x265-devel@videolan.org</a><br>
<a href="https://mailman.videolan.org/listinfo/x265-devel" target="_blank">https://mailman.videolan.org/listinfo/x265-devel</a><br>
<br></blockquote></div><br></div></div>