From ping at real.com  Tue Mar  2 14:14:45 2004
From: ping at real.com (Henry Ping)
Date: Mon May 10 16:37:25 2004
Subject: [Protocol-dev] CR-Client: fix RTSP message dump
Message-ID: <5.1.0.14.2.20040302140747.03b53fb8@mailone.real.com>

diff attached

Synopsis:
Fix RTSP message dump

Overview:
The outbound RTSP message is not dumped properly, it misses some critical 
information such as CSeq number. The fix is to move the dump to its base 
class right before being sent to the socket.

Files Modified:
protocol/rtsp/rtspbase.cpp
protocol/rtsp/rtspclnt.cpp

Files Added:
none

Image Size and Heap Use impact:
negligible

Platforms and Profiles affected:
x-platform

Distribution Libraries affected:
none

Platforms and Profiles Build Verified:
win32

Platforms and Profiles Functionality verified:
win32 w/ all-defines

Branch: HEAD, 1_1_6_neptune

QA Instructions: none

-->Henry
-------------- next part --------------
? Makefile
? Umakefil.upp
? a
? dbg32
? protocol_rtsp.dsp
? protocol_rtsp.dsw
Index: rtspbase.cpp
===================================================================
RCS file: /cvsroot/protocol/rtsp/rtspbase.cpp,v
retrieving revision 1.10.16.1
diff -u -w -4 -r1.10.16.1 rtspbase.cpp
--- rtspbase.cpp	18 Nov 2003 08:12:48 -0000	1.10.16.1
+++ rtspbase.cpp	2 Mar 2004 22:07:32 -0000
@@ -150,9 +150,10 @@
     m_pCommonClassFactory(NULL),
     m_pSocket(0),
     m_pFastSocket(0),
     m_uControlBytesSent(0),
-    m_pControlBuffer(0)
+    m_pControlBuffer(0),
+    m_bMessageDebug(FALSE)
 {
 }
 
 RTSPBaseProtocol::~RTSPBaseProtocol()
@@ -238,8 +239,10 @@
     pMsg->setSeqNo(seqNo);
     enqueueMessage(pMsg);
     CHXString msgStr = pMsg->asString();
 
+    handleDebug((const char*)msgStr, FALSE);
+
     CHXBuffer* pBuffer = new CHXBuffer;
     pBuffer->AddRef();
     pBuffer->Set((BYTE*)(const char*)msgStr, msgStr.GetLength());
     HX_RESULT rc = sendControlMessage(pBuffer);
@@ -253,8 +256,33 @@
 {
     // Only implemented by subclasses in server modules
 }
  
+void 
+RTSPBaseProtocol::handleDebug(const char* pMsg, BOOL bInBound)
+{
+    if(m_bMessageDebug && m_messageDebugFileName && pMsg)
+    {
+	FILE* fp = fopen(m_messageDebugFileName, "a");
+	if(!fp)
+	{
+	    return;
+	}
+
+	if(bInBound)
+	{
+	    fprintf(fp, "IN:\n");
+	}
+	else
+	{
+	    fprintf(fp, "OUT:\n");
+	}
+
+	fprintf(fp, "%s\n", pMsg);
+	fclose(fp);
+    }
+}
+
 void
 RTSPBaseProtocol::handleTiming(IHXBuffer* pMsgBuf, BOOL bInbound)
 {
     // Only implemented by subclasses in server modules
Index: rtspclnt.cpp
===================================================================
RCS file: /cvsroot/protocol/rtsp/rtspclnt.cpp,v
retrieving revision 1.41.2.14
diff -u -w -4 -r1.41.2.14 rtspclnt.cpp
--- rtspclnt.cpp	20 Feb 2004 21:09:51 -0000	1.41.2.14
+++ rtspclnt.cpp	2 Mar 2004 22:07:32 -0000
@@ -373,9 +373,8 @@
     m_pCloakValues(NULL),
     m_pSession(0),
     m_pRegistry(0),
     m_bClientDone(FALSE),
-    m_bMessageDebug(FALSE),
     m_bUseProxy(FALSE),
     m_bHTTPOnly(FALSE),
     m_pUDPSocketStreamMap(0),
     m_pRTCPSocketStreamMap(0),
@@ -3607,10 +3606,8 @@
 HX_RESULT 
 RTSPClientProtocol::sendRequest(RTSPRequestMessage* pMsg,
                                 UINT32 seqNo)
 {
-    messageDebugFileOut((const char*)pMsg->asString(), FALSE); 
-
     // Our legacy timeout approach was to periodically send messages
     // to the server.  Currently, we only send a keep alive message
     // if we have not sent an rtsp message for the duration
     // of the timeout value.
@@ -3627,10 +3624,8 @@
                                 const char* pContent,
                                 const char* pMimeType,
                                 UINT32 seqNo)
 {
-    messageDebugFileOut((const char*)pMsg->asString(), FALSE); 
-
     if (m_pSessionTimeout && !m_bUseLegacyTimeOutMsg)
     {
         m_pSessionTimeout->OnActivity();
     }
@@ -3935,9 +3930,11 @@
 {
     HX_RESULT rc = HXR_OK;
 
     m_pMutex->Lock();
-    messageDebugFileOut((const char*)pMsg->asString(), TRUE);       
+
+    handleDebug((const char*)pMsg->asString(), TRUE);
+    
     if(pMsg->tag() != RTSPMessage::T_RESP)
     {
 	int majorVersion = pMsg->majorVersion();
 	int minorVersion = pMsg->minorVersion();
@@ -5879,31 +5876,8 @@
 	}
     }
 
     return pTransportRequest;
-}
-
-void
-RTSPClientProtocol::messageDebugFileOut(const char* pMsg, BOOL bInbound)
-{
-    if(m_bMessageDebug)
-    {
-	FILE* fp = fopen(m_messageDebugFileName, "a");
-	if(!fp)
-	{
-	    return;
-	}
-	if(bInbound)
-	{
-	    fprintf(fp, "IN:\n");
-	}
-	else
-	{
-	    fprintf(fp, "OUT:\n");
-	}
-	fprintf(fp, "%s\n", pMsg);
-	fclose(fp);
-    }
 }
 
 /*
  * IHXThinnableSource methods.
Index: pub/rtspbase.h
===================================================================
RCS file: /cvsroot/protocol/rtsp/pub/rtspbase.h,v
retrieving revision 1.6
diff -u -w -4 -r1.6 rtspbase.h
--- pub/rtspbase.h	19 Sep 2003 22:39:29 -0000	1.6
+++ pub/rtspbase.h	2 Mar 2004 22:07:32 -0000
@@ -123,8 +123,9 @@
     virtual HX_RESULT	closeSocket() {return HXR_OK;}
     virtual HX_RESULT	reopenSocket() {return HXR_OK;}
 
     virtual void handleDebug(IHXBuffer* pMsgBuf, BOOL bInbound);
+    virtual void handleDebug(const char* pMsg, BOOL bInBound);
     virtual void handleTiming(IHXBuffer* pMsgBuf, BOOL bInbound);
     virtual void handleSendEvent(RTSPRequestMessage* pReqMsg);
     virtual void handleSendEvent(RTSPResponseMessage* pRespMsg);
 
@@ -134,8 +135,11 @@
     IHXBufferedSocket*		m_pFastSocket;
     UINT32			m_uControlBytesSent;
     BOOL			m_bConnectionlessControl;
     IHXBuffer*			m_pControlBuffer;
+
+    BOOL                        m_bMessageDebug;
+    CHXString                   m_messageDebugFileName;
 
 private:
     CHXSimpleList		m_msgQueue;
 };
Index: pub/rtspclnt.h
===================================================================
RCS file: /cvsroot/protocol/rtsp/pub/rtspclnt.h,v
retrieving revision 1.11.2.7
diff -u -w -4 -r1.11.2.7 rtspclnt.h
--- pub/rtspclnt.h	15 Jan 2004 23:21:46 -0000	1.11.2.7
+++ pub/rtspclnt.h	2 Mar 2004 22:07:32 -0000
@@ -821,9 +821,8 @@
 	IHXValues* pIHXValuesRequestHeaders,
 	BOOL bFirstSetup
     );
     const char* allowedMethods		();
-    void messageDebugFileOut            (const char* pMsg, BOOL bIncoming);
     void addTransportInfo		(RTSPTransportTypeEnum tType,
     					UINT16 sPort);
     RTSPTransportRequest* getTransportRequest(MIMEHeaderValue* pValue);
     void reset();
@@ -957,9 +956,8 @@
     CHXMapStringToOb*			m_pControlToStreamNoMap; // streamID->streamNumber
     BOOL				m_bSeqValueReceived;
     BOOL				m_bSetupRecord;
     BOOL				m_bClientDone;
-    BOOL                                m_bMessageDebug;
     BOOL				m_bUseProxy;
     BOOL				m_bUseHTTPProxy;
     BOOL				m_bHTTPOnly;
     BOOL				m_bNoReuseConnection;
@@ -976,9 +974,8 @@
     BOOL				m_bConnectionAlive;
     UINT32				m_uConnectionTimeout;
     BOOL				m_bEntityRequired;
     UINT16				m_uCloakPort;
-    CHXString                           m_messageDebugFileName;
     HXMutex*				m_pMutex;
     UINT16				m_uProtocolType;
     TransportMode			m_currentTransport;
 
From ehyche at real.com  Wed Mar  3 06:37:32 2004
From: ehyche at real.com (Eric Hyche)
Date: Mon May 10 16:37:25 2004
Subject: [Protocol-dev] CR-Client: fix RTSP message dump
In-Reply-To: <5.1.0.14.2.20040302140747.03b53fb8@mailone.real.com>
Message-ID: <5.1.0.14.2.20040303093630.0260ae80@mailone.real.com>


Shouldn't the body of handleDebug() be inside #ifdef _DEBUG,
as in:

void handleDebug(...)
{
#ifdef _DEBUG
...
#endif
}

or do we want to have it in release builds as well?
Other than that, looks good.

Eric

At 02:14 PM 3/2/2004 -0800, Henry Ping wrote:
>diff attached
>
>Synopsis:
>Fix RTSP message dump
>
>Overview:
>The outbound RTSP message is not dumped properly, it misses some critical 
>information such as CSeq number. The fix is to move the dump to its base 
>class right before being sent to the socket.
>
>Files Modified:
>protocol/rtsp/rtspbase.cpp
>protocol/rtsp/rtspclnt.cpp
>
>Files Added:
>none
>
>Image Size and Heap Use impact:
>negligible
>
>Platforms and Profiles affected:
>x-platform
>
>Distribution Libraries affected:
>none
>
>Platforms and Profiles Build Verified:
>win32
>
>Platforms and Profiles Functionality verified:
>win32 w/ all-defines
>
>Branch: HEAD, 1_1_6_neptune
>
>QA Instructions: none
>
>-->Henry
>
>
>_______________________________________________
>Protocol-dev mailing list
>Protocol-dev@lists.helixcommunity.org
>http://lists.helixcommunity.org/mailman/listinfo/protocol-dev

======================================
M. Eric Hyche (ehyche@real.com)
Core Technologies
RealNetworks, Inc.



From ping at real.com  Wed Mar  3 08:16:29 2004
From: ping at real.com (Henry Ping)
Date: Mon May 10 16:37:25 2004
Subject: [Protocol-dev] CR-Client: fix RTSP message dump
In-Reply-To: <5.1.0.14.2.20040303093630.0260ae80@mailone.real.com>
References: <5.1.0.14.2.20040302140747.03b53fb8@mailone.real.com>
Message-ID: <5.1.0.14.2.20040303081245.03b399f0@mailone.real.com>

Nope, but they are guarded by the unpublished preference setting 
"RTSPMessageDebug" & "RTSPMessageDebugFile".

We need this in release build so that we can ask the partners to enable 
this and send us RTSP callstack when facing RTSP playback issues in 
released players.

Thanks
-->Henry

At 09:37 AM 3/3/2004 -0500, Eric Hyche wrote:

>Shouldn't the body of handleDebug() be inside #ifdef _DEBUG,
>as in:
>
>void handleDebug(...)
>{
>#ifdef _DEBUG
>...
>#endif
>}
>
>or do we want to have it in release builds as well?
>Other than that, looks good.
>
>Eric
>
>At 02:14 PM 3/2/2004 -0800, Henry Ping wrote:
>>diff attached
>>
>>Synopsis:
>>Fix RTSP message dump
>>
>>Overview:
>>The outbound RTSP message is not dumped properly, it misses some critical 
>>information such as CSeq number. The fix is to move the dump to its base 
>>class right before being sent to the socket.
>>
>>Files Modified:
>>protocol/rtsp/rtspbase.cpp
>>protocol/rtsp/rtspclnt.cpp
>>
>>Files Added:
>>none
>>
>>Image Size and Heap Use impact:
>>negligible
>>
>>Platforms and Profiles affected:
>>x-platform
>>
>>Distribution Libraries affected:
>>none
>>
>>Platforms and Profiles Build Verified:
>>win32
>>
>>Platforms and Profiles Functionality verified:
>>win32 w/ all-defines
>>
>>Branch: HEAD, 1_1_6_neptune
>>
>>QA Instructions: none
>>
>>-->Henry
>>
>>
>>_______________________________________________
>>Protocol-dev mailing list
>>Protocol-dev@lists.helixcommunity.org
>>http://lists.helixcommunity.org/mailman/listinfo/protocol-dev
>
>======================================
>M. Eric Hyche (ehyche@real.com)
>Core Technologies
>RealNetworks, Inc.
>



From ping at real.com  Wed Mar  3 16:22:34 2004
From: ping at real.com (Henry Ping)
Date: Mon May 10 16:37:25 2004
Subject: [Protocol-dev] CR-Client: fix scalable multicast on surestream
 content & RTP via HTTPCloaking
Message-ID: <5.1.0.14.2.20040303154302.03b480c0@mailone.real.com>

Synopsis:
1. fixed failure of playback surestream content via scalable multicast
2. fixed crash when RTP via HTTPCloaking

Overview:
1. pasted from the bug report(b#113216):
"
The current logic for selecting and subscribing to streams in the client is 
broken.

On the server, multicast channels are determined based upon possible 
pairings in the Uber rulebook - thus for every bandwidth range, there is a 
unique multicast channel . This sometimes causes the same stream to be 
transmitted on multiple channels in order that the client need only 
subscribe to one given multicast channel.

Here is an Uberrulebook example:
#(Bandwidth < 20000) Stream0Bandwidth = 4000, Stream1Bandwidth = 10000)
#(Bandwidth >= 20000) Stream0Bandwidth = 4000, Stream1Bandwidth = 20000)

In this case, scalable multicast sends the 4k stream to 2 different 
channels. Once with the 10k video and once with the 20k. The client, 
however, will simply search through the SDP looking for the matching 
bandwidth. In the example, it will choose the first audio stream and the 
second video stream. Since these are on different multicast channels and 
the client only joins one, no video is received.
"

Thanks Sean who came up with most of the fix. The fix contains:
- find the proper matching stream based on the rule number if it's 
presented in SDP header
- retrieve multicast address from each media component/stream in SDP 
header, associate multicast address with each stream which will be used to 
join the multicast

2. while verifying Tommy's potential RTP reading beyond buffer fixes, I 
found the player crashes when playback via HTTPCloaking in RTP. The crash 
was caused by calling HandleOptionsResponse() prematurely without 
m_pSession and m_pSocket assignment. m_pSession is then later used without 
NULL checking (@@ -5510,21 +5502,21 @@  in the attached diff)

Files Modified:
protocol/rtsp/rtspclnt.cpp

Files Added:
none

Image Size and Heap Use impact:
negligible

Platforms and Profiles affected:
x-platform

Distribution Libraries affected:
none

Platforms and Profiles Build Verified:
win32

Platforms and Profiles Functionality verified:
win32 w/ all-defines

Branch: HEAD, 1_1_6_neptune

QA Instructions:
1. verify scalable multicast on both sure stream and non-surestream content
2. verify RTP via HTTPCloaking should succeed without crash.

-->Henry
-------------- next part --------------
? Makefile
? Umakefil.upp
? a
? dbg32
? protocol_rtsp.dsp
? protocol_rtsp.dsw
? rel32
Index: rtspclnt.cpp
===================================================================
RCS file: /cvsroot/protocol/rtsp/rtspclnt.cpp,v
retrieving revision 1.41.2.14
diff -u -w -4 -r1.41.2.14 rtspclnt.cpp
--- rtspclnt.cpp	20 Feb 2004 21:09:51 -0000	1.41.2.14
+++ rtspclnt.cpp	3 Mar 2004 23:40:03 -0000
@@ -574,27 +574,19 @@
             hresult = HXR_FAILED;
             goto cleanup;
         }
 
-        if (!m_sessionHost.IsEmpty())
+        if (m_bMulticast)
         {
-	    UINT32 addr = HXinet_addr((const char*)m_sessionHost);
-	    UINT32 ulHostAddr = DwToHost(addr);
-
-            if (ulHostAddr >= MULTICAST_ADDRESS_RANGE_LOW && 
-                ulHostAddr <= MULTICAST_ADDRESS_RANGE_HIGH)
+            if (m_sessionHost.IsEmpty())
             {
-                m_bMulticast = TRUE;
-                m_ulMulticastAddress = ulHostAddr;
+                m_sessionHost = "0.0.0.0";
+            }
 
                 pHostName = (const char*)m_sessionHost;
-
                 pInfo->SetPropertyULONG32("MulticastOnly", 1);
-                m_pSDPFileHeader->SetPropertyULONG32("LiveStream", 1);
             }
-        }
-        
-        if (!m_bMulticast)
+        else
         {
             pURL = new CHXURL(m_headerControl);
         
             if (!(pURLProps = pURL->GetProperties()))
@@ -765,9 +757,9 @@
         {
             pHost = m_hostName;
         }
 
-	if(IsNumericAddr(pHost, pHost.GetLength()))
+	if(IsNumericAddr(pHost, pHost.GetLength()) || m_bMulticast)
 	{
 	    UINT32 addr = HXinet_addr((const char*)pHost);
 	    UINT32 ulHostAddr = DwToHost(addr);
 
@@ -1432,12 +1424,12 @@
             pTrans->addStreamInfo(pStreamInfo);
 	    (*m_pTransportStreamMap)[pStreamInfo->m_streamNumber] = pTrans;
 
 	    (*m_pTransportMPortMap)[pStreamInfo->m_sPort] = pTrans;
-            pTrans->JoinMulticast(m_ulConnectToAddr, pStreamInfo->m_sPort, pUDPSocket);
+            pTrans->JoinMulticast(pStreamInfo->m_ulMulticastAddr, pStreamInfo->m_sPort, pUDPSocket);
 
 	    (*m_pTransportMPortMap)[pStreamInfo->m_sPort+1] = pRTCPTrans;
-            pRTCPTrans->JoinMulticast(m_ulConnectToAddr, pStreamInfo->m_sPort + 1, pRTCPUDPSocket);
+            pRTCPTrans->JoinMulticast(pStreamInfo->m_ulMulticastAddr, pStreamInfo->m_sPort + 1, pRTCPUDPSocket);
 
 	    if ((!m_bHasSyncMasterStream) && 
 		(pStreamInfo->m_eMediaType == RTSPMEDIA_TYPE_AUDIO))
 	    {
@@ -5510,21 +5502,21 @@
     // Assumption is we will send no options messages while waiting
     // for our session time out options response.
     HX_ASSERT(!m_bKeepAlivePending);
     
-    if (m_bNonRSRTP)
-    {
-	rc = m_pResp->HandleOptionsResponse(HXR_OK, NULL);
-	goto cleanup;
-    }
-
     if (!m_bSessionSucceeded)
     {
 	HX_ASSERT(!m_pSession && !m_pSocket);
 	m_pSession = pSession;
 	m_pSocket = pSocket;
     }
 
+    if (m_bNonRSRTP)
+    {
+	rc = m_pResp->HandleOptionsResponse(HXR_OK, NULL);
+	goto cleanup;
+    }
+
     pMsg = new RTSPOptionsMessage;
 
     // construct "rtsp://%-.200s:%u"
     m_url = "rtsp://";
@@ -5555,16 +5547,16 @@
     seqNo = m_pSession->getNextSeqNo(this);
 
     rc = sendRequest(pMsg, seqNo);
 
+cleanup:
+
     if (!m_bSessionSucceeded)
     {
 	m_pSession = NULL;
 	m_pSocket = NULL;
     }
     
-cleanup:
-
     m_pMutex->Unlock();
 
     return rc;
 }
@@ -6862,12 +6854,21 @@
 	// Get session level RTP bandwidth modifiers
 	ppValues[0]->GetPropertyULONG32("RtcpRRRate", ulRtpRRBitRate);
 	ppValues[0]->GetPropertyULONG32("RtcpRSRate", ulRtpRSBitRate);
         
+        // get multicast address from the session description
         if (HXR_OK == ppValues[0]->GetPropertyCString("MulticastAddress", pIPAddress))
         {
+	    UINT32 addr = HXinet_addr((const char*)pIPAddress->GetBuffer());
+            UINT32 ulHostAddr = DwToHost(addr);
+		
+            if (ulHostAddr >= MULTICAST_ADDRESS_RANGE_LOW && 
+                ulHostAddr <= MULTICAST_ADDRESS_RANGE_HIGH)
+            {
+                m_bMulticast = TRUE;
             m_sessionHost = pIPAddress->GetBuffer();
         }
+        }
         HX_RELEASE(pIPAddress);
 
         /*
          * Get a number of streams in this presentation
@@ -6893,8 +6894,10 @@
         }
 #if defined(HELIX_FEATURE_TRANSPORT_MULTICAST)
         else
         {
+	    ULONG32 ulRuleNumber = 0;
+
     	    // we should have at least one stream
     	    HX_ASSERT(ulNumStreams > 0 && m_bSDPInitiated);
     
             // set the StreamCount
@@ -6909,9 +6912,10 @@
 	    if (GetSubscriptionBW(m_pSDPFileHeader, 
 			          &ppValues[1], 
 			          nValues - 1, 
 			          pulSubscriptionBW, 
-			          ulNumStreams) != TRUE)
+			          ulNumStreams,
+                                  ulRuleNumber) != TRUE)
 	    {              
 	        // this should never happen
                 HX_ASSERT(FALSE);
 	        rc = HXR_UNEXPECTED;
@@ -6928,9 +6932,10 @@
      	    if (GetRightHeaders(ppRealHeaders,
      			        ulNumStreams,
      			        &ppValues[1],
      			        nValues - 1,
-     			        pulSubscriptionBW) != TRUE)
+     			        pulSubscriptionBW,
+                                ulRuleNumber) != TRUE)
      	    {
      	        // this should never happen
                 HX_ASSERT(FALSE);
 	        rc = HXR_UNEXPECTED;
@@ -7053,8 +7058,9 @@
 		char tmp[32];
 		SafeSprintf(tmp, 32, "streamid=%u", (UINT16)streamNumber);
 		pInfo->m_streamControl = tmp;
 	    }
+
 	    pInfo->m_streamNumber = (UINT16)streamNumber;
 	    pInfo->m_bNeedReliablePackets = needReliable ? TRUE: FALSE;
 	    pInfo->m_rtpPayloadType = (INT16)rtpPayloadType;
 	    pInfo->m_sampleRate = sampleRate;   
@@ -7072,17 +7078,37 @@
 	    pInfo->m_ulRtpRRBitRate = ulRtpRRBitRate;
 	    pInfo->m_ulRtpRSBitRate = ulRtpRSBitRate;
             pInfo->m_bRealMedia = bRealMedia;
 
-            if ((m_sessionHost.IsEmpty() || HXR_INADDR_ANY == HXinet_addr((const char*)m_sessionHost)) &&
-                HXR_OK == ppRealHeaders[i]->GetPropertyCString("MulticastAddress", pIPAddress))
+            // get multicast address from the media description
+            if (HXR_OK == ppRealHeaders[i]->GetPropertyCString("MulticastAddress", pIPAddress))
             {
-                m_sessionHost = pIPAddress->GetBuffer();
+		UINT32 addr = HXinet_addr((const char*)pIPAddress->GetBuffer());
+		UINT32 ulHostAddr = DwToHost(addr);
+		
+		if (ulHostAddr >= MULTICAST_ADDRESS_RANGE_LOW && 
+		    ulHostAddr <= MULTICAST_ADDRESS_RANGE_HIGH)
+		{
+		    m_bMulticast = TRUE;
+		    pInfo->m_ulMulticastAddr = ulHostAddr;
+		}
+            }
+            // otherwise, apply the session multicast address to media component
+            else if (m_bMulticast && !m_sessionHost.IsEmpty())
+            {
+		UINT32 addr = HXinet_addr((const char*)m_sessionHost);
+		UINT32 ulHostAddr = DwToHost(addr);
+                pInfo->m_ulMulticastAddr = ulHostAddr;
             }
             HX_RELEASE(pIPAddress);
 
             m_streamInfoList.AddTail(pInfo);
 	}
+
+        if (m_bMulticast)
+        {
+            m_pSDPFileHeader->SetPropertyULONG32("LiveStream", 1);
+        }
     }
 
 cleanup:
 
@@ -7190,9 +7216,10 @@
 RTSPClientProtocol::GetSubscriptionBW(IHXValues*    pFileHeader, 
 				      IHXValues**   ppStrmHeaders,
 				      UINT16        unNumStrmHeaders,
 				      REF(UINT32*)  pulSubscriptionBW,
-				      UINT32        ulNumStreams)					  
+				      UINT32        ulNumStreams,
+                                      REF(UINT32)   ulRuleNumber)					  
 {
     HX_ASSERT(pFileHeader);
     HX_ASSERT(ppStrmHeaders);
     HX_ASSERT(unNumStrmHeaders >= 1);
@@ -7201,8 +7228,10 @@
 
     IHXBuffer*	pRuleBuf = NULL;
     IHXBuffer* pBandwidth = NULL;
 
+    ulRuleNumber = 0;
+
     pFileHeader->AddRef();
 
     if (!m_pPreferences || HXR_OK != m_pPreferences->ReadPref("Bandwidth", pBandwidth))
     {
@@ -7298,9 +7327,8 @@
 	unRules = rules.GetNumRules();    
 
 	// get subscriptions for this bandwidth
 	BOOL bSubInfo[256];
-	UINT16 unRuleNum = 0;
 
 	IHXValues* pValues = new CHXHeader();
     	pValues->AddRef();
 	
@@ -7315,15 +7343,15 @@
 	{
 	    if (TRUE == bSubInfo[y])
 	    {
 	    	// there should be only one
-		unRuleNum = y;
+		ulRuleNumber = y;
 		break;
 	    }
 	}
 
 	// Get a BW for each stream
-        rules.GetProperties((int)unRuleNum, pValues);
+        rules.GetProperties((int)ulRuleNumber, pValues);
         for (int i = 0; i < (int)ulNumStreams; i++)
         {
             char rgStreamBW[32];
             sprintf(rgStreamBW, "Stream%dBandwidth", i);
@@ -7348,9 +7376,10 @@
 RTSPClientProtocol::GetRightHeaders(REF(IHXValues**)    ppRealHeaders, // out
      				    UINT32	        ulNumStreams,
      				    IHXValues**         ppHeaders,
      				    UINT32	        cHeaders,
-     				    UINT32*             pulSubscriptionBW)
+     				    UINT32*             pulSubscriptionBW,
+                                    UINT32              ulRuleNumber)
 {
     HX_ASSERT(ulNumStreams >= 1);
     HX_ASSERT(ppHeaders);
     HX_ASSERT(pulSubscriptionBW);
@@ -7360,9 +7389,10 @@
     
     for (int i = 0; i < (int)ulNumStreams; i++)
     {
 	ULONG32 ulID = 0;
-	ULONG32 ulBW = 0;;
+	ULONG32 ulBW = 0;
+	ULONG32 ulRule = 0;
 	BOOL    bFound = FALSE;
 
 	for (int j = 0; j < (int)cHeaders; j++)
     	{
@@ -7370,9 +7400,27 @@
 
     	    IHXValues* pSrcH = ppHeaders[j];
 	    pSrcH->AddRef();
 
-	    if ((HXR_OK == pSrcH->GetPropertyULONG32("AvgBitRate", ulBW)) &&
+	    // Scalable multicast identifies which uber rule each stream is for
+	    if (HXR_OK == pSrcH->GetPropertyULONG32("RuleNumber", ulRule))
+	    {
+		if (ulRule == ulRuleNumber)
+		{
+		    bFound = TRUE;
+		    
+		    // This is the right heaader, 
+		    if ((HXR_OK == pSrcH->GetPropertyULONG32("StreamId", ulID)) &&
+			((int)ulID == i))
+		    {
+			ppRealHeaders[i] = pSrcH;
+			ppRealHeaders[i]->AddRef();
+		        HX_RELEASE(pSrcH);		    
+			break; // we found for this stream, go to next one
+		    }
+		}
+	    }
+	    else if ((HXR_OK == pSrcH->GetPropertyULONG32("AvgBitRate", ulBW)) &&
 		(ulBW == pulSubscriptionBW[i]))
 	    {
 		// this one has the right BW, how about stream number?
 		if ((HXR_OK == pSrcH->GetPropertyULONG32("StreamId", ulID)) &&
Index: pub/rtspclnt.h
===================================================================
RCS file: /cvsroot/protocol/rtsp/pub/rtspclnt.h,v
retrieving revision 1.11.2.7
diff -u -w -4 -r1.11.2.7 rtspclnt.h
--- pub/rtspclnt.h	15 Jan 2004 23:21:46 -0000	1.11.2.7
+++ pub/rtspclnt.h	3 Mar 2004 23:40:03 -0000
@@ -875,15 +875,17 @@
     BOOL        GetSubscriptionBW(IHXValues*    pFileHeader, 
 			          IHXValues**   ppStrmHeaders,
 			          UINT16        unNumStrmHeaders,
 			          REF(UINT32*)  pulSubscriptionBW,
-			          UINT32        ulNumStreams);					  
+			          UINT32        ulNumStreams,
+                                  REF(UINT32)	ulRuleNumber);		                                  
 
     BOOL        GetRightHeaders(REF(IHXValues**)    ppRealHeaders, // out
      			        UINT32		    ulNumStreams,
 	     		        IHXValues**	    ppHeaders,
      			        UINT32		    cHeaders,
-     			        UINT32*             pulSubscriptionBW);
+     			        UINT32*             pulSubscriptionBW,
+                                UINT32		    ulRuleNumber);
 #endif /* HELIX_FEATURE_TRANSPORT_MULTICAST */
 
     BOOL        GetStreamCountNoTrust(IHXValues**   ppHeaders, 
 				      UINT16        unNumHeader,
-------------- next part --------------
? Makefile
? Umakefil.upp
? a
? dbg32
? protocol_transport_common_system.dsp
? protocol_transport_common_system.dsw
? rel32
Index: pub/rtspif.h
===================================================================
RCS file: /cvsroot/protocol/transport/common/system/pub/rtspif.h,v
retrieving revision 1.11.8.1
diff -u -w -4 -r1.11.8.1 rtspif.h
--- pub/rtspif.h	15 Oct 2003 16:34:42 -0000	1.11.8.1
+++ pub/rtspif.h	4 Mar 2004 00:17:54 -0000
@@ -193,8 +193,9 @@
 	, m_bHasOutOfOrderTS(FALSE)
 	, m_ulAvgBitRate(0)
 	, m_ulRtpRRBitRate((UINT32)-1)
 	, m_ulRtpRSBitRate((UINT32)-1)
+        , m_ulMulticastAddr(0)
         , m_bRealMedia(FALSE)
     {}	 
     
     UINT16	m_streamNumber;
@@ -221,8 +222,9 @@
     BOOL	m_bActive;
     UINT32      m_ulAvgBitRate;
     UINT32      m_ulRtpRRBitRate;
     UINT32      m_ulRtpRSBitRate;
+    UINT32      m_ulMulticastAddr;
     BOOL        m_bRealMedia;
 } RTSPStreamInfo;
 
 typedef struct _RTSPSocketInfo
From acolwell at real.com  Thu Mar  4 10:20:13 2004
From: acolwell at real.com (Aaron Colwell)
Date: Mon May 10 16:37:26 2004
Subject: [Protocol-dev] CR-Client: fix scalable multicast on
	surestream content & RTP via HTTPCloaking
In-Reply-To: <5.1.0.14.2.20040303154302.03b480c0@mailone.real.com>
Message-ID: <5.1.0.14.2.20040304102005.02466eb0@mailone.real.com>

These look good.

Aaron
At 04:22 PM 3/3/2004, Henry Ping wrote:
>Synopsis:
>1. fixed failure of playback surestream content via scalable multicast
>2. fixed crash when RTP via HTTPCloaking
>
>Overview:
>1. pasted from the bug report(b#113216):
>"
>The current logic for selecting and subscribing to streams in the client 
>is broken.
>
>On the server, multicast channels are determined based upon possible 
>pairings in the Uber rulebook - thus for every bandwidth range, there is a 
>unique multicast channel . This sometimes causes the same stream to be 
>transmitted on multiple channels in order that the client need only 
>subscribe to one given multicast channel.
>
>Here is an Uberrulebook example:
>#(Bandwidth < 20000) Stream0Bandwidth = 4000, Stream1Bandwidth = 10000)
>#(Bandwidth >= 20000) Stream0Bandwidth = 4000, Stream1Bandwidth = 20000)
>
>In this case, scalable multicast sends the 4k stream to 2 different 
>channels. Once with the 10k video and once with the 20k. The client, 
>however, will simply search through the SDP looking for the matching 
>bandwidth. In the example, it will choose the first audio stream and the 
>second video stream. Since these are on different multicast channels and 
>the client only joins one, no video is received.
>"
>
>Thanks Sean who came up with most of the fix. The fix contains:
>- find the proper matching stream based on the rule number if it's 
>presented in SDP header
>- retrieve multicast address from each media component/stream in SDP 
>header, associate multicast address with each stream which will be used to 
>join the multicast
>
>2. while verifying Tommy's potential RTP reading beyond buffer fixes, I 
>found the player crashes when playback via HTTPCloaking in RTP. The crash 
>was caused by calling HandleOptionsResponse() prematurely without 
>m_pSession and m_pSocket assignment. m_pSession is then later used without 
>NULL checking (@@ -5510,21 +5502,21 @@  in the attached diff)
>
>Files Modified:
>protocol/rtsp/rtspclnt.cpp
>
>Files Added:
>none
>
>Image Size and Heap Use impact:
>negligible
>
>Platforms and Profiles affected:
>x-platform
>
>Distribution Libraries affected:
>none
>
>Platforms and Profiles Build Verified:
>win32
>
>Platforms and Profiles Functionality verified:
>win32 w/ all-defines
>
>Branch: HEAD, 1_1_6_neptune
>
>QA Instructions:
>1. verify scalable multicast on both sure stream and non-surestream content
>2. verify RTP via HTTPCloaking should succeed without crash.
>
>-->Henry
>
>
>
>_______________________________________________
>Protocol-dev mailing list
>Protocol-dev@lists.helixcommunity.org
>http://lists.helixcommunity.org/mailman/listinfo/protocol-dev




From ping at real.com  Fri Mar  5 09:11:59 2004
From: ping at real.com (Henry Ping)
Date: Mon May 10 16:37:26 2004
Subject: [Protocol-dev] CR-Client: properly handle RTSP PLAY response
Message-ID: <5.1.0.14.2.20040305082420.03ce3d90@mailone.real.com>

Synopsis:
Exclude post-seeking logic when handling PLAY response from pause

Overview:
Before:
The client doesn't include range field in its PLAY request when resuming 
after the pause, it includes range field in PLAY request when resuming 
after the seeking.
The server doesn't include RTP-Info in its PLAY response when PLAY request 
doesn't include range.

Now:
The client's behavior is still the same but the new server10 now always 
include RTP-Info in PLAY response even the range is not included in PLAY 
request from the client.

The dependency between range in PLAY request and RTP-Info in PLAY response 
seems to be our own thing since the RTSP spec doesn't require such.

When RTP-Info is in PLAY response, RTSPTransportBuffer::Init() is called to 
reset the sequence number and there is logic inside this function which 
triggers post-seeking events such as flushing the packet queue.

The fix is to only set these variables(m_uSeekSequenceNumber and 
m_bWaitForSeekFlush) when we are sure this is from seeking.

Files Modified:
protocol/transport/common/system/transbuf.cpp

Files Added:
none

Image Size and Heap Use impact:
None

Platforms and Profiles affected:
all

Distribution Libraries affected:
None

Platforms and Profiles Build Verified:
Win32 w/ all-defines

Branch:
HEAD, Neptune

QA Instructions:
Verify pause->resume, pause->seeking->resume and seeking->resume from both 
server9.0 and server10

Index: transbuf.cpp
===================================================================
RCS file: /cvsroot/protocol/transport/common/system/transbuf.cpp,v
retrieving revision 1.12.2.4
diff -u -w -1 -0 -r1.12.2.4 transbuf.cpp
--- transbuf.cpp	1 Mar 2004 22:11:32 -0000	1.12.2.4
+++ transbuf.cpp	5 Mar 2004 16:23:06 -0000
@@ -306,35 +306,23 @@

          m_uACKSequenceNumber   =
          m_uFirstSequenceNumber =
          m_uLastSequenceNumber  = uSeqNo;

          if (m_uSeekCount > 0)
          {
              return HXR_OK;
          }
      }
-    else
-    {
-        /*
-         * m_uSeekCount had better be > 0
-         */
-
-        if (m_uSeekCount)
+    else if (m_uSeekCount)
          {
              m_uSeekCount--;
-        }
-        else
-        {
-            HX_ASSERT(FALSE);
-        }
-
          if (m_uSeekCount > 0)
          {
              return HXR_OK;
          }

          m_uSeekSequenceNumber = uSeqNo;
          m_bWaitingForSeekFlush = TRUE;
      }

      m_status = TRANSBUF_READY;

-->Henry



From pina.saginario at nexse.com  Fri Mar  5 01:04:57 2004
From: pina.saginario at nexse.com (Pina Roberta Saginario)
Date: Mon May 10 16:37:26 2004
Subject: [Protocol-dev] rm format
Message-ID: 

Hi folks!

I saw that if a player "use" all the stream sent from the server, the
"client.n.Session.n.Transport.n.BytesSent"
are ever less than "client.n.Session.n.FileSize". This appens because there
are data in the file that is not part of the media
payload, such as stream descriptive info, etc. depending on file type.

There is a way to know how this part is big, for example for .rm files? I
need to know if the server sent all the stream.

Thanks in advance.
	Pina





From ehyche at real.com  Sun Mar  7 18:08:06 2004
From: ehyche at real.com (Eric Hyche)
Date: Mon May 10 16:37:26 2004
Subject: [Protocol-dev] CR-Client: fix leak in RTSPClientProtocol
Message-ID: <5.1.0.14.2.20040307210417.02778350@mailone.real.com>


Synopsis: Fixes small leak in RTSPClientProtocol

Overview: When looping through the CString properties
           in the request headers, we were not releasing
           the IHXBuffer before getting the next property.

Branches: HEAD, 116Nep, 130NepX

Index: rtspclnt.cpp
===================================================================
RCS file: /cvsroot/protocol/rtsp/rtspclnt.cpp,v
retrieving revision 1.66
diff -u -w -u -w -r1.66 rtspclnt.cpp
--- rtspclnt.cpp        4 Mar 2004 02:32:11 -0000       1.66
+++ rtspclnt.cpp        8 Mar 2004 02:04:05 -0000
@@ -6359,7 +6359,7 @@
      if (pIHXValuesRequestHeaders)
      {
         const char* pName = NULL;
-       IHXBuffer* pValue;
+       IHXBuffer* pValue = NULL;

         HX_RESULT result = 
pIHXValuesRequestHeaders->GetFirstPropertyCString(pName, pValue);

@@ -6490,6 +6490,7 @@
                     HX_RELEASE(pRegistry);
                 }
             }
