コード例 #1
0
int MpTopologyGraph::addVirtualOutputs(MpResourceTopology& resourceTopology,
                                       UtlHashBag& newResources,
                                       UtlBoolean replaceNumInName,
                                       int resourceNum)
{
   int portsAdded = 0;
   MpResourceTopology::VirtualPortIterator portIter;
   UtlString realResourceName;
   int realPortIdx;
   UtlString virtualResourceName;
   int virtualPortIdx;

   resourceTopology.initVirtualOutputIterator(portIter);
   while (resourceTopology.getNextVirtualOutput(portIter,
                                                realResourceName, realPortIdx,
                                                virtualResourceName, virtualPortIdx)
          == OS_SUCCESS)
   {
      if(replaceNumInName)
      {
         MpResourceTopology::replaceNumInName(realResourceName, resourceNum);
         MpResourceTopology::replaceNumInName(virtualResourceName, resourceNum);
      }

      // Lookup real resource.
      MpResource *pResource = (MpResource*)newResources.find(&realResourceName);
      assert(pResource);
      if (!pResource)
      {
         continue;
      }

      // Check port index correctness. Note, that this check gracefully
      // handles case with realPortIdx equal -1.
      if (realPortIdx >= pResource->maxOutputs())
      {
         assert(!"Trying to map virtual port to non existing real port!");
         continue;
      }

      // Add entry to virtual ports map.
      // We need to create UtlVoidPtr wrapper for pResource, or it will be
      // destroyed on pair deletion.
      UtlContainablePair *pRealPort = new UtlContainablePair(new UtlVoidPtr(pResource),
                                                             new UtlInt(realPortIdx));
      UtlContainablePair *pVirtPort = new UtlContainablePair(new UtlString(virtualResourceName),
                                                             new UtlInt(virtualPortIdx));
      mVirtualOutputs.insertKeyAndValue(pVirtPort, pRealPort);
      portsAdded++;
   }
   resourceTopology.freeVirtualOutputIterator(portIter);

   return portsAdded;
}
コード例 #2
0
ファイル: MpFlowGraphBase.cpp プロジェクト: LordGaav/sipxecs
// (static) Displays information on the console about the specified flow
// graph.
void MpFlowGraphBase::flowGraphInfo(MpFlowGraphBase* pFlowGraph)
{
   int         i;
   MpResource* pResource;

   if (NULL == pFlowGraph) {
      MpMediaTask* pMediaTask = MpMediaTask::getMediaTask(0);
      pFlowGraph = pMediaTask->getFocus();
      if (NULL == pFlowGraph) {
         pMediaTask->getManagedFlowGraphs(&pFlowGraph, 1, i);
         if (0 == i) pFlowGraph = NULL;
      }
   }
   if (NULL == pFlowGraph) {
      printf("No flowGraph to display!\n");
      return;
   }
   printf("\nFlow graph information for %p\n", pFlowGraph);
   printf("  State:                    %s\n",
             pFlowGraph->isStarted() ? "STARTED" : "STOPPED");

   printf("  Processed Frame Count:    %d\n",
             pFlowGraph->numFramesProcessed());

   printf("  Samples Per Frame:        %d\n",
             pFlowGraph->getSamplesPerFrame());

   printf("  Samples Per Second:       %d\n",
             pFlowGraph->getSamplesPerSec());

   pResource = pFlowGraph->mpResourceInProcess;
   if (pResource == NULL)
      printf("  Resource Being Processed: NULL\n");
   else
      printf("  Resource Being Processed: %p\n", pResource);

   printf("\n  Resource Information\n");
   printf("    Resources:   %d\n", pFlowGraph->numResources());
   printf("    Links: %d\n", pFlowGraph->numLinks());
   for (i=0; i < pFlowGraph->mResourceCnt; i++)
   {
      pResource = pFlowGraph->mUnsorted[i];
      pResource->resourceInfo(pResource, i);
   }
}
コード例 #3
0
// Makes pBuf available to resource connected to the outPortIdx output
// port of this resource.
// Returns TRUE if there is a resource connected to the specified output
// port, FALSE otherwise.
UtlBoolean MpResource::pushBufferDownsream(int outPortIdx, const MpBufPtr& pBuf)
{
   MpResource* pDownstreamInput;
   int         downstreamPortIdx;

   // Not locking mpOutConns here as we only lock for setting/accessing
   // reservation state (the only thing set in mpOutConns outside media task)

   if (outPortIdx < 0 || outPortIdx >= mMaxOutputs)  // port  out of range
      return FALSE;

   pDownstreamInput  = mpOutConns[outPortIdx].pResource;
   downstreamPortIdx = mpOutConns[outPortIdx].portIndex;
   if (pDownstreamInput == NULL)                     // no connected resource
      return FALSE;

   pDownstreamInput->setInputBuffer(downstreamPortIdx, pBuf);
   return TRUE;
}
コード例 #4
0
ファイル: MpFlowGraphBase.cpp プロジェクト: LordGaav/sipxecs
//:Inserts "rResource" into the flow graph upstream of the
//:designated "rDownstreamResource" resource.
// The new resource will be inserted on the "inPortIdx" input
// link of "rDownstreamResource".
// If the flow graph is not "started", this call takes effect
// immediately.  Otherwise, the call takes effect at the start of the
// next frame processing interval.
// Returns OS_SUCCESS if the resource was successfully inserted. Returns
// OS_INVALID_ARGUMENT if the caller specified an invalid port index.
OsStatus MpFlowGraphBase::insertResourceBefore(MpResource& rResource,
                                 MpResource& rDownstreamResource,
                                 int inPortIdx)
{
   MpResource *pUpstreamResource;
   int         upstreamOutPortIdx;
   OsStatus    res;

   // Get information about the downstream end of the link
   rDownstreamResource.getInputInfo(inPortIdx, pUpstreamResource,
                                    upstreamOutPortIdx);

   // Add the new resource to the flow graph
   res = addResource(rResource);
   if (res != OS_SUCCESS)
      return res;

   if (pUpstreamResource != NULL)
   {
      // Remove the link between the upstream and downstream resources
      res = removeLink(*pUpstreamResource, upstreamOutPortIdx);
      if (res != OS_SUCCESS)
      {                              // recover from remove link failure
         removeResource(rResource);
         return res;
      }

      // Add the link between output port 0 the new resource and the
      // downstream resource
      res = addLink(rResource, 0, rDownstreamResource, inPortIdx);
      if (res != OS_SUCCESS)
      {                              // recover from add link failure
         removeResource(rResource);
         addLink(*pUpstreamResource, upstreamOutPortIdx,
                 rDownstreamResource, inPortIdx);
         return res;
      }
   }

   // Add the link between the upstream resource and input port 0 of
   // the new resource
   res = addLink(*pUpstreamResource, upstreamOutPortIdx, rResource, 0);
   if (res != OS_SUCCESS)
   {                              // recover from add link failure
      removeResource(rResource);
      if (pUpstreamResource != NULL)
      {
         addLink(*pUpstreamResource, upstreamOutPortIdx,
                 rDownstreamResource, inPortIdx);
      }
   }

   return res;
}
コード例 #5
0
ファイル: MpFlowGraphBase.cpp プロジェクト: LordGaav/sipxecs
// Handle the FLOWGRAPH_REMOVE_LINK message.
// Returns TRUE if the message was handled, otherwise FALSE.
UtlBoolean MpFlowGraphBase::handleRemoveLink(MpResource* pFrom, int outPortIdx)
{
   int         connectedPort;
   MpResource* pConnectedResource;

   // make sure the resource is part of this flow graph
   if (pFrom->getFlowGraph() != this)
   {
      Zprintf("handleRemoveLink: pFrom->getFlowGraph() != this: 0x%p != 0x%p\n",
         (pFrom->getFlowGraph()), this, 0,0,0,0);
      assert(FALSE);
      return FALSE;
   }

   // get information about the downstream end of the link
   pFrom->getOutputInfo(outPortIdx, pConnectedResource, connectedPort);

   // disconnect the upstream end of the link
   if (pFrom->disconnectOutput(outPortIdx) == FALSE)
   {
      Zprintf("handleRemoveLink: disconnectOutput(0x%p, %d) failed\n",
         pFrom, outPortIdx, 0,0,0,0);
      assert(FALSE);    // couldn't disconnect
      return FALSE;
   }

   // disconnect the downstream end of the link
   if (pConnectedResource->disconnectInput(connectedPort) == FALSE)
   {
      Zprintf("handleRemoveLink: disconnectInput(0x%p, %d) failed\n",
         pConnectedResource, connectedPort, 0,0,0,0);
      assert(FALSE);    // couldn't disconnect
      return FALSE;
   }

   mLinkCnt--;
   mRecomputeOrder = TRUE;

   return TRUE;
}
コード例 #6
0
ファイル: MpFlowGraphBase.cpp プロジェクト: LordGaav/sipxecs
// Creates a link between the "outPortIdx" port of the "rFrom" resource
// to the "inPortIdx" port of the "rTo" resource.
// If the flow graph is not "started", this call takes effect immediately.
// Otherwise, the call takes effect at the start of the next frame processing
// interval.
// Returns OS_SUCCESS if the link was successfully added. Returns
// OS_INVALID_ARGUMENT if the caller specified an invalid port index.
// Returns OS_UNSPECIFIED if the addLink attempt failed for some other
// reason.
OsStatus MpFlowGraphBase::addLink(MpResource& rFrom, int outPortIdx,
                              MpResource& rTo,   int inPortIdx)
{
   OsWriteLock    lock(mRWMutex);

   UtlBoolean      handled;
   MpFlowGraphMsg msg(MpFlowGraphMsg::FLOWGRAPH_ADD_LINK, NULL,
                      &rFrom, &rTo, outPortIdx, inPortIdx);

   if (outPortIdx < 0 || outPortIdx >= rFrom.maxOutputs() ||
       inPortIdx  < 0 || inPortIdx  >= rTo.maxInputs())
      return OS_INVALID_ARGUMENT;

   if (mCurState == STARTED)
      return postMessage(msg);

   handled = handleMessage(msg);
   if (handled)
      return OS_SUCCESS;
   else
      return OS_UNSPECIFIED;
}
コード例 #7
0
UtlBoolean MpRtpInputConnection::connectOutput(MpResource& rTo,
                                               int toPortIdx,
                                               int fromPortIdx)
{
   UtlBoolean res = MpResource::connectOutput(rTo, toPortIdx, fromPortIdx);
   if (res)
   {
      assert(rTo.getContainableType() == MprDecode::TYPE);
      MprDecode *pDecode = (MprDecode*)&rTo;
      res = mpRtpDispatcher->connectOutput(fromPortIdx, pDecode);
   }
   return res;
}
コード例 #8
0
ファイル: MpFlowGraphBase.cpp プロジェクト: LordGaav/sipxecs
// Handle the FLOWGRAPH_ENABLE message.
// Returns TRUE if the message was handled, otherwise FALSE.
UtlBoolean MpFlowGraphBase::handleEnable(void)
{
   int            i;
   MpFlowGraphMsg msg(MpFlowGraphMsg::RESOURCE_ENABLE);
   MpResource*    pResource;

   // iterate over all resources
   // invoke the enable() method for each resource in the flow graph
   for (i=0; i < mResourceCnt; i++)
   {
      // iterate through the resources
      pResource = mUnsorted[i];

      // make each resource handle a RESOURCE_ENABLE message
      msg.setMsgDest(pResource);
      if (!pResource->handleMessage(msg))
      {
         assert(FALSE);
         return FALSE;
      }
   }

   return TRUE;
}
コード例 #9
0
ファイル: MpFlowGraphBase.cpp プロジェクト: LordGaav/sipxecs
// Handle the FLOWGRAPH_SET_SAMPLES_PER_SEC message.
// Returns TRUE if the message was handled, otherwise FALSE.
UtlBoolean MpFlowGraphBase::handleSetSamplesPerSec(int samplesPerSec)
{
   int            i;
   MpFlowGraphMsg msg(MpFlowGraphMsg::RESOURCE_SET_SAMPLES_PER_SEC,
                      NULL, NULL, NULL, samplesPerSec);
   MpResource*    pResource;

   // iterate over all resources
   for (i=0; i < mResourceCnt; i++)
   {
      pResource = mUnsorted[i];

      // make each resource handle a SET_SAMPLES_PER_SEC message
      msg.setMsgDest(pResource);
      if (!pResource->handleMessage(msg))
      {
         assert(FALSE);
         return FALSE;
      }
   }

   mSamplesPerSec = samplesPerSec;
   return TRUE;
}
コード例 #10
0
// Notification that this flow graph has just lost the focus.
// Disable our microphone and speaker resources
OsStatus MpTopologyGraph::loseFocus(void)
{
   UtlBoolean    boolRes;
   OsStatus      result;
   OsStatus      retval = OS_FAILED;

   // disable the FromInputDevice and ToOutputDevice -- we no longer have the focus.
   {
      MpResource* pResource = NULL;
      result = lookupResource("FromMic1",
                              pResource);
      if (result == OS_SUCCESS)
      {
         // This flowgraph have local input part. Disable it.
         assert(pResource);
         boolRes = pResource->disable();
         assert(boolRes);
         retval = OS_SUCCESS;
      }
   }
   {
      MpResource* pResource = NULL;
      result = lookupResource("ToSpeaker1",
                              pResource);
      if (result == OS_SUCCESS)
      {
         // This flowgraph have local input part. Disable it.
         assert(pResource);
         boolRes = pResource->disable();
         assert(boolRes);
         retval = OS_SUCCESS;
      }
   }

   return retval;
}
コード例 #11
0
ファイル: MpFlowGraphBase.cpp プロジェクト: LordGaav/sipxecs
// Processes all of the messages currently queued for this flow graph.
// For now, this method always returns OS_SUCCESS.
OsStatus MpFlowGraphBase::processMessages(void)
{
   OsWriteLock     lock(mRWMutex);

   UtlBoolean       done;
   UtlBoolean       handled;
   static MpFlowGraphMsg* pStopMsg = NULL;
   MpResource*     pMsgDest;

   OsStatus        res;

   // First, we send ourselves a FLOWGRAPH_PROCESS_FRAME message.
   // This message serves as a "stopper" in the message queue.  When we
   // handle that message, we know that we have processed all of the messages
   // for the flowgraph (and its resources) that had arrived prior to the
   // start of this frame processing interval.

   if (NULL == pStopMsg) {
      pStopMsg = new MpFlowGraphMsg(MpFlowGraphMsg::FLOWGRAPH_PROCESS_FRAME);
      pStopMsg->setReusable(TRUE);
   }

   res = postMessage(*pStopMsg);
   assert(res == OS_SUCCESS);

   done = FALSE;
   while (!done)
   {
      // get the next message
      OsMsg* pMsg ;

      res = mMessages.receive(pMsg, OsTime::NO_WAIT);

      assert(res == OS_SUCCESS);

      if (pMsg->getMsgType() == OsMsg::MP_FLOWGRAPH_MSG)
      {
         MpFlowGraphMsg* pRcvdMsg = (MpFlowGraphMsg*) pMsg ;
         // determine if this message is intended for a resource in the
         // flow graph (as opposed to a message for the flow graph itself)
         pMsgDest = pRcvdMsg->getMsgDest();


         if (pMsgDest != NULL)
         {
            // deliver the message if the resource is still part of this graph
            if (pMsgDest->getFlowGraph() == this)
            {
               handled = pMsgDest->handleMessage(*pRcvdMsg);
               assert(handled);
            }
         }
         else
         {
            // since pMsgDest is NULL, this msg is intended for the flow graph
            switch (pRcvdMsg->getMsg())
            {
            case MpFlowGraphMsg::FLOWGRAPH_PROCESS_FRAME:
               done = TRUE;    // "stopper" message encountered -- we are done
               break;          //  processing messages for this frame interval

            default:
               handled = handleMessage(*pRcvdMsg);
               assert(handled);
               break;
            }
         }
         pRcvdMsg->releaseMsg();    // free the msg
      }
      else
      {
         handled = handleMessage(*pMsg);
         assert(handled);
         pMsg->releaseMsg() ;
      }

   }

   return OS_SUCCESS;
}
コード例 #12
0
ファイル: sipXtapiExt.cpp プロジェクト: Konnekt/lib-sipx
SIPXTAPI_API SIPX_RESULT sipxQOSDebug(SIPX_INST phInst, CStdString& txt) {
	CStdString buff;

#ifdef INCLUDE_RTCP
	IRTCPControl* ic = CRTCManager::getRTCPControl();
	IRTCPSession* sess = ic->GetFirstSession();
	while (sess) {
		buff.Format("Sess: %d ", sess->GetSessionID());
		txt += buff;
		IRTCPConnection* conn = sess->GetFirstConnection();
		while (conn) {
			txt += "Conn\n";
			CRTCPRender* render = (CRTCPRender*)((CRTCPConnection*)conn)->GetRenderInterface();
			IGetSrcDescription* statDesc;
			IGetSenderStatistics* statSender;
			IGetReceiverStatistics* statRcvr;
			IGetByeInfo* statBye;
			render->GetStatistics(&statDesc, &statSender, &statRcvr, &statBye);
			char appName [255];
			statDesc->GetAppName((unsigned char*)appName);
			unsigned long packetCount, octetCount;
			statSender->GetSenderStatistics(&packetCount, &octetCount);
			unsigned long fractionalLoss, cumulativeLoss, highestSeq, interarrivalJitter, SRtimestamp, packetDelay;
			statRcvr->GetReceiverStatistics(&fractionalLoss, &cumulativeLoss, &highestSeq, &interarrivalJitter, &SRtimestamp, &packetDelay);

			buff.Format("app=%s, packet=%d, octet=%d, loss=%d, cLoss=%d, seq=%d, jitt=%d, SR=%d, delay=%d", appName, packetCount, octetCount, fractionalLoss, cumulativeLoss, highestSeq, interarrivalJitter, SRtimestamp, packetDelay);
			txt += buff + "\n";
			conn = sess->GetNextConnection();
		}

		sess = ic->GetNextSession();
	}
#endif 

	MpMediaTask* mtask = MpMediaTask::getMediaTask(32);
	MpFlowGraphBase* flowGraph = mtask->getFocus();
	if (flowGraph) {
		for (int i=0; i < flowGraph->mResourceCnt; i++) {
			MpResource* r = flowGraph->mExecOrder[i];
			if (strstr(r->getName(), "Dejitter")) {
				/*
				MprDejitter* dejj = (MprDejitter*) r;
				buff.Format("<u>%s</u>:: ave=%d, buff=%d, pull=%d, push=%d, " 
					//"lmax=%d, lmin=%d, " 
					"disc=%d, packs=%d ", dejj->getName().data(), dejj->getAveBufferLength(), dejj->mBufferLength, dejj->mLastPulled, dejj->mLastPushed 
					//, dejj->mLatencyMax, dejj->mLatencyMin
					, dejj->mNumDiscarded, dejj->mNumPackets);
				txt += buff + "<br/>";
				*/
			} else if (strstr(r->getName(), "Decode")) {
				/*
				MprDecode* decode = (MprDecode*) r;

				for (int c=0; c < decode->mNumCurrentCodecs; c++) {
					MpDecoderBase* mpd = decode->mpCurrentCodecs[c];
					if (mpd->getInfo()->getCodecType() == SdpCodec::SDP_CODEC_PCMU || mpd->getInfo()->getCodecType() == SdpCodec::SDP_CODEC_PCMA) {
						MpdSipxPcma* pcma = (MpdSipxPcma*)mpd;
						MpJitterBuffer* jb = (MpJitterBuffer*)pcma->pJBState;
						buff.Format("Codec::%d tci=%d, pull=%d, wait=%d, under=%d, seq=%d, few=%d, many=%d, last=%d", pcma->getInfo()->getCodecType(), pcma->mTimerCountIncrement, pcma->mNextPullTimerCount, pcma->mWaitTimeInFrames, pcma->mUnderflowCount, pcma->mLastSeqNo, pcma->mTooFewPacketsInBuffer, pcma->mTooManyPacketsInBuffer, pcma->mLastReportSize);
						txt += buff + ", JB:";
						buff.Format("avail=%d, qc=%d, qi=%d, qo=%d", jb->JbPacketsAvail, jb->JbQCount, jb->JbQIn, jb->JbQOut);
						txt += buff + "<br/>";
					}
				}
*/
			}/* else if (stristr(r->getName(), "FromNet")) {
				MprFromNet* fromNet = (MprFromNet*) r;
			}*/
		}
	}

	int rating = 0;
	sipxQOSRating(phInst, rating);
	buff.Format("Rating: <b>%d</b>", rating);
	txt += buff;

/*
MprDejitter::getAveBufferLength -> MprDejitter -> MprDecode::getMyDejitter / MprFromNet::getMyDejitter()
MpdSipxPcmu -> MpConnection::mapPayloadType  MpCodecFactory::createDecoder 
MpdSipxPcma (MpDecoderBase)
MpJitterBuffer -> MpConnection::getJBinst

MpCallFlowGraph::getConnectionPtr
*/
	return SIPX_RESULT_SUCCESS;
}
コード例 #13
0
int MpTopologyGraph::linkTopologyResources(MpResourceTopology& resourceTopology,
                                           UtlHashBag& newResources,
                                           UtlBoolean replaceNumInName,
                                           int resourceNum)
{
    // Link the resources
    int connectionIndex = 0;
    UtlString outputResourceName;
    UtlString inputResourceName;
    int outputResourcePortIndex;
    int inputResourcePortIndex;
    MpResource* outputResource = NULL;
    MpResource* inputResource = NULL;
    OsStatus result;
    UtlHashMap newConnectionIds;

#ifdef TEST_PRINT
    osPrintf("%d new resources in the list\n", newResources.entries());
    UtlHashBagIterator iterator(newResources);
    MpResource* containerResource = NULL;
    while(containerResource = (MpResource*) iterator())
    {
        osPrintf("found list resource: \"%s\" value: \"%s\"\n",
                 containerResource->getName().data(), containerResource->data());
    }
#endif

    while(resourceTopology.getConnection(connectionIndex,
                                         outputResourceName,
                                         outputResourcePortIndex,
                                         inputResourceName,
                                         inputResourcePortIndex) == OS_SUCCESS)
    {
        if(replaceNumInName)
        {
            resourceTopology.replaceNumInName(outputResourceName, resourceNum);
            resourceTopology.replaceNumInName(inputResourceName, resourceNum);
        }

        // Look in the container of new resources first as this is more 
        // efficient and new resources are not added immediately to a running
        // flowgraph
        outputResource = (MpResource*) newResources.find(&outputResourceName);
        if(outputResource == NULL)
        {
            result = lookupResource(outputResourceName, outputResource);
            if(result != OS_SUCCESS)
            {
                int virtPortIdx = outputResourcePortIndex>=0?outputResourcePortIndex:-1;
                int realPortIdx;
                result = lookupVirtualOutput(outputResourceName, virtPortIdx,
                                             outputResource, realPortIdx);
                if (result == OS_SUCCESS && outputResourcePortIndex>=0)
                {
                   outputResourcePortIndex = realPortIdx;
                }
            }
            assert(result == OS_SUCCESS);
        }
        inputResource = (MpResource*) newResources.find(&inputResourceName);
        if(inputResource == NULL)
        {
            result = lookupResource(inputResourceName, inputResource);
            if(result != OS_SUCCESS)
            {
                int virtPortIdx = inputResourcePortIndex>=0?inputResourcePortIndex:-1;
                int realPortIdx;
                result = lookupVirtualInput(inputResourceName, virtPortIdx,
                                            inputResource, realPortIdx);
                if (result == OS_SUCCESS && inputResourcePortIndex>=0)
                {
                   inputResourcePortIndex = realPortIdx;
                }
            }
            assert(result == OS_SUCCESS);
        }
        assert(outputResource);
        assert(inputResource);

        if(outputResource && inputResource)
        {
            if(outputResourcePortIndex == MpResourceTopology::MP_TOPOLOGY_NEXT_AVAILABLE_PORT)
            {
                outputResourcePortIndex = outputResource->reserveFirstUnconnectedOutput();
                assert(outputResourcePortIndex >= 0);
            }
            else if(outputResourcePortIndex < MpResourceTopology::MP_TOPOLOGY_NEXT_AVAILABLE_PORT)
            {
                // First see if a real port is already in the dictionary
                UtlInt searchKey(outputResourcePortIndex);
                UtlInt* foundValue = NULL;
                if((foundValue = (UtlInt*) newConnectionIds.findValue(&searchKey)))
                {
                    // Use the mapped index
                    outputResourcePortIndex = foundValue->getValue();
                }
                else
                {
                    // Find an available port and add it to the map
                    int realPortNum = outputResource->reserveFirstUnconnectedOutput();
                    assert(realPortNum >= 0);
                    UtlInt* portKey = new UtlInt(outputResourcePortIndex);
                    UtlInt* portValue = new UtlInt(realPortNum);
                    newConnectionIds.insertKeyAndValue(portKey, portValue);
                    outputResourcePortIndex = realPortNum;
                }
            }

            if(inputResourcePortIndex == MpResourceTopology::MP_TOPOLOGY_NEXT_AVAILABLE_PORT)
            {
                inputResourcePortIndex = inputResource->reserveFirstUnconnectedInput();
                assert(inputResourcePortIndex >= 0);
            }
            else if(inputResourcePortIndex < MpResourceTopology::MP_TOPOLOGY_NEXT_AVAILABLE_PORT)
            {
                // First see if a real port is already in the dictionary
                UtlInt searchKey(inputResourcePortIndex);
                UtlInt* foundValue = NULL;
                if((foundValue = (UtlInt*) newConnectionIds.findValue(&searchKey)))
                {
                    // Use the mapped index
                    inputResourcePortIndex = foundValue->getValue();
                }
                else
                {
                    // Find an available port and add it to the map
                    int realPortNum = inputResource->reserveFirstUnconnectedInput();
                    assert(realPortNum >= 0);
                    UtlInt* portKey = new UtlInt(inputResourcePortIndex);
                    UtlInt* portValue = new UtlInt(realPortNum);
                    newConnectionIds.insertKeyAndValue(portKey, portValue);
                    inputResourcePortIndex = realPortNum;
                }
            }


            result = addLink(*outputResource, outputResourcePortIndex, *inputResource, inputResourcePortIndex);
            assert(result == OS_SUCCESS);
        }
        connectionIndex++;
    }

    newConnectionIds.destroyAll();
    return(connectionIndex);
}
コード例 #14
0
int MpTopologyGraph::addTopologyResources(MpResourceTopology& resourceTopology,
                                          MpResourceFactory& resourceFactory,
                                          UtlHashBag& newResources,
                                          UtlBoolean replaceNumInName,
                                          int resourceNum)
{
    // Add the resources
    int resourceIndex = 0;
    MpResource* resourcePtr = NULL;
    MpResource* resourceArray[MAX_CONSTRUCTED_RESOURCES];
    UtlString resourceType;
    UtlString resourceName;
    MpConnectionID resourceConnId;
    int resourceStreamId;
    OsStatus result;
    while(resourceTopology.getResource(resourceIndex, resourceType, resourceName,
                                       resourceConnId, resourceStreamId) == OS_SUCCESS)
    {
        if(replaceNumInName)
        {
           MpResourceTopology::replaceNumInName(resourceName, resourceNum);
        }

        int numConstructorResources;
        OsStatus status;
        status = resourceFactory.newResource(resourceType, resourceName, MAX_CONSTRUCTED_RESOURCES,
                                             numConstructorResources, resourceArray);        
        if(status == OS_SUCCESS)
        {
           assert(numConstructorResources > 0);
           int arrayIndex;
           // We now can potentially get more than one resource back from the
           // constructor
           for(arrayIndex = 0; arrayIndex < numConstructorResources; arrayIndex++)
           {
              resourcePtr = resourceArray[arrayIndex];
              assert(resourcePtr);
              if(resourcePtr)
              {
#ifdef TEST_PRINT
                  printf("constructed and adding resource name: %s type: %s\n",
                         resourcePtr->getName().data(),
                         resourceType.data());
#endif
                  if(replaceNumInName && resourceConnId == MP_INVALID_CONNECTION_ID)
                  {
                     resourcePtr->setConnectionId(resourceNum);
                  }
                  else
                  {
                     resourcePtr->setConnectionId(resourceConnId);
                  }
                  resourcePtr->setStreamId(resourceStreamId);
                  newResources.insert(resourcePtr);
                  result = addResource(*resourcePtr, FALSE);
                  assert(result == OS_SUCCESS);
               }
           }
        }
        else
        {
           OsSysLog::add(FAC_MP, PRI_ERR, 
              "Failed to create resource type: %s name: %s status: %d",
              resourceType.data(), resourceName.data(), status);
        }
        resourceIndex++;
    }
    return(resourceIndex);
}