Retransmission of datapackets being streamed using gstreamer over RTP - gstreamer

Established: I am currently streaming data packets(.mp3 files) from source(server) to sink(client A) using gstreamer over RTP. This thing is pretty easy and I am successfully able to stream music over a network from server to device.
Requirement: Now, I want to retransmit the data packets in real time(or atleast as close to real time as possible) from the client A to say any other client B . Hence the control would still remain with client A and only the music would now be actually streaming with client B.
What is the most optimum way to do such a thing.

Assuming you want to quickly try this. The ideal way is to setup a rtsp server on client A which can forward client B data. If you want to do it your way here is one way to do it:
If you have a player in client B which can play a rtp stream given a sdp file this is what you can do:
Create a copy of the sdp you get in client A. Give it to client B via some path. [Say tcp socket that both agree to communicate upon]
Stream a copy of what you get in client A to client B as well.
You need to change port numbers in sdp to be the one available at client B [This what RTSP negotiation does]. If the client B can tell client A the port number before it gets the SDP, great, you can then set the port number in the sdp correctly, give it to client B and then send a copy of he stream to client B. you are done.

you also uset RTP over TCP.
So it would be easy for you, as no changes require at RTP level.
You need to pass packet to RTSP instead of sending directly over UDP socket.
everything will be handle by RTSP.
If you are using RTP as a stand alone ,accoeding to rfc 3550 , its not a part of RTP
Still you wan't to do so, then you are not following standard way of RTP implementation.

Related

Does the client have to query the server for each new piece of data in RTSP communication?

