Can not trigger "on-receiving-rtcp" event to get RTCP packet

Max Weng zhiyong.weng at gmail.com
Sun May 21 07:27:41 UTC 2023


Hi,

    I am currently exploring the possibilities of using GStreamer for a
project, a territory that is relatively new to me. I am convinced, however,
that GStreamer is an ideal fit for my objectives.

The task at hand is to extract server timestamps from RTCP packets. For
this, I referred to the article, Absolute Timestamp of Arbitrary Frame in
RTSP Stream with GStreamer
<https://medium.com/@Qorela/absolue-timestamp-of-arbitrary-frame-in-rtsp-stream-with-gstreamer-5a98c3057843>

  I have been running into some difficulties during the implementation
phase.

I am experiencing an inconsistent triggering of the "on-receiving-rtcp"
event. It appears to get activated only sporadically, approximately once in
every 20 attempts. This inconsistency makes it challenging for me to
proceed effectively with the project.

In addition, an error message always presents itself: "Element manager
already has a pad named recv_rtcp_sink_0, the behaviour of
gst_element_get_request_pad() for existing pads is undefined!". This error
is making the situation even more complex to understand and resolve.

I would truly appreciate it if you could provide some insights or
suggestions regarding these issues. I am eager to understand what might be
causing these problems, and how best to address them.

  *here is my code test_gstreamer.py:*

import datetime
import pickle
from multiprocessing.connection import Connection
import threading

from time import sleep
import gi
from log import setup_custom_logger

gi.require_version("Gst", "1.0")
gi.require_version("GstRtp", "1.0")
gi.require_version("GstVideo", "1.0")

from gi.repository import GLib, GObject, Gst, GstRtp, GstVideo #
noqa:F401,E402

logger = setup_custom_logger(__name__)

GObject.threads_init()
Gst.init()

url = 'rtsp://localhost:8554/mystream'
pipeline = ''


def fly():
main_loop = GLib.MainLoop()
main_loop_thread = threading.Thread(target=main_loop.run)
main_loop_thread.start()
command = f"rtspsrc name=rtspsrc location={url} protocols=tcp latency=10
max-rtcp-rtp-time-diff=10 ! errorignore ! rtph265depay name=depay ! appsink
name=sink"
pipeline = Gst.parse_launch(command)
bus = pipeline.get_bus()
bus.add_signal_watch()
bus.connect("message", on_message)
bus.enable_sync_message_emission()

rtspsrc = pipeline.get_by_name("rtspsrc")
rtspsrc.connect("new-manager", on_new_manager)
depay = pipeline.get_by_name("depay")
sinkpad = depay.get_static_pad("sink")
probeID = sinkpad.add_probe(
Gst.PadProbeType.BUFFER, calculate_timestamp)

pipeline.set_state(Gst.State.PLAYING)

try:
while True:
sleep(0.1)
except KeyboardInterrupt:
pass

pipeline.set_state(Gst.State.NULL)
main_loop.quit()
main_loop_thread.join()


def calculate_timestamp(pad, info):
return Gst.PadProbeReturn.OK


def on_new_manager(rtspsrc, manager):
logger.info(f"on_new_manager")
sinkpad = manager.get_request_pad("recv_rtcp_sink_0")
session = manager.emit("get-internal-session", 0)
session.connect("on-receiving-rtcp", on_receive_rtcp)


def on_receive_rtcp(session, buffer: Gst.Buffer):
logger.info("on_receive_rtcp")
logger.info(buffer)
rtcp_buffer = GstRtp.RTCPBuffer()
res = GstRtp.RTCPBuffer.map(buffer, Gst.MapFlags.READ, rtcp_buffer)
rtcp_packet = GstRtp.RTCPPacket()
rtcp_buffer.get_first_packet(rtcp_packet)

while True:
if rtcp_packet.get_type() == GstRtp.RTCPType.SR:
logger.info(rtcp_packet)
si = rtcp_packet.sr_get_sender_info()
ntp_time = si[1]
rtp_time = si[2]
logger.info("ntp_time: %d, rtp_time: %d", ntp_time, rtp_time)
if rtcp_packet.move_to_next() == False:
break


def on_message(bus: Gst.Bus, message: Gst.Message):
mtype = message.type
# TODO handle message


if __name__ == "__main__":
fly()


*here is how I run a local RSTP server:*

$ docker run --rm -it --network=host aler9/rtsp-simple-server
$ while true; do gst-launch-1.0 rtspclientsink name=s
location=rtsp://localhost:8554/mystream
 filesrc location=//path/to/video.mp4
 ! qtdemux name=d d.video_0 ! queue ! s.sink_0 d.audio_0 ! queue !
s.sink_1 ; done


*here is the output from my code, no "on-receiving-rtcp" triggered:*

$ python test_gstreamer.py
test_gstreamer.py:19: PyGIDeprecationWarning: Since version 3.11,
calling threads_init is no longer needed. See:
https://wiki.gnome.org/PyGObject/Threading
  GObject.threads_init()
2023-05-21 15:05:06,467 - __main__ - INFO - on_new_manager

(python:96503): GStreamer-CRITICAL **: 15:05:06.469: Element manager
already has a pad named recv_rtcp_sink_0, the behaviour of
gst_element_get_request_pad() for existing pads is undefined!


*here is output with "on-receiving-rtcp" triggered:*

$ python test_gstreamer.py
test_gstreamer.py:19: PyGIDeprecationWarning: Since version 3.11,
calling threads_init is no longer needed. See:
https://wiki.gnome.org/PyGObject/Threading
  GObject.threads_init()
2023-05-21 15:05:10,382 - __main__ - INFO - on_new_manager

(python:96548): GStreamer-CRITICAL **: 15:05:10.384: Element manager
already has a pad named recv_rtcp_sink_0, the behaviour of
gst_element_get_request_pad() for existing pads is undefined!
2023-05-21 15:05:11,730 - __main__ - INFO - on_receive_rtcp
2023-05-21 15:05:11,730 - __main__ - INFO - <Gst.Buffer object at
0x7fbf3a6918e0 (GstBuffer at 0x166cc60)>
2023-05-21 15:05:11,732 - __main__ - INFO - <GstRtp.RTCPPacket object
at 0x7fbf39c49860 (void at 0x7fbf2c08b390)>
2023-05-21 15:05:11,732 - __main__ - INFO - ntp_time:
16723062952823484284, rtp_time: 4125066893
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/gstreamer-devel/attachments/20230521/a26674b5/attachment.htm>


More information about the gstreamer-devel mailing list