add support to use ffmpeg and aom scaler

besides the option to use hdrtool as the scaler for adaptive
streaming configuraiton, this patch add the support to use ffmpeg and
lanscoz filter implementation in libaom code base as the scalers

Change-Id: Ifeafcbcf7510b421c8caa80006c80450698e6407
diff --git a/tools/convexhull_framework/src/CalcQtyWithVmafTool.py b/tools/convexhull_framework/src/CalcQtyWithVmafTool.py
index aee4ab6..8e020b2 100644
--- a/tools/convexhull_framework/src/CalcQtyWithVmafTool.py
+++ b/tools/convexhull_framework/src/CalcQtyWithVmafTool.py
@@ -29,6 +29,8 @@
     floats = len(VMAFMetricsFullList) * [0.0]
     per_frame_log = []
     flog = open(vmaf_log, 'r')
+    psnr_y='0'; psnr_cb='0'; psnr_cr='0'; ssim='0'; psnr_hvs='0'; ms_ssim='0';ciede2000='0'
+    frameNum='0'; vmaf='0'; vmaf_neg='0'
     for line in flog:
         m = re.search(r"<frame\s+frameNum=\"(\d+)\"",line)
         if m:
@@ -113,8 +115,7 @@
 
 ################################################################################
 ##################### Exposed Functions ########################################
-def VMAF_CalQualityMetrics(origfile, recfile, fmt, num, w, h, bit_depth,
-                           logfilePath, LogCmdOnly=False):
+def VMAF_CalQualityMetrics(origfile, recfile, logfilePath, LogCmdOnly=False):
     vmaf_log = GetVMAFLogFile(recfile, logfilePath)
     args = " -r %s -d %s --aom_ctc v1.0 -q --threads 4 -o %s" \
            % (origfile, recfile, vmaf_log)
diff --git a/tools/convexhull_framework/src/CalculateQualityMetrics.py b/tools/convexhull_framework/src/CalculateQualityMetrics.py
index ada29c7..45a60d8 100644
--- a/tools/convexhull_framework/src/CalculateQualityMetrics.py
+++ b/tools/convexhull_framework/src/CalculateQualityMetrics.py
@@ -23,8 +23,7 @@
 def CalculateQualityMetric(src_file, framenum, reconYUV, fmt, width, height,
                            bit_depth, logfilePath, LogCmdOnly=False):
     Utils.CmdLogger.write("::Quality Metrics\n")
-    VMAF_CalQualityMetrics(src_file, reconYUV, fmt, framenum, width, height,
-                           bit_depth, logfilePath, LogCmdOnly)
+    VMAF_CalQualityMetrics(src_file, reconYUV, logfilePath, LogCmdOnly)
 
 def GatherQualityMetrics(reconYUV, logfilePath):
     qresult, per_frame_log = VMAF_GatherQualityMetrics(reconYUV, logfilePath)
diff --git a/tools/convexhull_framework/src/Config.py b/tools/convexhull_framework/src/Config.py
index fc8afab..653f0e0 100644
--- a/tools/convexhull_framework/src/Config.py
+++ b/tools/convexhull_framework/src/Config.py
@@ -44,11 +44,14 @@
 DnScalingAlgos = ['lanczos'] #['bicubic', 'bilinear', 'gauss', 'lanczos', 'sinc']
 UpScalingAlgos = ['lanczos'] #['bicubic', 'bilinear', 'gauss', 'lanczos', 'sinc']
 
+ScaleMethods = ['hdrtool', 'ffmpeg', 'aom']
+
 if SMOKE_TEST:
     DnScalingAlgos = ['bicubic', 'lanczos', 'sinc']
     UpScalingAlgos = ['bicubic', 'lanczos', 'sinc']
 HDRToolsConfigFileTemplate = os.path.join(BinPath, 'HDRConvScalerY4MFile.cfg')
 HDRConvert = os.path.join(BinPath, 'HDRConvert.exe')
+AOMScaler = os.path.join(BinPath, 'lanczos_resample_y4m.exe')
 
 ##################### Encode Config ########################################
 EncodeMethods = ["aom", "svt"]
