Hi Team,
Below code calculates absolute timestamp of RTSP frame from RTP and RTCP frames for remote stream. I want to calculate the same using local .mp4 video. So I want to modify the code to start using filesrc instead of rtspsrc but when I make this change then the code is not working. What changes do you suggest to make in this code.
Thanks and regards,
Kartik Choudhary
Source Code:
import gi
from gi.repository import GObject, Gst, GstRtp
gi.require_version('Gst', '1.0')
GObject.threads_init()
Gst.init(None)
ntp_time = 0 # Initialize NTP time
rtp_time = 0 # Initialize RTP time
class TimeValue:
def __init__(self):
self.tv_sec = 0
self.tv_usec = 0
def convert_ntp_to_datetime(self, ntp_timestamp):
if ntp_timestamp>0:
ntp_seconds, ntp_fraction = divmod(ntp_timestamp, 2**32)
# Calculate the seconds and microseconds
self.tv_sec = ntp_seconds - 2208988800 # Subtract the NTP epoch offset
self.tv_usec = (ntp_fraction * 1000000) // 2**32
time_value_instance = TimeValue()
def on_new_manager_callback(rtspsrc, manager):
sinkpad = manager.get_request_pad("recv_rtcp_sink_0")
session = manager.emit("get-internal-session", 0)
session.connect_after("on-receiving-rtcp", on_receiving_rtcp_callback)
def on_receiving_rtcp_callback(session, buffer: Gst.Buffer):
global ntp_time, rtp_time
rtcp_buffer = GstRtp.RTCPBuffer()
res = GstRtp.RTCPBuffer.map(buffer, Gst.MapFlags.READ, rtcp_buffer)
rtcp_packet = GstRtp.RTCPPacket()
new_packet = rtcp_buffer.get_first_packet(rtcp_packet)
while True:
if rtcp_packet.get_type() == GstRtp.RTCPType.SR:
si = rtcp_packet.sr_get_sender_info()
ntp_time = si[1]
rtp_time = si[2]
if rtcp_packet.move_to_next() == False:
break
def calculate_timestamp(pad, info):
global ntp_time, rtp_time
res, rtpBuff = GstRtp.RTPBuffer.map(info.get_buffer(), Gst.MapFlags.READ)
time_value_instance.convert_ntp_to_datetime(ntp_time)
rtp_diff = float(rtpBuff.get_timestamp() - rtp_time) / 90000.0
timestamp = float(time_value_instance.tv_sec) + float(time_value_instance.tv_usec) / 1000000.0 + rtp_diff
marker_bit = rtpBuff.get_marker()
# In case multiple RTP packets arriving with same timestamp for single video frame, for the last frame the marker
# bit is set to True to indicate complete video frame is recieved
if marker_bit:
print(f"timestamp: {timestamp}, NTP in SR: {ntp_time}, RTP in SR: {rtp_time}, time in RTP header: {rtpBuff.get_timestamp()}, marker bit:{marker_bit}")
return Gst.PadProbeReturn.OK
pipeline_str = "rtspsrc name = rtspsrc location=rtsp://<username>:<password>@<ipAddress>/stream0 ! rtph264depay name=depay ! appsink name=sink"
pipeline = Gst.parse_launch(pipeline_str)
if pipeline:
rtspsrc = pipeline.get_by_name('rtspsrc')
if rtspsrc:
rtspsrc.connect("new-manager", on_new_manager_callback)
depay = pipeline.get_by_name('depay')
sinkpad = depay.get_static_pad('sink')
probID = sinkpad.add_probe(Gst.PadProbeType.BUFFER, calculate_timestamp)
pipeline.set_state(Gst.State.PLAYING)
try:
loop = GObject.MainLoop()
loop.run()
except KeyboardInterrupt:
pipeline.set_state(Gst.State.NULL)
else:
print("rtspsrc is Null...")
else:
print("Pipleline is Null...")