+            HX_RELEASE(pValue);
             result = 
pIHXValuesRequestHeaders->GetNextPropertyCString(pName, pValue);
         }
      }


======================================
M. Eric Hyche (ehyche@real.com)
Core Technologies
RealNetworks, Inc.



From ping at real.com  Sun Mar  7 18:12:44 2004
From: ping at real.com (Henry Ping)
Date: Mon May 10 16:37:26 2004
Subject: [Protocol-dev] CR-Client: fix leak in RTSPClientProtocol
In-Reply-To: <5.1.0.14.2.20040307210417.02778350@mailone.real.com>
Message-ID: <5.1.0.14.2.20040307181236.03d46298@mailone.real.com>

looks good

-->Henry

At 09:08 PM 3/7/2004 -0500, Eric Hyche wrote:

>Synopsis: Fixes small leak in RTSPClientProtocol
>
>Overview: When looping through the CString properties
>           in the request headers, we were not releasing
>           the IHXBuffer before getting the next property.
>
>Branches: HEAD, 116Nep, 130NepX
>
>Index: rtspclnt.cpp
>===================================================================
>RCS file: /cvsroot/protocol/rtsp/rtspclnt.cpp,v
>retrieving revision 1.66
>diff -u -w -u -w -r1.66 rtspclnt.cpp
>--- rtspclnt.cpp        4 Mar 2004 02:32:11 -0000       1.66
>+++ rtspclnt.cpp        8 Mar 2004 02:04:05 -0000
>@@ -6359,7 +6359,7 @@
>      if (pIHXValuesRequestHeaders)
>      {
>         const char* pName = NULL;
>-       IHXBuffer* pValue;
>+       IHXBuffer* pValue = NULL;
>
>         HX_RESULT result = 
> pIHXValuesRequestHeaders->GetFirstPropertyCString(pName, pValue);
>
>@@ -6490,6 +6490,7 @@
>                     HX_RELEASE(pRegistry);
>                 }
>             }
>+            HX_RELEASE(pValue);
>             result = 
> pIHXValuesRequestHeaders->GetNextPropertyCString(pName, pValue);
>         }
>      }
>
>
>======================================
>M. Eric Hyche (ehyche@real.com)
>Core Technologies
>RealNetworks, Inc.
>
>
>_______________________________________________
>Protocol-dev mailing list
>Protocol-dev@lists.helixcommunity.org
>http://lists.helixcommunity.org/mailman/listinfo/protocol-dev



From ehyche at real.com  Sun Mar  7 18:25:54 2004
From: ehyche at real.com (Eric Hyche)
Date: Mon May 10 16:37:26 2004
Subject: [Protocol-dev] CR-Client: fix leak in RTSPClientProtocol
In-Reply-To: <5.1.0.14.2.20040307181236.03d46298@mailone.real.com>
References: <5.1.0.14.2.20040307210417.02778350@mailone.real.com>
Message-ID: <5.1.0.14.2.20040307212538.02778350@mailone.real.com>


Committed to HEAD, 116Nep, 130NepX

At 06:12 PM 3/7/2004 -0800, Henry Ping wrote:
>looks good
>
>-->Henry
>
>At 09:08 PM 3/7/2004 -0500, Eric Hyche wrote:
>
>>Synopsis: Fixes small leak in RTSPClientProtocol
>>
>>Overview: When looping through the CString properties
>>           in the request headers, we were not releasing
>>           the IHXBuffer before getting the next property.
>>
>>Branches: HEAD, 116Nep, 130NepX
>>
>>Index: rtspclnt.cpp
>>===================================================================
>>RCS file: /cvsroot/protocol/rtsp/rtspclnt.cpp,v
>>retrieving revision 1.66
>>diff -u -w -u -w -r1.66 rtspclnt.cpp
>>--- rtspclnt.cpp        4 Mar 2004 02:32:11 -0000       1.66
>>+++ rtspclnt.cpp        8 Mar 2004 02:04:05 -0000
>>@@ -6359,7 +6359,7 @@
>>      if (pIHXValuesRequestHeaders)
>>      {
>>         const char* pName = NULL;
>>-       IHXBuffer* pValue;
>>+       IHXBuffer* pValue = NULL;
>>
>>         HX_RESULT result = 
>> pIHXValuesRequestHeaders->GetFirstPropertyCString(pName, pValue);
>>
>>@@ -6490,6 +6490,7 @@
>>                     HX_RELEASE(pRegistry);
>>                 }
>>             }
>>+            HX_RELEASE(pValue);
>>             result = 
>> pIHXValuesRequestHeaders->GetNextPropertyCString(pName, pValue);
>>         }
>>      }
>>
>>
>>======================================
>>M. Eric Hyche (ehyche@real.com)
>>Core Technologies
>>RealNetworks, Inc.
>>
>>
>>_______________________________________________
>>Protocol-dev mailing list
>>Protocol-dev@lists.helixcommunity.org
>>http://lists.helixcommunity.org/mailman/listinfo/protocol-dev
>

======================================
M. Eric Hyche (ehyche@real.com)
Core Technologies
RealNetworks, Inc.



From ping at real.com  Mon Mar  8 11:33:49 2004
From: ping at real.com (Henry Ping)
Date: Mon May 10 16:37:26 2004
Subject: [Protocol-dev] CR-Client: fix HTTPCloaking in SmartER Networking
Message-ID: <5.1.0.14.2.20040308111115.03c06fa0@mailone.real.com>

Synopsis:
The core saves the wrong cloaking port which causes failure of the 
subsequent HTTPCloaking playbacks. b#113538

Overview:
Part of the SmartER Networking is to save the successful transport & 
cloaking port for a particular server.

When HTTPCloaking is selected and it's the 1st playback from this server, 
the core doesn't know which cloaking port to use so it will attempt 4 
cloaking ports at the same time and selects the first one succeeded.

Receiving redirect request is considered to be a transport success, but 
apparently the protocol doesn't pass the successful cloaking port back to 
the core so the core saves the default port(likely the wrong one).

For the subsequent HTTPCloaking playback from the same server, the core 
will skip the cloaking port detection and use the previous known cloaking 
port for this server. In this case, the playback fails due to the invalid 
cloaking port.

The changes include:
- pass the succeeded transport/cloaking port to the core when processing 
Redirect
- consolidate transport reporting logic into a function: 
ReportSuccessfulTransport()

Files Modified:
protocol/rtsp/rtspclnt.cpp

Image Size and Heap Use impact:
Minor saving in image size

Platforms and Profiles Affected:
x-platform

Distribution Libraries affected:
none

Distribution library impact and planned action:
none

Platforms and Profiles Build Verified:
Win32 w/ all-defines

Platforms and Profiles Functionality verified:
Win32

Branch: HEAD and Neptune

QA Instructions: verify UDP/TCP/HTTPCloaking playback involving redirector

-->Henry
-------------- next part --------------
? Makefile
? Umakefil.upp
? a
? dbg32
? protocol_rtsp.dsp
? protocol_rtsp.dsw
? rel32
Index: rtspclnt.cpp
===================================================================
RCS file: /cvsroot/protocol/rtsp/rtspclnt.cpp,v
retrieving revision 1.41.2.16
diff -u -w -1 -0 -r1.41.2.16 rtspclnt.cpp
--- rtspclnt.cpp	4 Mar 2004 02:35:05 -0000	1.41.2.16
+++ rtspclnt.cpp	8 Mar 2004 19:10:58 -0000
@@ -3064,20 +3064,21 @@
 	    {
 		msFromNow = pRange->m_begin;
 	    }
 	}
 	MIMEHeaderValue* pURLValue = pLocation->getFirstHeaderValue();
 	if(pURLValue)
 	{
 	    CHXString redirectURL = pURLValue->value();
 	    if(redirectURL.GetLength() > 0)
 	    {
+                ReportSuccessfulTransport();
 		rc = m_pResp->HandleRedirectRequest((const char*)redirectURL, 
 		    msFromNow);
 		goto exit;
 	    }
 	}
     }
     rc = m_pResp->HandleRedirectRequest(0, 0);
 exit:
     m_pMutex->Unlock();
     return rc; 
@@ -3133,20 +3134,21 @@
 	    {
 		msFromNow = pRange->m_begin;
 	    }
 	}
 	MIMEHeaderValue* pURLValue = pLocation->getFirstHeaderValue();
 	if(pURLValue)
 	{
 	    CHXString redirectURL = pURLValue->value();
 	    if(redirectURL.GetLength() > 0)
 	    {
+                ReportSuccessfulTransport();
 		rc = m_pResp->HandleRedirectRequest((const char*)redirectURL, 
 		    msFromNow);
 		goto exit;
 	    }
 	}
     }    
     
     rc = m_pResp->HandleRedirectRequest(0, 0);
 exit:
     m_pMutex->Unlock();
@@ -3617,20 +3619,42 @@
                                 UINT32 seqNo)
 {
     if (m_pSessionTimeout && !m_bUseLegacyTimeOutMsg)
     {
         m_pSessionTimeout->OnActivity();
     }
 
     return RTSPBaseProtocol::sendRequest(pMsg, pContent, pMimeType, seqNo);
 }
 