I'm trying to figure out how RTSP works, when the handshake is complete.
Does the client have to query the server for each new piece of data? Or the server sends data all the time and doesn't care how the client receives the data?
The reason why I ask this is my Gstreamer pipeline receiving RTSP stream from IP camera:
uridecodebin -> nvstreammux -> queue1 -> nvinfer -> queue2 -> fakesink
The IP camera has 30FPS but the nvinfer element can process only 10FPS. So I assumed that pending frames are stored in queue1 element waiting to be processed. However the current number of buffers of the queue1 is 1 all the time.
So one possible answer is that frames or packets are queued in one of the elements of uridecodebin element, but I did not find any such element there. Next it can mean that the IP camera was informed by uridecodebin to decrease FPS. Or if the uridecodebin element has to ask for each new piece of data, it just means that it asks for new data only when all frames are processed in the pipeline.
Do you have any idea?
First it is worth mentioning that RTSP is a control protocol - the actual video media is usually sent over RTP protocol in most 'RTSP' video streaming cases.
RTSP is a streaming control protocol, to control streaming servers (whoami's remote control analogy here is nice: https://stackoverflow.com/a/43045354/334402) It defines how to package data to stream it and how both ends of the connection should behave to support the protocol.
So RTSP does not actually transport the media data itself - as mentioned above it is usually RTP (Real Time Transport) that does this.
Back to your question - RTCP and RTP can be transferred over UDP or TCP in IP Networks. In the former case, a socket is opened a stream established and the client can sit back and wait for the packets to arrive. In the latter case, the client requests each packet as you outline.
In practice you will likely find TCP is more commonly used, even if it is not necessarily the best match for streamed video, because it is more suited to traversing the many firewalls and NAT's on the internet.
In fact it gets more complicated sometimes with the RTSP data interleaved with RTP and RTCP (Real Tine Control Protocol that collects statistics about the flow) packets over TCP - you can see most detail by looking at the IEFT RFC: https://datatracker.ietf.org/doc/html/rfc2326

socket data emiter c++

i'm having some sync trouble with threads and sockets. I need one thread to recive incoming connections on socket (and remember client data to respond) and other thread to setup frames and send current frame to listed clients. So i was wondering if its possible to (kinda) put my data frames into server socket, so that everyone could just read current frame from socket without server knowing.
Server will just spam its socket with some data and client will get data without server actions. Is this possible? how?
I'm currently doing it pretty messed up way which i dont like:
server is listening on one thread for incoming transmissions and upon reciving such, add client data to list.
on other thread server is sending data to all clients from list.
EDIT:
I want to send data to some kind of buffer from which clients are allowed to read. (client doesnt have to read all messages server sends, just the one buffer contains at the moment of clients request), i dont want server to even notice that clients are reading from buffer if possible.
Right now threads are syncronised using uniqe_lock
What you're describing is probably MultiCast. Specifically, IP MultiCast (I think).
Searching finds a number of useful resources. This one looks concise, and includes coded examples (although I'm not sure how current it is).
If you're only transmitting to a LAN then broadcast will work too.

How to send SDP over RTP

I've developed an app which sends RTP packets to a local ip client. So the client has to listen on the specified port (rtp://:#portnumber, on VLC) to play the streamed data. Right now i'm going to develop the code needed to create the SDP file needed to start streaming.
My doubt is, how to send this file to the client? At the beginning of the RTP stream?
Really n00b at this point. Any help will be useful.
Thanks
VLC specifically supports RTSP, HTTP, SAP protocols for establishing session and communication. And of course the local file system (file://)
so basically you can call vlc in some manner like this (I cannot test it but should be like this):
vlc file://path/to/sdp-file
or
vlc rtsp://server-path:port/sdpfile.sdp
and so on
Aside from storing the SDP file in the local system, perhaps HTTP would be easiest if you have up and running http server on your server machine.

How do I apply both RTP and UDP protocols to achieve audio streaming?

How do I write a C++/MFC program to make a server as a bridge for clients to stream their audio? I have been told to use UDP and RTP protocol but due to my lack knowledge of media streaming, I couldn't make it work. What is relationship between UDP and RTP and steps needed for server to listen, accept and handle packet transfer between client to client.
As unwind said, generally RTP runs on top of UDP. It's called a conectionless protocol.
This is the specification of UDP: http://www.ietf.org/rfc/rfc768.txt
An this is the specification of RTP: http://www.ietf.org/rfc/rfc1889.txt
You can find very useful information about RTP on this site. There are different libraries and docs.
It's possible to write a "RTP forwarder" application.
RTP generally runs on top of UDP, to get away from TCP's streaming behavior, TCP always delivers data in-order, which is not optimal for real-time applications.
It might be possible to do a "dumb" forwarder that is not RTP-aware, but instead is configured to e.g. accept UDP packets to port X, and forward all traffic to host:Y, packet by packet. Not sure if that works in practice, though.

RTSP client in android

I am writing a RTSP client in Android. I am able to receive the Responses for all the requests
i.e.,
DESCRIBE it sends back the 200 OK
SETUP with transport: RTP/AVP:unicast:client_port=4568:4569 got the 200 OK Message back
Sent PLAY, and got the OK Message
After that how to get the audio and video frames?
I have searched on blogs, but all say to listen at client_port but I am not receiving any packets.
Please let me know am I doing correctly.
You may or may not know this, but Android has built in support for RTSP using the VideoView.
http://developer.android.com/reference/android/widget/VideoView.html
This may cut down on your development time...or it may be totally useless if you're trying to roll your own RTSP stack.
RTSP is only used to start the streaming. It gives you an SDP description of the real streams. You have to manage an RTCP connection and a RTP connection per channel (audio / video). The ports to use are the "client_port" ones.
It is pretty complex to code a RTSP/RTCP/RTP stack from scratch. You can have a look at the live555 library that implement such a stack in c++.
Put a sniffer on the network, you should see UDP packet with destination port 4568 targeted at your IP address.
With a decent sniffer, you will be able to see the rtsp dialog. Maybe you are missing something in the answers
You should also check the content of the SETUP response, to see if the port you requested were accepted.
Things to check :
Listening in UDP.
Firewall rules.
Range of the play request : Don't specify any to be sure the server will be playing something.
If you are behind a router or firewall, you probably won't receive anything, because your router / firewall don't know what to do with incoming UDP packets
Try first with a local Darwin Streaming server installed within your LAN.that way Firewall wont matter.Streaming will work.
If you want to try from external server then:
1) Check the client_ports mentioned in the SERVER response,some servers suggest different ports from the one requested.you have to use the ports suggested by server.
2) If the ports are correct, then you can send 64byte empty packets from each of the UDP ports to the server(called "door openers").
3) If the above two don't fix it, check the server side logs.The server might be closing the UDP ports.