Creating an RTSP Server using the RTSP Sink

Introduction

An RTSP server can deliver several media streams simultaneously and independently of each other. The server listens for connection requests on a TCP/IP port. An RTSP client (like the LEAD RTSP Source filter) will connect and issue RTSP commands to the server. The most common commands are:

A server needs to respond to each of these commands.

We use the term "media stream" because the media being streamed can be a file or a live stream. The live stream can be from a capture device, or an MPEG-2 Transport stream received over a UDP port, or an RTSP stream from another server. The stream can also be from a DVD image (pretty much anything that can be used to create an output file can also be used as a source media stream for an RTSP folder).

Typically, an RTSP server streams all of the files from a certain folder. Not all the compressions are supported by the RTSP streaming technology, so in some cases the files with incompatible compressions might need to be transcoded on the fly.

Currently, the LEAD RTSP Sink filter supports H264, H265 video compressions and AAC audio compression. Files with different video or audio compressions would have to recompress the video, the audio or both video and audio.

See the "RFC 2326 - Real Time Streaming Protocol (RTSP)" standard for more information on the RTSP specification.

Security

RTSP servers provide a way to restrict access to content to unauthorized users. RTSP servers can optionally use authentication to allow access only to authorized users. The authentication can be Basic or Digest. In either mode, the users would have to enter a user name and password before they can access a media stream. You can use the different authentication methods and give different access rights to each media stream. Or you can make it simple and give the same access rights to any media stream.

High Level Implementation

LEADTOOLS Multimedia contains some high level objects that make it very easy to implement an RTSP server:

Each of these objects allow you to stream all the files from one or more folders. You just need to pick the source folders, customize some parameters like security settings and the timeout, and start listening for connections on a certain TCP/IP address and port. These modules will then stream any file with a corresponding filename that it finds on disk. It will also support .LNK files, which make it possible to redirect files outside the folders in question. So the real media can be outside the source folder, but the .LNK will have to be inside the folder.

Example:

Suppose you want an RTSP server that streams all of the files from "c:\MyFiles", and you want the server to listen on address 127.0.0.1 at port 554 (default RTSP port). The C++ code for a simple server would look like this:

void SetupRTSPServer() 
{ 
   IltmmRTSPServer *pServer; 
   // create the server instance 
   HRESULT hr = CoCreateInstance(CLSID_LMRTSPServer, NULL, CLSCTX_ALL, IID_ILMRTSPServer, (void**)&pServer); 
   // handle the error. Error checking is suppressed here for brevity 
   // specify c:\MyFiles as the source folder 
   pServer->put_SourceFolder(0, L"c:\\MyFiles"); // you can just pass a wide char string if the server is in the same EXE 
   // will listen on 127.0.0.1 
   pServer->put_TargetAddress(L"127.0.0.1"); 
   // start listening on port 554 
   pServer->StartServer(554); 
} 

This server would handle all of the RTSP URLs of this format:

rtsp://127.0.0.1/RelativeURL

As requests to stream the file "c:\MyFiles\RelativeURL". Here are some examples of files you might want to stream and their corresponding URLs:

Case 1: Stream a file from the root of the source folders

Try to connect with the LEAD RTSP Source and stream c:\MyFiles\file1.mpg filter using this URL:

rtsp://127.0.0.1/file1.mpg

When the LEAD RTSP server receives this URL, it will look for file1.mpg in all the source folders. In our case, there is only one folder, so it will look for c:\MyFiles\file1.mpg.

Case 2: Stream a file

You can use the same server to also stream from a live video capture device. All you have to do is run a capture from the video and audio capture that you have and write to a DVR file that you store in c:\Myfiles. The simplest way is to run the DVR demo and set the output file to be something like c:\MyFiles\LiveCapture2.lbl. In this case, you would use the RTSP Source filter to stream the following URL:

rtsp://127.0.0.1/LiveCapture2.lbl

Case 3: Restream an MPEG2 Transport UDP stream

Run the MPEG-2 Transport stream and set its DVR settings to use c:\MyFiles\UDPStream3.lbl. And then use this URL in the RTSP Source filter:

rtsp://127.0.0.1/UDPStream3.lbl

Case 4: Stream a file from a subfolder of the source folders

The server will automatically search in subfolders if a subfolder was specified in the RTSP URL. For example, you might want to keep the DVR files in different subfolders or you just want to reduce the number of files in the root folders.

If you want to stream the file c:\MyFiles\MySubfolder\file4.avi, then you would use this RTSP URL:

