blob: 0aa13017b841bca536bb448a68a15b3a43e77274 [file] [log] [blame]
#!/usr/bin/env python
## Copyright (c) 2019, Alliance for Open Media. All rights reserved
##
## This source code is subject to the terms of the BSD 2 Clause License and
## the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
## was not distributed with this source code in the LICENSE file, you can
## obtain it at www.aomedia.org/license/software. If the Alliance for Open
## Media Patent License 1.0 was not distributed with this source code in the
## PATENTS file, you can obtain it at www.aomedia.org/license/patent.
##
__author__ = "maggie.sun@intel.com, ryan.lei@intel.com"
import os
import re
import logging
from Config import BinPath, LoggerName, LogCmdOnly, FFMPEG
from Utils import GetShortContentName, ExecuteCmd
subloggername = "CalcQtyMetrics_FFMPEGTool"
loggername = LoggerName + '.' + '%s' % subloggername
logger = logging.getLogger(loggername)
FFMPEGMetricsFullList = ['PSNR_Y', 'PSNR_U', 'PSNR_V']
def ParseFfmpegLogFile(psnr_log):
floats = len(FFMPEGMetricsFullList) * [0.0]
flog = open(psnr_log, 'r')
cnt = 0
for line in flog:
cnt += 1
item = re.findall(r"psnr_y:(\d+\.?\d*)", line)
floats[0] += 0 if len(item) == 0 else float(item[0])
item = re.findall(r"psnr_u:(\d+\.?\d*)", line)
floats[1] += 0 if len(item) == 0 else float(item[0])
item = re.findall(r"psnr_v:(\d+\.?\d*)", line)
floats[2] += 0 if len(item) == 0 else float(item[0])
floats = [float(i) / cnt for i in floats]
print_str = "FFMPEG quality metrics: "
for metrics, idx in zip(FFMPEGMetricsFullList, range(len(FFMPEGMetricsFullList))):
print_str += "%s = %2.5f, " % (metrics, floats[idx])
logger.info(print_str)
return floats[0:len(FFMPEGMetricsFullList)]
def GetFfmpegLogFile(recfile, path):
filename = GetShortContentName(recfile, False) + '_psnr.log'
file = os.path.join(path, filename)
return file
################################################################################
##################### Exposed Functions ########################################
def FFMPEG_CalQualityMetrics(origfile, recfile, num, w, h, logfilePath):
#calculate psnr using ffmpeg filter to get psnr_u and psnr_v
#here we have to pass the psnr_log file name to FFMPEG without the target
#log path first, then copy the result psnr log to the target log path after
#the ffmpeg call. it doesn't work if the full path is directly passed to FFMPEG
psnr_log = GetFfmpegLogFile(recfile, BinPath)
psnr_log = os.path.basename(psnr_log)
args = " -s %dx%d -pix_fmt yuv420p -i %s -s %dx%d -pix_fmt yuv420p -i %s" \
" -frames:v %d -lavfi psnr=%s -f null -" % \
(w, h, origfile, w, h, recfile, num, psnr_log)
cmd = FFMPEG + args
ExecuteCmd(cmd, LogCmdOnly)
#move the psnr log to the target log path
target = os.path.join(logfilePath, psnr_log)
cmd = "move %s %s" % (psnr_log, target)
ExecuteCmd(cmd, LogCmdOnly)
def FFMPEG_GatherQualityMetrics(recfile, logfilePath):
psnr_log = GetFfmpegLogFile(recfile, logfilePath)
results = ParseFfmpegLogFile(psnr_log)
return results