Deepstream python apps: How to get fpsdisplaysink "last-message" property to display current, avg fps?

•Jetson Nano
•DeepStream 6.0
•JetPack 4.6
•TensorRT 8.0.1.6
•CUDA 10.2.300

Hi I have a question for deepstream python apps. I am trying to use fpsdisplaysink to get current fps, avg fps etc. and I have modified the sample code for example deepstream_test_1.py to add fpsdisplaysink into the pipeline and use EGL sink as video-sink

    print("Creating EGLSink \n")
    videosink = Gst.ElementFactory.make("nveglglessink", "nvvideo-renderer")
    if not videosink:
        sys.stderr.write(" Unable to create egl sink \n")

    # Create FPS display sink
    sink = Gst.ElementFactory.make("fpsdisplaysink", "fps-display")
    if not sink:
        sys.stderr.write(" Unable to create fpssink \n")
    sink.set_property('video-sink', videosink)    
    sink.set_property('text-overlay', False)
    sink.set_property('signal-fps-measurements', True)
    sink.set_property('sync', False)

My question is, how do I get and print the “last-message” property of fpsdisplaysink in the osd_sink_pad_buffer_probe function? So far I’ve only found a solution in C but not in python.

Hi,
There is a python sample of registering callback functions:
GstreamerCodeSnippets/basic-tutorial-8.py at master · rubenrua/GstreamerCodeSnippets · GitHub

Please check and see if it helps.

Hi DaneLLL, thank you for the reply. I couldn’t find a way to solve my problem after looking through the sample codes you provided. I opted to ditch fpsdisplaysink to get current and average fps by using this solution and modified it slightly instead.
It is a shame that I couldn’t get fpsdisplay sink to work and get information such as dropped rate and such, but if anyone interested in my solution of getting current and average fps in deepstream python apps:

My FPS.py in the common folder looks like this:

import time
start_time=time.time()
frame_count=0

class GETFPS:
    def __init__(self,stream_id):
        global start_time
        self.start_time=start_time
        self.is_first=True
        global frame_count
        self.frame_count=frame_count
        self.stream_id=stream_id
    def print_data(self):
        print('frame_count=',self.frame_count)
        print('start_time=',self.start_time)
    def calc_fps(self):
        end_time=time.time()
        elapsed_time = end_time - self.start_time
        current_fps = 1.0/float(elapsed_time)
        self.start_time=end_time
        return current_fps

Then, I import it to e.g. deepstream_test_1.py and declare these empty lists

from common.FPS import GETFPS

fps_streams={}
fpsarray=[]

in def osd_sink_pad_buffer_probe(pad,info,u_data) I modified the code as such:

        # Acquiring a display meta object. The memory ownership remains in
        # the C code so downstream plugins can still access it. Otherwise
        # the garbage collector will claim it when this probe function exits.
        display_meta=pyds.nvds_acquire_display_meta_from_pool(batch_meta)
        display_meta.num_labels = 1
        py_nvosd_text_params = display_meta.text_params[0]
        
        # FPS Counter
        # Get frame rate through this probe
        fps = fps_streams["stream{0}".format(frame_meta.pad_index)].calc_fps()
        fpsarray.append(fps)
        fps = "%.1f"%(fps)
        avg = "%.1f"%(sum(fpsarray)/len(fpsarray))

        # Setting display text to be shown on screen
        # Note that the pyds module allocates a buffer for the string, and the
        # memory will not be claimed by the garbage collector.
        # Reading the display_text field here will return the C address of the
        # allocated string. Use pyds.get_string() to get the string content.
        py_nvosd_text_params.display_text = "FPS={} Avg FPS={} Frame Number={}\nNumber of Objects={} Vehicle_count={} Person_count={}".format(fps, avg, frame_number, num_rects, obj_counter[PGIE_CLASS_ID_VEHICLE], obj_counter[PGIE_CLASS_ID_PERSON])

and put this code at the beginning of def main(args)

for i in range(0,len(args)-1):
        fps_streams["stream{0}".format(i)]=GETFPS(i)
    number_sources=len(args)-1

And this is a screenshot of how the display text looks like
image