diff --git a/tools/convexhull_framework/src/ConvexHullTest.py b/tools/convexhull_framework/src/ConvexHullTest.py
index ccde128..ca4f670 100755
--- a/tools/convexhull_framework/src/ConvexHullTest.py
+++ b/tools/convexhull_framework/src/ConvexHullTest.py
@@ -34,7 +34,7 @@
      EncodeMethods, CodecNames, LoggerName, DnScaleRatio, TargetQtyMetrics, \
      CvxHDataRows, CvxHDataStartRow, CvxHDataStartCol, CvxHDataNum, \
      Int_ConvexHullColor, EnablePreInterpolation, AS_DOWNSCALE_ON_THE_FLY,\
-     UsePerfUtil
+     UsePerfUtil, ScaleMethods
 
 ###############################################################################
 ##### Helper Functions ########################################################
@@ -177,7 +177,7 @@
     for folder in folders:
         Cleanfolder(folder)
 
-def Run_ConvexHull_Test(clip, dnScalAlgo, upScalAlgo, LogCmdOnly = False):
+def Run_ConvexHull_Test(clip, dnScalAlgo, upScalAlgo, ScaleMethod, LogCmdOnly = False):
     Utils.Logger.info("start encode %s" % clip.file_name)
     DnScaledRes = [(int(clip.width / ratio), int(clip.height / ratio)) for ratio in
                    DnScaleRatio]
@@ -189,9 +189,9 @@
         DnScaledH = DnScaledRes[i][1]
         # downscaling if the downscaled file does not exist
         dnscalyuv = GetDownScaledOutFile(clip, DnScaledW, DnScaledH, Path_DnScaleYuv,
-                                         dnScalAlgo, AS_DOWNSCALE_ON_THE_FLY, i)
+                                         ScaleMethod, dnScalAlgo, AS_DOWNSCALE_ON_THE_FLY, i)
         if not os.path.isfile(dnscalyuv):
