Basic Process of RTSP server processing client on-demand video
Transferred from:
Http://blog.csdn.net/huangxinfeng/archive/2010/03/22/5404233.aspx
The basic process for processing connection requests:
L step 1: Establish a RTSP connection with the client (call the incomingconnectionhandler method), create a clientsession, and associate fclientsocket with incomingrequesthandler (call incomingconnectionhandler1 ).
L step 2: receive client requests (call the incomingrequesthandler method ).
L step 3: read data from the client socket and convert the request data (that is, the request string) (call the parsertsprequeststring method, which is in the rtspcommon class ).
L step 4: Separate the commands:
N options → handleapps_options
N describe → handleapps_describe
Handlecmd_describe is an important method. First, you can use urlsuffix to check whether servermediasession exists (call the lookupservermediasession method, and use hashtable to find it in this method ).
In the testondemandrtspserver project, only the streamname is used to check whether the session is null. In the complete live555mediaserver project, it is processed through the dynamicrtspserver class. First, it is to find whether the file exists. If the file does not exist, it is determined whether servermediasession (smsexists) exists, if yes, remove the file (call the removeservermediasession method). If the file exists, create a servermediasession Based on the file name (call the createnewsms method. If the corresponding file extension cannot be found in this method, returns NULL ).
If the returned value through lookupservermediasession is null, the system sends a Response Message to the client and sets fsessionisactive to false. Otherwise, an SDP description is assembled for the session (the generatesdpdescription method is called, this method is in the servermediasession class). After assembly, an rtsp url is generated (call the rtspurl method, which is in the rtspserver class ).
N setup → handleapps_setup
In the handleapps_setup method, there are two key terms: urlpresuffix, representing the session name (Stream name); urlsuffix, representing the subsession name (track name ), the streamname and trackID used later are related to these two terms.
Next, we will create the session's state, including incrementreferencecount. Next, we will find the corresponding information for the specified subsession (track. Next, find a "Transport:" header in the request string to extract some parameters of the client request (call the parsetransportheader method, which is in the rtspserver class ), such as clientsdestinationaddressstr and clientrtpportnum.
Next, getstreamparameters (this method is defined as a pure virtual function in the servermediasession class and is redefined in the ondemandservermediasubsession class), and then different response messages are assembled through fismulticast and streamingmode.
N play → handle+_play: process the playback request. For the specific implementation process, see the subsequent steps.
N pause → handleapps_pause: process the paused request. After the request is executed, the stopplaying method is called and the farecurrentlyplaying is set to false.
N teardown → handle+_teardown: process the stop request and set fsessionisactive to false.
N get_parameter → handleapps_get_parameter: This method is mainly used to maintain the survival state of the client-server communication, just for keep alive.
N set_parameter → handlecmd_set_parameter: This method is not implemented for set_parameter. Using this method, the handlecmd_notsupported method is called and the client is eventually disconnected.
L step 5: Perform message response (call the send method) based on different instructions in Step 4. The message response is instant.
L step 6: handle special cases where the client starts playing after sending the "setup" command.
L step 7: reset requestbuffer to prepare for subsequent requests.
L step 8: Check whether fsessionisactive is false. If yes, delete the current clientsession.
The basic process for processing play:
L step 1: handling rtspurl and related headers involves many details.
L step 2: scale or locate the stream based on different headers.
If it is sawscaleheader, the scaling ratio is processed (call the setstreamscale method, which is implemented in the ondemandservermediasubsession class ).
If it is a sawrangeheader, the stream is searched for (that is, the stream is located, and the seekstream method is called. This method is implemented in the ondemandservermediasubsession class; at the same time, this method is called for a series of requests generated by dragging the playback progress bar before and during the initial playback ).
In the ondemandservermediasubsession class, the seekstream method calls the seekstreamsource method, which is implemented in the fileservermediasubsession class of the corresponding Media Format File (for example, for WAV format, it is implemented in the wavaudiofileservermediasubsession class; for MP3 format, it is implemented in the mp3audiofileservermediasubsession class ).
Similarly, the setstreamsourcescale method called in the setstreamscale method in the ondemandservermediasubsession class is also similar to the implementation mechanism.
L step 3: Start stream playback (call the startstream method, which is implemented in the ondemandservermediasubsession class ).
N Step 3.1: Find destinations from fdestinationshashtable Based on clientsessionid (including the Client IP address, RTP Port Number, RTCP port number, and other information ).
N Step 3.2: Call the startplaying method. In this method, call the startplaying Method Based on rtpsink or udpsink.
If the startplaying method of rtpsink is called, The startplaying method in the mediasink class is called, And the continueplaying method in the multiframedrtpsink class is called in this method, followed by buildandsendpacket. The focus is on constantly reading frames and sending them. In the multiframedrtpsink class, a loop is formed through buildandsendpacket, packframe, aftergettingframe, aftergettingframe1, sendpacketifnecessary, and sendnext. The reading and sending of data packets are carried out cyclically here. Note that the Code (nexttask () = envir () following the sendpacketifnecessary method is used (). taskscheduler (). scheduledelayedtask (usecondstogo, (taskfunc *) sendnext, this);), continue to the next task through delay amount of time, and return to continue to call the buildandsendpacket method.
In the packframe method, normally, the getnextframe method needs to be called (this method is in the framedsource class and obtaining frames of different media formats appears in the getnextframe method of the framedsource class, by calling the dogetnextframe method) to obtain the new frame.
If you call the startplaying method of udpsink, The startplaying method in the mediasink class is called and the continueplaying method in the basicudpsink class is called in this method. After that, several methods form a cycle: continueplaying1, aftergettingframe, aftergettingframe1, and sendnext. The aftergettingframe1 method implements packet sending (FGS-> output (envir (), FGS-> TTL (), foutputbuffer, framesize );).
Step 3.3: Create an RTCP instance for rtpsink (the supporting use of RTP and RTCP determines that this is required; otherwise, it may be the same as sending data packets directly using UDP ), when creating an RTCP instance, use the incomingreporthandler handle as the backgroundhandlerproc to process the RTCP report and start startnetworkreading. Here, there are two ways to use RTP/RTCP: one is built on TCP and the other is built on UDP.