Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(95)

Unified Diff: webrtc/tools/run_video_analysis.py

Issue 2746413002: Improve error handling for ffmpeg operations (Closed)
Patch Set: Remove blank line Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..29682aa02917779742ececaca52b0662a6d80546 100755
--- a/webrtc/tools/run_video_analysis.py
+++ b/webrtc/tools/run_video_analysis.py
@@ -14,10 +14,28 @@ 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")
+
+class Error(Exception):
+ pass
+
+
+class FfmpegError(Error):
+ pass
+
+
+class MagewellError(Error):
+ pass
+
+
+class CompareVideosError(Error):
+ pass
+
+
def _ParseArgs():
"""Registers the command-line options."""
usage = 'usage: %prog [options]'
@@ -111,7 +129,8 @@ def CreateRecordingDirs(options):
Args:
options(object): Contains all the provided command line options.
- Return:
+
+ Returns:
record_paths(dict): key: value pair with reference and test file
absolute paths.
"""
@@ -147,9 +166,12 @@ def RestartMagewellDevices(ref_video_device, test_video_device):
This is due to Magewell capture devices have proven to be unstable after the
first recording attempt.
- Args:
+ Args :
ref_video_device(string): reference recording device path.
test_video_device(string): test recording device path
+
+ Raises:
+ MagewellError: If no magewell devices are found.
"""
# Get the dev/videoN device name from the command line arguments.
@@ -166,7 +188,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 +195,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 +217,38 @@ 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.
+
+ Returns:
+ recording_files_and_time(dict): key: value pair with the path to cropped
+ test and reference video files.
+
+ Raises:
+ FfmpegError: If the ffmpeg command fails.
"""
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 +262,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 +277,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 +292,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,
@@ -298,9 +318,13 @@ def FlipAndCropRecordings(options, test_file_name, test_file_location,
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:
+
+ Returns:
recording_files_and_time(dict): key: value pair with the path to cropped
test and reference video files.
+
+ Raises:
+ FfmpegError: If the ffmpeg command fails.
"""
print 'Trying to crop videos...'
@@ -336,11 +360,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,14 +379,10 @@ 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):
+def CompareVideos(options, cropped_ref_file, cropped_test_file):
"""Runs the compare_video.py script from src/webrtc/tools using the file path.
Uses the path from recording_result and writes the output to a file named
@@ -365,21 +391,22 @@ def CompareVideos(options, 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
+ cropped_ref_file(string): Path to cropped reference video file.
+ cropped_test_file(string): Path to cropped test video file.
+
+ Raises:
+ CompareVideosError: If compare_videos.py fails.
"""
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)
rec_path = os.path.abspath(os.path.join(
- os.path.dirname(recording_result['cropped_ref_file'])))
+ os.path.dirname(cropped_test_file)))
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]
@@ -401,15 +428,14 @@ def CompareVideos(options, recording_result):
'--yuv_frame_width', 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
+ with open(result_file_name, 'w') as f:
+ compare_video_recordings = subprocess.Popen(compare_cmd, stdout=f)
+ compare_video_recordings.wait()
+ if compare_video_recordings.returncode != 0:
+ raise CompareVideosError('Failed to perform comparison.')
+ else:
+ print 'Result recorded to: ' + os.path.abspath(result_file_name)
+ print 'Comparison done!'
def main():
@@ -442,11 +468,13 @@ 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:
- CompareVideos(options, recording_result)
+ CompareVideos(options, recording_result['cropped_ref_file'],
+ recording_result['cropped_test_file'])
else:
print ('Skipping compare videos step due to compare_videos flag were not '
'passed.')
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698