Can not trigger "on-receiving-rtcp" event to get RTCP packet
Mathieu Duponchelle
mathieu at centricular.com
Tue May 23 10:25:53 UTC 2023
Why are you requesting the pad in the first place?
On Sun, 2023-05-21 at 15:27 +0800, Max Weng via gstreamer-devel wrote:
> 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
>
> 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
>
More information about the gstreamer-devel
mailing list