+HX_RESULT
+RTSPClientProtocol::ReportSuccessfulTransport(void)
+{
+    HX_RESULT   rc = HXR_OK;
+
+    if (!m_bReportedSuccessfulTransport)
+    {
+	m_bReportedSuccessfulTransport = TRUE;
+
+	IHXPreferredTransportSink* pPreferredTransportSink = NULL;
+	if (m_pResp &&
+	    HXR_OK == m_pResp->QueryInterface(IID_IHXPreferredTransportSink, 
+					      (void**)&pPreferredTransportSink))
+	{
+	    pPreferredTransportSink->TransportSucceeded(m_currentTransport, m_uCloakPort);
+	}
+	HX_RELEASE(pPreferredTransportSink);
+    }
+
+    return rc;
+}
+
 BOOL
 RTSPClientProtocol::IsRealServer(void)
 {
     return FALSE;
 }
 
 STDMETHODIMP
 RTSPClientProtocol::SetFirstSeqNum(UINT16 uStreamNumber, UINT16 uSeqNum)
 {
     m_pMutex->Lock();
@@ -3719,33 +3743,21 @@
 	    bMCastPort = TRUE;
 	    m_currentTransport = MulticastMode;
 	}
 
         if (pTrans)
         {
             // make sure the unicast packets received are coming from the same server
             // we are connecting to
             if ((m_ulConnectToAddr == ulAddr) || bMCastPort)
             {            
-	        if (!m_bReportedSuccessfulTransport)
-	        {
-		    m_bReportedSuccessfulTransport = TRUE;
-
-		    IHXPreferredTransportSink* pPreferredTransportSink = NULL;
-		    if (m_pResp &&
-		        HXR_OK == m_pResp->QueryInterface(IID_IHXPreferredTransportSink, 
-						          (void**)&pPreferredTransportSink))
-		    {
-		        pPreferredTransportSink->TransportSucceeded(m_currentTransport, m_uCloakPort);
-		    }
-		    HX_RELEASE(pPreferredTransportSink);
-	        }
+                ReportSuccessfulTransport();
 
                 // drop all the scalable multicast packets when we are paused
                 if ((MulticastMode != m_currentTransport) || !m_bSDPInitiated || !m_bPaused)
                 {
 	            hresult = pTrans->handlePacket(pBuffer);
 	            if (m_bSplitterConsumer)
 	            {
 		        pTrans->releasePackets();
 	            }
                 }
@@ -4265,34 +4277,21 @@
     if( rc == HXR_OUTOFMEMORY )
     {
         pBuffer->Release();
         rc = HXR_OUTOFMEMORY;
         goto overandout;
     }
 
     RTSPTransport* pTrans;
     if (m_pTransportChannelMap->Lookup(channel, (void*&)pTrans))
     {
-        // report that the transport succeeded, if we haven't do so already
-        if (!m_bReportedSuccessfulTransport)
-        {
-            m_bReportedSuccessfulTransport = TRUE;
-            IHXPreferredTransportSink* pPreferredTransportSink = NULL;
-            if (m_pResp &&
-                HXR_OK == m_pResp->QueryInterface(IID_IHXPreferredTransportSink, 
-                                                (void**)&pPreferredTransportSink))
-            {
-                pPreferredTransportSink->TransportSucceeded(m_currentTransport, m_uCloakPort);
-            }
-            HX_RELEASE(pPreferredTransportSink);
-        }
-        
+        ReportSuccessfulTransport();        
 	rc = pTrans->handlePacket(pBuffer);
     }
 #ifdef _DEBUG
     else
     {
 	HX_ASSERT(!"make sure TransportChannelMap has been set up right...");	
     }
 #endif	
 
     pBuffer->Release();
Index: pub/rtspclnt.h
===================================================================
RCS file: /cvsroot/protocol/rtsp/pub/rtspclnt.h,v
retrieving revision 1.11.2.9
diff -u -w -1 -0 -r1.11.2.9 rtspclnt.h
--- pub/rtspclnt.h	4 Mar 2004 02:35:06 -0000	1.11.2.9
+++ pub/rtspclnt.h	8 Mar 2004 19:10:58 -0000
@@ -907,20 +907,21 @@
 				       INT32 bandwidthWanted);
     void addUAProfHeaders(IHXValues *pHeaders);
 
     RTSPTransportBuffer* getTransportBuffer(UINT16 uStreamNumber);
 
     virtual HX_RESULT	sendRequest(RTSPRequestMessage* pMsg, UINT32 seqNo);
     virtual HX_RESULT	sendRequest(RTSPRequestMessage* pMsg,
                                     const char* pContent,
                                     const char* pMimeType, UINT32 seqNo);
 
+            HX_RESULT   ReportSuccessfulTransport(void);
 
     LONG32                              m_lRefCount;
     UINT16				m_foreignPort;
     UINT32				m_foreignAddr;
     UINT32                              m_ulConnectToAddr;
     UINT16				m_setupResponseCount;    
     IHXInterruptState*			m_pInterruptState;
     IHXRTSPClientProtocolResponse*	m_pResp;
     RTSPClientSessionManager*		m_pSessionManager;
     RTSPClientSession*  m_pSession;
From damonlan at real.com  Wed Mar 10 09:48:24 2004
From: damonlan at real.com (Damon Lanphear)
Date: Mon May 10 16:37:26 2004
Subject: [Protocol-dev] CR: Use server thread safe scheduler for RTCP when
	available
Message-ID: <1078940904.32592.1203.camel@poesis>

Suggested Reviewers:

Go Hori, and protocol dev list.

Problem description:

The server has two schedulers.  One locks a global mutex when executing
its callback methods, the other does not.  For control paths that do not
require protection from thread contention, it is preferable to use the
scheduler that does not lock the global mutex.  

Scheduling of RTCP RR transmission occurs using the scheduler that locks
the global mutex, creating mutex contention and compromising scalability
on multi processor hosts.

Solution:

When the "thread safe" scheduler is available from the server context,
use it from scheduling RTCP Receiver Reports.

Files affected:

protocol/transport/rtp/rtptran.cpp
protocol/transport/rtp/pub/rtptran.h


-------------- next part --------------
A non-text attachment was scrubbed...
Name: rtcp_isched.diff
Type: text/x-patch
Size: 2474 bytes
Desc: not available
Url : http://lists.helixcommunity.org/pipermail/protocol-dev/attachments/20040310/55692fbf/rtcp_isched.bin
From ghori at real.com  Wed Mar 10 11:10:06 2004
From: ghori at real.com (Go Hori)
Date: Mon May 10 16:37:26 2004
Subject: [Protocol-dev] CR: Use server thread safe scheduler for RTCP
	when available
In-Reply-To: <1078940904.32592.1203.camel@poesis>
Message-ID: 

Ok for head.  Please check this in to SERVER_10_1_STABLE as soon as it 
becomes available for checkins. 
Thanks,
Go

On 10 Mar 2004, Damon Lanphear wrote:

> Suggested Reviewers:
> 
> Go Hori, and protocol dev list.
> 
> Problem description:
> 
> The server has two schedulers.  One locks a global mutex when executing
> its callback methods, the other does not.  For control paths that do not
> require protection from thread contention, it is preferable to use the
> scheduler that does not lock the global mutex.  
> 
> Scheduling of RTCP RR transmission occurs using the scheduler that locks
> the global mutex, creating mutex contention and compromising scalability
> on multi processor hosts.
> 
> Solution:
> 
> When the "thread safe" scheduler is available from the server context,
> use it from scheduling RTCP Receiver Reports.
> 
> Files affected:
> 
> protocol/transport/rtp/rtptran.cpp
> protocol/transport/rtp/pub/rtptran.h
> 
> 
> 

-- 
Go Hori
ghori@real.com




From damonlan at real.com  Wed Mar 10 11:53:18 2004
From: damonlan at real.com (Damon Lanphear)
Date: Mon May 10 16:37:26 2004
Subject: [Protocol-dev] CR: Use server thread safe scheduler for RTCP
	when available
In-Reply-To: 
References: 
Message-ID: <1078948397.32592.1205.camel@poesis>

The following change has been committed to the mainline
(head/SERVER_CURRENT)

On Wed, 2004-03-10 at 11:10, Go Hori wrote:
> Ok for head.  Please check this in to SERVER_10_1_STABLE as soon as it 
> becomes available for checkins. 
> Thanks,
> Go
> 
> On 10 Mar 2004, Damon Lanphear wrote:
> 
> > Suggested Reviewers:
> > 
> > Go Hori, and protocol dev list.
> > 
> > Problem description:
> > 
> > The server has two schedulers.  One locks a global mutex when executing
> > its callback methods, the other does not.  For control paths that do not
> > require protection from thread contention, it is preferable to use the
> > scheduler that does not lock the global mutex.  
> > 
> > Scheduling of RTCP RR transmission occurs using the scheduler that locks
> > the global mutex, creating mutex contention and compromising scalability
> > on multi processor hosts.
> > 
> > Solution:
> > 
> > When the "thread safe" scheduler is available from the server context,
> > use it from scheduling RTCP Receiver Reports.
> > 
> > Files affected:
> > 
> > protocol/transport/rtp/rtptran.cpp
> > protocol/transport/rtp/pub/rtptran.h
> > 
> > 
> > 



From ghori at real.com  Fri Mar 19 15:07:04 2004
From: ghori at real.com (Go Hori)
Date: Mon May 10 16:37:26 2004
Subject: [Protocol-dev] Re: Using raw socket in Helix Netio
In-Reply-To: 
Message-ID: 

Avijit,

This is probably more suited in protocol mailing list.  I'll forward all
of your 3 msgs to the new list.

Thanks,
Go

On Tue, 9 Mar 2004, Avijit SenMazumder wrote:

> I am trying to implement a robust multicast join for Helix client. One 
> idea is to investigate the multicast support avaiable in the connected
> subnet, I would need to use ICMP and IGMP messages directly using raw socket.
> The main limitation is raw socket's requirement of administrative privilege. 
> Do we at all use raw socket in Helix for any purpose? Please let me if it 
> is not at all recommended. Otherwise I would like to pursue this idea and 
> hopefully it will help some group of user with adminsitrative privilege.
> 
> Thanks
> Avijit
> 
> 

-- 
Go Hori
ghori@real.com





From ghori at real.com  Fri Mar 19 15:07:31 2004
From: ghori at real.com (Go Hori)
Date: Mon May 10 16:37:26 2004
Subject: [Protocol-dev] Re: Socket read and blocking
In-Reply-To: 
Message-ID: 

forwarding

On Wed, 17 Mar 2004, Avijit SenMazumder wrote:

> I am trying to build a set of multicast diagnostic in NetWkSvc. I will 
> have a new interface implemented by HXNetworkServices to support these methods. 
> Most of the time these method calls will do some kind of socket i/o.
> 
> This being merely diagnostic I will rather not create a Network Source and
> have a light weight callback listner just to look into few received
> packets. Even  some of the time I will have to use raw socket for ICMP and
> IGMP packet exchange.
>   
> As for example a method may test multicast connectivity by joining a 
> Beacon Group. I will pass in IHXUDPResponse* to receive the response 
> packets. The part I did not understand whether I have to call Read method 
> explicitly. I suspect that it will block until the packet arrives. I would 
> like to use a different thread or some kind of callback to notify upon 
> packet arrival. Does it have to be ThreadedConn for this kind of use? Is 
> there a standard way to receive packets on network thread and then get
> notified on core thread? 
> 
> So far single threaded apps are concerned, do we use scheduler event for 
> network read notification and do I need to do any specific handling for 
> that?
> 
> I did not completely understand the flow of network packets in different 
> threading scenario, but it might be that core framework code ensures that 
> IHXUDPResponse::ReadDone gets called asynchronously no matter which 
> threading model we follow. Please help me to understand this.
> 
> 
> Avijit
> 
> 

-- 
Go Hori
ghori@real.com



From ghori at real.com  Fri Mar 19 15:07:46 2004
From: ghori at real.com (Go Hori)
Date: Mon May 10 16:37:26 2004
Subject: [Protocol-dev] Re: UDP Socket read and blocking
In-Reply-To: 
Message-ID: 

forwarding.

On Fri, 19 Mar 2004 avijit@cs.ucsb.edu wrote:

> I am writing to clarify further on my previous email. The following is from 
> helix sdk doc.
> 
> --------
> The component can call IHXUDPSocket::Read to read a specified number of bytes 
> from the UDP source. The UDP interface uses IHXUDPResponse::ReadDone to 
> return a status code, the local address, the local port, and a pointer to an 
> IHXBuffer interface containing the data.
> ---------
> 
> Does the call IHXUDPSocket::Read block until it receives a packet? Or does it 
> return immediately and subsequently we get notified on IHXUDPResponse?
> 
> If it blocks can I do the read on a different thread (like Network thread) 
> and get notified asynchronously on the IHXUDPResponse interface?
> 
> How would I achieve this kind of non blocking for a single threaded app? Is 
> it done using a scheduler? 
> 
> Please help me understand this. If there are already examples for this kind 
> of situations in helix codebase, please let me know.
> 
> Thanks.
> Avijit
> 
> 

-- 
Go Hori
ghori@real.com



From tmarshall at real.com  Fri Mar 19 15:09:24 2004
From: tmarshall at real.com (Tom Marshall)
Date: Mon May 10 16:37:26 2004
Subject: [Protocol-dev] [Fwd: [Fwd: [MMUSIC] draft-rfc2326-06 comments wrt
	live streaming]]
Message-ID: <20040319230924.GE17433@real.com>

[forwarding to protocol list]

This came in to the MMUSIC list.  We have recently done quite a bit of work
in these areas, especially for 3GPP.  Do we want to make any comments or
take any positions on these issues based on implementation experience?

----- Forwarded message from Geetha Srikantan  -----

Delivery-date: Fri, 19 Mar 2004 10:00:36 -0800
Date: Fri, 19 Mar 2004 09:57:15 -0800
From: Geetha Srikantan 
To: mmusic@ietf.org
Reply-to: Geetha.Srikantan@Sun.COM
User-Agent: Mozilla/5.0 (X11; U; SunOS sun4u; en-US; rv:1.4) Gecko/20031128
Subject: [MMUSIC] draft-rfc2326-06 comments wrt live streaming
X-Spam-Status: No, hits=0.000000 required=0.900000


This draft addresses the on-demand streaming case very well, however
I believe there are some issues in live streaming that need clarification.
The issues are in the use of the RTP-Info header, the Range header and
ssrc parameter in the Transport header. The points are related, so I 
will cover
them in a single message.


Section 11.3, page 44: 4th paragragh:
'...SHOULD also include the RTP-Info header..'

This requirement is fine for on-demand content, however it creates 
complications
for live media. There are many reasons why the RTP-Info cannot be populated
accurately by the server for live content:
(a) Arbitrary delays between live source and server - If there are
   several relay nodes between source and server, there maybe a skew
   in system clocks of each node that tries to correlate
   NPT <-> RTP timestamp (i.e. Range header <-> RTP-Info's rtptime).
(b) Lost packets between live source and server, imply that the server
   cannot accurately predict the next packet's sequence number.

For these reasons, the RTP-Info header is not very useful for live
streaming, and RTCP-based stream synchronization is preferred for live
streams. In any case RTP-Info is only useful for initial stream
synchronization. During a long-running live session the client has to
rely on RTCP for ongoing stream synchronization.
This is a motivation to drop RTP-Info entirely for live streams.

Section 11.4, page 45:
2nd last paragraph:

Range header for live streams:
There is a subtle difference in the semantics of the Range header for live
streams versus on-demand streams. For on-demand streams, the Range
header's start value refers to the presentation time, i.e. NPT of the 
presentation.
For live streams, the Range header's start value indicates either
(a) the duration of time between the start of the live session and the
   time when this Range header was created, or,
(b) the wall-clock time at the server responding to PLAY requests.

Also the main purpose of the Range header is to map the NPT to
the RTP timestamp. As discussed above this mapping is not terribly
accurate in several live streaming scenarios.

If the live streams are part of a multicast session then there would
be an indication of the time when the session is active in the SDP,
however, with clock skews etc, it is diffcult to accurately pinpoint
the instantaneous time in the session.

If the start time of the live session is not known, then 'npt=now-'
is the only reasonable value for the Range header in a PLAYresponse.

For this reason, it would be good to *not* require a Range header
other than 'Range: npt=now-' for live streams.

Perhaps this could also be the mechanism to signal to the client that
this is a live stream and that it needs to perform stream
synchronization strictly via RTCP sender reports.


Section 14.40, page 91:
ssrc:
The transport header in the server's response cannot populate the ssrc for
each stream, accurately in certain scenarios.
The source of the live stream may not be RTSP-aware, and the server has 
to rely
on RTP/RTCP to determine ssrc for each stream.
The server may have joined a multicast live session and receives, say, 
one of the streams.
It also receives SETUP request from a client and needs to respond to 
SETUP from a client,
before it sees the first packet of each stream.
Dropping the ssrc parameter from the Transport header in the SETUP 
response would
simplify this case.

thanks
geetha


_______________________________________________
mmusic mailing list
mmusic@ietf.org
https://www1.ietf.org/mailman/listinfo/mmusic


----- End forwarded message -----

-- 
Real Users never know what they want, but they always know when your program
doesn't deliver it.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
Url : http://lists.helixcommunity.org/pipermail/protocol-dev/attachments/20040319/05222bf6/attachment.bin
From tmarshall at real.com  Fri Mar 19 15:23:50 2004
From: tmarshall at real.com (Tom Marshall)
Date: Mon May 10 16:37:26 2004
Subject: [Protocol-dev] Re: Using raw socket in Helix Netio
In-Reply-To: 
References: 
	
Message-ID: <20040319232350.GF17433@real.com>

> > I am trying to implement a robust multicast join for Helix client. One 
> > idea is to investigate the multicast support avaiable in the connected
> > subnet, I would need to use ICMP and IGMP messages directly using raw socket.
> > The main limitation is raw socket's requirement of administrative privilege. 
> > Do we at all use raw socket in Helix for any purpose? Please let me if it 
> > is not at all recommended. Otherwise I would like to pursue this idea and 
> > hopefully it will help some group of user with adminsitrative privilege.

I don't believe SOCK_RAW is currently used in Helix.  I grepped the code and
there appears to be no reference to it anywhere except in a compatibility
header for the Macintosh.

We are in the process of redesigning the network services layer, mainly to
support IPv6.  Expect to see a document either tonight or Monday on the
proposed interfaces on the common-dev list.  Preliminary implementation
should be done within a week, or perhaps two at the longest.  I will attempt
to ensure that raw sockets are available in the new API.

Please note that the Helix products do not require administrative privileges
to run (including the server, if configured on nondefault port ranges). 

-- 
Logic is a systematic method of coming to the wrong conclusion with
confidence.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
Url : http://lists.helixcommunity.org/pipermail/protocol-dev/attachments/20040319/a0a6e773/attachment.bin
From damonlan at real.com  Fri Mar 19 15:17:50 2004
From: damonlan at real.com (Damon Lanphear)
Date: Mon May 10 16:37:26 2004
Subject: [Protocol-dev] Re: UDP Socket read and blocking
In-Reply-To: 
References: 
Message-ID: <1079738270.1415.110.camel@poesis>

In the server IHXUDPSocket::Read() will not block.  The user of
IHXUDPSocket needs only to call ::Read() once, and subsequently
IHXUDPResponse::ReadDone() will get called as datagrams become
available.

This semantic is achieved by placing the socket fd to be read in the
fd_set for the select()/poll() loop, and associating a callback with the
fd for when data becomes available on that socket.

On Fri, 2004-03-19 at 15:07, Go Hori wrote:
> forwarding.
> 
> On Fri, 19 Mar 2004 avijit@cs.ucsb.edu wrote:
> 
> > I am writing to clarify further on my previous email. The following is from 
> > helix sdk doc.
> > 
> > --------
> > The component can call IHXUDPSocket::Read to read a specified number of bytes 
> > from the UDP source. The UDP interface uses IHXUDPResponse::ReadDone to 
> > return a status code, the local address, the local port, and a pointer to an 
> > IHXBuffer interface containing the data.
> > ---------
> > 
> > Does the call IHXUDPSocket::Read block until it receives a packet? Or does it 
> > return immediately and subsequently we get notified on IHXUDPResponse?
> > 
> > If it blocks can I do the read on a different thread (like Network thread) 
> > and get notified asynchronously on the IHXUDPResponse interface?
> > 
> > How would I achieve this kind of non blocking for a single threaded app? Is 
> > it done using a scheduler? 
> > 
> > Please help me understand this. If there are already examples for this kind 
> > of situations in helix codebase, please let me know.
> > 
> > Thanks.
> > Avijit
> > 
> > 



From tmarshall at real.com  Fri Mar 19 15:45:04 2004
From: tmarshall at real.com (Tom Marshall)
Date: Mon May 10 16:37:26 2004
Subject: [Protocol-dev] Re: Socket read and blocking
In-Reply-To: 
References: 
	
Message-ID: <20040319234504.GG17433@real.com>

> > As for example a method may test multicast connectivity by joining a 
> > Beacon Group. I will pass in IHXUDPResponse* to receive the response 
> > packets. The part I did not understand whether I have to call Read method 
> > explicitly. I suspect that it will block until the packet arrives.

The Read() method simply tells the network layer that you are interested in
receiving a packet.  You will get a ReadDone() notification when a packet is
available.  Currently this may be either synchronously or asynchronously,
but we will be making it always async at some point to improve efficiency.

I have heard rumor that the UDP socket implementation is blocking, but I
cannot confirm that.  Note this does not necessarily mean that Read()
blocks.  I don't think that should ever happen.  But Write() can sometimes
do strange things under stress.

> > I would like to use a different thread or some kind of callback to
> > notify upon packet arrival. Does it have to be ThreadedConn for this
> > kind of use? Is there a standard way to receive packets on network
> > thread and then get notified on core thread?

If you are using the provided interfaces (eg. IHXUDPSocket), the ReadDone()
method is your notification.  If you are using your own implementation, you
will need to implement some sort of notification scheme on your own.  I
would strongly recommend using the new socket API, as it will probably be
available before you could implement and test such a thing.

-- 
Remember, God could only create the world in 6 days because he didn't
have an established user base.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
Url : http://lists.helixcommunity.org/pipermail/protocol-dev/attachments/20040319/6aa45572/attachment.bin
From tmarshall at real.com  Mon Mar 22 11:50:58 2004
From: tmarshall at real.com (Tom Marshall)
Date: Mon May 10 16:37:26 2004
Subject: [Protocol-dev] [Fwd: RFC: New socket API]
Message-ID: <20040322195058.GG23188@real.com>

Skipped content of type multipart/mixed-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
Url : http://lists.helixcommunity.org/pipermail/protocol-dev/attachments/20040322/551b0d02/attachment.bin
From avijit at cs.ucsb.edu  Tue Mar 23 09:39:23 2004
From: avijit at cs.ucsb.edu (avijit@cs.ucsb.edu)
Date: Mon May 10 16:37:26 2004
Subject: [Protocol-dev] [Fwd: RFC: New socket API]
In-Reply-To: <20040322195058.GG23188@real.com>
Message-ID: 

Tom,

I have read the RFC for new socket api. I have few comments, and most of 
them are primarily related to multicast.

1. I am planing to add Source Specific Multicast (SSM) for helix. Which 
will require 4 new methods on mulitcast interface.
  SubscribeSource( IHXSocAddr* sourceIp, IHXSocAddr* groupIp );
  UnsubscribeSource( IHXSocAddr* sourceIp, IHXSocAddr* groupIp );
  // Not sure whether following two are required, but for compliance
  BlockSource( IHXSocAddr* sourceIp, IHXSocAddr* groupIp );
  UnblockSource( IHXSocAddr* sourceIp, IHXSocAddr* groupIp );

2. I have noticed unlike the current NetSvc, the new interface does not  
support local interface as param for JoinMulticast/LeaveMulticast. May be its 
redundant in first place, but thought I should point it out, and thats why I 
did not mention it as part of SSM apis.

3. I don't mind moving IHXMulitcastSocket methods to IHXSocket, its 
basically a udp socket after all.

4. I would like to add a Multicast specific diagnostic interface though. 
It could be IHXMulticastDiagnostic or could be part of IHXSocketEx. It will 
support method like.
    // Join a multicast beacon group and listen for packet received,
    // if we here from few sources we assume connectivty. There could
    // be a different class which will interpret response from different
    // beacon source.
    ListenMulticastBeacon( IHXSocketResponse* pResponse )

    // Is IGMPV3/SSM supported on this host.
    bool IsSSMSupported()

    // The following will require raw socket support for ICMP
    // and IGMP.
    PingFirstHopMulticastRouter( IHXSocketResponse* pResponse )
    
    // Send IGMP Join request
    SendIGMPJoin( IHXSocAddr* pAddr );
    SendIGMPLeave( IHXSocAddr* pAddr );

    // Listen for IGMP query
    ReceiveIGMPQuery( IHXSocAddr* pAddr ); 
    
5. On different context, are we going to implement the new UDP read semantic, 
using a single listner thread, which will demultiplex all the responses to 
the specifc event listner? For a single threaded app is it going to be driven 
by a scheduler?

6. Also we have to extend HXSockOpt enum for SSM.
   HX_IP_BLOCK_SOURCE
   HX_IP_UNBLOCK_SOURCE
   HX_IP_ADD_SOURCE_MEMBERSHIP
   HX_IP_DROP_SOURCE_MEMBERSHIP


As I am planing to implement SSM, I should mention that all platforms do not 
have SSM support yet, but WinXP does. If we decide to do raw socket, I will 
be able to help too.

Also I think there are few implications of IP 6 on multicast, I will look 
into it.

With regards.
Avijit 


From tmarshall at real.com  Tue Mar 23 10:22:03 2004
From: tmarshall at real.com (Tom Marshall)
Date: Mon May 10 16:37:26 2004
Subject: [Protocol-dev] [Fwd: RFC: New socket API]
In-Reply-To: 
References: <20040322195058.GG23188@real.com>
	
Message-ID: <20040323182202.GB27441@real.com>

> I have read the RFC for new socket api. I have few comments, and most of 
> them are primarily related to multicast.

Thank you for your comments.  I am not very familiar with multicast, so I
will be relying on others to determine the appropriate method(s) for the
multicast interface.  If anyone else has suggestions wrt. multicast, please
do speak out.

One of the high priority items for the new API is to provide a generic and
extensible framework that follows the "standard" BSD and BSD-like semantics
closely.  Will you be using IPv4, IPv6, or both for your application?  Are
you familiar with multicast for IPv6 and how it compares to IPv4?  I'm all
ears at this point.  :-)

> 5. On different context, are we going to implement the new UDP read semantic, 
> using a single listner thread, which will demultiplex all the responses to 
> the specifc event listner? For a single threaded app is it going to be driven 
> by a scheduler?

The UDP read semantics will be very close to the existing semantics in that
you will select the read event (similar to calling Read() now) and you will
get a notification when packet(s) are pending (similar to ReadDone() now). 
The underlying implementation is, and will continue to be, a select or poll
loop (depending on the platform).

I am a bit less familiar with the server's current process model as it
relates to listening sockets.  AFAIK, you can only create a socket in a
single process after the server has initialized.  The listening sockets
created in the core process for RTSP, HTTP, etc. use a master/slave type
system.  The core process holds the listening socket and sends each client
to the appropriate streamer depending on load.

There will be some work on the process model within the next couple of
months.  We will likely be looking at the so-called "thundering herd" model
for listening sockets in the streamers, where each streamer has the same
listening socket and the first one to accept the client gets it.  I don't
know if this will be possible with UDP sockets.

-- 
I put instant coffee in a microwave and almost went back in time.
        -- Steven Wright
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
Url : http://lists.helixcommunity.org/pipermail/protocol-dev/attachments/20040323/bc5770f7/attachment.bin
From avijit at cs.ucsb.edu  Wed Mar 24 08:27:47 2004
From: avijit at cs.ucsb.edu (avijit@cs.ucsb.edu)
Date: Mon May 10 16:37:26 2004
Subject: [Protocol-dev] [Fwd: RFC: New socket API]
In-Reply-To: <20040323182202.GB27441@real.com>
Message-ID: 

The SSM is going to be the primary way to do multicast in IP V6 instead of 
ASM supported in IP V4. So in a way implementing SSM will help IP V6 
migration. The method signature I suggested for SSM is BSD like, they are all 
implemented calling setsocketopt() with proper structure and enum value.

However to make the method signature to look exactly like BSD, it may be 
useful to add local interface address.

  SubscribeSource( IHXSocAddr* localIf, IHXSocAddr* sourceIp, IHXSocAddr* 
groupIp );
  UnsubscribeSource( IHXSocAddr* localIf, IHXSocAddr* sourceIp, IHXSocAddr* 
groupIp );
  // Not sure whether following two are required, but for compliance
  BlockSource( IHXSocAddr* localIf, IHXSocAddr* sourceIp, IHXSocAddr* 
groupIp );
  UnblockSource( IHXSocAddr* localIf, IHXSocAddr* sourceIp, IHXSocAddr* 
groupIp );

I recommend that you keep it that way for JoinMulticast and LeaveMulticast 
method too. The current NetSvc follows this signature.

These methods could be used for both IP V4 and V6, depending on the passed in 
IHXSocAddr. I will add on if I find more details.

Are we supporting IP V6's index to name mapping? Something could be useful 
for local interface determination.

> One of the high priority items for the new API is to provide a generic and
> extensible framework that follows the "standard" BSD and BSD-like semantics
> closely.  Will you be using IPv4, IPv6, or both for your application?  Are
> you familiar with multicast for IPv6 and how it compares to IPv4?  I'm all
> ears at this point.  :-)
>

My plan is to build the NetSvc infrastructure at this point to support any 
SSM based multicast streaming. I am not building for any specific 
application. However I would like to tie this up with Helix player's 
NetSource.

Thanks.
Avijit



From jsf26 at drexel.edu  Wed Mar 24 09:17:55 2004
From: jsf26 at drexel.edu (J Falcone)
Date: Mon May 10 16:37:26 2004
Subject: [Protocol-dev] ASM (Adaptive Stream Management)
Message-ID: <30856614-7DB7-11D8-AD79-0003939CC860@drexel.edu>

I am new to the development of helix, I am trying to implement a volume 
dependent algorithm for low-volume, or, low-bandwidth clients, and 
high-volume, or, high-bandwidth clients to interact with the already 
existent ASM.  My project is aimed to manipulate the current 
receiver-driven layered multicast (RLM), algorithm with a tunable 
algorithm, for the clients individual volume specifications.

While looking at the code, it seems that ASM, will help me achieve this.

I am looking for someone who is intimate with ASM who can help answer a 
few of my questions.

We have searched throughout the source code and found what appears to 
be a rule book of 4 rules if TESTING is defined, in the asmrulep.cpp 
file.  However, the documentation for ASM explained the rule book as 
defining rules for separate filetypes.

Any response would be appreciated!

Thanks for your time and help.


Josh






From tmarshall at real.com  Wed Mar 24 09:49:31 2004
From: tmarshall at real.com (Tom Marshall)
Date: Mon May 10 16:37:26 2004
Subject: [Protocol-dev] ASM (Adaptive Stream Management)
In-Reply-To: <30856614-7DB7-11D8-AD79-0003939CC860@drexel.edu>
References: <30856614-7DB7-11D8-AD79-0003939CC860@drexel.edu>
Message-ID: <20040324174931.GA30691@real.com>

On Wed, Mar 24, 2004 at 12:17:55PM -0500, J Falcone wrote:
> I am new to the development of helix, I am trying to implement a volume 
> dependent algorithm for low-volume, or, low-bandwidth clients, and 
> high-volume, or, high-bandwidth clients to interact with the already 
> existent ASM.  My project is aimed to manipulate the current 
> receiver-driven layered multicast (RLM), algorithm with a tunable 
> algorithm, for the clients individual volume specifications.
> 
> While looking at the code, it seems that ASM, will help me achieve this.
> 
> I am looking for someone who is intimate with ASM who can help answer a 
> few of my questions.
> 
> We have searched throughout the source code and found what appears to 
> be a rule book of 4 rules if TESTING is defined, in the asmrulep.cpp 
> file.  However, the documentation for ASM explained the rule book as 
> defining rules for separate filetypes.

The TESTING macro is for unit testing.  It's supposed to be used to verify
that the code is functional independent of the rest of the codebase.

The ASM rulebook provides a way for the fileformat to tell the client core
which ASM rules should be subscribed to.  An ASM rule can be thought of as a
sub-stream.  These sub-streams are usually implemented based on bandwidth,
but they could potentially be used for other things.

As an example, suppose you wish to provide an video file with multiple
bitrates.  It should have the best quality when viewed via a broadband
connection, but modem users should also be able to view it in a reduced
quality mode.  You might want to provide, say, 300kbps for the high quality
video and 32kbps for the low quality video.  The file has only one stream so
the SDP only has one "m=" line.  But this stream has two sub-streams.  The
ASM rulebook might look like this:

  #($Bandwidth < 330000), AverageBandwidth=32000;
  #($Bandwidth >= 330000), AverageBandwidth=300000;

The client will select the first rule (which presumedly holds the low
bitrate video) when its available bandwidth is less than 330kbps (I left 10%
for safety) and the second rule when the available bandwidth is 330kbps or
higher.

Note that ASM is a Helix concept.  It is not a standard.  The ASM
subscriptions are implemented in RTSP using SET_PARAMETER requests from
client to server.  The ASM rule number associated with data packets is
provided in a Helix RTP extension.

The rules follow an expression syntax.  Each rule starts with a # symbol and
an expression to be evaluated.  Several variables are available for use in
this expression, the most common being $Bandwidth.  This is followed by a
comma separated list of variables to set.  Again, several variables are
defined.  A semicolon terminates the rule.

I don't have a comprehensive list of variables used in ASM.  You should be
able to find most or all of them in the source.

Hope that helps.

-- 
One has to look out for engineers -- they begin with sewing machines
and end up with the atomic bomb.
        -- Marcel Pagnol
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
Url : http://lists.helixcommunity.org/pipermail/protocol-dev/attachments/20040324/08e44d1f/attachment.bin
From jsf26 at drexel.edu  Wed Mar 24 11:47:33 2004
From: jsf26 at drexel.edu (J Falcone)
Date: Mon May 10 16:37:26 2004
Subject: [Protocol-dev] ASM (Adaptive Stream Management)
In-Reply-To: <20040324174931.GA30691@real.com>
References: <30856614-7DB7-11D8-AD79-0003939CC860@drexel.edu>
	<20040324174931.GA30691@real.com>
Message-ID: <17A63166-7DCC-11D8-AD79-0003939CC860@drexel.edu>



We think we understand the concept of ASM and how it uses virtual 
streams or sub-streams.  But we are having a problem finding where the 
separate rule books for the filetypes are located.  e.g. is there a 
rule book somewhere defined in the filetype/mp3 or filetype/rm 
directory?  Or are the only rules used by Helix held in the 
engine/core/asmrulep.cpp?  Also are the rules held on the client side, 
server side, or both.



On Mar 24, 2004, at 12:49 PM, Tom Marshall wrote:

