-
Notifications
You must be signed in to change notification settings - Fork 4.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
added syncer/test-ts-playback.py to test playback behavior at EOF
- Loading branch information
Showing
2 changed files
with
247 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
# License: Apache 2.0. See LICENSE file in root directory. | ||
# Copyright(c) 2021 Intel Corporation. All Rights Reserved. | ||
|
||
import pyrealsense2 as rs | ||
from rspy import log, test | ||
import sw | ||
|
||
|
||
# The timestamp jumps are closely correlated to the FPS passed to the video streams: | ||
# syncer expects frames to arrive every 1000/FPS milliseconds! | ||
sw.fps_c = sw.fps_d = 60 | ||
sw.init() | ||
|
||
import tempfile, os | ||
temp_dir = tempfile.TemporaryDirectory( prefix = 'recordings_' ) | ||
filename = os.path.join( temp_dir.name, 'rec.bag' ) | ||
recorder = rs.recorder( filename, sw.device ) | ||
|
||
sw.start() | ||
|
||
############################################################################################# | ||
# | ||
test.start( "Init" ) | ||
|
||
# It can take a few frames for the syncer to actually produce a matched frameset (it doesn't | ||
# know what to match to in the beginning) | ||
|
||
sw.generate_depth_and_color( frame_number = 0, timestamp = 0 ) | ||
sw.expect( depth_frame = 0 ) # syncer doesn't know about color yet | ||
sw.expect( color_frame = 0, nothing_else = True ) # less than next expected of D | ||
# | ||
# NOTE: if the syncer queue wasn't 100 (see above) then we'd only get the color frame! | ||
# | ||
sw.generate_depth_and_color( 1, sw.gap_d * 1 ) | ||
sw.expect( depth_frame = 1, color_frame = 1, nothing_else = True ) # frameset 1 | ||
|
||
test.finish() | ||
# | ||
############################################################################################# | ||
# | ||
test.start( "Keep going" ) | ||
|
||
sw.generate_depth_and_color( 2, sw.gap_d * 2 ) | ||
sw.expect( depth_frame = 2, color_frame = 2, nothing_else = True ) # frameset 2 | ||
|
||
test.finish() | ||
# | ||
############################################################################################# | ||
# | ||
test.start( "Stop giving color; nothing output" ) | ||
|
||
sw.generate_depth_frame( 3, sw.gap_d * 3 ) | ||
|
||
# The depth frame will be kept in the syncer, and never make it out (no matching color frame | ||
# and we're not going to push additional frames that would cause it to eventually flush): | ||
# | ||
sw.expect_nothing() | ||
# | ||
# ... BUT the file should still have it! | ||
|
||
test.finish() | ||
# | ||
############################################################################################# | ||
# | ||
test.start( "Dump the file" ) | ||
|
||
recorder.pause() | ||
recorder = None # otherwise the file will be open when we exit | ||
log.d( "filename=", filename ) | ||
sw.stop() | ||
sw.reset() | ||
# | ||
# Dump it... should look like: | ||
# [Depth/0 #0 @0.000000] | ||
# [Color/1 #0 @0.000000] | ||
# [Depth/0 #1 @16.666667] | ||
# [Color/1 #1 @16.666667] | ||
# [Depth/0 #2 @33.333333] | ||
# [Color/1 #2 @33.333333] | ||
# [Depth/0 #3 @50.000000] <--- the frame that was "lost" | ||
# | ||
import subprocess, sys | ||
for p in sys.path: | ||
rs_convert = os.path.join( p, 'rs-convert.exe' ) | ||
if os.path.isfile( rs_convert ): | ||
subprocess.run( [rs_convert, '-i', filename, '-T'], | ||
stdout=None, | ||
stderr=subprocess.STDOUT, | ||
universal_newlines=True, | ||
timeout=10, | ||
check=True ) | ||
break | ||
|
||
test.finish() | ||
# | ||
############################################################################################# | ||
# | ||
test.start( "Play it back, with syncer -- lose last frame" ) | ||
|
||
sw.playback( filename ) | ||
sw.start() | ||
|
||
sw.expect( depth_frame = 0 ) # syncer doesn't know about color yet | ||
sw.expect( color_frame = 0 ) # less than next expected of D | ||
sw.expect( depth_frame = 1, color_frame = 1 ) | ||
sw.expect( depth_frame = 2, color_frame = 2 ) | ||
|
||
# We know there should be another frame in the file: | ||
# [Depth/0 #3 @50.000000] | ||
# ... but the syncer is keeping it inside, waiting for a matching color frame, and does not | ||
# know that we've reached the EOF. There is a flush when we reach the EOF, but not on the | ||
# syncer -- the playback device knows not that its client is a syncer! | ||
# | ||
#sw.expect( depth_frame = 3 ) | ||
sw.expect_nothing() | ||
# | ||
# There is no API to flush the syncer, but it can easily be added. Or we can implement a | ||
# special frame type, an "end-of-file frame", which would cause the syncer to flush... | ||
|
||
sw.stop() | ||
sw.reset() | ||
|
||
test.finish() | ||
# | ||
############################################################################################# | ||
# | ||
test.start( "Play it back, without syncer -- and now expect the lost frame" ) | ||
|
||
sw.playback( filename, use_syncer = False ) | ||
sw.start() | ||
|
||
sw.expect( depth_frame = 0 ) # none of these is synced (no syncer) | ||
sw.expect( color_frame = 0 ) | ||
sw.expect( depth_frame = 1 ) | ||
sw.expect( color_frame = 1 ) | ||
sw.expect( depth_frame = 2 ) | ||
sw.expect( color_frame = 2 ) | ||
|
||
# This line is the difference from the last test: | ||
# | ||
sw.expect( depth_frame = 3 ) | ||
|
||
sw.expect_nothing() | ||
sw.stop() | ||
sw.reset() | ||
|
||
test.finish() | ||
# | ||
############################################################################################# | ||
test.print_results_and_exit() |