add support for interpolation before calculating convex hull
add support for generating interpolated sampling RD points for RD
curves for each resolution before calculating convex hull. save the RD
point for convex hull generated based on the original RD points and
interpolated RD points. update BD rate calculaiton script to also
calculate bdrate based on two convex hulls
Change-Id: I9631c1e4f7c6a20ab59817b893aa7ccad8e87695
diff --git a/tools/convexhull_framework/src/CalcBDRate.py b/tools/convexhull_framework/src/CalcBDRate.py
index 9e7646d..aca1997 100644
--- a/tools/convexhull_framework/src/CalcBDRate.py
+++ b/tools/convexhull_framework/src/CalcBDRate.py
@@ -10,7 +10,7 @@
##
__author__ = "maggie.sun@intel.com, ryan.lei@intel.com"
-import numpy
+import numpy as np
import math
import scipy.interpolate
import logging
@@ -68,15 +68,14 @@
# BJONTEGAARD Bjontegaard metric
# Calculation is adapted from Google implementation
# PCHIP method - Piecewise Cubic Hermite Interpolating Polynomial interpolation
-def BD_RATE(br1, qtyMtrc1, br2, qtyMtrc2, qp1=None, qp2=None, EnablePreInterpolation=False):
- brqtypairs1 = []; brqtypairs2=[]
- if (EnablePreInterpolation):
- assert(qp1 is not None and qp2 is not None)
- brqtypairs1 = [(br1[i], qtyMtrc1[i], qp1[i]) for i in range(min(len(qp1), len(qtyMtrc1), len(br1)))]
- brqtypairs2 = [(br2[i], qtyMtrc2[i], qp2[i]) for i in range(min(len(qp2), len(qtyMtrc2), len(br2)))]
- else:
- brqtypairs1 = [(br1[i], qtyMtrc1[i]) for i in range(min(len(qtyMtrc1), len(br1)))]
- brqtypairs2 = [(br2[i], qtyMtrc2[i]) for i in range(min(len(qtyMtrc2), len(br2)))]
+def BD_RATE(br1, qtyMtrc1, br2, qtyMtrc2):
+ brqtypairs1 = []; brqtypairs2 = []
+ for i in range(min(len(qtyMtrc1), len(br1))):
+ if (br1[i] != '' and qtyMtrc1[i] != ''):
+ brqtypairs1.append((br1[i], qtyMtrc1[i]))
+ for i in range(min(len(qtyMtrc2), len(br2))):
+ if (br2[i] != '' and qtyMtrc2[i] != ''):
+ brqtypairs2.append((br2[i], qtyMtrc2[i]))
# sort the pair based on quality metric values in increasing order
# if quality metric values are the same, then sort the bit rate in increasing order
@@ -87,19 +86,11 @@
qmetrics1 = [100.0 if x[1] == float('inf') else x[1] for x in brqtypairs1]
logbr2 = [math.log(x[0]) for x in brqtypairs2]
qmetrics2 = [100.0 if x[1] == float('inf') else x[1] for x in brqtypairs2]
- if (EnablePreInterpolation):
- qp1 = [x[2] for x in brqtypairs1]
- qp2 = [x[2] for x in brqtypairs2]
if not brqtypairs1 or not brqtypairs2:
logger.info("one of input lists is empty!")
return 0.0
- # perform an bi-linear interpolation based on QP
- if EnablePreInterpolation:
- qp1, logbr1, qmetrics1 = Interpolate(qp1, logbr1, qmetrics1)
- qp2, logbr2, qmetrics2 = Interpolate(qp2, logbr2, qmetrics2)
-
# remove duplicated quality metric value, the RD point with higher bit rate is removed
dup_idx = [i for i in range(1, len(qmetrics1)) if qmetrics1[i - 1] == qmetrics1[i]]
for idx in sorted(dup_idx, reverse=True):
@@ -118,7 +109,7 @@
return 0.0
# generate samples between max and min of quality metrics
- lin = numpy.linspace(min_int, max_int, num=100, retstep=True)
+ lin = np.linspace(min_int, max_int, num=100, retstep=True)
interval = lin[1]
samples = lin[0]
@@ -127,8 +118,8 @@
v2 = scipy.interpolate.pchip_interpolate(qmetrics2, logbr2, samples)
# Calculate the integral using the trapezoid method on the samples.
- int1 = numpy.trapz(v1, dx=interval)
- int2 = numpy.trapz(v2, dx=interval)
+ int1 = np.trapz(v1, dx=interval)
+ int2 = np.trapz(v2, dx=interval)
# find avg diff
avg_exp_diff = (int2 - int1) / (max_int - min_int)
diff --git a/tools/convexhull_framework/src/Config.py b/tools/convexhull_framework/src/Config.py
index 53281f3..2fc154c 100644
--- a/tools/convexhull_framework/src/Config.py
+++ b/tools/convexhull_framework/src/Config.py
@@ -117,12 +117,14 @@
VMAF = os.path.join(BinPath, 'vmafossexec.exe')
HDRTool = os.path.join(BinPath, 'HDRMetrics.exe')
CalcBDRateInExcel = False
+EnablePreInterpolation = True
######################## config for exporting data to excel #################
#https://xlsxwriter.readthedocs.io/working_with_colors.html#colors
# line color used, number of colors >= len(DnScaledRes)
LineColors = ['blue', 'red', 'green', 'orange', 'pink', 'yellow']
ConvexHullColor = 'white'
+Int_ConvexHullColor = 'cyan'
# find out QP/Resolution with specified qty metrics
TargetQtyMetrics = {'VMAF_Y': [60, 70, 80, 90],
@@ -140,7 +142,7 @@
# format for writing convexhull curve data
CvxHDataStartRow = CvxH_WtRows[-1] + 2; CvxHDataStartCol = 0
-CvxHDataNum = 5 # qty, bitrate, qp, resolution, 1 empty row as internal
+CvxHDataNum = 7 # qty, bitrate, qp, resolution, int_qty, int_bitrate, 1 empty row as internal
CvxHDataRows = [CvxHDataStartRow + 1 + CvxHDataNum * i for i in range(len(QualityList))]
######################## post analysis #########################################
diff --git a/tools/convexhull_framework/src/ConvexHullBDRate.py b/tools/convexhull_framework/src/ConvexHullBDRate.py
index 311fe91..b7a8b40 100644
--- a/tools/convexhull_framework/src/ConvexHullBDRate.py
+++ b/tools/convexhull_framework/src/ConvexHullBDRate.py
@@ -79,12 +79,16 @@
return int(cell_val)
-def ParseConvexHullRD(xls):
+def ParseConvexHullRD(xls, EnablePreInterpolation = False):
wb = xlrd.open_workbook(xls)
shts = wb.sheet_names() #list of sheet names
data = {} #dict of data, key is the sheet name
- cols = [3 + i * 4 for i in range(len(QualityList))]
+ cvx_cols = 4
+ if EnablePreInterpolation:
+ cvx_cols = 6
+
+ cols = [3 + i * cvx_cols for i in range(len(QualityList))]
for sht_name in shts:
sht = wb.sheet_by_name(sht_name)
#skip the title row
@@ -107,11 +111,20 @@
qp = read_cell_as_int(sht, start_row+row, col + 1) #QP
br = read_cell_as_float(sht, start_row+row, col + 2) #Bitrate
q = read_cell_as_float(sht, start_row+row, col + 3) #Quality
- if br != '' and q != '':
- if qty in rd_data:
- rd_data[qty].append((res, qp, br, q))
- else:
- rd_data.update({qty: [(res, qp, br, q)]})
+ if EnablePreInterpolation:
+ int_br = read_cell_as_float(sht, start_row+row, col + 4) #Int_Bitrate
+ int_q = read_cell_as_float(sht, start_row+row, col + 5) # Int_Quality
+ if int_br != '' and int_q != '':
+ if qty in rd_data:
+ rd_data[qty].append((br, q, int_br, int_q))
+ else:
+ rd_data.update({qty: [(br, q, int_br, int_q)]})
+ else:
+ if br != '' and q != '':
+ if qty in rd_data:
+ rd_data[qty].append((br, q))
+ else:
+ rd_data.update({qty: [(br, q)]})
start_row += num
point.RDPoints = rd_data
@@ -123,93 +136,147 @@
return shts, data
-def WriteOutputHeaderRow(sht):
+def WriteOutputHeaderRow(sht, EnablePreInterpolation = False):
sht.write(0, 0, 'Content Class')
sht.write(0, 1, 'Content Name')
sht.write(0, 2, 'Num RD Points')
col = 3
for qty in QualityList:
- sht.write(0, col, 'Resolution')
- sht.write(0, col + 1, 'QP')
- sht.write(0, col + 2, 'Bitrate(kbps)')
- sht.write(0, col + 3, qty)
- col += 4
+ sht.write(0, col, 'Bitrate(kbps)')
+ sht.write(0, col + 1, qty)
+ if EnablePreInterpolation:
+ sht.write(0, col + 2, 'Int_Bitrate(kbps)')
+ sht.write(0, col + 3, 'Int_' + qty)
+ col += 4
+ else:
+ col += 2
+
col += 1
for qty in QualityList:
- sht.write(0, col, 'Resolution')
- sht.write(0, col + 1, 'QP')
- sht.write(0, col + 2, 'Bitrate(kbps)')
- sht.write(0, col + 3, qty)
- col += 4
+ sht.write(0, col, 'Bitrate(kbps)')
+ sht.write(0, col + 1, qty)
+ if EnablePreInterpolation:
+ sht.write(0, col + 2, 'Int_Bitrate(kbps)')
+ sht.write(0, col + 3, 'Int_' + qty)
+ col += 4
+ else:
+ col += 2
col += 1
for (idx, qty) in zip(range(len(QualityList)), QualityList):
sht.write(0, col + idx, "BDRATE-%s" % qty)
-def WriteRDData(sht, rd_data, start_row, start_col, format):
+def WriteRDData(sht, rd_data, start_row, start_col, format,
+ EnablePreInterpolation = False):
col = start_col
max_rows = 0
for qty in QualityList:
row = start_row
for (line, point) in zip(range(len(rd_data.RDPoints[qty])),
rd_data.RDPoints[qty]):
- sht.write_string(row + line, col, point[0]) #Resolution
- sht.write_number(row + line, col + 1, point[1]) #QP
- sht.write_number(row + line, col + 2, point[2], format) #Bitrate
- sht.write_number(row + line, col + 3, point[3], format) #Quality
- col += 4
+ if point[0] != '':
+ sht.write_number(row + line, col, point[0], format) #Bitrate
+ if point[1] != '':
+ sht.write_number(row + line, col + 1, point[1], format) #Quality
+ if EnablePreInterpolation:
+ if point[2] != '':
+ sht.write_number(row + line, col + 2, point[2], format) # Int_Bitrate
+ if point[3] != '':
+ sht.write_number(row + line, col + 3, point[3], format) # Int_Quality
+ if EnablePreInterpolation:
+ col += 4
+ else:
+ col += 2
max_rows = max(max_rows, len(rd_data.RDPoints[qty]))
return max_rows
-def WriteRDRecord(sht, base_data, target_data, start_row, bdrate_fmt, float_fmt):
+def WriteRDRecord(sht, base_data, target_data, start_row, bdrate_fmt, float_fmt,
+ EnablePreInterpolation = False):
sht.write(start_row, 0, base_data.ContentClass)
sht.write(start_row, 1, base_data.ContentName)
#write base data
base_start_col = 3
+ cvx_cols = 2
+ if EnablePreInterpolation:
+ cvx_cols = 4
+
base_max_rows = WriteRDData(sht, base_data, start_row, base_start_col,
- float_fmt)
+ float_fmt, EnablePreInterpolation)
#write target data
- target_start_col = base_start_col + 4 * len(QualityList) + 1
+ target_start_col = base_start_col + cvx_cols * len(QualityList) + 1
target_max_rows = WriteRDData(sht, target_data, start_row, target_start_col,
- float_fmt)
+ float_fmt, EnablePreInterpolation)
#write bdrate formula
- bdrate_start_col = target_start_col + 4 * len(QualityList) + 1
+ bdrate_start_col = target_start_col + cvx_cols * len(QualityList) + 1
total_rows = max(base_max_rows, target_max_rows)
sht.write(start_row, 2, total_rows)
for (qty, col) in zip(QualityList, range(len(QualityList))):
if CalcBDRateInExcel:
- refbr_b = xlrd.cellnameabs(start_row, base_start_col + col * 4 + 2)
+ refbr_b = xlrd.cellnameabs(start_row,
+ base_start_col + col * cvx_cols)
refbr_e = xlrd.cellnameabs(start_row + total_rows - 1,
- base_start_col + col * 4 + 2)
- refq_b = xlrd.cellnameabs(start_row, base_start_col + col * 4 + 3)
+ base_start_col + col * cvx_cols)
+ refq_b = xlrd.cellnameabs(start_row,
+ base_start_col + col * cvx_cols + 1)
refq_e = xlrd.cellnameabs(start_row + total_rows - 1,
- base_start_col + col * 4 + 3)
+ base_start_col + col * cvx_cols + 1)
- testbr_b = xlrd.cellnameabs(start_row, target_start_col + col * 4 + 2)
+ testbr_b = xlrd.cellnameabs(start_row,
+ target_start_col + col * cvx_cols)
testbr_e = xlrd.cellnameabs(start_row + total_rows - 1,
- target_start_col + col * 4 + 2)
- testq_b = xlrd.cellnameabs(start_row, target_start_col + col * 4 + 3)
+ target_start_col + col * cvx_cols)
+ testq_b = xlrd.cellnameabs(start_row,
+ target_start_col + col * cvx_cols + 1)
testq_e = xlrd.cellnameabs(start_row + total_rows - 1,
- target_start_col + col * 4 + 3)
+ target_start_col + col * cvx_cols + 1)
# formula = '=-bdrate(%s:%s,%s:%s,%s:%s,%s:%s)' % (
# refbr_b, refbr_e, refq_b, refq_e, testbr_b, testbr_e, testq_b, testq_e)
formula = '=bdRateExtend(%s:%s,%s:%s,%s:%s,%s:%s)'\
% (refbr_b, refbr_e, refq_b, refq_e, testbr_b, testbr_e, testq_b, testq_e)
sht.write_formula(start_row, bdrate_start_col + col, formula, bdrate_fmt)
+
+ if EnablePreInterpolation:
+ refbr_b = xlrd.cellnameabs(start_row,
+ base_start_col + col * cvx_cols + 2)
+ refbr_e = xlrd.cellnameabs(start_row + total_rows - 1,
+ base_start_col + col * cvx_cols + 2)
+ refq_b = xlrd.cellnameabs(start_row,
+ base_start_col + col * cvx_cols + 3)
+ refq_e = xlrd.cellnameabs(start_row + total_rows - 1,
+ base_start_col + col * cvx_cols + 3)
+
+ testbr_b = xlrd.cellnameabs(start_row,
+ target_start_col + col * cvx_cols + 2)
+ testbr_e = xlrd.cellnameabs(start_row + total_rows - 1,
+ target_start_col + col * cvx_cols + 2)
+ testq_b = xlrd.cellnameabs(start_row,
+ target_start_col + col * cvx_cols + 3)
+ testq_e = xlrd.cellnameabs(start_row + total_rows - 1,
+ target_start_col + col * cvx_cols + 3)
+ formula = '=bdRateExtend(%s:%s,%s:%s,%s:%s,%s:%s)' \
+ % (refbr_b, refbr_e, refq_b, refq_e, testbr_b, testbr_e, testq_b,
+ testq_e)
+
+ sht.write_formula(start_row + 1, bdrate_start_col + col, formula, bdrate_fmt)
else:
- refqps = [base_data.RDPoints[qty][i][1] for i in range(len(base_data.RDPoints[qty]))]
- refbrs = [base_data.RDPoints[qty][i][2] for i in range(len(base_data.RDPoints[qty]))]
- refqtys = [base_data.RDPoints[qty][i][3] for i in range(len(base_data.RDPoints[qty]))]
- testqps = [target_data.RDPoints[qty][i][1] for i in range(len(target_data.RDPoints[qty]))]
- testbrs = [target_data.RDPoints[qty][i][2] for i in range(len(target_data.RDPoints[qty]))]
- testqtys = [target_data.RDPoints[qty][i][3] for i in range(len(target_data.RDPoints[qty]))]
- bdrate = BD_RATE(refbrs, refqtys, testbrs, testqtys, refqps, testqps, False) / 100.0
+ refbrs = [base_data.RDPoints[qty][i][0] for i in range(len(base_data.RDPoints[qty]))]
+ refqtys = [base_data.RDPoints[qty][i][1] for i in range(len(base_data.RDPoints[qty]))]
+ testbrs = [target_data.RDPoints[qty][i][0] for i in range(len(target_data.RDPoints[qty]))]
+ testqtys = [target_data.RDPoints[qty][i][1] for i in range(len(target_data.RDPoints[qty]))]
+ bdrate = BD_RATE(refbrs, refqtys, testbrs, testqtys) / 100.0
sht.write_number(start_row, bdrate_start_col + col, bdrate, bdrate_fmt)
+ if EnablePreInterpolation:
+ refbrs = [base_data.RDPoints[qty][i][2] for i in range(len(base_data.RDPoints[qty]))]
+ refqtys = [base_data.RDPoints[qty][i][3] for i in range(len(base_data.RDPoints[qty]))]
+ testbrs = [target_data.RDPoints[qty][i][2] for i in range(len(target_data.RDPoints[qty]))]
+ testqtys = [target_data.RDPoints[qty][i][3] for i in range(len(target_data.RDPoints[qty]))]
+ bdrate = BD_RATE(refbrs, refqtys, testbrs, testqtys) / 100.0
+ sht.write_number(start_row + 1, bdrate_start_col + col, bdrate, bdrate_fmt)
return total_rows
@@ -228,8 +295,8 @@
#"-o","ConvexHullBDRate.xlsm"]
ParseArguments(sys.argv)
- base_shts, base_rd_data = ParseConvexHullRD(InputBase)
- target_shts, target_rd_data = ParseConvexHullRD(InputTarget)
+ base_shts, base_rd_data = ParseConvexHullRD(InputBase, True)
+ target_shts, target_rd_data = ParseConvexHullRD(InputTarget, True)
output_wb = xlsxwriter.Workbook(Output)
# vba file needed when to calculate bdrate
@@ -242,14 +309,14 @@
for sht_name in base_shts:
if sht_name in target_shts:
sht = output_wb.add_worksheet(sht_name)
- WriteOutputHeaderRow(sht)
+ WriteOutputHeaderRow(sht, True)
start_row = 1
for base_data in base_rd_data[sht_name]:
ContentName = base_data.ContentName
target_data = FindContent(ContentName, target_rd_data[sht_name])
if target_data != '':
total_rows = WriteRDRecord(sht, base_data, target_data,
- start_row, bdrate_fmt, float_fmt)
+ start_row, bdrate_fmt, float_fmt, True)
start_row += total_rows
output_wb.close()
diff --git a/tools/convexhull_framework/src/ConvexHullTest.py b/tools/convexhull_framework/src/ConvexHullTest.py
index 3c3e4c3..8493db1 100644
--- a/tools/convexhull_framework/src/ConvexHullTest.py
+++ b/tools/convexhull_framework/src/ConvexHullTest.py
@@ -14,6 +14,9 @@
import sys
import xlsxwriter
import argparse
+import numpy as np
+import scipy.interpolate
+
from EncDecUpscale import Run_EncDec_Upscale, GetBsReconFileName
from VideoScaler import GetDownScaledOutFile, DownScaling
from CalculateQualityMetrics import CalculateQualityMetric, GatherQualityMetrics
@@ -29,7 +32,9 @@
CvxH_WtRows, QualityList, LineColors, DnScalingAlgos, UpScalingAlgos,\
ContentPath, SummaryOutPath, WorkPath, Path_RDResults, Clips, \
ConvexHullColor, EncodeMethods, CodecNames, LoggerName, LogCmdOnly, \
- TargetQtyMetrics, CvxHDataRows, CvxHDataStartRow, CvxHDataStartCol, CvxHDataNum
+ TargetQtyMetrics, CvxHDataRows, CvxHDataStartRow, CvxHDataStartCol, \
+ CvxHDataNum, Int_ConvexHullColor, EnablePreInterpolation
+from operator import itemgetter
###############################################################################
##### Helper Functions ########################################################
@@ -121,11 +126,15 @@
return qtyQPs, qtyRes
-def AddConvexHullCurveToCharts(sht, charts, rdPoints, dnScaledRes, tgtqmetrics):
+def AddConvexHullCurveToCharts(sht, charts, rdPoints, dnScaledRes, tgtqmetrics,
+ EnablePreInterpolation = False, int_rdPoints = None):
+ if EnablePreInterpolation:
+ assert int_rdPoints is not None
+
shtname = sht.get_name()
sht.write(CvxHDataStartRow, CvxHDataStartCol, "ConvexHull Data")
- hull = {}; cvh_QPs = {}; cvh_Res_txt = {}
+ hull = {}; cvh_QPs = {}; cvh_Res_txt = {}; int_hull = {}
max_len = 0
for qty, idx, row in zip(QualityList, range(len(QualityList)), CvxHDataRows):
@@ -136,6 +145,11 @@
sht.write(row + 1, CvxHDataStartCol, "Bitrate(kbps)")
sht.write(row + 2, CvxHDataStartCol, "QP")
sht.write(row + 3, CvxHDataStartCol, 'Resolution')
+ if EnablePreInterpolation:
+ lower, upper = convex_hull(int_rdPoints[idx])
+ int_hull[qty] = upper
+ sht.write(row + 4, CvxHDataStartCol, "Int_" + qty)
+ sht.write(row + 5, CvxHDataStartCol, "Int_Bitrate(kbps)")
brts = [h[0] for h in hull[qty]]
qtys = [h[1] for h in hull[qty]]
@@ -148,10 +162,20 @@
cvh_Res_txt[qty] = ["%sx%s" % (x, y) for (x, y) in cvh_Res]
sht.write_row(row + 2, CvxHDataStartCol + 1, cvh_QPs[qty])
sht.write_row(row + 3, CvxHDataStartCol + 1, cvh_Res_txt[qty])
+ if EnablePreInterpolation:
+ int_brts = [h[0] for h in int_hull[qty]]
+ int_qtys = [h[1] for h in int_hull[qty]]
+ sht.write_row(row + 4, CvxHDataStartCol + 1, int_qtys)
+ sht.write_row(row + 5, CvxHDataStartCol + 1, int_brts)
cols = [CvxHDataStartCol + 1 + i for i in range(len(hull[qty]))]
AddSeriesToChart_Scatter_Rows(shtname, cols, row, row + 1, charts[idx],
'ConvexHull', ConvexHullColor)
+ if EnablePreInterpolation:
+ int_cols = [CvxHDataStartCol + 1 + i for i in range(len(int_hull[qty]))]
+ AddSeriesToChart_Scatter_Rows(shtname, int_cols, row + 4, row + 5,
+ charts[idx], 'Int_ConvexHull',
+ Int_ConvexHullColor)
endrow = CvxHDataRows[-1] + CvxHDataNum
# find out QP/resolution for given qty metric and qty value
@@ -233,7 +257,40 @@
Utils.Logger.info("finish running encode test.")
-def SaveConvexHullResultsToExcel(content, dnScAlgos, upScAlgos):
+def Interpolate(RDPoints):
+ '''
+ generate interpolated points on a RD curve.
+ input is list of existing RD points as (bitrate, quality) tuple
+ total number of interpolated points depends on the min and max QP
+ '''
+ # sort the pair based on bitrate in increasing order
+ # if bitrate is the same, then sort based on quality in increasing order
+ RDPoints.sort(key = itemgetter(0, 1))
+ br = [RDPoints[i][0] for i in range(len(RDPoints))]
+ qty = [RDPoints[i][1] for i in range(len(RDPoints))]
+
+ # generate samples between max and min of quality metrics
+ min_br = min(br); max_br = max(br)
+ min_qp = min(QPs); max_qp = max(QPs)
+ lin = np.linspace(min_br, max_br, num = (max_qp - min_qp + 1), retstep = True)
+ int_br = lin[0]
+
+ # interpolation using pchip
+ int_qty = scipy.interpolate.pchip_interpolate(br, qty, int_br)
+
+ '''
+ print("before interpolation:")
+ for i in range(len(br)):
+ print("%f, %f"%(br[i], qty[i]))
+ print("after interpolation:")
+ for i in range(len(int_br)):
+ print("%f, %f"%(int_br[i], int_qty[i]))
+ '''
+ int_points = [(int_br[i], int_qty[i]) for i in range(len(int_br))]
+ return int_points
+
+def SaveConvexHullResultsToExcel(content, dnScAlgos, upScAlgos,
+ EnablePreInterpolation=False):
Utils.Logger.info("start saving RD results to excel file.......")
if not os.path.exists(Path_RDResults):
os.makedirs(Path_RDResults)
@@ -253,13 +310,13 @@
sht.write_column(CvxH_WtRows[0], 0, QPs)
shtname = sht.get_name()
- charts = []; y_mins = {}; y_maxs = {}; RDPoints = {}
+ charts = []; y_mins = {}; y_maxs = {}; RDPoints = {}; Int_RDPoints = {}
for qty, x in zip(QualityList, range(len(QualityList))):
chart_title = 'RD Curves - %s with %s' % (contentname, shtname)
xaxis_name = 'Bitrate - Kbps'
chart = CreateChart_Scatter(wb, chart_title, xaxis_name, qty)
charts.append(chart)
- y_mins[x] = []; y_maxs[x] = []; RDPoints[x] = []
+ y_mins[x] = []; y_maxs[x] = []; RDPoints[x] = []; Int_RDPoints[x] = []
# write RD data
for col, i in zip(CvxH_WtCols, range(len(DnScaledRes))):
@@ -297,10 +354,14 @@
# get RD points - (bitrate, quality) for each quality metrics
rdpnts = [(brt, qty) for brt, qty in zip(bitratesKbps, qs)]
RDPoints[x] = RDPoints[x] + rdpnts
+ if EnablePreInterpolation:
+ int_rdpnts = Interpolate(rdpnts)
+ Int_RDPoints[x] = Int_RDPoints[x] + int_rdpnts
# add convexhull curve to charts
endrow = AddConvexHullCurveToCharts(sht, charts, RDPoints, DnScaledRes,
- TargetQtyMetrics)
+ TargetQtyMetrics, EnablePreInterpolation,
+ Int_RDPoints)
#update RD chart with approprate y axis range
for qty, x in zip(QualityList, range(len(QualityList))):
@@ -399,8 +460,8 @@
Run_ConvexHull_Test(content, dnScalAlgo, upScalAlgo)
elif Function == 'convexhull':
for content in Contents:
- SaveConvexHullResultsToExcel(content, DnScalingAlgos, UpScalingAlgos)
-
+ SaveConvexHullResultsToExcel(content, DnScalingAlgos, UpScalingAlgos,
+ EnablePreInterpolation)
elif Function == 'summary':
RDResultFilesGenerated = []
for content in Contents:
@@ -411,8 +472,10 @@
ContentPath, Clips)
Utils.Logger.info("RD data summary file generated: %s" % RDsmfile)
- CvxHsmfile = GenerateSummaryConvexHullExcelFile(EncodeMethod, CodecName, EncodePreset,
- SummaryOutPath, RDResultFilesGenerated)
+ CvxHsmfile = GenerateSummaryConvexHullExcelFile(EncodeMethod, CodecName,
+ EncodePreset, SummaryOutPath,
+ RDResultFilesGenerated,
+ EnablePreInterpolation)
Utils.Logger.info("Convel hull summary file generated: %s" % CvxHsmfile)
else:
Utils.Logger.error("invalid parameter value of Function")
diff --git a/tools/convexhull_framework/src/PostAnalysis_Summary.py b/tools/convexhull_framework/src/PostAnalysis_Summary.py
index c2b78a9..290c8c9 100644
--- a/tools/convexhull_framework/src/PostAnalysis_Summary.py
+++ b/tools/convexhull_framework/src/PostAnalysis_Summary.py
@@ -414,16 +414,19 @@
return smfile
def GenerateSummaryConvexHullExcelFile(encMethod, codecName, preset,
- summary_outpath, resultfiles):
+ summary_outpath, resultfiles,
+ EnablePreInterpolation = False):
if not os.path.exists(summary_outpath):
os.makedirs(summary_outpath)
smfile = GetConvexHullDataSummaryFileName(encMethod, codecName, preset,
summary_outpath)
wb = xlsxwriter.Workbook(smfile)
-
+ cvx_cols = 4
+ if EnablePreInterpolation:
+ cvx_cols = 6
# shts is for all scaling algorithms' convex hull test results
shts = []
- cols = [3 + i * 4 for i in range(len(QualityList))]
+ cols = [3 + i * cvx_cols for i in range(len(QualityList))]
for dnsc, upsc in zip(dnScalAlgos, upScalAlgos):
shtname = dnsc + '--' + upsc
sht = wb.add_worksheet(shtname)
@@ -438,6 +441,9 @@
sht.write(0, col + 1, 'QP')
sht.write(0, col + 2, 'Bitrate(kbps)')
sht.write(0, col + 3, qty)
+ if EnablePreInterpolation:
+ sht.write(0, col + 4, 'Int_Bitrate(kbps)')
+ sht.write(0, col + 5, 'Int_' + qty)
# copy convexhull data from each content's result file to corresponding
# location in summary excel file
@@ -452,9 +458,10 @@
if key in resfile:
rdwb = xlrd.open_workbook(resfile)
rdsht = rdwb.sheet_by_name(shtname)
- maxNumQty = 0
+ maxNumQty = 0; maxNumIntQty = 0
for rdrow, col in zip(CvxHDataRows, cols):
qtys = []; brs = []; qps = []; ress = []
+ int_qtys = []; int_brs = []
numQty = 0
for qty in rdsht.row_values(rdrow)[rdcolstart:]:
if qty == '':
@@ -479,14 +486,32 @@
break
else:
ress.append(res)
+ if EnablePreInterpolation:
+ numQty = 0
+ for qty in rdsht.row_values(rdrow + 4)[
+ rdcolstart:]:
+ if qty == '':
+ break
+ else:
+ int_qtys.append(qty)
+ numQty = numQty + 1
+ maxNumIntQty = max(maxNumIntQty, numQty)
+ for br in rdsht.row_values(rdrow + 5)[rdcolstart:]:
+ if br == '':
+ break
+ else:
+ int_brs.append(br)
sht.write_column(row, col, ress)
sht.write_column(row, col + 1, qps)
sht.write_column(row, col + 2, brs)
sht.write_column(row, col + 3, qtys)
+ if EnablePreInterpolation:
+ sht.write_column(row, col + 4, int_brs)
+ sht.write_column(row, col + 5, int_qtys)
- sht.write(row, 2, maxNumQty)
- row = row + maxNumQty
+ sht.write(row, 2, max(maxNumQty, maxNumIntQty))
+ row = row + max(maxNumQty, maxNumIntQty)
break
wb.close()