> On Wed, Mar 24, 2004 at 12:17:55PM -0500, J Falcone wrote:
>> I am new to the development of helix, I am trying to implement a 
>> volume
>> dependent algorithm for low-volume, or, low-bandwidth clients, and
>> high-volume, or, high-bandwidth clients to interact with the already
>> existent ASM.  My project is aimed to manipulate the current
>> receiver-driven layered multicast (RLM), algorithm with a tunable
>> algorithm, for the clients individual volume specifications.
>>
>> While looking at the code, it seems that ASM, will help me achieve 
>> this.
>>
>> I am looking for someone who is intimate with ASM who can help answer 
>> a
>> few of my questions.
>>
>> We have searched throughout the source code and found what appears to
>> be a rule book of 4 rules if TESTING is defined, in the asmrulep.cpp
>> file.  However, the documentation for ASM explained the rule book as
>> defining rules for separate filetypes.
>
> The TESTING macro is for unit testing.  It's supposed to be used to 
> verify
> that the code is functional independent of the rest of the codebase.
>
> The ASM rulebook provides a way for the fileformat to tell the client 
> core
> which ASM rules should be subscribed to.  An ASM rule can be thought 
> of as a
> sub-stream.  These sub-streams are usually implemented based on 
> bandwidth,
> but they could potentially be used for other things.
>
> As an example, suppose you wish to provide an video file with multiple
> bitrates.  It should have the best quality when viewed via a broadband
> connection, but modem users should also be able to view it in a reduced
> quality mode.  You might want to provide, say, 300kbps for the high 
> quality
> video and 32kbps for the low quality video.  The file has only one 
> stream so
> the SDP only has one "m=" line.  But this stream has two sub-streams.  
> The
> ASM rulebook might look like this:
>
>   #($Bandwidth < 330000), AverageBandwidth=32000;
>   #($Bandwidth >= 330000), AverageBandwidth=300000;
>
> The client will select the first rule (which presumedly holds the low
> bitrate video) when its available bandwidth is less than 330kbps (I 
> left 10%
> for safety) and the second rule when the available bandwidth is 
> 330kbps or
> higher.
>
> Note that ASM is a Helix concept.  It is not a standard.  The ASM
> subscriptions are implemented in RTSP using SET_PARAMETER requests from
> client to server.  The ASM rule number associated with data packets is
> provided in a Helix RTP extension.
>
> The rules follow an expression syntax.  Each rule starts with a # 
> symbol and
> an expression to be evaluated.  Several variables are available for 
> use in
> this expression, the most common being $Bandwidth.  This is followed 
> by a
> comma separated list of variables to set.  Again, several variables are
> defined.  A semicolon terminates the rule.
>
> I don't have a comprehensive list of variables used in ASM.  You 
> should be
> able to find most or all of them in the source.
>
> Hope that helps.
>
> -- 
> One has to look out for engineers -- they begin with sewing machines
> and end up with the atomic bomb.
>         -- Marcel Pagnol



From tmarshall at real.com  Wed Mar 24 12:07:19 2004
From: tmarshall at real.com (Tom Marshall)
Date: Mon May 10 16:37:26 2004
Subject: [Protocol-dev] ASM (Adaptive Stream Management)
In-Reply-To: <17A63166-7DCC-11D8-AD79-0003939CC860@drexel.edu>
References: <30856614-7DB7-11D8-AD79-0003939CC860@drexel.edu>
	<20040324174931.GA30691@real.com>
	<17A63166-7DCC-11D8-AD79-0003939CC860@drexel.edu>
Message-ID: <20040324200719.GF30691@real.com>

> We think we understand the concept of ASM and how it uses virtual 
> streams or sub-streams.  But we are having a problem finding where the 
> separate rule books for the filetypes are located.  e.g. is there a 
> rule book somewhere defined in the filetype/mp3 or filetype/rm 
> directory?  Or are the only rules used by Helix held in the 
> engine/core/asmrulep.cpp?  Also are the rules held on the client side, 
> server side, or both.

The rule book is normally a property of the stream header (though we do have
a rule book in the file header for some datatypes).  The file format fills
in this property in its GetStreamHeader method.  Some file formats hold the
rulebook in the file itself (.rm).  For others, the file format creates an
appropriate rulebook based on the file's properties.

Example:

  DESCRIBE rtsp://localhost/realmp3.mp3 RTSP/1.0

  RTSP/1.0 200 OK
  [...]
  Content-type: application/sdp
  Content-length: 689

  v=0
  [...]
  m=audio 0 RTP/AVP 101
  [...]
  a=ASMRuleBook:string;"AverageBandwidth=128000, AverageBandwidthStd=0, Priority=9;"

Obviously, this rulebook is not stored in the .mp3 file itself.  The mp3
file format plugin generated it dynamically.

-- 
While most peoples' opinions change, the conviction of their correctness
never does.
        -- Unknown
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
Url : http://lists.helixcommunity.org/pipermail/protocol-dev/attachments/20040324/f36ae11d/attachment.bin
From tmarshall at real.com  Wed Mar 24 13:12:21 2004
From: tmarshall at real.com (Tom Marshall)
Date: Mon May 10 16:37:26 2004
Subject: [Protocol-dev] ASM (Adaptive Stream Management)
In-Reply-To: <90CA2487-7DD3-11D8-AD79-0003939CC860@drexel.edu>
References: <30856614-7DB7-11D8-AD79-0003939CC860@drexel.edu>
	<20040324174931.GA30691@real.com>
	<17A63166-7DCC-11D8-AD79-0003939CC860@drexel.edu>
	<20040324200719.GF30691@real.com>
	<90CA2487-7DD3-11D8-AD79-0003939CC860@drexel.edu>
Message-ID: <20040324211221.GA31360@real.com>

On Wed, Mar 24, 2004 at 03:41:02PM -0500, J Falcone wrote:
> How can we implement a rule book based on clients bandwidth criteria.  
> I am unclear of how the DESCRIBE command is working, (implementation of 
> it).

Your rulebook should cover all bandwidth criteria.  In other words, the ASM
rulebook is not created based on available bandwidth.  It is a fixed set of
rules.  The client will subscribe to a subset of those rules depending on
the playback conditions.  The client may, and does, reevaluate the rules
periodically and switches subscriptions dynamically during playback.

> Any chance you can show a specific example for writing a rule book for 
> a .mp3 file on the server that should subscribe/unsubscribe to rules, 
> based on the bandwidth of the client.  (Where does the DESCRIBE, play a 
> role, what else is there to do to implement the rule book).

There should be examples both in the SDK and in the Helix fileformat code. 
In the case of .mp3, there is only one available bitrate.  This is why the
rulebook consists of only one rule with no evaluation expression.  There is
no way for the server to thin the delivery bandwidth when the client has
less than 128kbps available.

-- 
A great many people think they are thinking when they are merely
rearranging their prejudices.
        -- William James
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
Url : http://lists.helixcommunity.org/pipermail/protocol-dev/attachments/20040324/f0593e91/attachment.bin
From ghori at real.com  Wed Mar 24 13:57:19 2004
From: ghori at real.com (Go Hori)
Date: Mon May 10 16:37:26 2004
Subject: [Protocol-dev] ASM (Adaptive Stream Management)
In-Reply-To: <30856614-7DB7-11D8-AD79-0003939CC860@drexel.edu>
Message-ID: 

Hi,

Before you go further into ASM, can you give us a little bit more about 
what you are trying to accomplish so we can all get on the same page?  

As I understand it, you need to consider about encoding scheme as well to
support RLM.  If you can outline your current thinking, we maybe able to 
help come up with a solution that may or may not involve ASM.

Thanks,
Go



On Wed, 24 Mar 2004, J Falcone wrote:

> I am new to the development of helix, I am trying to implement a volume 
> dependent algorithm for low-volume, or, low-bandwidth clients, and 
> high-volume, or, high-bandwidth clients to interact with the already 
> existent ASM.  My project is aimed to manipulate the current 
> receiver-driven layered multicast (RLM), algorithm with a tunable 
> algorithm, for the clients individual volume specifications.
> 
> While looking at the code, it seems that ASM, will help me achieve this.
> 
> I am looking for someone who is intimate with ASM who can help answer a 
> few of my questions.
> 
> We have searched throughout the source code and found what appears to 
> be a rule book of 4 rules if TESTING is defined, in the asmrulep.cpp 
> file.  However, the documentation for ASM explained the rule book as 
> defining rules for separate filetypes.
> 
> Any response would be appreciated!
> 
> Thanks for your time and help.
> 
> 
> Josh
> 
> 
> 
> 
> 
> _______________________________________________
> Protocol-dev mailing list
> Protocol-dev@lists.helixcommunity.org
> http://lists.helixcommunity.org/mailman/listinfo/protocol-dev
> 

-- 
Go Hori
ghori@real.com



From jsf26 at drexel.edu  Thu Mar 25 05:39:16 2004
From: jsf26 at drexel.edu (J Falcone)
Date: Mon May 10 16:37:26 2004
Subject: [Protocol-dev] ASM (Adaptive Stream Management)
In-Reply-To: 
References: 
Message-ID: 


Go,

Essentially, we would like to add a volume dependant subscription 
algorithm to Helix. ?Whereby, either filetype or a predetermined stream 
volume (bit rate) sets the threshold between small and large streams. 
?We want to have the small volume stream (say audio) to more 
aggressively pursue higher rates than large streams (video). ?Small 
volume streams would start off subscribing to rule 0 + rule 1(maximum 
subscription level), at the onset of congestion it would drop to the 
base rule, rule 0. ?Then we would wait an exponential amount of time to 
perform a join experiment adding rule 1 back.? Large volume streams 
would start out subscribing to rule 0(minimum subscription level), and 
add rule 1 after a random period of time in a similar fashion. ?Note 
that the efficiency of this algorithm lies in the selection of the 
threshold rate.? This is a simple explanation of how our algorithm 
would work with 2 rules, and this is what we want to implement in Helix 
somehow.? For testing, we plan to only implement this for mp3 and rm 
files.? After reading about ASM in the Helix SDK we felt confident that 
this would be our best route, but if you can think of an better method 
we would be very grateful for your input either way.?

  ?

Thanks,

?

Josh
On Mar 24, 2004, at 4:57 PM, Go Hori wrote:

> Hi,
>
> Before you go further into ASM, can you give us a little bit more about
> what you are trying to accomplish so we can all get on the same page?
>
> As I understand it, you need to consider about encoding scheme as well 
> to
> support RLM.  If you can outline your current thinking, we maybe able 
> to
> help come up with a solution that may or may not involve ASM.
>
> Thanks,
> Go
>
>
>
> On Wed, 24 Mar 2004, J Falcone wrote:
>
>> I am new to the development of helix, I am trying to implement a 
>> volume
>> dependent algorithm for low-volume, or, low-bandwidth clients, and
>> high-volume, or, high-bandwidth clients to interact with the already
>> existent ASM.  My project is aimed to manipulate the current
>> receiver-driven layered multicast (RLM), algorithm with a tunable
>> algorithm, for the clients individual volume specifications.
>>
>> While looking at the code, it seems that ASM, will help me achieve 
>> this.
>>
>> I am looking for someone who is intimate with ASM who can help answer 
>> a
>> few of my questions.
>>
>> We have searched throughout the source code and found what appears to
>> be a rule book of 4 rules if TESTING is defined, in the asmrulep.cpp
>> file.  However, the documentation for ASM explained the rule book as
>> defining rules for separate filetypes.
>>
>> Any response would be appreciated!
>>
>> Thanks for your time and help.
>>
>>
>> Josh
>>
>>
>>
>>
>>
>> _______________________________________________
>> Protocol-dev mailing list
>> Protocol-dev@lists.helixcommunity.org
>> http://lists.helixcommunity.org/mailman/listinfo/protocol-dev
>>
>
> -- 
> Go Hori
> ghori@real.com
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: text/enriched
Size: 3661 bytes
Desc: not available
Url : http://lists.helixcommunity.org/pipermail/protocol-dev/attachments/20040325/807c22c3/attachment.bin
From willman023 at excite.com  Fri Mar 26 11:14:37 2004
From: willman023 at excite.com (willman023@excite.com)
Date: Mon May 10 16:37:26 2004
Subject: [Protocol-dev] MP3 ASM
Message-ID: <20040326191437.DDC273E1C@xprdmailfe6.nwk.excite.com>

 For the mp3 asm rulbook in the file format plugin is m_Info.ulBitRate the maximum BitRate for the file or the Current BitRate? Thanks Bryan Willman  

_______________________________________________
Join Excite! - http://www.excite.com
The most personalized portal on the Web!
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.helixcommunity.org/pipermail/protocol-dev/attachments/20040326/e417f9fc/attachment.htm
From ehyche at real.com  Fri Mar 26 11:49:12 2004
From: ehyche at real.com (Eric Hyche)
Date: Mon May 10 16:37:26 2004
Subject: [Protocol-dev] MP3 ASM
In-Reply-To: <20040326191437.DDC273E1C@xprdmailfe6.nwk.excite.com>
Message-ID: <5.1.0.14.2.20040326144609.00baa298@mailone.real.com>


[Moving to datatype-dev as this is a datatypes question...]

Bryan,

The mp3 file format looks at all the frames in the first
32k of the .mp3 file and computes the average bitrate of
all the frames it finds. m_Info.ulBitRate is this average
bitrate.

Eric

At 02:14 PM 3/26/2004 -0500, willman023@excite.com wrote:
>Content-Type: multipart/alternative;
>         boundary="EXCITEBOUNDARY_000__97663fd40ee0baeb2803f482ed97ccd3";
>Content-Transfer-Encoding: 7bit
>
>For the mp3 asm rulbook in the file format plugin is m_Info.ulBitRate the 
>maximum BitRate for the file or the Current BitRate?
>
>Thanks
>
>Bryan Willman
>
>
>
>
>
>
>----------
>Join Excite! - http://www.excite.com
>The most personalized portal on the Web!
>_______________________________________________
>Protocol-dev mailing list
>Protocol-dev@lists.helixcommunity.org
>http://lists.helixcommunity.org/mailman/listinfo/protocol-dev

======================================
M. Eric Hyche (ehyche@real.com)
Core Technologies
RealNetworks, Inc.



From acolwell at real.com  Mon Mar 29 13:38:28 2004
From: acolwell at real.com (Aaron Colwell)
Date: Mon May 10 16:37:26 2004
Subject: [Protocol-dev] CR-Client: Pipelined RTSP changes
Message-ID: <20040329213828.GA12753@real.com>



Overview: These changes allow every SETUP message after the first one to be
          pipelined with the Subscribe SET_PARAM and PLAY messages. The 
          original code would wait for all the SETUP response messages before
          issuing the Subscribe SET_PARAM and PLAY messages. These changes
          allow the SET_PARAM and PLAY to be sent before the SETUP responses
          arrive. This pipelining behavior is only turned on when the
          PipelineRTSP preference is set. If the preference is not set or
          if it doesn't exist the player defaults to the old behavior.

          Now that the SETUP and PLAY messages are pipelined, it is possible
          for data packets to arrive before the transport buffer is created.
          The transport buffer is created when the SETUP response arrives
          for a stream. A packet queue was added to handle the case where
          data packets arrive before the SETUP response does. This queue only
          holds packets during a very short interval and is immediately emptied
          and destroyed once the transport buffer has been created.

Files Modified:
common/util/pub/basepkt.h
protocol/rtsp/rtspclnt.cpp
protocol/rtsp/pub/rtspclnt.h
protocol/transport/common/system/rtsptran.cpp
protocol/transport/common/system/pub/rtsptran.h

Files Added: none

Image Size and Heap Use impact:

Platforms and Profiles affected: all

Distribution Libraries affected: rdtclntlib

Distribution library impact and planned action: 
A member variable was added to the transport base class. This changes
the layout of the RDT transport object so the distlib needs to be updated.

Platforms and Profiles Build Verified: win32 helix-client-all-defines

Platforms and Profiles Functionality verified: win32 helix-client-all-defines

Branch: HEAD

QA Instructions: none

Index: util/pub/basepkt.h
===================================================================
RCS file: /cvsroot/common/util/pub/basepkt.h,v
retrieving revision 1.5
diff -u -r1.5 basepkt.h
--- util/pub/basepkt.h	24 Sep 2003 18:45:39 -0000	1.5
+++ util/pub/basepkt.h	29 Mar 2004 20:42:45 -0000
@@ -111,6 +111,11 @@
 inline void
 BasePacket::SetPacket(IHXPacket* pPacket)
 {
+    if (m_pPacket)
+    {
+        m_pPacket->Release();
+    }
+
     m_pPacket = pPacket;
 
     if (m_pPacket)
@@ -255,6 +260,7 @@
     BOOL			IsDroppedPacket();
     BOOL			IsSanitizePacket();
     Timeval			GetStartTime();
+    void                        SetStartTime(Timeval startTime);
 
     // serialization method
     static void	Pack	(IHXClientPacket* pPacket, char* pData, UINT32& ulSize);
@@ -327,6 +333,12 @@
 ClientPacket::GetStartTime()
 {
     return m_StartTime;
+}
+
+inline void
+ClientPacket::SetStartTime(Timeval startTime)
+{
+    m_StartTime = startTime;
 }
 
 // serialization method

Index: rtsp/rtspclnt.cpp
===================================================================
RCS file: /cvsroot/protocol/rtsp/rtspclnt.cpp,v
retrieving revision 1.72
diff -u -r1.72 rtspclnt.cpp
--- rtsp/rtspclnt.cpp	18 Mar 2004 01:53:45 -0000	1.72
+++ rtsp/rtspclnt.cpp	29 Mar 2004 20:41:09 -0000
@@ -3183,8 +3183,6 @@
     RTSPTransport* pTrans =
 	(RTSPTransport*)(*m_pTransportStreamMap)[uStreamNumber];
 
-    HX_ASSERT(pTrans);
-
     rc = pTrans ?
 	    pTrans->GetCurrentBuffering(uStreamNumber,
 					llLowestTimestamp,
@@ -4905,13 +4903,26 @@
     status = handleSetupResponseExt(pStreamInfo, pMsg, pSetupMsg);
 
     UINT16 nStreamCount = (UINT16)m_streamInfoList.GetCount();
+
+    BOOL bSetupsDone = FALSE;
+
     if(m_setupResponseCount == 1 && (nStreamCount > 1))
     {
+        // Signal that we are done if we 
+        // are pipelining RTSP messages
+        bSetupsDone = PipelineRTSP();
+
 	// first time, send the rest...
 	sendRemainingSetupRequests();
     }
+    else if (!PipelineRTSP())
+    {
+        // We only update bSetupsDone this way
+        // if we are not pipelining RTSP messages.
+        bSetupsDone = (m_setupResponseCount == nStreamCount);
+    }
 
-    if(m_setupResponseCount == nStreamCount)
+    if(bSetupsDone)
     {
 	// all done!
 
@@ -7620,6 +7631,15 @@
     }
 
     return rc;
+}
+
+BOOL RTSPClientProtocol::PipelineRTSP()
+{
+    BOOL bRet = FALSE;
+
+    ReadPrefBOOL(m_pPreferences, "PipelineRTSP", bRet);
+
+    return bRet;
 }
 
 RTSPClientProtocol::UDPResponseHelper::UDPResponseHelper(RTSPClientProtocol* pParent, UINT16 nPort)
Index: rtsp/pub/rtspclnt.h
===================================================================
RCS file: /cvsroot/protocol/rtsp/pub/rtspclnt.h,v
retrieving revision 1.26
diff -u -r1.26 rtspclnt.h
--- rtsp/pub/rtspclnt.h	8 Mar 2004 19:49:24 -0000	1.26
+++ rtsp/pub/rtspclnt.h	29 Mar 2004 20:41:09 -0000
@@ -932,6 +932,8 @@
                                     const char* pContent,
                                     const char* pMimeType, UINT32 seqNo);
 
+    BOOL PipelineRTSP();
+
             HX_RESULT   ReportSuccessfulTransport(void);
 
     LONG32                              m_lRefCount;
Index: transport/common/system/rtsptran.cpp
===================================================================
RCS file: /cvsroot/protocol/transport/common/system/rtsptran.cpp,v
retrieving revision 1.24
diff -u -r1.24 rtsptran.cpp
--- transport/common/system/rtsptran.cpp	24 Feb 2004 19:53:31 -0000	1.24
+++ transport/common/system/rtsptran.cpp	29 Mar 2004 20:41:09 -0000
@@ -332,6 +332,7 @@
     m_pPlayerState(NULL),
     m_pPacketFilter(NULL),
     m_pClientPacketList(NULL),
+    m_pNoTransBufPktList(NULL),
     m_bPrefetch(FALSE),
     m_bFastStart(FALSE),
     m_ulPlayRangeFrom(RTSP_PLAY_RANGE_BLANK),
@@ -367,7 +368,8 @@
     HX_RELEASE(m_pPacketFilter);
     HX_RELEASE(m_pContext);
 
-    HX_DELETE(m_pClientPacketList);
+    destroyPktList(m_pClientPacketList);
+    destroyPktList(m_pNoTransBufPktList);
 }
 
 void
@@ -733,6 +735,7 @@
     uStreamNumber = clientPacket->GetStreamNumber();
     RTSPTransportBuffer* pTransportBuffer = getTransportBuffer(uStreamNumber);
     pTransportBuffer->Add(clientPacket);
+    HX_RELEASE(clientPacket);
 }
 
 void RTSPTransport::GetContext(IUnknown*& pContext)   
@@ -855,78 +858,134 @@
                            UINT16 uReliableSeqNo,
                            BOOL isReliable)
 {
+    m_bIsReceivedData = TRUE;
+
+    ULONG32 ulPktSize = 0;
+    IHXPacket* pPkt = NULL;
+
+    if (pPacket && !pPacket->IsLost())
+    {
+        IHXBuffer* pBuffer = pPacket->GetBuffer();
+        
+        if (pBuffer)
+        {
+            ulPktSize = pBuffer->GetSize();
+        }
+
+        HX_RELEASE(pBuffer);
+        
+        pPkt = pPacket;
+    }
+
     RTSPTransportBuffer* pTransportBuffer = getTransportBuffer(uStreamNumber);
+    Timeval startTime;
 
-    if (!pTransportBuffer)
+    if (pTransportBuffer)
     {
-	return HXR_FAIL;
+        startTime = pTransportBuffer->GetTime();
     }
 
-    ClientPacket* clientPacket = 0;
+    HX_RESULT res = HXR_OUTOFMEMORY;
+    ClientPacket* pClientPacket = new ClientPacket(uSeqNo, 
+                                                   uReliableSeqNo,
+                                                   pPacket->GetTime(), 
+                                                   ulPktSize, 
+                                                   isReliable,
+                                                   pPkt, 
+                                                   startTime, 
+                                                   FALSE);
     
-    m_bIsReceivedData = TRUE;
-
-    if (pPacket->IsLost())
+    if (pClientPacket)
     {
-        clientPacket = new ClientPacket(uSeqNo, uReliableSeqNo,
-		                        pPacket->GetTime(), 0, isReliable,
-		                        0, pTransportBuffer->GetTime(), FALSE);
-        if( !clientPacket )
+        pClientPacket->AddRef();
+
+        if (pTransportBuffer)
         {
-            return HXR_OUTOFMEMORY;
+            if (m_pNoTransBufPktList)
+            {
+                // We handle any packets received
+                // when we didn't have a transport buffer
+                // first.
+                res = handleNoTransBufList(pTransportBuffer);
+            }
+            else
+            {
+                res = HXR_OK;
+            }
+            
+            if (HXR_OK == res)
+            {
+                // Now store the packet for this call
+                res = storeClientPacket(pTransportBuffer, pClientPacket);
+            }
         }
+        else
+        {
+            // We don't have a transport buffer yet.
+            // Queue the packet until we have one.
+            if (!m_pNoTransBufPktList)
+            {
+                m_pNoTransBufPktList = new CHXSimpleList;
+            }
 
-	clientPacket->AddRef();
+            if (m_pNoTransBufPktList &&
+                m_pNoTransBufPktList->AddTail(pClientPacket))
+            {
+                // We successfully queued the packet
+                pClientPacket->AddRef();
+                res = HXR_OK;
+            }
+        }
 
-	return pTransportBuffer->Add(clientPacket);
+        HX_RELEASE(pClientPacket);
     }
-    
-    IHXBuffer* pBuffer = pPacket->GetBuffer();
 
-    if (m_pPacketFilter)
+    return res;
+}
+
+HX_RESULT 
+RTSPTransport::storeClientPacket(RTSPTransportBuffer* pTransportBuffer,
+                                 ClientPacket* pClientPkt)
+{
+    HX_RESULT res = HXR_OUTOFMEMORY;
+
+    IHXPacket* pPkt = pClientPkt->GetPacket();
+
+    if (!pPkt)
     {
-	if (!m_pClientPacketList)
-	{
-	    m_pClientPacketList = new CHXSimpleList;
-            if( !m_pClientPacketList )
+        // This is a lost packet
+        res = pTransportBuffer->Add(pClientPkt);
+    }
+    else if (m_pPacketFilter)
+    {
+        if (!m_pClientPacketList)
+        {
+            m_pClientPacketList = new CHXSimpleList;
+
+            if (m_pClientPacketList)
             {
-                return HXR_OUTOFMEMORY;
+                m_pPacketFilter->SetFilterResponse(this);
             }
-	    m_pPacketFilter->SetFilterResponse(this);
-	}
-	clientPacket = new ClientPacket(uSeqNo, uReliableSeqNo,
-		pPacket->GetTime(), pBuffer->GetSize(), isReliable,
-		NULL, pTransportBuffer->GetTime(),
-		FALSE);
-        if( !clientPacket )
-        {
-            return HXR_OUTOFMEMORY;
         }
-	
-	clientPacket->AddRef();
-	pBuffer->Release();
 
-	m_pClientPacketList->AddHead((void*)clientPacket);
-	m_pPacketFilter->FilterPacket(pPacket);
+        if (m_pClientPacketList &&
+            m_pClientPacketList->AddHead((void*)pClientPkt))
+        {
+            // Successfully added the client packet to the list
+            pClientPkt->AddRef();
 
-	// just guessing on what this should be?????
-        return HXR_OK;
+            m_pPacketFilter->FilterPacket(pPkt);
+            res = HXR_OK;
+        }
     }
     else
     {
-       clientPacket = new ClientPacket(uSeqNo, uReliableSeqNo,
-		pPacket->GetTime(), pBuffer->GetSize(), isReliable,
-		pPacket, pTransportBuffer->GetTime(), FALSE);
-        if( !clientPacket )
-        {
-            return HXR_OUTOFMEMORY;
-        }
+        res = pTransportBuffer->Add(pClientPkt);
+    }
 
-	clientPacket->AddRef();
-	pBuffer->Release();
+    HX_RELEASE(pPkt);
 
-	return pTransportBuffer->Add(clientPacket);
-    }
+    return res;
 }
 
 HX_RESULT			
@@ -1759,3 +1818,50 @@
     }
 }
 #endif	// RDT_MESSAGE_DEBUG
+
+HX_RESULT 
+RTSPTransport::handleNoTransBufList(RTSPTransportBuffer* pTransportBuffer)
+{
+    HX_RESULT res = HXR_OK;
+
+    while ((HXR_OK == res) && !m_pNoTransBufPktList->IsEmpty())
+    {
+        ClientPacket* pTmpClientPkt = 
+            (ClientPacket*)m_pNoTransBufPktList->RemoveHead();
+        
+        // Set the start time now that we have a 
+        // transport buffer
+        pTmpClientPkt->SetStartTime(pTransportBuffer->GetTime());
+        
+        // Store the packet
+        res = storeClientPacket(pTransportBuffer, pTmpClientPkt);
+        
+        HX_RELEASE(pTmpClientPkt);
+    }
+    
+    if (HXR_OK == res)
+    {
+        // Destroy the packet list now that it is
+        // empty and we already have a transport 
+        // buffer
+        destroyPktList(m_pNoTransBufPktList);
+    }
+
+    return res;
+}
+
+void RTSPTransport::destroyPktList(REF(CHXSimpleList*) pList)
+{
+    if (pList)
+    {
+        while(!pList->IsEmpty())
+        {
+            ClientPacket* pPkt = 
+                (ClientPacket*)pList->RemoveTail();
+
+            HX_RELEASE(pPkt);
+        }
+
+        HX_DELETE(pList);
+    }
+}
Index: transport/common/system/pub/rtsptran.h
===================================================================
RCS file: /cvsroot/protocol/transport/common/system/pub/rtsptran.h,v
retrieving revision 1.18
diff -u -r1.18 rtsptran.h
--- transport/common/system/pub/rtsptran.h	2 Mar 2004 19:48:37 -0000	1.18
+++ transport/common/system/pub/rtsptran.h	29 Mar 2004 20:41:09 -0000
@@ -346,7 +346,13 @@
     UINT32 GetTotalSuccessfulResends() { return m_ulTotalSuccessfulResends; }
     UINT32 GetTotalFailedResends() { return m_ulTotalFailedResends; }
     UINT32 GetSendingTime() { return m_ulSendingTime; }
