# License: Apache 2.0. See LICENSE file in root directory. # Copyright(c) 2021 Intel Corporation. All Rights Reserved. #test:device D400* !D457 # Objective: # # Verify that pause & resume did not mess up the recorded timestamps and the sleep time between each 2 frames is # reasonable. We had a BUG with calculating the sleep time between each 2 frames when the pause action occurred # before the recording base time was set (first frame arrival time), causing the recorded bag file "capture # time" to go up and down, and therefore huge sleep times. See [DSO-14342] # # Here we test multiple flows on pause & resume actions and verify that the whole file will be be played until a # stop event (EOF) within a reasonable time. import pyrealsense2 as rs, os, time, tempfile from rspy import log, test from playback_helper import PlaybackStatusVerifier # create temporary folder to record to that will be deleted automatically at the end of the script # (requires that no files are being held open inside this directory. Important to not keep any handle open to a file # in this directory, any handle as such must be set to None) temp_dir = tempfile.TemporaryDirectory( prefix='recordings_' ) file_name = temp_dir.name + os.sep + 'rec.bag' stop_detected = False STREAMING_DURATION = 3 TIMEOUT_BUFFER = 3 # [sec] extra time to the expected playback time for not failing on runtime hiccups.. def record_with_pause( file_name, iterations, pause_delay=0, resume_delay=0 ): # creating a pipeline and recording to a file pipeline = rs.pipeline() cfg = rs.config() cfg.enable_record_to_file( file_name ) pipeline_record_profile = pipeline.start( cfg ) device = pipeline_record_profile.get_device() device_recorder = device.as_recorder() for i in range( iterations ): if pause_delay > 0: log.d('Sleeping for', pause_delay, '[sec]') time.sleep( pause_delay ) log.d( 'Pausing...' ) rs.recorder.pause(device_recorder) if resume_delay > 0: log.d('Sleeping for', resume_delay, '[sec]') time.sleep( resume_delay ) log.d('Resumed...') rs.recorder.resume( device_recorder ) time.sleep( STREAMING_DURATION ) pipeline.stop() return calc_playback_timeout( iterations, pause_delay ) def playback( pipeline, file_name ): cfg = rs.config() cfg.enable_device_from_file( file_name, repeat_playback=False ) log.d( 'Playing...' ) pipeline_playback_profile = pipeline.start( cfg ) device = pipeline_playback_profile.get_device() playback_dev = device.as_playback() # We force realtime=True to ensure that a sleep with be performed between frames while playback is on, # without it we would have to manually look at the frame timestamps. Instead, we turn it on and depend on the # timeout, albeit at the cost of playback runtime. playback_dev.set_real_time( True ) pipeline.wait_for_frames() test.check_equal( playback_dev.current_status(), rs.playback_status.playing ) return playback_dev def calc_playback_timeout( iterations, pause_delay ): global TIMEOUT_BUFFER # NOTE: the recording resume-delay is the time we have paused the stream, and is not # reflected in the playback! Therefore it's not reflected here: return iterations * ( pause_delay + STREAMING_DURATION ) + TIMEOUT_BUFFER ################################################################################################ # test.start("Immediate pause & test") # probably pause & resume will occur before recording base time is set. try: timeout = record_with_pause( file_name, iterations = 1, pause_delay = 0, resume_delay = 0 ) pipeline = rs.pipeline() device_playback = playback( pipeline, file_name ) psv = PlaybackStatusVerifier( device_playback ); psv.wait_for_status(timeout, rs.playback_status.stopped) except Exception: test.unexpected_exception() finally: # remove all references to the file and dereference the pipeline device_playback = None pipeline = None test.finish() # ################################################################################################ # test.start("Immediate pause & delayed resume test") # Pause time should be lower than recording base time and resume time higher try: timeout = record_with_pause( file_name, iterations = 1, pause_delay = 0, resume_delay = 5 ) pipeline = rs.pipeline() device_playback = playback( pipeline, file_name ) psv = PlaybackStatusVerifier( device_playback ); psv.wait_for_status( timeout, rs.playback_status.stopped ) except Exception: test.unexpected_exception() finally: # remove all references to the file and dereference the pipeline device_playback = None pipeline = None test.finish() # ################################################################################################ # test.start("delayed pause & delayed resume test") # Pause & resume will occur after recording base time is set try: timeout = record_with_pause( file_name, iterations = 1, pause_delay = 3, resume_delay = 2 ) pipeline = rs.pipeline() device_playback = playback( pipeline, file_name ) psv = PlaybackStatusVerifier( device_playback ); psv.wait_for_status( timeout, rs.playback_status.stopped ) except Exception: test.unexpected_exception() finally: # remove all references to the file and dereference the pipeline device_playback = None pipeline = None test.finish() # ################################################################################################ # test.start("multiple delay & pause test") # Combination of some of the previous tests, testing accumulated recording capture time try: timeout = record_with_pause( file_name, iterations = 2, pause_delay = 0, resume_delay = 2 ) pipeline = rs.pipeline() device_playback = playback( pipeline, file_name ) psv = PlaybackStatusVerifier( device_playback ); psv.wait_for_status( timeout, rs.playback_status.stopped ) except Exception: test.unexpected_exception() finally: # remove all references to the file and dereference the pipeline device_playback = None pipeline = None test.finish() # ############################################################################################# # test.print_results_and_exit()