Hi, I am streaming GMSL camera to a host computer and I record the SVOs using the ROS service calls for starting and stopping SVOs. The params used for streaming is as follows: (ZED SDK: 5.0.1, JP: 6.2, Link driver:1.3.0)
Streaming resolution and FPS: HD1200@60FPS
Bitrate: 0
Compression: H265
The service calls has the following arguments passed:
When we playback the SVOs in the ZED_Explorer we see the following warning
[ZED][WARNING] Frame with index 0 not found in SVO2 file.
The playback functionality cannot be used in the ZED_Explorer when this happens. Attached is a link to the SVO and a screen recording showing the SVO playback issue in ZED_Explorer.
I have analyzed your SVO file and noticed that the frame index appears to be corrupted; all frames seem to have an 860 shift index, which is quite unusual.
Could you provide more details on how you obtained this file? Did you perform any cuts or manipulations on it?
Additionally, do you encounter the same issue when recording an SVO file using ZED Explorer or the ZED SDK sample?
We have not performed any cuts or manipulations on this file. Recording the SVO through the ZED_Explorer works fine for us.
We have our own script to start and stop the SVO recordings (through ROS service calls).
Firstly, we create the clients for the start and stop service servers.
import rclpy
from rclpy.node import Node
from zed_msgs.srv import StartSvoRec
from std_srvs.srv import Trigger
start_client = self.node.create_client(StartSvoRec, start_service)
stop_client = self.node.create_client(Trigger, stop_service)
We then have separate functions to start and stop the SVO recording:
def start_recording(self, svo_filename: str):
if not self.start_client.wait_for_service(timeout_sec=5.0):
self.node.get_logger().error(
f"[{self.cam_name}] Start service not available!"
)
return
req = StartSvoRec.Request()
req.svo_filename = svo_filename
req.compression_mode = 0 # H.265
req.input_transcode = False
req.target_framerate = 60
future = self.start_client.call_async(req)
while not future.done() and rclpy.ok():
rclpy.spin_once(self.node, timeout_sec=0.1)
result = future.result()
if result and result.success:
self.node.get_logger().info(f"[{self.cam_name}] SVO recording started.")
else:
self.node.get_logger().error(
f"[{self.cam_name}] Failed to start SVO recording."
)
def stop_recording(self):
if not self.stop_client.wait_for_service(timeout_sec=2.0):
self.node.get_logger().error(
f"[{self.cam_name}] Stop service not available!"
)
return
req = Trigger.Request()
future = self.stop_client.call_async(req)
while not future.done() and rclpy.ok():
rclpy.spin_once(self.node, timeout_sec=0.1)
result = future.result()
if result and result.success:
self.node.get_logger().info(f"[{self.cam_name}] SVO recording stopped.")
else:
self.node.get_logger().error(
f"[{self.cam_name}] Failed to stop SVO recording."
)
We initialize the clients once for the camera, and we run the start_recording and stop_recording in a loop with some time between the start and the stop calls.
I updated my SDK version to 5.0.2 and performed the above operations again. I still face the same Frame with index 0 not found in SVO2 file warning when I open the recording using ZED_Explorer. The playback slider also does not work in such cases. Do you have any suggestions/thoughts on why this happens?
I am wondering if you have any updates for me. I have made a simple script that will help you generate the files that have the Frame with index 0 not found warning.
Here is the script:
import rclpy
import time
from pathlib import Path
from datetime import datetime
from rclpy.node import Node
from zed_msgs.srv import StartSvoRec
from std_srvs.srv import Trigger
class CameraObject:
def __init__(
self,
node: Node,
cam_name: str,
start_service: str,
stop_service: str,
camera_type: str = "zed"
):
self.node = node
self.cam_name = cam_name
self.camera_type = camera_type
self.start_client = self.node.create_client(StartSvoRec, start_service)
self.stop_client = self.node.create_client(Trigger, stop_service)
def start_recording(self, svo_filename: str):
req = StartSvoRec.Request()
req.svo_filename = svo_filename
req.compression_mode = 0 # H.265
req.input_transcode = False
req.target_framerate = 60
future = self.start_client.call_async(req)
while not future.done() and rclpy.ok():
rclpy.spin_once(self.node, timeout_sec=0.1)
result = future.result()
if result and result.success:
self.node.get_logger().info(f"[{self.cam_name}] SVO recording started.")
return True
else:
self.node.get_logger().error(
f"[{self.cam_name}] Failed to start SVO recording."
)
return False
def stop_recording(self):
req = Trigger.Request()
future = self.stop_client.call_async(req)
while not future.done() and rclpy.ok():
rclpy.spin_once(self.node, timeout_sec=0.1)
result = future.result()
if result and result.success:
self.node.get_logger().info(f"[{self.cam_name}] SVO recording stopped.")
return True
else:
self.node.get_logger().error(
f"[{self.cam_name}] Failed to stop SVO recording."
)
return False
class EpisodeRecorder:
def __init__(self, node, camera_config):
self.node = node
self.camera_objects = {
name: CameraObject(
node=node,
cam_name=name,
start_service=cfg["start"],
stop_service=cfg["stop"]
)
for name, cfg in camera_config.items()
}
def start_episode(self, episode_dir: Path):
episode_dir.mkdir(parents=True, exist_ok=True)
self.node.get_logger().info(f"Starting episode: {episode_dir}")
for name, cam in self.camera_objects.items():
svo_path = episode_dir / f"{name}.svo2"
success = cam.start_recording(str(svo_path))
if not success:
self.node.get_logger().warning(f"Skipping {name} due to failure.")
def end_episode(self):
for name, cam in self.camera_objects.items():
success = cam.stop_recording()
if not success:
self.node.get_logger().warning(f"Could not stop {name} properly.")
def main():
rclpy.init()
node = rclpy.create_node("episode_recorder")
camera_config = {
"cam1": {
"start": "/sensors/cam1/start_svo_rec",
"stop": "/sensors/cam1/stop_svo_rec"
},
# "cam2": {
# "start": "/sensors/cam2/start_svo_rec",
# "stop": "/sensors/cam2/stop_svo_rec"
# },
}
recorder = EpisodeRecorder(node, camera_config)
for i in range(4):
date_str = datetime.now().strftime("%H-%M-%S")
episode_dir = Path("episodes").expanduser() / date_str
recorder.start_episode(episode_dir)
time.sleep(4)
recorder.end_episode()
node.get_logger().info("Episode complete.")
rclpy.shutdown()
if __name__ == "__main__":
main()
Simply change the name of the start and stop svo service call names in the camera_config dict on line 101.
To reproduce the error:
Stream GMSL camera (I have zedxm) to a host computer.
On host, launch the camera using the zed-ros-wrapper.
Then run the script I attached above.
Try visualizing the generated SVOs using ZED_Explorer, you should see the warning.
Please let me know if you need any more information from my end. I look forward to hearing from you.
Hello, I am checking in to see if you have any updates on the issue.
I am hoping to make successive ROS service calls and I am having a hard time getting reliable SVO recordings.
I have shared the script that I have used to make those calls in the forum post. Please let me know if you need anything else from my end to replicate the issue.
One additional thing to add, the Frame with index 0 not found in SVO2 file issue is only observed when the input_transcode is set to False.
If the input_transcode is set to True, I don’t see the Frame with index 0 ... warning but sometimes the StopSvoRec service does not return a response even though the recording is stopped. So both transcode options have some error in the recording process.
Ideally, I would prefer to avoid decoding and re-encoding the stream into an .svo file.
The two sources (here and here) of information for input_transcode seem to have contradictory information. What should my input_transcode be if I intend to avoid decoding and re-encoding the stream.