-        
+
+private:
+    HX_RESULT handleNoTransBufList(RTSPTransportBuffer* pTransportBuffer);
+    HX_RESULT storeClientPacket(RTSPTransportBuffer* pTransportBuffer,
+                                ClientPacket* pClientPkt);
+    void destroyPktList(REF(CHXSimpleList*) pList);
+
 protected:
     IUnknown*				m_pContext;
     IHXCommonClassFactory*     		m_pCommonClassFactory;
@@ -377,6 +383,7 @@
     
     RawPacketFilter*			m_pPacketFilter;
     CHXSimpleList* 			m_pClientPacketList;
+    CHXSimpleList* 			m_pNoTransBufPktList;
     BOOL                                m_bPlayRequestSent;
 
     UINT32                              m_ulTotalSuccessfulResends; 


From srobinson at real.com  Mon Mar 29 13:46:30 2004
From: srobinson at real.com (Sean Robinson)
Date: Mon May 10 16:37:26 2004
Subject: [Protocol-dev] CR-Client: Pipelined RTSP changes
In-Reply-To: <20040329213828.GA12753@real.com>
References: <20040329213828.GA12753@real.com>
Message-ID: <40689936.4020708@real.com>

Which servers was this tested against?  We obviously need to make sure 
we test against the latest Mobile 10 release...

Aaron Colwell wrote:

> 
> Overview: These changes allow every SETUP message after the first one to be
>           pipelined with the Subscribe SET_PARAM and PLAY messages. The 
>           original code would wait for all the SETUP response messages before
>           issuing the Subscribe SET_PARAM and PLAY messages. These changes
>           allow the SET_PARAM and PLAY to be sent before the SETUP responses
>           arrive. This pipelining behavior is only turned on when the
>           PipelineRTSP preference is set. If the preference is not set or
>           if it doesn't exist the player defaults to the old behavior.
> 
>           Now that the SETUP and PLAY messages are pipelined, it is possible
>           for data packets to arrive before the transport buffer is created.
>           The transport buffer is created when the SETUP response arrives
>           for a stream. A packet queue was added to handle the case where
>           data packets arrive before the SETUP response does. This queue only
>           holds packets during a very short interval and is immediately emptied
>           and destroyed once the transport buffer has been created.
> 
> Files Modified:
> common/util/pub/basepkt.h
> protocol/rtsp/rtspclnt.cpp
> protocol/rtsp/pub/rtspclnt.h
> protocol/transport/common/system/rtsptran.cpp
> protocol/transport/common/system/pub/rtsptran.h
> 
> Files Added: none
> 
> Image Size and Heap Use impact:
> 
> Platforms and Profiles affected: all
> 
> Distribution Libraries affected: rdtclntlib
> 
> Distribution library impact and planned action: 
> A member variable was added to the transport base class. This changes
> the layout of the RDT transport object so the distlib needs to be updated.
> 
> Platforms and Profiles Build Verified: win32 helix-client-all-defines
> 
> Platforms and Profiles Functionality verified: win32 helix-client-all-defines
> 
> Branch: HEAD
> 
> QA Instructions: none
> 
> Index: util/pub/basepkt.h
> ===================================================================
> RCS file: /cvsroot/common/util/pub/basepkt.h,v
> retrieving revision 1.5
> diff -u -r1.5 basepkt.h
> --- util/pub/basepkt.h	24 Sep 2003 18:45:39 -0000	1.5
> +++ util/pub/basepkt.h	29 Mar 2004 20:42:45 -0000
> @@ -111,6 +111,11 @@
>  inline void
>  BasePacket::SetPacket(IHXPacket* pPacket)
>  {
> +    if (m_pPacket)
> +    {
> +        m_pPacket->Release();
> +    }
> +
>      m_pPacket = pPacket;
>  
>      if (m_pPacket)
> @@ -255,6 +260,7 @@
>      BOOL			IsDroppedPacket();
>      BOOL			IsSanitizePacket();
>      Timeval			GetStartTime();
> +    void                        SetStartTime(Timeval startTime);
>  
>      // serialization method
>      static void	Pack	(IHXClientPacket* pPacket, char* pData, UINT32& ulSize);
> @@ -327,6 +333,12 @@
>  ClientPacket::GetStartTime()
>  {
>      return m_StartTime;
> +}
> +
> +inline void
> +ClientPacket::SetStartTime(Timeval startTime)
> +{
> +    m_StartTime = startTime;
>  }
>  
>  // serialization method
> 
> Index: rtsp/rtspclnt.cpp
> ===================================================================
> RCS file: /cvsroot/protocol/rtsp/rtspclnt.cpp,v
> retrieving revision 1.72
> diff -u -r1.72 rtspclnt.cpp
> --- rtsp/rtspclnt.cpp	18 Mar 2004 01:53:45 -0000	1.72
> +++ rtsp/rtspclnt.cpp	29 Mar 2004 20:41:09 -0000
> @@ -3183,8 +3183,6 @@
>      RTSPTransport* pTrans =
>  	(RTSPTransport*)(*m_pTransportStreamMap)[uStreamNumber];
>  
> -    HX_ASSERT(pTrans);
> -
>      rc = pTrans ?
>  	    pTrans->GetCurrentBuffering(uStreamNumber,
>  					llLowestTimestamp,
> @@ -4905,13 +4903,26 @@
>      status = handleSetupResponseExt(pStreamInfo, pMsg, pSetupMsg);
>  
>      UINT16 nStreamCount = (UINT16)m_streamInfoList.GetCount();
> +
> +    BOOL bSetupsDone = FALSE;
> +
>      if(m_setupResponseCount == 1 && (nStreamCount > 1))
>      {
> +        // Signal that we are done if we 
> +        // are pipelining RTSP messages
> +        bSetupsDone = PipelineRTSP();
> +
>  	// first time, send the rest...
>  	sendRemainingSetupRequests();
>      }
> +    else if (!PipelineRTSP())
> +    {
> +        // We only update bSetupsDone this way
> +        // if we are not pipelining RTSP messages.
> +        bSetupsDone = (m_setupResponseCount == nStreamCount);
> +    }
>  
> -    if(m_setupResponseCount == nStreamCount)
> +    if(bSetupsDone)
>      {
>  	// all done!
>  
> @@ -7620,6 +7631,15 @@
>      }
>  
>      return rc;
> +}
> +
> +BOOL RTSPClientProtocol::PipelineRTSP()
> +{
> +    BOOL bRet = FALSE;
> +
> +    ReadPrefBOOL(m_pPreferences, "PipelineRTSP", bRet);
> +
> +    return bRet;
>  }
>  
>  RTSPClientProtocol::UDPResponseHelper::UDPResponseHelper(RTSPClientProtocol* pParent, UINT16 nPort)
> Index: rtsp/pub/rtspclnt.h
> ===================================================================
> RCS file: /cvsroot/protocol/rtsp/pub/rtspclnt.h,v
> retrieving revision 1.26
> diff -u -r1.26 rtspclnt.h
> --- rtsp/pub/rtspclnt.h	8 Mar 2004 19:49:24 -0000	1.26
> +++ rtsp/pub/rtspclnt.h	29 Mar 2004 20:41:09 -0000
> @@ -932,6 +932,8 @@
>                                      const char* pContent,
>                                      const char* pMimeType, UINT32 seqNo);
>  
> +    BOOL PipelineRTSP();
> +
>              HX_RESULT   ReportSuccessfulTransport(void);
>  
>      LONG32                              m_lRefCount;
> Index: transport/common/system/rtsptran.cpp
> ===================================================================
> RCS file: /cvsroot/protocol/transport/common/system/rtsptran.cpp,v
> retrieving revision 1.24
> diff -u -r1.24 rtsptran.cpp
> --- transport/common/system/rtsptran.cpp	24 Feb 2004 19:53:31 -0000	1.24
> +++ transport/common/system/rtsptran.cpp	29 Mar 2004 20:41:09 -0000
> @@ -332,6 +332,7 @@
>      m_pPlayerState(NULL),
>      m_pPacketFilter(NULL),
>      m_pClientPacketList(NULL),
> +    m_pNoTransBufPktList(NULL),
>      m_bPrefetch(FALSE),
>      m_bFastStart(FALSE),
>      m_ulPlayRangeFrom(RTSP_PLAY_RANGE_BLANK),
> @@ -367,7 +368,8 @@
>      HX_RELEASE(m_pPacketFilter);
>      HX_RELEASE(m_pContext);
>  
> -    HX_DELETE(m_pClientPacketList);
> +    destroyPktList(m_pClientPacketList);
> +    destroyPktList(m_pNoTransBufPktList);
>  }
>  
>  void
> @@ -733,6 +735,7 @@
>      uStreamNumber = clientPacket->GetStreamNumber();
>      RTSPTransportBuffer* pTransportBuffer = getTransportBuffer(uStreamNumber);
>      pTransportBuffer->Add(clientPacket);
> +    HX_RELEASE(clientPacket);
>  }
>  
>  void RTSPTransport::GetContext(IUnknown*& pContext)   
> @@ -855,78 +858,134 @@
>                             UINT16 uReliableSeqNo,
>                             BOOL isReliable)
>  {
> +    m_bIsReceivedData = TRUE;
> +
> +    ULONG32 ulPktSize = 0;
> +    IHXPacket* pPkt = NULL;
> +
> +    if (pPacket && !pPacket->IsLost())
> +    {
> +        IHXBuffer* pBuffer = pPacket->GetBuffer();
> +        
> +        if (pBuffer)
> +        {
> +            ulPktSize = pBuffer->GetSize();
> +        }
> +
> +        HX_RELEASE(pBuffer);
> +        
> +        pPkt = pPacket;
> +    }
> +
>      RTSPTransportBuffer* pTransportBuffer = getTransportBuffer(uStreamNumber);
> +    Timeval startTime;
>  
> -    if (!pTransportBuffer)
> +    if (pTransportBuffer)
>      {
> -	return HXR_FAIL;
> +        startTime = pTransportBuffer->GetTime();
>      }
>  
> -    ClientPacket* clientPacket = 0;
> +    HX_RESULT res = HXR_OUTOFMEMORY;
> +    ClientPacket* pClientPacket = new ClientPacket(uSeqNo, 
> +                                                   uReliableSeqNo,
> +                                                   pPacket->GetTime(), 
> +                                                   ulPktSize, 
> +                                                   isReliable,
> +                                                   pPkt, 
> +                                                   startTime, 
> +                                                   FALSE);
>      
> -    m_bIsReceivedData = TRUE;
> -
> -    if (pPacket->IsLost())
> +    if (pClientPacket)
>      {
> -        clientPacket = new ClientPacket(uSeqNo, uReliableSeqNo,
> -		                        pPacket->GetTime(), 0, isReliable,
> -		                        0, pTransportBuffer->GetTime(), FALSE);
> -        if( !clientPacket )
> +        pClientPacket->AddRef();
> +
> +        if (pTransportBuffer)
>          {
> -            return HXR_OUTOFMEMORY;
> +            if (m_pNoTransBufPktList)
> +            {
> +                // We handle any packets received
> +                // when we didn't have a transport buffer
> +                // first.
> +                res = handleNoTransBufList(pTransportBuffer);
> +            }
> +            else
> +            {
> +                res = HXR_OK;
> +            }
> +            
> +            if (HXR_OK == res)
> +            {
> +                // Now store the packet for this call
> +                res = storeClientPacket(pTransportBuffer, pClientPacket);
> +            }
>          }
> +        else
> +        {
> +            // We don't have a transport buffer yet.
> +            // Queue the packet until we have one.
> +            if (!m_pNoTransBufPktList)
> +            {
> +                m_pNoTransBufPktList = new CHXSimpleList;
> +            }
>  
> -	clientPacket->AddRef();
> +            if (m_pNoTransBufPktList &&
> +                m_pNoTransBufPktList->AddTail(pClientPacket))
> +            {
> +                // We successfully queued the packet
> +                pClientPacket->AddRef();
> +                res = HXR_OK;
> +            }
> +        }
>  
> -	return pTransportBuffer->Add(clientPacket);
> +        HX_RELEASE(pClientPacket);
>      }
> -    
> -    IHXBuffer* pBuffer = pPacket->GetBuffer();
>  
> -    if (m_pPacketFilter)
> +    return res;
> +}
> +
> +HX_RESULT 
> +RTSPTransport::storeClientPacket(RTSPTransportBuffer* pTransportBuffer,
> +                                 ClientPacket* pClientPkt)
> +{
> +    HX_RESULT res = HXR_OUTOFMEMORY;
> +
> +    IHXPacket* pPkt = pClientPkt->GetPacket();
> +
> +    if (!pPkt)
>      {
> -	if (!m_pClientPacketList)
> -	{
> -	    m_pClientPacketList = new CHXSimpleList;
> -            if( !m_pClientPacketList )
> +        // This is a lost packet
> +        res = pTransportBuffer->Add(pClientPkt);
> +    }
> +    else if (m_pPacketFilter)
> +    {
> +        if (!m_pClientPacketList)
> +        {
> +            m_pClientPacketList = new CHXSimpleList;
> +
> +            if (m_pClientPacketList)
>              {
> -                return HXR_OUTOFMEMORY;
> +                m_pPacketFilter->SetFilterResponse(this);
>              }
> -	    m_pPacketFilter->SetFilterResponse(this);
> -	}
> -	clientPacket = new ClientPacket(uSeqNo, uReliableSeqNo,
> -		pPacket->GetTime(), pBuffer->GetSize(), isReliable,
> -		NULL, pTransportBuffer->GetTime(),
> -		FALSE);
> -        if( !clientPacket )
> -        {
> -            return HXR_OUTOFMEMORY;
>          }
> -	
> -	clientPacket->AddRef();
> -	pBuffer->Release();
>  
> -	m_pClientPacketList->AddHead((void*)clientPacket);
> -	m_pPacketFilter->FilterPacket(pPacket);
> +        if (m_pClientPacketList &&
> +            m_pClientPacketList->AddHead((void*)pClientPkt))
> +        {
> +            // Successfully added the client packet to the list
> +            pClientPkt->AddRef();
>  
> -	// just guessing on what this should be?????
> -        return HXR_OK;
> +            m_pPacketFilter->FilterPacket(pPkt);
> +            res = HXR_OK;
> +        }
>      }
>      else
>      {
> -       clientPacket = new ClientPacket(uSeqNo, uReliableSeqNo,
> -		pPacket->GetTime(), pBuffer->GetSize(), isReliable,
> -		pPacket, pTransportBuffer->GetTime(), FALSE);
> -        if( !clientPacket )
> -        {
> -            return HXR_OUTOFMEMORY;
> -        }
> +        res = pTransportBuffer->Add(pClientPkt);
> +    }
>  
> -	clientPacket->AddRef();
> -	pBuffer->Release();
> +    HX_RELEASE(pPkt);
>  
> -	return pTransportBuffer->Add(clientPacket);
> -    }
> +    return res;
>  }
>  
>  HX_RESULT			
> @@ -1759,3 +1818,50 @@
>      }
>  }
>  #endif	// RDT_MESSAGE_DEBUG
> +
> +HX_RESULT 
> +RTSPTransport::handleNoTransBufList(RTSPTransportBuffer* pTransportBuffer)
> +{
> +    HX_RESULT res = HXR_OK;
> +
> +    while ((HXR_OK == res) && !m_pNoTransBufPktList->IsEmpty())
> +    {
> +        ClientPacket* pTmpClientPkt = 
> +            (ClientPacket*)m_pNoTransBufPktList->RemoveHead();
> +        
> +        // Set the start time now that we have a 
> +        // transport buffer
> +        pTmpClientPkt->SetStartTime(pTransportBuffer->GetTime());
> +        
> +        // Store the packet
> +        res = storeClientPacket(pTransportBuffer, pTmpClientPkt);
> +        
> +        HX_RELEASE(pTmpClientPkt);
> +    }
> +    
> +    if (HXR_OK == res)
> +    {
> +        // Destroy the packet list now that it is
> +        // empty and we already have a transport 
> +        // buffer
> +        destroyPktList(m_pNoTransBufPktList);
> +    }
> +
> +    return res;
> +}
> +
> +void RTSPTransport::destroyPktList(REF(CHXSimpleList*) pList)
> +{
> +    if (pList)
> +    {
> +        while(!pList->IsEmpty())
> +        {
> +            ClientPacket* pPkt = 
> +                (ClientPacket*)pList->RemoveTail();
> +
> +            HX_RELEASE(pPkt);
> +        }
> +
> +        HX_DELETE(pList);
> +    }
> +}
> Index: transport/common/system/pub/rtsptran.h
> ===================================================================
> RCS file: /cvsroot/protocol/transport/common/system/pub/rtsptran.h,v
> retrieving revision 1.18
> diff -u -r1.18 rtsptran.h
> --- transport/common/system/pub/rtsptran.h	2 Mar 2004 19:48:37 -0000	1.18
> +++ transport/common/system/pub/rtsptran.h	29 Mar 2004 20:41:09 -0000
> @@ -346,7 +346,13 @@
>      UINT32 GetTotalSuccessfulResends() { return m_ulTotalSuccessfulResends; }
>      UINT32 GetTotalFailedResends() { return m_ulTotalFailedResends; }
>      UINT32 GetSendingTime() { return m_ulSendingTime; }
> -        
> +
> +private:
> +    HX_RESULT handleNoTransBufList(RTSPTransportBuffer* pTransportBuffer);
> +    HX_RESULT storeClientPacket(RTSPTransportBuffer* pTransportBuffer,
> +                                ClientPacket* pClientPkt);
> +    void destroyPktList(REF(CHXSimpleList*) pList);
> +
>  protected:
>      IUnknown*				m_pContext;
>      IHXCommonClassFactory*     		m_pCommonClassFactory;
> @@ -377,6 +383,7 @@
>      
>      RawPacketFilter*			m_pPacketFilter;
>      CHXSimpleList* 			m_pClientPacketList;
> +    CHXSimpleList* 			m_pNoTransBufPktList;
>      BOOL                                m_bPlayRequestSent;
>  
>      UINT32                              m_ulTotalSuccessfulResends; 
> 
> _______________________________________________
> Protocol-dev mailing list
> Protocol-dev@lists.helixcommunity.org
> http://lists.helixcommunity.org/mailman/listinfo/protocol-dev
> 
> 


From acolwell at real.com  Mon Mar 29 14:13:55 2004
From: acolwell at real.com (Aaron Colwell)
Date: Mon May 10 16:37:26 2004
Subject: [Protocol-dev] CR-Client: Pipelined RTSP changes
In-Reply-To: <40689936.4020708@real.com>
References: <20040329213828.GA12753@real.com> <40689936.4020708@real.com>
Message-ID: <20040329221355.GA12774@real.com>

I tested this against Helix Server Version 9.0.3.916. I'll test this against
Mobile 10.02 right now.

Aaron

On Mon, Mar 29, 2004 at 01:46:30PM -0800, Sean Robinson wrote:
> Which servers was this tested against?  We obviously need to make sure 
> we test against the latest Mobile 10 release...
> 
> Aaron Colwell wrote:
> 
> >
> >Overview: These changes allow every SETUP message after the first one to be
> >          pipelined with the Subscribe SET_PARAM and PLAY messages. The 
> >          original code would wait for all the SETUP response messages 
> >          before
> >          issuing the Subscribe SET_PARAM and PLAY messages. These changes
> >          allow the SET_PARAM and PLAY to be sent before the SETUP 
> >          responses
> >          arrive. This pipelining behavior is only turned on when the
> >          PipelineRTSP preference is set. If the preference is not set or
> >          if it doesn't exist the player defaults to the old behavior.
> >
> >          Now that the SETUP and PLAY messages are pipelined, it is 
> >          possible
> >          for data packets to arrive before the transport buffer is 
> >          created.
> >          The transport buffer is created when the SETUP response arrives
> >          for a stream. A packet queue was added to handle the case where
> >          data packets arrive before the SETUP response does. This queue 
> >          only
> >          holds packets during a very short interval and is immediately 
> >          emptied
> >          and destroyed once the transport buffer has been created.
> >
> >Files Modified:
> >common/util/pub/basepkt.h
> >protocol/rtsp/rtspclnt.cpp
> >protocol/rtsp/pub/rtspclnt.h
> >protocol/transport/common/system/rtsptran.cpp
> >protocol/transport/common/system/pub/rtsptran.h
> >
> >Files Added: none
> >
> >Image Size and Heap Use impact:
> >
> >Platforms and Profiles affected: all
> >
> >Distribution Libraries affected: rdtclntlib
> >
> >Distribution library impact and planned action: 
> >A member variable was added to the transport base class. This changes
> >the layout of the RDT transport object so the distlib needs to be updated.
> >
> >Platforms and Profiles Build Verified: win32 helix-client-all-defines
> >
> >Platforms and Profiles Functionality verified: win32 
> >helix-client-all-defines
> >
> >Branch: HEAD
> >
> >QA Instructions: none
> >
> >Index: util/pub/basepkt.h
> >===================================================================
> >RCS file: /cvsroot/common/util/pub/basepkt.h,v
> >retrieving revision 1.5
> >diff -u -r1.5 basepkt.h
> >--- util/pub/basepkt.h	24 Sep 2003 18:45:39 -0000	1.5
> >+++ util/pub/basepkt.h	29 Mar 2004 20:42:45 -0000
> >@@ -111,6 +111,11 @@
> > inline void
> > BasePacket::SetPacket(IHXPacket* pPacket)
> > {
> >+    if (m_pPacket)
> >+    {
> >+        m_pPacket->Release();
> >+    }
> >+
> >     m_pPacket = pPacket;
> > 
> >     if (m_pPacket)
> >@@ -255,6 +260,7 @@
> >     BOOL			IsDroppedPacket();
> >     BOOL			IsSanitizePacket();
> >     Timeval			GetStartTime();
> >+    void                        SetStartTime(Timeval startTime);
> > 
> >     // serialization method
> >     static void	Pack	(IHXClientPacket* pPacket, char* pData, 
> >     UINT32& ulSize);
> >@@ -327,6 +333,12 @@
> > ClientPacket::GetStartTime()
> > {
> >     return m_StartTime;
> >+}
> >+
> >+inline void
> >+ClientPacket::SetStartTime(Timeval startTime)
> >+{
> >+    m_StartTime = startTime;
> > }
> > 
> > // serialization method
> >
> >Index: rtsp/rtspclnt.cpp
> >===================================================================
> >RCS file: /cvsroot/protocol/rtsp/rtspclnt.cpp,v
> >retrieving revision 1.72
> >diff -u -r1.72 rtspclnt.cpp
> >--- rtsp/rtspclnt.cpp	18 Mar 2004 01:53:45 -0000	1.72
> >+++ rtsp/rtspclnt.cpp	29 Mar 2004 20:41:09 -0000
> >@@ -3183,8 +3183,6 @@
> >     RTSPTransport* pTrans =
> > 	(RTSPTransport*)(*m_pTransportStreamMap)[uStreamNumber];
> > 
> >-    HX_ASSERT(pTrans);
> >-
> >     rc = pTrans ?
> > 	    pTrans->GetCurrentBuffering(uStreamNumber,
> > 					llLowestTimestamp,
> >@@ -4905,13 +4903,26 @@
> >     status = handleSetupResponseExt(pStreamInfo, pMsg, pSetupMsg);
> > 
> >     UINT16 nStreamCount = (UINT16)m_streamInfoList.GetCount();
> >+
> >+    BOOL bSetupsDone = FALSE;
> >+
> >     if(m_setupResponseCount == 1 && (nStreamCount > 1))
> >     {
> >+        // Signal that we are done if we 
> >+        // are pipelining RTSP messages
> >+        bSetupsDone = PipelineRTSP();
> >+
> > 	// first time, send the rest...
> > 	sendRemainingSetupRequests();
> >     }
> >+    else if (!PipelineRTSP())
> >+    {
> >+        // We only update bSetupsDone this way
> >+        // if we are not pipelining RTSP messages.
> >+        bSetupsDone = (m_setupResponseCount == nStreamCount);
> >+    }
> > 
> >-    if(m_setupResponseCount == nStreamCount)
> >+    if(bSetupsDone)
> >     {
> > 	// all done!
> > 
> >@@ -7620,6 +7631,15 @@
> >     }
> > 
> >     return rc;
> >+}
> >+
> >+BOOL RTSPClientProtocol::PipelineRTSP()
> >+{
> >+    BOOL bRet = FALSE;
> >+
> >+    ReadPrefBOOL(m_pPreferences, "PipelineRTSP", bRet);
> >+
> >+    return bRet;
> > }
> > 
> > RTSPClientProtocol::UDPResponseHelper::UDPResponseHelper(RTSPClientProtocol* pParent, UINT16 nPort)
> >Index: rtsp/pub/rtspclnt.h
> >===================================================================
> >RCS file: /cvsroot/protocol/rtsp/pub/rtspclnt.h,v
> >retrieving revision 1.26
> >diff -u -r1.26 rtspclnt.h
> >--- rtsp/pub/rtspclnt.h	8 Mar 2004 19:49:24 -0000	1.26
> >+++ rtsp/pub/rtspclnt.h	29 Mar 2004 20:41:09 -0000
> >@@ -932,6 +932,8 @@
> >                                     const char* pContent,
> >                                     const char* pMimeType, UINT32 seqNo);
> > 
> >+    BOOL PipelineRTSP();
> >+
> >             HX_RESULT   ReportSuccessfulTransport(void);
> > 
> >     LONG32                              m_lRefCount;
> >Index: transport/common/system/rtsptran.cpp
> >===================================================================
> >RCS file: /cvsroot/protocol/transport/common/system/rtsptran.cpp,v
> >retrieving revision 1.24
> >diff -u -r1.24 rtsptran.cpp
> >--- transport/common/system/rtsptran.cpp	24 Feb 2004 19:53:31 -0000 
> >1.24
> >+++ transport/common/system/rtsptran.cpp	29 Mar 2004 20:41:09 -0000
> >@@ -332,6 +332,7 @@
> >     m_pPlayerState(NULL),
> >     m_pPacketFilter(NULL),
> >     m_pClientPacketList(NULL),
> >+    m_pNoTransBufPktList(NULL),
> >     m_bPrefetch(FALSE),
> >     m_bFastStart(FALSE),
> >     m_ulPlayRangeFrom(RTSP_PLAY_RANGE_BLANK),
> >@@ -367,7 +368,8 @@
> >     HX_RELEASE(m_pPacketFilter);
> >     HX_RELEASE(m_pContext);
> > 
> >-    HX_DELETE(m_pClientPacketList);
> >+    destroyPktList(m_pClientPacketList);
> >+    destroyPktList(m_pNoTransBufPktList);
> > }
> > 
> > void
> >@@ -733,6 +735,7 @@
> >     uStreamNumber = clientPacket->GetStreamNumber();
> >     RTSPTransportBuffer* pTransportBuffer = 
> >     getTransportBuffer(uStreamNumber);
> >     pTransportBuffer->Add(clientPacket);
> >+    HX_RELEASE(clientPacket);
> > }
> > 
> > void RTSPTransport::GetContext(IUnknown*& pContext)   
> >@@ -855,78 +858,134 @@
> >                            UINT16 uReliableSeqNo,
> >                            BOOL isReliable)
> > {
> >+    m_bIsReceivedData = TRUE;
> >+
> >+    ULONG32 ulPktSize = 0;
> >+    IHXPacket* pPkt = NULL;
> >+
> >+    if (pPacket && !pPacket->IsLost())
> >+    {
> >+        IHXBuffer* pBuffer = pPacket->GetBuffer();
> >+        
> >+        if (pBuffer)
> >+        {
> >+            ulPktSize = pBuffer->GetSize();
> >+        }
> >+
> >+        HX_RELEASE(pBuffer);
> >+        
> >+        pPkt = pPacket;
> >+    }
> >+
> >     RTSPTransportBuffer* pTransportBuffer = 
> >     getTransportBuffer(uStreamNumber);
> >+    Timeval startTime;
> > 
> >-    if (!pTransportBuffer)
> >+    if (pTransportBuffer)
> >     {
> >-	return HXR_FAIL;
> >+        startTime = pTransportBuffer->GetTime();
> >     }
> > 
> >-    ClientPacket* clientPacket = 0;
> >+    HX_RESULT res = HXR_OUTOFMEMORY;
> >+    ClientPacket* pClientPacket = new ClientPacket(uSeqNo, 
> >+                                                   uReliableSeqNo,
> >+                                                   pPacket->GetTime(), 
> >+                                                   ulPktSize, 
> >+                                                   isReliable,
> >+                                                   pPkt, 
> >+                                                   startTime, 
> >+                                                   FALSE);
> >     
> >-    m_bIsReceivedData = TRUE;
> >-
> >-    if (pPacket->IsLost())
> >+    if (pClientPacket)
> >     {
> >-        clientPacket = new ClientPacket(uSeqNo, uReliableSeqNo,
> >-		                        pPacket->GetTime(), 0, isReliable,
> >-		                        0, pTransportBuffer->GetTime(), 
> >FALSE);
> >-        if( !clientPacket )
> >+        pClientPacket->AddRef();
> >+
> >+        if (pTransportBuffer)
> >         {
> >-            return HXR_OUTOFMEMORY;
> >+            if (m_pNoTransBufPktList)
> >+            {
> >+                // We handle any packets received
> >+                // when we didn't have a transport buffer
> >+                // first.
> >+                res = handleNoTransBufList(pTransportBuffer);
> >+            }
> >+            else
> >+            {
> >+                res = HXR_OK;
> >+            }
> >+            
> >+            if (HXR_OK == res)
> >+            {
> >+                // Now store the packet for this call
> >+                res = storeClientPacket(pTransportBuffer, pClientPacket);
> >+            }
> >         }
> >+        else
> >+        {
> >+            // We don't have a transport buffer yet.
> >+            // Queue the packet until we have one.
> >+            if (!m_pNoTransBufPktList)
> >+            {
> >+                m_pNoTransBufPktList = new CHXSimpleList;
> >+            }
> > 
> >-	clientPacket->AddRef();
> >+            if (m_pNoTransBufPktList &&
> >+                m_pNoTransBufPktList->AddTail(pClientPacket))
> >+            {
> >+                // We successfully queued the packet
> >+                pClientPacket->AddRef();
> >+                res = HXR_OK;
> >+            }
> >+        }
> > 
> >-	return pTransportBuffer->Add(clientPacket);
> >+        HX_RELEASE(pClientPacket);
> >     }
> >-    
> >-    IHXBuffer* pBuffer = pPacket->GetBuffer();
> > 
> >-    if (m_pPacketFilter)
> >+    return res;
> >+}
> >+
> >+HX_RESULT 
> >+RTSPTransport::storeClientPacket(RTSPTransportBuffer* pTransportBuffer,
> >+                                 ClientPacket* pClientPkt)
> >+{
> >+    HX_RESULT res = HXR_OUTOFMEMORY;
> >+
> >+    IHXPacket* pPkt = pClientPkt->GetPacket();
> >+
> >+    if (!pPkt)
> >     {
> >-	if (!m_pClientPacketList)
> >-	{
> >-	    m_pClientPacketList = new CHXSimpleList;
> >-            if( !m_pClientPacketList )
> >+        // This is a lost packet
> >+        res = pTransportBuffer->Add(pClientPkt);
> >+    }
> >+    else if (m_pPacketFilter)
> >+    {
> >+        if (!m_pClientPacketList)
> >+        {
> >+            m_pClientPacketList = new CHXSimpleList;
> >+
> >+            if (m_pClientPacketList)
> >             {
> >-                return HXR_OUTOFMEMORY;
> >+                m_pPacketFilter->SetFilterResponse(this);
> >             }
> >-	    m_pPacketFilter->SetFilterResponse(this);
> >-	}
> >-	clientPacket = new ClientPacket(uSeqNo, uReliableSeqNo,
> >-		pPacket->GetTime(), pBuffer->GetSize(), isReliable,
> >-		NULL, pTransportBuffer->GetTime(),
> >-		FALSE);
> >-        if( !clientPacket )
> >-        {
> >-            return HXR_OUTOFMEMORY;
> >         }
> >-	
> >-	clientPacket->AddRef();
> >-	pBuffer->Release();
> > 
> >-	m_pClientPacketList->AddHead((void*)clientPacket);
> >-	m_pPacketFilter->FilterPacket(pPacket);
> >+        if (m_pClientPacketList &&
> >+            m_pClientPacketList->AddHead((void*)pClientPkt))
> >+        {
> >+            // Successfully added the client packet to the list
> >+            pClientPkt->AddRef();
> > 
> >-	// just guessing on what this should be?????
> >-        return HXR_OK;
> >+            m_pPacketFilter->FilterPacket(pPkt);
> >+            res = HXR_OK;
> >+        }
> >     }
> >     else
> >     {
> >-       clientPacket = new ClientPacket(uSeqNo, uReliableSeqNo,
> >-		pPacket->GetTime(), pBuffer->GetSize(), isReliable,
> >-		pPacket, pTransportBuffer->GetTime(), FALSE);
> >-        if( !clientPacket )
> >-        {
> >-            return HXR_OUTOFMEMORY;
> >-        }
> >+        res = pTransportBuffer->Add(pClientPkt);
> >+    }
> > 
> >-	clientPacket->AddRef();
> >-	pBuffer->Release();
> >+    HX_RELEASE(pPkt);
> > 
> >-	return pTransportBuffer->Add(clientPacket);
> >-    }
> >+    return res;
> > }
> > 
> > HX_RESULT			
> >@@ -1759,3 +1818,50 @@
> >     }
> > }
> > #endif	// RDT_MESSAGE_DEBUG
> >+
> >+HX_RESULT 
> >+RTSPTransport::handleNoTransBufList(RTSPTransportBuffer* pTransportBuffer)
> >+{
> >+    HX_RESULT res = HXR_OK;
> >+
> >+    while ((HXR_OK == res) && !m_pNoTransBufPktList->IsEmpty())
> >+    {
> >+        ClientPacket* pTmpClientPkt = 
> >+            (ClientPacket*)m_pNoTransBufPktList->RemoveHead();
> >+        
> >+        // Set the start time now that we have a 
> >+        // transport buffer
> >+        pTmpClientPkt->SetStartTime(pTransportBuffer->GetTime());
> >+        
> >+        // Store the packet
> >+        res = storeClientPacket(pTransportBuffer, pTmpClientPkt);
> >+        
> >+        HX_RELEASE(pTmpClientPkt);
> >+    }
> >+    
> >+    if (HXR_OK == res)
> >+    {
> >+        // Destroy the packet list now that it is
> >+        // empty and we already have a transport 
> >+        // buffer
> >+        destroyPktList(m_pNoTransBufPktList);
> >+    }
> >+
> >+    return res;
> >+}
> >+
> >+void RTSPTransport::destroyPktList(REF(CHXSimpleList*) pList)
> >+{
> >+    if (pList)
> >+    {
> >+        while(!pList->IsEmpty())
> >+        {
> >+            ClientPacket* pPkt = 
> >+                (ClientPacket*)pList->RemoveTail();
> >+
> >+            HX_RELEASE(pPkt);
> >+        }
> >+
> >+        HX_DELETE(pList);
> >+    }
> >+}
> >Index: transport/common/system/pub/rtsptran.h
> >===================================================================
> >RCS file: /cvsroot/protocol/transport/common/system/pub/rtsptran.h,v
> >retrieving revision 1.18
> >diff -u -r1.18 rtsptran.h
> >--- transport/common/system/pub/rtsptran.h	2 Mar 2004 19:48:37 -0000 
> >1.18
> >+++ transport/common/system/pub/rtsptran.h	29 Mar 2004 20:41:09 -0000
> >@@ -346,7 +346,13 @@
> >     UINT32 GetTotalSuccessfulResends() { return 
> >     m_ulTotalSuccessfulResends; }
> >     UINT32 GetTotalFailedResends() { return m_ulTotalFailedResends; }
> >     UINT32 GetSendingTime() { return m_ulSendingTime; }
> >-        
> >+
> >+private:
> >+    HX_RESULT handleNoTransBufList(RTSPTransportBuffer* pTransportBuffer);
> >+    HX_RESULT storeClientPacket(RTSPTransportBuffer* pTransportBuffer,
> >+                                ClientPacket* pClientPkt);
> >+    void destroyPktList(REF(CHXSimpleList*) pList);
> >+
> > protected:
> >     IUnknown*				m_pContext;
> >     IHXCommonClassFactory*     		m_pCommonClassFactory;
> >@@ -377,6 +383,7 @@
> >     
> >     RawPacketFilter*			m_pPacketFilter;
> >     CHXSimpleList* 			m_pClientPacketList;
> >+    CHXSimpleList* 			m_pNoTransBufPktList;
> >     BOOL                                m_bPlayRequestSent;
> > 
> >     UINT32                              m_ulTotalSuccessfulResends; 
> >
> >_______________________________________________
> >Protocol-dev mailing list
> >Protocol-dev@lists.helixcommunity.org
> >http://lists.helixcommunity.org/mailman/listinfo/protocol-dev
> >
> >


