Made video quality toolchain more configurable.

R=kjellander@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/4139007

git-svn-id: http://webrtc.googlecode.com/svn/trunk@5171 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
phoglund@webrtc.org 2013-11-25 14:10:20 +00:00
parent 47fadba750
commit 3260f109e3
2 changed files with 58 additions and 32 deletions

View File

@ -11,15 +11,18 @@ import optparse
import os import os
import sys import sys
import helper_functions if __name__ == '__main__':
# Make sure we always can import helper_functions.
sys.path.append(os.path.dirname(__file__))
import helper_functions
# Chrome browsertests will throw away stderr; avoid that output gets lost. # Chrome browsertests will throw away stderr; avoid that output gets lost.
sys.stderr = sys.stdout sys.stderr = sys.stdout
def convert_yuv_to_png_files(yuv_file_name, yuv_frame_width, yuv_frame_height, def convert_yuv_to_png_files(yuv_file_name, yuv_frame_width, yuv_frame_height,
output_directory, ffmpeg_dir=None): output_directory, ffmpeg_path):
"""Converts a YUV video file into PNG frames. """Converts a YUV video file into PNG frames.
The function uses ffmpeg to convert the YUV file. The output of ffmpeg is in The function uses ffmpeg to convert the YUV file. The output of ffmpeg is in
@ -31,18 +34,17 @@ def convert_yuv_to_png_files(yuv_file_name, yuv_frame_width, yuv_frame_height,
yuv_frame_height(int): The height of one YUV frame. yuv_frame_height(int): The height of one YUV frame.
output_directory(string): The output directory where the PNG frames will be output_directory(string): The output directory where the PNG frames will be
stored. stored.
ffmpeg_dir(string): The directory containing the ffmpeg executable. If ffmpeg_path(string): The path to the ffmpeg executable. If None, the PATH
omitted, the PATH will be searched for it. will be searched for it.
Return: Return:
(bool): True if the conversion was OK. (bool): True if the conversion was OK.
""" """
size_string = str(yuv_frame_width) + 'x' + str(yuv_frame_height) size_string = str(yuv_frame_width) + 'x' + str(yuv_frame_height)
output_files_pattern = os.path.join(output_directory, 'frame_%04d.png') output_files_pattern = os.path.join(output_directory, 'frame_%04d.png')
ffmpeg_executable = 'ffmpeg.exe' if sys.platform == 'win32' else 'ffmpeg' if not ffmpeg_path:
if ffmpeg_dir: ffmpeg_path = 'ffmpeg.exe' if sys.platform == 'win32' else 'ffmpeg'
ffmpeg_executable = os.path.join(ffmpeg_dir, ffmpeg_executable) command = [ffmpeg_path, '-s', '%s' % size_string, '-i', '%s'
command = [ffmpeg_executable, '-s', '%s' % size_string, '-i', '%s'
% yuv_file_name, '-f', 'image2', '-vcodec', 'png', % yuv_file_name, '-f', 'image2', '-vcodec', 'png',
'%s' % output_files_pattern] '%s' % output_files_pattern]
try: try:
@ -54,12 +56,12 @@ def convert_yuv_to_png_files(yuv_file_name, yuv_frame_width, yuv_frame_height,
print 'Error executing command: %s. Error: %s' % (command, err) print 'Error executing command: %s. Error: %s' % (command, err)
return False return False
except OSError: except OSError:
print ('Did not find %s. Have you installed it?' % ffmpeg_executable) print ('Did not find %s. Have you installed it?' % ffmpeg_path)
return False return False
return True return True
def decode_frames(input_directory, zxing_dir=None): def decode_frames(input_directory, zxing_path):
"""Decodes the barcodes overlaid in each frame. """Decodes the barcodes overlaid in each frame.
The function uses the Zxing command-line tool from the Zxing C++ distribution The function uses the Zxing command-line tool from the Zxing C++ distribution
@ -73,19 +75,18 @@ def decode_frames(input_directory, zxing_dir=None):
Args: Args:
input_directory(string): The input directory from where the PNG frames are input_directory(string): The input directory from where the PNG frames are
read. read.
zxing_dir(string): The directory containing the zxing executable. If zxing_path(string): The path to the zxing binary. If specified as None,
omitted, the PATH will be searched for it. the PATH will be searched for it.
Return: Return:
(bool): True if the decoding went without errors. (bool): True if the decoding succeeded.
""" """
zxing_executable = 'zxing.exe' if sys.platform == 'win32' else 'zxing' if not zxing_path:
if zxing_dir: zxing_path = 'zxing.exe' if sys.platform == 'win32' else 'zxing'
zxing_executable = os.path.join(zxing_dir, zxing_executable) print 'Decoding barcodes from PNG files with %s...' % zxing_path
print 'Decoding barcodes from PNG files with %s...' % zxing_executable
return helper_functions.perform_action_on_all_files( return helper_functions.perform_action_on_all_files(
directory=input_directory, file_pattern='frame_', directory=input_directory, file_pattern='frame_',
file_extension='png', start_number=1, action=_decode_barcode_in_file, file_extension='png', start_number=1, action=_decode_barcode_in_file,
command_line_decoder=zxing_executable) command_line_decoder=zxing_path)
def _decode_barcode_in_file(file_name, command_line_decoder): def _decode_barcode_in_file(file_name, command_line_decoder):
@ -230,14 +231,14 @@ def _parse_args():
usage = "usage: %prog [options]" usage = "usage: %prog [options]"
parser = optparse.OptionParser(usage=usage) parser = optparse.OptionParser(usage=usage)
parser.add_option('--zxing_dir', type='string', parser.add_option('--zxing_path', type='string',
help=('The path to the directory where the zxing executable' help=('The path to where the zxing executable is located. '
'is located. If omitted, it will be assumed to be ' 'If omitted, it will be assumed to be present in the '
'present in the PATH.')) 'PATH with the name zxing[.exe].'))
parser.add_option('--ffmpeg_dir', type='string', default=None, parser.add_option('--ffmpeg_path', type='string',
help=('The path to the directory where the ffmpeg ' help=('The path to where the ffmpeg executable is located. '
'executable is located. If omitted, it will be ' 'If omitted, it will be assumed to be present in the '
'assumed to be present in the PATH.')) 'PATH with the name ffmpeg[.exe].'))
parser.add_option('--yuv_frame_width', type='int', default=640, parser.add_option('--yuv_frame_width', type='int', default=640,
help='Width of the YUV file\'s frames. Default: %default') help='Width of the YUV file\'s frames. Default: %default')
parser.add_option('--yuv_frame_height', type='int', default=480, parser.add_option('--yuv_frame_height', type='int', default=480,
@ -271,13 +272,13 @@ def _main():
if not convert_yuv_to_png_files(options.yuv_file, options.yuv_frame_width, if not convert_yuv_to_png_files(options.yuv_file, options.yuv_frame_width,
options.yuv_frame_height, options.yuv_frame_height,
output_directory=options.png_working_dir, output_directory=options.png_working_dir,
ffmpeg_dir=options.ffmpeg_dir): ffmpeg_path=options.ffmpeg_path):
print 'An error occurred converting from YUV to PNG frames.' print 'An error occurred converting from YUV to PNG frames.'
return -1 return -1
# Decode the barcodes from the PNG frames. # Decode the barcodes from the PNG frames.
if not decode_frames(input_directory=options.png_working_dir, if not decode_frames(input_directory=options.png_working_dir,
zxing_dir=options.zxing_dir): zxing_path=options.zxing_path):
print 'An error occurred decoding barcodes from PNG frames.' print 'An error occurred decoding barcodes from PNG frames.'
return -2 return -2

View File

@ -9,8 +9,10 @@
import optparse import optparse
import os import os
import shutil
import subprocess import subprocess
import sys import sys
import tempfile
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
@ -24,7 +26,7 @@ def _ParseArgs():
usage = 'usage: %prog [options]' usage = 'usage: %prog [options]'
parser = optparse.OptionParser(usage=usage) parser = optparse.OptionParser(usage=usage)
parser.add_option('--label', type='string', default="MY_TEST", parser.add_option('--label', type='string', default='MY_TEST',
help=('Label of the test, used to identify different ' help=('Label of the test, used to identify different '
'tests. Default: %default')) 'tests. Default: %default'))
parser.add_option('--ref_video', type='string', parser.add_option('--ref_video', type='string',
@ -34,6 +36,18 @@ def _ParseArgs():
'video (YUV).')) 'video (YUV).'))
parser.add_option('--frame_analyzer', type='string', parser.add_option('--frame_analyzer', type='string',
help='Path to the frame analyzer executable.') help='Path to the frame analyzer executable.')
parser.add_option('--barcode_decoder', type='string',
help=('Path to the barcode decoder script. By default, we '
'will assume we can find it in barcode_tools/'
'relative to this directory.'))
parser.add_option('--ffmpeg_path', type='string',
help=('The path to where the ffmpeg executable is located. '
'If omitted, it will be assumed to be present in the '
'PATH with the name ffmpeg[.exe].'))
parser.add_option('--zxing_path', type='string',
help=('The path to where the zxing executable is located. '
'If omitted, it will be assumed to be present in the '
'PATH with the name zxing[.exe].'))
parser.add_option('--stats_file', type='string', default='stats.txt', parser.add_option('--stats_file', type='string', default='stats.txt',
help=('Path to the temporary stats file to be created and ' help=('Path to the temporary stats file to be created and '
'used. Default: %default')) 'used. Default: %default'))
@ -77,14 +91,18 @@ def main():
""" """
options = _ParseArgs() options = _ParseArgs()
# Run barcode decoder on the test video to identify frame numbers. if options.barcode_decoder:
path_to_decoder = os.path.join(SCRIPT_DIR, 'barcode_tools', path_to_decoder = options.barcode_decoder
'barcode_decoder.py') else:
path_to_decoder = os.path.join(SCRIPT_DIR, 'barcode_tools',
'barcode_decoder.py')
# On Windows, sometimes the inherited stdin handle from the parent process # On Windows, sometimes the inherited stdin handle from the parent process
# fails. Work around this by passing null to stdin to the subprocesses. # fails. Work around this by passing null to stdin to the subprocesses.
null_filehandle = open(os.devnull, 'r') null_filehandle = open(os.devnull, 'r')
# Run barcode decoder on the test video to identify frame numbers.
png_working_directory = tempfile.mkdtemp()
cmd = [ cmd = [
sys.executable, sys.executable,
path_to_decoder, path_to_decoder,
@ -92,10 +110,17 @@ def main():
'--yuv_frame_width=%d' % options.yuv_frame_width, '--yuv_frame_width=%d' % options.yuv_frame_width,
'--yuv_frame_height=%d' % options.yuv_frame_height, '--yuv_frame_height=%d' % options.yuv_frame_height,
'--stats_file=%s' % options.stats_file, '--stats_file=%s' % options.stats_file,
'--png_working_dir=%s' % png_working_directory,
] ]
if options.zxing_path:
cmd.append('--zxing_path=%s' % options.zxing_path)
if options.ffmpeg_path:
cmd.append('--ffmpeg_path=%s' % options.ffmpeg_path)
barcode_decoder = subprocess.Popen(cmd, stdin=null_filehandle, barcode_decoder = subprocess.Popen(cmd, stdin=null_filehandle,
stdout=sys.stdout, stderr=sys.stderr) stdout=sys.stdout, stderr=sys.stderr)
barcode_decoder.wait() barcode_decoder.wait()
shutil.rmtree(png_working_directory)
if barcode_decoder.returncode != 0: if barcode_decoder.returncode != 0:
print 'Failed to run barcode decoder script.' print 'Failed to run barcode decoder script.'
return 1 return 1