1 #!/usr/bin/env python 2 # Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. 3 # 4 # Use of this source code is governed by a BSD-style license 5 # that can be found in the LICENSE file in the root of the source 6 # tree. An additional intellectual property rights grant can be found 7 # in the file PATENTS. All contributing project authors may 8 # be found in the AUTHORS file in the root of the source tree. 9 10 import optparse 11 import os 12 import shutil 13 import subprocess 14 import sys 15 import tempfile 16 17 18 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) 19 20 # Chrome browsertests will throw away stderr; avoid that output gets lost. 21 sys.stderr = sys.stdout 22 23 24 def _ParseArgs(): 25 """Registers the command-line options.""" 26 usage = 'usage: %prog [options]' 27 parser = optparse.OptionParser(usage=usage) 28 29 parser.add_option('--label', type='string', default='MY_TEST', 30 help=('Label of the test, used to identify different ' 31 'tests. Default: %default')) 32 parser.add_option('--ref_video', type='string', 33 help='Reference video to compare with (YUV).') 34 parser.add_option('--test_video', type='string', 35 help=('Test video to be compared with the reference ' 36 'video (YUV).')) 37 parser.add_option('--frame_analyzer', type='string', 38 help='Path to the frame analyzer executable.') 39 parser.add_option('--barcode_decoder', type='string', 40 help=('Path to the barcode decoder script. By default, we ' 41 'will assume we can find it in barcode_tools/' 42 'relative to this directory.')) 43 parser.add_option('--ffmpeg_path', type='string', 44 help=('The path to where the ffmpeg executable is located. ' 45 'If omitted, it will be assumed to be present in the ' 46 'PATH with the name ffmpeg[.exe].')) 47 parser.add_option('--zxing_path', type='string', 48 help=('The path to where the zxing executable is located. ' 49 'If omitted, it will be assumed to be present in the ' 50 'PATH with the name zxing[.exe].')) 51 parser.add_option('--stats_file', type='string', default='stats.txt', 52 help=('Path to the temporary stats file to be created and ' 53 'used. Default: %default')) 54 parser.add_option('--yuv_frame_width', type='int', default=640, 55 help='Width of the YUV file\'s frames. Default: %default') 56 parser.add_option('--yuv_frame_height', type='int', default=480, 57 help='Height of the YUV file\'s frames. Default: %default') 58 options, _ = parser.parse_args() 59 60 if not options.ref_video: 61 parser.error('You must provide a path to the reference video!') 62 if not os.path.exists(options.ref_video): 63 parser.error('Cannot find the reference video at %s' % options.ref_video) 64 65 if not options.test_video: 66 parser.error('You must provide a path to the test video!') 67 if not os.path.exists(options.test_video): 68 parser.error('Cannot find the test video at %s' % options.test_video) 69 70 if not options.frame_analyzer: 71 parser.error('You must provide the path to the frame analyzer executable!') 72 if not os.path.exists(options.frame_analyzer): 73 parser.error('Cannot find frame analyzer executable at %s!' % 74 options.frame_analyzer) 75 return options 76 77 78 def main(): 79 """The main function. 80 81 A simple invocation is: 82 ./webrtc/tools/barcode_tools/compare_videos.py 83 --ref_video=<path_and_name_of_reference_video> 84 --test_video=<path_and_name_of_test_video> 85 --frame_analyzer=<path_and_name_of_the_frame_analyzer_executable> 86 87 Notice that the prerequisites for barcode_decoder.py also applies to this 88 script. The means the following executables have to be available in the PATH: 89 * zxing 90 * ffmpeg 91 """ 92 options = _ParseArgs() 93 94 if options.barcode_decoder: 95 path_to_decoder = options.barcode_decoder 96 else: 97 path_to_decoder = os.path.join(SCRIPT_DIR, 'barcode_tools', 98 'barcode_decoder.py') 99 100 # On Windows, sometimes the inherited stdin handle from the parent process 101 # fails. Work around this by passing null to stdin to the subprocesses. 102 null_filehandle = open(os.devnull, 'r') 103 104 # Run barcode decoder on the test video to identify frame numbers. 105 png_working_directory = tempfile.mkdtemp() 106 cmd = [ 107 sys.executable, 108 path_to_decoder, 109 '--yuv_file=%s' % options.test_video, 110 '--yuv_frame_width=%d' % options.yuv_frame_width, 111 '--yuv_frame_height=%d' % options.yuv_frame_height, 112 '--stats_file=%s' % options.stats_file, 113 '--png_working_dir=%s' % png_working_directory, 114 ] 115 if options.zxing_path: 116 cmd.append('--zxing_path=%s' % options.zxing_path) 117 if options.ffmpeg_path: 118 cmd.append('--ffmpeg_path=%s' % options.ffmpeg_path) 119 barcode_decoder = subprocess.Popen(cmd, stdin=null_filehandle, 120 stdout=sys.stdout, stderr=sys.stderr) 121 barcode_decoder.wait() 122 123 shutil.rmtree(png_working_directory) 124 if barcode_decoder.returncode != 0: 125 print 'Failed to run barcode decoder script.' 126 return 1 127 128 # Run frame analyzer to compare the videos and print output. 129 cmd = [ 130 options.frame_analyzer, 131 '--label=%s' % options.label, 132 '--reference_file=%s' % options.ref_video, 133 '--test_file=%s' % options.test_video, 134 '--stats_file=%s' % options.stats_file, 135 '--width=%d' % options.yuv_frame_width, 136 '--height=%d' % options.yuv_frame_height, 137 ] 138 frame_analyzer = subprocess.Popen(cmd, stdin=null_filehandle, 139 stdout=sys.stdout, stderr=sys.stderr) 140 frame_analyzer.wait() 141 if frame_analyzer.returncode != 0: 142 print 'Failed to run frame analyzer.' 143 return 1 144 145 return 0 146 147 if __name__ == '__main__': 148 sys.exit(main()) 149