From acolwell at real.com  Mon Mar 29 16:32:27 2004
From: acolwell at real.com (Aaron Colwell)
Date: Mon May 10 16:37:26 2004
Subject: [Protocol-dev] CR-Client: Pipelined RTSP changes
In-Reply-To: <20040329221355.GA12774@real.com>
References: <20040329213828.GA12753@real.com> <40689936.4020708@real.com>
	<20040329221355.GA12774@real.com>
Message-ID: <20040330003227.GA13369@real.com>

Sean,

These changes also appear to work with Mobile Server 10.02. Here is an
updated diff for rtspclnt.cpp. I discovered a bug related to streaming
single stream files.

Aaron

Index: rtspclnt.cpp
===================================================================
RCS file: /cvsroot/protocol/rtsp/rtspclnt.cpp,v
retrieving revision 1.72
diff -u -r1.72 rtspclnt.cpp
--- rtspclnt.cpp	18 Mar 2004 01:53:45 -0000	1.72
+++ rtspclnt.cpp	30 Mar 2004 00:29:21 -0000
@@ -3183,8 +3183,6 @@
     RTSPTransport* pTrans =
 	(RTSPTransport*)(*m_pTransportStreamMap)[uStreamNumber];
 
-    HX_ASSERT(pTrans);
-
     rc = pTrans ?
 	    pTrans->GetCurrentBuffering(uStreamNumber,
 					llLowestTimestamp,
@@ -4833,7 +4831,7 @@
     UINT16 streamNumber = 0;
     IHXValues* pReconnectValues = NULL;
     RTSPStreamInfo* pStreamInfo = 0;
-
+    
     if(pMsg->errorCodeAsUINT32() == 401 || pMsg->errorCodeAsUINT32() == 407)
     {
 	status = handleAuthentication(pMsg);
@@ -4905,13 +4903,35 @@
     status = handleSetupResponseExt(pStreamInfo, pMsg, pSetupMsg);
 
     UINT16 nStreamCount = (UINT16)m_streamInfoList.GetCount();
-    if(m_setupResponseCount == 1 && (nStreamCount > 1))
+
+    BOOL bSetupsDone = FALSE;
+
+    if(m_setupResponseCount == 1)
+    {
+        if (nStreamCount > 1)
+        {
+            // Signal that we are done if we 
+            // are pipelining RTSP messages
+            bSetupsDone = PipelineRTSP();
+
+            // first time, send the rest...
+            sendRemainingSetupRequests();
+        }
+        else
+        {
+            // Single stream case
+            bSetupsDone = TRUE;
+        }
+    }
+    else if (!PipelineRTSP())
     {
-	// first time, send the rest...
-	sendRemainingSetupRequests();
+        // We only update bSetupsDone this way
+        // if we are not pipelining RTSP messages
+        // and this isn't the first response
+        bSetupsDone = (m_setupResponseCount == nStreamCount);
     }
 
-    if(m_setupResponseCount == nStreamCount)
+    if(bSetupsDone)
     {
 	// all done!
 
@@ -7620,6 +7640,15 @@
     }
 
     return rc;
+}
+
+BOOL RTSPClientProtocol::PipelineRTSP()
+{
+    BOOL bRet = FALSE;
+
+    ReadPrefBOOL(m_pPreferences, "PipelineRTSP", bRet);
+
+    return bRet;
 }
 
 RTSPClientProtocol::UDPResponseHelper::UDPResponseHelper(RTSPClientProtocol* pParent, UINT16 nPort)



On Mon, Mar 29, 2004 at 02:13:55PM -0800, Aaron Colwell wrote:
> I tested this against Helix Server Version 9.0.3.916. I'll test this against
> Mobile 10.02 right now.
> 
> Aaron
> 
> On Mon, Mar 29, 2004 at 01:46:30PM -0800, Sean Robinson wrote:
> > Which servers was this tested against?  We obviously need to make sure 
> > we test against the latest Mobile 10 release...
> > 
> > Aaron Colwell wrote:
> > 
> > >
> > >Overview: These changes allow every SETUP message after the first one to be
> > >          pipelined with the Subscribe SET_PARAM and PLAY messages. The 
> > >          original code would wait for all the SETUP response messages 
> > >          before
> > >          issuing the Subscribe SET_PARAM and PLAY messages. These changes
> > >          allow the SET_PARAM and PLAY to be sent before the SETUP 
> > >          responses
> > >          arrive. This pipelining behavior is only turned on when the
> > >          PipelineRTSP preference is set. If the preference is not set or
> > >          if it doesn't exist the player defaults to the old behavior.
> > >
> > >          Now that the SETUP and PLAY messages are pipelined, it is 
> > >          possible
> > >          for data packets to arrive before the transport buffer is 
> > >          created.
> > >          The transport buffer is created when the SETUP response arrives
> > >          for a stream. A packet queue was added to handle the case where
> > >          data packets arrive before the SETUP response does. This queue 
> > >          only
> > >          holds packets during a very short interval and is immediately 
> > >          emptied
> > >          and destroyed once the transport buffer has been created.
> > >
> > >Files Modified:
> > >common/util/pub/basepkt.h
> > >protocol/rtsp/rtspclnt.cpp
> > >protocol/rtsp/pub/rtspclnt.h
> > >protocol/transport/common/system/rtsptran.cpp
> > >protocol/transport/common/system/pub/rtsptran.h
> > >
> > >Files Added: none
> > >
> > >Image Size and Heap Use impact:
> > >
> > >Platforms and Profiles affected: all
> > >
> > >Distribution Libraries affected: rdtclntlib
> > >
> > >Distribution library impact and planned action: 
> > >A member variable was added to the transport base class. This changes
> > >the layout of the RDT transport object so the distlib needs to be updated.
> > >
> > >Platforms and Profiles Build Verified: win32 helix-client-all-defines
> > >
> > >Platforms and Profiles Functionality verified: win32 
> > >helix-client-all-defines
> > >
> > >Branch: HEAD
> > >
> > >QA Instructions: none
> > >
> > >Index: util/pub/basepkt.h
> > >===================================================================
> > >RCS file: /cvsroot/common/util/pub/basepkt.h,v
> > >retrieving revision 1.5
> > >diff -u -r1.5 basepkt.h
> > >--- util/pub/basepkt.h	24 Sep 2003 18:45:39 -0000	1.5
> > >+++ util/pub/basepkt.h	29 Mar 2004 20:42:45 -0000
> > >@@ -111,6 +111,11 @@
> > > inline void
> > > BasePacket::SetPacket(IHXPacket* pPacket)
> > > {
> > >+    if (m_pPacket)
> > >+    {
> > >+        m_pPacket->Release();
> > >+    }
> > >+
> > >     m_pPacket = pPacket;
> > > 
> > >     if (m_pPacket)
> > >@@ -255,6 +260,7 @@
> > >     BOOL			IsDroppedPacket();
> > >     BOOL			IsSanitizePacket();
> > >     Timeval			GetStartTime();
> > >+    void                        SetStartTime(Timeval startTime);
> > > 
> > >     // serialization method
> > >     static void	Pack	(IHXClientPacket* pPacket, char* pData, 
> > >     UINT32& ulSize);
> > >@@ -327,6 +333,12 @@
> > > ClientPacket::GetStartTime()
> > > {
> > >     return m_StartTime;
> > >+}
> > >+
> > >+inline void
> > >+ClientPacket::SetStartTime(Timeval startTime)
> > >+{
> > >+    m_StartTime = startTime;
> > > }
> > > 
> > > // serialization method
> > >
> > >Index: rtsp/rtspclnt.cpp
> > >===================================================================
> > >RCS file: /cvsroot/protocol/rtsp/rtspclnt.cpp,v
> > >retrieving revision 1.72
> > >diff -u -r1.72 rtspclnt.cpp
> > >--- rtsp/rtspclnt.cpp	18 Mar 2004 01:53:45 -0000	1.72
> > >+++ rtsp/rtspclnt.cpp	29 Mar 2004 20:41:09 -0000
> > >@@ -3183,8 +3183,6 @@
> > >     RTSPTransport* pTrans =
> > > 	(RTSPTransport*)(*m_pTransportStreamMap)[uStreamNumber];
> > > 
> > >-    HX_ASSERT(pTrans);
> > >-
> > >     rc = pTrans ?
> > > 	    pTrans->GetCurrentBuffering(uStreamNumber,
> > > 					llLowestTimestamp,
> > >@@ -4905,13 +4903,26 @@
> > >     status = handleSetupResponseExt(pStreamInfo, pMsg, pSetupMsg);
> > > 
> > >     UINT16 nStreamCount = (UINT16)m_streamInfoList.GetCount();
> > >+
> > >+    BOOL bSetupsDone = FALSE;
> > >+
> > >     if(m_setupResponseCount == 1 && (nStreamCount > 1))
> > >     {
> > >+        // Signal that we are done if we 
> > >+        // are pipelining RTSP messages
> > >+        bSetupsDone = PipelineRTSP();
> > >+
> > > 	// first time, send the rest...
> > > 	sendRemainingSetupRequests();
> > >     }
> > >+    else if (!PipelineRTSP())
> > >+    {
> > >+        // We only update bSetupsDone this way
> > >+        // if we are not pipelining RTSP messages.
> > >+        bSetupsDone = (m_setupResponseCount == nStreamCount);
> > >+    }
> > > 
> > >-    if(m_setupResponseCount == nStreamCount)
> > >+    if(bSetupsDone)
> > >     {
> > > 	// all done!
> > > 
> > >@@ -7620,6 +7631,15 @@
> > >     }
> > > 
> > >     return rc;
> > >+}
> > >+
> > >+BOOL RTSPClientProtocol::PipelineRTSP()
> > >+{
> > >+    BOOL bRet = FALSE;
> > >+
> > >+    ReadPrefBOOL(m_pPreferences, "PipelineRTSP", bRet);
> > >+
> > >+    return bRet;
> > > }
> > > 
> > > RTSPClientProtocol::UDPResponseHelper::UDPResponseHelper(RTSPClientProtocol* pParent, UINT16 nPort)
> > >Index: rtsp/pub/rtspclnt.h
> > >===================================================================
> > >RCS file: /cvsroot/protocol/rtsp/pub/rtspclnt.h,v
> > >retrieving revision 1.26
> > >diff -u -r1.26 rtspclnt.h
> > >--- rtsp/pub/rtspclnt.h	8 Mar 2004 19:49:24 -0000	1.26
> > >+++ rtsp/pub/rtspclnt.h	29 Mar 2004 20:41:09 -0000
> > >@@ -932,6 +932,8 @@
> > >                                     const char* pContent,
> > >                                     const char* pMimeType, UINT32 seqNo);
> > > 
> > >+    BOOL PipelineRTSP();
> > >+
> > >             HX_RESULT   ReportSuccessfulTransport(void);
> > > 
> > >     LONG32                              m_lRefCount;
> > >Index: transport/common/system/rtsptran.cpp
> > >===================================================================
> > >RCS file: /cvsroot/protocol/transport/common/system/rtsptran.cpp,v
> > >retrieving revision 1.24
> > >diff -u -r1.24 rtsptran.cpp
> > >--- transport/common/system/rtsptran.cpp	24 Feb 2004 19:53:31 -0000 
> > >1.24
> > >+++ transport/common/system/rtsptran.cpp	29 Mar 2004 20:41:09 -0000
> > >@@ -332,6 +332,7 @@
> > >     m_pPlayerState(NULL),
> > >     m_pPacketFilter(NULL),
> > >     m_pClientPacketList(NULL),
> > >+    m_pNoTransBufPktList(NULL),
> > >     m_bPrefetch(FALSE),
> > >     m_bFastStart(FALSE),
> > >     m_ulPlayRangeFrom(RTSP_PLAY_RANGE_BLANK),
> > >@@ -367,7 +368,8 @@
> > >     HX_RELEASE(m_pPacketFilter);
> > >     HX_RELEASE(m_pContext);
> > > 
> > >-    HX_DELETE(m_pClientPacketList);
> > >+    destroyPktList(m_pClientPacketList);
> > >+    destroyPktList(m_pNoTransBufPktList);
> > > }
> > > 
> > > void
> > >@@ -733,6 +735,7 @@
> > >     uStreamNumber = clientPacket->GetStreamNumber();
> > >     RTSPTransportBuffer* pTransportBuffer = 
> > >     getTransportBuffer(uStreamNumber);
> > >     pTransportBuffer->Add(clientPacket);
> > >+    HX_RELEASE(clientPacket);
> > > }
> > > 
> > > void RTSPTransport::GetContext(IUnknown*& pContext)   
> > >@@ -855,78 +858,134 @@
> > >                            UINT16 uReliableSeqNo,
> > >                            BOOL isReliable)
> > > {
> > >+    m_bIsReceivedData = TRUE;
> > >+
> > >+    ULONG32 ulPktSize = 0;
> > >+    IHXPacket* pPkt = NULL;
> > >+
> > >+    if (pPacket && !pPacket->IsLost())
> > >+    {
> > >+        IHXBuffer* pBuffer = pPacket->GetBuffer();
> > >+        
> > >+        if (pBuffer)
> > >+        {
> > >+            ulPktSize = pBuffer->GetSize();
> > >+        }
> > >+
> > >+        HX_RELEASE(pBuffer);
> > >+        
> > >+        pPkt = pPacket;
> > >+    }
> > >+
> > >     RTSPTransportBuffer* pTransportBuffer = 
> > >     getTransportBuffer(uStreamNumber);
> > >+    Timeval startTime;
> > > 
> > >-    if (!pTransportBuffer)
> > >+    if (pTransportBuffer)
> > >     {
> > >-	return HXR_FAIL;
> > >+        startTime = pTransportBuffer->GetTime();
> > >     }
> > > 
> > >-    ClientPacket* clientPacket = 0;
> > >+    HX_RESULT res = HXR_OUTOFMEMORY;
> > >+    ClientPacket* pClientPacket = new ClientPacket(uSeqNo, 
> > >+                                                   uReliableSeqNo,
> > >+                                                   pPacket->GetTime(), 
> > >+                                                   ulPktSize, 
> > >+                                                   isReliable,
> > >+                                                   pPkt, 
> > >+                                                   startTime, 
> > >+                                                   FALSE);
> > >     
> > >-    m_bIsReceivedData = TRUE;
> > >-
> > >-    if (pPacket->IsLost())
> > >+    if (pClientPacket)
> > >     {
> > >-        clientPacket = new ClientPacket(uSeqNo, uReliableSeqNo,
> > >-		                        pPacket->GetTime(), 0, isReliable,
> > >-		                        0, pTransportBuffer->GetTime(), 
> > >FALSE);
> > >-        if( !clientPacket )
> > >+        pClientPacket->AddRef();
> > >+
> > >+        if (pTransportBuffer)
> > >         {
> > >-            return HXR_OUTOFMEMORY;
> > >+            if (m_pNoTransBufPktList)
> > >+            {
> > >+                // We handle any packets received
> > >+                // when we didn't have a transport buffer
> > >+                // first.
> > >+                res = handleNoTransBufList(pTransportBuffer);
> > >+            }
> > >+            else
> > >+            {
> > >+                res = HXR_OK;
> > >+            }
> > >+            
> > >+            if (HXR_OK == res)
> > >+            {
> > >+                // Now store the packet for this call
> > >+                res = storeClientPacket(pTransportBuffer, pClientPacket);
> > >+            }
> > >         }
> > >+        else
> > >+        {
> > >+            // We don't have a transport buffer yet.
> > >+            // Queue the packet until we have one.
> > >+            if (!m_pNoTransBufPktList)
> > >+            {
> > >+                m_pNoTransBufPktList = new CHXSimpleList;
> > >+            }
> > > 
> > >-	clientPacket->AddRef();
> > >+            if (m_pNoTransBufPktList &&
> > >+                m_pNoTransBufPktList->AddTail(pClientPacket))
> > >+            {
> > >+                // We successfully queued the packet
> > >+                pClientPacket->AddRef();
> > >+                res = HXR_OK;
> > >+            }
> > >+        }
> > > 
> > >-	return pTransportBuffer->Add(clientPacket);
> > >+        HX_RELEASE(pClientPacket);
> > >     }
> > >-    
> > >-    IHXBuffer* pBuffer = pPacket->GetBuffer();
> > > 
> > >-    if (m_pPacketFilter)
> > >+    return res;
> > >+}
> > >+
> > >+HX_RESULT 
> > >+RTSPTransport::storeClientPacket(RTSPTransportBuffer* pTransportBuffer,
> > >+                                 ClientPacket* pClientPkt)
> > >+{
> > >+    HX_RESULT res = HXR_OUTOFMEMORY;
> > >+
> > >+    IHXPacket* pPkt = pClientPkt->GetPacket();
> > >+
> > >+    if (!pPkt)
> > >     {
> > >-	if (!m_pClientPacketList)
> > >-	{
> > >-	    m_pClientPacketList = new CHXSimpleList;
> > >-            if( !m_pClientPacketList )
> > >+        // This is a lost packet
> > >+        res = pTransportBuffer->Add(pClientPkt);
> > >+    }
> > >+    else if (m_pPacketFilter)
> > >+    {
> > >+        if (!m_pClientPacketList)
> > >+        {
> > >+            m_pClientPacketList = new CHXSimpleList;
> > >+
> > >+            if (m_pClientPacketList)
> > >             {
> > >-                return HXR_OUTOFMEMORY;
> > >+                m_pPacketFilter->SetFilterResponse(this);
> > >             }
> > >-	    m_pPacketFilter->SetFilterResponse(this);
> > >-	}
> > >-	clientPacket = new ClientPacket(uSeqNo, uReliableSeqNo,
> > >-		pPacket->GetTime(), pBuffer->GetSize(), isReliable,
> > >-		NULL, pTransportBuffer->GetTime(),
> > >-		FALSE);
> > >-        if( !clientPacket )
> > >-        {
> > >-            return HXR_OUTOFMEMORY;
> > >         }
> > >-	
> > >-	clientPacket->AddRef();
> > >-	pBuffer->Release();
> > > 
> > >-	m_pClientPacketList->AddHead((void*)clientPacket);
> > >-	m_pPacketFilter->FilterPacket(pPacket);
> > >+        if (m_pClientPacketList &&
> > >+            m_pClientPacketList->AddHead((void*)pClientPkt))
> > >+        {
> > >+            // Successfully added the client packet to the list
> > >+            pClientPkt->AddRef();
> > > 
> > >-	// just guessing on what this should be?????
> > >-        return HXR_OK;
> > >+            m_pPacketFilter->FilterPacket(pPkt);
> > >+            res = HXR_OK;
> > >+        }
> > >     }
> > >     else
> > >     {
> > >-       clientPacket = new ClientPacket(uSeqNo, uReliableSeqNo,
> > >-		pPacket->GetTime(), pBuffer->GetSize(), isReliable,
> > >-		pPacket, pTransportBuffer->GetTime(), FALSE);
> > >-        if( !clientPacket )
> > >-        {
> > >-            return HXR_OUTOFMEMORY;
> > >-        }
> > >+        res = pTransportBuffer->Add(pClientPkt);
> > >+    }
> > > 
> > >-	clientPacket->AddRef();
> > >-	pBuffer->Release();
> > >+    HX_RELEASE(pPkt);
> > > 
> > >-	return pTransportBuffer->Add(clientPacket);
> > >-    }
> > >+    return res;
> > > }
> > > 
> > > HX_RESULT			
> > >@@ -1759,3 +1818,50 @@
> > >     }
> > > }
> > > #endif	// RDT_MESSAGE_DEBUG
> > >+
> > >+HX_RESULT 
> > >+RTSPTransport::handleNoTransBufList(RTSPTransportBuffer* pTransportBuffer)
> > >+{
> > >+    HX_RESULT res = HXR_OK;
> > >+
> > >+    while ((HXR_OK == res) && !m_pNoTransBufPktList->IsEmpty())
> > >+    {
> > >+        ClientPacket* pTmpClientPkt = 
> > >+            (ClientPacket*)m_pNoTransBufPktList->RemoveHead();
> > >+        
> > >+        // Set the start time now that we have a 
> > >+        // transport buffer
> > >+        pTmpClientPkt->SetStartTime(pTransportBuffer->GetTime());
> > >+        
> > >+        // Store the packet
> > >+        res = storeClientPacket(pTransportBuffer, pTmpClientPkt);
> > >+        
> > >+        HX_RELEASE(pTmpClientPkt);
> > >+    }
> > >+    
> > >+    if (HXR_OK == res)
> > >+    {
> > >+        // Destroy the packet list now that it is
> > >+        // empty and we already have a transport 
> > >+        // buffer
> > >+        destroyPktList(m_pNoTransBufPktList);
> > >+    }
> > >+
> > >+    return res;
> > >+}
> > >+
> > >+void RTSPTransport::destroyPktList(REF(CHXSimpleList*) pList)
> > >+{
> > >+    if (pList)
> > >+    {
> > >+        while(!pList->IsEmpty())
> > >+        {
> > >+            ClientPacket* pPkt = 
> > >+                (ClientPacket*)pList->RemoveTail();
> > >+
> > >+            HX_RELEASE(pPkt);
> > >+        }
> > >+
> > >+        HX_DELETE(pList);
> > >+    }
> > >+}
> > >Index: transport/common/system/pub/rtsptran.h
> > >===================================================================
> > >RCS file: /cvsroot/protocol/transport/common/system/pub/rtsptran.h,v
> > >retrieving revision 1.18
> > >diff -u -r1.18 rtsptran.h
> > >--- transport/common/system/pub/rtsptran.h	2 Mar 2004 19:48:37 -0000 
> > >1.18
> > >+++ transport/common/system/pub/rtsptran.h	29 Mar 2004 20:41:09 -0000
> > >@@ -346,7 +346,13 @@
> > >     UINT32 GetTotalSuccessfulResends() { return 
> > >     m_ulTotalSuccessfulResends; }
> > >     UINT32 GetTotalFailedResends() { return m_ulTotalFailedResends; }
> > >     UINT32 GetSendingTime() { return m_ulSendingTime; }
> > >-        
> > >+
> > >+private:
> > >+    HX_RESULT handleNoTransBufList(RTSPTransportBuffer* pTransportBuffer);
> > >+    HX_RESULT storeClientPacket(RTSPTransportBuffer* pTransportBuffer,
> > >+                                ClientPacket* pClientPkt);
> > >+    void destroyPktList(REF(CHXSimpleList*) pList);
> > >+
> > > protected:
> > >     IUnknown*				m_pContext;
> > >     IHXCommonClassFactory*     		m_pCommonClassFactory;
> > >@@ -377,6 +383,7 @@
> > >     
> > >     RawPacketFilter*			m_pPacketFilter;
> > >     CHXSimpleList* 			m_pClientPacketList;
> > >+    CHXSimpleList* 			m_pNoTransBufPktList;
> > >     BOOL                                m_bPlayRequestSent;
> > > 
> > >     UINT32                              m_ulTotalSuccessfulResends; 
> > >
> > >_______________________________________________
> > >Protocol-dev mailing list
> > >Protocol-dev@lists.helixcommunity.org
> > >http://lists.helixcommunity.org/mailman/listinfo/protocol-dev
> > >
> > >
> 
> _______________________________________________
> Protocol-dev mailing list
> Protocol-dev@lists.helixcommunity.org
> http://lists.helixcommunity.org/mailman/listinfo/protocol-dev


