The send path in rtpsession processes the buffer list along the way,
sharing info and stats between packets in the same list, because it
assumes that all packets in a buffer list are from the same frame.
However, in the receiving path packets can arrive in all sorts of
arrangements:
- different sources,
- different frames (different timestamps),
- different types (multiplexed RTP and RTCP, invalid RTP packets).
so a more general approach should be used to correctly support buffer
lists in the receive path.
It turns out that it's simpler and more robust to process buffers
individually inside the rtpsession element even if they come in a buffer
list, and then reassemble a new buffer list when pushing the buffers
downstream.
This avoids complicating the existing code to make all functions
buffer-list-aware with the risk of introducing regressions,
To support buffer lists in the receive path and reduce the "push
overhead" in the pipeline, a new private field named processed_list is
added to GstRtpSessionPrivate, it is set in the chain_list handler and
used in the process_rtp callback; this is to achieve the following:
- iterate over the incoming buffer list;
- process the packets one by one;
- add the valid ones to a new buffer list;
- push the new buffer list downstream.
The processed_list field is reset before pushing a buffer list to be on
the safe side in case a single buffer was to be pushed by upstream
at some later point.
NOTE:
The proposed modifications do not change the behavior of the send path.
The process_rtp callback is called in rtpsource.c by the push_rtp
callback (via source_push_rtp) only when the source is not internal.
So even though push_rtp is also called in the send path, it won't end up
using process_rtp in this case because the source would be internal in
the send path.
The reasoning from above may suggest a future refactoring: push_rtp
might be split to better differentiate the send and receive path.
One comments in gst_rtp_session_chain_send_rtp_common() is referring to
groups in a buffer list, however this concept of "group" comes from
GStreamer 0.10 and does not exist anymore in GStreamer 1.0, so update the
comment to refer to buffers instead.
Some functions now accept a generic 'gpointer data' parameter because
they can work either on a single buffer or a buffer list.
However the comments were still referring to the old 'GstBuffer *buffer'
parameter, so update the comments to match the actual functions
signature.
So far we assumed that if all sources are bye, this meant we needed to
send an EOS on the RTCP sink. The problem is that this case may happens
if we only had one internal source and it detected a collision.
So now we limit the EOS forwarding to when there is a send_rtp_sink pad
and that this pad has received EOS. We don'tcheck the recv_rtp_sink
since the code does not wait for the bye to be send before sending EOS
to the RTCP src pad.
Reset RTPSession when rtpsession changes state from PAUSED to READY.
Without this change, a stored last_rtptime in RTPSource could interfere
with RTP timestamp generation in RTCP Sender Report.
Fixes#510
Always wait with starting the RTCP thread until either a RTP or RTCP
packet is sent or received. Special handling is needed to make sure the
RTCP thread is started when requesting an early RTCP packet.
We want to wait with starting the RTCP thread until it's needed in order
to not send RTCP packets for an inactive source.
https://bugzilla.gnome.org/show_bug.cgi?id=795139
Instead of sending EOS when a source byes we have to wait for
all the sources to be gone, which means they already sent BYE and
were removed from the session. We now handle the EOS in the rtcp
loop checking the amount of sources in the session.
https://bugzilla.gnome.org/show_bug.cgi?id=773218
Add statitics from each rtp source to the rtp session property.
'source-stats' is a GValueArray where each element is a GstStructure of
stats for one rtp source.
The availability of new stats is signaled via g_object_notify.
https://bugzilla.gnome.org/show_bug.cgi?id=752669
The new property allows to select the time source that should be used for the
NTP time in RTCP packets. By default it will continue to calculate the NTP
timestamp (1900 epoch) based on the realtime clock. Alternatively it can use
the UNIX timestamp (1970 epoch), the pipeline's running time or the pipeline's
clock time. The latter is especially useful for synchronizing multiple
receivers if all of them share the same clock.
If use-pipeline-clock is set to TRUE, it will override the ntp-time-source
setting and continue to use the running time plus 70 years. This is only kept
for backwards compatibility.
And modify our RTCP scheduling algorithm accordingly. We now can send more
RTCP packets if needed for feedback, but will throttle full RTCP packets by
rtcp-min-interval (t-rr-int from RFC4585).
In non-feedback mode, rtcp-min-interval is Tmin from RFC3550, which is
statically set to 1s or 0s by RFC4585. Tmin defines how often we should
send RTCP packets at most.
https://bugzilla.gnome.org/show_bug.cgi?id=746543
Make sure that the sync_src pad has caps before the segment event.
Otherwise we might get a segment event before caps from the receive
RTCP pad, and then later when receiving RTCP packets will set caps.
This will results in a sticky event misordering warning
This fixes warnings in the rtpaux unit test but also in the
rtpaux and rtx examples in tests/examples/rtp
https://bugzilla.gnome.org/show_bug.cgi?id=746445
Before we only started it when either:
- there is no send RTP stream
or
- we received an RTP packet for sending
This could mean that if the send RTP pads are connected but never receive any
RTP data, and the same session is also used for receiving RTP/RTCP, we would
never start the RTCP thread and would never send RTCP for the receiving part
of the session.
This can be reproduced with a pipeline like:
gst-launch-1.0 rtpbin name=rtpbin \
udpsrc port=5000 ! "application/x-rtp, media=video, clock-rate=90000, encoding-name=H264" ! rtpbin.recv_rtp_sink_0 \
udpsrc port=5001 ! rtpbin.recv_rtcp_sink_0 \
rtpbin.send_rtcp_src_0 ! fakesink name=rtcp_fakesink silent=false async=false sync=false \
rtpbin.recv_rtp_src_0_2553225531_96 ! decodebin ! xvimagesink \
fakesrc ! valve drop=true ! rtpbin.send_rtp_sink_0 \
rtpbin.send_rtp_src_0 ! fakesink name=rtp_fakesink silent=false async=false sync=false -v
Before this change the rtcp_fakesink would never send RTCP for the receiving
part of the session (i.e. no receiver reports!), after the change it does.
And before and after this change it would send RTCP for the receiving part of
the session if the sender part was omitted (the last two lines).
They are very confusing for people, and more often than not
also just not very accurate. Seeing 'last reviewed: 2005' in
your docs is not very confidence-inspiring. Let's just remove
those comments.
When the internal-ssrc property changes, we want to send a reconfigure
upstream to make payloaders use the new suggested ssrc.
Using the internal-ssrc property to change the SSRC of a stream is not a
good idea and doesn't work when there are multiple senders, we want to
set the SSRC directly on the payloaders. Therefore, deprecate this
property.
Fixes https://bugzilla.gnome.org/show_bug.cgi?id=725361
recv_rtp_sink: allow proxying of the allocation query.
send_rtp_sink: allow proxying of caps and allocation. This allows us to
query caps downstream as well as get an allocator from downstream.
send_rtp_src: allow proxy of caps, this makes the caps query do
upstream.
See https://bugzilla.gnome.org/show_bug.cgi?id=723850
When a collision is found on the internal ssrc, we have to change it.
Ideally, we want also the payloader upstream to follow this change and use
the new internal ssrc. Ideally we want this condition to be always met:
if there is one payloader sending on this session, its ssrc should match the
internal ssrc.