 Chromium Code Reviews
 Chromium Code Reviews Issue 2746413002:
  Improve error handling for ffmpeg operations  (Closed)
    
  
    Issue 2746413002:
  Improve error handling for ffmpeg operations  (Closed) 
  | OLD | NEW | 
|---|---|
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python | 
| 2 # Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. | 2 # Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. | 
| 3 # | 3 # | 
| 4 # Use of this source code is governed by a BSD-style license | 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 | 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 | 6 # tree. An additional intellectual property rights grant can be found | 
| 7 # in the file PATENTS. All contributing project authors may | 7 # in the file PATENTS. All contributing project authors may | 
| 8 # be found in the AUTHORS file in the root of the source tree. | 8 # be found in the AUTHORS file in the root of the source tree. | 
| 9 | 9 | 
| 10 import optparse | 10 import optparse | 
| 11 import os | 11 import os | 
| 12 import subprocess | 12 import subprocess | 
| 13 import sys | 13 import sys | 
| 14 import time | 14 import time | 
| 15 import glob | 15 import glob | 
| 16 import re | 16 import re | 
| 17 import shutil | |
| 17 | 18 | 
| 18 # Used to time-stamp output files and directories | 19 # Used to time-stamp output files and directories | 
| 19 CURRENT_TIME = time.strftime("%d_%m_%Y-%H:%M:%S") | 20 CURRENT_TIME = time.strftime("%d_%m_%Y-%H:%M:%S") | 
| 20 | 21 | 
| 22 # 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.
 | |