From ping at real.com  Tue Mar 30 08:35:26 2004
From: ping at real.com (Henry Ping)
Date: Mon May 10 16:37:26 2004
Subject: [Common-dev] Re: [Protocol-dev] CR-Client: Pipelined RTSP changes
In-Reply-To: <20040330003227.GA13369@real.com>
References: <20040329221355.GA12774@real.com> <20040329213828.GA12753@real.com>
	<40689936.4020708@real.com> <20040329221355.GA12774@real.com>
Message-ID: <5.1.0.14.2.20040330082309.0367cba0@mailone.real.com>

Looks good.

Does HTTPCloaking work with this new support?

-->Henry

At 04:32 PM 3/29/2004 -0800, Aaron Colwell wrote:
>Sean,
>
>These changes also appear to work with Mobile Server 10.02. Here is an
>updated diff for rtspclnt.cpp. I discovered a bug related to streaming
>single stream files.
>
>Aaron
>
>Index: rtspclnt.cpp
>===================================================================
>RCS file: /cvsroot/protocol/rtsp/rtspclnt.cpp,v
>retrieving revision 1.72
>diff -u -r1.72 rtspclnt.cpp
>--- rtspclnt.cpp        18 Mar 2004 01:53:45 -0000      1.72
>+++ rtspclnt.cpp        30 Mar 2004 00:29:21 -0000
>@@ -3183,8 +3183,6 @@
>      RTSPTransport* pTrans =
>         (RTSPTransport*)(*m_pTransportStreamMap)[uStreamNumber];
>
>-    HX_ASSERT(pTrans);
>-
>      rc = pTrans ?
>             pTrans->GetCurrentBuffering(uStreamNumber,
>                                         llLowestTimestamp,
>@@ -4833,7 +4831,7 @@
>      UINT16 streamNumber = 0;
>      IHXValues* pReconnectValues = NULL;
>      RTSPStreamInfo* pStreamInfo = 0;
>-
>+
>      if(pMsg->errorCodeAsUINT32() == 401 || pMsg->errorCodeAsUINT32() == 407)
>      {
>         status = handleAuthentication(pMsg);
>@@ -4905,13 +4903,35 @@
>      status = handleSetupResponseExt(pStreamInfo, pMsg, pSetupMsg);
>
>      UINT16 nStreamCount = (UINT16)m_streamInfoList.GetCount();
>-    if(m_setupResponseCount == 1 && (nStreamCount > 1))
>+
>+    BOOL bSetupsDone = FALSE;
>+
>+    if(m_setupResponseCount == 1)
>+    {
>+        if (nStreamCount > 1)
>+        {
>+            // Signal that we are done if we
>+            // are pipelining RTSP messages
>+            bSetupsDone = PipelineRTSP();
>+
>+            // first time, send the rest...
>+            sendRemainingSetupRequests();
>+        }
>+        else
>+        {
>+            // Single stream case
>+            bSetupsDone = TRUE;
>+        }
>+    }
>+    else if (!PipelineRTSP())
>      {
>-       // first time, send the rest...
>-       sendRemainingSetupRequests();
>+        // We only update bSetupsDone this way
>+        // if we are not pipelining RTSP messages
>+        // and this isn't the first response
>+        bSetupsDone = (m_setupResponseCount == nStreamCount);
>      }
>
>-    if(m_setupResponseCount == nStreamCount)
>+    if(bSetupsDone)
>      {
>         // all done!
>
>@@ -7620,6 +7640,15 @@
>      }
>
>      return rc;
>+}
>+
>+BOOL RTSPClientProtocol::PipelineRTSP()
>+{
>+    BOOL bRet = FALSE;
>+
>+    ReadPrefBOOL(m_pPreferences, "PipelineRTSP", bRet);
>+
>+    return bRet;
>  }
>
> 
>RTSPClientProtocol::UDPResponseHelper::UDPResponseHelper(RTSPClientProtocol* 
>pParent, UINT16 nPort)
>
>
>
>On Mon, Mar 29, 2004 at 02:13:55PM -0800, Aaron Colwell wrote:
> > I tested this against Helix Server Version 9.0.3.916. I'll test this 
> against
> > Mobile 10.02 right now.
> >
> > Aaron
> >
> > On Mon, Mar 29, 2004 at 01:46:30PM -0800, Sean Robinson wrote:
> > > Which servers was this tested against?  We obviously need to make sure
> > > we test against the latest Mobile 10 release...
> > >
> > > Aaron Colwell wrote:
> > >
> > > >
> > > >Overview: These changes allow every SETUP message after the first 
> one to be
> > > >          pipelined with the Subscribe SET_PARAM and PLAY messages. The
> > > >          original code would wait for all the SETUP response messages
> > > >          before
> > > >          issuing the Subscribe SET_PARAM and PLAY messages. These 
> changes
> > > >          allow the SET_PARAM and PLAY to be sent before the SETUP
> > > >          responses
> > > >          arrive. This pipelining behavior is only turned on when the
> > > >          PipelineRTSP preference is set. If the preference is not 
> set or
> > > >          if it doesn't exist the player defaults to the old behavior.
> > > >
> > > >          Now that the SETUP and PLAY messages are pipelined, it is
> > > >          possible
> > > >          for data packets to arrive before the transport buffer is
> > > >          created.
> > > >          The transport buffer is created when the SETUP response 
> arrives
> > > >          for a stream. A packet queue was added to handle the case 
> where
> > > >          data packets arrive before the SETUP response does. This 
> queue
> > > >          only
> > > >          holds packets during a very short interval and is immediately
> > > >          emptied
> > > >          and destroyed once the transport buffer has been created.
> > > >
> > > >Files Modified:
> > > >common/util/pub/basepkt.h
> > > >protocol/rtsp/rtspclnt.cpp
> > > >protocol/rtsp/pub/rtspclnt.h
> > > >protocol/transport/common/system/rtsptran.cpp
> > > >protocol/transport/common/system/pub/rtsptran.h
> > > >
> > > >Files Added: none
> > > >
> > > >Image Size and Heap Use impact:
> > > >
> > > >Platforms and Profiles affected: all
> > > >
> > > >Distribution Libraries affected: rdtclntlib
> > > >
> > > >Distribution library impact and planned action:
> > > >A member variable was added to the transport base class. This changes
> > > >the layout of the RDT transport object so the distlib needs to be 
> updated.
> > > >
> > > >Platforms and Profiles Build Verified: win32 helix-client-all-defines
> > > >
> > > >Platforms and Profiles Functionality verified: win32
> > > >helix-client-all-defines
> > > >
> > > >Branch: HEAD
> > > >
> > > >QA Instructions: none
> > > >
> > > >Index: util/pub/basepkt.h
> > > >===================================================================
> > > >RCS file: /cvsroot/common/util/pub/basepkt.h,v
> > > >retrieving revision 1.5
> > > >diff -u -r1.5 basepkt.h
> > > >--- util/pub/basepkt.h     24 Sep 2003 18:45:39 -0000      1.5
> > > >+++ util/pub/basepkt.h     29 Mar 2004 20:42:45 -0000
> > > >@@ -111,6 +111,11 @@
> > > > inline void
> > > > BasePacket::SetPacket(IHXPacket* pPacket)
> > > > {
> > > >+    if (m_pPacket)
> > > >+    {
> > > >+        m_pPacket->Release();
> > > >+    }
> > > >+
> > > >     m_pPacket = pPacket;
> > > >
> > > >     if (m_pPacket)
> > > >@@ -255,6 +260,7 @@
> > > >     BOOL                  IsDroppedPacket();
> > > >     BOOL                  IsSanitizePacket();
> > > >     Timeval                       GetStartTime();
> > > >+    void                        SetStartTime(Timeval startTime);
> > > >
> > > >     // serialization method
> > > >     static void   Pack    (IHXClientPacket* pPacket, char* pData,
> > > >     UINT32& ulSize);
> > > >@@ -327,6 +333,12 @@
> > > > ClientPacket::GetStartTime()
> > > > {
> > > >     return m_StartTime;
> > > >+}
> > > >+
> > > >+inline void
> > > >+ClientPacket::SetStartTime(Timeval startTime)
> > > >+{
> > > >+    m_StartTime = startTime;
> > > > }
> > > >
> > > > // serialization method
> > > >
> > > >Index: rtsp/rtspclnt.cpp
> > > >===================================================================
> > > >RCS file: /cvsroot/protocol/rtsp/rtspclnt.cpp,v
> > > >retrieving revision 1.72
> > > >diff -u -r1.72 rtspclnt.cpp
> > > >--- rtsp/rtspclnt.cpp      18 Mar 2004 01:53:45 -0000      1.72
> > > >+++ rtsp/rtspclnt.cpp      29 Mar 2004 20:41:09 -0000
> > > >@@ -3183,8 +3183,6 @@
> > > >     RTSPTransport* pTrans =
> > > >   (RTSPTransport*)(*m_pTransportStreamMap)[uStreamNumber];
> > > >
> > > >-    HX_ASSERT(pTrans);
> > > >-
> > > >     rc = pTrans ?
> > > >       pTrans->GetCurrentBuffering(uStreamNumber,
> > > >                                   llLowestTimestamp,
> > > >@@ -4905,13 +4903,26 @@
> > > >     status = handleSetupResponseExt(pStreamInfo, pMsg, pSetupMsg);
> > > >
> > > >     UINT16 nStreamCount = (UINT16)m_streamInfoList.GetCount();
> > > >+
> > > >+    BOOL bSetupsDone = FALSE;
> > > >+
> > > >     if(m_setupResponseCount == 1 && (nStreamCount > 1))
> > > >     {
> > > >+        // Signal that we are done if we
> > > >+        // are pipelining RTSP messages
> > > >+        bSetupsDone = PipelineRTSP();
> > > >+
> > > >   // first time, send the rest...
> > > >   sendRemainingSetupRequests();
> > > >     }
> > > >+    else if (!PipelineRTSP())
> > > >+    {
> > > >+        // We only update bSetupsDone this way
> > > >+        // if we are not pipelining RTSP messages.
> > > >+        bSetupsDone = (m_setupResponseCount == nStreamCount);
> > > >+    }
> > > >
> > > >-    if(m_setupResponseCount == nStreamCount)
> > > >+    if(bSetupsDone)
> > > >     {
> > > >   // all done!
> > > >
> > > >@@ -7620,6 +7631,15 @@
> > > >     }
> > > >
> > > >     return rc;
> > > >+}
> > > >+
> > > >+BOOL RTSPClientProtocol::PipelineRTSP()
> > > >+{
> > > >+    BOOL bRet = FALSE;
> > > >+
> > > >+    ReadPrefBOOL(m_pPreferences, "PipelineRTSP", bRet);
> > > >+
> > > >+    return bRet;
> > > > }
> > > >
> > > > 
> RTSPClientProtocol::UDPResponseHelper::UDPResponseHelper(RTSPClientProtocol* 
> pParent, UINT16 nPort)
> > > >Index: rtsp/pub/rtspclnt.h
> > > >===================================================================
> > > >RCS file: /cvsroot/protocol/rtsp/pub/rtspclnt.h,v
> > > >retrieving revision 1.26
> > > >diff -u -r1.26 rtspclnt.h
> > > >--- rtsp/pub/rtspclnt.h    8 Mar 2004 19:49:24 -0000       1.26
> > > >+++ rtsp/pub/rtspclnt.h    29 Mar 2004 20:41:09 -0000
> > > >@@ -932,6 +932,8 @@
> > > >                                     const char* pContent,
> > > >                                     const char* pMimeType, UINT32 
> seqNo);
> > > >
> > > >+    BOOL PipelineRTSP();
> > > >+
> > > >             HX_RESULT   ReportSuccessfulTransport(void);
> > > >
> > > >     LONG32                              m_lRefCount;
> > > >Index: transport/common/system/rtsptran.cpp
> > > >===================================================================
> > > >RCS file: /cvsroot/protocol/transport/common/system/rtsptran.cpp,v
> > > >retrieving revision 1.24
> > > >diff -u -r1.24 rtsptran.cpp
> > > >--- transport/common/system/rtsptran.cpp   24 Feb 2004 19:53:31 -0000
> > > >1.24
> > > >+++ transport/common/system/rtsptran.cpp   29 Mar 2004 20:41:09 -0000
> > > >@@ -332,6 +332,7 @@
> > > >     m_pPlayerState(NULL),
> > > >     m_pPacketFilter(NULL),
> > > >     m_pClientPacketList(NULL),
> > > >+    m_pNoTransBufPktList(NULL),
> > > >     m_bPrefetch(FALSE),
> > > >     m_bFastStart(FALSE),
> > > >     m_ulPlayRangeFrom(RTSP_PLAY_RANGE_BLANK),
> > > >@@ -367,7 +368,8 @@
> > > >     HX_RELEASE(m_pPacketFilter);
> > > >     HX_RELEASE(m_pContext);
> > > >
> > > >-    HX_DELETE(m_pClientPacketList);
> > > >+    destroyPktList(m_pClientPacketList);
> > > >+    destroyPktList(m_pNoTransBufPktList);
> > > > }
> > > >
> > > > void
> > > >@@ -733,6 +735,7 @@
> > > >     uStreamNumber = clientPacket->GetStreamNumber();
> > > >     RTSPTransportBuffer* pTransportBuffer =
> > > >     getTransportBuffer(uStreamNumber);
> > > >     pTransportBuffer->Add(clientPacket);
> > > >+    HX_RELEASE(clientPacket);
> > > > }
> > > >
> > > > void RTSPTransport::GetContext(IUnknown*& pContext)
> > > >@@ -855,78 +858,134 @@
> > > >                            UINT16 uReliableSeqNo,
> > > >                            BOOL isReliable)
> > > > {
> > > >+    m_bIsReceivedData = TRUE;
> > > >+
> > > >+    ULONG32 ulPktSize = 0;
> > > >+    IHXPacket* pPkt = NULL;
> > > >+
> > > >+    if (pPacket && !pPacket->IsLost())
> > > >+    {
> > > >+        IHXBuffer* pBuffer = pPacket->GetBuffer();
> > > >+
> > > >+        if (pBuffer)
> > > >+        {
> > > >+            ulPktSize = pBuffer->GetSize();
> > > >+        }
> > > >+
> > > >+        HX_RELEASE(pBuffer);
> > > >+
> > > >+        pPkt = pPacket;
> > > >+    }
> > > >+
> > > >     RTSPTransportBuffer* pTransportBuffer =
> > > >     getTransportBuffer(uStreamNumber);
> > > >+    Timeval startTime;
> > > >
> > > >-    if (!pTransportBuffer)
> > > >+    if (pTransportBuffer)
> > > >     {
> > > >-  return HXR_FAIL;
> > > >+        startTime = pTransportBuffer->GetTime();
> > > >     }
> > > >
> > > >-    ClientPacket* clientPacket = 0;
> > > >+    HX_RESULT res = HXR_OUTOFMEMORY;
> > > >+    ClientPacket* pClientPacket = new ClientPacket(uSeqNo,
> > > >+                                                   uReliableSeqNo,
> > > >+                                                   pPacket->GetTime(),
> > > >+                                                   ulPktSize,
> > > >+                                                   isReliable,
> > > >+                                                   pPkt,
> > > >+                                                   startTime,
> > > >+                                                   FALSE);
> > > >
> > > >-    m_bIsReceivedData = TRUE;
> > > >-
> > > >-    if (pPacket->IsLost())
> > > >+    if (pClientPacket)
> > > >     {
> > > >-        clientPacket = new ClientPacket(uSeqNo, uReliableSeqNo,
> > > >-                                  pPacket->GetTime(), 0, isReliable,
> > > >-                                  0, pTransportBuffer->GetTime(),
> > > >FALSE);
> > > >-        if( !clientPacket )
> > > >+        pClientPacket->AddRef();
> > > >+
> > > >+        if (pTransportBuffer)
> > > >         {
> > > >-            return HXR_OUTOFMEMORY;
> > > >+            if (m_pNoTransBufPktList)
> > > >+            {
> > > >+                // We handle any packets received
> > > >+                // when we didn't have a transport buffer
> > > >+                // first.
> > > >+                res = handleNoTransBufList(pTransportBuffer);
> > > >+            }
> > > >+            else
> > > >+            {
> > > >+                res = HXR_OK;
> > > >+            }
> > > >+
> > > >+            if (HXR_OK == res)
> > > >+            {
> > > >+                // Now store the packet for this call
> > > >+                res = storeClientPacket(pTransportBuffer, 
> pClientPacket);
> > > >+            }
> > > >         }
> > > >+        else
> > > >+        {
> > > >+            // We don't have a transport buffer yet.
> > > >+            // Queue the packet until we have one.
> > > >+            if (!m_pNoTransBufPktList)
> > > >+            {
> > > >+                m_pNoTransBufPktList = new CHXSimpleList;
> > > >+            }
> > > >
> > > >-  clientPacket->AddRef();
> > > >+            if (m_pNoTransBufPktList &&
> > > >+                m_pNoTransBufPktList->AddTail(pClientPacket))
> > > >+            {
> > > >+                // We successfully queued the packet
> > > >+                pClientPacket->AddRef();
> > > >+                res = HXR_OK;
> > > >+            }
> > > >+        }
> > > >
> > > >-  return pTransportBuffer->Add(clientPacket);
> > > >+        HX_RELEASE(pClientPacket);
> > > >     }
> > > >-
> > > >-    IHXBuffer* pBuffer = pPacket->GetBuffer();
> > > >
> > > >-    if (m_pPacketFilter)
> > > >+    return res;
> > > >+}
> > > >+
> > > >+HX_RESULT
> > > >+RTSPTransport::storeClientPacket(RTSPTransportBuffer* pTransportBuffer,
> > > >+                                 ClientPacket* pClientPkt)
> > > >+{
> > > >+    HX_RESULT res = HXR_OUTOFMEMORY;
> > > >+
> > > >+    IHXPacket* pPkt = pClientPkt->GetPacket();
> > > >+
> > > >+    if (!pPkt)
> > > >     {
> > > >-  if (!m_pClientPacketList)
> > > >-  {
> > > >-      m_pClientPacketList = new CHXSimpleList;
> > > >-            if( !m_pClientPacketList )
> > > >+        // This is a lost packet
> > > >+        res = pTransportBuffer->Add(pClientPkt);
> > > >+    }
> > > >+    else if (m_pPacketFilter)
> > > >+    {
> > > >+        if (!m_pClientPacketList)
> > > >+        {
> > > >+            m_pClientPacketList = new CHXSimpleList;
> > > >+
> > > >+            if (m_pClientPacketList)
> > > >             {
> > > >-                return HXR_OUTOFMEMORY;
> > > >+                m_pPacketFilter->SetFilterResponse(this);
> > > >             }
> > > >-      m_pPacketFilter->SetFilterResponse(this);
> > > >-  }
> > > >-  clientPacket = new ClientPacket(uSeqNo, uReliableSeqNo,
> > > >-          pPacket->GetTime(), pBuffer->GetSize(), isReliable,
> > > >-          NULL, pTransportBuffer->GetTime(),
> > > >-          FALSE);
> > > >-        if( !clientPacket )
> > > >-        {
> > > >-            return HXR_OUTOFMEMORY;
> > > >         }
> > > >-
> > > >-  clientPacket->AddRef();
> > > >-  pBuffer->Release();
> > > >
> > > >-  m_pClientPacketList->AddHead((void*)clientPacket);
> > > >-  m_pPacketFilter->FilterPacket(pPacket);
> > > >+        if (m_pClientPacketList &&
> > > >+            m_pClientPacketList->AddHead((void*)pClientPkt))
> > > >+        {
> > > >+            // Successfully added the client packet to the list
> > > >+            pClientPkt->AddRef();
> > > >
> > > >-  // just guessing on what this should be?????
> > > >-        return HXR_OK;
> > > >+            m_pPacketFilter->FilterPacket(pPkt);
> > > >+            res = HXR_OK;
> > > >+        }
> > > >     }
> > > >     else
> > > >     {
> > > >-       clientPacket = new ClientPacket(uSeqNo, uReliableSeqNo,
> > > >-          pPacket->GetTime(), pBuffer->GetSize(), isReliable,
> > > >-          pPacket, pTransportBuffer->GetTime(), FALSE);
> > > >-        if( !clientPacket )
> > > >-        {
> > > >-            return HXR_OUTOFMEMORY;
> > > >-        }
> > > >+        res = pTransportBuffer->Add(pClientPkt);
> > > >+    }
> > > >
> > > >-  clientPacket->AddRef();
> > > >-  pBuffer->Release();
> > > >+    HX_RELEASE(pPkt);
> > > >
> > > >-  return pTransportBuffer->Add(clientPacket);
> > > >-    }
> > > >+    return res;
> > > > }
> > > >
> > > > HX_RESULT
> > > >@@ -1759,3 +1818,50 @@
> > > >     }
> > > > }
> > > > #endif    // RDT_MESSAGE_DEBUG
> > > >+
> > > >+HX_RESULT
> > > >+RTSPTransport::handleNoTransBufList(RTSPTransportBuffer* 
> pTransportBuffer)
> > > >+{
> > > >+    HX_RESULT res = HXR_OK;
> > > >+
> > > >+    while ((HXR_OK == res) && !m_pNoTransBufPktList->IsEmpty())
> > > >+    {
> > > >+        ClientPacket* pTmpClientPkt =
> > > >+            (ClientPacket*)m_pNoTransBufPktList->RemoveHead();
> > > >+
> > > >+        // Set the start time now that we have a
> > > >+        // transport buffer
> > > >+        pTmpClientPkt->SetStartTime(pTransportBuffer->GetTime());
> > > >+
> > > >+        // Store the packet
> > > >+        res = storeClientPacket(pTransportBuffer, pTmpClientPkt);
> > > >+
> > > >+        HX_RELEASE(pTmpClientPkt);
> > > >+    }
> > > >+
> > > >+    if (HXR_OK == res)
> > > >+    {
> > > >+        // Destroy the packet list now that it is
> > > >+        // empty and we already have a transport
> > > >+        // buffer
> > > >+        destroyPktList(m_pNoTransBufPktList);
> > > >+    }
> > > >+
> > > >+    return res;
> > > >+}
> > > >+
> > > >+void RTSPTransport::destroyPktList(REF(CHXSimpleList*) pList)
> > > >+{
> > > >+    if (pList)
> > > >+    {
> > > >+        while(!pList->IsEmpty())
> > > >+        {
> > > >+            ClientPacket* pPkt =
> > > >+                (ClientPacket*)pList->RemoveTail();
> > > >+
> > > >+            HX_RELEASE(pPkt);
> > > >+        }
> > > >+
> > > >+        HX_DELETE(pList);
> > > >+    }
> > > >+}
> > > >Index: transport/common/system/pub/rtsptran.h
> > > >===================================================================
> > > >RCS file: /cvsroot/protocol/transport/common/system/pub/rtsptran.h,v
> > > >retrieving revision 1.18
> > > >diff -u -r1.18 rtsptran.h
> > > >--- transport/common/system/pub/rtsptran.h 2 Mar 2004 19:48:37 -0000
> > > >1.18
> > > >+++ transport/common/system/pub/rtsptran.h 29 Mar 2004 20:41:09 -0000
> > > >@@ -346,7 +346,13 @@
> > > >     UINT32 GetTotalSuccessfulResends() { return
> > > >     m_ulTotalSuccessfulResends; }
> > > >     UINT32 GetTotalFailedResends() { return m_ulTotalFailedResends; }
> > > >     UINT32 GetSendingTime() { return m_ulSendingTime; }
> > > >-
> > > >+
> > > >+private:
> > > >+    HX_RESULT handleNoTransBufList(RTSPTransportBuffer* 
> pTransportBuffer);
> > > >+    HX_RESULT storeClientPacket(RTSPTransportBuffer* pTransportBuffer,
> > > >+                                ClientPacket* pClientPkt);
> > > >+    void destroyPktList(REF(CHXSimpleList*) pList);
> > > >+
> > > > protected:
> > > >     IUnknown*                             m_pContext;
> > > >     IHXCommonClassFactory*                m_pCommonClassFactory;
> > > >@@ -377,6 +383,7 @@
> > > >
> > > >     RawPacketFilter*                      m_pPacketFilter;
> > > >     CHXSimpleList*                        m_pClientPacketList;
> > > >+    CHXSimpleList*                        m_pNoTransBufPktList;
> > > >     BOOL                                m_bPlayRequestSent;
> > > >
> > > >     UINT32                              m_ulTotalSuccessfulResends;
> > > >
> > > >_______________________________________________
> > > >Protocol-dev mailing list
> > > >Protocol-dev@lists.helixcommunity.org
> > > >http://lists.helixcommunity.org/mailman/listinfo/protocol-dev
> > > >
> > > >
> >
> > _______________________________________________
> > Protocol-dev mailing list
> > Protocol-dev@lists.helixcommunity.org
> > http://lists.helixcommunity.org/mailman/listinfo/protocol-dev
>
>_______________________________________________
>Common-dev mailing list
>Common-dev@lists.helixcommunity.org
>http://lists.helixcommunity.org/mailman/listinfo/common-dev



