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 |
| index 350bc556fb71cd4a461639eb045d14432133a85b..f133c7d93c0d955a100d6453f855b305fd9e7498 100755 |
| --- a/webrtc/tools/run_video_analysis.py |
| +++ b/webrtc/tools/run_video_analysis.py |
| @@ -14,10 +14,24 @@ import sys |
| import time |
| import glob |
| import re |
| +import shutil |
| # Used to time-stamp output files and directories |
| CURRENT_TIME = time.strftime("%d_%m_%Y-%H:%M:%S") |
| +# Base error class. |
|
kjellander_webrtc
2017/03/15 11:51:00
Please skip the comment for each of these classes.
janssonWebRTC
2017/03/15 13:44:36
Done.
|
| +class Error(Exception): |
| + pass |
| + |
| +# FFMpeg related error class. |
| +class FfmpegError(Error): |
| + pass |
| + |
| +# Magewell related error class. |
| +class MagewellError(Error): |
| + pass |
| + |
| + |
| def _ParseArgs(): |
| """Registers the command-line options.""" |
| usage = 'usage: %prog [options]' |
| @@ -166,7 +180,6 @@ def RestartMagewellDevices(ref_video_device, test_video_device): |
| # 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): |
| @@ -174,17 +187,18 @@ def RestartMagewellDevices(ref_video_device, test_video_device): |
| 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: |
| + # Abort early if no devices are found. |
| + if len(magewell_usb_ports) == 0: |
| + raise MagewellError('No magewell devices found.') |
| + else: |
| + 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). |
| for usb_port in magewell_usb_ports: |
| echo_cmd = ['echo', usb_port] |
| unbind_cmd = ['sudo', 'tee', '/sys/bus/usb/drivers/usb/unbind'] |
| @@ -195,38 +209,35 @@ def RestartMagewellDevices(ref_video_device, test_video_device): |
| 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 |
| + if bind.returncode == 0: |
| + print 'Reset done!\n' |
| - print 'Reset done!\n' |
| - |
| -def StartRecording(options, record_paths): |
| +def StartRecording(options, ref_file_location, test_file_location): |
| """Starts recording from the two specified video devices. |
| Args: |
| options(object): Contains all the provided command line options. |
| record_paths(dict): key: value pair with reference and test file |
| absolute paths. |
| + Return: |
|
kjellander_webrtc
2017/03/15 11:51:00
nit: You should document the potentially raised Ff
janssonWebRTC
2017/03/15 13:44:36
Done.
|
| + FlipAndCropRecordings(function): Performs cropping and transforms on the |
|
kjellander_webrtc
2017/03/15 11:51:00
This is actually not true, what is returned from t
janssonWebRTC
2017/03/15 13:44:36
Right, was a bit unsure of what to document since
|
| + reference and test recordings and returns the path for each |
| + respectively. |
| """ |
| ref_file_name = '%s_%s_ref.%s' % (options.app_name, CURRENT_TIME, |
| options.video_container) |
| - ref_file_location = os.path.join(record_paths['ref_rec_location'], |
| - ref_file_name) |
| + ref_file = os.path.join(ref_file_location, ref_file_name) |
| test_file_name = '%s_%s_test.%s' % (options.app_name, CURRENT_TIME, |
| options.video_container) |
| - test_file_location = os.path.join(record_paths['test_rec_location'], |
| - test_file_name) |
| + test_file = os.path.join(test_file_location, test_file_name) |
| # Reference video recorder command line. |
| ref_cmd = [ |
| @@ -240,7 +251,7 @@ def StartRecording(options, record_paths): |
| '-s', options.frame_width + 'x' + options.frame_height, |
| '-t', options.ref_duration, |
| '-framerate', options.framerate, |
| - ref_file_location |
| + ref_file |
| ] |
| # Test video recorder command line. |
| @@ -255,7 +266,7 @@ def StartRecording(options, record_paths): |
| '-s', options.frame_width + 'x' + options.frame_height, |
| '-t', options.test_duration, |
| '-framerate', options.framerate, |
| - test_file_location |
| + test_file |
| ] |
| print 'Trying to record from reference recorder...' |
| ref_recorder = subprocess.Popen(ref_cmd, stderr=sys.stderr) |
| @@ -270,19 +281,17 @@ def StartRecording(options, record_paths): |
| ref_recorder.wait() |
| # ffmpeg does not abort when it fails, need to check return code. |
| - assert ref_recorder.returncode == 0, ( |
| - 'Ref recording failed, check ffmpeg output and device: %s' |
| - % options.ref_video_device) |
| - assert test_recorder.returncode == 0, ( |
| - 'Test recording failed, check ffmpeg output and device: %s' |
| - % options.test_video_device) |
| - |
| - 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 FlipAndCropRecordings(options, test_file_name, |
| - record_paths['test_rec_location'], ref_file_name, |
| - record_paths['ref_rec_location']) |
| + if ref_recorder.returncode != 0 or test_recorder.returncode != 0: |
| + # Cleanup recording directories. |
| + shutil.rmtree(ref_file_location) |
| + shutil.rmtree(test_file_location) |
| + raise FfmpegError('Recording failed, check ffmpeg output.') |
| + else: |
| + print 'Ref file recorded to: ' + os.path.abspath(ref_file) |
| + print 'Test file recorded to: ' + os.path.abspath(test_file) |
| + print 'Recording done!\n' |
| + return FlipAndCropRecordings(options, test_file_name, test_file_location, |
| + ref_file_name, ref_file_location) |
| def FlipAndCropRecordings(options, test_file_name, test_file_location, |
| @@ -336,11 +345,17 @@ def FlipAndCropRecordings(options, test_file_name, test_file_location, |
| ref_crop = subprocess.Popen(ref_video_crop_cmd) |
| ref_crop.wait() |
| - print 'Ref file cropped to: ' + cropped_ref_file |
| + test_crop = subprocess.Popen(test_video_crop_cmd) |
| + test_crop.wait() |
| - try: |
| - test_crop = subprocess.Popen(test_video_crop_cmd) |
| - test_crop.wait() |
| + # ffmpeg does not abort when it fails, need to check return code. |
| + if ref_crop.returncode != 0 or test_crop.returncode != 0: |
| + # Cleanup recording directories. |
| + shutil.rmtree(ref_file_location) |
| + shutil.rmtree(test_file_location) |
| + raise FfmpegError('Cropping failed, check ffmpeg output.') |
| + else: |
| + print 'Ref file cropped to: ' + cropped_ref_file |
| print 'Test file cropped to: ' + cropped_test_file |
| print 'Cropping done!\n' |
| @@ -349,11 +364,7 @@ def FlipAndCropRecordings(options, test_file_name, test_file_location, |
| '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 CompareVideos(options, recording_result): |
| @@ -378,8 +389,8 @@ def CompareVideos(options, recording_result): |
| result_file_name = os.path.join(rec_path, '%s_%s_result.txt') % ( |
| options.app_name, CURRENT_TIME) |
| - # Find the crop dimensions (950 and 420) in the ref crop parameter string: |
| - # 'hflip, crop=950:420:130:56' |
| + # Find the crop dimensions (e.g. 950 and 420) in the ref crop parameter |
| + # string: 'hflip, crop=950:420:130:56' |
| for param in options.ref_crop_parameters.split('crop'): |
| if param[0] == '=': |
| crop_width = param.split(':')[0].split('=')[1] |
| @@ -405,11 +416,12 @@ def CompareVideos(options, recording_result): |
| 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: |
| + except OSError as e: |
| print 'Something went wrong when trying to compare videos: ' + e |
| raise |
| + else: |
| + print 'Result recorded to: ' + os.path.abspath(result_file_name) |
| + print 'Comparison done!' |
| def main(): |
| @@ -442,7 +454,8 @@ def main(): |
| options = _ParseArgs() |
| RestartMagewellDevices(options.ref_video_device, options.test_video_device) |
| record_paths = CreateRecordingDirs(options) |
| - recording_result = StartRecording(options, record_paths) |
| + recording_result = StartRecording(options, record_paths['ref_rec_location'], |
| + record_paths['test_rec_location']) |
| # Do not require compare_video.py script to run, no metrics will be generated. |
| if options.compare_videos_script: |