Hi all,
We had some trouble when trying to get video frame from simulated drone from Sphinx. In the official example of streaming.py (https://github.com/Parrot-Developers/olympe/blob/master/src/olympe/doc/examples/streaming.py)
I printed out all the steps, and found out yuv_frame_cb
is invoked after self.drone.streaming.start()
.
But, the exact same code dose invoke yuv_frame_cb
in our ROS interface. There are the relevant snippets.
self.drone.streaming.set_callbacks(
raw_cb=self.yuv_frame_cb,
h264_cb=self.h264_frame_cb,
start_cb=self.start_cb,
end_cb=self.end_cb,
flush_raw_cb=self.flush_cb,
)
# Start video streaming
self.drone.streaming.start()
self.renderer = PdrawRenderer(pdraw=self.drone.streaming)
self.running = True
self.processing_thread.start()
# print("try calling yuv_frame_processing directly")
# self.yuv_frame_processing()
def h264_frame_cb(self, h264_frame):
"""
This function will be called by Olympe for each new h264 frame.
:type yuv_frame: olympe.VideoFrame
"""
# Get a ctypes pointer and size for this h264 frame
frame_pointer, frame_size = h264_frame.as_ctypes_pointer()
# For this example we will just compute some basic video stream stats
# (bitrate and FPS) but we could choose to resend it over an another
# interface or to decode it with our preferred hardware decoder..
# Compute some stats and dump them in a csv file
info = h264_frame.info()
frame_ts = info["ntp_raw_timestamp"]
if not bool(info["is_sync"]):
while len(self.h264_frame_stats) > 0:
start_ts, _ = self.h264_frame_stats[0]
if (start_ts + 1e6) < frame_ts:
self.h264_frame_stats.pop(0)
else:
break
self.h264_frame_stats.append((frame_ts, frame_size))
h264_fps = len(self.h264_frame_stats)
h264_bitrate = 8 * sum(map(lambda t: t[1], self.h264_frame_stats))
self.h264_stats_writer.writerow({"fps": h264_fps, "bitrate": h264_bitrate})
def start_cb(self):
pass
def end_cb(self):
pass
# this function will be called by Olympe for each decoded YUV frame
def yuv_frame_cb(self, yuv_frame):
print("entering yuv_frame_cb")
yuv_frame.ref()
print('ok1')
if self.frame_queue.full():
print('ok2')
self.frame_queue.get_nowait().unref()
print('ok3')
self.frame_queue.put_nowait(yuv_frame)
print('ok4')
def flush_cb(self, stream):
if stream["vdef_format"] != olympe.VDEF_I420:
return True
while not self.frame_queue.empty():
self.frame_queue.get_nowait().unref()
return True
def yuv_frame_processing(self):
print("yuv_frame_processing")
while self.running:
try:
yuv_frame = self.frame_queue.get(timeout=0.1)
except queue.Empty:
print("empty frame, continue")
self.yuv_frame_cb
continue