From acolwell at real.com  Tue Mar 30 10:34:13 2004
From: acolwell at real.com (Aaron Colwell)
Date: Mon May 10 16:37:26 2004
Subject: [Protocol-dev] CN-Client: Pipelined RTSP changes
In-Reply-To: <5.1.0.14.2.20040330082309.0367cba0@mailone.real.com>
References: <20040329221355.GA12774@real.com>
	<20040329213828.GA12753@real.com> <40689936.4020708@real.com>
	<20040329221355.GA12774@real.com>
	<5.1.0.14.2.20040330082309.0367cba0@mailone.real.com>
Message-ID: <20040330183413.GC15180@real.com>

Modified by: acolwell@real.com
 
Reviewed by: ping@real.com
 
Date: 03:30:2004
 
Project: HEAD


Aaron

On Tue, Mar 30, 2004 at 08:35:26AM -0800, Henry Ping wrote:
> Looks good.
> 
> Does HTTPCloaking work with this new support?
> 
> -->Henry
> 
> At 04:32 PM 3/29/2004 -0800, Aaron Colwell wrote:
> >Sean,
> >
> >These changes also appear to work with Mobile Server 10.02. Here is an
> >updated diff for rtspclnt.cpp. I discovered a bug related to streaming
> >single stream files.
> >
> >Aaron
> >
> >Index: rtspclnt.cpp
> >===================================================================
> >RCS file: /cvsroot/protocol/rtsp/rtspclnt.cpp,v
> >retrieving revision 1.72
> >diff -u -r1.72 rtspclnt.cpp
> >--- rtspclnt.cpp        18 Mar 2004 01:53:45 -0000      1.72
> >+++ rtspclnt.cpp        30 Mar 2004 00:29:21 -0000
> >@@ -3183,8 +3183,6 @@
> >     RTSPTransport* pTrans =
> >        (RTSPTransport*)(*m_pTransportStreamMap)[uStreamNumber];
> >
> >-    HX_ASSERT(pTrans);
> >-
> >     rc = pTrans ?
> >            pTrans->GetCurrentBuffering(uStreamNumber,
> >                                        llLowestTimestamp,
> >@@ -4833,7 +4831,7 @@
> >     UINT16 streamNumber = 0;
> >     IHXValues* pReconnectValues = NULL;
> >     RTSPStreamInfo* pStreamInfo = 0;
> >-
> >+
> >     if(pMsg->errorCodeAsUINT32() == 401 || pMsg->errorCodeAsUINT32() == 
> >     407)
> >     {
> >        status = handleAuthentication(pMsg);
> >@@ -4905,13 +4903,35 @@
> >     status = handleSetupResponseExt(pStreamInfo, pMsg, pSetupMsg);
> >
> >     UINT16 nStreamCount = (UINT16)m_streamInfoList.GetCount();
> >-    if(m_setupResponseCount == 1 && (nStreamCount > 1))
> >+
> >+    BOOL bSetupsDone = FALSE;
> >+
> >+    if(m_setupResponseCount == 1)
> >+    {
> >+        if (nStreamCount > 1)
> >+        {
> >+            // Signal that we are done if we
> >+            // are pipelining RTSP messages
> >+            bSetupsDone = PipelineRTSP();
> >+
> >+            // first time, send the rest...
> >+            sendRemainingSetupRequests();
> >+        }
> >+        else
> >+        {
> >+            // Single stream case
> >+            bSetupsDone = TRUE;
> >+        }
> >+    }
> >+    else if (!PipelineRTSP())
> >     {
> >-       // first time, send the rest...
> >-       sendRemainingSetupRequests();
> >+        // We only update bSetupsDone this way
> >+        // if we are not pipelining RTSP messages
> >+        // and this isn't the first response
> >+        bSetupsDone = (m_setupResponseCount == nStreamCount);
> >     }
> >
> >-    if(m_setupResponseCount == nStreamCount)
> >+    if(bSetupsDone)
> >     {
> >        // all done!
> >
> >@@ -7620,6 +7640,15 @@
> >     }
> >
> >     return rc;
> >+}
> >+
> >+BOOL RTSPClientProtocol::PipelineRTSP()
> >+{
> >+    BOOL bRet = FALSE;
> >+
> >+    ReadPrefBOOL(m_pPreferences, "PipelineRTSP", bRet);
> >+
> >+    return bRet;
> > }
> >
> >
> >RTSPClientProtocol::UDPResponseHelper::UDPResponseHelper(RTSPClientProtocol* 
> >pParent, UINT16 nPort)
> >
> >
> >
> >On Mon, Mar 29, 2004 at 02:13:55PM -0800, Aaron Colwell wrote:
> >> I tested this against Helix Server Version 9.0.3.916. I'll test this 
> >against
> >> Mobile 10.02 right now.
> >>
> >> Aaron
> >>
> >> On Mon, Mar 29, 2004 at 01:46:30PM -0800, Sean Robinson wrote:
> >> > Which servers was this tested against?  We obviously need to make sure
> >> > we test against the latest Mobile 10 release...
> >> >
> >> > Aaron Colwell wrote:
> >> >
> >> > >
> >> > >Overview: These changes allow every SETUP message after the first 
> >one to be
> >> > >          pipelined with the Subscribe SET_PARAM and PLAY messages. 
> >The
> >> > >          original code would wait for all the SETUP response messages
> >> > >          before
> >> > >          issuing the Subscribe SET_PARAM and PLAY messages. These 
> >changes
> >> > >          allow the SET_PARAM and PLAY to be sent before the SETUP
> >> > >          responses
> >> > >          arrive. This pipelining behavior is only turned on when the
> >> > >          PipelineRTSP preference is set. If the preference is not 
> >set or
> >> > >          if it doesn't exist the player defaults to the old behavior.
> >> > >
> >> > >          Now that the SETUP and PLAY messages are pipelined, it is
> >> > >          possible
> >> > >          for data packets to arrive before the transport buffer is
> >> > >          created.
> >> > >          The transport buffer is created when the SETUP response 
> >arrives
> >> > >          for a stream. A packet queue was added to handle the case 
> >where
> >> > >          data packets arrive before the SETUP response does. This 
> >queue
> >> > >          only
> >> > >          holds packets during a very short interval and is 
> >immediately
> >> > >          emptied
> >> > >          and destroyed once the transport buffer has been created.
> >> > >
> >> > >Files Modified:
> >> > >common/util/pub/basepkt.h
> >> > >protocol/rtsp/rtspclnt.cpp
> >> > >protocol/rtsp/pub/rtspclnt.h
> >> > >protocol/transport/common/system/rtsptran.cpp
> >> > >protocol/transport/common/system/pub/rtsptran.h
> >> > >
> >> > >Files Added: none
> >> > >
> >> > >Image Size and Heap Use impact:
> >> > >
> >> > >Platforms and Profiles affected: all
> >> > >
> >> > >Distribution Libraries affected: rdtclntlib
> >> > >
> >> > >Distribution library impact and planned action:
> >> > >A member variable was added to the transport base class. This changes
> >> > >the layout of the RDT transport object so the distlib needs to be 
> >updated.
> >> > >
> >> > >Platforms and Profiles Build Verified: win32 helix-client-all-defines
> >> > >
> >> > >Platforms and Profiles Functionality verified: win32
> >> > >helix-client-all-defines
> >> > >
> >> > >Branch: HEAD
> >> > >
> >> > >QA Instructions: none
> >> > >
> >> > >Index: util/pub/basepkt.h
> >> > >===================================================================
> >> > >RCS file: /cvsroot/common/util/pub/basepkt.h,v
> >> > >retrieving revision 1.5
> >> > >diff -u -r1.5 basepkt.h
> >> > >--- util/pub/basepkt.h     24 Sep 2003 18:45:39 -0000      1.5
> >> > >+++ util/pub/basepkt.h     29 Mar 2004 20:42:45 -0000
> >> > >@@ -111,6 +111,11 @@
> >> > > inline void
> >> > > BasePacket::SetPacket(IHXPacket* pPacket)
> >> > > {
> >> > >+    if (m_pPacket)
> >> > >+    {
> >> > >+        m_pPacket->Release();
> >> > >+    }
> >> > >+
> >> > >     m_pPacket = pPacket;
> >> > >
> >> > >     if (m_pPacket)
> >> > >@@ -255,6 +260,7 @@
> >> > >     BOOL                  IsDroppedPacket();
> >> > >     BOOL                  IsSanitizePacket();
> >> > >     Timeval                       GetStartTime();
> >> > >+    void                        SetStartTime(Timeval startTime);
> >> > >
> >> > >     // serialization method
> >> > >     static void   Pack    (IHXClientPacket* pPacket, char* pData,
> >> > >     UINT32& ulSize);
> >> > >@@ -327,6 +333,12 @@
> >> > > ClientPacket::GetStartTime()
> >> > > {
> >> > >     return m_StartTime;
> >> > >+}
> >> > >+
> >> > >+inline void
> >> > >+ClientPacket::SetStartTime(Timeval startTime)
> >> > >+{
> >> > >+    m_StartTime = startTime;
> >> > > }
> >> > >
> >> > > // serialization method
> >> > >
> >> > >Index: rtsp/rtspclnt.cpp
> >> > >===================================================================
> >> > >RCS file: /cvsroot/protocol/rtsp/rtspclnt.cpp,v
> >> > >retrieving revision 1.72
> >> > >diff -u -r1.72 rtspclnt.cpp
> >> > >--- rtsp/rtspclnt.cpp      18 Mar 2004 01:53:45 -0000      1.72
> >> > >+++ rtsp/rtspclnt.cpp      29 Mar 2004 20:41:09 -0000
> >> > >@@ -3183,8 +3183,6 @@
> >> > >     RTSPTransport* pTrans =
> >> > >   (RTSPTransport*)(*m_pTransportStreamMap)[uStreamNumber];
> >> > >
> >> > >-    HX_ASSERT(pTrans);
> >> > >-
> >> > >     rc = pTrans ?
> >> > >       pTrans->GetCurrentBuffering(uStreamNumber,
> >> > >                                   llLowestTimestamp,
> >> > >@@ -4905,13 +4903,26 @@
> >> > >     status = handleSetupResponseExt(pStreamInfo, pMsg, pSetupMsg);
> >> > >
> >> > >     UINT16 nStreamCount = (UINT16)m_streamInfoList.GetCount();
> >> > >+
> >> > >+    BOOL bSetupsDone = FALSE;
> >> > >+
> >> > >     if(m_setupResponseCount == 1 && (nStreamCount > 1))
> >> > >     {
> >> > >+        // Signal that we are done if we
> >> > >+        // are pipelining RTSP messages
> >> > >+        bSetupsDone = PipelineRTSP();
> >> > >+
> >> > >   // first time, send the rest...
> >> > >   sendRemainingSetupRequests();
> >> > >     }
> >> > >+    else if (!PipelineRTSP())
> >> > >+    {
> >> > >+        // We only update bSetupsDone this way
> >> > >+        // if we are not pipelining RTSP messages.
> >> > >+        bSetupsDone = (m_setupResponseCount == nStreamCount);
> >> > >+    }
> >> > >
> >> > >-    if(m_setupResponseCount == nStreamCount)
> >> > >+    if(bSetupsDone)
> >> > >     {
> >> > >   // all done!
> >> > >
> >> > >@@ -7620,6 +7631,15 @@
> >> > >     }
> >> > >
> >> > >     return rc;
> >> > >+}
> >> > >+
> >> > >+BOOL RTSPClientProtocol::PipelineRTSP()
> >> > >+{
> >> > >+    BOOL bRet = FALSE;
> >> > >+
> >> > >+    ReadPrefBOOL(m_pPreferences, "PipelineRTSP", bRet);
> >> > >+
> >> > >+    return bRet;
> >> > > }
> >> > >
> >> > > 
> >RTSPClientProtocol::UDPResponseHelper::UDPResponseHelper(RTSPClientProtocol* 
> >pParent, UINT16 nPort)
> >> > >Index: rtsp/pub/rtspclnt.h
> >> > >===================================================================
> >> > >RCS file: /cvsroot/protocol/rtsp/pub/rtspclnt.h,v
> >> > >retrieving revision 1.26
> >> > >diff -u -r1.26 rtspclnt.h
> >> > >--- rtsp/pub/rtspclnt.h    8 Mar 2004 19:49:24 -0000       1.26
> >> > >+++ rtsp/pub/rtspclnt.h    29 Mar 2004 20:41:09 -0000
> >> > >@@ -932,6 +932,8 @@
> >> > >                                     const char* pContent,
> >> > >                                     const char* pMimeType, UINT32 
> >seqNo);
> >> > >
> >> > >+    BOOL PipelineRTSP();
> >> > >+
> >> > >             HX_RESULT   ReportSuccessfulTransport(void);
> >> > >
> >> > >     LONG32                              m_lRefCount;
> >> > >Index: transport/common/system/rtsptran.cpp
> >> > >===================================================================
> >> > >RCS file: /cvsroot/protocol/transport/common/system/rtsptran.cpp,v
> >> > >retrieving revision 1.24
> >> > >diff -u -r1.24 rtsptran.cpp
> >> > >--- transport/common/system/rtsptran.cpp   24 Feb 2004 19:53:31 -0000
> >> > >1.24
> >> > >+++ transport/common/system/rtsptran.cpp   29 Mar 2004 20:41:09 -0000
> >> > >@@ -332,6 +332,7 @@
> >> > >     m_pPlayerState(NULL),
> >> > >     m_pPacketFilter(NULL),
> >> > >     m_pClientPacketList(NULL),
> >> > >+    m_pNoTransBufPktList(NULL),
> >> > >     m_bPrefetch(FALSE),
> >> > >     m_bFastStart(FALSE),
> >> > >     m_ulPlayRangeFrom(RTSP_PLAY_RANGE_BLANK),
> >> > >@@ -367,7 +368,8 @@
> >> > >     HX_RELEASE(m_pPacketFilter);
> >> > >     HX_RELEASE(m_pContext);
> >> > >
> >> > >-    HX_DELETE(m_pClientPacketList);
> >> > >+    destroyPktList(m_pClientPacketList);
> >> > >+    destroyPktList(m_pNoTransBufPktList);
> >> > > }
> >> > >
> >> > > void
> >> > >@@ -733,6 +735,7 @@
> >> > >     uStreamNumber = clientPacket->GetStreamNumber();
> >> > >     RTSPTransportBuffer* pTransportBuffer =
> >> > >     getTransportBuffer(uStreamNumber);
> >> > >     pTransportBuffer->Add(clientPacket);
> >> > >+    HX_RELEASE(clientPacket);
> >> > > }
> >> > >
> >> > > void RTSPTransport::GetContext(IUnknown*& pContext)
> >> > >@@ -855,78 +858,134 @@
> >> > >                            UINT16 uReliableSeqNo,
> >> > >                            BOOL isReliable)
> >> > > {
> >> > >+    m_bIsReceivedData = TRUE;
> >> > >+
> >> > >+    ULONG32 ulPktSize = 0;
> >> > >+    IHXPacket* pPkt = NULL;
> >> > >+
> >> > >+    if (pPacket && !pPacket->IsLost())
> >> > >+    {
> >> > >+        IHXBuffer* pBuffer = pPacket->GetBuffer();
> >> > >+
> >> > >+        if (pBuffer)
> >> > >+        {
> >> > >+            ulPktSize = pBuffer->GetSize();
> >> > >+        }
> >> > >+
> >> > >+        HX_RELEASE(pBuffer);
> >> > >+
> >> > >+        pPkt = pPacket;
> >> > >+    }
> >> > >+
> >> > >     RTSPTransportBuffer* pTransportBuffer =
> >> > >     getTransportBuffer(uStreamNumber);
> >> > >+    Timeval startTime;
> >> > >
> >> > >-    if (!pTransportBuffer)
> >> > >+    if (pTransportBuffer)
> >> > >     {
> >> > >-  return HXR_FAIL;
> >> > >+        startTime = pTransportBuffer->GetTime();
> >> > >     }
> >> > >
> >> > >-    ClientPacket* clientPacket = 0;
> >> > >+    HX_RESULT res = HXR_OUTOFMEMORY;
> >> > >+    ClientPacket* pClientPacket = new ClientPacket(uSeqNo,
> >> > >+                                                   uReliableSeqNo,
> >> > >+                                                   
> >pPacket->GetTime(),
> >> > >+                                                   ulPktSize,
> >> > >+                                                   isReliable,
> >> > >+                                                   pPkt,
> >> > >+                                                   startTime,
> >> > >+                                                   FALSE);
> >> > >
> >> > >-    m_bIsReceivedData = TRUE;
> >> > >-
> >> > >-    if (pPacket->IsLost())
> >> > >+    if (pClientPacket)
> >> > >     {
> >> > >-        clientPacket = new ClientPacket(uSeqNo, uReliableSeqNo,
> >> > >-                                  pPacket->GetTime(), 0, isReliable,
> >> > >-                                  0, pTransportBuffer->GetTime(),
> >> > >FALSE);
> >> > >-        if( !clientPacket )
> >> > >+        pClientPacket->AddRef();
> >> > >+
> >> > >+        if (pTransportBuffer)
> >> > >         {
> >> > >-            return HXR_OUTOFMEMORY;
> >> > >+            if (m_pNoTransBufPktList)
> >> > >+            {
> >> > >+                // We handle any packets received
> >> > >+                // when we didn't have a transport buffer
> >> > >+                // first.
> >> > >+                res = handleNoTransBufList(pTransportBuffer);
> >> > >+            }
> >> > >+            else
> >> > >+            {
> >> > >+                res = HXR_OK;
> >> > >+            }
> >> > >+
> >> > >+            if (HXR_OK == res)
> >> > >+            {
> >> > >+                // Now store the packet for this call
> >> > >+                res = storeClientPacket(pTransportBuffer, 
> >pClientPacket);
> >> > >+            }
> >> > >         }
> >> > >+        else
> >> > >+        {
> >> > >+            // We don't have a transport buffer yet.
> >> > >+            // Queue the packet until we have one.
> >> > >+            if (!m_pNoTransBufPktList)
> >> > >+            {
> >> > >+                m_pNoTransBufPktList = new CHXSimpleList;
> >> > >+            }
> >> > >
> >> > >-  clientPacket->AddRef();
> >> > >+            if (m_pNoTransBufPktList &&
> >> > >+                m_pNoTransBufPktList->AddTail(pClientPacket))
> >> > >+            {
> >> > >+                // We successfully queued the packet
> >> > >+                pClientPacket->AddRef();
> >> > >+                res = HXR_OK;
> >> > >+            }
> >> > >+        }
> >> > >
> >> > >-  return pTransportBuffer->Add(clientPacket);
> >> > >+        HX_RELEASE(pClientPacket);
> >> > >     }
> >> > >-
> >> > >-    IHXBuffer* pBuffer = pPacket->GetBuffer();
> >> > >
> >> > >-    if (m_pPacketFilter)
> >> > >+    return res;
> >> > >+}
> >> > >+
> >> > >+HX_RESULT
> >> > >+RTSPTransport::storeClientPacket(RTSPTransportBuffer* 
> >pTransportBuffer,
> >> > >+                                 ClientPacket* pClientPkt)
> >> > >+{
> >> > >+    HX_RESULT res = HXR_OUTOFMEMORY;
> >> > >+
> >> > >+    IHXPacket* pPkt = pClientPkt->GetPacket();
> >> > >+
> >> > >+    if (!pPkt)
> >> > >     {
> >> > >-  if (!m_pClientPacketList)
> >> > >-  {
> >> > >-      m_pClientPacketList = new CHXSimpleList;
> >> > >-            if( !m_pClientPacketList )
> >> > >+        // This is a lost packet
> >> > >+        res = pTransportBuffer->Add(pClientPkt);
> >> > >+    }
> >> > >+    else if (m_pPacketFilter)
> >> > >+    {
> >> > >+        if (!m_pClientPacketList)
> >> > >+        {
> >> > >+            m_pClientPacketList = new CHXSimpleList;
> >> > >+
> >> > >+            if (m_pClientPacketList)
> >> > >             {
> >> > >-                return HXR_OUTOFMEMORY;
> >> > >+                m_pPacketFilter->SetFilterResponse(this);
> >> > >             }
> >> > >-      m_pPacketFilter->SetFilterResponse(this);
> >> > >-  }
> >> > >-  clientPacket = new ClientPacket(uSeqNo, uReliableSeqNo,
> >> > >-          pPacket->GetTime(), pBuffer->GetSize(), isReliable,
> >> > >-          NULL, pTransportBuffer->GetTime(),
> >> > >-          FALSE);
> >> > >-        if( !clientPacket )
> >> > >-        {
> >> > >-            return HXR_OUTOFMEMORY;
> >> > >         }
> >> > >-
> >> > >-  clientPacket->AddRef();
> >> > >-  pBuffer->Release();
> >> > >
> >> > >-  m_pClientPacketList->AddHead((void*)clientPacket);
> >> > >-  m_pPacketFilter->FilterPacket(pPacket);
> >> > >+        if (m_pClientPacketList &&
> >> > >+            m_pClientPacketList->AddHead((void*)pClientPkt))
> >> > >+        {
> >> > >+            // Successfully added the client packet to the list
> >> > >+            pClientPkt->AddRef();
> >> > >
> >> > >-  // just guessing on what this should be?????
> >> > >-        return HXR_OK;
> >> > >+            m_pPacketFilter->FilterPacket(pPkt);
> >> > >+            res = HXR_OK;
> >> > >+        }
> >> > >     }
> >> > >     else
> >> > >     {
> >> > >-       clientPacket = new ClientPacket(uSeqNo, uReliableSeqNo,
> >> > >-          pPacket->GetTime(), pBuffer->GetSize(), isReliable,
> >> > >-          pPacket, pTransportBuffer->GetTime(), FALSE);
> >> > >-        if( !clientPacket )
> >> > >-        {
> >> > >-            return HXR_OUTOFMEMORY;
> >> > >-        }
> >> > >+        res = pTransportBuffer->Add(pClientPkt);
> >> > >+    }
> >> > >
> >> > >-  clientPacket->AddRef();
> >> > >-  pBuffer->Release();
> >> > >+    HX_RELEASE(pPkt);
> >> > >
> >> > >-  return pTransportBuffer->Add(clientPacket);
> >> > >-    }
> >> > >+    return res;
> >> > > }
> >> > >
> >> > > HX_RESULT
> >> > >@@ -1759,3 +1818,50 @@
> >> > >     }
> >> > > }
> >> > > #endif    // RDT_MESSAGE_DEBUG
> >> > >+
> >> > >+HX_RESULT
> >> > >+RTSPTransport::handleNoTransBufList(RTSPTransportBuffer* 
> >pTransportBuffer)
> >> > >+{
> >> > >+    HX_RESULT res = HXR_OK;
> >> > >+
> >> > >+    while ((HXR_OK == res) && !m_pNoTransBufPktList->IsEmpty())
> >> > >+    {
> >> > >+        ClientPacket* pTmpClientPkt =
> >> > >+            (ClientPacket*)m_pNoTransBufPktList->RemoveHead();
> >> > >+
> >> > >+        // Set the start time now that we have a
> >> > >+        // transport buffer
> >> > >+        pTmpClientPkt->SetStartTime(pTransportBuffer->GetTime());
> >> > >+
> >> > >+        // Store the packet
> >> > >+        res = storeClientPacket(pTransportBuffer, pTmpClientPkt);
> >> > >+
> >> > >+        HX_RELEASE(pTmpClientPkt);
> >> > >+    }
> >> > >+
> >> > >+    if (HXR_OK == res)
> >> > >+    {
> >> > >+        // Destroy the packet list now that it is
> >> > >+        // empty and we already have a transport
> >> > >+        // buffer
> >> > >+        destroyPktList(m_pNoTransBufPktList);
> >> > >+    }
> >> > >+
> >> > >+    return res;
> >> > >+}
> >> > >+
> >> > >+void RTSPTransport::destroyPktList(REF(CHXSimpleList*) pList)
> >> > >+{
> >> > >+    if (pList)
> >> > >+    {
> >> > >+        while(!pList->IsEmpty())
> >> > >+        {
> >> > >+            ClientPacket* pPkt =
> >> > >+                (ClientPacket*)pList->RemoveTail();
> >> > >+
> >> > >+            HX_RELEASE(pPkt);
> >> > >+        }
> >> > >+
> >> > >+        HX_DELETE(pList);
> >> > >+    }
> >> > >+}
> >> > >Index: transport/common/system/pub/rtsptran.h
> >> > >===================================================================
> >> > >RCS file: /cvsroot/protocol/transport/common/system/pub/rtsptran.h,v
> >> > >retrieving revision 1.18
> >> > >diff -u -r1.18 rtsptran.h
> >> > >--- transport/common/system/pub/rtsptran.h 2 Mar 2004 19:48:37 -0000
> >> > >1.18
> >> > >+++ transport/common/system/pub/rtsptran.h 29 Mar 2004 20:41:09 -0000
> >> > >@@ -346,7 +346,13 @@
> >> > >     UINT32 GetTotalSuccessfulResends() { return
> >> > >     m_ulTotalSuccessfulResends; }
> >> > >     UINT32 GetTotalFailedResends() { return m_ulTotalFailedResends; }
> >> > >     UINT32 GetSendingTime() { return m_ulSendingTime; }
> >> > >-
> >> > >+
> >> > >+private:
> >> > >+    HX_RESULT handleNoTransBufList(RTSPTransportBuffer* 
> >pTransportBuffer);
> >> > >+    HX_RESULT storeClientPacket(RTSPTransportBuffer* 
> >pTransportBuffer,
> >> > >+                                ClientPacket* pClientPkt);
> >> > >+    void destroyPktList(REF(CHXSimpleList*) pList);
> >> > >+
> >> > > protected:
> >> > >     IUnknown*                             m_pContext;
> >> > >     IHXCommonClassFactory*                m_pCommonClassFactory;
> >> > >@@ -377,6 +383,7 @@
> >> > >
> >> > >     RawPacketFilter*                      m_pPacketFilter;
> >> > >     CHXSimpleList*                        m_pClientPacketList;
> >> > >+    CHXSimpleList*                        m_pNoTransBufPktList;
> >> > >     BOOL                                m_bPlayRequestSent;
> >> > >
> >> > >     UINT32                              m_ulTotalSuccessfulResends;
> >> > >
> >> > >_______________________________________________
> >> > >Protocol-dev mailing list
> >> > >Protocol-dev@lists.helixcommunity.org
> >> > >http://lists.helixcommunity.org/mailman/listinfo/protocol-dev
> >> > >
> >> > >
> >>
> >> _______________________________________________
> >> Protocol-dev mailing list
> >> Protocol-dev@lists.helixcommunity.org
> >> http://lists.helixcommunity.org/mailman/listinfo/protocol-dev
> >
> >_______________________________________________
> >Common-dev mailing list
> >Common-dev@lists.helixcommunity.org
> >http://lists.helixcommunity.org/mailman/listinfo/common-dev
> 


From almeroth at cs.ucsb.edu  Wed Mar 24 08:32:24 2004
From: almeroth at cs.ucsb.edu (Kevin C. Almeroth)
Date: Mon May 10 16:37:27 2004
Subject: [Protocol-dev] [Fwd: RFC: New socket API]
In-Reply-To: 
Message-ID: 

>>> One of the high priority items for the new API is to provide a generic and
>>> extensible framework that follows the "standard" BSD and BSD-like semantics
>>> closely.  Will you be using IPv4, IPv6, or both for your application?  Are
>>> you familiar with multicast for IPv6 and how it compares to IPv4?  I'm all
>>> ears at this point.  :-)

Just an update on this...  the consensus seems to be to have SSM be the first
phase of deployment for IPv6, so that means support for MLDv2 and PIM-SSM.
Beyond this, there is talk of things like embedding RP addresses into IPv6
addresses so it can support ASM.  But that solution, or a solution like BGMP,
or some other solution is really yet-to-be-decided.

-kevin



 

Site Map   |   Terms of Use   |   Privacy Policy   |   Contact Us

Copyright © 1995-2007 RealNetworks, Inc. All rights reserved. RealNetworks and Helix are trademarks of RealNetworks.
All other trademarks or registered trademarks are the property of their respective holders.