예제 #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);
    }
}
예제 #4
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;
   */
}