You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
168 lines
5.1 KiB
168 lines
5.1 KiB
# 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)
|
|
|
|
# D C @timestamp comment
|
|
# -- -- ----------- ----------------
|
|
# 0 @0 so next expected frame timestamp is at 0+16.67
|
|
# 0 @0
|
|
#
|
|
sw.generate_depth_and_color( frame_number = 0, timestamp = 0 )
|
|
sw.expect( depth_frame = 0 ) # syncer doesn't know about C yet, so releases right away
|
|
sw.expect( color_frame = 0, nothing_else = True ) # no hope for a match: D@0 is already out, so it's released
|
|
#
|
|
# NOTE: if the syncer queue wasn't 100 (see above) then we'd only get the color frame!
|
|
# (it will output D to the queue, then C to the queue, but the queue size is 1 so we lose D)
|
|
#
|
|
# 1 @16
|
|
# 1 @16
|
|
#
|
|
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" )
|
|
|
|
# 2 @33
|
|
# 2 @33
|
|
#
|
|
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" )
|
|
|
|
# 3 @50
|
|
#
|
|
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"
|
|
#
|
|
from rspy import repo
|
|
rs_convert = repo.find_built_exe( 'tools/convert', 'rs-convert' )
|
|
if rs_convert:
|
|
import subprocess
|
|
subprocess.run( [rs_convert, '-i', filename, '-T'],
|
|
stdout=None,
|
|
stderr=subprocess.STDOUT,
|
|
universal_newlines=True,
|
|
timeout=10,
|
|
check=False ) # don't fail on errors
|
|
else:
|
|
log.w( 'no rs-convert was found!' )
|
|
import sys
|
|
log.d( 'sys.path=\n ' + '\n '.join( sys.path ) )
|
|
|
|
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()
|