private float estimateLayerThreshold(int targetBytes, EBCOTLayer lastLayer)
{
float log_sl1; // The log of the first slope used for interpolation
float log_sl2; // The log of the second slope used for interpolation
float log_len1; // The log of the first length used for interpolation
float log_len2; // The log of the second length used for interpolation
float log_isl; // The log of the interpolated slope
float log_ilen; // Log of the interpolated length
float log_ab; // Log of actual bytes in last layer
int sidx; // Index into the summary R-D info array
float log_off; // The log of the offset proportion
int tlen; // The corrected target layer length
float lthresh; // The threshold of the last layer
float eth; // The estimated threshold
// In order to estimate the threshold we base ourselves in the summary
// R-D info in RDSlopesRates. In order to use it we must compensate
// for the overhead of the packet heads. The proportion of overhead is
// estimated using the last layer simulation results.
// NOTE: the model used in this method is that the slope varies
// linearly with the log of the rate (i.e. length).
// NOTE: the model used in this method is that the distortion is
// proprotional to a power of the rate. Thus, the slope is also
// proportional to another power of the rate. This translates as the
// log of the slope varies linearly with the log of the rate, which is
// what we use.
// 1) Find the offset of the length predicted from the summary R-D
// information, to the actual length by using the last layer.
// We ensure that the threshold we use for estimation actually
// includes some data.
lthresh = lastLayer.rdThreshold;
if (lthresh > maxSlope)
lthresh = maxSlope;
// If the slope of the last layer is too small then we just include
// all the rest (not possible to do better).
if (lthresh < FLOAT_ABS_PRECISION)
return 0f;
sidx = getLimitedSIndexFromSlope(lthresh);
// If the index is outside of the summary info array use the last two,
// or first two, indexes, as appropriate
if (sidx >= RD_SUMMARY_SIZE - 1)
sidx = RD_SUMMARY_SIZE - 2;
// Get the logs of the lengths and the slopes
if (RDSlopesRates[sidx + 1] == 0)
{
// Pathological case, we can not use log of 0. Add
// RDSlopesRates[sidx]+1 bytes to the rates (just a crude simple
// solution to this rare case)
//UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
log_len1 = (float) System.Math.Log((RDSlopesRates[sidx] << 1) + 1);
//UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
log_len2 = (float) System.Math.Log(RDSlopesRates[sidx] + 1);
//UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
log_ab = (float) System.Math.Log(lastLayer.actualBytes + RDSlopesRates[sidx] + 1);
}
else
{
//UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
log_len1 = (float) System.Math.Log(RDSlopesRates[sidx]);
//UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
log_len2 = (float) System.Math.Log(RDSlopesRates[sidx + 1]);
//UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
log_ab = (float) System.Math.Log(lastLayer.actualBytes);
}
//UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
log_sl1 = (float) System.Math.Log(getSlopeFromSIndex(sidx));
//UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
log_sl2 = (float) System.Math.Log(getSlopeFromSIndex(sidx + 1));
//UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
log_isl = (float) System.Math.Log(lthresh);
log_ilen = log_len1 + (log_isl - log_sl1) * (log_len1 - log_len2) / (log_sl1 - log_sl2);
log_off = log_ab - log_ilen;
// Do not use negative offsets (i.e. offset proportion larger than 1)
// since that is probably a sign that our model is off. To be
// conservative use an offset of 0 (i.e. offset proportiojn 1).
if (log_off < 0)
log_off = 0f;
// 2) Correct the target layer length by the offset.
//UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
tlen = (int) (targetBytes / (float) System.Math.Exp(log_off));
// 3) Find, from the summary R-D info, the thresholds that generate
// lengths just above and below our corrected target layer length.
// Look for the index in the summary info array that gives the largest
// length smaller than the target length
for (sidx = RD_SUMMARY_SIZE - 1; sidx >= 0; sidx--)
{
if (RDSlopesRates[sidx] >= tlen)
break;
}
sidx++;
// Correct if out of the array
if (sidx >= RD_SUMMARY_SIZE)
sidx = RD_SUMMARY_SIZE - 1;
if (sidx <= 0)
sidx = 1;
// Get the log of the lengths and the slopes that are just above and
// below the target length.
if (RDSlopesRates[sidx] == 0)
{
// Pathological case, we can not use log of 0. Add
// RDSlopesRates[sidx-1]+1 bytes to the rates (just a crude simple
// solution to this rare case)
//UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
log_len1 = (float) System.Math.Log(RDSlopesRates[sidx - 1] + 1);
//UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
log_len2 = (float) System.Math.Log((RDSlopesRates[sidx - 1] << 1) + 1);
//UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
log_ilen = (float) System.Math.Log(tlen + RDSlopesRates[sidx - 1] + 1);
}
else
{
// Normal case, we can safely take the logs.
//UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
log_len1 = (float) System.Math.Log(RDSlopesRates[sidx]);
//UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
log_len2 = (float) System.Math.Log(RDSlopesRates[sidx - 1]);
//UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
log_ilen = (float) System.Math.Log(tlen);
}
//UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
log_sl1 = (float) System.Math.Log(getSlopeFromSIndex(sidx));
//UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
log_sl2 = (float) System.Math.Log(getSlopeFromSIndex(sidx - 1));
// 4) Interpolate the two thresholds to find the target threshold.
log_isl = log_sl1 + (log_ilen - log_len1) * (log_sl1 - log_sl2) / (log_len1 - log_len2);
//UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
eth = (float) System.Math.Exp(log_isl);
// Correct out of bounds results
if (eth > lthresh)
eth = lthresh;
if (eth < FLOAT_ABS_PRECISION)
eth = 0f;
// Return the estimated threshold
return eth;
}