Retired Document
Important: Apple recommends that developers explore QTKit and Core Video for new development in this technology area. See QTKit Framework Reference and Core Video Programming Guide for more information.
Concepts
This manual describes version 4.0 of the programming interface for creating QuickTime Streaming Server (QTSS) modules. This version of the programming interface is compatible with QuickTime Streaming Server version 5.
QTSS is an open-source, standards-based streaming server that runs on Windows NT and Windows 2000 and several UNIX implementations, including Mac OS X, Linux, FreeBSD, and the Solaris operating system. To use the programming interface for the QuickTime Streaming Server, you should be familiar with the following Internet Engineering Task Force (IETF) protocols that the server implements:
Real Time Streaming Protocol (RTSP)
Real Time Transport Protocol (RTP)
Real Time Transport Control Protocol (RTCP)
Session Description Protocol (SDP)
This manual describes how to use the QTSS programming interface to develop QTSS modules for the QuickTime Streaming Server. Using the programming interface described in this manual allows your application to take advantage of the server’s scalability and protocol implementation in a way that will be compatible with future versions of the QuickTime Streaming Server. Most of the core features of the QuickTime Streaming Server are implemented as modules, so support for modules has been designed into the core of the server.
You can use the programming interface to develop QTSS modules that supplement the features of the QuickTime Streaming server. For example, you could write a module that
acts as an RTSP proxy, which would be useful for streaming clients located behind a firewall
supports virtual hosting, allowing a single server to serve multiple domains from multiple document roots.
logs statistical information for particular RTSP and client sessions
supports additional ways of storing content, such as storing movies in databases
configures users’ QuickTime Streaming Server preferences
monitors and reports statistical information in real time
tracks pay-per-view accounting information
Server Architecture
The Streaming Server consists of one parent process that forks a child process, which is the core server. The parent process waits for the child process to exit. If the child process exits with an error, the parent process forks a new child process.
The core server acts as an interface between network clients, which use RTP and RTSP to send requests and receive responses, and server modules, which process requests and send packets to the client. The core server does its work by creating four types of threads:
the server’s own Main thread. The Main thread checks to see if the server needs to shut down, log status information, or print statistics.
the Idle Task thread. The Idle Task thread manages a queue of tasks that occur periodically. There are two types of task queues: timeout tasks and socket tasks.
the Event thread. The Event thread listens for socket events such as a received RTSP request or RTP packet and forwards them to a Task thread.
one or more Task threads. Tasks threads receive RTSP and RTP requests from the Event thread. Tasks threads foward requests to the appropriate server module for processing and send packets to the client. By default, the core server creates one Task thread per processor.
Figure 1-1 summarizes the relationship between clients, the core server’s threads, and server modules.
Because the server is largely asynchronous, there needs to be a communication mechanism for events. For instance, when a socket used for an RTSP connection gets data, something has to be notified so that data can be processed. The Task object is a generalized mechanism for performing this communication.
Each Task object has two major methods: Signal and Run. Signal is called by the server to send an event to a Task object. Run is called to give time to the Task for processing the event.
The goal of each Task object is to implement server functionality using small non-blocking time slices. Run is a pure virtual function that is called when a Task object has events to process. Inside the Run function, the Task object can call GetEvents to receive and automatically dequeue all its current and previously signaled events. The Run function is never re-entered: if a Task object calls GetEvents in its Run function, and is then signaled before the Run function completes, the Run function will be called again for the new event only after exiting the function. In fact, the Task’s Run function will be called repeatedly until the all the Task object’s events have been cleared with GetEvents.
This core concept of event-triggered tasks is integrated into almost every Streaming Server subsystem. For example, a Task object can be associated with a Socket object. If the Socket gets an event (through a select() notification or through the Mac OS X Event Queue, the corresponding Task object will be signaled. In this case, the body of the Run function will contain the code for processing whatever event was received on that Socket.
Task objects make it possible for the Streaming Server use a singlethread to run all connections, which is the Streaming Server’s default configuration on a single processor system.
Modules
The Streaming Server uses modules to respond to requests and complete tasks. There are three types of modules:
Content-Managing Modules
The content-managing modules manage RTSP requests and responses related to media sources, such as a file or a broadcast. Each module is responsible for interpreting the client’s request, reading and parsing their supported files or network source, and responding with RTSP and RTP. In some cases, such as the mp3 streaming module, the module uses HTTP.
The content-managing modules are QTSSFileModule, QTSSReflectorModule, QTSSRelayModule, and QTSSMP3StreamingModule.
Server-Support Modules
The server-support modules perform server data gathering and logging functions. The server-support modules are QTSSErrorLogModule, QTSSAccessLogModule, QTSSWebStatsModule, QTSSWebDebugModule, QTSSAdminModule, and QTSSPOSIXFileSystemModule.
Access Control Modules
The access control modules provide authentication and authorization functions as well as URL path manipulation.
The access control modules are QTSSAccessModule, QTSSHomeDirectoryModule, QTSSHttpFileModule, and QTSSSpamDefenseModule.
Protocols
The Streaming Server supports the following protocols:
RTSP over TCP. The Real Time Streaming Protocol (RTSP) is a client-server multimedia presentation control protocol designed to provide efficient delivery of streamed multimedia over IP networks. RTSP provides a basis for negotiating unicast and multicast transport protocols, such as RTP, and negotiates codecs in a file format independent way. It works well for large audiences as well as single-viewer media-on-demand. RFC 2326 defines the IETF standard for RTSP.
RTP over UDP. The Realtime Transport Protocol (RTP) is a packet format for multimedia data streams. RTP is used by many standard protocols, such as RTSP for streaming applications and SDP for multicast applications. It provides the data delivery format for RTSP and SDP. RFC 1889 defines the IETF proposed standard for RTP.
RTP over Apple’s Reliable UDP. If an RTP client requests it, the server sends RTP packets using Reliable UDP. Reliable UDP is a set of quality of service enhancements, such as congestion control tuning improvements, retransmit, and thinning server algorithms, that improve the ability to present a good quality RTP stream to RTP clients even in the presence of packet loss and network congestion. For more information, see Reliable UDP.
RTSP/RTP in HTTP (tunneled). Firewalls often prevent users on private IP networks from receiving QuickTime presentations. On private networks, an HTTP proxy server is often configured to provide users with indirect access to the Internet. To reach such clients, QuickTime 4.1 supports the placement of RTSP and RTP data in HTTP requests and replies, allowing viewers behind firewalls to access QuickTime presentations through HTTP proxy servers. For more information, see Tunneling RTSP and RTP Over HTTP.
RTP over RTSP (RTP over TCP). Certain firewall designs and other circumstances may require a server to use alternative means to send data to clients. RFC 2326 allows RTSP packets destined for the same control end point to be packed into a single lower-layer protocol data unint (PDU), encapsulated into a TCP stream, or interleaved with RTP and RTCP packets. Interleaving complicates client and server operation and imposes additional overhead and should only be used if RTSP is carried over TCP. RTP packets are encapsulated by an ASCII dollar sign ($), followed by a one-byte channel identifier (defined in the transport header using the interleaved parameter), followed by the length of the encapsulated binary data as a binary, two-byte integer in network byte order. The stream data follows immediately, without a CRLF, but including the upper-layer protocol headers. Each $ block contains exactly one RTP packet. When the transport is RTP, RTCP messages are also interleaved by the server over the TCP connection. By default, RTCP packets are sent on the first available channel higher than the RTP channel. The client may request RTCP packets on another channel explicitly. This is done by specifying two channels in the interleaved parameter of the transport header. RTCP is used for synchronization when two or more streams are interleaved. Also, this provides a convenient way to tunnel RTP/RTCP packets through the TCP control connection when required by the network configuration and transfer them onto UDP when possible.
In addition, the following modules implement HTTP:
QTSSAdminModule
QTSSMP3StreamingModule
QTSSWebStatsModule
QTSSHTTPStreamingModule
QTSSRefMovieModule
QTSSWebStats
QTSSWebDebugModule
Data
When a module needs access to a request’s RTSP header, it gains access to the request through a request object defined by the QTSS.h API header file. For example, the RTSPRequestInterface class implements the API dictionary elements accessible by the API. Objects whose name ends with “Interface”, such as RTSPRequestInterface, RTSPSessionInterface, and QTSServerInterface, implement the module’s API.
The following interface classes are significant:
QTSServerInterface — This is the internal data storage object tagged as the QTSS_ServerObject in the API. Each of the QTSS_ServerAttributes in the API is declared and implemented in this base class.
RTSPSessionInterace — This is the internal data storage object tagged as the qtssRTSPSessionObjectType in the API. Each of the QTSS_RTSPSessionAttributes in the API is declared and implemented in this base class.
RTPSessionInterface — This is the internal data storage object tagged as the QTSS_ClientSessionObject in the API. Each of the QTSS_ClientSessionAttributes in the API is declared and implemented in this base class.
RTSPRequestInterface — This is the internal data storage object tagged as the QTSS_RTSPRequestObject in the API. Each of the QTSS_RTSPRequestAttributes in the API is declared and implemented in this base class.
Classes
Figure 1-2 shows how the objects in the server reference each other.
The server object has a a dictionary of preferences. The server owns a list of modules each with a dictionary for their preferences. The server owns a list of RTP client sessions, each of which can have an RTSP session and one or more RTP media streams. It is possible to use the API to walk all of the server’s the live sessions and streams.
QTServer is the core server object, some of which is accessible through the API and the QTSServerInterface base class.
Dictionary is a data storage base class that implements key and value access to object data. This base class is inherited by all server objects defined by the API.
Module is a class for managing modules. Each module instance is responsible for loading, initializing, and executing a static or dynamic API module.
RTSP and RTP sessions. Reads and writes are managed by the sessions through a stream object. The RTSP session calls each of the modules in their registered RTSP role fromthe session’s RTSPSession::Run method. The API module roles that are called are
QTSS_RTSPFilter_Role
,QTSS_RTSPRoute_Role
,QTSS_RTSPAuthenticate_Role
,QTSS_RTSPAuthorize_Role
,QTSS_RTSPPreProcessor_Role
,QTSS_RTSPRequest_Role
,QTSS_RTSPPostProcessor_Role
, andQTSS_RTSPSessionClosingRole
. The RTSP session also calls modules in theirQTSS_RTSPIncomingData_Role
. The RTP session handles the following role calls as well as data reads and writes:QTSS_RTPSendPackets_Role
,QTSS_RTCPProcess_Role
, andQTSS_ClientSessionClosing_Role
. For more information about roles, see Module Roles.
Applications and Tools
The Streaming Server comes with the following applications and tools:
PlayListBroadcaster
MP3Broadcaster
StreamingProxy
QTFileTools (POSIX and Mac OS X only; not maintained)
WebAdmin
qtpasswd
PlayListBroadcaster
PlaylistBroadcaster broadcasts QuickTime, MPEG4, and 3GPP streaming files to a streaming server, such as QuickTime Streaming Server, which then reflects the media to clients. This lets you create a virtual radio station or TV broadcast that appears to users as a live broadcast of the media.
MP3Broadcaster
The MP3Broadcaster application broadcasts an MP3 file as if it were a live broadcast.
StreamingProxy
POSIX and Mac OS X only.
QTFileTools
QTFileTools are movie-inspection utilities that use the QTFile library. The utillities are:
QTBroadcaster. This utility requires a target IP address, a source movie having one or more hint track IDs, and an initial port. Every packet referenced by the hint track(s) is broadcast to the specified IP address.
QTFileInfo. This utility requires a source movie. It displays the movie’s name, creation date, and modification date. If the track is a hint track, the utility also displays the total RTP bytes and packets, the average bit rate and packet size, and the total header percentage of the stream.
QTFileTest. This utility requires a source movie. It parses the Movie Header Atom and displays a trace of the output.
QTRTPGent. This utility requires a source movie having a hint track ID. It displays the number of packets in each hint track sample and writes the RTP packets to a file named
track.cache
.QTRTPFileTest. This utility requires a source movie having a hint track ID. It displays the RTP header (TransmitTime, Cookie, SeqNum, and TimeStamp) for each packet.
QTSampleLister. This utility requires a source movie and a track ID. It displays the track media sample number, media time, data offset, and sample size for each sample in the track.
QTSDPGen. This utility requires a list of one or more source movies. It displays the SDP information for all of the hinted tracks in each movie. Use the
-f
option to save the SDP information to the file moviename.sdp
in the same directory as the source movie.QTTrackInfo. This utility requires a source movie, a sample table atom type (
stco
,stsc
,stsz
, orstts
) and a track ID. It displays the information in the sample table atom of the specified track.
The following example displays the chunk offset sample table in track 3:
./QTTrackInfo -T stco /movies/mystery/.mov 3 |
WebAdmin
WebAdmin is a Perl-based web server. Connect a browser to it, and you can administer the server.
qtpasswd
The qtpasswd
application
generates password files for access control.
Source Organization
The Streaming Server source code is written entirely in C++ and pervasively uses object-oriented concepts such as inheritance and polymorphism. Almost exclusively, there is one C++ class per .h / .cpp file pair, and those file names match the class name.The Streaming Server source is organized as follows:
Server.tproj
This directory contains the core server code, which can be divided into three subsystems:
Server core. Classes in this subsystem are prefixed by QTSS. QTSServer handles startup and shutdown. QTSServerInterface stores server globals and compiles server statistics. QTSSPrefs is a data store for server preferences. QTSSModule, QTSSModuleInterface, and QTSSCallbacks are classes whose sole purpose is to support the QTSS module API.
RTSP subsystem. These classes handle the parsing and processing of RTSP requests, and implement the RTSP part of the QTSS module API. Several of the classes correspond directly to elements of the QTSS API (for instance, RTSPRequestInterface is a QTSS_RTSPRequestObject). There is one RTSP session object per RTSP TCP connection. The RTSPSession object is a Task object that processes RTSP related events.
RTP subsystem. These classes handle the sending of media data. The RTPSession object contains the data associated with each RTSP session ID. Each RTPSession is a Task object that can be scheduled to send RTP packets. The RTPStream object represents a single RTP stream. Any number of RTPStream objects can be associated with a single RTPSession. These two objects implement the RTP specific parts of the QTSS module API.
CommonUtilitiesLib
This directory contains a toolkit of thread management, data structure, networking, and text parsing utilities. Darwin Streaming Server and associated tools use these classes to reduce repeated code by abstracting similar or identical tasks, to simplify higher level code through encapsulation, and to separate out platform-specific code. Here is a short description of the classes in the CommonUtilitiesLib directory:
OS Classes. These classes provide platform-specific code abstractions for timing, condition variables, mutexes, and threads. The classes are OS, OSCond, OSMutex, OSThread, and OSFileSource. The data structures are OSQueue, OSHashTable, OSHeap, and OSRef.
Sockets. These classes provide platform-specific code abstractions for TCP and UDP networking. Socket classes are generally asynchronous (or non-blocking), and can send events to Task objects. The classes are EventContext, Socket, UDPSocket, UDPDemuxer, UDPSocketPool, TCPSocket, and TCPListenerSocket.
Parsing Utilities. These classes parse and format text. The classes are StringParser, StringFormatter, StrPtrLen, and StringTranslator.
Tasks: These classes implement the server’s asynchronous event mechanism.
QTFileLib
A major feature of the Streaming Server is its ability to serve hinted QuickTime movie files over RTSP and RTP. This directory contains source code for the QTFile library, which contains all of the code for parsing hinted QuickTime files. The server’s RTPFileModule calls the QTFile library to retrieve packets and meta-data from hinted QuickTime files. The QTFile library parses the following movie file types: .mov, .mp4 (a modification of .mov), and .3gpp (a modification of .mov).
APICommonCode
This directory contains source code for API-related classes, such as moduletils, or common module functions, such as log file management.
APIModules
This directory contains a directory for each Streaming Server module.
RTSPClientLib
This directory contains source code that implements the server’s RTSP client, which can be used to connect to the server using any of the supported protocols.
RTCPUtilitiesLib
This directory contains source code for parsing RTCP requests.
APIStubLib
This directory contains API definition and support files.
HTTPUtilitiesLib
This directory contains source code for parsing HTTP requests.
Server Preference Naming
The file QTSS,h
defines
server preferences. Each server preference defined in QTSS.h
has
a name, such as qtssPrefsEnableMonitorStatsFile
,
a numeric ID, such as 57, and a string constant, such as enable_monitor_stats_file
.
To get the current setting of server preferences, the server
reads the file StreamingServer.xml
when
it starts up or when signaled to reread that file. In the StreamingServer.xml
file,
string constant names are used to refer to preferences.
The modules that come with the server use the built-in preference
file support provided by the API to generate preferences and a unique
ID if the preference is not already defined in the module’s preference
object. The check and creation of preferences is usually done in QTSS_Initialize_Role
but
the code to generate the preference and an ID from the string name
for the preference is also run in QTSS_RereadPrefs_Role
.
The modules that come with the server use the QTSSModuleUtils
object
to encapsulate API calls such as QTSS_AddInstanceAttribute
and QTSS_GetAttrInfoByName
.
Module developers who want to use theserver’s built-in preference
storage support should use the utility method QTSSModuleUtils::GetAttribute
or
examine and call the QTSS API callbacks used by QTSSModuleUtils::GetAttribute
.
The implementation and header file for QTSSModuleUtils
can
be found in the APICommonCode
directory.
Requirements for Modules
Every QTSS module must implement two routines:
a main routine, which the server calls when it starts up to initialize the QTSS stub library with your module
a dispatch routine, which the server uses when it calls the module for a specific purpose
Main Routine
Every QTSS modules must provide a main routine. The server calls the main routine as the server starts up and uses it to initialize the QTSS stub library so the server can invoke your module later.
For modules that are compiled into the server, the address of the module's main routine must be passed to the server's module initialization routine, as described in the section “Compiling a QTSS Module into the Server”.
The body of the main routine must be written like this:
QTSS_Error MyModule_Main(void* inPrivateArgs) |
{ |
return _stublibrary_main(inPrivateArgs, MyModuleDispatch); |
} |
where MyModuleDispatch is the name of the module’s dispatch routine, which is described in the following section, Dispatch Routine.
Dispatch Routine
Every QTSS module must provide a dispatch routine. The server calls the dispatch routine when it invokes a module for a specific task, passing to the dispatch routine the name of the task and a task-specific parameter block. (The programming interface uses the term “role” to describe specific tasks. For information about roles, see Module Roles.)
The dispatch routine must have the following prototype:
void MyModuleDispatch(QTSS_Role inRole, QTSS_RoleParamPtr inParams); |
where MyModuleDispatch is the name specified as the name of
the dispatch routine by the module’s main routine, inRole
is
the name of the role for which the module is being called, and inParams
is
a structure containing values of interest to the module.
Overview of QuickTime Streaming Server Operations
The QuickTime Streaming Server works with modules to process requests from clients by invoking modules in a particular role. Each role is designed to perform a particular task. This section describes how the server works with roles when it starts up and shuts down and how the server works with roles when it processes client requests.
Server Startup and Shutdown
Figure 2-1 shows how the server works with the Register, Initialize, and Shutdown roles when the server starts up and shuts down.
When the server starts up, it first loads modules that are not compiled into the server (dynamic modules) and then loads modules that are compiled into the server (static modules). If you are writing a module that replaces existing server functionality, compile it as a dynamic module so that it is loaded first.
Then the server invokes each QTSS module in the Register role,
which is a role that every module must support. In the Register
role, the module calls QTSS_AddRole
to
specify the other roles that the module supports.
Next, the server invokes the Initialize role for each module that has registered for that role. The Initialize role performs any initialization tasks that the module requires, such as allocating memory and initializing global data structures.
At shutdown, the server invokes the Shutdown role for each module that has registered for that role. When handling the Shutdown role, the module should perform cleanup tasks and free global data structures.
RTSP Request Processing
After the server calls each module that has registered for the Initialize role, the server is ready to receive requests from the client. These requests are known as RTSP requests. A sample RTSP request is shown in Figure 1-4.
When the server receives an RTSP request, it creates an RTSP
request object, which is a collection of attributes that describe
the request. At this point, the qtssRTSPReqFullRequest
attribute
is the only attribute that has a value and that value consists of
the complete contents of the RTSP request.
Next, the server calls modules in specific roles according to a predetermined sequence. That sequence is shown in Figure 1-5.
When processing an RTSP request, the first role that the server
calls is the RTSP Filter role. The server calls each module that
has registered for the RTSP Filter role and passes to it the RTSP
request object. Each module’s RTSP Filter role has the option
of changing the value of the qtssRTSPReqFullRequest
attribute.
For example, an RTSP Filter role might change /foo/foo.mov
to /bar/bar.mov
,
thereby changing the folder that will be used to satisfy this request.
When all RTSP Filter roles have been invoked, the server parses the request. Parsing the request consists of filling in the remaining attributes of the RTSP object and creating two sessions:
an RTSP session, which is associated with this particular request and closes when the client closes its RTSP connection to the server
a client session, which is associated with the client connection that originated the request and remains in place until the client’s streaming presentation is complete
After parsing the request, the server calls the RTSP Route
role for each module that has registered in that role and passes
the RTSP object. Each RTSP Route role has the option of using the
values of certain attributes to determine whether to change the
value of the qtssRTSPReqRootDir
attribute,
thereby changing the folder that is used to process this request.
For example, if the language type is French, the module could change
the qtssRTSPReqRootDir
attribute
to a folder that contains the French version of the requested file.
After all RTSP Route roles have been called, the server calls
the RTSP Preprocessor role for each module that has registered for
that role. The RTSP Preprocessor role typically uses the qtssRTSPReqAbsoluteURL
attribute
to determine whether the request matches the type of request that
the module handles.
If the request matches, the RTSP Preprocessor role responds
to the request by calling QTSS_Write
or QTSS_WriteV
to
send data to the client. To send a standard response, the module
can call QTSS_SendStandardRTSPResponse
,
or QTSS_AppendRTSPHeader
and QTSS_SendRTSPHeaders
.
If no RTSP Preprocessor role responds to the RTSP request, the server invokes the RTSP Request role of the module that successfully registered for this role. (The first module that registers for the RTSP Request role is the only module that can register for the RTSP Request role.) The RTSP Request role is responsible for responding to all RTSP Requests that are not handled by modules registered for the RTSP Preprocessor role.
After the RTSP Request role processes the request, the server calls modules that have registered for the RTSP Postprocessor role. The RTSP Postprocessor role typically performs accounting tasks, such as logging statistical information.
A module handling the RTSP Preprocessor or RTSP Request role
may generate the media data for a particular client session. To
generate media data, the module calls QTSS_Play
, which
causes that module to be invoked in the RTP Send Packets role, as
shown in Figure 1-6.
The RTP Send Packets role calls QTSS_Write
or QTSS_WriteV
to
send data to the client over the RTP session. When the RTP Send
Packets role has sent some packets, it returns to the server and
specifies the time that is to elapse before the server calls the
module’s RTP Send Packets role again. This cycle repeats until
all of the packets for the media have been sent or until the client
requests that the client session be paused or torn down.
Runtime Environment for QTSS Modules
QTSS modules can spawn threads, use mutexes, and are completely free to use any operating system tools.
The QuickTime Streaming Server is fully multi-threaded, so QTSS modules must be prepared to be preempted. Global data structures and critical sections in code should be protected with mutexes. Unless otherwise noted, assume that preemption can occur at any time.
The server usually runs all activity from very few threads or possibly a single thread, which requires the server to use asynchronous I/O whenever possible. (The actual behavior depends on the platform and how the administrator configures the server.)
QTSS modules should adhere to the following rules:
Perform tasks and return control to the server as quickly as possible. Returning quickly allows the server to load balance among a large number of clients.
Be prepared for
QTSS_WouldBlock
errors when performing stream I/O. TheQTSS_Write
,QTSS_WriteV
, andQTSS_Read
callback routines returnQTSS_WouldBlock
if the requested I/O would block. For more information about streams, see QTSS Streams.Avoid using synchronous I/O wherever possible. An I/O operation that blocks may affect streaming quality for other clients.
Server Time
The QuickTime Streaming Server handles real-time delivery of media, so many elements of QTSS module programming interface are time values.
The server’s internal clock counts the number of milliseconds
that have elapsed since midnight, January 1st, 1970. The data type QTSS_TimeVal
is
used to store the value of the server’s internal clock. To make
it easy to work with time values, every attribute, parameter, and
callback routine that deals with time specifies the time units explicitly.
For example, the qtssRTPStrBufferDelayInSecs
attribute
specifies the client’s buffer size in seconds. Unless otherwise
noted, all time values are reported in milliseconds from the server’s
internal clock using a QTSS_TimeVal
data
type.
To get the current value of the server’s clock, call QTSS_Milliseconds
or
get the value of the qtssSvrCurrentTimeMilliseconds
attribute
of the server object (QTSS_ServerObject
).
To convert a time obtained from the server’s clock to the current
time, call QTSS_MilliSecsTo1970Secs
.
Naming Conventions
The QTSS programming interface uses a naming convention for the data types that it defines. The convention is to use the size of the data type in the name. Here are the data types that the QTSS programming interface uses:
Bool16
— A 16-bit Boolean valueSInt64
— A signed 64-bit integer valueSInt32
— A signed 32-bit integer valueUInt16
— An unsigned 16-bit integer valueUInt32
— An unsigned 32-bit integer value
Parameters for callback functions defined by the QTSS programming interface follow these naming conventions:
Input parameters begin with
in
.Output parameters begin with
out
.Parameters that are used for both input and output begin with
io
.
Module Roles
Roles provide modules with a well-defined state for performing
certain types of processing. A selector of type QTSS_Role
defines
each role and represents the internal processing state of the server
and the number, accessibility, and validity of server data. Depending
on the role, the server may pass to the module one or more QTSS
objects. In general, the server uses objects to exchange information
with modules. For more information about QTSS objects, see QTSS Objects.
Table 1-1 lists the roles that this version of the QuickTime Streaming Server supports.
Name |
Constant |
Task |
---|---|---|
Register role |
|
Registers the roles the module supports. |
Initialize role |
|
Performs tasks that initialize the module. |
Shutdown role |
|
Performs cleanup tasks. |
Reread Preferences role |
|
Rereads the modules’s preferences. |
Error Log role |
|
Logs errors. |
RTSP Filter role |
|
Makes changes to the contents of RTSP requests. |
RTSP Route role |
|
Routes requests from the client to the appropriate folder. |
RTSP Preprocessor role |
|
Processes requests from the client before the server processes them. |
RTSP Request role |
|
Processes a request from the client if no other role responds to the request. |
RTSP Postprocessor role |
|
Performs tasks, such as logging statistical information, after a request has been responded to. |
RTP Send Packets role |
|
Sends packets. |
Client Session Closing role |
|
Performs tasks when a client session closes. |
RTCP Process role |
|
Processes RTCP receiver reports. |
Open File Preprocess role |
|
Processes requests to open files. |
Open File role |
|
Processes requests to open files that are not handled by the Open File Preprocess role. |
Advise File role |
|
|
Read File role |
|
Reads a file. |
Request Event File role |
|
Handles requests for notification of when a file becomes available for reading. |
Close File role |
|
Closes a file that was previously opened. |
With the exception of the Register, Shutdown, and Reread Preferences roles, when the server invokes a module for a role, the server passes to the module a structure specific to that particular role. The structure contains information that the modules uses in the execution of that role or provides a way for the module to return information to the server.
The RTSP roles have the option of responding to the client.
A response is defined as any data that a module sends to a client.
Modules can send data to the client in a variety of ways. They can,
for example, call QTSS_Write
or QTSS_WriteV
.
Register Role
Modules use the Register role to call QTSS_AddRole
to
tell the server the roles they support.
Modules also use the Register role to call QTSS_AddService
to
register services and to call QTSS_AddStaticAttribute
to
add static attributes to QTSS object types. (QTSS objects are collections
of attributes, each having a value.)
The server calls a module’s Register role once at startup. The Register role is always the first role that the server calls.
A module that returns any value other than QTSS_NoErr
from
its Register role is not loaded into the server.
Initialize Role
The server calls the Initialize role of those modules that have registered for this role after it calls the Register role for all modules. Modules use the Initialize role to initialize global and private data structures.
The server passes to each module’s Initialize role objects that can be used to obtain the server’s global attributes, preferences, and text error messages. The server also passes the error log stream reference, which can be used to write to the error log. All of these objects are globals, so they are valid for the duration of this run of the server and may be accessed at any time.
When called in the Initialize role, the module receives a QTSS_Initialize_Params
structure which
is defined as follows:
typedef struct |
{ |
QTSS_ServerObject inServer; |
QTSS_PrefsObject inPrefs; |
QTSS_TextMessagesObjectinMessages; |
QTSS_ErrorLogStream inErrorLogStream; |
QTSS_ModuleObject inModule; |
} QTSS_Initialize_Params; |
inServer
A
QTSS_ServerObject
object containing the server’s global attributes and an attribute that contains information about all of the modules in the running server. For a description of each attribute, see the section qtssServerObjectType.inPrefs
A
QTSS_PrefsObject
object containing the server’s preferences. For a description of each attribute, see the section qtssPrefsObjectType.inMessages
A
QTSS_TextMessagesObject
object that a module can use for providing localized text strings. See the section“qtssTextMessageObjectType”
.inErrorLogStream
A
QTSS_ErrorLogStream
stream reference that a module can use to write to the server’s error log. Writing to this stream causes the module to be invoked in its Error Log role.inModule
A
QTSS_ModuleObject
object that a module can use to store information about itself, including its name, version number, and a description of what the module does. See the section“qttsModuleObjectType”
.
A module that wants to be called in the Initialize role must
in its Register role call QTSS_AddRole
and
specify QTSS_Initialize_Role
as
the role.
A module that returns any value other than QTSS_NoErr
from
its Initialize role is not loaded into the server.
Shutdown Role
The server calls the Shutdown role of those modules that have registered for this role when the server is getting ready to shut down.
The server calls a module’s Shutdown role without passing any parameters.
The module uses its Shutdown role to delete all data structures it has created and to perform any other cleanup task
A module that wants to be called in the Shutdown role must
in its Register role call QTSS_AddRole
and
specify QTSS_Shutdown_Role
as
the role.
Modules should always return QTSS_NoErr
when
they finish handling this role.
The server guarantees that the Shutdown role is the last time that the module is called before the server shuts down.
Reread Preferences Role
The server calls the Reread Preferences role of those modules
that have registered for this role and rereads its own preferences
when the server receives a SIGHUP
signal
or when a module calls the Reread Preferences service described
in the section QTSS Services.
When called in this role, the module should reread its preferences, which may be stored in a file or in a QTSS object.
A module that wants to be called in the Reread Preferences
role must in its Register role call QTSS_AddRole
and
specify QTSS_RereadPrefs_Role
as
the role.
Modules should always return QTSS_NoErr
when
they finish handling this role.
Error Log Role
The server calls the Error Log role of those modules that have registered for this role when an error occurs. The module should process the error message by, for example, writing the message to a log file.
When called in the Error Log role, the module receives a QTSS_ErrorLog_Params
structure, which
is defined as follows:
typedef struct |
{ |
QTSS_ErrorVerbosity inVerbosity; |
char * inBuffer; |
} QTSS_ErrorLog_Params; |
inVerbosity
Specifies the verbosity level of this error message. Modules should use the
inFlags
parameter ofQTSS_Write
to specify the verbosity level. The following constants are defined:qtssFatalVerbosity = 0, qtssWarningVerbosity = 1, qtssMessageVerbosity = 2, qtssAssertVerbosity = 3, qtssDebugVerbosity = 4,
inBuffer
Points to a null-terminated string containing the error message.
Writing an error message at the level qtssFatalVerbosity
causes
the server to shut down immediately.
Writing to the error log cannot result in an QTSS_WouldBlock
error.
A module that wants to be called in the Error Log role must
in its Register role call QTSS_AddRole
and
specify QTSS_ErrorLog_Role
as
the role.
Modules should always return QTSS_NoErr
when
they finish handling this role.
RTSP Roles
When the server receives an RTSP request, it goes through a series of steps to process the request and ensure that a response is sent to the client. The steps consist of calling certain roles in a predetermined order. This section describes each role in detail. For an overview of roles and the sequence in which they are called, see the section Overview of QuickTime Streaming Server Operations.
RTSP Filter Role
The server calls the RTSP Filter role of those modules that have registered for the RTSP Filter role immediately upon receipt of an RTSP request. Processing the Filter role gives the module an opportunity to respond to the request or to change the RTSP request.
When called in the RTSP Filter role, the module receives a QTSS_StandardRTSP_Params
structure,
which is defined as follows:
typedef struct |
{ |
QTSS_RTSPSessionObject inRTSPSession; |
QTSS_RTSPRequestObject inRTSPRequest; |
char** outNewRequest; |
} QTSS_StandardRTSP_Params; |
inRTSPSession
The
QTSS_RTSPSessionObject
object for this RTSP session. See the section qtssRTSPSessionObjectType for information about RTSP session object attributes.inRTSPRequest
The
QTSS_RTSPRequestObject
object for this RTSP request. When called in the RTSP Filter role, only theqtssRTSPReqFullRequest
attribute has a value. See the section qtssRTSPRequestObjectType for information about RTSP request object attributes.- outNewRequest
A pointer to a location in memory.
The module calls QTSS_GetValuePtr
to
get from the qtssRTSPReqFullRequest
attribute
the complete RTSP request that caused the server to call this role.
The qtssRTSPReqFullRequest
attribute
is a read-only attribute. To change the RTSP request, the module
should call QTSS_New
to
allocate a buffer, write the modified request into that buffer,
and return a pointer to that buffer in the outNewRequest
field
of the QTSS_StandardRTSP_Params
structure.
While a module is handling the RTSP Filter role, the server
guarantees that the module will not be called for any other role
referencing the RTSP session represented by inRTSPSession
.
If module handling the RTSP Filter role responds directly to the client, the server next calls the responding module in the RTSP Postprocessor role. For information about that role, see the section RTSP Postprocessor Role.
A module that wants to be called in the RTSP Filter role must
in its Register role call QTSS_AddRole
and
specify QTSS_RTSPFilter_Role
as
the role.
Modules should always return QTSS_NoErr
when
they finish handling this role.
RTSP Route Role
The server calls the RTSP Route role after the server has
called all modules that have registered for the RTSP Filter role.
It is the responsibility of a module handling this role to set the
appropriate root directory for each RTSP request by changing the qtssRTSPReqRootDir
attribute
for the request.
When called, an RTSP Route role receives a QTSS_StandardRTSP_Params
structure,
which is defined as follows:
typedef struct |
{ |
QTSS_RTSPSessionObject inRTSPSession; |
QTSS_RTSPRequestObject inRTSPRequest; |
QTSS_RTSPHeaderObject inRTSPHeaders; |
QTSS_ClientSessionObject inClientSession; |
} QTSS_StandardRTSP_Params; |
inRTSPSession
The
QTSS_RTSPSessionObject
object for this RTSP session. See the section qtssRTSPSessionObjectType for information about RTSP session object attributes.inRTSPRequest
The
QTSS_RTSPRequestObject
object for this RTSP request. In the Route role and all subsequent RTSP roles, all of the attributes are filled in. See the section qtssRTSPRequestObjectType for information about RTSP request object attributes.inRTSPHeaders
The
QTSS_RTSPHeaderObject
object for the RTSP headers. See the section qtssRTSPHeaderObjectType for information about RTSP header object attributes.inClientSession
The
QTSS_ClientSessionObject
object for the client session. See the section qtssClientSessionObjectType for information about client session object attributes.
Before calling modules in the RTSP Route role, the server
parses the request. Parsing the request consists of filling in all
of the attributes of the QTSS_RTSPSessionObject
and QTSS_RTSPRequestObject
members
of the QTSS_StandardRTSP_Params
structure.
A module processing the RTSP Route role has the option of
changing the qtssRTSPReqRootDir
attribute
of the QTSS_RTSPRequestObject
member
of the QTSS_StandardRTSP_Params
structure.
Changing the qtssRTSPReqRootDir
attribute
changes the root folder for this RTSP request.
While a module is handling the RTSP Route role, the server guarantees that the module will not be called for any other role referencing the RTSP session represented by inRTSPSession.
If a module that is processing the RTSP Route role responds directly to the client, the server immediately skips the processing of any other roles and calls the responding module’s RTSP Postprocessor role. For information about that role, see the section RTSP Postprocessor Role.
A module that wants to be called in the RTSP Route role must
in its Register role call QTSS_AddRole
and
specify QTSS_RTSPRoute_Role
as
the role.
Modules should always return QTSS_NoErr
when
they finish handling this role.
RTSP Preprocessor Role
The server calls the RTSP Preprocessor role after the server has called all modules that have registered for the RTSP Route role. If the module handles the type of RTSP request for which the module is called, it is the responsibility of a module handling this role to send a proper RTSP response to the client.
When called, an RTSP Preprocessor role receives a QTSS_StandardRTSP_Params
structure, which
is defined as follows:
typedef struct |
{ |
QTSS_RTSPSessionObject inRTSPSession; |
QTSS_RTSPRequestObject inRTSPRequest; |
QTSS_RTSPHeaderObject inRTSPHeaders; |
QTSS_ClientSessionObjectinClientSession; |
} QTSS_StandardRTSP_Params; |
inRTSPSession
The
QTSS_RTSPSessionObject
object for this RTSP session. See the section qtssRTSPSessionObjectType for information about RTSP session object attributes.inRTSPRequest
The
QTSS_RTSPRequestObject
object for this RTSP request with a value for each attribute. See the section qtssRTSPRequestObjectType for information about RTSP request object attributes.inRTSPHeaders
The
QTSS_RTSPHeaderObject
object for the RTSP headers. See the section qtssRTSPHeaderObjectType for information about RTSP header object attributes.inClientSession
The
QTSS_ClientSessionObject
object for the client session. See the section qtssClientSessionObjectType for information about client session object attributes.
The RTSP Preprocessor role typically uses the qtssRTSPReqFilePath
attribute
of the inRTSPRequest
member
of the QTSS_StandardRTSP_Params
structure
to determine whether the request matches the type of request that
the module handles. For example, a module may only handle URLs that
end in .mov
or .sdp
.
If the request matches, the module handling the RTSP Preprocessor
role responds to the request by calling QTSS_SendStandardRTSPResponse
, QTSS_Write
,
or QTSS_WriteV
, or by calling QTSS_AppendRTSPHeader
,
and QTSS_SendRTSPHeaders
.
If this module is also responsible for generating RTP packets for
this client session, it should call QTSS_AddRTPStream
to
add streams to the client session, and QTSS_Play
,
which causes the server to invoke the RTP Send Packets role of the
module whose RTSP Preprocessor role calls QTSS_Play
.
While a module is handling the RTSP Preprocessor role, the
server guarantees that the module will not be called for any other
role referencing the RTSP session specified by inRTSPSession
or
the client session specified by inClientSession
.
A module that wants to be called in the RTSP Preprocessor
role must in its Register role call QTSS_AddRole
and
specify QTSS_RTSPPreProcessor_Role
as
the role.
Modules should always return QTSS_NoErr
when
they finish handling this role.
RTSP Request Role
The server calls the RTSP Request role if no RTSP Preprocessor role responds to an RTSP request. Only one module is called in the RTSP Request role, and that is the first module to register for the RTSP Request role when the server starts up.
When called, the RTSP Request role receives a QTSS_StandardRTSP_Params
structure,
which is defined as follows:
typedef struct |
{ |
QTSS_RTSPSessionObject inRTSPSession; |
QTSS_RTSPRequestObject inRTSPRequest; |
QTSS_RTSPHeaderObject inRTSPHeaders; |
QTSS_ClientSessionObject inClientSession; |
} QTSS_StandardRTSP_Params; |
inRTSPSession
The
QTSS_RTSPSessionObject
object for this RTSP session. See the section qtssRTSPSessionObjectType for information about RTSP session object attributes.inRTSPRequest
The
QTSS_RTSPRequestObject
object for this RTSP request with a value for each attribute. See the sectionqtssRTSPRequestObjectType for information about RTSP request object attributes.inRTSPHeaders
The
QTSS_RTSPHeaderObject
object for the RTSP headers. See the section qtssRTSPHeaderObjectType for information about RTSP header object attributes.inClientSession
The
QTSS_ClientSessionObject
object for the client session. See the section qtssClientSessionObjectType for information about client session object attributes.
Like a module processing the RTSP Preprocessor role, a module
that processes the RTSP Request Role should use an attribute, such
as the qtssRTSPReqFilePath
attribute
of the inRTSPRequest
member
of the QTSS_StandardRTSP_Params
structure,
to determine whether the request matches the type of request that
the module can handle.
A module handling the RTSP Request role should respond to the request by
Sending an RTSP response to the client by calling
QTSS_AppendRTSPHeader
andQTSS_SendRTSPHeaders
, by callingQTSS_SendStandardRTSPResponse
, or by callingQTSS_Write
orQTSS_WriteV
.Preparing the
QTSS_ClientSessionObject
for streaming by using the RTP callbacks, such asQTSS_AddRTPStream
andQTSS_Play
. IfQTSS_Play
is called, the server will invoke the calling module in the RTP Send Packets role, at which time the module will be expected to generate RTP packets to send to the client.
A module that wants to be called in the RTSP Request role
must in its Register role call QTSS_AddRole
and
specify QTSS_RTSPRequest_Role
as
the role. The first module that successfully calls QTSS_AddRole
and
specifies QTSS_RTSPRequest_Role
as
the role is the only module that is called in the RTSP Request role.
Modules should always return QTSS_NoErr
when
they finish handling this role.
RTSP Postprocessor Role
The server calls a module’s RTSP Postprocessor role whenever the module responds to an RTSP request if that module has registered for this role.
Modules can use the RTSP Postprocessor role to log statistical information.
When called, the RTSP Postprocessor role receives a QTSS_StandardRTSP_Params
structure, which
is defined as follows:
typedef struct |
{ |
QTSS_RTSPSessionObject inRTSPSession; |
QTSS_RTSPRequestObject inRTSPRequest; |
QTSS_RTSPHeaderObject inRTSPHeaders; |
QTSS_ClientSessionObject inClientSession; |
} QTSS_StandardRTSP_Params; |
inRTSPSession
The
QTSS_RTSPSessionObject
object for this RTSP session. See the section qtssRTSPSessionObjectType for information about RTSP session object attributes.inRTSPRequest
The
QTSS_RTSPRequestObject
object for this RTSP request with a value for each attribute. See the section qtssRTSPRequestObjectType for information about RTSP request object attributes.inRTSPHeaders
The
QTSS_RTSPHeaderObject
object for the RTSP headers. See the section qtssRTSPHeaderObjectType for information about RTSP header object attributes.inClientSession
The
QTSS_ClientSessionObject
object for the client session. See the section qtssClientSessionObjectType for information about client session object attributes.
While a module is handling the RTSP Postprocessor role, the server guarantees that the module will not be called for any role referencing the RTSP session specified by inRTSPSession or the client session specified by inClientSession.
A module that wants to be called in the RTSP Postprocessor
role must in its Register role call QTSS_AddRole
and
specify QTSS_RTSPPostProcessor_Role
as
the role.
Modules should always return QTSS_NoErr
when
they finish handling this role.
RTP Roles
This section describes RTP roles, which are used to send data to clients and to handle the closing of client sessions.
RTP Send Packets Role
The server calls a module’s RTP Send Packets role when the
module calls QTSS_Play
.
It is the responsibility of the RTP Send Packets role to send media
data to the client and tell the server when the module’s RTP Send
Packets role should be called again.
When called, the RTP Send Packets role receives a QTSS_RTPSendPackets_Params
structure, which
is defined as follows:
typedef struct |
{ |
QTSS_ClientSessionObject inClientSession; |
SInt64 inCurrentTime; |
QTSS_TimeVal outNextPacketTime; |
} QTSS_RTPSendPackets_Params; |
inClientSession
The
QTSS_ClientSessionObject
object for the client session. See the section qtssClientSessionObjectType for information about client session object attributes.inCurrentTime
The current time in server time units.
outNextPacketTime
A time offset in milliseconds. Before returning from this role, a module should set
outNextPacketTime
to the amount of time that the server should allow to elapse before calling the RTP Send Packets role again for this session.
The RTP Send Packets role is invoked whenever a module calls QTSS_Play
for
that client session. The module calls QTSS_Write
or QTSS_WriteV
to
send data to the client.
While a module is handling the RTP Send Packets role, the
server guarantees that the module will not be called for any role
referencing the client session specified by inClientSession
.
A module that wants to be called in the RTP Send Packets role
must in its Register role call QTSS_AddRole
and
specify QTSS_RTPSendPackets_Role
as
the role.
Modules should always return QTSS_NoErr
when
they finish handling this role.
Client Session Closing Role
The server calls a module’s Client Session Closing role to allow the module to process the closing of client sessions.
When called, the Client Session Closing role receives a QTSS_ClientSessionClosing_Params
structure,
which is defined as follows:
typedef struct |
{ |
QTSS_ClientClosing inReason; |
QTSS_ClientSessionObject inClientSession; |
} QTSS_ClientSessionClosing_Params; |
inReason
The reason why the session is closing. The session may be closing because the client sent an RTSP teardown (
qtssCliSesClosClientTeardown
), because this session has timed out (qtssCliSesClosTimeout
), or because the client disconnected without issuing a teardown (qtssCliSesClosClientDisconnect
).inClientSession
The
QTSS_ClientSessionObject
object for the client session that is closing.
The Client Session Closing role is called whenever the client
session specified by inClientSession
is
about to be torn down.
While a module is handling the Client Session Closing role,
the server guarantees that the module will not be called for any
role referencing the client session specified by inClientSession
.
A module that wants to be called in the Client Session Closing
role must in its Register role call QTSS_AddRole
and
specify QTSS_ClientSessionClosing_Role
as
the role.
Modules should always return QTSS_NoErr
when
they finish handling this role.
RTCP Process Role
The server calls a module’s RTCP Process role whenever it receives an RTCP receiver report from a client.
RTCP receiver reports contain feedback from the client on
the quality of the stream. The feedback includes the percentage
of lost packets, the number of times the audio has run dry, and
frames per second. Many attributes in the QTSS_RTPStreamObject
correlate
directly to fields in the receiver report.
When called, the RTP Process role receives a QTSS_RTCPProcess_Params
structure,
which is defined as follows:
typedef struct |
{ |
QTSS_RTPStreamObject inRTPStream; |
QTSS_ClientSessionObject inClientSession; |
void* inRTCPPacketData; |
UInt32 inRTCPPacketDataLen; |
} QTSS_RTCPProcess_Params; |
inRTPStream
The
QTSS_RTPStreamObject
object for the RTP stream that this RTCP packet belongs to. See the section qtssRTPStreamObjectType for information about RTP stream object attributes.inClientSession
The
QTSS_ClientSessionObject
object for the client session. See the section qtssClientSessionObjectType for information about client session object attributes.inRTCPPacketData
A pointer to a buffer containing the packets that are to be processed.
inRTCPPacketDataLen
The length of valid data in the buffer pointed to by
inRTCPPacketData
.
A module handling the RTCP Process role typically monitors the status of the connection. It might, for example, track the percentage of packets lost for each connected client and update its counters.
While a module is handling the RTCP Process role, the server
guarantees that the module will not be called for any role referencing
the RTP stream specified by inRTPStream
.
A module that wants to be called in the RTCP Process role
must in its Register role call QTSS_AddRole
and
specify QTSS_RTCPProcess_Role
as
the role.
Modules should always return QTSS_NoErr
when
they finish handling this role.
QTSS Objects
QTSS objects provide a way for modules and the server to exchange
data with each other. QTSS objects consist of attributes that are
used to store data. Every attribute has a name, an attribute ID,
a data type, and permissions for reading and writing the attribute’s
value. Built-in attributes are attributes that the server always
defines for an object type. For example, the QTSS_RTSPRequestObject
object
has a built-in URL attribute that other modules can read to obtain
the URL associated with a particular RTSP request.
This section describes the attributes for each object type. The object types are
qtssAttrInfoObjectType
An object of type qtssAttrInfoObjectType
consists
of attributes whose values describe an attribute: the attribute’s
name, attribute ID, data type, and permissions for reading and writing
the attribute’s value. An attribute information object (QTSS_AttrInfoObject
)
is an instance of this object type. There is one QTSS_AttrInfoObject
for
every attribute.
Table 1-2 lists the attributes for objects of type qtssAttrInfoObjectType
.
Attribute Name and Description |
Access |
Data Type |
---|---|---|
|
Readable, preemptive safe |
QTSS_AttributeID |
|
Readable, preemptive safe |
QTSS_AttrDataType |
|
Readable, preemptive safe |
char |
|
Readable, preemptive safe |
QTSS_AttrPermission |
qtssClientSessionObjectType
An object of type qtssClientSessionObjectType
consists
of attributes that describe a client session, where a client session
is defined as a single client streaming presentation. A client session
object (QTSS_ClientSessionObject
)
is an instance of this object type. The attributes of a client session
object are valid for all roles that receive a value of type QTSS_ClientSessionObject
in
the structure the server passes to them.
Table 1-3 lists the attributes for objects of type qtssClientSessionObjectType
.
Attribute Name and Description |
Access |
Data Type |
---|---|---|
|
Readable, preemptive safe |
QTSS_TimeVal |
|
Readable, preemptive safe |
UInt32 |
|
Readable, preemptive safe |
QTSS_TimeVal |
|
Readable, preemptive safe |
UInt32 |
|
Readable, preemptive safe |
QTSS_TimeVal |
|
Readable, preemptive safe |
char |
|
Readable, preemptive safe |
char |
|
Readable, writable, preemptive safe |
UInt32 |
|
Readable, writable, preemptive safe |
Float64 |
|
Readable, writable, preemptive safe |
UInt64 |
|
Readable, preemptive safe |
Float32 |
|
Readable, preemptive safe |
QTSS_TimeVal |
|
Readable, preemptive safe |
char |
|
Readable, preemptive safe |
char |
|
Readable, preemptive safe |
SInt32 |
|
Readable, preemptive safe |
SInt32 |
|
Readable, preemptive safe |
QTSS_RTPSessionState |
|
Readable, preemptive safe |
QTSS_RTPStreamObject |
|
Readable, preemptive safe |
SInt64 |
|
Readable, preemptive safe |
UInt32 |
|
Readable, preemptive safe |
char |
|
Readable, preemptive safe |
char |
|
Readable, preemptive safe |
char |
|
Readable, preemptive safe |
char |
|
Readable, preemptive safe |
char |
|
Readable, preemptive safe |
char |
|
Readable, writable, preemptive safe |
QTSS_CliSesTeardownReason |
qtssConnectedUserObjectType
An object of type qtssConnectedUserObjectType
consists
of attributes associated with a connected user, irrespective of
the transport. Users connecting to a QuickTime movie are already
represented by objects of type qtssClientSessionObjectType
,
so this object is used for other connected users, such as those
requesting MP3 streams.
A connected user object (QTSS_ConnectedUserObject
)
is an instance of this object type. A QTSS_ConnectedUserObject
can
be created in any module. It can be added to the qtssSvrConnectedUsers
attribute
of the QTSS_ServerObject
(described
in the section “qtssServerObjectType”
).
Table 2-4
lists the
attributes for objects of type qtssConnectedUserObjectType
.
Attribute Name and Description |
Access |
Data Types |
---|---|---|
|
Readable, preemptive safe |
UInt32 |
|
Readable, preemptive safe |
QTSS_TimeVal |
|
Readable, preemptive safe |
UInt32 |
|
Readable, preemptive safe |
char |
|
Readable, preemptive safe |
char |
|
Readable, preemptive safe |
Float32 |
|
Readable, preemptive safe |
QTSS_TimeVal |
|
Readable, preemptive safe |
char |
|
Readable, preemptive safe |
char |
|
Readable, preemptive safe |
char |
qtssDynamicObjectType
An object of type qtssDynamicObjectType
can
be used to create an object that doesn’t have any static attributes.
qtssFileObjectType
An object of type qtssFileObject
consists
of attributes that describe a file that has been opened. A file
object (QTSS_FileObject
)
is an instance of this object type. These attributes are valid for
all roles that receive a QTSS_FileObject
in
the structure the server passes to them.
Table 1-5 lists the attributes for objects of type qtssFileObjectType
.
Attribute Name and Description |
Access |
Data Type |
---|---|---|
|
Readable, preemptive safe |
QTSS_StreamRef |
|
Readable, preemptive safe |
char |
|
Readable, writable, preemptive safe |
UInt64 |
|
Readable, writable, preemptive safe |
UInt64 |
|
Readable, writable, preemptive safe |
QTSS_TimeVal |
qttsModuleObjectType
An object of type qtssModuleObject
consists
of attributes that describe a particular QTSS module, including
its name, version number, a description of what the module does,
its preferences, and the roles the module is registered for. A module
object (QTSS_ModuleObject
)
is an instance of this object type. These attributes are valid for
all roles that receive a QTSS_ModuleObject
in
the structure the server passes to them.
For each module the server loads, the server creates a module
object and passes it to the module in the module’s Initialize
role. Modules can get information about other modules the server
has loaded by accessing the qtssSvrModuleObject
attribute
of the QTSS_ServerObject
object.
In addition to the attributes that store the module’s name,
version number and description, this object type has a module preferences
attribute, qtssModPrefs
.
The qtssModPrefs
attribute
itself is an object whose attributes store the module’s preferences
as instance attributes. All modifications to the qtssModPrefs
attribute
are persistent between invocations of the server because the contents
of each module’s qtssModPrefs
attribute
are written to the server’s configuration file, which is read
when the server starts up.
Table 1-6 lists the attributes for objects of type qtssModuleObjectType
.
Attribute Name and Description |
Access |
Data Type |
---|---|---|
|
Readable, writable, preemptive safe |
QTSS_Object |
|
Readable, writable not preemptive safe |
char |
|
Readable, preemptive safe |
char |
|
Readable, preemptive safe |
QTSS_ModulePrefsObject |
|
Readable, preemptive safe |
QTSS_Role |
|
Readable, writable, not preemptive safe |
UInt32 |
qtssModulePrefsObjectType
An object of type QTSS_ModulePrefsObject
consists
of attributes that contain a module’s preferences. A module preferences
object QTSS_ModulePrefsObject
)
is an instance of this object type.
Each module is reponsible for adding attributes to its module preferences object and setting their values. The values of the preferences in the module preferences object are persistent between invocations of the server because the server writes the module preferences object for each module to a configuration file that the server reads when it is started.
QTSSAccessLogModule Preferences
Table 1-7 lists the attributes for preferences of the module QTSSAccessLogModule
.
These preferences are maintained in the streamingserver.xml
file.
Attribute Name and Description |
Access |
Data Type |
---|---|---|
|
Readable, writable, not preemptive safe |
Bool16 |
|
Readable, writable, not preemptive safe |
UInt32 |
|
Readable, writable, not preemptive safe |
UInt32 |
|
Readable, writable, not preemptive safe |
Bool16 |
|
Readable, writable, not preemptive safe |
char |
|
Readable, writable, not preemptive safe |
char |
QTSSAccessModule Preferences
Table 1-8 lists the attributes for preferences of the module QTSSAccessModule
.
These preferences are maintained in the streamingserver.xml
file.
Attribute Name and Description |
Access |
Data Type |
---|---|---|
|
Readable, writable, not preemptive safe |
char |
|
Readable, writable, not preemptive safe |
char |
|
Readable, writable, not preemptive safe |
char |
QTSSAdminModule Preferences
Table 1-9 lists the attributes for preferences of the module QTSSAdminModule
.
These preferences are maintained in the streamingserver.xml
file.
Attribute Name and Description |
Access |
Data Type |
---|---|---|
|
Readable, writable, not preemptive safe |
char |
|
Readable, writable, not preemptive safe |
Bool16 |
|
Readable, writable, not preemptive safe |
Bool16 |
|
Readable, writable, not preemptive safe |
char |
|
Readable, writable, not preemptive safe |
Bool16 |
|
Readable, writable, not preemptive safe |
UInt32 |
QTSSFileModule Preferences
Table 1-10 lists the attributes for preferences of the module QTSSFileModule
.
These preferences are maintained in the streamingserver.xml
file.
Attribute Name and Description |
Access |
Data Type |
---|---|---|
|
Readable, writable, not preemptive safe |
Float32 |
|
Readable, writable, not preemptive safe |
char |
|
Readable, writable, not preemptive safe |
UInt32 |
|
Readable, writable, not preemptive safe |
Bool16 |
|
Readable, writable, not preemptive safe |
Bool16 |
|
Readable, writable, not preemptive safe |
Bool16 |
|
Readable, writable, not preemptive safe |
Bool16 |
|
Readable, writable, not preemptive safe |
UInt32 |
|
Readable, writable, not preemptive safe |
Float32 |
|
Readable, writable, not preemptive safe |
UInt32 |
|
Readable, writable, not preemptive safe |
UInt32 |
|
Readable, writable, not preemptive safe |
UInt32 |
|
Readable, writable, not preemptive safe |
UInt32 |
|
Readable, writable, not preemptive safe |
UInt32 |
|
Readable, writable, not preemptive safe |
UInt32 |
|
Readable, writable, not preemptive safe |
Bool16 |
|
Readable, writable, not preemptive safe |
char |
|
Readable, writable, not preemptive safe |
UInt32 |
QTSSFlowControlModule Preferences
Table 1-11 lists the attributes for preferences of the module QTSSFlowControlModule
.
These preferences are maintained in the streamingserver.xml
file.
Attribute Name and Description |
Access |
Data Type |
---|---|---|
|
Readable, writable, not preemptive safe |
Bool16 |
|
Readable, writable, not preemptive safe |
UInt32 |
|
Readable, writable, not preemptive safe |
UInt32 |
|
Readable, writable, not preemptive safe |
UInt32 |
|
Readable, writable, not preemptive safe |
UInt32 |
|
Readable, writable, not preemptive safe |
UInt32 |
QTSSHomeDirectoryModule Preferences
Table 1-12 lists the attributes for preferences of the module QTSSHomeDirectoryModule
. These
preferences are maintained in the streamingserver.xml
file.
Attribute Name and Description |
Access |
Data Type |
---|---|---|
|
Readable, writable, not preemptive safe |
Bool16 |
|
Readable, writable, not preemptive safe |
Bool16 |
|
Readable, writable, not preemptive safe |
UInt32 |
|
Readable, writable, not preemptive safe |
UInt32 |
QTSSMP3StreamingModule Preferences
Table 1-13 lists the attributes for preferences of the module QTSSMp3StreamingModule
.
These preferences are maintained in the streamingserver.xml
file.
Attribute Name and Description |
Access |
Data Type |
---|---|---|
|
Readable, writable, not preemptive safe |
char |
|
Readable, writable, not preemptive safe |
char |
|
Readable, writable, not preemptive safe |
Bool16 |
|
Readable, writable, not preemptive safe |
Bool16 |
|
Readable, writable, not preemptive safe |
char |
|
Readable, writable, not preemptive safe |
SInt32 |
|
Readable, writable, not preemptive safe |
UInt32 |
|
Readable, writable, not preemptive safe |
Bool16 |
|
Readable, writable, not preemptive safe |
UInt32 |
|
Readable, writable, not preemptive safe |
UInt32 |
|
Readable, writable, not preemptive safe |
Bool16 |
QTSSReflectorModule Preferences
Table 1-14 lists the attributes for preferences of the module QTSSReflectorModule
.
These preferences are maintained in the streamingserver.xml
file.
Attribute Name and Description |
Access |
Data Type |
---|---|---|
|
Readable, writable, not preemptive safe |
Bool16 |
|
Readable, writable, not preemptive safe |
Bool16 |
|
Readable, writable, not preemptive safe |
Bool16 |
|
Readable, writable, not preemptive safe |
Bool16 |
|
Readable, writable, not preemptive safe |
Bool16 |
|
Readable, writable, not preemptive safe |
char |
|
Readable, writable, not preemptive safe |
UInt32 |
|
Readable, writable, not preemptive safe |
Bool16 |
|
Readable, writable, not preemptive safe |
Bool16 |
|
Readable, writable, not preemptive safe |
Bool16 |
|
Readable, writable, not preemptive safe |
Bool16 |
|
Readable, writable, not preemptive safe |
Bool16 |
|
Readable, writable, not preemptive safe |
Bool16 |
|
Readable, writable, not preemptive safe |
Bool16 |
|
Readable, writable, not preemptive safe |
Bool16 |
|
Readable, writable, not preemptive safe |
char |
|
Readable, writable, not preemptive safe |
Bool16 |
|
Readable, writable, not preemptive safe |
UInt32 |
|
Readable, writable, not preemptive safe |
UInt16 |
|
Readable, writable, not preemptive safe |
UInt16 |
|
Readable, writable, not preemptive safe |
char |
|
Readable, writable, not preemptive safe |
char |
|
Readable, writable, not preemptive safe |
UInt32 |
|
Readable, writable, not preemptive safe |
UInt32 |
|
Readable, writable, not preemptive safe |
UInt32 |
|
Readable, writable, not preemptive safe |
UInt32 |
|
Readable, writable, not preemptive safe |
Bool16 |
|
Readable, writable, not preemptive safe |
UInt32 |
|
Readable, writable, not preemptive safe |
Bool16 |
QTSSRefMovieModule Preferences
Table 1-15 lists the attributes for preferences of the module QTSSRefMovieModule
,
which allows web developers to put RTSP URLs in web pages. These
preferences are maintained in the streamingserver.xml
file.
Attribute Name and Description |
Access |
Data Type |
---|---|---|
|
Readable, writable, not preemptive safe |
UInt16 |
|
Readable, writable, not preemptive safe |
Bool16 |
QTSSRelayModule Preferences
Table 1-16 lists the attributes for preferences of the module QTSSRelayModule
.
These preferences are maintained in the streamingserver.xml
file.
Attribute Name and Description |
Access |
Data Type |
---|---|---|
|
Readable, writable, not preemptive safe |
char |
|
Readable, writable, not preemptive safe |
char |
qtssPrefsObjectType
An object of type qtssPrefsObjectType
consists
of attributes that describe the server’s internal preference storage
system. A preference object (QTSS_PrefsObject
)
is an instance of this object type. The attribute values for objects
of this type are stored in the server’s configuration file, streamingserver.xml
.
For each server, there is a single instance of this object type.
In previous versions of the QTSS programming interface, module
preferences were stored in this object. Since version 4.0, module
preferences have been stored in each module’s QTSS_ModuleObject
object.
Table 1-17 lists the attributes for objects of type qtssPrefsObjectType
.
Attribute Name and Description |
Name in streamingserver.xml |
Access |
Data Type |
---|---|---|---|
|
|
Readable, writable, not preemptive safe |
Bool16 |
|
|
Readable, writable, not preemptive safe |
char |
|
|
Readable, writable, not preemptive safe |
SInt32 |
|
|
Readable, writable, not preemptive safe |
char |
|
|
Readable, writable, not preemptive safe |
Bool16 |
|
|
Readable, writable, not preemptive safe |
Bool16 |
|
|
Readable, writable, not preemptive safe |
Bool16 |
|
|
Readable, writable, not preemptive safe |
UInt32 |
|
|
Readable, writable, not preemptive safe |
Bool16 |
|
|
Readable, writable, not preemptive safe |
Bool16 |
|
|
Readable, writable, not preemptive safe |
char |
|
|
Readable, writable, not preemptive safe |
Bool16 |
|
|
Readable, writable, not preemptive safe |
Bool16 |
|
|
Readable, writable, not preemptive safe |
SInt32 |
|
|
Readable, writable, not preemptive safe |
SInt32 |
|
|
Readable, writable, not preemptive safe |
Bool16 |
|
|
Readable, writable, not preemptive safe |
Bool16 |
|
|
Readable, writable, not preemptive safe |
Bool16 |
|
|
Readable, writable, not preemptive safe |
Bool16 |
|
|
Readable, writable, not preemptive safe |
Bool16 |
|
|
Readable, writable, not preemptive safe |
UInt32 |
|
|
Readable, writable, not preemptive safe |
UInt32 |
|
|
Readable, writable, not preemptive safe |
SInt32 |
|
|
Readable, writable, not preemptive safe |
SInt32 |
|
|
Readable, writable, not preemptive safe |
UInt32 |
|
|
Readable, writable, not preemptive safe |
Float32 |
|
|
Readable, writable, not preemptive safe |
UInt32 |
|
|
Readable, writable, not preemptive safe |
UInt32 |
|
|
Readable, writable, not preemptive safe |
char |
|
|
Readable, writable, not preemptive safe |
char |
|
|
Readable, writable, not preemptive safe |
char |
|
|
Readable, writable, not preemptive safe |
UInt32 |
|
|
Readable, writable, not preemptive safe |
Float32 |
|
|
Readable, writable, not preemptive safe |
char |
|
|
Readable, writable, not preemptive safe |
char |
|
|
Readable, writable, not preemptive safe |
UInt32 |
|
|
Readable, writable, not preemptive safe |
Bool16 |
|
|
Readable, writable, not preemptive safe |
char |
|
|
Readable, writable, not preemptive safe |
Bool16 |
|
|
Readable, writable, not preemptive safe |
Bool16 |
|
|
Readable, writable, not preemptive safe |
UInt32 |
|
|
Readable, writable, not preemptive safe |
UInt32 |
|
|
Readable, writable, not preemptive safe |
UInt32 |
|
|
Readable, writable, not preemptive safe |
char |
|
|
Readable, writable, not preemptive safe |
UInt32 |
|
|
Readable, writable, not preemptive safe |
UInt32 |
|
|
Readable, writable, not preemptive safe |
char |
|
|
Readable, writable, not preemptive safe |
UInt32 |
|
|
Readable, writable, not preemptive safe |
char |
|
|
Readable, writable, not preemptive safe |
UInt32 |
|
|
Readable, writable, not preemptive safe |
UInt32 |
|
|
Readable, writable, not preemptive safe |
UInt32 |
|
|
Readable, writable, not preemptive safe |
Bool16 |
|
|
Readable, writable, not preemptive safe |
|
|
|
Readable, writable, not preemptive safe |
|
|
|
Readable, writable, not preemptive safe |
SInt32 |
|
|
Readable, writable, not preemptive safe |
Float32 |
|
|
Readable, writable, not preemptive safe |
UInt32 |
|
|
Readable, writable, not preemptive safe |
|
|
|
Readable, writable, not preemptive safe |
UInt32 |
|
|
Readable, writable, not preemptive safe |
UInt32 |
|
|
Readable, writable, not preemptive safe |
UInt32 |
This attribute is used for performance testing. When
set to |
|
Readable, writable, not preemptive safe |
Bool16 |
This attribute is used for compatibility with certain
players. It contains a list of players that, for compatibility,
require RTP header informatin. By default, the list consists of |
|
Readable, writable, not preemptive safe |
char |
This attribute is used for compatibility with certain players. |
|
Readable, writable, not preemptive safe |
char |
The built-in error log module that loads before all other modules uses the following seven attributes: |
|||
|
|
Readable, writable, not preemptive safe |
char |
|
|
Readable, writable, not preemptive safe |
Bool16 |
|
|
Readable, writable, not preemptive safe |
char |
|
|
Readable, writable, not preemptive safe |
UInt32 |
|
|
Readable, writable, not preemptive safe |
UInt32 |
|
|
Readable, writable, not preemptive safe |
UInt32 |
|
|
Readable, writable, not preemptive safe |
Bool16 |
qtssRTPStreamObjectType
An object of type qtssRTPStreamObjectType
consists
of attributes that describe a particular RTP stream whether it’s
an audio, video, or text stream. An RTP stream object (QTSS_RTPStreamObject
)
is an instance of this object type and is created by calling QTSS_AddRTPStream
.
An RTP stream object must be associated with a single client session object
(QTSS_ClientSessionObject
).
A client session object may be associated with any number of RTP
stream objects. These attributes are valid for all roles that receive
a QTSS_RTPStreamObject
in
the structure the server passes to them.
Table 1-18 lists the attributes for objects of type qtssRTPStreamObjectType
.
Attribute Name and Description |
Access |
Data Type |
---|---|---|
|
Readable, preemptive safe |
Float32 |
|
Readable, writable, preemptive safe |
SInt16 |
|
Readable, writable, preemptive safe |
SInt32 |
|
Readable, preemptive safe |
UInt32 |
|
Readable, writable, preemptive safe |
char |
|
Readable, writable, preemptive safe |
|
|
Readable, writable, preemptive safe |
UInt32 |
|
Readable, writable, preemptive safe |
SInt32 |
|
Readable, preemptive safe |
UInt32 |
The values of the following attributes come from the most recent RTCP packet received on a stream. If a field in the most recent RTCP packet is blank, the server sets the value of the corresponding attribute to zero. |
||
|
Readable, preemptive safe |
UInt16 |
|
Readable, preemptive safe |
UInt16 |
|
Readable, preemptive safe |
UInt16 |
|
Readable, preemptive safe |
UInt16 |
|
Readable, preemptive safe |
UInt16 |
|
Readable, preemptive safe |
UInt32 |
|
Readable, preemptive safe |
UInt16 |
|
Readable, preemptive safe |
UInt16 |
|
Readable, preemptive safe |
UInt16 |
|
Readable, preemptive safe |
Bool16 |
|
Readable, preemptive safe |
UInt32 |
|
Readable, preemptive safe |
UInt32 |
|
Readable, preemptive safe |
UInt32 |
|
Readable, preemptive safe |
UInt32 |
|
Readable, preemptive safe |
UInt16 |
|
Readable, preemptive safe |
UInt32 |
|
Readable, preemptive safe |
QTSS_StreamRef |
|
Readable, preemptive safe |
UInt32 |
|
Readable, preemptive safe |
UInt32 |
|
Readable, preemptive safe |
UInt16 |
|
Readable, preemptive safe |
UInt16 |
|
Readable, preemptive safe |
|
qtssRTSPHeaderObjectType
An object of type qtssRTSPHeaderObjectType
consists
of attributes containing all of the RTSP request headers associated
with an individual RTSP request. An RTSP header object (QTSS_RTSPHeaderObject
)
is an instance of this object type.
The names of the attributes are the names of the RTSP headers associated with that RTSP request. For example, the following RTSP request has a Session header and a User-agent header:
DESCRIBE /foo.mov RTSP/1.0 |
Session: 20fj02ijf |
User-agent: QTS/4.0.3 |
In this case, the value of the Session attribute is “20fj02ijf”
and the value of the User-agent attribute is “QTS/4.0.3”. Modules
can get the value of a given header by calling QTSS_GetValue
, QTSS_GetValueAsString,
or QTSS_GetValuePtr
.
qtssRTSPRequestObjectType
An object of type qtssRTSPRequestObjectType
consists
of attributes that describe a particular RTSP request. An RTSP request
object (QTSS_RTSPRequestObject
)
is an instance of this object type and exists from the time the
server receives a complete RTSP request from a client until the
response is sent and the server moves on to the next request. An RTSP
request object must be associated with a single RTSP session object (QTSS_RTSPSessionObject
)
for a given request made over a given connection.
With the exception of the RTSP Filter role, the value of each
attribute is available in all roles that receive an object of type QTSS_RTSPRequestObject
.
When the RTSP Filter role receives an object of type QTSS_RTSPRequestObject
,
the only attribute that has a value is the qtssRTSPReqFullRequest
attribute.
Each text name is identical to its enumerated type name.
Table 1-19 lists the attributes for objects of type qtssRTSPRequestObjectType
.
Attribute Name and Description |
Access |
Data Type |
---|---|---|
|
Readable, preemptive safe |
char |
|
Readable, preemptive safe |
UInt32 |
|
Readable, preemptive safe |
char |
|
Readable, preemptive safe |
char |
|
Readable, preemptive safe |
char |
|
Readable, preemptive safe |
char |
|
Readable, preemptive safe |
char |
|
Readable, preemptive safe |
QTSS_TimeVal |
|
Readable, preemptive safe |
Float32 |
|
Readable, preemptive safe |
QTSS_RTSPMethod |
|
Readable, preemptive safe |
char |
|
Readable, preemptive safe |
Bool16 |
|
Readable, preemptive safe |
UInt32 |
|
Readable, writable, preemptive safe |
Bool16 |
|
Readable, writable, preemptive safe |
char |
|
Readable, writable, preemptive safe |
char |
|
Readable, writable, preemptive safe |
Bool16 |
|
Readable, preemptive safe |
Float32 |
|
Readable, preemptive safe |
Float64 |
|
Readable, writable, preemptive safe |
QTSS_RTSPStatusCode |
|
Readable, preemptive safe |
Float64 |
|
Readable, preemptive safe |
QTSS_StreamRef |
|
Readable, preemptive safe |
char |
|
Readable, preemptive safe |
char |
|
Readable, writable, preemptive safe |
char |
|
Readable, preemptive safe |
char |
qtssRTSPSessionObjectType
An object of type qtssRTSPSessionObjectType
consists
of attributes associated with an RTSP client-server connection.
An RTSP session object (QTSS_RTSPSessionObject
)
is an instance of this object type and exists as long as the RTSP
client is connected to the server. These attributes are valid for
all roles that receive a QTSS_RTSPSessionObject
in
the structure the server passes to them.
Table 1-20 lists the attributes for objects of type qtssRTSPSessionObjectType
.
Attribute Name and Description |
Access |
Data Type |
---|---|---|
|
Readable, preemptive safe |
QTSS_EventContextRef |
|
Readable, preemptive safe |
UInt32 |
|
Readable, preemptive safe |
UInt32 |
|
Readable, preemptive safe |
char |
|
Readable, preemptive safe |
char |
|
Readable, preemptive safe |
UInt16 |
|
Readable, preemptive safe |
UInt32 |
|
Readable, preemptive safe |
char |
|
Readable, preemptive safe |
UInt16 |
|
Readable, preemptive safe |
QTSS_RTSPSessionStream |
|
Readable, preemptive safe |
QTSS_RTSPSessionType |
qtssServerObjectType
An object of type qtssServerObjectType
consists
of attributes that contain global server information, such as server
statistics. A server object (QTSS_ServerObject
is
an instance of this object type.There is a single instance of this
object type for each server. These attributes are valid for all
roles that receive a QTSS_ServerObject
in
the structure the server passes to them.
Table 1-21 lists the attributes for objects of type qtssServerObjectType
.
Attribute Name and Description |
Access |
Data Type |
---|---|---|
|
Readable, writable, preemptive safe |
UInt32 |
|
Readable, writable, preemptive safe |
UInt32 |
|
Readable, writable, preemptive safe |
UInt32 |
|
Readable, writable, preemptive safe |
UInt32 |
|
Readable, writable, preemptive safe |
UInt32 |
|
Readable, not preemptive safe |
UInt32 |
|
Readable, not preemptive safe |
UInt32 |
|
Readable, not preemptive safe |
UInt32 |
|
Readable, not preemptive safe |
UInt32 |
|
Readable, not preemptive safe |
UInt32 |
|
Readable, not preemptive safe |
UInt64 |
|
Readable, not preemptive safe |
UInt32 |
|
Readable, not preemptive safe |
UInt64 |
|
Readable, not preemptive safe |
UInt32 |
|
Readable, not preemptive safe |
UInt32 |
|
Readable, preemptive safe |
UInt32 |
|
Readable, preemptive safe |
char |
|
Read |
QTSS_Object |
|
Readable, writable, not preemptive safe |
QTSS_ConnectedUserObject |
|
Readable, not preemptive safe |
Float32 |
|
Readable, not preemptive safe |
QTSS_TimeVal |
|
Readable, preemptive safe |
char |
|
Readable, preemptive safe |
UInt32 |
|
Readable, preemptive safe |
SInt32 |
|
Readable, writable, not preemptive safe |
QTSS_RTSPMethod |
|
Readable, not preemptive safe |
Bool16 |
|
Readable, preemptive safe |
QTSS_Object |
|
Readable, preemptive safe |
QTSS_ModuleObject |
|
Readable, preemptive safe |
QTSS_PrefsObject |
|
Readable, not preemptive safe |
char |
|
Readable, preemptive safe |
char |
|
Readable, preemptive safe |
char |
|
Readable, preemptive safe |
char |
|
Readable, preemptive safe |
char |
|
Readable, preemptive safe |
QTSS_TimeVal |
|
Readable, writable, not preemptive safe |
QTSS_ServerState |
qtssTextMessageObjectType
An object of type qtssTextMessageObjectType
consists
of attributes whose values are intended for display to the user
or that are returned to the client. A text message object (QTSS_TextMessageObject
)
is an instance of this object type. To make localization easier,
the attribute values are text strings.
Table 1-22 lists the attributes for objects of type qtssTextMessageObjectType
.
Attribute Name and Description |
Access |
Data Type |
---|---|---|
|
Read only, preemptive safe |
char |
|
Read only, preemptive safe |
char |
|
Read only, preemptive safe |
char |
|
Read only, preemptive safe |
char |
|
Read only, preemptive safe |
char |
|
Read only, preemptive safe |
char |
|
Read only, preemptive safe |
char |
|
Read only, preemptive safe |
char |
|
Read only, preemptive safe |
char |
|
Read only, preemptive safe |
char |
|
Read only, preemptive safe |
char |
|
Read only, preemptive safe |
char |
|
Read only, preemptive safe |
char |
|
Read only, preemptive safe |
char |
|
Read only, preemptive safe |
char |
|
Read only, preemptive safe |
char |
|
Read only, preemptive safe |
char |
|
Read only, preemptive safe |
char |
|
Read only, preemptive safe |
char |
|
Read only, preemptive safe |
char |
|
Read only, preemptive safe |
char |
|
Read only, preemptive safe |
char |
|
Read only, preemptive safe |
char |
|
Read only, preemptive safe |
char |
|
Read only, preemptive safe |
char |
|
Read only, preemptive safe |
char |
|
Read only, preemptive safe |
|
|
Read only, preemptive safe |
char |
|
Read only, preemptive safe |
char |
|
Read only, preemptive safe |
char |
|
Read only, preemptive safe |
char |
|
Read only, preemptive safe |
char |
|
Read only, preemptive safe |
char |
|
Read only, preemptive safe |
char |
|
Read only, preemptive safe |
char |
|
Read only, preemptive safe |
char |
|
Read only, preemptive safe |
char |
|
Read only, preemptive safe |
char |
|
Read only, preemptive safe |
char |
|
Read only, preemptive safe |
|
|
Read only, preemptive safe |
|
|
Read only, preemptive safe |
|
|
Read only, preemptive safe |
char |
|
Read only, preemptive safe |
char |
qtssUserProfileObjectType
An object of type qtssUserProfileObjectType
consists
of attributes whose values describe a user’s profile.
Table 1-23 lists the attributes for objects of type qtssUserProfileObjectType
.
Attribute Name and Description |
Access |
Data Type |
---|---|---|
|
Readable, writable preemptive safe |
char |
|
Readable, writable preemptive safe |
char |
|
Readable, preemptive safe |
char |
|
Readable, writable preemptive safe |
char |
QTSS Streams
The QTSS programming interface provides QTSS stream references
as a generalized stream abstraction. Streams can be used for reading
and writing data to many types of I/O sources, including, but not
limited to files, the error log, and sockets and for communicating
with the client via RTSP or RTP. In all RTSP roles, for example,
modules receive an object of type QTSS_RTSPRequestObject
that
has a qtssRTSPReqStreamRef
attribute. The
value of this attribute is of type QTSS_StreamRef,
and
it can be used for sending RTSP response data to the client.
Unless otherwise noted, all streams are asynchronous. When
using the asynchronous QTSS file system callbacks, modules should
be prepared to receive the QTSS_WouldBlock
result
code, subject to the restrictions and rules of each stream type
described in this section. The QTSS_WouldBlock
error
is returned from a stream callback when completing the requested
operation would require the current thread to block. For instance, QTSS_Write
on a
socket will return QTSS_WouldBlock
if
the socket is currently subject to flow control. For information
on threading and asynchronous I/O, see the section Runtime Environment for QTSS Modules.
When a module receives the QTSS_WouldBlock
result
code, modules should call the QTSS_RequestEvent
callback
routine to request a notification from the server when the specified
stream becomes available for I/O. After calling QTSS_RequestEvent
,
the module should return control immediately to the server. The
module will be re-invoked in the same role in the exact same state
when the specified stream is available for I/O.
All stream references are of type QTSS_StreamRef
.
The QTSS programming interface uses following stream types:
QTSS_ErrorLogStream
Used for writing binary data to the server’s error log. There is a single instance of this stream type, which is passed to each module in the Initialize role. When data is written to this stream, modules that have registered for the Error Log role are invoked. For information about this role, see the section Error Log Role. All operations on this stream type are synchronous.
QTSS_FileStream
Represents a file and is obtained by making the
QTSS_OpenFileStream
callback. If the file stream is opened with theqtssFileStreamAsync
flag, callers should expect to receive a result code ofQTSS_WouldBlock
when they callQTSS_Read
,QTSS_Write
, andQTSS_WriteV
.QTSS_RTSPSessionStream
Used for reading data (
QTSS_Read
) from an RTSP client and writing data (QTSS_Write
orQTSS_WriteV
) to an RTSP client. The server may encounter flow control conditions, so modules should be prepared to handleQTSS_WouldBlock
result codes when reading from or writing to this stream type. CallingQTSS_Read
means that you are reading the request body sent by the client to the server. This stream reference is an attribute of the objectQTSS_RTSPSessionObject
.QTSS_RTSPRequestStream
Used for reading data (
QTSS_Read
) from an RTSP client and writing data (QTSS_Write
orQTSS_WriteV
) to an RTSP client. This stream is identical to theQTSS_RTSPSessionStream
stream except that data written to streams of this type is buffered in memory until a full RTSP response is constructed. Because the data is buffered internally, modules do not receiveQTSS_WouldBlock
errors when writing to streams of this type. CallingQTSS_Read
on this type of stream
means that you are reading the request body sent by the client to the server. Modules that callQTSS_Read to read this type of stream
should be prepared to handle a result code ofQTSS_WouldBlock
. This stream reference is an attribute of the objectQTSS_RTSPRequestObject
.QTSS_RTPStreamStream
Used for writing data to an RTP client. When writing to a stream of this type, a single write call corresponds to a single, complete RTP packet, including headers. Currently, it is not possible to use the
QTSS_RequestEvent
callback to receive events for this stream, so ifQTSS_Write
orQTSS_WriteV
returnsQTSS_WouldBlock
, modules must poll periodically for the blocking condition to be lifted. This stream reference is an attribute of the objectQTSS_RTPStreamObject
.QTSS_SocketStream
Represents a socket. This stream type allows modules to use the QTSS stream event mechanism (
QTSS_RequestEvent
) for raw socket I/O. (In fact, theQTSS_RequestEvent
callback is the only stream callback available for this type of stream.) Modules should read sockets asynchronously and should use the operating system’s socket function to read from and write to sockets. When those routines reach a blocking condition, the module can callQTSS_RequestEvent
to be notified when the blocking condition has cleared.
Table 1-24 uses an “X” to summarize the I/O-related callback routines that are appropriate for each type of stream.
Stream Type |
Read |
Seek |
Flush |
Advise |
Write |
WriteV |
RequestEvent |
SignalStream |
---|---|---|---|---|---|---|---|---|
File Stream |
X |
X |
X |
X |
X |
|||
Error Log |
X |
|||||||
Socket Stream |
X |
|||||||
RTSP Session Stream |
X |
X |
X |
X |
X |
|||
RTSP Request Stream |
X |
X |
X |
X |
X |
|||
RTP Stream |
X |
X |
X |
X |
QTSS Services
QTSS services are services the modules can access. The service may be a built-in service provided by the server or an added service provided by another module. An example of a service would be a logging module that allows other modules to write messages to the error log.
Modules use the callback routines described in the section Service Callback Routines to register and invoke services. Modules add and find services in a way that is similar to the way in which they add and find attributes of an object.
Every service has a name. To invoke a service, the calling module must know the name of the service and resolve that name into an ID.
Each service has its own specific parameter block format. Modules that export services should carefully document the services they export. Modules that call services should fail gracefully if the service isn’t available or returns an error.
A module that implements a service calls QTSS_AddService
in
its Register role to add the service to the server’s internal
database of services, as shown in the following code:
void MyAddService() |
{ |
QTSS_Error theErr = QTSS_AddService("MyService", &MyServiceFunction); |
} |
The MyServiceFunction
corresponds
to the name of a function that must be implemented in the same module.
Here is a stub implementation of the MyServiceFunction
:
QTSS_Error MyServiceFunction(MyServiceArgs* inArgs) |
{ |
// Each service function must take a single void* argument |
// Implement the service here. |
// Return a QTSS_Error. |
} |
To use a service, a module must get the service’s ID by
calling QTSS_IDForService
and providing
the name of the service as a parameter. With the service’s ID,
the module calls QTSS_DoService
to
cause the service to run, as shown in Listing 1-1.
Listing 1-1 Starting a service
void MyInvokeService() |
{ |
// Service functions take a single void* parameter that corresponds |
// to a parameter block specific to the service. |
MyServiceParamBlock theParamBlock; |
// Initialize service-specific parameters in the parameter block. |
theParamBlock.myArgument = xxx; |
QTSS_ServiceID theServiceID = qtssIllegalServiceID; |
// Get the service ID by providing the name of the service. |
QTSS_Error theErr = QTSS_IDForService(‘MyService’, &theServiceID); |
if (theErr != QTSS_NoErr) |
return; // The service isn’t available. |
// Run the service. |
theErr = QTSS_DoService(theServiceID, &theParamBlock); |
} |
Built-in Services
The QuickTime Streaming Server provides built-in services that modules may invoke using the service routines. In this version of the QTSS programming interface, there is one built-in service:
#define QTSS_REREAD_PREFS_SERVICE "RereadPreferences" |
Invoking the Reread Preferences service causes the server to reread its preferences and invoke each module in the Reread Preferences role, if they have registered for that role.
To invoke a built-in service, retrieve the service ID of the
service by calling QTSS_IDForService
.
Then call QTSS_DoService
to
run the service.
Automatic Broadcasting
The Streaming Server can accept RTSP ANNOUNCE requests from
QuickTime broadcasters. Support for ANNOUNCE requests and the ability
of the server to act as an RTSP client allow the server to initiate
new relay sessions. This section describes the two ways in which
an automatic broadcast can be initiated, how ANNOUNCE requests work with
SDP, and how the qtaccess
and qtusers
files
control automatic broadcasting.
Automatic Broadcasting Scenarios
QTSS supports two automatic broadcasting scenarios:
Pull then push. To initiate automatic broadcast, an RTSP client sends standard RTSP requests to request a stream and the server then relays the stream to one or more other streaming servers. This scenario is described in the section
“Pull Then Push”
.Listen then push. In this scenario, an automatic broadcast is initiated when the streaming server receives an ANNOUNCE request. This scenario is described in the section
“Listen Then Push”
.
Pull Then Push
The user can request a stream from a remote source by making
standard DESCRIBE/SETUP/PLAY requests and then relay it to one or
more destinations. This functionality can be useful when an organization
only wants one copy of an outside stream to consume bandwidth on
its Internet connection. The relay would sit just inside the corporate
network and push the stream to a reflector (possibly itself). Figure 2-7
provides
an example of the pull-then-push scenario.
Using Figure 2-7
as a reference, the steps for the pull-then-push scenario
are as follows:
Streaming Server A (the relay client) sends standard RTSP client DESCRIBE/SETUP/PLAY requests to a remote server, Streaming Server B.
The relay “client” (Streaming Server A) that requested the stream will begin receiving it and then send an ANNOUNCE to all of the destinations listed in the relay configuration for that particular incoming stream.
Listen Then Push
The streaming server can be configured to send incoming streams
created by an ANNOUNCE request to one or more destination machines
automatically. This can be useful for setting up an automated broadcast
network. Figure 2-8
provides an example of the pull-then-push scenario.
Using Figure 2-8
as a reference, the steps for the listen -then-push scenario
are as follows:
A remote machine (a broadcaster or a relay) sends an ANNOUNCE request to Streaming Server A. The streaming server may accept or deny the request. If it accepts the request, the streaming server checks its relay configuration to determined whether the stream should be relayed.
If the stream should be relayed, the streaming server will send standard RTSP client DESCRIBE/SETUP/PLAY request to itself.
The relay “client” (Streaming Server A) that requested the stream will begin receiving it and then send an ANNOUCE to all of the destinations listed in its relay configuration for that particular incoming stream.
By default, authentication is required for automatic broadcasts.
ANNOUNCE requests from broadcasters are filtered through the authentication
mechanism active in the server. To support broadcast authentication,
a new WRITE directive has been added to qtaccess file. The new directive
allows SDP files to be written to the movies
folder.
ANNOUNCE Requests and SDP
The ANNOUNCE request contains the Session Description Protocol (SDP) information for the broadcast. The ANNOUNCE request’s URI value may contain path delimiters in order to provide name space functionality.
When a broadcast is initiated by an ANNOUNCE request, the SDP information is stored in an in-memory broadcast list. To terminate a broadcast, the broadcaster sends to the server a TEARDOWN request, which causes the server to close the broadcast session and discard the SDP information. Similarly, dropped RTSP connections and broadcasters that do no send RTCP sender reports to the server within a 90-second window cause the server to close the broadcast session and discard the SDP information.
To support multiple SDP references to the same broadcast for announced UDP and TCP broadcasts, the port setting is zero in the ANNOUNCE header. Here is an example:
m=audio 0 RTP/AVP |
The a=x-urlmap tag is required to support sharing streams between broadcasts (where one stream comes from one broadcaster and another stream comes from another broadcaster). The a=x-urlmap tag should appear in the SDP that references the source SDP. Here is an example:
a=x-urlmap: someotherbroadcastURL/TrackID=1 |
Access Control of Announced Broadcasts
To control automatic broadcasting, two new user tags have
been defined in the qtaccess file. Table 2-25
lists the new tags.
Tag |
Purpose |
---|---|
|
Specifies that the user can have access to the requested movie
if the client provides a name and password that match an entry in
the qtusers file. The tag is written as |
|
Specifies that any user can have access to the requested movie,
with no requirement that the user be defined in the |
By default, the qtaccess
file
allows read access for all directives in the file. To allow announced
broadcasts, the qtaccess
file
must contain a Limit
directive
that allows writing.
The purpose of the Limit
directive
is to restrict the effect of access controls to RTSP readers or
writers. The following example limits the require
access
control so that only users defined in the qtusers
file
can RTSP PLAY a broadcast to the server. All other normal client PLAY
requests are available to any user:
<Limit WRITE> |
require valid-user |
</Limit> |
The following example allows movie viewing by any user in
the qtusers
file that
is in the movie_watchers
group
and the user john
. Broadcasters
must be in the movie_broadcasters
group
to broadcast to this directory or its protected branches.
<Limit READ> |
require group movie_watchers |
require user john |
</Limit> |
<Limit WRITE> |
require group movie_broadcasters |
</Limit> |
The following example has the same effect as the previous example. It works because the default behavior is to limit access to reading when no limit field is specified.
require group movie_watchers |
<Limit WRITE> |
require group movie_broadcasters |
</Limit> |
require user john |
The following example allows movie viewing and broadcasting
by any user in the qtusers
file
that is in the movie_watchers_and_broadcasters
group:
<Limit READ WRITE> |
require group movie_watchers_and_broadcasters |
</Limit> |
Broadcaster-to-Server Example
This section shows a typical exchange between a client and a server in order to initiate an announced broadcast. The following example shows a UDP multicast. Announced broadcasts can also set up requests with using unicast RTP/AVP/UDP streams as well as RTP/AVP/TCP interleaved streams. For more information, see RFC 2326.
Client to server:
ANNOUNCE rtsp://server.example.com/meeting RTSP/1.0 |
CSeq: 90 |
Content-Type: application/sdp |
Content-Length: 121 |
v=0 |
o=camera1 3080117314 3080118787 IN IP4 195.27.192.36 |
s=IETF Meeting, Munich - 1 |
i=The thirty-ninth IETF meeting will be held in Munich, Germany |
u=http://www.ietf.org/meetings/Munich.html |
e=IETF Channel 1 <ietf39-mbone@uni-koeln.de> |
p=IETF Channel 1 +49-172-2312 451 |
c=IN IP4 224.0.1.11/127 |
t=3080271600 3080703600 |
a=tool:sdr v2.4a6 |
a=type:test |
m=audio 0 RTP/AVP 5 |
a=control:trackID=1 |
c=IN IP4 224.0.1.11/127 |
a=ptime:40 |
m=video 0 RTP/AVP 31 |
a=control:trackID=2 |
c=IN IP4 224.0.1.12/127 |
Server to client:
RTSP/1.0 200 OK |
CSeq: 90 |
Client to server:
SETUP rtsp://server.example.com/meeting/trackID=1 RTSP/1.0 |
CSeq: 91 |
Transport: RTP/AVP;multicast;destination=224.0.1.11; |
client_port=21010-21011;mode=record;ttl=127 |
Server to client:
RTSP/1.0 200 OK |
CSeq: 91 |
Session: 50887676 |
Transport: RTP/AVP;multicast;destination=224.0.1.11; |
client_port=21010-21011;serverport=6000-6001;mode=receive;ttl=127 |
Client to server:
SETUP rtsp://server.example.com/meeting/trackID=2 RTSP/1.0 |
CSeq: 92 |
Session: 50887676 |
Transport: RTP/AVP;multicast;destination=224.0.1.12; |
client_port =61010-61011;mode=record;ttl=127 |
Server to client:
RTSP/1.0 200 OK |
CSeq: 92 |
Transport: RTP/AVP;multicast;destination=224.0.1.12; |
client_port =61010-61011;serverport=6002-6003;mode=record;ttl=127 |
Client to server:
RECORD rtsp://server.example.com/meeting RTSP/1.0 |
CSeq: 93 |
Session: 50887676 |
Server to client:
RTSP/1.0 200 OK |
CSeq: 93 |
Additional Trace Examples
This section provides three traces. The first trace is from the QuickTime Broadcaster, and it is sending MPEG 4 streams using TCP. The second trace is also from the QuickTime Broadcaster, but it is using UDP. The third trace is from RFC 2326 (RTSP) showing the ANNOUNCE and RECORD RTSP methods using UDP transport.
The broadcaster requests to notice are
RTSP ANNOUNCE to send the SDP file to the server
RTSP SETUP to send a Transport header setting
mode=record
; the direction of the stream is implicitly from the perspective of the serverRTSP RECORD to start the broadcast
The requests mirror the streaming client requests:
RTSP DESCRIBE to receive the SDP file from the server
RTSP SETUP to set up each stream
RTSP PLAY to start the streams
Trace of QuickTime Broadcaster Using TCP
Here is a trace of a QuickTime Broadcaster sending MPEG 4
streams using TCP. A TCP connection uses the same set of RTSP requests
with the standard specified transport of RTP/AVP/TCP and the port
identifier of interleaved=
for
each stream.
For this example, authentication and authorization has been
disabled by a qtaccess
file
to allow any user to annouce a broadcast. The broadcast file is
relative to the movies
directory. If
an SDP file already exists for the URL, it is replaced. Clients
that are already connected to the URL are not updated with the new
SDP as doing so would require a new DESCRIBE
from
the client, and there currently is no way to notify clients of the
SDP change.
Client to server:
ANNOUNCE rtsp://127.0.0.1/mystream.sdp RTSP/1.0\r\n |
CSeq: 1\r\n |
Content-Type: application/sdp\r\n |
User-Agent: QTS (qtver=6.1;cpu=PPC;os=Mac 10.2.3)\r\n |
Content-Length: 790\r\n |
\r\n |
c=IN IP4 |
127.0.0.1\ra=x-qt-text-nam:test\ra=x-qt-text-cpy:apple\ |
ra=x-qt-text-aut:john\ |
ra=x-qt-text-inf:none\ |
ra=mpeg4-iod:"data:application/ |
mpeg4-iod;base64,AoF/ |
AE8BAQEBAQOBEgABQHRkYXRhOmFwcGxpY2F0aW9uL21wZWc0LW9kLWF1O2Jhc2U2NCxBVGdC |
R3dVZkF4Y0F5U1FBWlFRTklCRUFGM0FBQVBvQUFBRERVQVlCQkFFWkFwOERGUUJsQlFRTlFC |
VUFCOUFBQUQ2QUFBQStnQVlCQXc9PQQNAQUAAMgAAAAAAAAAAAYJAQAAAAAAAAAAA2EAAkA+ |
ZGF0YTphcHBsaWNhdGlvbi9tcGVnNC1iaWZzLWF1O2Jhc2U2NCx3QkFTZ1RBcUJYSmhCSWhR |
UlFVL0FBPT0EEgINAAAUAAAAAAAAAAAFAwAAQAYJAQAAAAAAAAAA"\ra=isma- |
compliance:1,1.0,1\rm=audio 0 RTP/AVP 96\ra=rtpmap:96 |
X-QT/8000/1\ra=control:trackid=1\rm=video 0 RTP/AVP 97\ra=rtpmap:97 |
MP4V-ES\ra=fmtp:97 |
profile-level-id=1;config=000001B0F3000001B50EE040C0CF0000010000000120008440FA2850 20F0 |
A31F\ra=mpeg4-esid:201\ra=cliprect:0,0,240,320\ra=control:trackid=2\r |
Server to client:
RTSP/1.0 200 OK\r\n |
Server: QTSS/4.1.3.x (Build/425; Platform/MacOSX; Release/Development;)\r\n |
Cseq: 1\r\n |
\r\n |
Client to server:
// The broadcaster is trying to determine if RECORD is supported. QTSS 4.0 used an Apple |
// method of RECEIVE instead of the RECORD. |
OPTIONS rtsp://127.0.0.1/mystream.sdp RTSP/1.0\r\n |
CSeq: 2\r\n |
User-Agent: QTS (qtver=6.1;cpu=PPC;os=Mac 10.2.3)\r\n |
\r\n |
Server to client:
RTSP/1.0 200 OK\r\n |
Server: QTSS/4.1.3.x (Build/425; Platform/MacOSX; Release/Development;)\r\n |
Cseq: 2\r\n |
Public: DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE, ANNOUNCE, SET_PARAMETER, RECORD\r\n |
\r\n |
Client to server:
// Here is the first setup with the transport defined from the client to the |
// server. The URL is the same as when a client performs a setup requesting |
// a stream. QTSS does not allow a SETUP on a stream that is already set up |
// and will return an error. This can happen in two ways. |
// 1) A broadcast software error that does not change the URL. |
// 2) A broadcast dies without performing a teardown. In this case, the |
// broadcast session has to timeout and die before another setup can occur. |
// The server uses a short timeout of 20 seconds for broadcast sessions. The |
// timeout is refreshed by any packet received from the broadcaster. |
SETUP rtsp://127.0.0.1/mystream.sdp/trackid=1 RTSP/1.0\r\n |
CSeq: 3\r\n |
Transport: RTP/AVP/TCP;unicast;mode=record;interleaved=0-1\r\n |
User-Agent: QTS (qtver=6.1;cpu=PPC;os=Mac 10.2.3)\r\n |
Accept-Language: en-US\r\n |
\r\n |
Server to client:
// The server responds with the interleaved values. If the values conflict, |
// the client will change them so each stream has a unique set of |
// interleaved IDs. |
RTSP/1.0 200 OK\r\n |
Server: QTSS/4.1.3.x (Build/425; Platform/MacOSX; Release/Development;)\r\n |
Cseq: 3\r\n |
Cache-Control: no-cache\r\n |
Session: 6664885458621367225\r\n |
Date: Thu, 13 Feb 2003 21:34:27 GMT\r\n |
Expires: Thu, 13 Feb 2003 21:34:27 GMT\r\n |
Transport: RTP/AVP/TCP;unicast;mode=record;interleaved=0-1\r\n |
\r\n |
Client to server:
SETUP rtsp://127.0.0.1/mystream.sdp/trackid=2 RTSP/1.0\r\n |
CSeq: 4\r\n |
Transport: RTP/AVP/TCP;unicast;mode=record;interleaved=2-3\r\n |
Session: 6664885458621367225\r\n |
User-Agent: QTS (qtver=6.1;cpu=PPC;os=Mac 10.2.3)\r\n |
Accept-Language: en-US\r\n |
\r\n |
Server to client:
RTSP/1.0 200 OK\r\n |
Server: QTSS/4.1.3.x (Build/425; Platform/MacOSX; Release/Development;)\r\n |
Cseq: 4\r\n |
Session: 6664885458621367225\r\n |
Cache-Control: no-cache\r\n |
Date: Thu, 13 Feb 2003 21:34:27 GMT\r\n |
Expires: Thu, 13 Feb 2003 21:34:27 GMT\r\n |
Transport: RTP/AVP/TCP;unicast;mode=record;interleaved=2-3\r\n |
\r\n |
Client to server:
// This is the equivalent to a client PLAY request. The broadcaster is now |
// starting the streams. |
RECORD rtsp://127.0.0.1/mystream.sdp RTSP/1.0\r\n |
CSeq: 5\r\n |
Session: 6664885458621367225\r\n |
User-Agent: QTS (qtver=6.1;cpu=PPC;os=Mac 10.2.3)\r\n |
\r\n |
Server to client:
// RTCPs will be sent back on the channels to show the number of watching |
// clients. |
RTSP/1.0 200 OK\r\n |
Server: QTSS/4.1.3.x (Build/425; Platform/MacOSX; Release/Development;)\r\n |
Cseq: 5\r\n |
Session: 6664885458621367225\r\n |
RTP-Info: url=trackid=1,url=trackid=2\r\n |
\r\n |
Client to server:
PAUSE rtsp://127.0.0.1/mystream.sdp RTSP/1.0\r\n |
CSeq: 6\r\n |
Session: 6664885458621367225\r\n |
User-Agent: QTS (qtver=6.1;cpu=PPC;os=Mac 10.2.3)\r\n |
\r\n |
Server to client:
RTSP/1.0 200 OK\r\n |
Server: QTSS/4.1.3.x (Build/425; Platform/MacOSX; Release/Development;)\r\n |
Cseq: 6\r\n |
Session: 6664885458621367225\r\n |
\r\n |
Client to server:
// A TEARDOWN stops the broadcast streams. It does not stop the clients or |
// their streams. By default, QTSS allows a restarted or different broadcaster |
// to send to the same URL and the clients will receive the new streams. This |
// can be both good and bad since the broadcaster can change the stream media |
// type on the clients. The streamingserver.xml file provides an attribute |
// that allows the server to force clients to disconnect if the broadcaster |
// disconnects. The broadcast receiver is recommended to have a way for an |
// administrator or the broadcaster to tear down sessions that have failed. |
// The server adds a 30 second timeout between SSRC values to prevent someone |
// from pirating a stream. As long as a stream is playing with the initial |
// SSRC, another stream arriving on the same ports will not be reflected to |
// clients. Attempts to pirate a steam usually occur by accident when users |
// manually set their SDP ports. |
TEARDOWN rtsp://127.0.0.1/mystream.sdp RTSP/1.0\r\n |
CSeq: 7\r\n |
Session: 6664885458621367225\r\n |
User-Agent: QTS (qtver=6.1;cpu=PPC;os=Mac 10.2.3)\r\n |
\r\n |
Server to client:
// The server removes the SDP file from the movies directory on teardown or |
// broadcaster timeout. |
RTSP/1.0 200 OK\r\n |
Server: QTSS/4.1.3.x (Build/425; Platform/MacOSX; Release/Development;)\r\n |
Cseq: 7\r\n |
Session: 6664885458621367225\r\n |
Connection: Close\r\n |
\r\n |
Trace of UDP Broadcast with Negotiated Server Ports
The only significant addition to RFC 2326 is that when receiving
a broadcast over UDP, the QuickTime server uses SETUP with mode=RECORD
to
generate and send back to the client a UDP port to use when the
SDP contains a port value of 0 for a given stream. Otherwise, the
server uses the SDP-defined port to receive the streams. The server's
receive port is declared in the SETUP response transport header.
The format looks exactly as if a client were performing a SETUP
request for a stream from the server and then receiving the port the
server is sending from.
Client to server:
ANNOUNCE rtsp://127.0.0.1/mystream.sdp RTSP/1.0\r\n |
CSeq: 1\r\n |
Content-Type: application/sdp\r\n |
User-Agent: QTS (qtver=6.1;cpu=PPC;os=Mac 10.2.3)\r\n |
Content-Length: 790\r\n |
\r\n |
c=IN IP4 |
127.0.0.1\ra=x-qt-text-nam:test\ra=x-qt-text-cpy:apple\ |
ra=x-qt-text-aut:john\ |
ra=x-qt-text-inf:none\ |
ra=mpeg4-iod:"data:application/ |
mpeg4-iod;base64,AoF/ |
AE8BAQEBAQOBEgABQHRkYXRhOmFwcGxpY2F0aW9uL21wZWc0LW9kLWF1O2Jhc2U2NCxBVGdC |
R3dVZkF4Y0F5U1FBWlFRTklCRUFGM0FBQVBvQUFBRERVQVlCQkFFWkFwOERGUUJsQlFRTlFC |
VUFCOUFBQUQ2QUFBQStnQVlCQXc9PQQNAQUAAMgAAAAAAAAAAAYJAQAAAAAAAAAAA2EAAkA+ |
ZGF0YTphcHBsaWNhdGlvbi9tcGVnNC1iaWZzLWF1O2Jhc2U2NCx3QkFTZ1RBcUJYSmhCSWhR |
UlFVL0FBPT0EEgINAAAUAAAAAAAAAAAFAwAAQAYJAQAAAAAAAAAA"\ra=isma- |
compliance:1,1.0,1\rm=audio 0 RTP/AVP 96\ra=rtpmap:96 |
X-QT/8000/1\ra=control:trackid=1\rm=video 0 RTP/AVP 97\ra=rtpmap:97 |
MP4V-ES\ra=fmtp:97 |
profile-level-id=1;config=000001B0F3000001B50EE040C0CF0000010000000120008440FA2850 20F0 |
A31F\ra=mpeg4-esid:201\ra=cliprect:0,0,240,320\ra=control:trackid=2\r |
Server to client:
RTSP/1.0 200 OK\r\n |
Server: QTSS/4.1.3.x (Build/425; Platform/MacOSX; Release/Development;)\r\n |
Cseq: 1\r\n |
\r\n |
Client to server:
OPTIONS rtsp://127.0.0.1/mystream.sdp RTSP/1.0\r\n |
CSeq: 2\r\n |
User-Agent: QTS (qtver=6.1;cpu=PPC;os=Mac 10.2.3)\r\n |
\r\n |
Server to client:
RTSP/1.0 200 OK\r\n |
Server: QTSS/4.1.3.x (Build/425; Platform/MacOSX; Release/Development;)\r\n |
Cseq: 2\r\n |
Public: DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE, ANNOUNCE, SET_PARAMETER, RECORD\r\n |
\r\n |
Client to server:
SETUP rtsp://127.0.0.1/mystream.sdp/trackid=1 RTSP/1.0\r\n |
CSeq: 3\r\n |
Transport: RTP/AVP;unicast;client_port=6974-6975;mode=record\r\n |
User-Agent: QTS (qtver=6.1;cpu=PPC;os=Mac 10.2.3)\r\n |
Accept-Language: en-US\r\n |
\r\n |
Server to client:
RTSP/1.0 200 OK\r\n |
Server: QTSS/4.1.3.x (Build/425; Platform/MacOSX; Release/Development;)\r\n |
Cseq: 3\r\n |
Cache-Control: no-cache\r\n |
Session: 1549167172936112945\r\n |
Date: Thu, 13 Feb 2003 21:59:22 GMT\r\n |
Expires: Thu, 13 Feb 2003 21:59:22 GMT\r\n |
Transport: |
RTP/AVP;unicast;client_port=6974-6975;mode=record;source=127.0.0.1; |
server_port=6976-6977\r\n |
\r\n |
Client to server:
SETUP rtsp://127.0.0.1/mystream.sdp/trackid=2 RTSP/1.0\r\n |
CSeq: 4\r\n |
Transport: RTP/AVP;unicast;client_port=6972-6973;mode=record\r\n |
Session: 1549167172936112945\r\n |
User-Agent: QTS (qtver=6.1;cpu=PPC;os=Mac 10.2.3)\r\n |
Accept-Language: en-US\r\n |
\r\n |
Server to client:
RTSP/1.0 200 OK\r\n |
Server: QTSS/4.1.3.x (Build/425; Platform/MacOSX; Release/Development;)\r\n |
Cseq: 4\r\n |
Session: 1549167172936112945\r\n |
Cache-Control: no-cache\r\n |
Date: Thu, 13 Feb 2003 21:59:22 GMT\r\n |
Expires: Thu, 13 Feb 2003 21:59:22 GMT\r\n |
Transport: |
RTP/AVP;unicast;client_port=6972-6973;mode=record;source=127.0.0.1; |
server_port=6978-6979\r\n |
\r\n |
Client to server:
RECORD rtsp://127.0.0.1/mystream.sdp RTSP/1.0\r\n |
CSeq: 5\r\n |
Session: 1549167172936112945\r\n |
User-Agent: QTS (qtver=6.1;cpu=PPC;os=Mac 10.2.3)\r\n |
\r\n |
Server to client:
RTSP/1.0 200 OK\r\n |
Server: QTSS/4.1.3.x (Build/425; Platform/MacOSX; Release/Development;)\r\n |
Cseq: 5\r\n |
Session: 1549167172936112945\r\n |
RTP-Info: url=trackid=1,url=trackid=2\r\n |
\r\n |
Trace of ANNOUNCE and RECORD Using UDP Transport
The following trace example of ANNOUNCE and RECORD RTSP methods using UDP transport is from RFC 2326. The conference participant client asks the media server to record the audio and video portions of a meeting. The client uses the ANNOUNCE method to provide meta-information about the recorded session to the server.
Client to server:
ANNOUNCE rtsp://server.example.com/meeting RTSP/1.0 |
CSeq: 90 |
Content-Type: application/sdp |
Content-Length: 121 |
v=0 |
o=camera1 3080117314 3080118787 IN IP4 195.27.192.36 |
s=IETF Meeting, Munich - 1 |
i=The thirty-ninth IETF meeting will be held in Munich, Germany |
u=http://www.ietf.org/meetings/Munich.html |
e=IETF Channel 1 <ietf39-mbone@uni-koeln.de> |
p=IETF Channel 1 +49-172-2312 451 |
c=IN IP4 224.0.1.11/127 |
t=3080271600 3080703600 |
a=tool:sdr v2.4a6 |
a=type:test |
m=audio 21010 RTP/AVP 5 |
c=IN IP4 224.0.1.11/127 |
a=ptime:40 |
m=video 61010 RTP/AVP 31 |
c=IN IP4 224.0.1.12/127 |
Server to client:
RTSP/1.0 200 OK |
CSeq: 90 |
Client to server:
SETUP rtsp://server.example.com/meeting/audiotrack RTSP/1.0 |
CSeq: 91 |
Transport: RTP |
AVP;multicast;destination=224.0.1.11;port=21010-21011;mode=record;ttl=127 |
Server to client:
RTSP/1.0 200 OK |
CSeq: 91 |
Session: 50887676 |
Transport: RTP |
AVP;multicast;destination=224.0.1.11;port=21010-21011;mode=record;ttl=127 |
Client to server:
SETUP rtsp://server.example.com/meeting/videotrack RTSP/1.0 |
CSeq: 92 |
Session: 50887676 |
Transport: RTP/ |
AVP;multicast;destination=224.0.1.12;port=61010-61011;mode=record;ttl=127 |
Server to client:
RTSP/1.0 200 OK |
CSeq: 92 |
Transport: RTP |
AVP;multicast;destination=224.0.1.12;port=61010-61011;mode=record;ttl=127 |
Client to server:
RECORD rtsp://server.example.com/meeting RTSP/1.0 |
CSeq: 93 |
Session: 50887676 |
Range: clock=19961110T1925-19961110T2015 |
Server to client:
RTSP/1.0 200 OK |
CSeq: 93 |
Stream Caching
This version of QTSS includes RTSP and RTP features that make it as easy for a caching proxy server to capture and manage a pristine copy of a media stream. Some of these features are elements of RTSP that were not supported in previous versions of QTSS, and other features are additions to RTSP and RTP. The features are
Speed RTSP header. This version of QTSS supports the speed header wherever possible. The speed header allows a caching proxy server to request that a stream be delivered faster than real time so that the caching proxy server can move the stream into the cache as quickly as possible. This header is described in the section
“Speed RTSP Header”
.x-Transport-Options RTSP header. This version of QTSS supports the non-standard RTSP header,
x-Transport-Options
. Caching proxy servers can use this header to tell the streaming server how late packets the streaming server can send packets and have them still be useful to the caching proxy server. This header is described in the section“x-Transport-Options Header”
.RTP payload meta-information. This version of QTSS fully supports RTP payload meta-information (an IETF draft), which includes information such as the packet transmission time, unique packet number, and video frame type. Caching proxy servers can use this information to provide the same quality of service to clients as the originating server. This header is described in the section
“RTP Payload Meta-Information”
.x-Packet-Range RTSP header. This version of QTSS supports the non-standard RTSP header,
x-Packet-Range
. This header is similar to theRange
RTSP header but allows the client to specify a specific range of packets instead of a range of time. A caching proxy server can use thex-Packet-Range
header to tell the originating server to selectively retransmit only those packets that the caching proxy server needs in order to fill in holes in its cached copy of the stream. This header is described in the section“x-Packet-Range RTSP Header”
.
The following sections describe each of these features.
Speed RTSP Header
Clients can send to the server the optional Speed RTSP header to request that the server send data to the client at a particular speed. The server must respond by echoing the Speed RTSP header to the client. If the server does not echo the Speed RTSP header, the client must assume that the server cannot accommodate the request at this time. The server may modify the value of the Speed RTSP header argument. If the server modifies the value of the argument, the client must accept the modified value.
The value of the Speed
RTSP
header argument is expressed as a decimal ratio. The following example
asks the server to send data twice as fast as normal:
Speed: 2.0 |
If the request also contains a Range argument, the new speed value will take effect at the specified time.
This header is intended for use when preview of the presentation at a higher or lower rate is necessary. Bandwidth for the session may have been negotiated earlier (by means other than RTSP), and therefore re-negotiation may be necessary.
When data is delivered over UDP, it is highly recommended that means such as RTCP be used to track packet loss rates.
x-Transport-Options Header
The optional x-Transport-Options
RTSP
header should be sent from a client (typically a caching proxy server)
to the server in an RTSP SETUP request and must echoed by the server.
If the server does not echo the x-Transport-Options
header,
the client must assume that the server does not support this header.
The server may modify the value of the x-Transport-Options
header
argument. If the server modifies the value of the argument, the
client must accept the modified value.
The body of this header contains one or more arguments delimited by the semicolon character. For this version of QTSS, there is only one argument, the late-tolerance argument.
The value of the late-tolerance
argument
is a positive integer that represents the number of seconds late
that the server can send a media packet and still have it be useful
to the client. The server should use the value of the late-tolerance
argument
as a guide for making a best-effort attempt to deliver all media
data so that the delivered data is no older than the late-tolerance
value.
Here is an example:
x-Transport-Options: late-tolerance=30 |
If this example were for a video stream, the server would send all video frames that are less than 30 seconds old. The server would drop frames that are more than 30 seconds old because they are stale.
Caching proxy servers can use the x-Transport-Options
header
to prevent the media server from dropping frames or lowering the
stream bit rate in the event it falls behind in sending media data.
If the caching proxy server knows the duration of the media, it
can prevent the server from dropping any frames by setting the late-tolerance
argument
to the duration of the media, allowing the cache to receive a complete
copy of the media data.
For a live broadcast, a caching proxy server may want to do
extra buffering to improve quality for its clients. It could use
the x-Transport-Options
header
to advertise the length of its buffer to the server.
RTP Payload Meta-Information
Certain RTP clients, such as caching proxy servers, require per-packet meta information that goes beyond the sequence number and timestamp already provided in the RTP header. For instance, a caching proxy server may want to provide stream thinning to its clients in case those clients are bandwidth constrained. If that stream thinning is based on the type of video frame being sent by the originating server, there is no payload-independent way for the caching proxy server to determine the frame type.
The RTP payload meta-information solves this deficiency by
including information that RTP clients can use to provide the same
quality of service to clients as the originating server. The following
section, “RTP Data”
, describes the RTP data that the server delivers in
the RTP payload meta-information type.
RTP Data
The server uses the RTP payload meta-information type to provide the following information to the RTP client:
Transmission time, described in the section
“Transmission Time”
Frame type, described in the section
“Frame Type”
Packet number, described in the section
“Packet Number”
Packet position, described in the section
“Packet Position”
Media data, described in the section
“Media Data”
Sequence number, described in the section
“Sequence Number”
Transmission Time
The server sends the transmission time as a single four-octet unsigned integer representing the recommended transmission time of the RTP packet in milliseconds.
The transmission time is always offset from the start of the media presentation. For example, if the SDP response for a URL includes a range of 0-729.45 and the client makes a PLAY request with a range of 100-729.45, the first RTP packet from the server should provide a transmission time value of approximately 100,000. (It may not be exactly 100,000 because the server is free to find a frame nearby the requested time.) If the SDP for a URL does not contain a range, the client can at least use these values as relative offsets.
Frame Type
The server sends the frame type as a single 16-bit unsigned integer value for which several well-known values representing different frame types are defined. The well-known values are as follows:
0 represents an unknown frame type
1 represents a key frame
2 represents a b-frame
3 represents a p-frame
Packet Number
The server sends the packet number as a single 64-bit unsigned integer value. The value is the packet number offset from the absolute start of the stream. For example, if the SDP response for a URL includes a range of 0-729.45 and the client makes a PLAY request with a range of 0-729.45, the packet number value of the first packet will be 0 and will increment by 1 for each subsequent packet. If there are 1000 packets between in the first 60 seconds of a stream and a client makes a PLAY request of 60-729.45, the packet number of the first packet will be 1001 and will increment by 1 for each subsequent packet.
Packet Position
The server sends the packet position as a single 64-bit unsigned integer value. The value is the byte offset of this packet from the absolute start of the stream. For example, if the SDP response for a URL includes a range of 0-729.45 and the client makes a PLAY request with a range of 100-729.45, the packet position value of the first video RTP packet will be the total number of bytes of the video RTP packets between 0 and 100. Only the RTP packet payload bytes are used to compute each packet position value.
The server cannot provide the packet position for live or dynamic media. In general, if the media SDP has a range attribute, the server can provide the packet position.
Media Data
The server sends media data for the underlying RTP protocol.
Sequence Number
The server sends the RTP sequence number as a two-octet value. The sequence number is useful for mapping RTP meta-information to the underlying payload data that they refer to, if that data is being sent out-of-band.
Standard Format
The RTP payload meta-information returned by the server consists of a series of fields. Each field consists of a header and data. When returned in standard format, the first bit of the header is zero to indicate that the field is in standard format (that is, not compressed).
The first bit is followed by the 15-bit Name subfield. The
Name subfield contains two ASCII alphanumeric characters that represent
one of the RTP data types listed in the section “RTP Data”
. The first character
is seven bits long, so the value of the Name subfield must consist
of seven-bit ASCII characters.
Table 2-26
lists the
Name subfield values for each of the RTP data types.
RTP data type |
Name subfield value |
---|---|
Transmission time |
|
Frame type |
|
Packet number |
|
Packet position |
|
Media |
|
Sequence number |
|
The Name subfield is followed by a two-octet Length subfield that contains the full length of the Data subfield.
Figure 2-9
shows the
format of the Name subfield in standard format.
Figure 2-10
shows the
format of the RTP data in standard format.
Compressed Format
When the server provides a field of RTP meta-information in compressed format, the field consists of a header and data. The first bit of the header is set to one to indicate that the rest of the header is in compressed format.
The first bit is followed by a seven-bit ID subfield that
identifies the type of data in the Data subfield. The meaning of
the ID subfield is assigned by the server, as described in the section “x-RTP-Meta-Info RTSP Header Negotiation”
.
The ID subfield is followed by the one-octet Length subfield that contains the full length of the Data subfield that follows the Length subfield.
Figure 2-11
shows the
format of the ID subfield in compressed format.
Figure 2-12
shows an
RTP payload meta-information packet when some fields are in compressed
format and some fields are in standard format.
Negotiation for Use of Compressed Format
Use of the compressed format requires out-of-band negotiation
between client and server. During the negotiation process, the server
assigns a seven-bit ID for each RTP data type. Instead sending the
name of the RTP data type (for example, ft
)
in the RTP payload, only the ID is sent.
Negotiation for using the compressed format can occur in two ways:
Through the x-RTP-Meta-Info RTSP header, described in the section
“x-RTP-Meta-Info RTSP Header Negotiation”
Through the SDP description of the data, described in the section
“Describing RTP-Meta-Info Payload in SDP”
x-RTP-Meta-Info RTSP Header Negotiation
The client can negotiate compression with the server for any payload by sending an x-RTP-Meta-Info RTSP header to the server in a SETUP request. If the server does not echo the header in its SETUP response, the client must assume that the server does not support this header.
The client’s SETUP request specifies the RTP data types the client wants to receive in the specified RTP stream. Here is an example of a client request:
x-RTP-Meta-Info: to;bi;bo |
The server’s response lists the names of the RTP data that the server will provide for that RTP stream. If the server supports the compressed format, the response may also contain ID mappings for some or all of the names. The server may return a subset of the names if it doesn’t support all of the requested names, or if some requested names don’t apply to the RTP stream specified by the SETUP request. Here are two examples of a server response:
x-RTP-Meta-Info: to=0;bi;bo=1 |
x-RTP-Meta-Info: to;bi |
In the first response, the server indicates that it will provide bi data in standard format. The server will send to data in compressed format and use an ID of 0 to indicate fields that contain to data. The server will send bo data in compressed format and use an ID of 1 to indicate fields that contain bo data. Because IDs are represented by seven bits, an ID must be between 0 and 127.
In the second response, the server indicates that it will provide to and bi data in standard format.
Describing RTP-Meta-Info Payload in SDP
The originator of RTP-Meta-Info payload packets should describe the contents of the payload as part of the SDP description of the media. RTP-Meta-Info descriptions consist of two additional a= headers.
The a=x-embedded-rtpmap
header
tells the client the payload type of the underlying RTP payload.
The a=x-RTP-Meta-Info
header
tells the client the RTP data types the server will provide. Here
is an example of an SDP description of the RTP-Meta-Info payload:
m=other 5084 RTP/AVP 96 |
a=rtpmap:96 x-RTP-Meta-Info |
a=x-embedded-rtpmap:96 x-QT} |
a=x-RTP-Meta-Info: standard;to;bi;bo |
x-Packet-Range RTSP Header
The x-Packet-Range RTSP header allows the client (typically a caching proxy server) to specify a range of packets that the server should retransmit, thereby allowing the client to fill in holes in its cached copy of the stream. The client should send the x-Packet-Range RTSP header in a PLAY request in place of the Range header. If the server does not support this header, it sends the client a “501 Header Not Implemented” response.
The body of this header contains a start and stop packet number for this PLAY request. The specified packet numbers must be based on the packet number RTP-Meta-Info field. For information on how to request packet numbers as part of the RTP stream, see the RTP-Meta-Info payload format IETF Draft.
The header format consists of two arguments delimited by the semicolon character. The first argument must be the packet number range, with the start and stop packet numbers separated by a hyphen (-). The second argument must be the stream URL to which the specified packets belong.
The following example requests packet numbers 4551 through 4689 for trackID3:
x-Packet-Range: pn=4551-4689;url=trackID3 |
The stop packet number must be equal to or greater than the start packet number. Otherwise, the server may return an error or may not send any media data after the PLAY response.
Reliable UDP
Reliable UDP is a set of quality of service enhancements, such as congestion control tuning improvements, retransmit, and thinning server algorithms, that improve the ability to present a good quality RTP stream to RTP clients even in the presence of packet loss and network congestion. Reliable UDP’s congestion control mechanisms allow streams to behave in a TCP-friendly fashion without disturbing the real-time nature of the protocol.
To work well with TCP traffic on the Internet, Reliable UDP uses retransmission and congestion control algorithms similar to the algorithms used by TCP. Additionally, these algorithms are time-tested to utilize available bandwidth optimally.
Relibable UDP features include
Client acknowledgment of packets sent by the server to the client
Windowing and congestion control so the server does not exceed the currently available bandwidth
Server retransmission to the client in the event of packet loss
Faster than real-time streaming known as “overbuffering”
Whether a client uses Reliable UDP is determined by the content of the client’s RTSP SETUP request.
Acknowledgment Packets
When using Reliable UDP, the server expects to receive an acknowledgment for each RTP packet it sends. If the server does not receive an acknowledgment for a packet, it may retransmit the packet. The client does not need to send an acknowledgment packet for each RTP packet it receives. Instead, the client can coalesce acknowledgments for several packets and send them to the server in a single packet.
The Reliable UDP acknowledgment packet format is a type of RTCP APP packet. After the standard RTCP APP packet headers, the payload for an acknowledgment packet consists of an RTP sequence number followed by a variable length bit mask. The sequence number identifies the first RTP packet that the client is acknowledging. Each additional RTP packet being acknowledged is represented by a bit set in the bitmask. The bit mask is an offset from the specified sequence number, where the high order bit of the first byte in the mask is one greater than the sequence number, the second bit is two greater, and so on. Bit masks must be sent in multiples of four octets. Setting a bit to 0 in the mask simply means that the client does not wish to acknowledge this sequence number right now and does not imply a negative acknowledgment.
Figure 2-13
shows the
format of the Reliable UDP acknowledgment packet.
RTSP Negotiation
Whether to use Reliable UDP is negotiated out of band in RTSP.
If a client wants to use Reliable UDP, it should include an x-Retransmit
header in its RTSP SETUP request. The body of the header contains
the retransmit protocol name (our-retransmit
)
followed by a list of arguments delimited by the semicolon character.
Currently, one argument can be passed from the client to the server: the window argument. If included, the window argument tells the Reliable UDP server the size of the client’s window in KBytes.
Here is an example:
x-Retransmit: our-retransmit;window=128 |
The server must echo the header and all parameters. If the x-Retransmit header is not in the SETUP response, the client must assume that Reliable UDP will not be used for this stream. If the server changes the parameter values, the client must use the new values.
Tunneling RTSP and RTP Over HTTP
Using standard RTSP/RTP, a single TCP connection can be used to stream a QuickTime presentation to a user. Such a connection is not sufficient to reach users on private IP networks behind firewalls where HTTP proxy servers provide clients with indirect access to the Internet. To reach such clients, QuickTime 4.1 supports the placement of RTSP and RTP data in HTTP requests and replies. As a result, viewers behind firewalls can access QuickTime presentations through HTTP proxy servers.
The QuickTime HTTP transport is built from two separate HTTP GET and POST method requests initiated by the client. The server then binds the connections to form a virtual full-duplex connection. The protocol that forms this type of connection is must meet the following requirements:
Work with unmodified RTSP/RTP packets
Be acceptable to HTTP proxy servers
Indicate to proxy servers that requests and replies are not to be cached
Work in an environment where the client originates all requests
Provide a way to uniquely identify request pairs so that they can be bound together to form a full-duplex connection
Ensure that related requests connect to the same RTSP server in spite of load-balancing algorithms such as round-robin DNS servers
Identify any request as one that will eventually tunnel an RTSP conversation and RTP data
The QuickTime HTTP transport exploits the capability of HTTP’s
GET and POST methods to carry an indefinite amount of data in their
reply and message body respectively. In the most simple case, the
client makes an HTTP GET request to the server to open the server-to-client
connection. Then the client makes a HTTP POST request to the server
to open the client-to-server connection. The resulting virtual full-duplex
connection (shown in Figure 2-14
) makes it possible to send unmodified RTSP and RTP data
over the connection.
HTTP Client Request Requirements
To work with the QuickTime HTTP transport, client HTTP requests must
Be made using HTTP version 1.0
Include in the header an
x-sessioncookie
directive whose value is a globally unique identifier (GUID). The GUID makes it possible for the server to unambiguously bind the two connections by passing it as an opaque token to the C librarystrcmp
functionIn POST requests, the
application/x-rtsp-tunneled
MIME type for both theContent-Type
andAccept
directives must be specified; this MIME type reflects the data type that is expected and delivered by the client and serverDirect POST requests to the specified IP address if a server’s reply to an initial GET request includes the
x-server-ip-address
directive and an IP address
In addition to these requirements, client HTTP POST request headers may include other directives in order to help HTTP proxy servers handle RTSP streams optimally.
Sample Client GET Request
Here is an example of a client GET request:
GET /sw.mov HTTP/1.0 |
User-Agent: QTS (qtver=4.1;cpu=PPC;os=Mac8.6) |
x-sessioncookie: tD9hKgAAfB8ABCftAAAAAw |
Sample Client POST Request
Here is an example of a client POST request:
POST /sw.mov HTTP/1.0 |
User-Agent: QTS (qtver=4.1;cpu=PPC;os=Mac8.6) |
Content-Type: application/x-rtsp-tunnelled |
Pragma: no-cache |
Cache-Control: no-cache |
Content-Length: 32767 |
Expires: Sun, 9 Jan 1972 00:00:00 GMT |
The sample client POST request includes three optional header directives that are present to control the behavior of HTTP proxy servers so that they handle RTSP streams optimally:
The
Pragma: no-cache
directive tells many HTTP 1.0 proxy servers not to cache the transaction.The
Cache-Control: no-cache
directive tells many HTTP 1.1 proxy servers not to cache the transaction.The
Expires
directive specifies an arbitrary time in the past. This directive is intended to prevent proxy servers from caching the transaction.
HTTP requires that all POST requests have a content-length header. In the sample client POST request, the content length of 32767 is an arbitrary value. In practice, the actual value seems to be ignored by proxy servers, so it is possible to send more than this amount of data in the form of RTSP requests. The QuickTime Server ignores the content-length header.
HTTP Server Reply Requirements
When the server receives an HTTP GET request from a client,
it must respond with a reply whose header specifies the application/x-rtsp-tunneled
MIME
type for both the Content-Type
and Accept
directives.
Server reply headers may optionally include the Cache-Control:
no-store
and Pragma: no-cache
directives
to prevent HTTP proxy servers from caching the transaction. It is recommended
that implementations honor these headers if they are present.
Server clusters are often allocated connections by a round-robin
DNS or other load-balancing algorithm. To insure that client requests
are directed to the same server among potentially several servers
in a server farm, the server may optionally include the x-server-ip-address
directive
followed by an IP address in dotted decimal format in the header
of its reply to a client’s initial GET request. When this directive
is present, the client must direct its POST request to the specified
IP address regardless of the IP address returned by a DNS lookup.
In the absence of an HTTP error, the server reply header contains “200 OK”. An HTTP error in a server reply reflects the inability of the server to form the virtual full-duplex connection; an HTTP error does not imply an RTSP error. When an HTTP error occurs, the server simply closes the connection.
Sample Server Reply to a GET Request
Here is an example of a server reply to a GET request:
HTTP/1.0 200 OK |
Server: QTSS/2.0 [v101] MacOSX |
Connection: close |
Date: Thu, 19 Aug 1982 18:30:00 GMT |
Cache-Control: no-store |
Pragma: no-cache |
Content-Type: application/x-rtsp-tunnelled |
Including the following header directives in a reply is not required but is recommended because the directives they tell proxy servers to behave in a way that allows them to handle RTSP streams optimally:
The
Date
directive specifies an arbitrary time in the past. This keeps proxy servers from caching the transaction.The
Cache-Control: no-cache
directive tells many HTTP 1.1 proxy servers not to cache the transaction.The
Pragma: no-cache
directive tells many HTTP 1.0 proxy servers not to cache the transaction.
RTSP Request Encoding
RTSP requests made by the client on the POST connection must be encoded using the base64 method. (See RFC 2045 “Internet Message Bodies”, section 6.8, Base64 Content-Transfer-Encoding, and RFC 1421 “Privacy Enhancements for Electronic Mail,” section 4.3.2.4, Printable Encoding.) The base64 encoding prevents HTTP proxy server from determining that an embodied RTSP request is a malformed HTTP requests.
Here is a sample RTSP request before it is encoded:
DESCRIBE rtsp://tuckru.apple.com/sw.movRTSP/1.0 |
CSeq: 1 |
Accept: application/sdp |
Bandwidth: 1500000 |
Accept-Language: en-US |
User-Agent: QTS (qtver=4.1;cpu=PPC;os=Mac8.6) |
Here is the same request after encoding:
REVTQ1JJQkUgcnRzcDovL3R1Y2tydS5hcHBsZS5jb20vc3cubW92IFJUU1AvMS4w |
DQpDU2VxOiAxDQpBY2N1cHQ6IGFwcGxpY2F0aW9uL3NkcA0KQmFuZHdpZHRo0iAx |
NTAwMDAwDQpBY2N1cHQtTGFuZ3VhZ2U6IGVuLVVTDQpVc2VyLUFnZW50OiBRVFMg |
KHF0dmVyPTQuMTtjcHU9UFBDO29zPU1hYyA4LjYpDQoNCg== |
Connection Maintenance
The client may close the POST connection at any time. Doing so frees socket and memory resources at the server that might otherwise be unused for a long time. In QuickTime HTTP streaming, the best time to close the POST connection usually occurs after the PLAY request.
Support For Other HTTP Features
Support for HTTP features that are not documented here is not required in order to implement the tunneling of QuickTime RTSP and RTP over HTTP. The tunnel should mimic a normal TCP connection as closely as possible without adding unnecessary features.
Copyright © 2002, 2009 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2009-06-01