-            dnscalyuv = DownScaling(clip, FrameNum['AS'], DnScaledW, DnScaledH,
+            dnscalyuv = DownScaling(ScaleMethod, clip, FrameNum['AS'], DnScaledW, DnScaledH,
                                     Path_DnScaleYuv, Path_CfgFiles, dnScalAlgo, LogCmdOnly)
         ds_clip = Clip(GetShortContentName(dnscalyuv, False)+'.y4m', dnscalyuv,
                        clip.file_class, DnScaledW, DnScaledH, clip.fmt, clip.fps_num,
@@ -357,19 +357,24 @@
                         help="EncodeMethod: aom, svt")
     parser.add_argument('-p', "--EncodePreset", dest='EncodePreset', type=str,
                         metavar='', help="EncodePreset: 0,1,2... for aom and svt")
+    parser.add_argument('-t', '--ScaleMethod', dest='ScaleMethod', type=str,
+                        choices=ScaleMethods, metavar='',
+                        help="ScaleMethod: ffmpeg, hdrtool, aom")
+
     if len(raw_args) == 1:
         parser.print_help()
         sys.exit(1)
     args = parser.parse_args(raw_args[1:])
 
     global Function, KeepUpscaledOutput, SaveMemory, LogLevel, CodecName,\
-        EncodeMethod, EncodePreset, LogCmdOnly
+        EncodeMethod, ScaleMethod, EncodePreset, LogCmdOnly
     Function = args.Function
     KeepUpscaledOutput = args.KeepUpscaledOutput
     SaveMemory = args.SaveMemory
     LogLevel = args.LogLevel
     CodecName = args.CodecName
     EncodeMethod = args.EncodeMethod
+    ScaleMethod = args.ScaleMethod
     EncodePreset = args.EncodePreset
     LogCmdOnly = args.LogCmdOnly
 
@@ -379,11 +384,11 @@
 ######################################
 if __name__ == "__main__":
     #sys.argv = ["","-f","clean"]
-    #sys.argv = ["","-f","scaling"]
-    #sys.argv = ["", "-f", "sumscaling"]
-    #sys.argv = ["", "-f", "encode","-c","av1","-m","aom","-p","6"]
-    #sys.argv = ["", "-f", "convexhull","-c","av1","-m","aom","-p","6"]
-    #sys.argv = ["", "-f", "summary", "-c", "av1", "-m", "aom", "-p", "6"]
+    #sys.argv = ["","-f","scaling", "-t", "hdrtool"]
+    #sys.argv = ["", "-f", "sumscaling", "-t", "hdrtool"]
+    #sys.argv = ["", "-f", "encode","-c","av1","-m","aom","-p","6", "-t", "hdrtool"]
+    #sys.argv = ["", "-f", "convexhull","-c","av1","-m","aom","-p","6", "-t", "hdrtool"]
+    #sys.argv = ["", "-f", "summary", "-c", "av1", "-m", "aom", "-p", "6", "-t", "hdrtool"]
     ParseArguments(sys.argv)
 
     # preparation for executing functions
@@ -400,15 +405,15 @@
             for dnScaleAlgo, upScaleAlgo in zip(DnScalingAlgos, UpScalingAlgos):
                 Run_Scaling_Test(clip, dnScaleAlgo, upScaleAlgo,
                                  Path_DnScaleYuv, Path_UpScaleYuv, Path_QualityLog,
-                                 Path_CfgFiles, SaveMemory, KeepUpscaledOutput,
+                                 Path_CfgFiles, SaveMemory, KeepUpscaledOutput, ScaleMethod,
                                  LogCmdOnly)
     elif Function == 'sumscaling':
-        SaveScalingResultsToExcel(DnScalingAlgos, UpScalingAlgos, clip_list,
+        SaveScalingResultsToExcel(ScaleMethod, DnScalingAlgos, UpScalingAlgos, clip_list,
                                   Path_QualityLog)
     elif Function == 'encode':
         for clip in clip_list:
             for dnScalAlgo, upScalAlgo in zip(DnScalingAlgos, UpScalingAlgos):
-                Run_ConvexHull_Test(clip, dnScalAlgo, upScalAlgo, LogCmdOnly)
+                Run_ConvexHull_Test(clip, dnScalAlgo, upScalAlgo, ScaleMethod, LogCmdOnly)
     elif Function == 'convexhull':
         csv_file, perframe_csvfile = GetRDResultCsvFile(EncodeMethod, CodecName, EncodePreset, "AS")
         csv = open(csv_file, "wt")
diff --git a/tools/convexhull_framework/src/EncDecUpscale.py b/tools/convexhull_framework/src/EncDecUpscale.py
index fe97ad5..62d6c88 100644
--- a/tools/convexhull_framework/src/EncDecUpscale.py
+++ b/tools/convexhull_framework/src/EncDecUpscale.py
@@ -61,7 +61,7 @@
 
 def Run_EncDec_Upscale(method, codec, preset, clip, test_cfg, QP, num, outw,
                        outh, path_bs, path_decoded, path_upscaled, path_cfg,
-                       path_perf, path_enc_log, upscale_algo, LogCmdOnly = False):
+                       path_perf, path_enc_log, upscale_algo, scale_method, LogCmdOnly = False):
     logger.info("%s %s start encode file %s with QP = %d" %
                 (method, codec, clip.file_name, QP))
     bsFile = Encode(method, codec, preset, clip, test_cfg, QP, num, path_bs,
@@ -75,15 +75,15 @@
     dec_clip = Clip(GetShortContentName(decodedYUV, False) + ".y4m",
                     decodedYUV, clip.file_class, clip.width, clip.height,
                     clip.fmt, 0, 0, clip.bit_depth)
-    upscaledYUV = UpScaling(dec_clip, num, outw, outh, path_upscaled, path_cfg,
+    upscaledYUV = UpScaling(scale_method, dec_clip, num, outw, outh, path_upscaled, path_cfg,
                             upscale_algo, LogCmdOnly)
     logger.info("finish Run Encode, Decode and Upscale")
     return upscaledYUV
 
 
 def GetBsReconFileName(encmethod, codecname, test_cfg, preset, clip, dw, dh,
-                       dnScAlgo, upScAlgo, qp, path_bs, ds_on_the_fly=True, ratio_idx=0):
-    dsyuv_name = GetDownScaledOutFile(clip, dw, dh, path_bs, dnScAlgo, ds_on_the_fly, ratio_idx)
+                       scale_method, dnScAlgo, upScAlgo, qp, path_bs, ds_on_the_fly=True, ratio_idx=0):
+    dsyuv_name = GetDownScaledOutFile(clip, dw, dh, path_bs, scale_method, dnScAlgo, ds_on_the_fly, ratio_idx)
     # return bitstream file with absolute path
     bs = GetBitstreamFile(encmethod, codecname, test_cfg, preset, dsyuv_name,
                           qp, path_bs)
diff --git a/tools/convexhull_framework/src/ScalingTest.py b/tools/convexhull_framework/src/ScalingTest.py
index f6e4710..382b919 100644
--- a/tools/convexhull_framework/src/ScalingTest.py
+++ b/tools/convexhull_framework/src/ScalingTest.py
@@ -22,7 +22,7 @@
      ScalSumQty_WtCols
 from Utils import Cleanfolder, GetShortContentName, CreateChart_Scatter, \
      AddSeriesToChart_Scatter, UpdateChart, InsertChartsToSheet, \
-     CalcRowsClassAndContentDict, Clip
+     CalcRowsClassAndContentDict, Clip, CreateChart_Bar, AddSeriesToChart_Bar
 
 subloggername = "ScalingTest"
 loggername = LoggerName + '.' + '%s' % subloggername
@@ -30,20 +30,20 @@
 
 StatsMetrics = ['Max', 'Std+', 'Average', 'Std-', 'Min']
 
-def GetScalingResultExcelFile(rationum, scalAlgoNum):
-    filename = "ScalingResults_RatioNum_%d_AlgoNum_%d.xlsx"\
-               % (rationum, scalAlgoNum)
+def GetScalingResultExcelFile(method, rationum, scalAlgoNum):
+    filename = "ScalingResults_RatioNum_%d_%s_AlgoNum_%d.xlsx"\
+               % (rationum, method, scalAlgoNum)
     file = os.path.join(Path_ScalingResults, filename)
     return file
 
-def GetScalingResultExcelFile_PerContent(content):
+def GetScalingResultExcelFile_PerContent(content, method):
     filename = GetShortContentName(content, False)
-    filename = "ScalingResults_%s.xlsx" % filename
+    filename = "ScalingResults_%s_%s.xlsx" % (method, filename)
     file = os.path.join(Path_ScalingResults, filename)
     return file
 
 def Run_Scaling_Test(clip, dnScalAlgo, upScalAlgo, path_dnscl, path_upscl,
-                     path_log, path_cfg, savememory, keepupscaledyuv,
+                     path_log, path_cfg, savememory, keepupscaledyuv, ScaleMethod,
                      LogCmdOnly=False):
     logger.info("start running scaling tests with content %s"
                 % os.path.basename(clip.file_name))
@@ -60,15 +60,15 @@
         logger.info("start downscaling content to %dx%d" % (DnScaledW, DnScaledH))
         # downscaling
         dnscalyuv = GetDownScaledOutFile(clip, DnScaledW, DnScaledH,
-                                         path_dnscl, dnScalAlgo)
+                                         path_dnscl, ScaleMethod, dnScalAlgo)
         if not os.path.isfile(dnscalyuv):
-            dnscalyuv = DownScaling(clip, FrameNum['AS'], DnScaledW, DnScaledH,
+            dnscalyuv = DownScaling(ScaleMethod, clip, FrameNum['AS'], DnScaledW, DnScaledH,
                                     path_dnscl, path_cfg, dnScalAlgo, LogCmdOnly)
         dnscaled_clip = Clip(GetShortContentName(dnscalyuv, False)+'.y4m',
                              dnscalyuv, "", DnScaledW, DnScaledH,
                              clip.fmt, clip.fps_num, clip.fps_denom,
                              clip.bit_depth)
-        upscaleyuv = UpScaling(dnscaled_clip, FrameNum['AS'], clip.width, clip.height,
+        upscaleyuv = UpScaling(ScaleMethod, dnscaled_clip, FrameNum['AS'], clip.width, clip.height,
                                path_upscl, path_cfg, upScalAlgo, LogCmdOnly)
         CalculateQualityMetric(clip.file_path, FrameNum['AS'], upscaleyuv, clip.fmt,
                                clip.width, clip.height, clip.bit_depth,
@@ -78,9 +78,9 @@
 
     logger.info("finish running scaling test.")
 
-def GeneratePerClipExcelFile(dnScalAlgos, upScalAlgos, clip, path_log):
+def GeneratePerClipExcelFile(ScaleMethod, dnScalAlgos, upScalAlgos, clip, path_log):
     logger.info("start generate excel file for content :%s" % clip.file_name)
-    excFile = GetScalingResultExcelFile_PerContent(clip.file_name)
+    excFile = GetScalingResultExcelFile_PerContent(clip.file_name, ScaleMethod)
     wb = xlsxwriter.Workbook(excFile)
     shtname = GetShortContentName(clip.file_name)
     sht = wb.add_worksheet(shtname)
@@ -122,12 +122,12 @@
             h = continfos[idx][1]
             dw = continfos[idx][2]
             dh = continfos[idx][3]
-            dnScalOut = GetDownScaledOutFile(clip, dw, dh, path_log, dn_algo)
+            dnScalOut = GetDownScaledOutFile(clip, dw, dh, path_log, ScaleMethod, dn_algo)
             ds_clip = Clip(GetShortContentName(dnScalOut, False) + '.y4m',
                  dnScalOut, "", dw, dh, clip.fmt, clip.fps_num, clip.fps_denom,
                  clip.bit_depth)
             upScalOut = GetUpScaledOutFile(ds_clip, clip.width, clip.height,
-                                           up_algo, path_log)
+                                           ScaleMethod, up_algo, path_log)
             qtys, perframe_vmaf_log = GatherQualityMetrics(upScalOut, path_log)
             sht.write_row(row, col, qtys)
             qualities.append(qtys)
@@ -154,7 +154,7 @@
     wb.close()
     logger.info("finish export scaling quality results to excel file.")
 
-def GenerateSummarySheet(wb, dnScalAlgos, upScalAlgos, ratio, path_log):
+def GenerateSummarySheet(wb, ScaleMethod, dnScalAlgos, upScalAlgos, ratio, path_log):
     logger.info("start generate summary sheet for ratio %2.2f" % ratio)
 
     shts = []
@@ -188,7 +188,7 @@
     charts = []; y_mins = {}; y_maxs = {}
     for qty, x in zip(QualityList, range(len(QualityList))):
         chart_title = '%s of %s' % (qty, shtname)
-        chart = CreateChart_Scatter(wb, chart_title, 'Contents', qty)
+        chart = CreateChart_Bar(wb, chart_title, 'Contents', qty)
         charts.append(chart)
         y_mins[x] = []; y_maxs[x] = []
 
@@ -206,18 +206,17 @@
                 h = content_infos[key][1]
                 dw = content_infos[key][2]
                 dh = content_infos[key][3]
-                dnScalOut = GetDownScaledOutFile(clip, dw, dh, path_log, dn_algo)
+                dnScalOut = GetDownScaledOutFile(clip, dw, dh, path_log, ScaleMethod, dn_algo)
                 ds_clip = Clip(GetShortContentName(dnScalOut, False) + '.y4m',
                                dnScalOut, clss, dw, dh, clip.fmt, clip.fps_num,
                                clip.fps_denom, clip.bit_depth)
-                upScalOut = GetUpScaledOutFile(ds_clip, w, h, up_algo, path_log)
+                upScalOut = GetUpScaledOutFile(ds_clip, w, h, ScaleMethod, up_algo, path_log)
                 qtys, perframe_vmaf_log = GatherQualityMetrics(upScalOut, path_log)
                 sht.write_row(row_clss + row_cont, col, qtys)
                 qualities.append(qtys)
 
         for x in range(len(QualityList)):
-            AddSeriesToChart_Scatter(shtname, rows_all, col + x, 1, charts[x],
-                                     seriname, LineColors[i])
+            AddSeriesToChart_Bar(shtname, rows_all, col + x, 1, charts[x], seriname)
 
         # get min and max of y-axis for a certain dn up scaling algo
         for qty, x in zip(QualityList, range(len(QualityList))):
@@ -328,28 +327,27 @@
 
     logger.info("finish average sheet for ratio:%2.2f." % ratio)
 
-def SaveScalingResultsToExcel(dnScalAlgos, upScalAlgos, clip_list, path_log):
+def SaveScalingResultsToExcel(ScaleMethod, dnScalAlgos, upScalAlgos, clip_list, path_log):
     logger.info("start saving scaling quality results to excel files.......")
     if not os.path.exists(Path_ScalingResults):
         os.makedirs(Path_ScalingResults)
 
     logger.info("start generating per content scaling quality excel file.......")
     for clip in clip_list:
-        GeneratePerClipExcelFile(dnScalAlgos, upScalAlgos, clip, path_log)
+        GeneratePerClipExcelFile(ScaleMethod, dnScalAlgos, upScalAlgos, clip, path_log)
 
     scaleRatios = DnScaleRatio
     if (1.0 in scaleRatios):
         scaleRatios.remove(1.0)
     logger.info("start generating scaling quality summary excel file.......")
-    sumexcFile = GetScalingResultExcelFile(len(scaleRatios), len(dnScalAlgos))
+    sumexcFile = GetScalingResultExcelFile(ScaleMethod, len(scaleRatios), len(dnScalAlgos))
     wb = xlsxwriter.Workbook(sumexcFile)
     # to generate rows number of starting of each class: Rows_Class
     global ClipDict, Rows_Class
-    ClipDict, Rows_Class = CalcRowsClassAndContentDict(ScalQty_startRow,
-                                                       clip_list)
+    ClipDict, Rows_Class = CalcRowsClassAndContentDict(ScalQty_startRow,  clip_list)
     sumShts = []
     for ratio in scaleRatios:
-        sht = GenerateSummarySheet(wb, dnScalAlgos, upScalAlgos, ratio, path_log)
+        sht = GenerateSummarySheet(wb, ScaleMethod, dnScalAlgos, upScalAlgos, ratio, path_log)
         sumShts.append(sht)
     for ratio, sumsht in zip(scaleRatios, sumShts):
         GenerateAverageSheet(wb, sumsht, dnScalAlgos, upScalAlgos, ratio)
diff --git a/tools/convexhull_framework/src/Utils.py b/tools/convexhull_framework/src/Utils.py
index 7929922..1c2a8a0 100755
--- a/tools/convexhull_framework/src/Utils.py
+++ b/tools/convexhull_framework/src/Utils.py
@@ -144,6 +144,35 @@
     return contentsdict, rows_class
 
 
+def CreateChart_Bar(wb, title, xaxis_name, yaxis_name):
+    chart = wb.add_chart({'type': 'column'})
+    chart.set_title({'name': title, 'name_font': {'color': 'white'}})
+    chart.set_x_axis({'name': xaxis_name,
+                      'major_gridlines': {'visible': True, 'line': {'width': 0.25}},
+                      'name_font': {'color': 'white'},
+                      'num_font': {'color': 'white', 'transparency': 80},
+                      'label_position' : 'low'
+                      })
+    chart.set_y_axis({'name': yaxis_name, 'name_font': {'color': 'white'},
+                      'num_font': {'color': 'white'}})
+    chart.set_style(11)
+    chart.set_size({'x_scale': 1.5, 'y_scale': 2.0})
+    chart.set_chartarea({"fill": {'color': '#505050'}})
+    chart.set_plotarea({"fill": {'color': '#505050'}})
+    chart.set_legend({'position': 'bottom', 'font': {'color': 'white'}})
+    return chart
+
+def AddSeriesToChart_Bar(shtname, rows, coly, colx, chart, seriname):
+    yvalues = [shtname, rows[0], coly, rows[-1], coly]
+    xvalues = [shtname, rows[0], colx, rows[-1], colx]
+
+    chart.add_series({
+        'name': seriname,
+        'categories': xvalues,
+        'values': yvalues
+    })
+
+
 def CreateChart_Scatter(wb, title, xaxis_name, yaxis_name):
     chart = wb.add_chart({'type': 'scatter', 'subtype': 'straight_with_markers'})
     chart.set_title({'name': title, 'name_font': {'color': 'white'}})
diff --git a/tools/convexhull_framework/src/VideoScaler.py b/tools/convexhull_framework/src/VideoScaler.py
index 61e628a..4cf5b32 100644
--- a/tools/convexhull_framework/src/VideoScaler.py
+++ b/tools/convexhull_framework/src/VideoScaler.py
@@ -14,9 +14,10 @@
 import Utils
 import logging
 import fileinput
+import math
 from shutil import copyfile
 from Config import LoggerName, FFMPEG, HDRToolsConfigFileTemplate, HDRConvert, Platform, \
-    ContentPath
+    ContentPath, AOMScaler
 from Utils import GetShortContentName, ExecuteCmd, md5
 from AV2CTCVideo import AS_Downscaled_Clips
 
@@ -24,6 +25,39 @@
 loggername = LoggerName + '.' + '%s' % subloggername
 logger = logging.getLogger(loggername)
 
+#use AOMScaler to do image rescaling
+def RescaleWithAom(clip, outw, outh, algo, outfile, num, LogCmdOnly):
+    out_s = outw / math.gcd(outw, clip.width)
+    in_s  = clip.width / math.gcd(outw, clip.width)
+    assert(out_s == int(out_s) and in_s == int(in_s))
+
+    scaling_str = "%d:%d:5" %(int(out_s), int(in_s))
+
+    args = ' -ieb:6 %s %d %s:c,d, %s %s' % (clip.file_path, num, scaling_str, scaling_str, outfile)
+    if (outw > clip.width and outh > clip.height):
+        args += ' %dx%d' % (outw, outh)
+
+    cmd = AOMScaler + args
+    ExecuteCmd(cmd, LogCmdOnly)
+
+#use ffmpeg to do image rescaling
+def RescaleWithFfmpeg(clip, outw, outh, algo, outfile, num, LogCmdOnly):
+    if clip.fmt == '420' and clip.bit_depth == 8:
+        pix_fmt = "yuv420p"
+    elif clip.fmt == '420' and clip.bit_depth == 10:
+        pix_fmt = "yuv420p10le"
+    else:
+        print("Unsupported color format")
+
+    args = " -y -i %s -vf scale=%d:%d -pix_fmt %s -strict -1" \
+           " -sws_flags %s+accurate_rnd+full_chroma_int -sws_dither none" \
+           % (clip.file_path, outw, outh, pix_fmt, algo)
+    if (algo == 'lanczos'):
+        args += " -param0 5 "
+    args += " -frames %d %s" % (num, outfile)
+    cmd = FFMPEG + args
+    ExecuteCmd(cmd, LogCmdOnly)
+
 def GenerateCfgFile(clip, outw, outh, algo, outfile, num, configpath):
     contentBaseName = GetShortContentName(clip.file_name, False)
     cfg_filename = contentBaseName + ('_Scaled_%s_%dx%d.cfg'% (algo, outw, outh))
@@ -92,19 +126,25 @@
     cmd = HDRConvert + args
     ExecuteCmd(cmd, LogCmdOnly)
 
-def VideoRescaling(clip, num, outw, outh, outfile, algo, cfg_path,
+def VideoRescaling(method, clip, num, outw, outh, outfile, algo, cfg_path,
                    LogCmdOnly = False):
-    RescaleWithHDRTool(clip, outw, outh, algo, outfile, num, cfg_path, LogCmdOnly)
+    if method == "hdrtool":
+        RescaleWithHDRTool(clip, outw, outh, algo, outfile, num, cfg_path, LogCmdOnly)
+    elif method == "aom":
+        RescaleWithAom(clip, outw, outh, algo, outfile, num, LogCmdOnly)
+    else:
+        RescaleWithFfmpeg(clip, outw, outh, algo, outfile, num, LogCmdOnly)
+
     # add other tools for scaling here later
 
 ####################################################################################
 ##################### Major Functions ################################################
-def GetDownScaledOutFile(clip, dnw, dnh, path, algo, ds_on_the_fly=True, ratio_idx=0):
+def GetDownScaledOutFile(clip, dnw, dnh, path, method, algo, ds_on_the_fly=True, ratio_idx=0):
     contentBaseName = GetShortContentName(clip.file_name, False)
     dnscaledout = clip.file_path
     if clip.width != dnw or clip.height != dnh:
         if ds_on_the_fly:
-            filename = contentBaseName + ('_Scaled_%s_%dx%d.y4m' % (algo, dnw, dnh))
+            filename = contentBaseName + ('_Scaled_%s_%s_%dx%d.y4m' % (method, algo, dnw, dnh))
             dnscaledout = os.path.join(path, filename)
         else:
             dnscaledout = ContentPath + "/A1_downscaled/" + \
@@ -112,53 +152,53 @@
 
     return dnscaledout
 
-def GetUpScaledOutFile(clip, outw, outh, algo, path):
+def GetUpScaledOutFile(clip, outw, outh, method, algo, path):
     contentBaseName = GetShortContentName(clip.file_name, False)
     upscaledout = clip.file_path
     if clip.width != outw or clip.height != outh:
-        filename = contentBaseName  + ('_Scaled_%s_%dx%d.y4m' % (algo, outw, outh))
+        filename = contentBaseName  + ('_Scaled_%s_%s_%dx%d.y4m' % (method, algo, outw, outh))
         upscaledout = os.path.join(path, filename)
     return upscaledout
 
-def GetDownScaledMD5File(clip, dnw, dnh, path, algo):
+def GetDownScaledMD5File(clip, dnw, dnh, path, method, algo):
     contentBaseName = GetShortContentName(clip.file_name, False)
     filename = contentBaseName + ".md5"
     if clip.width != dnw or clip.height != dnh:
-        filename = contentBaseName + ('_Scaled_%s_%dx%d.md5' % (algo, dnw, dnh))
+        filename = contentBaseName + ('_Scaled_%s_%s_%dx%d.md5' % (method, algo, dnw, dnh))
     dnscaledmd5 = os.path.join(path, filename)
     return dnscaledmd5
 
-def CalculateDownScaledMD5(clip, dnw, dnh, path, algo, LogCmdOnly):
-    dnScaleMD5 = GetDownScaledMD5File(clip, dnw, dnh, path, algo)
+def CalculateDownScaledMD5(clip, dnw, dnh, path, method, algo, LogCmdOnly):
+    dnScaleMD5 = GetDownScaledMD5File(clip, dnw, dnh, path, method, algo)
     if LogCmdOnly == 1:
         if Platform == "Linux":
             cmd = "md5sum %s &> %s" % (clip.file_path, dnScaleMD5)
         ExecuteCmd(cmd, 1)
     else:
         f = open(dnScaleMD5, 'wt')
-        dnScaledOut = GetDownScaledOutFile(clip, dnw, dnh, path, algo)
+        dnScaledOut = GetDownScaledOutFile(clip, dnw, dnh, path, method, algo)
         MD5 = md5(dnScaledOut)
         f.write(MD5)
         f.close()
 
-def DownScaling(clip, num, outw, outh, path, cfg_path, algo, LogCmdOnly = False):
-    dnScaledOut = GetDownScaledOutFile(clip, outw, outh, path, algo)
+def DownScaling(method, clip, num, outw, outh, path, cfg_path, algo, LogCmdOnly = False):
+    dnScaledOut = GetDownScaledOutFile(clip, outw, outh, path, method, algo)
 
     Utils.CmdLogger.write("::Downscaling\n")
     if (clip.width != outw or clip.height != outh):
         # call separate process to do the downscaling
-        VideoRescaling(clip, num, outw, outh, dnScaledOut, algo, cfg_path,
+        VideoRescaling(method, clip, num, outw, outh, dnScaledOut, algo, cfg_path,
                        LogCmdOnly)
 
-    CalculateDownScaledMD5(clip, outw, outh, path, algo, LogCmdOnly)
+    CalculateDownScaledMD5(clip, outw, outh, path, method, algo, LogCmdOnly)
 
     return dnScaledOut
 
-def UpScaling(clip, num, outw, outh, path, cfg_path, algo, LogCmdOnly = False):
-    upScaleOut = GetUpScaledOutFile(clip, outw, outh, algo, path)
+def UpScaling(method, clip, num, outw, outh, path, cfg_path, algo, LogCmdOnly = False):
+    upScaleOut = GetUpScaledOutFile(clip, outw, outh, method, algo, path)
     Utils.CmdLogger.write("::Upscaling\n")
     if (clip.width != outw or clip.height != outh):
         # call separate process to do the upscaling
-        VideoRescaling(clip, num, outw, outh, upScaleOut, algo, cfg_path,
+        VideoRescaling(method, clip, num, outw, outh, upScaleOut, algo, cfg_path,
                        LogCmdOnly)
     return upScaleOut