Пример #1
0
ProxyDemuxerTask* ProxyClientInfo::AddStream(QTSS_RTPStreamObject inStream)
{
    //
    // Allocate some UDP sockets out of our pool to receive the UDP data from
    // the server. Demuxing is based on the origin server's (host's) IP addr, so
    // pass that to the socket pool so it can properly allocate a pair of UDP sockets.
    // We don't know what the remote port is yet (we only find out when we get the
    // SETUP response from the origin), so just pass in 0.
    UInt32 theHostAddr = fClient.GetSocket()->GetHostAddr();
    UInt32 theLocalAddr = fClient.GetSocket()->GetLocalAddr();
    
    UDPSocketPair* thePair = sSocketPool->GetUDPSocketPair(theLocalAddr, 0, theHostAddr, 0);

    fLastDemuxerTask = NEW ProxyDemuxerTask(inStream, thePair);
    fDemuxerTaskQueue.EnQueue(fLastDemuxerTask->GetQueueElem());
    
    //
    // Tell the demuxers for these sockets to send any packets from this IP addr
    // to the ProxyDemuxerTask for this stream. This is how incoming UDP packets
    // will be routed to the proper QTSS_RTPStreamObject
    thePair->GetSocketA()->GetDemuxer()->RegisterTask(theHostAddr, 0, fLastDemuxerTask);
    thePair->GetSocketB()->GetDemuxer()->RegisterTask(theHostAddr, 0, fLastDemuxerTask);
    
    //
    // return the newly created ProxyDemuxerTask
    return fLastDemuxerTask;
}
Пример #2
0
SInt64 ProxyTask::Run()
{
    const UInt32 kMaxRTCPPacketSize = 2048;
    char thePacketBuffer[kMaxRTCPPacketSize];
    QTSS_PacketStruct thePacketStruct;
    thePacketStruct.packetTransmitTime = QTSS_Milliseconds();
    thePacketStruct.packetData = thePacketBuffer;

    (void)this->GetEvents();    

    OSMutexLocker locker(sSocketPool->GetMutex());
    for (OSQueueIter iter(sSocketPool->GetSocketQueue()); !iter.IsDone(); iter.Next())
    {
        UInt32 theRemoteAddr = 0;
        UInt16 theRemotePort = 0;

        UDPSocketPair* thePair = (UDPSocketPair*)iter.GetCurrent()->GetEnclosingObject();
        Assert(thePair != NULL);
        
        for (UInt32 x = 0; x < 2; x++)
        {
            QTSS_WriteFlags theFlags = qtssWriteFlagsNoFlags;
            
            UDPSocket* theSocket = NULL;
            if (x == 0)
            {
                theFlags = qtssWriteFlagsIsRTP;
                theSocket = thePair->GetSocketA();
            }
            else
            {
                theFlags = qtssWriteFlagsIsRTCP;
                theSocket = thePair->GetSocketB();
            }
            
            Assert(theSocket->GetDemuxer() != NULL);
            OSMutexLocker locker(theSocket->GetDemuxer()->GetMutex());
            
            //get all the outstanding packets for this socket
            while (true)
            {
                UInt32 thePacketLen = 0;
                theSocket->RecvFrom(&theRemoteAddr, &theRemotePort, thePacketStruct.packetData, 
                                kMaxRTCPPacketSize, &thePacketLen);
                if (thePacketLen == 0)
                    break;//no more packets on this socket!
                    
                ProxyDemuxerTask* theDemuxerTask = (ProxyDemuxerTask*)theSocket->GetDemuxer()->GetTask(theRemoteAddr, 0);
                if (theDemuxerTask != NULL)
                {
                    QTSS_RTPStreamObject theStream = theDemuxerTask->GetStream();
                    (void)QTSS_Write(theStream, &thePacketStruct, thePacketLen, NULL, theFlags);
                }
            }
        }
    }
    return kProxyTaskPollIntervalMsec;
}
Пример #3
0
ProxyClientInfo::~ProxyClientInfo()
{
    UInt32 theHostAddr = fClient.GetSocket()->GetHostAddr();

    for (OSQueueIter iter(&fDemuxerTaskQueue); !iter.IsDone(); )
    {
        OSQueueElem* theElem = iter.GetCurrent();
        ProxyDemuxerTask* theTask = (ProxyDemuxerTask*)theElem->GetEnclosingObject();
        
        //
        // Move onto the next element becase we are going to be deleting this one
        iter.Next();
        theElem->Remove(); // Get off the queue before deleting
        
        //
        // Clean up
        UDPSocketPair* thePair = theTask->GetSockets();
        thePair->GetSocketA()->GetDemuxer()->UnregisterTask(theHostAddr, 0, theTask);
        thePair->GetSocketB()->GetDemuxer()->UnregisterTask(theHostAddr, 0, theTask);
        
        delete theTask;     
        sSocketPool->ReleaseUDPSocketPair(thePair);
    }
}
int QTFileBroadcaster::SetUp(PLBroadcastDef *broadcastDefPtr, bool *quitImmediatePtr)
{
    int result = -1;
    int numStreams = 0;
    fQuitImmediatePtr = quitImmediatePtr;
    PlayListUtils::Initialize();
    do 
    {
        if (! broadcastDefPtr) 
        { result = eParam;          break; };
            
        if (!broadcastDefPtr->mSDPFile || 0 == broadcastDefPtr->mSDPFile[0] ) 
        { result = eSDPFileInvalidName; break; };
        
        int nameLen = strlen(broadcastDefPtr->mSDPFile);
        if (nameLen > 255)  
        { result = eSDPFileInvalidName; break; };   
                
        if (0 ==  nameLen)  
        { result = eSDPFileInvalidName; break; };   

        if (broadcastDefPtr->mTheSession)
        {   if (!broadcastDefPtr->mDestSDPFile)
            { result = eNetworkSDPFileNameInvalidMissing; break; };
                
            if (!broadcastDefPtr->mDestSDPFile[0])
            { result = eNetworkSDPFileNameInvalidMissing; break; };
                
            if (!::strcmp(broadcastDefPtr->mDestSDPFile, "no_name"))
            { result = eNetworkSDPFileNameInvalidMissing; break; }; 
                        
//          if ('/' == broadcastDefPtr->mDestSDPFile[0])
//          { result = eNetworkSDPFileNameInvalidBadPath; break; };
        }
            
        result = fStreamSDPParser.ReadSDP(broadcastDefPtr->mSDPFile);
            
        if (result != 0)
        {   if (result < 0) { result = eSDPFileNotFound;    break; };
            if (result > 0) { result = eSDPFileInvalid;     break; };
        }   
        

        fBroadcastDefPtr = broadcastDefPtr;
        if (broadcastDefPtr->mTheSession == NULL)
        {   if (!broadcastDefPtr->mBasePort) { result = eSDPFileNoPorts; break; };
            
            int portLen = strlen(broadcastDefPtr->mBasePort);
            if (0 ==  portLen) { result = eDescriptionInvalidDestPort;      break; };   
            if (portLen > 5  )  { result = eDescriptionInvalidDestPort; break; };

            int basePort = atoi(broadcastDefPtr->mBasePort);
            if  ( basePort > 65531 ) { result = eDescriptionInvalidDestPort;                break; };
            if  ( basePort < 5004 )  { result = eDescriptionInvalidDestPort;                break; };

        }
            
        numStreams = fStreamSDPParser.GetNumTracks();       
        if (numStreams == 0) { result = eSDPFileNoMedia;    break; };
        
        UDPSocketPair *socketArrayPtr = fSocketlist.SetSize(numStreams);
        if (socketArrayPtr == NULL) { result = eMem;        break; };

        // Bind SDP file defined ports to active stream ports
        { 
            UInt16          streamIndex = 0;
            UInt16          rtpPort = 0;
            UInt16          rtcpPort = 0;
            TypeMap*        mediaTypePtr;
            char            sdpIPAddress[32];
            SimpleString* ipStringPtr = fStreamSDPParser.GetIPString();
            
            if ( (NULL == ipStringPtr) || (ipStringPtr->fLen >= 32) )
            {   
                result = eSDPFileInvalid;               
                break; 
            }
                
            memcpy(sdpIPAddress,ipStringPtr->fTheString,ipStringPtr->fLen);
            sdpIPAddress[ipStringPtr->fLen] = '\0';
            
            UDPSocketPair *aSocketPair = fSocketlist.Begin();
            Bool16 setupUDP = true;
            while (aSocketPair != NULL)
            {   
                mediaTypePtr = fStreamSDPParser.fSDPMediaList.SetPos(streamIndex);
                
                if (mediaTypePtr == NULL) 
                {   result = eSDPFileInvalid;   
                    break;  
                }
                                    
                if (broadcastDefPtr->mTheSession != NULL)
                {
                    mediaTypePtr->fPort = broadcastDefPtr->mTheSession->GetStreamDestPort(streamIndex);
                    //qtss_printf("QTFileBroadcaster::SetUp streamIndex=%u port=%d\n",streamIndex,mediaTypePtr->fPort);
                
                    if (BroadcasterSession::kTCPTransportType == broadcastDefPtr->mTheSession->GetTransportType())
                    {   aSocketPair->SetRTSPSession(broadcastDefPtr->mTheSession, (UInt8) streamIndex * 2);
                        setupUDP = false;
                    }
                    else
                    {   setupUDP = true;
                    }
                }
                
                if (setupUDP)
                {
                    SInt16 ttl = (SInt16) atoi(broadcastDefPtr->mTTL);
                    if  ( ( ttl > 255 ) || ( ttl < 1 ) )
                    {   result = eSDPFileInvalidTTL;    break; 
                    };

                    if (mediaTypePtr->fPort == 0) 
                    {  
                        result = eSDPFileInvalidPort;   
                        break;  
                    }
    
                    rtpPort = mediaTypePtr->fPort;
                    rtcpPort = rtpPort + 1;
                    
                    result = aSocketPair->OpenAndBind(rtpPort,rtcpPort,sdpIPAddress);
                    if (result != 0) 
                    { 
                        result = eFailedBind; 
                        break; 
                    }
                    
                    (void) aSocketPair->SetMultiCastOptions(ttl);

                }
                
                aSocketPair = fSocketlist.Next();
                streamIndex++;
            }
            
            if (result != 0) 
                break;
        }

            
        MediaStream *mediaArrayPtr = fMediaStreamList.SetSize(numStreams);
        if (mediaArrayPtr == NULL) 
        { 
            result = eMem; 
            break; 
        }
                
        for (int i = 0; i < numStreams; i ++)
        {   UDPSocketPair   *socketPairPtr = fSocketlist.SetPos(i);
            MediaStream     *mediaStreamPtr = fMediaStreamList.SetPos(i);
            TypeMap         *streamMediaTypePtr = fStreamSDPParser.fSDPMediaList.SetPos(i);
            
            if (socketPairPtr && mediaStreamPtr && streamMediaTypePtr)
            {
                mediaStreamPtr->fData.fSocketPair = socketPairPtr;
                streamMediaTypePtr->fMediaStreamPtr = mediaStreamPtr;
                mediaStreamPtr->fData.fStreamMediaTypePtr = streamMediaTypePtr;
            }
            else 
            { 
                result = eMem;
                break; 
            }
        }
        
        
        fMediaStreamList.SetUpStreamSSRCs();
        fStreamStartTime = PlayListUtils::Milliseconds(); 
        fMediaStreamList.StreamStarted(fStreamStartTime);
        result = 0;
        LogFileOpen();
        
    } while (false);
    
    return result;
}
Пример #5
0
SInt64 RTCPTask::Run()
{
    const UInt32 kMaxRTCPPacketSize = 2048;
    char thePacketBuffer[kMaxRTCPPacketSize];
    StrPtrLen thePacket(thePacketBuffer, 0);
    QTSServerInterface* theServer = QTSServerInterface::GetServer();
    
    //This task goes through all the UDPSockets in the RTPSocketPool, checking to see
    //if they have data. If they do, it demuxes the packets and sends the packet onto
    //the proper RTP session.
    EventFlags events = this->GetEvents(); // get and clear events
    
    if ( (events & Task::kReadEvent) || (events & Task::kIdleEvent) )
        {
                //Must be done atomically wrt the socket pool.
                
                OSMutexLocker locker(theServer->GetSocketPool()->GetMutex());
                for (OSQueueIter iter(theServer->GetSocketPool()->GetSocketQueue());
                                !iter.IsDone(); iter.Next())
                {
                        UInt32 theRemoteAddr = 0;
                        UInt16 theRemotePort = 0;
        
                        UDPSocketPair* thePair = (UDPSocketPair*)iter.GetCurrent()->GetEnclosingObject();
                        Assert(thePair != NULL);
                        
                        for (UInt32 x = 0; x < 2; x++)
                        {
                                UDPSocket* theSocket = NULL;
                                if (x == 0)
                                        theSocket = thePair->GetSocketA();
                                else
                                        theSocket = thePair->GetSocketB();
                                        
                                UDPDemuxer* theDemuxer = theSocket->GetDemuxer();
                        if (theDemuxer == NULL) 
                            continue;
                        else
                        {
                                        theDemuxer->GetMutex()->Lock();
                            while (true) //get all the outstanding packets for this socket
                                {
                                        thePacket.Len = 0;
                                        theSocket->RecvFrom(&theRemoteAddr, &theRemotePort, thePacket.Ptr,  
                                                                        kMaxRTCPPacketSize, &thePacket.Len);
                                        if (thePacket.Len == 0)
                                        {
                                                theSocket->RequestEvent(EV_RE);   
                                                break;//no more packets on this socket!
                                        }
                                        
                                        //if this socket has a demuxer, find the target RTPStream
                                        if (theDemuxer != NULL)
                                        {
                                                RTPStream* theStream = (RTPStream*)theDemuxer->GetTask(theRemoteAddr, theRemotePort);
                                                if (theStream != NULL)
                                                        theStream->ProcessIncomingRTCPPacket(&thePacket);
                                        }
                                }
                                        theDemuxer->GetMutex()->Unlock();
                        }
                }
        }
    }
     
    return 0; /* Fix for 4004432 */   
    /*
    SInt64 result = 0;
    if (theServer->GetNumRTPSessions() > 0)
        result =  theServer->GetPrefs()->GetRTCPPollIntervalInMsec();
    
   return result;
   */
}