rtsp://127.0.0.1/MySubfolder/file4.avi

Note that in this case, the backslash from the source filename is translated into a forward slash in the RTSP URL.

Case 5: Stream a file that is outside the source folders

Let's say you want to stream a file you have on another disk "f:\abc\def.mkv". In this case, you can just create a link called c:\MyFiles\MyLink5.lnk and make it point to f:\abc\def.mkv. You would then use this URL:

rtsp://127.0.0.1/MySubfolder/MyLink5.lnk

This applies to DVDs as well, so you can create a link to d:\VIDEO_TS\VIDEO_TS.IFO called "c:\MyFiles\MyDvd5.lnk" and stream it using this URL:

rtsp://127.0.0.1/MySubfolder/MyDvd5.lnk

In this case, you need to keep in mind that the DVD will be recompressed on the fly and that DVDs take some time to start converting. So you might need to specify a timeout on the RTSP URL to instruct the RTSP filter to wait for the DVD to start converting, This URL would tell it to wait 10s before giving up with a timeout:

rtsp://127.0.0.1/MySubfolder/MyDvd5.lnk?Timeout=10 

Special note regarding streaming live DVR streams

When the high level RTSP objects are streaming a growing DVR file, they will start streaming from the live position. This enables you to implement live streaming with the RTSP server. In this case, all the clients are seeing pretty much the same video, regardless of how long ago they connected to the RTSP server.

If you are streaming a DVR file that is not growing anymore, the clients will start playing the video from the beginning of the DVR buffer. 

Automatic Recompression in the high level RTSP objects

The high level RTSP objects provide automatic recompression using the LEAD H264 Encoder and LEAD AAC Encoder if the source video or audio are not using compatible compressions. They also provide a way to specify the compression settings to be used with the H264 encoder and AAC Encoder. These settings would override the current settings for the H264 and AAC Encoders when they are used to recompress the files on the fly. 

Low Level Implementation

If you desire to implement your RTSP server using the LEAD RTSP Sink filter directly, you will need to understand the relationship between the various RTSP Server interfaces. You will also need to have some knowledge of the RTSP protocol. The LEAD RTSP Sink will do most of the hard work, but you need to be aware of the structure of RTSP commands and of the most important parts of these commands.

The LEAD RTSP Sink filter will typically act in two different roles:

  1. As a server, in which case it waits for RTSP clients to connect and send commands. In this case, you get the ILMRTSPServer interface from it. And you don't need to add it to a DirectShow graph - you just need the ILMRTSPServer interface.

  2. As a sink, in which case it will send data to one RTSP client in response to commands received from another LEAD RTSP Sink acting as a server. This filter will be the sink in a convert or capture object and you will need to get the ILMRTSPServerSession interface from it.

    Interface

    Who implements it

    What it does

    ILMRTSPServer

    LEAD RTSP Sink

    This is the main server interface. It keeps track of the ILMRTSPServerMedia interfaces that will handle all the client requests. The Server will go through all the ILMRTSPServerMedia interfaces and ask each of them if they can handle the RTSP command. The first ILMRTSPServerMedia interface that indicates it can handle the command will have to handle it.

    ILMRTSPServerMedia

    You

    This interface is responsible for handling the RTSP command for compatible media. You can use the ILMRTSPCommandParser and ILMRTSPResponseBuilder interfaces provided by the LEAD RTSP Sink filter to parse RTSP commands.

For example, if you are asked to stream a file from a certain folder, this interface should parse the RTSP url using the ILMRTSPCommandParser interface to determine which file should satisfy the request.

 

When you detect an RTSP DESCRIBE command for a media stream you can serve, the ILMRTSPServerMedia interface (implemented in your object) is responsible for sending a response describing whether the stream has video, audio and the characteristics for each available stream (compression, width/height for video, audio sampling rate, etc). The LEAD RTSP Sink filter will provide support for adding information through the ILMRTSPServerSession interface describing the video and audio streams in the file. But you should add the other information like the file duration, information fields, etc. So you will need to add some response fields using the ILMRTSPResponseBuilder interface and then call the ILMRTSPServerSession interface to fill the remaining fields.

If the DESCRIBE command is for a stream or file you cannot serve, you can return an error and the ILMRTSPServer interface will ask next ILMRTSPServerMedia interface in the list whether it can support the URL. It will continue doing so until it finds a ILMRTSPServerMedia interface that can handle the URL. If nobody can handle it, the describe command will fail and the ILMRTSPServer interface will send an error code to the RTSP source client.

 

