Exemplo n.º 1
0
QTSS_Error ProcessRTSPRequest(QTSS_StandardRTSP_Params* inParams)
{
    QTSS_RTSPMethod* theMethod = NULL;
    UInt32 theMethodLen = 0;
    if ((QTSS_GetValuePtr(inParams->inRTSPRequest, qtssRTSPReqMethod, 0,
            (void**)&theMethod, &theMethodLen) != QTSS_NoErr) || (theMethodLen != sizeof(QTSS_RTSPMethod)))
    {
        Assert(0);
        return QTSS_RequestFailed;
    }
    
    switch (*theMethod)
    {
        case qtssDescribeMethod:
            return DoDescribe(inParams);
        case qtssSetupMethod:
            return DoSetup(inParams);
        case qtssPlayMethod:
            return DoPlay(inParams);
        case qtssTeardownMethod:
            // Tell the server that this session should be killed, and send a TEARDOWN response
            (void)QTSS_Teardown(inParams->inClientSession);
            (void)QTSS_SendStandardRTSPResponse(inParams->inRTSPRequest, inParams->inClientSession, 0);
            break;
        case qtssPauseMethod:
            (void)QTSS_Pause(inParams->inClientSession);
            (void)QTSS_SendStandardRTSPResponse(inParams->inRTSPRequest, inParams->inClientSession, 0);
            break;
        default:
            break;
    }           

    return QTSS_NoErr;
}
QTSS_Error ProcessRTSPRequest(QTSS_StandardRTSP_Params* inParams)
{
    QTSS_RTSPMethod* theMethod = NULL;

	UInt32 theLen = 0;
    if ((QTSS_GetValuePtr(inParams->inRTSPRequest, qtssRTSPReqMethod, 0,
            (void**)&theMethod, &theLen) != QTSS_NoErr) || (theLen != sizeof(QTSS_RTSPMethod)))
    {
        Assert(0);
        return QTSS_RequestFailed;
    }

    if (*theMethod == qtssDescribeMethod)
        return DoDescribe(inParams);
    if (*theMethod == qtssSetupMethod)
        return DoSetup(inParams);
        
    RTPSessionOutput** theOutput = NULL;
    QTSS_Error theErr = QTSS_GetValuePtr(inParams->inClientSession, sOutputAttr, 0, (void**)&theOutput, &theLen);
    if ((theErr != QTSS_NoErr) || (theLen != sizeof(RTPSessionOutput*))) // a broadcaster push session
    {   if (*theMethod == qtssPlayMethod || *theMethod == qtssRecordMethod)
            return DoPlay(inParams, NULL);
        else
            return QTSS_RequestFailed;
    }

    switch (*theMethod)
    {
        case qtssPlayMethod:
            return DoPlay(inParams, (*theOutput)->GetReflectorSession());
        case qtssTeardownMethod:
            // Tell the server that this session should be killed, and send a TEARDOWN response
            (void)QTSS_Teardown(inParams->inClientSession);
            (void)QTSS_SendStandardRTSPResponse(inParams->inRTSPRequest, inParams->inClientSession, 0);
            break;
        case qtssPauseMethod:
            (void)QTSS_Pause(inParams->inClientSession);
            (void)QTSS_SendStandardRTSPResponse(inParams->inRTSPRequest, inParams->inClientSession, 0);
            break;
        default:
            break;
    }           
    return QTSS_NoErr;
}
Exemplo n.º 3
0
void RTPSessionOutput::TearDown()
{
    QTSS_CliSesTeardownReason reason = qtssCliSesTearDownBroadcastEnded;
    (void)QTSS_SetValue(fClientSession, qtssCliTeardownReason, 0, &reason, sizeof(reason));     
    (void)QTSS_Teardown(fClientSession);
}
Exemplo n.º 4
0
QTSS_Error DoDescribe(QTSS_StandardRTSP_Params* inParamBlock)
{
    // Check and see if this is a request we should handle. We handle all requests with URLs that
    // end in a '.rtp'
    char* theFullPathStr = NULL;
    QTSS_Error theError = QTSS_GetValueAsString(inParamBlock->inRTSPRequest, qtssRTSPReqLocalPath, 0, &theFullPathStr);
	QTSSCharArrayDeleter theFullPathDeleter(theFullPathStr);
    Assert(theError == QTSS_NoErr);
    
    StrPtrLen theFullPath(theFullPathStr);
    
    if ((theFullPath.Len <= sRTPSuffix.Len) ||
        (!sRTPSuffix.NumEqualIgnoreCase(&theFullPath.Ptr[theFullPath.Len - sRTPSuffix.Len], sRTPSuffix.Len)))
        return QTSS_RequestFailed;
    
    // It is, so let's set everything up...
    
    //
    // Get the FileSession for this DESCRIBE, if any.
    UInt32 theLen = sizeof(FileSession*);
    FileSession*    theFile = NULL;
    QTSS_Error      theErr = QTSS_NoErr;

    (void)QTSS_GetValue(inParamBlock->inClientSession, sFileSessionAttr, 0, (void*)&theFile, &theLen);

    if ( theFile != NULL )  
    {
        //
        // There is already a file for this session. This can happen if there are multiple DESCRIBES,
        // or a DESCRIBE has been issued with a Session ID, or some such thing.
        
        if ( !theFullPath.Equal( *theFile->fFile.GetMoviePath() ) )
        {
            delete theFile;
            theFile = NULL;
            
            // NULL out the attribute value, just in case.
            (void)QTSS_SetValue(inParamBlock->inClientSession, sFileSessionAttr, 0, &theFile, sizeof(theFile));
        }
    }
    
    if ( theFile == NULL )
    {   
        theErr = CreateRTPFileSession(inParamBlock, theFullPath, &theFile);
        if (theErr != QTSS_NoErr)
        {
            (void)QTSS_Teardown(inParamBlock->inClientSession);
            return theErr;
        }
    
        // Store this newly created file object in the RTP session.
        theErr = QTSS_SetValue(inParamBlock->inClientSession, sFileSessionAttr, 0, &theFile, sizeof(theFile));
    }
    
    //generate the SDP.
    UInt32 totalSDPLength = sSDPHeader1.Len;
    iovec theSDPVec[10];//1 for the RTSP header, 6 for the sdp header, 1 for the sdp body
    theSDPVec[1].iov_base = sSDPHeader1.Ptr;
    theSDPVec[1].iov_len = sSDPHeader1.Len;
    
    //filename goes here
    //(void)QTSS_GetValuePtr(inParamBlock->inRTSPRequest, qtssRTSPReqFilePath, 0, (void**)&theSDPVec[2].iov_base, (UInt32*)&theSDPVec[2].iov_len);
	char* filenameStr = NULL;
	(void)QTSS_GetValueAsString(inParamBlock->inRTSPRequest, qtssRTSPReqFilePath, 0, &filenameStr);
    QTSSCharArrayDeleter filenameStrDeleter(filenameStr);
	theSDPVec[2].iov_base = filenameStr;
	theSDPVec[2].iov_len = ::strlen(filenameStr);
	
    totalSDPLength += theSDPVec[2].iov_len;
    
    //url & admin email goes here
    theSDPVec[3].iov_base = sSDPHeader2.Ptr;
    theSDPVec[3].iov_len = sSDPHeader2.Len;
    totalSDPLength += sSDPHeader2.Len;

    //connection header
    theSDPVec[4].iov_base = sSDPHeader3.Ptr;
    theSDPVec[4].iov_len = sSDPHeader3.Len;
    totalSDPLength += sSDPHeader3.Len;
    
    //append IP addr
    (void)QTSS_GetValuePtr(inParamBlock->inRTSPSession, qtssRTSPSesLocalAddrStr, 0,
                                                (void**)&theSDPVec[5].iov_base, (UInt32*)&theSDPVec[5].iov_len);
    totalSDPLength += theSDPVec[5].iov_len;

    //last static sdp line
    theSDPVec[6].iov_base = sSDPHeader4.Ptr;
    theSDPVec[6].iov_len = sSDPHeader4.Len;
    totalSDPLength += sSDPHeader4.Len;
    
    //now append content-determined sdp
    theSDPVec[7].iov_base = theFile->fFile.GetSDPFile()->Ptr;
    theSDPVec[7].iov_len = theFile->fFile.GetSDPFile()->Len;
    totalSDPLength += theSDPVec[7].iov_len;
    
    Assert(theSDPVec[2].iov_base != NULL);


    // Append the Last Modified header to be a good caching proxy citizen before sending the Describe
    //(void)QTSS_AppendRTSPHeader(inParamBlock->inRTSPRequest, qtssLastModifiedHeader,
    //                              theFile->fFile.GetQTFile()->GetModDateStr(), DateBuffer::kDateBufferLen);
    (void)QTSS_AppendRTSPHeader(inParamBlock->inRTSPRequest, qtssCacheControlHeader,
                                    kCacheControlHeader.Ptr, kCacheControlHeader.Len);

    //ok, we have a filled out iovec. Let's send it!
    QTSSModuleUtils::SendDescribeResponse(inParamBlock->inRTSPRequest, inParamBlock->inClientSession,
                                                                    &theSDPVec[0], 8, totalSDPLength);  
	
    return QTSS_NoErr;
}