Chromium Code Reviews| Index: webrtc/tools/run_video_analysis.py |
| diff --git a/webrtc/tools/run_video_analysis.py b/webrtc/tools/run_video_analysis.py |
| new file mode 100755 |
| index 0000000000000000000000000000000000000000..a1376b896ffc69718d80d1bdeac58ea57da6d1d1 |
| --- /dev/null |
| +++ b/webrtc/tools/run_video_analysis.py |
| @@ -0,0 +1,464 @@ |
| +#!/usr/bin/env python |
| +# Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. |
| +# |
| +# Use of this source code is governed by a BSD-style license |
| +# that can be found in the LICENSE file in the root of the source |
| +# tree. An additional intellectual property rights grant can be found |
| +# in the file PATENTS. All contributing project authors may |
| +# be found in the AUTHORS file in the root of the source tree. |
| + |
| +import optparse |
| +import os |
| +import subprocess |
| +import sys |
| +import time |
| +import glob |
| +import re |
| + |
| +# Used to time-stamp output files and directories |
| +CURRENT_TIME = time.strftime("%d_%m_%Y-%H:%M:%S") |
| + |
| +def _parseArgs(): |
|
kjellander_webrtc
2017/02/22 12:30:51
Chromium has two exceptions from the standard goog
janssonWebRTC
2017/03/07 14:23:45
In my opinion the linter should catch these things
kjellander_webrtc
2017/03/08 07:31:21
You're right, I filed https://bugs.chromium.org/p/
|
| + """Registers the command-line options.""" |
| + usage = 'usage: %prog [options]' |
| + parser = optparse.OptionParser(usage=usage) |
| + |
| + parser.add_option('--frame_width', type='string', default='1280', |
| + help='Width of the recording. Default: %default') |
| + parser.add_option('--frame_height', type='string', default='720', |
| + help='Height of the recording. Default: %default') |
| + parser.add_option('--framerate', type='string', default='60', |
| + help='Recording framerate. Default: %default') |
| + parser.add_option('--ref_duration', type='string', default='20', |
| + help='Reference recording duration. Default: %default') |
| + parser.add_option('--test_duration', type='string', default='10', |
| + help='Test recording duration. Default: %default') |
| + parser.add_option('--ref_video_device', type='string', default='/dev/video0', |
| + help='Reference recording device. Default: %default') |
| + parser.add_option('--test_video_device', type='string', default='/dev/video1', |
| + help='Test recording device. Default: %default') |
| + parser.add_option('--app_name', type='string', |
| + help='Name of the app under test.') |
| + parser.add_option('--recording_api', type='string', default='Video4Linux2', |
| + help='Recording API to use. Default: %default') |
| + parser.add_option('--pixel_format', type='string', default='yuv420p', |
| + help='Recording pixel format Default: %default') |
| + parser.add_option('--ref_ffmpeg', type='string', |
|
kjellander_webrtc
2017/02/22 12:30:50
When do you need two different ffmpeg binaries? Th
janssonWebRTC
2017/03/07 14:23:45
Initially I could not run the same executable at t
kjellander_webrtc
2017/03/08 07:31:20
Acknowledged.
|
| + help='Path to the ffmpeg executable for the reference \ |
| + device.') |
| + parser.add_option('--test_ffmpeg', type='string', |
| + help='Path to the ffmpeg executable for the test device.') |
| + parser.add_option('--video_container', type='string', default='yuv', |
| + help='Video container for the recordings. \ |
| + Default: %default') |
| + parser.add_option('--compare_videos_script', type='string', |
| + default='compare_videos.py', |
| + help='Path to script used to compare and generate metrics. \ |
| + Default: %default') |
| + parser.add_option('--frame_analyzer', type='string', |
| + default='../../out/Default/frame_analyzer', |
| + help='Path to the frame analyzer executable. \ |
| + Default: %default') |
| + parser.add_option('--zxing_path', type='string', |
| + help='Path to the zebra xing barcode analyzer.') |
| + parser.add_option('--ref_crop_width', type='string', default='950', |
| + help='Cropping width. \ |
| + Default: %default') |
| + parser.add_option('--ref_crop_height', type='string', default='420', |
| + help='Cropping height. \ |
| + Default: %default') |
| + parser.add_option('--ref_crop_x_axis_start', type='string', default='130', |
| + help='y coordinate where cropping starts from. \ |
| + Default: %default') |
| + parser.add_option('--ref_crop_y_axis_start', type='string', default='56', |
| + help='x coordinate where cropping starts from. \ |
| + Default: %default') |
| + parser.add_option('--test_crop_width', type='string', default='950', |
| + help='Cropping width. \ |
| + Default: %default') |
| + parser.add_option('--test_crop_height', type='string', default='420', |
| + help='Cropping height. \ |
| + Default: %default') |
| + parser.add_option('--test_crop_x_axis_start', type='string', default='130', |
| + help='y coordinate where cropping starts from. \ |
| + Default: %default') |
| + parser.add_option('--test_crop_y_axis_start', type='string', default='56', |
| + help='x coordinate where cropping starts from. \ |
| + Default: %default') |
| + parser.add_option('--ref_rec_dir', type='string', default='ref', |
| + help='Path to where reference recordings will be created. \ |
| + Ideally keep the ref and test directories on separate \ |
| + drives. Default: %default') |
| + parser.add_option('--test_rec_dir', type='string', default='test', |
| + help='Path to where test recordings will be created. \ |
| + Ideally keep the ref and test directories on separate \ |
| + drives. Default: %default') |
| + |
| + options, _ = parser.parse_args() |
| + |
| + if not options.app_name: |
| + parser.error('You must provide an application name!') |
| + |
| + if not options.ref_ffmpeg: |
| + parser.error('You most provide location for the reference device ffmpeg \ |
| + executable.') |
| + if not os.path.exists(options.ref_ffmpeg): |
|
kjellander_webrtc
2017/02/22 12:30:50
I usually use os.path.isfile instead, since if you
janssonWebRTC
2017/03/07 14:23:45
Done.
|
| + parser.error('Cannot find the reference device ffmpeg executable.') |
| + |
| + if not options.test_ffmpeg: |
| + parser.error('You most provide location for the test device ffmpeg \ |
|
kjellander_webrtc
2017/02/22 12:30:50
Skip the \, it's not needed if you end the string
janssonWebRTC
2017/03/07 14:23:45
Done.
|
| + executable.') |
| + if not os.path.exists(options.test_ffmpeg): |
| + parser.error('Cannot find the test device ffmpeg executable.') |
| + |
| + # compare_videos.py dependencies. |
| + if not os.path.exists(options.compare_videos_script): |
| + parser.warning('Cannot find compare_videos.py script, no metrics will be \ |
| + generated!') |
|
kjellander_webrtc
2017/02/22 12:30:51
align indent with the above (
https://google.githu
janssonWebRTC
2017/03/07 14:23:45
Done.
|
| + if not os.path.exists(options.frame_analyzer): |
| + parser.warning('Cannot find frame_analyzer, no metrics will be generated!') |
| + if not os.path.exists(options.frame_analyzer): |
|
kjellander_webrtc
2017/02/22 12:30:50
options.zxing_path
janssonWebRTC
2017/03/07 14:23:45
Done.
|
| + parser.warning('Cannot find Zebra Xing, no metrics will be generated!') |
| + |
| + return options |
| + |
| + |
| +def create_recording_dirs(options): |
| + """Creates root directories for reference and test recordings and |
|
kjellander_webrtc
2017/02/22 12:30:49
Make the summary line fit on a single line
Quotin
janssonWebRTC
2017/03/07 14:23:45
Done.
|
| + sub-directories using <options.app_name + '_' + CURRENT_TIME>. |
| + |
| + Args: |
| + options(object): Contains all the provided command line options. |
| + Return: |
| + record_paths(dict): key: value pair with reference and test file |
| + absolute paths. |
|
kjellander_webrtc
2017/02/22 12:30:50
+4 spaces indent before "absolute" here.
janssonWebRTC
2017/03/07 14:23:45
Done.
|
| + """ |
| + # Create root directories for the video recordings. |
| + if not os.path.exists(options.ref_rec_dir): |
|
kjellander_webrtc
2017/02/22 12:30:50
Use os.path.isdir
janssonWebRTC
2017/03/07 14:23:44
Done.
|
| + os.makedirs(options.ref_rec_dir) |
| + if not os.path.exists(options.test_rec_dir): |
| + os.makedirs(options.test_rec_dir) |
| + # Create and time-stamp directories for all the output files. |
|
kjellander_webrtc
2017/02/22 12:30:50
+1 blank line before comment
janssonWebRTC
2017/03/07 14:23:44
Done.
|
| + ref_rec_dir = os.path.join(options.ref_rec_dir, options.app_name + '_' + \ |
| + CURRENT_TIME) |
| + test_rec_dir = os.path.join(options.test_rec_dir, options.app_name + '_' + \ |
| + CURRENT_TIME) |
| + |
| + os.makedirs(ref_rec_dir) |
| + os.makedirs(test_rec_dir) |
| + |
| + record_paths = { |
| + 'ref_rec_location' : os.path.abspath(ref_rec_dir), |
| + 'test_rec_location' : os.path.abspath(test_rec_dir) |
| + } |
| + |
| + return record_paths |
| + |
| + |
| +def restart_magewell_devices(options): |
| + """Tries to find the provided options.ref_video_device and |
|
kjellander_webrtc
2017/02/22 12:30:50
Same comment here about the docstring summary line
janssonWebRTC
2017/03/07 14:23:45
Done.
|
| + options.test_video_device devices which use video4linux and then do a soft |
| + reset by using USB unbind and bind. This is due to Magewell capture devices |
| + have proven to be unstable after the first recording attempt. |
| + |
| + Args: |
| + options(object): Contains all the provided command line options. |
| + """ |
| + # Get the dev/videoN device name from the command line arguments. |
| + ref_magewell = options.ref_video_device.split('/')[2] |
| + test_magewell = options.test_video_device.split('/')[2] |
| + |
| + # Find the device location including USB and USB Bus ID's. |
| + ref_magewell_device = \ |
| + glob.glob('/sys/bus/usb/devices/usb*/**/**/video4linux/' + ref_magewell) |
| + test_magewell_device = \ |
| + glob.glob('/sys/bus/usb/devices/usb*/**/**/video4linux/' + test_magewell) |
| + |
| + magewell_usb_ports = [] |
| + # Figure out the USB bus and port ID for each device. |
| + ref_magewell_path = str(ref_magewell_device).split('/') |
| + for directory in ref_magewell_path: |
| + # Find the folder with pattern "N-N", e.g. "4-3" or \ |
| + # "[USB bus ID]-[USB port]" |
| + if re.match(r'^\d-\d$', directory): |
| + magewell_usb_ports.append(directory) |
| + |
| + test_magewell_path = str(test_magewell_device).split('/') |
| + for directory in test_magewell_path: |
| + # Find the folder with pattern "N-N", e.g. "4-3" or \ |
| + # "[USB bus ID]-[USB port]" |
| + if re.match(r'^\d-\d$', directory): |
| + magewell_usb_ports.append(directory) |
| + |
| + print '\nResetting USB ports where magewell devices are connected...' |
| + # Use the USB bus and port ID (e.g. 4-3) to unbind and bind the USB devices |
| + # (i.e. soft eject and insert). |
| + try: |
| + for usb_port in magewell_usb_ports: |
| + echo_cmd = ['echo', usb_port] |
| + unbind_cmd = ['sudo', 'tee', '/sys/bus/usb/drivers/usb/unbind'] |
| + bind_cmd = ['sudo', 'tee', '/sys/bus/usb/drivers/usb/bind'] |
|
kjellander_webrtc
2017/02/22 12:30:50
Will the script ask for sudo password in a clear w
janssonWebRTC
2017/03/07 14:23:45
Yes it will but for me it's quite clear that it as
kjellander_webrtc
2017/03/08 07:31:20
Acknowledged.
|
| + |
| + # TODO(jansson) Figure out a way to call on echo once for bind & unbind |
| + # if possible. |
| + echo_unbind = subprocess.Popen(echo_cmd, stdout=subprocess.PIPE) |
| + unbind = subprocess.Popen(unbind_cmd, stdin=echo_unbind.stdout) |
| + echo_unbind.stdout.close() |
| + unbind.communicate() |
| + unbind.wait() |
| + |
| + echo_bind = subprocess.Popen(echo_cmd, stdout=subprocess.PIPE) |
| + bind = subprocess.Popen(bind_cmd, stdin=echo_bind.stdout) |
| + echo_bind.stdout.close() |
| + bind.communicate() |
| + bind.wait() |
| + except OSError as e: |
| + print 'Error while resetting magewell devices: ' + e |
| + raise |
| + |
| + print 'Reset done!\n' |
| + |
| + |
| +def start_recording(options, record_paths): |
| + """Starts recording from the two specified video devices with |
| + |
| + Args: |
| + options(object): Contains all the provided command line options. |
| + record_paths(dict): key: value pair with reference and test file |
| + absolute paths. |
| + """ |
| + ref_file_name = options.app_name + '_' + CURRENT_TIME + '_ref.' + \ |
|
kjellander_webrtc
2017/02/22 12:30:50
Use Python string formatters instead, i.e.
ref_fi
janssonWebRTC
2017/03/07 14:23:44
Done.
|
| + options.video_container |
| + ref_file_location = os.path.join(record_paths['ref_rec_location'], |
| + ref_file_name) |
| + |
| + test_file_name = options.app_name + '_' + CURRENT_TIME + '_test.' + \ |
| + options.video_container |
| + test_file_location = os.path.join(record_paths['test_rec_location'], |
| + test_file_name) |
| + |
| + # Reference video recorder command line. |
| + ref_cmd = [ |
| + options.ref_ffmpeg, |
| + '-v', 'error', |
| + '-s', options.frame_width + 'x' + options.frame_height, |
| + '-framerate', options.framerate, |
| + '-f', options.recording_api, |
| + '-i', options.ref_video_device, |
| + '-pix_fmt', options.pixel_format, |
| + '-s', options.frame_width + 'x' + options.frame_height, |
| + '-t', options.ref_duration, |
| + '-framerate', options.framerate, |
| + ref_file_location |
| + ] |
| + |
| + # Test video recorder command line. |
| + test_cmd = [ |
| + options.test_ffmpeg, |
| + '-v', 'error', |
| + '-s', options.frame_width + 'x' + options.frame_height, |
| + '-framerate', options.framerate, |
| + '-f', options.recording_api, |
| + '-i', options.test_video_device, |
| + '-pix_fmt', options.pixel_format, |
| + '-s', options.frame_width + 'x' + options.frame_height, |
| + '-t', options.test_duration, |
| + '-framerate', options.framerate, |
| + test_file_location |
| + ] |
| + try: |
| + print 'Trying to record from reference recorder...' |
| + ref_recorder = subprocess.Popen(ref_cmd, stderr=None) |
| + # Start the 2nd recording a little later to ensure the 1st one has started. |
| + # TODO(jansson) Check that the ref_recorder output file exists rather than |
| + # using sleep. |
| + time.sleep(5) |
|
kjellander_webrtc
2017/02/22 12:30:51
Maybe this should be a flag as well? Constants lik
janssonWebRTC
2017/03/07 14:23:45
Made it a flag.
kjellander_webrtc
2017/03/08 07:31:20
Acknowledged.
|
| + print 'Trying to record from test recorder...' |
| + test_recorder = subprocess.Popen(test_cmd, stderr=None) |
|
kjellander_webrtc
2017/02/22 12:30:50
Why stderr=None ? Don't you risk to ignore errors
janssonWebRTC
2017/03/07 14:23:45
This was just a default setting. Will fix.
kjellander_webrtc
2017/03/08 07:31:20
Acknowledged.
|
| + test_recorder.wait() |
| + ref_recorder.wait() |
| + |
| + print 'Ref file recorded to: ' + os.path.abspath(ref_file_location) |
| + print 'Test file recorded to: ' + os.path.abspath(test_file_location) |
| + print 'Recording done!\n' |
| + return flip_and_crop_recordings(options, test_file_name, |
| + record_paths['test_rec_location'], ref_file_name, |
| + record_paths['ref_rec_location']) |
| + except subprocess.CalledProcessError as e: |
| + print 'Something went wrong when trying to record: ' + e |
| + raise |
| + |
| + |
| +def flip_and_crop_recordings(options, test_file_name, test_file_location, |
| + ref_file_name, ref_file_location): |
|
kjellander_webrtc
2017/02/22 12:30:50
indent aligning with ( above
janssonWebRTC
2017/03/07 14:23:45
Done.
|
| + """Performs a horizontal flip of the reference video to match the test video |
| + orientation and then crops the ref and test videos using |
| + options.ref_crop_height, options.ref_crop_width, options.test_crop_height and |
| + options.test_crop_width. Crop starting position is taken from |
| + options.ref_crop_x_axis_start, options.ref_crop_y_axis_start, |
| + options.test_crop_x_axis_start and options.test_crop_x_axis_start. |
| + |
| + Args: |
| + options(object): Contains all the provided command line options. |
| + test_file_name(string): Name of the test video file recording. |
| + test_file_location(string): Path to the test video file recording. |
| + ref_file_name(string): Name of the reference video file recording. |
| + ref_file_location(string): Path to the reference video file recording. |
| + Return: |
| + recording_files_and_time(dict): key: value pair with the path to cropped |
| + test and reference video files. |
|
kjellander_webrtc
2017/02/22 12:30:50
+4 indent
janssonWebRTC
2017/03/07 14:23:45
Done.
|
| + """ |
| + print 'Trying to crop videos...' |
| + # Ref file cropping. |
|
kjellander_webrtc
2017/02/22 12:30:50
+blank line
janssonWebRTC
2017/03/07 14:23:44
Done.
|
| + cropped_ref_file_name = 'cropped_' + ref_file_name |
| + cropped_ref_file = os.path.abspath(\ |
|
kjellander_webrtc
2017/02/22 12:30:50
remove \
janssonWebRTC
2017/03/07 14:23:44
Done.
|
| + os.path.join(ref_file_location, cropped_ref_file_name)) |
| + ref_crop_parameters = options.ref_crop_width + ':' + \ |
|
kjellander_webrtc
2017/02/22 12:30:51
use string formatter
janssonWebRTC
2017/03/07 14:23:45
Done.
|
| + options.ref_crop_height + ':' + options.ref_crop_x_axis_start + ':' + \ |
| + options.ref_crop_y_axis_start |
| + |
| + ref_video_crop_cmd = [ |
| + options.ref_ffmpeg, |
| + '-v', 'error', |
| + '-s', options.frame_width + 'x' + options.frame_height, |
| + '-i', os.path.join(ref_file_location, ref_file_name), |
| + # Flip the ref video horizontally before cropping so that we can use the |
| + # same coordinates on both ref and test recordings. |
| + # Also keep in mind that the X:Y starting positions are critical for the |
| + # zxing library, if the barcode is moved within the recording, these |
| + # probably need to be changed otherwise barcode decoding will fail. |
| + # TODO(jansson) make the entire crop parameter section a command line |
| + # argument. |
| + '-vf', 'hflip, crop=' + ref_crop_parameters, |
| + '-c:a', 'copy', |
| + cropped_ref_file |
| + ] |
| + # Test file cropping. |
| + cropped_test_file_name = 'cropped_' + test_file_name |
| + cropped_test_file = os.path.abspath(\ |
| + os.path.join(test_file_location, cropped_test_file_name)) |
| + test_crop_parameters = options.test_crop_width + ':' + \ |
| + options.test_crop_height + ':' + options.test_crop_x_axis_start + ':' + \ |
| + options.test_crop_y_axis_start |
| + |
| + test_video_crop_cmd = [ |
| + options.test_ffmpeg, |
| + '-v', 'error', |
| + '-s', options.frame_width + 'x' + options.frame_height, |
| + '-i', os.path.join(test_file_location, test_file_name), |
| + # TODO(jansson) make the entire crop parameter section a command line |
| + # argument. |
| + '-vf', 'crop=' + test_crop_parameters, |
| + '-c:a', 'copy', |
| + cropped_test_file |
| + ] |
| + |
| + ref_crop = subprocess.Popen(ref_video_crop_cmd) |
| + ref_crop.wait() |
| + print 'Ref file cropped to: ' + cropped_ref_file |
| + |
| + try: |
| + test_crop = subprocess.Popen(test_video_crop_cmd) |
| + test_crop.wait() |
| + print 'Test file cropped to: ' + cropped_test_file |
| + print 'Cropping done!\n' |
| + # Need to return these so they can be used by other parts. |
| + cropped_recordings = { |
| + 'cropped_test_file' : cropped_test_file, |
| + 'cropped_ref_file' : cropped_ref_file |
| + } |
| + |
| + return cropped_recordings |
| + except subprocess.CalledProcessError as e: |
| + print 'Something went wrong during cropping: ' + e |
| + raise |
| + |
| + |
| +def compare_videos(options, recording_result): |
| + """Runs the compare_video.py script from src/webrtc/tools using the file paths |
| + from recording_result and writes the output to a file named |
| + <options.app_name + '_' + CURRENT_TIME + '_result.txt> in the reference video |
| + recording folder taken from recording_result. |
| + |
| + Args: |
| + options(object): Contains all the provided command line options. |
| + recording_files_and_time(dict): key: value pair with the path to cropped |
| + test and reference video files |
| + """ |
| + print 'Starting comparison...' |
| + print 'Grab a coffee, this might take a few minutes...' |
| + cropped_ref_file = recording_result['cropped_ref_file'] |
| + cropped_test_file = recording_result['cropped_test_file'] |
| + compare_videos_script = os.path.abspath(options.compare_videos_script) |
| + result_file_name = \ |
|
kjellander_webrtc
2017/02/22 12:30:50
remove \ and use string formatter instead.
janssonWebRTC
2017/03/07 14:23:45
Done.
|
| + os.path.join(os.path.dirname(recording_result['cropped_ref_file']), |
| + options.app_name + '_' + CURRENT_TIME + '_result.txt') |
| + |
| + compare_cmd = [ |
| + sys.executable, |
| + compare_videos_script, |
| + '--ref_video', cropped_ref_file, |
| + '--test_video', cropped_test_file, |
| + '--frame_analyzer', os.path.abspath(options.frame_analyzer), |
| + '--zxing_path', options.zxing_path, |
| + '--ffmpeg_path', options.ref_ffmpeg, |
| + '--stats_file_ref', os.path.join(os.path.dirname(cropped_ref_file), |
| + cropped_ref_file + '_stats.txt'), |
| + '--stats_file_test', os.path.join(os.path.dirname(cropped_test_file), |
| + cropped_test_file + '_stats.txt'), |
| + '--yuv_frame_height', options.ref_crop_height, |
| + '--yuv_frame_width', options.ref_crop_width |
| + ] |
| + |
| + try: |
| + with open(result_file_name, 'w') as f: |
| + compare_video_recordings = subprocess.Popen(compare_cmd, stdout=f) |
| + compare_video_recordings.wait() |
| + print 'Result recorded to: ' + os.path.abspath(result_file_name) |
| + print 'Comparison done!' |
| + except subprocess.CalledProcessError as e: |
| + print 'Something went wrong when trying to compare videos: ' + e |
| + raise |
| + |
| + |
| +def main(): |
| + """The main function. |
| + |
| + A simple invocation is: |
| + ./run_video_analysis.py \ |
| + --app_name AppRTCMobile \ |
| + --ref_ffmpeg ./ref_ffmpeg --ref_video_device=/dev/video0 \ |
| + --test_ffmpeg ./test_ffmpeg --test_video_device=/dev/video1 \ |
| + --zxing_path ./zxing \ |
| + --test_crop_width 950 --test_crop_height 420 \ |
| + --ref_crop_width 950 --ref_crop_height 420 \ |
| + --test_crop_x_axis_start 130 --test_crop_y_axis_start 56 \ |
| + --ref_crop_x_axis_start 130 --ref_crop_y_axis_start 56 \ |
| + --ref_rec_dir /tmp/ref \ |
| + --test_rec_dir /tmp/test |
| + |
| + This will produce the following files if successful: |
| + # Original video recordings. |
| + /tmp/ref/AppRTCMobile_<recording date and time>_ref.yuv |
| + /tmp/test/AppRTCMobile_<recording date and time>_test.yuv |
| + |
| + # Cropped video recordings according to the crop parameters. |
| + /tmp/ref/cropped_AppRTCMobile_<recording date and time>_ref.yuv |
| + /tmp/test/cropped_AppRTCMobile_<recording date and time>_ref.yuv |
| + |
| + # Comparison metrics from cropped test and ref videos. |
| + /tmp/test/AppRTCMobile_<recording date and time>_result.text |
| + |
| + """ |
| + options = _parseArgs() |
| + restart_magewell_devices(options) |
| + record_paths = create_recording_dirs(options) |
| + recording_result = start_recording(options, record_paths) |
| + # Do not require compare_video.py script to run, no metrics will be generated. |
| + if os.path.exists(options.frame_analyzer) or \ |
| + os.path.exists(options.compare_videos_script) or \ |
| + os.path.exists(options.zxing_path): |
| + compare_videos(options, recording_result) |
|
kjellander_webrtc
2017/02/22 12:30:50
This is a bit unexpected. I suggest you at least a
janssonWebRTC
2017/03/07 14:23:45
Done.
|
| + |
|
kjellander_webrtc
2017/02/22 12:30:50
+1 blank line for top-level statements.
janssonWebRTC
2017/03/07 14:23:45
Done.
|
| +if __name__ == '__main__': |
| + sys.exit(main()) |