Optofidelity: Save calibration videos when using --save-video

For testing PWM compensation we need access to calibration videos, which
we save with this flag.

BUG=chromium:536633
TEST=manual testing

Change-Id: I88447c3853e7eb61627671c996d6009734996ffe
Reviewed-on: https://chromium-review.googlesource.com/336523
Commit-Ready: Dennis Kempin <denniskempin@chromium.org>
Tested-by: Dennis Kempin <denniskempin@chromium.org>
Reviewed-by: Dennis Kempin <denniskempin@chromium.org>
diff --git a/optofidelity/optofidelity/benchmark/runner.py b/optofidelity/optofidelity/benchmark/runner.py
index 792caca..07c2b2a 100644
--- a/optofidelity/optofidelity/benchmark/runner.py
+++ b/optofidelity/optofidelity/benchmark/runner.py
@@ -78,8 +78,9 @@
     finally:
       self.CloseSubject()
 
-  def OpenAndCalibrateSubject(self, subject):
-    self._screen_calibration = self._OpenAndCalibrateSubject(subject)
+  def OpenAndCalibrateSubject(self, subject, save_video=False):
+    self._screen_calibration = self._OpenAndCalibrateSubject(subject,
+                                                             save_video)
     self._current_subject = subject
 
   def CloseSubject(self):
@@ -107,7 +108,7 @@
       raise Exception("Must be executed within the context of UseSubject.")
     self._ExecuteBenchmark(benchmark)
 
-  def _OpenAndCalibrateSubject(self, subject):
+  def _OpenAndCalibrateSubject(self, subject, save_video=False):
     """Open a subject and calibrate screen.
 
     :type subject: BenchmarkSubject
@@ -116,7 +117,7 @@
     self._progress.Info(subject.name, "Opening and calibrating")
     subject.navigator.Open()
     try:
-      return self._CalibrateScreen(subject)
+      return self._CalibrateScreen(subject, save_video)
     except:
       subject.navigator.Close()
       raise
@@ -145,12 +146,19 @@
     benchmark.results.metadata["elapsed_time"] =  "%ds" % elapsed_time
     benchmark.log = capture.log
 
-  def _CalibrateScreen(self, subject):
+  def _CalibrateScreen(self, subject, save_video=False):
     """Execute the screen calibration process.
 
     :type subject: BenchmarkSubject
     :rtype Optional[ScreenCalibration]
     """
+    def SaveVideo(video_reader):
+      if self._calib_video_path:
+        unique_file, _ = GSFindUniqueFilename(self._calib_video_path,
+                                              "calibration_", ".avi")
+        self._progress.Info(subject.name, "Calibration video at: %s" %
+                                           (unique_file,))
+        video_reader.Save(unique_file)
     try:
       self._progress.Info(subject.name, "Calibrating screen")
       if subject.camera.is_relative:
@@ -158,15 +166,11 @@
       video_reader = subject.RecordCalibrationVideo()
       screen_calibration = self.video_processor.CreateScreenCalibration(
           video_reader)
+      if save_video:
+        SaveVideo(video_reader)
       return screen_calibration
     except KeyboardInterrupt:
       raise
     except:
-      if self._calib_video_path:
-        unique_file, _ = GSFindUniqueFilename(self._calib_video_path,
-                                              "calibration_", ".avi")
-        self._progress.Exception(subject.name, "Failed calibration video at: %s" %
-                                           (unique_file,))
-        video_reader.Save(unique_file)
-
+      SaveVideo(video_reader)
       raise
diff --git a/optofidelity/optofidelity/orchestrator/orchestrator.py b/optofidelity/optofidelity/orchestrator/orchestrator.py
index 95996b2..5ff3d3d 100644
--- a/optofidelity/optofidelity/orchestrator/orchestrator.py
+++ b/optofidelity/optofidelity/orchestrator/orchestrator.py
@@ -174,7 +174,7 @@
           if not subject.Verify():
             self._progress.Error(subject.name, "Subject is in a bad state.")
 
-          self._runner.OpenAndCalibrateSubject(subject)
+          self._runner.OpenAndCalibrateSubject(subject, self._save_video)
           self._runner.CloseSubject()
 
   def PrepareSubjects(self, match="*"):
@@ -361,7 +361,7 @@
     :returns bool: True if successful.
     """
     with self._progress.CaptureFailures(subject.name, "Subject calibration"):
-      self._runner.OpenAndCalibrateSubject(subject)
+      self._runner.OpenAndCalibrateSubject(subject, self._save_video)
       return True
     return False