Live555 Source Analysis: generatesdpdescription_live555

Source: Internet
Author: User
[3]generatesdpdescription
With the above knowledge, we will continue to look at the processing of rtspserver::rtspclientconnection::handlecmd_describe.
[cpp]  View Plain  copy   Void rtspserver::rtspclientconnection::handlecmd_describe (char  CONST* URLPRESUFFIX, CHAR CONST* URLSUFFIX, CHAR CONST* FULLREQUESTSTR)    {       char* sdpDescription = NULL;        char* rtspURL = NULL;       do {            char urlTotalSuffix[RTSP_PARAM_STRING_MAX];            if  (strlen (urlpresuffix)  + strlen ( Urlsuffix)  + 2 > sizeof urltotalsuffix             {                Handlecmd_bad ();               break;            }           urltotalsuffix [0] =  ';   '         if  (urlpresuffix[0)  !=  ' a ')            {                strcat (Urltotalsuffix, urlpresuffix);               strcat (urlTotalSuffix,  "/");            }            strcat (urltotalsuffix, urlsuffix);   //formatted request flow information             if  (!authenticationok ("DESCRIBE",  urltotalsuffix, fullrequeststr))  break;  //user authentication            // We  should really check that the request contains an  "Accept:"  #####            // for  "APPLICATION/SDP",  because that ' S what  we ' re sending back #####  //Unfortunately now the code is not verified             // Begin by looking up the  "Servermediasession"   object for the specified  "Urltotalsuffix":            servermediasession* session = fourserver.lookupservermediasession (UrlTotalSuffix);   //Find Servermediasession session based on the stream specified in the request. In the current analysis, Testondemandrtpserver is using rtspserver::lookupservermediasession,  to find only from the created reply. The Dynamicrtspserver overloaded this function, first calling the parent class Rtpserver's lookupservermediasession, and then checking whether it exists, and creating a new one if it does not exist.            if  (session == null)            {                handlecmd_notfound ();                break;           }            // Then, assemble a SDP description for this  session:           sdpDescription = session-> Generatesdpdescription ()//Get SDP description information, describe command main content             if  (sdpdescription == null)            {                // this usually  means that a file name that was specified for a               //  "Servermediasubsession"  does not  exist.               setrtspresponse ("404  file not found, or in incorrect format ");                break;            }           unsigned sdpdescriptionsize  = strlen (sdpdescription);           // also,  generate our RTSP URL, for the  "Content-base:"  header           //  (which is necessary to ensure  that the correct URL gets used in subsequent  "SETUP"   Requests) .    &NBSp;      rtspurl = fourserver.rtspurl (Session, fClientInputSocket );  generates content-base content:rtsp url           snprintf ( char*) fresponsebuffer, sizeof fresponsebuffer,                 "rtsp/1.0 200 ok\r\ncseq: %s\r\n"                  "%s"                  "content-base: %s/\r\n"                  "content-type: application/sdp\r\n"                  "content-length: %d\r\n\r\n"                 '%s ',                fcurrentcseq,                dateheader (),                rtspURL,                sdpdescriptionsize,                Sdpdescription);                The response of               //splicing describe        } while  (0);       delete[]  sdpdescription;       delete[] rtspURL;  }  

In the processing of the describe command, the main content is the right to authenticate, this in the previous Live555 source code analysis [2]:rtspserver in the user authentication said. The other is the SDP information that returns the request stream. This is accomplished by generatesdpdescription.


In Servermediasession::generatesdpdescription () basically are fixed string stitching, we need to focus on the
    [cpp]  View plain  copy  // count the lengths of each  Subsession ' s media-level sdp lines.      //  (we do this  first, because the call to  "Subsession->sdplines ()"        // causes correct subsession  ' duration () ' s to be calculated  Later.)   /Generate sdplines and compute the length of the stitching process at the end, but the purpose here is to invoke Subsession's duration interface to return the length of the media file        unsigned sdpLength = 0;      ServerMediaSubsession*  subsession;      for  (subsession = fsubsessionshead; subsession  != NULL;    subsession = subsession->fnext)  {         char const* sdplines = subsession->sdplines ();    //returned at this time, although not used,But the interior is well preserved, the back stitching is called again, but it is returned directly. In fact, live555 does not delete the used SMS and SMSS by default, so this will not generate         if  again when the second request for this media stream sdplines == null)  continue; // the media ' s not available        sdplength += strlen (sdplines);      }       if  (sdplength == 0)  break; // the session has  no usable subsessions            // unless  subsessions have differing durations, we also have a  "A=range:"  line:      float dur = duration ()    //return media length   



Ondemandservermediasubsession::sdplines () is implemented as follows
[cpp]  View Plain  copy   Char const* ondemandservermediasubsession::sdplines ()      {       if  (fsdplines == null)  {           // we need to construct a set  of SDP lines that describe this subsession  (as a unicast  stream) . to do so, we first create            // dummy  (unused)  source and  "Rtpsink"  objects,  whose parameters we use for the sdp lines:            unsigned estBitrate;            framedsource* inputsource = createnewstreamsource (0, estbitrate);            if  (inputsource == null)  return null; // file not  found                 struct in_ addr dummyaddr;           dummyaddr.s_addr = 0 ;           groupsock dummygroupsock (EnviR (),  dummyaddr, 0, 0);           unsigned char  rtppayloadtype = 96 + tracknumber () -1; // if dynamic           RTPSink* dummyRTPSink                = createnewrtpsink (&dummyGroupsock,  Rtppayloadtype, inputsource);           if  ( Dummyrtpsink != null &amP;& dummyrtpsink->estimatedbitrate ()  > 0)  estbitrate = dummyrtpsink- >estimatedbitrate ();                  Setsdplinesfromrtpsink (dummyrtpsink, inputsource, estbitrate);            medium::close (dummyrtpsink);            closestreamsource (InputSource);       }             return fSDPLines;  }  

The Createnewstreamsource and Createnewrtpsink are virtual functions, which are realized by the concrete servermediasubsession.
The Framedsource subclass Framedfilter provides a function of an abstract data source, its inheritance relationship mediasource->framedsource->framedfilter, which masks the difference of different types of data sources. Rtpsource is responsible for the handling of RTP message encapsulation.
After creating the temporary source and sink, get sdpline from the sink, some media types read the file header, some need to play a video first, such as H.264 ... In order to get the SDP information correctly ... The details have not been studied,

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.