| 23 class Error(Exception): | |
| 24 pass | |
| 25 | |
| 26 # FFMpeg related error class. | |
| 27 class FfmpegError(Error): | |
| 28 pass | |
| 29 | |
| 30 # Magewell related error class. | |
| 31 class MagewellError(Error): | |
| 32 pass | |
| 33 | |
| 34 | |
| 21 def _ParseArgs(): | 35 def _ParseArgs(): | 
| 22 """Registers the command-line options.""" | 36 """Registers the command-line options.""" | 
| 23 usage = 'usage: %prog [options]' | 37 usage = 'usage: %prog [options]' | 
| 24 parser = optparse.OptionParser(usage=usage) | 38 parser = optparse.OptionParser(usage=usage) | 
| 25 | 39 | 
| 26 parser.add_option('--frame_width', type='string', default='1280', | 40 parser.add_option('--frame_width', type='string', default='1280', | 
| 27 help='Width of the recording. Default: %default') | 41 help='Width of the recording. Default: %default') | 
| 28 parser.add_option('--frame_height', type='string', default='720', | 42 parser.add_option('--frame_height', type='string', default='720', | 
| 29 help='Height of the recording. Default: %default') | 43 help='Height of the recording. Default: %default') | 
| 30 parser.add_option('--framerate', type='string', default='60', | 44 parser.add_option('--framerate', type='string', default='60', | 
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 142 def RestartMagewellDevices(ref_video_device, test_video_device): | 156 def RestartMagewellDevices(ref_video_device, test_video_device): | 
| 143 """Reset the USB ports where Magewell capture devices are connected to. | 157 """Reset the USB ports where Magewell capture devices are connected to. | 
| 144 | 158 | 
| 145 Tries to find the provided ref_video_device and test_video_device devices | 159 Tries to find the provided ref_video_device and test_video_device devices | 
| 146 which use video4linux and then do a soft reset by using USB unbind and bind. | 160 which use video4linux and then do a soft reset by using USB unbind and bind. | 
| 147 This is due to Magewell capture devices have proven to be unstable after the | 161 This is due to Magewell capture devices have proven to be unstable after the | 
| 148 first recording attempt. | 162 first recording attempt. | 
| 149 | 163 | 
| 150 Args: | 164 Args: | 
| 151 ref_video_device(string): reference recording device path. | 165 ref_video_device(string): reference recording device path. | 
| 152 test_video_device(string): test recording device path | 166 test_video_device(string): test recording device path | 
| 
kjellander_webrtc
2017/03/15 11:51:00
Document that MagewellError may be raised
 
janssonWebRTC
2017/03/15 13:44:36
Done.
 | |
| 153 """ | 167 """ | 
| 154 | 168 | 
| 155 # Get the dev/videoN device name from the command line arguments. | 169 # Get the dev/videoN device name from the command line arguments. | 
| 156 ref_magewell = ref_video_device.split('/')[2] | 170 ref_magewell = ref_video_device.split('/')[2] | 
| 157 test_magewell = test_video_device.split('/')[2] | 171 test_magewell = test_video_device.split('/')[2] | 
| 158 | 172 | 
| 159 # Find the device location including USB and USB Bus ID's. | 173 # Find the device location including USB and USB Bus ID's. | 
| 160 device_string = '/sys/bus/usb/devices/usb*/**/**/video4linux/' | 174 device_string = '/sys/bus/usb/devices/usb*/**/**/video4linux/' | 
| 161 ref_magewell_device = glob.glob('%s%s' % (device_string, ref_magewell)) | 175 ref_magewell_device = glob.glob('%s%s' % (device_string, ref_magewell)) | 
| 162 test_magewell_device = glob.glob('%s%s' % (device_string, test_magewell)) | 176 test_magewell_device = glob.glob('%s%s' % (device_string, test_magewell)) | 
| 163 | 177 | 
| 164 magewell_usb_ports = [] | 178 magewell_usb_ports = [] | 
| 165 | 179 | 
| 166 # Figure out the USB bus and port ID for each device. | 180 # Figure out the USB bus and port ID for each device. | 
| 167 ref_magewell_path = str(ref_magewell_device).split('/') | 181 ref_magewell_path = str(ref_magewell_device).split('/') | 
| 168 for directory in ref_magewell_path: | 182 for directory in ref_magewell_path: | 
| 169 | |
| 170 # Find the folder with pattern "N-N", e.g. "4-3" or \ | 183 # Find the folder with pattern "N-N", e.g. "4-3" or \ | 
| 171 # "[USB bus ID]-[USB port]" | 184 # "[USB bus ID]-[USB port]" | 
| 172 if re.match(r'^\d-\d$', directory): | 185 if re.match(r'^\d-\d$', directory): | 
| 173 magewell_usb_ports.append(directory) | 186 magewell_usb_ports.append(directory) | 
| 174 | 187 | 
| 175 test_magewell_path = str(test_magewell_device).split('/') | 188 test_magewell_path = str(test_magewell_device).split('/') | 
| 176 for directory in test_magewell_path: | 189 for directory in test_magewell_path: | 
| 177 | |
| 178 # Find the folder with pattern "N-N", e.g. "4-3" or \ | 190 # Find the folder with pattern "N-N", e.g. "4-3" or \ | 
| 179 # "[USB bus ID]-[USB port]" | 191 # "[USB bus ID]-[USB port]" | 
| 180 if re.match(r'^\d-\d$', directory): | 192 if re.match(r'^\d-\d$', directory): | 
| 181 magewell_usb_ports.append(directory) | 193 magewell_usb_ports.append(directory) | 
| 182 | 194 | 
| 183 print '\nResetting USB ports where magewell devices are connected...' | 195 # Abort early if no devices are found. | 
| 184 | 196 if len(magewell_usb_ports) == 0: | 
| 185 # Use the USB bus and port ID (e.g. 4-3) to unbind and bind the USB devices | 197 raise MagewellError('No magewell devices found.') | 
| 186 # (i.e. soft eject and insert). | 198 else: | 
| 187 try: | 199 print '\nResetting USB ports where magewell devices are connected...' | 
| 200 # Use the USB bus and port ID (e.g. 4-3) to unbind and bind the USB devices | |
| 201 # (i.e. soft eject and insert). | |
| 188 for usb_port in magewell_usb_ports: | 202 for usb_port in magewell_usb_ports: | 
| 189 echo_cmd = ['echo', usb_port] | 203 echo_cmd = ['echo', usb_port] | 
| 190 unbind_cmd = ['sudo', 'tee', '/sys/bus/usb/drivers/usb/unbind'] | 204 unbind_cmd = ['sudo', 'tee', '/sys/bus/usb/drivers/usb/unbind'] | 
| 191 bind_cmd = ['sudo', 'tee', '/sys/bus/usb/drivers/usb/bind'] | 205 bind_cmd = ['sudo', 'tee', '/sys/bus/usb/drivers/usb/bind'] | 
| 192 | 206 | 
| 193 # TODO(jansson) Figure out a way to call on echo once for bind & unbind | 207 # TODO(jansson) Figure out a way to call on echo once for bind & unbind | 
| 194 # if possible. | 208 # if possible. | 
| 195 echo_unbind = subprocess.Popen(echo_cmd, stdout=subprocess.PIPE) | 209 echo_unbind = subprocess.Popen(echo_cmd, stdout=subprocess.PIPE) | 
| 196 unbind = subprocess.Popen(unbind_cmd, stdin=echo_unbind.stdout) | 210 unbind = subprocess.Popen(unbind_cmd, stdin=echo_unbind.stdout) | 
| 197 echo_unbind.stdout.close() | 211 echo_unbind.stdout.close() | 
| 198 unbind.communicate() | |
| 199 unbind.wait() | 212 unbind.wait() | 
| 200 | 213 | 
| 201 echo_bind = subprocess.Popen(echo_cmd, stdout=subprocess.PIPE) | 214 echo_bind = subprocess.Popen(echo_cmd, stdout=subprocess.PIPE) | 
| 202 bind = subprocess.Popen(bind_cmd, stdin=echo_bind.stdout) | 215 bind = subprocess.Popen(bind_cmd, stdin=echo_bind.stdout) | 
| 203 echo_bind.stdout.close() | 216 echo_bind.stdout.close() | 
| 204 bind.communicate() | |
| 205 bind.wait() | 217 bind.wait() | 
| 206 except OSError as e: | 218 if bind.returncode == 0: | 
| 207 print 'Error while resetting magewell devices: ' + e | 219 print 'Reset done!\n' | 
| 208 raise | |
| 209 | |
| 210 print 'Reset done!\n' | |
| 211 | 220 | 
| 212 | 221 | 
| 213 def StartRecording(options, record_paths): | 222 def StartRecording(options, ref_file_location, test_file_location): | 
| 214 """Starts recording from the two specified video devices. | 223 """Starts recording from the two specified video devices. | 
| 215 | 224 | 
| 216 Args: | 225 Args: | 
| 217 options(object): Contains all the provided command line options. | 226 options(object): Contains all the provided command line options. | 
| 218 record_paths(dict): key: value pair with reference and test file | 227 record_paths(dict): key: value pair with reference and test file | 
| 219 absolute paths. | 228 absolute paths. | 
| 229 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.
 | |
| 230 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
 | |
| 231 reference and test recordings and returns the path for each | |
| 232 respectively. | |
| 220 """ | 233 """ | 
| 221 ref_file_name = '%s_%s_ref.%s' % (options.app_name, CURRENT_TIME, | 234 ref_file_name = '%s_%s_ref.%s' % (options.app_name, CURRENT_TIME, | 
| 222 options.video_container) | 235 options.video_container) | 
| 223 ref_file_location = os.path.join(record_paths['ref_rec_location'], | 236 ref_file = os.path.join(ref_file_location, ref_file_name) | 
| 224 ref_file_name) | |
| 225 | 237 | 
| 226 test_file_name = '%s_%s_test.%s' % (options.app_name, CURRENT_TIME, | 238 test_file_name = '%s_%s_test.%s' % (options.app_name, CURRENT_TIME, | 
| 227 options.video_container) | 239 options.video_container) | 
| 228 test_file_location = os.path.join(record_paths['test_rec_location'], | 240 test_file = os.path.join(test_file_location, test_file_name) | 
| 229 test_file_name) | |
| 230 | 241 | 
| 231 # Reference video recorder command line. | 242 # Reference video recorder command line. | 
| 232 ref_cmd = [ | 243 ref_cmd = [ | 
| 233 options.ffmpeg, | 244 options.ffmpeg, | 
| 234 '-v', 'error', | 245 '-v', 'error', | 
| 235 '-s', options.frame_width + 'x' + options.frame_height, | 246 '-s', options.frame_width + 'x' + options.frame_height, | 
| 236 '-framerate', options.framerate, | 247 '-framerate', options.framerate, | 
| 237 '-f', options.recording_api, | 248 '-f', options.recording_api, | 
| 238 '-i', options.ref_video_device, | 249 '-i', options.ref_video_device, | 
| 239 '-pix_fmt', options.pixel_format, | 250 '-pix_fmt', options.pixel_format, | 
| 240 '-s', options.frame_width + 'x' + options.frame_height, | 251 '-s', options.frame_width + 'x' + options.frame_height, | 
| 241 '-t', options.ref_duration, | 252 '-t', options.ref_duration, | 
| 242 '-framerate', options.framerate, | 253 '-framerate', options.framerate, | 
| 243 ref_file_location | 254 ref_file | 
| 244 ] | 255 ] | 
| 245 | 256 | 
| 246 # Test video recorder command line. | 257 # Test video recorder command line. | 
| 247 test_cmd = [ | 258 test_cmd = [ | 
| 248 options.ffmpeg, | 259 options.ffmpeg, | 
| 249 '-v', 'error', | 260 '-v', 'error', | 
| 250 '-s', options.frame_width + 'x' + options.frame_height, | 261 '-s', options.frame_width + 'x' + options.frame_height, | 
| 251 '-framerate', options.framerate, | 262 '-framerate', options.framerate, | 
| 252 '-f', options.recording_api, | 263 '-f', options.recording_api, | 
| 253 '-i', options.test_video_device, | 264 '-i', options.test_video_device, | 
| 254 '-pix_fmt', options.pixel_format, | 265 '-pix_fmt', options.pixel_format, | 
| 255 '-s', options.frame_width + 'x' + options.frame_height, | 266 '-s', options.frame_width + 'x' + options.frame_height, | 
| 256 '-t', options.test_duration, | 267 '-t', options.test_duration, | 
| 257 '-framerate', options.framerate, | 268 '-framerate', options.framerate, | 
| 258 test_file_location | 269 test_file | 
| 259 ] | 270 ] | 
| 260 print 'Trying to record from reference recorder...' | 271 print 'Trying to record from reference recorder...' | 
| 261 ref_recorder = subprocess.Popen(ref_cmd, stderr=sys.stderr) | 272 ref_recorder = subprocess.Popen(ref_cmd, stderr=sys.stderr) | 
| 262 | 273 | 
| 263 # Start the 2nd recording a little later to ensure the 1st one has started. | 274 # Start the 2nd recording a little later to ensure the 1st one has started. | 
| 264 # TODO(jansson) Check that the ref_recorder output file exists rather than | 275 # TODO(jansson) Check that the ref_recorder output file exists rather than | 
| 265 # using sleep. | 276 # using sleep. | 
| 266 time.sleep(options.time_between_recordings) | 277 time.sleep(options.time_between_recordings) | 
| 267 print 'Trying to record from test recorder...' | 278 print 'Trying to record from test recorder...' | 
| 268 test_recorder = subprocess.Popen(test_cmd, stderr=sys.stderr) | 279 test_recorder = subprocess.Popen(test_cmd, stderr=sys.stderr) | 
| 269 test_recorder.wait() | 280 test_recorder.wait() | 
| 270 ref_recorder.wait() | 281 ref_recorder.wait() | 
| 271 | 282 | 
| 272 # ffmpeg does not abort when it fails, need to check return code. | 283 # ffmpeg does not abort when it fails, need to check return code. | 
| 273 assert ref_recorder.returncode == 0, ( | 284 if ref_recorder.returncode != 0 or test_recorder.returncode != 0: | 
| 274 'Ref recording failed, check ffmpeg output and device: %s' | 285 # Cleanup recording directories. | 
| 275 % options.ref_video_device) | 286 shutil.rmtree(ref_file_location) | 
| 276 assert test_recorder.returncode == 0, ( | 287 shutil.rmtree(test_file_location) | 
| 277 'Test recording failed, check ffmpeg output and device: %s' | 288 raise FfmpegError('Recording failed, check ffmpeg output.') | 
| 278 % options.test_video_device) | 289 else: | 
| 279 | 290 print 'Ref file recorded to: ' + os.path.abspath(ref_file) | 
| 280 print 'Ref file recorded to: ' + os.path.abspath(ref_file_location) | 291 print 'Test file recorded to: ' + os.path.abspath(test_file) | 
| 281 print 'Test file recorded to: ' + os.path.abspath(test_file_location) | 292 print 'Recording done!\n' | 
| 282 print 'Recording done!\n' | 293 return FlipAndCropRecordings(options, test_file_name, test_file_location, | 
| 283 return FlipAndCropRecordings(options, test_file_name, | 294 ref_file_name, ref_file_location) | 
| 284 record_paths['test_rec_location'], ref_file_name, | |
| 285 record_paths['ref_rec_location']) | |
| 286 | 295 | 
| 287 | 296 | 
| 288 def FlipAndCropRecordings(options, test_file_name, test_file_location, | 297 def FlipAndCropRecordings(options, test_file_name, test_file_location, | 
| 289 ref_file_name, ref_file_location): | 298 ref_file_name, ref_file_location): | 
| 290 """Performs a horizontal flip of the reference video to match the test video. | 299 """Performs a horizontal flip of the reference video to match the test video. | 
| 291 | 300 | 
| 292 This is done to the match orientation and then crops the ref and test videos | 301 This is done to the match orientation and then crops the ref and test videos | 
| 293 using the options.test_crop_parameters and options.ref_crop_parameters. | 302 using the options.test_crop_parameters and options.ref_crop_parameters. | 
| 294 | 303 | 
| 295 Args: | 304 Args: | 
| 296 options(object): Contains all the provided command line options. | 305 options(object): Contains all the provided command line options. | 
| 297 test_file_name(string): Name of the test video file recording. | 306 test_file_name(string): Name of the test video file recording. | 
| 298 test_file_location(string): Path to the test video file recording. | 307 test_file_location(string): Path to the test video file recording. | 
| 299 ref_file_name(string): Name of the reference video file recording. | 308 ref_file_name(string): Name of the reference video file recording. | 
| 300 ref_file_location(string): Path to the reference video file recording. | 309 ref_file_location(string): Path to the reference video file recording. | 
| 301 Return: | 310 Return: | 
| 
kjellander_webrtc
2017/03/15 11:51:00
Raises: docstring needed here.
 
janssonWebRTC
2017/03/15 13:44:36
Done.
 | |
| 302 recording_files_and_time(dict): key: value pair with the path to cropped | 311 recording_files_and_time(dict): key: value pair with the path to cropped | 
| 303 test and reference video files. | 312 test and reference video files. | 
| 304 """ | 313 """ | 
| 305 print 'Trying to crop videos...' | 314 print 'Trying to crop videos...' | 
| 306 | 315 | 
| 307 # Ref file cropping. | 316 # Ref file cropping. | 
| 308 cropped_ref_file_name = 'cropped_' + ref_file_name | 317 cropped_ref_file_name = 'cropped_' + ref_file_name | 
| 309 cropped_ref_file = os.path.abspath( | 318 cropped_ref_file = os.path.abspath( | 
| 310 os.path.join(ref_file_location, cropped_ref_file_name)) | 319 os.path.join(ref_file_location, cropped_ref_file_name)) | 
| 311 | 320 | 
| (...skipping 17 matching lines...) Expand all Loading... | |
| 329 '-v', 'error', | 338 '-v', 'error', | 
| 330 '-s', options.frame_width + 'x' + options.frame_height, | 339 '-s', options.frame_width + 'x' + options.frame_height, | 
| 331 '-i', os.path.join(test_file_location, test_file_name), | 340 '-i', os.path.join(test_file_location, test_file_name), | 
| 332 '-vf', options.test_crop_parameters, | 341 '-vf', options.test_crop_parameters, | 
| 333 '-c:a', 'copy', | 342 '-c:a', 'copy', | 
| 334 cropped_test_file | 343 cropped_test_file | 
| 335 ] | 344 ] | 
| 336 | 345 | 
| 337 ref_crop = subprocess.Popen(ref_video_crop_cmd) | 346 ref_crop = subprocess.Popen(ref_video_crop_cmd) | 
| 338 ref_crop.wait() | 347 ref_crop.wait() | 
| 339 print 'Ref file cropped to: ' + cropped_ref_file | 348 test_crop = subprocess.Popen(test_video_crop_cmd) | 
| 349 test_crop.wait() | |
| 340 | 350 | 
| 341 try: | 351 # ffmpeg does not abort when it fails, need to check return code. | 
| 342 test_crop = subprocess.Popen(test_video_crop_cmd) | 352 if ref_crop.returncode != 0 or test_crop.returncode != 0: | 
| 343 test_crop.wait() | 353 # Cleanup recording directories. | 
| 354 shutil.rmtree(ref_file_location) | |
| 355 shutil.rmtree(test_file_location) | |
| 356 raise FfmpegError('Cropping failed, check ffmpeg output.') | |
| 357 else: | |
| 358 print 'Ref file cropped to: ' + cropped_ref_file | |
| 344 print 'Test file cropped to: ' + cropped_test_file | 359 print 'Test file cropped to: ' + cropped_test_file | 
| 345 print 'Cropping done!\n' | 360 print 'Cropping done!\n' | 
| 346 | 361 | 
| 347 # Need to return these so they can be used by other parts. | 362 # Need to return these so they can be used by other parts. | 
| 348 cropped_recordings = { | 363 cropped_recordings = { | 
| 349 'cropped_test_file' : cropped_test_file, | 364 'cropped_test_file' : cropped_test_file, | 
| 350 'cropped_ref_file' : cropped_ref_file | 365 'cropped_ref_file' : cropped_ref_file | 
| 351 } | 366 } | 
| 352 | |
| 353 return cropped_recordings | 367 return cropped_recordings | 
| 354 except subprocess.CalledProcessError as e: | |
| 355 print 'Something went wrong during cropping: ' + e | |
| 356 raise | |
| 357 | 368 | 
| 358 | 369 | 
| 359 def CompareVideos(options, recording_result): | 370 def CompareVideos(options, recording_result): | 
| 360 """Runs the compare_video.py script from src/webrtc/tools using the file path. | 371 """Runs the compare_video.py script from src/webrtc/tools using the file path. | 
| 361 | 372 | 
| 362 Uses the path from recording_result and writes the output to a file named | 373 Uses the path from recording_result and writes the output to a file named | 
| 363 <options.app_name + '_' + CURRENT_TIME + '_result.txt> in the reference video | 374 <options.app_name + '_' + CURRENT_TIME + '_result.txt> in the reference video | 
| 364 recording folder taken from recording_result. | 375 recording folder taken from recording_result. | 
| 365 | 376 | 
| 366 Args: | 377 Args: | 
| 367 options(object): Contains all the provided command line options. | 378 options(object): Contains all the provided command line options. | 
| 368 recording_files_and_time(dict): key: value pair with the path to cropped | 379 recording_files_and_time(dict): key: value pair with the path to cropped | 
| 369 test and reference video files | 380 test and reference video files | 
| 370 """ | 381 """ | 
| 371 print 'Starting comparison...' | 382 print 'Starting comparison...' | 
| 372 print 'Grab a coffee, this might take a few minutes...' | 383 print 'Grab a coffee, this might take a few minutes...' | 
| 373 cropped_ref_file = recording_result['cropped_ref_file'] | 384 cropped_ref_file = recording_result['cropped_ref_file'] | 
| 374 cropped_test_file = recording_result['cropped_test_file'] | 385 cropped_test_file = recording_result['cropped_test_file'] | 
| 375 compare_videos_script = os.path.abspath(options.compare_videos_script) | 386 compare_videos_script = os.path.abspath(options.compare_videos_script) | 
| 376 rec_path = os.path.abspath(os.path.join( | 387 rec_path = os.path.abspath(os.path.join( | 
| 377 os.path.dirname(recording_result['cropped_ref_file']))) | 388 os.path.dirname(recording_result['cropped_ref_file']))) | 
| 378 result_file_name = os.path.join(rec_path, '%s_%s_result.txt') % ( | 389 result_file_name = os.path.join(rec_path, '%s_%s_result.txt') % ( | 
| 379 options.app_name, CURRENT_TIME) | 390 options.app_name, CURRENT_TIME) | 
| 380 | 391 | 
| 381 # Find the crop dimensions (950 and 420) in the ref crop parameter string: | 392 # Find the crop dimensions (e.g. 950 and 420) in the ref crop parameter | 
| 382 # 'hflip, crop=950:420:130:56' | 393 # string: 'hflip, crop=950:420:130:56' | 
| 383 for param in options.ref_crop_parameters.split('crop'): | 394 for param in options.ref_crop_parameters.split('crop'): | 
| 384 if param[0] == '=': | 395 if param[0] == '=': | 
| 385 crop_width = param.split(':')[0].split('=')[1] | 396 crop_width = param.split(':')[0].split('=')[1] | 
| 386 crop_height = param.split(':')[1] | 397 crop_height = param.split(':')[1] | 
| 387 | 398 | 
| 388 compare_cmd = [ | 399 compare_cmd = [ | 
| 389 sys.executable, | 400 sys.executable, | 
| 390 compare_videos_script, | 401 compare_videos_script, | 
| 391 '--ref_video', cropped_ref_file, | 402 '--ref_video', cropped_ref_file, | 
| 392 '--test_video', cropped_test_file, | 403 '--test_video', cropped_test_file, | 
| 393 '--frame_analyzer', os.path.abspath(options.frame_analyzer), | 404 '--frame_analyzer', os.path.abspath(options.frame_analyzer), | 
| 394 '--zxing_path', options.zxing_path, | 405 '--zxing_path', options.zxing_path, | 
| 395 '--ffmpeg_path', options.ffmpeg, | 406 '--ffmpeg_path', options.ffmpeg, | 
| 396 '--stats_file_ref', os.path.join(os.path.dirname(cropped_ref_file), | 407 '--stats_file_ref', os.path.join(os.path.dirname(cropped_ref_file), | 
| 397 cropped_ref_file + '_stats.txt'), | 408 cropped_ref_file + '_stats.txt'), | 
| 398 '--stats_file_test', os.path.join(os.path.dirname(cropped_test_file), | 409 '--stats_file_test', os.path.join(os.path.dirname(cropped_test_file), | 
| 399 cropped_test_file + '_stats.txt'), | 410 cropped_test_file + '_stats.txt'), | 
| 400 '--yuv_frame_height', crop_height, | 411 '--yuv_frame_height', crop_height, | 
| 401 '--yuv_frame_width', crop_width | 412 '--yuv_frame_width', crop_width | 
| 402 ] | 413 ] | 
| 403 | 414 | 
| 404 try: | 415 try: | 
| 405 with open(result_file_name, 'w') as f: | 416 with open(result_file_name, 'w') as f: | 
| 406 compare_video_recordings = subprocess.Popen(compare_cmd, stdout=f) | 417 compare_video_recordings = subprocess.Popen(compare_cmd, stdout=f) | 
| 407 compare_video_recordings.wait() | 418 compare_video_recordings.wait() | 
| 408 print 'Result recorded to: ' + os.path.abspath(result_file_name) | 419 except OSError as e: | 
| 409 print 'Comparison done!' | |
| 410 except subprocess.CalledProcessError as e: | |
| 411 print 'Something went wrong when trying to compare videos: ' + e | 420 print 'Something went wrong when trying to compare videos: ' + e | 
| 412 raise | 421 raise | 
| 422 else: | |
| 423 print 'Result recorded to: ' + os.path.abspath(result_file_name) | |
| 424 print 'Comparison done!' | |
| 413 | 425 | 
| 414 | 426 | 
| 415 def main(): | 427 def main(): | 
| 416 """The main function. | 428 """The main function. | 
| 417 | 429 | 
| 418 A simple invocation is: | 430 A simple invocation is: | 
| 419 ./run_video_analysis.py \ | 431 ./run_video_analysis.py \ | 
| 420 --app_name AppRTCMobile \ | 432 --app_name AppRTCMobile \ | 
| 421 --ffmpeg ./ffmpeg --ref_video_device=/dev/video0 \ | 433 --ffmpeg ./ffmpeg --ref_video_device=/dev/video0 \ | 
| 422 --test_video_device=/dev/video1 \ | 434 --test_video_device=/dev/video1 \ | 
| (...skipping 12 matching lines...) Expand all Loading... | |
| 435 /tmp/ref/cropped_AppRTCMobile_<recording date and time>_ref.yuv | 447 /tmp/ref/cropped_AppRTCMobile_<recording date and time>_ref.yuv | 
| 436 /tmp/test/cropped_AppRTCMobile_<recording date and time>_ref.yuv | 448 /tmp/test/cropped_AppRTCMobile_<recording date and time>_ref.yuv | 
| 437 | 449 | 
| 438 # Comparison metrics from cropped test and ref videos. | 450 # Comparison metrics from cropped test and ref videos. | 
| 439 /tmp/test/AppRTCMobile_<recording date and time>_result.text | 451 /tmp/test/AppRTCMobile_<recording date and time>_result.text | 
| 440 | 452 | 
| 441 """ | 453 """ | 
| 442 options = _ParseArgs() | 454 options = _ParseArgs() | 
| 443 RestartMagewellDevices(options.ref_video_device, options.test_video_device) | 455 RestartMagewellDevices(options.ref_video_device, options.test_video_device) | 
| 444 record_paths = CreateRecordingDirs(options) | 456 record_paths = CreateRecordingDirs(options) | 
| 445 recording_result = StartRecording(options, record_paths) | 457 recording_result = StartRecording(options, record_paths['ref_rec_location'], | 
| 458 record_paths['test_rec_location']) | |
| 446 | 459 | 
| 447 # Do not require compare_video.py script to run, no metrics will be generated. | 460 # Do not require compare_video.py script to run, no metrics will be generated. | 
| 448 if options.compare_videos_script: | 461 if options.compare_videos_script: | 
| 449 CompareVideos(options, recording_result) | 462 CompareVideos(options, recording_result) | 
| 
kjellander_webrtc
2017/03/15 11:51:00
It's much more clear if you pass recording_result[
 
janssonWebRTC
2017/03/15 13:44:36
Done.
 | |
| 450 else: | 463 else: | 
| 451 print ('Skipping compare videos step due to compare_videos flag were not ' | 464 print ('Skipping compare videos step due to compare_videos flag were not ' | 
| 452 'passed.') | 465 'passed.') | 
| 453 | 466 | 
| 454 | 467 | 
| 455 if __name__ == '__main__': | 468 if __name__ == '__main__': | 
| 456 sys.exit(main()) | 469 sys.exit(main()) | 
| OLD | NEW |