When you detect an RTSP SETUP command without a session field, the ILMRTSPServerMedia is responsible for creating a ILMRTSPServerSession object and keeping it in the list of active sessions (A session is somewhat similar to a client connection). The LEAD RTSP Sink filter will provide the ILMRTSPServerSession interface and will typically be the sink in a convert or capture graph. So if the URL indicates the intent to stream a file, you might do the following:

When you detect an RTSP SETUP command with a session field, you will need to do the following:

The ILMRTSPServerMedia will handle the RTSP PLAY command you will need to do the following:

The ILMRTSPServerMedia will handle the RTSP PAUSE command

The ILMRTSPServerMedia will handle the RTSP TEARDOWN command you will need to do the following:

You should handle the various notifications passed to ILMRTSPServerMedia::OnNotification, which will indicate whether

ILMRTSPServerSession

LEAD RTSP Sink

This interface will be implemented by the LEAD RTSP Sink filter that will do the actual sending of the data to the RTSP client. All you have to do is set up the convert or capture object that will do the actual streaming to have a  LEAD RTSP Sink and obtain the ILMRTSPServerSession interface from it. You should then keep this convert/capture object in the list of active sessions.

ILMRTSPCommandParser

LEAD RTSP Sink

The server will pass this interface whenever it receives an RTSP command from the client. This interface should be used to find out which stream is requested, what RTSP command was received (DESCRIBE, SETUP, PLAY, PAUSE, TEARDOWN) and command parameters.

You will need to find which file/media should be streamed by examining the command URL.

The command parameters contain important information also. For example, the session parameter tells you which session should execute the command. Also, for a file you might have an interval which tells you to stream a portion, rather than the whole file.

ILMRTSPResponseBuilder

LEAD RTSP Sink

The server will pass this interface when it receives an RTSP command from the client. This interface should be used to build the RTSP response. It is important to be familiar with the RTSP protocol so you know how the response should look and how to set the various error codes whenever something goes wrong.

Particular care should be taken with the DESCRIBE command, which contains a description of the media. You should fill the response parameters regarding the server not accessible to the sink (the "v=", "o=" and "s=" parameters). Please see "RFC 2326 - Real Time Streaming Protocol (RTSP)" specification for more information. For example, this sequence might be enough:

ILMRTSPResponseBuilder *pBuilder; 
hr = pBuilder->put_ContentType(L'application/sdp'); 
hr = AddContent(pBuilder, L'v=0'); 
hr = AddContent(pBuilder, L'o=- 0 0 IN IP4 127.0.0.1'); 
hr = AddContent(pBuilder, L's=Test session'); 
hr = AddContent(pBuilder, L'a=range:npt=0-'); // indicate that we are playing the whole file/stream 
hr = pDescribeSession->HandleCommand(pServer, pParser, pBuilder, socket); /* where pDescribeSession is a pointer to an ILMRTSPServerSession interface from a LEAD RTSP Sink filter. The filter should be a sink in a graph in which the media requested is the source */ 

In the above example, the pDescribeSession->HandleCommand call will fill the rest of the response with the media compression information (the "m=" parameters and "a=" fields regarding the audio/video streams in the file).

IFileSinkFilter Interface (UDP, RTSP, MMS)

LEAD RTSP Sink

Use IFileSinkFilter::SetFileName to set the address to be used by the filter. The same address will be used whether the filter acts as a server or a sink. When you add the filter as a sink to a convert object, set the target filename to the loopback address ("rtsp://localhost" or "rtsp://127.0.0.1"). The IP address in this URL will be overwritten by the IP address set on the server.

Note that when you use the LEAD RTSP Sink as a sink in a capture graph, it is most likely that only one client will be able to view the stream because DirectShow capture devices can rarely be used in multiple capture graphs. This is why it is best to capture to a DVR file (and stream that DVR file whenever you want to implement a live stream).

Streaming a DVR file is also recommended for restreaming an MPEG-2 Transport UDP stream, since the LEAD MPEG-2 Transport UDP Source filter uses DVR files to store data.

Help Version 21.0.2021.7.2
Products | Support | Contact Us | Intellectual Property Notices
© 1991-2021 LEAD Technologies, Inc. All Rights Reserved.

LEADTOOLS Filters C API Help
Products | Support | Contact Us | Intellectual Property Notices
© 1991-2021 LEAD Technologies, Inc. All Rights Reserved.