List Info

Thread: CR: RTSP, RTP and 3GPP Adaptation fixes




CR: RTSP, RTP and 3GPP Adaptation fixes
user name
2006-11-14 07:36:02
Modified by: milkoreal.com
Date: 11:13:06
Project: Atlas

Synopsis: RTSP, RTP and 3GPP Adaptation fixes

Overview:
This submission includes enhancements and fixes to a number
of RTSP 
protocol related defects:

-> Enabled logging in rtsp protocol library

-> Properly handled PLAY reponse to PLAY request issued
for resumption of 
playback not to be isunderstood for PLAY response received
on 
seek.  Previously, the following sequence of RTSP commands
caused 
mishandling in the transport buffer due to improperly set
first sequence 
number and thus resuting in freeze of audio or video
playback or freeze in 
both.  The freezing occured due to inclusion of stale data
into poset seek 
packets.

PAUSE

PAUSE resp

PLAY  (resume)

PLAY  (seek)

PLAY resp (resume)

PLAY resp (seek)

The correction records PLAY command sequence numbers
represeting resumption 
(as opposed to seek) and handles the response differently.

-> In RTP transport removed time-out for receotion of
play response.  If 
play response is not received, playback will not start.  Any
pre-start 
packet queueing is limited to the set transport buffer byte
limit.

-> Corrected handling of 3gpp alternate streams.  The
parsing logic did not 
properly set RTPPayloadType if an alternate stream was
chosen.  This 
resulted all incomming RTP packets to be rejected due to not
matching the 
RTP payload.

-> Corrected handling of fast start on RTP streams with
RTSP pipelining 
enabled.  Previously, the code crashed in attempt to set
FastStart on 
transport streams not yet set-up.  This occured to RTPS
pipelining 
optimizations which allowe playback engine to proceed with
set-up prior to 
all streams setting up porperly.  The fix account for
possibility of fast 
start being communicated to a transport stream prior to it
being fully 
set-up and deferes needed action until full set-up is
accomplished.

-> Properly handled pipleined seek messaged in RTSP/RTP
by keeping track of 
outstanding seeks in transport and ignoring RTP info for
intermediate seeks:
PLAY (seek1)

PLAY (seek2)

PLAY (seek3)

PLAY resp (seek1)

PLAY resp (seek2)

PLAY resp (seek3)

-> Updated few log statements in client audio services
and corrected 
sequence of m_Owner->CheckIfLastNMilliSecsToBeStored()
invocation thus 
resulting on proper communication of NMilliSecsToBeStored on
stream 
creation.  This only correctes asserts in certain cases.  No
known defects 
are associated with this change.


Files Modified:
/client/audiosvc/hxaudply.cpp,v
/client/audiosvc/hxaudstr_new.cpp,v
/protocol/rtsp/rtspclnt.cpp,v
/protocol/rtsp/pub/rtspclnt.h,v
/protocol/sdp/sdpmdparse.cpp,v
/protocol/transport/common/system/rtsptran.cpp,v
/protocol/transport/common/system/transbuf.cpp,v
/protocol/transport/common/system/pub/rtsptran.h,v
/protocol/transport/common/system/pub/transbuf.h,v
/protocol/transport/rtp/rtptran.cpp,v
/protocol/transport/rtp/pub/rtptran.h,v


Image Size and Heap Use impact (Client -Only):
Insignificant.

Platforms and Profiles Affected:
All

Distribution Libraries Affected:
none

Distribution library impact and planned action:
n/a

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

Platforms and Profiles Functionality verified:
win32
Index: rtsp/rtspclnt.cpp
============================================================
=======
RCS file: /cvsroot/protocol/rtsp/rtspclnt.cpp,v
retrieving revision 1.203
diff -u -w -r1.203 rtspclnt.cpp
--- rtsp/rtspclnt.cpp	11 Oct 2006 04:33:25 -0000	1.203
+++ rtsp/rtspclnt.cpp	14 Nov 2006 07:01:15 -0000
 -160,6
+160,12 
 #define DEFAULT_SERVER_TIMEOUT          90          // in
seconds
 #define MINIMUM_TIMEOUT                 5           // in
seconds
 
+#if defined(HELIX_FEATURE_MIN_HEAP)
+#define DEFAULT_TRANSPORT_BYTE_LIMIT	1024000	    // 1MByte
+#else	// HELIX_FEATURE_MIN_HEAP
+#define DEFAULT_TRANSPORT_BYTE_LIMIT	104875600   //
100MBytes
+#endif	// HELIX_FEATURE_MIN_HEAP
+
 #define AUTOBWDETECTION_TIMEOUT         1500        // in
ms
 
 const RTSPTableEntry
RTSPClientProtocol::zm_pRTSPTable[RTSP_TABLE_SIZE] =
 -525,6
+531,8 
         m_pContext->AddRef();
     }
 
+    HX_ENABLE_LOGGING(m_pContext);
+
     CreateInstanceCCF(CLSID_IHXMutex,
(void**)&m_pMutex, m_pContext);
 
     // host name and port from request URL
 -4343,7
+4351,14 
         return HXR_OK;
     }
 
-    HX_RESULT rc = SendMsgToServer(RTSP_PLAY);
+    UINT32 ulMsgSeqNum = 0;
+
+    HX_RESULT rc = SendMsgToServer(RTSP_PLAY,
&ulMsgSeqNum);
+
+    if (SUCCEEDED(rc))
+    {
+	rc = augmentResumeRequestPendingReplyList(ulMsgSeqNum);
+    }
 
     m_pMutex->Unlock();
     return rc;
 -4763,6
+4778,13 
                                 IHXPacket* pPacket)
 {
     m_pMutex->Lock();
+    if (pPacket)
+    {
+	HXLOGL4(HXLOG_TRAN,
"RTSPClientProtocol::PacketReady() PacketReady:
StrmNum=%hu TS=%lu ASMRule=%hu",
+	    pPacket->GetStreamNumber(),
+	    pPacket->GetTime(),
+	    pPacket->GetASMRuleNumber());
+    }
     HX_RESULT rc = m_pResp->HandlePacket(status,
pSessionID, pPacket);
     m_pMutex->Unlock();
     return rc;
 -6049,6
+6071,14 
 RTSPClientProtocol::SetRTPInfo(UINT16 uStreamNumber, UINT16
uSeqNum,
                                UINT32 ulRTPTime,
RTPInfoEnum info)
 {
+    return _SetRTPInfo(uStreamNumber, uSeqNum, ulRTPTime,
info);
+}
+
+HX_RESULT
+RTSPClientProtocol::_SetRTPInfo(UINT16 uStreamNumber,
UINT16 uSeqNum,
+                                UINT32 ulRTPTime,
RTPInfoEnum info,
+			        HXBOOL bOnPauseResume)
+{
     m_pMutex->Lock();
     HX_ASSERT(RTPINFO_ERROR != info);
 
 -6062,20
+6092,16 
          */
         if (RTPINFO_SEQ_RTPTIME == info)
         {
-            pTrans->setFirstSeqNum(uStreamNumber,
uSeqNum);
-            pTrans->setFirstTimeStamp(uStreamNumber,
ulRTPTime);
+            pTrans->setFirstSeqNum(uStreamNumber,
uSeqNum, bOnPauseResume);
+            pTrans->setFirstTimeStamp(uStreamNumber,
ulRTPTime, bOnPauseResume);
         }
         else if (RTPINFO_SEQ == info)
         {
-            pTrans->setFirstSeqNum(uStreamNumber,
uSeqNum);
+            pTrans->setFirstSeqNum(uStreamNumber,
uSeqNum, bOnPauseResume);
         }
         else if (RTPINFO_RTPTIME == info)
         {
-            pTrans->setFirstTimeStamp(uStreamNumber,
ulRTPTime);
-        }
-        else if (RTPINFO_EMPTY == info)
-        {
-            pTrans->notifyRTPInfoProcessed();
+            pTrans->setFirstTimeStamp(uStreamNumber,
ulRTPTime, bOnPauseResume);
         }
     }
 
 -6105,7
+6131,7 
   }*/
 
 void
-RTSPClientProtocol::NotifyStreamsRTPInfoProcessed(void)
+RTSPClientProtocol::NotifyStreamsRTPInfoProcessed(HXBOOL
bOnPauseResume)
 {
     m_pMutex->Lock();
 
 -6125,7
+6151,7 
             pTrans = GetTransport(streamID);
             if (pTrans)
             {
-                pTrans->notifyRTPInfoProcessed();
+               
pTrans->notifyRTPInfoProcessed(bOnPauseResume);
             }
         }
     }
 -6966,7
+6992,7 
 }
 
 HX_RESULT
-RTSPClientProtocol::SendMsgToServer(RTSPMethod msg)
+RTSPClientProtocol::SendMsgToServer(RTSPMethod msg, UINT32*
pulMsgSeqNum)
 {
     HX_RESULT           rc = HXR_OK;
     RTSPRequestMessage* pMsg = NULL;
 -6994,6
+7020,10 
 
         UINT32 seqNo = m_pSession->getNextSeqNo(this);
         rc = sendRequest(pMsg, seqNo);
+	if (pulMsgSeqNum)
+	{
+	    *pulMsgSeqNum = seqNo;
+	}
     }
     else
     {
 -7539,6
+7569,9 
     UINT32 ulRTPTime = 0;
     const char* pControl = 0;
     RTPInfoEnum RTPErr;
+    HXBOOL bIsResumeResponse;
+
+    bIsResumeResponse =
trimResumeRequestPendingReplyList(pMsg->seqNo());
 
     if (pSequence)
     {
 -7581,7
+7614,7 
             // Without pInfo, we do not know the streamID
to set RTPInfo to.
             if ((RTPINFO_ERROR != RTPErr) && pInfo)
             {
-                SetRTPInfo(streamID, seqNum, ulRTPTime,
RTPErr);
+                _SetRTPInfo(streamID, seqNum, ulRTPTime,
RTPErr, bIsResumeResponse);
             }
 
             pSeqValue = pSequence->getNextHeaderValue();
 -7590,7
+7623,7 
 
     // Meke sure all streams involved are aware that
     // RTP Info has been processed and no more info is
comming.
-    NotifyStreamsRTPInfoProcessed();
+    NotifyStreamsRTPInfoProcessed(bIsResumeResponse);
 
     m_bSeqValueReceived = TRUE;
 
 -8625,6
+8658,7 
     clearTransportRequestList();
     clearUDPResponseHelperList();
     ClearPreSetupResponseQueueMap();
+    clearResumeRequestPendingReplyList();
 
     HX_RELEASE(m_pConnectAddr);
     HX_RELEASE(m_pPeerAddr);
 -8760,6
+8794,63 
 }
 
 void
+RTSPClientProtocol::clearResumeRequestPendingReplyList()
+{
+    UINT32* pDeadCmdSeqNum;
+
+    while (!m_ResumeRequestPendingReplyList.IsEmpty())
+    {
+	pDeadCmdSeqNum = (UINT32*)
m_ResumeRequestPendingReplyList.RemoveHead();
+	delete pDeadCmdSeqNum;
+    }
+}
+
+HXBOOL
+RTSPClientProtocol::trimResumeRequestPendingReplyList(UINT3
2 ulPlayReplySeqNum)
+{
+    UINT32* pHeadCmdSeqNum;
+    HXBOOL bIsResumeReply = FALSE;
+
+
+    while (!m_ResumeRequestPendingReplyList.IsEmpty())
+    {
+	pHeadCmdSeqNum = (UINT32*)
m_ResumeRequestPendingReplyList.GetHead();
+	if ((ulPlayReplySeqNum - (*pHeadCmdSeqNum)) >= 0)
+	{
+	    if ((*pHeadCmdSeqNum) == ulPlayReplySeqNum)
+	    {
+		bIsResumeReply = TRUE;
+	    }
+
+	    m_ResumeRequestPendingReplyList.RemoveHead();
+	    delete pHeadCmdSeqNum;
+	}
+	else
+	{
+	    break;
+	}
+    }
+
+    return bIsResumeReply;
+}
+
+HX_RESULT
+RTSPClientProtocol::augmentResumeRequestPendingReplyList(UI
NT32 ulPlayReplySeqNum)
+{
+    UINT32* pTailCmdSeqNum = new UINT32;
+    HX_RESULT retVal = HXR_OUTOFMEMORY;
+
+    if (pTailCmdSeqNum)
+    {
+	retVal = HXR_OK;
+	*pTailCmdSeqNum = ulPlayReplySeqNum;
+	m_ResumeRequestPendingReplyList.AddTail((void*)
pTailCmdSeqNum);
+    }
+
+    return retVal;
+}
+
+void
 RTSPClientProtocol::clearSocketStreamMap(CHXMapLongToObj*&a
mp; pSocketStreamMap)
 {
     if(pSocketStreamMap)
 -10060,7
+10151,15 
     }
     else
     {
-        rc = CHXAltGroupUtil::SelectAltGroups(m_pContext,
nValues, ppValues);
+	CHXString languages;
+	ReadPrefCSTRING(m_pPreferences, "Language",
languages);
+
+	HX_ASSERT(m_pSession);
+
+        rc = CHXAltGroupUtil::SelectAltGroups(m_pContext, 
+					      m_pSession ? m_pSession->getConnectionBW() :
0, 
+					      languages, 
+					      nValues, ppValues);
     }
 
     if (HXR_OK == rc)
Index: rtsp/pub/rtspclnt.h
============================================================
=======
RCS file: /cvsroot/protocol/rtsp/pub/rtspclnt.h,v
retrieving revision 1.87
diff -u -w -r1.87 rtspclnt.h
--- rtsp/pub/rtspclnt.h	21 Jul 2006 07:50:29 -0000	1.87
+++ rtsp/pub/rtspclnt.h	14 Nov 2006 07:01:17 -0000
 -1009,7
+1009,12 
     HX_RESULT addTransportMimeType      (MIMEHeaderValue*
pValue,
                                         UINT16
streamNumber);
 
-    void NotifyStreamsRTPInfoProcessed  (void);
+    HX_RESULT _SetRTPInfo		(UINT16 uStreamNumber,
+                                         UINT16 uSeqNum,
+                                         UINT32 ulRTPTime,
+                                         RTPInfoEnum info,
+					 HXBOOL bOnPauseResume = FALSE);
+    void NotifyStreamsRTPInfoProcessed  (HXBOOL
bOnPauseResume = FALSE);
 
     HX_RESULT sendFirstSetupRequest
     (
 -1028,6
+1033,9 
     void clearTransportRequestList      ();
     void clearStreamInfoList            ();
     void clearUDPResponseHelperList     ();
+    void clearResumeRequestPendingReplyList();
+    HXBOOL trimResumeRequestPendingReplyList(UINT32
ulReplySeqNum);
+    HX_RESULT augmentResumeRequestPendingReplyList(UINT32
ulReplySeqNum);
     void clearSocketStreamMap(CHXMapLongToObj*&
pSocketStreamMap);
     HX_RESULT getStreamDescriptionMimeType  (char*&
pMimeType);
     IHXStreamDescription*
 -1062,7
+1070,7 
     HX_RESULT       GetStreamDescriptionInfo(IUnknown*
pUnknown, CHXString& mimeTypes);
     void            SendMsgToTransport(TRANSPORT_MSG msg);
     void           
AddCommonHeaderToMsg(RTSPRequestMessage* pMsg);
-    HX_RESULT       SendMsgToServer(RTSPMethod msg);
+    HX_RESULT       SendMsgToServer(RTSPMethod msg, UINT32*
pulMsgSeqNum = NULL);
     HX_RESULT       SendOptionsMsgToServer(HXBOOL
bKeepAlive);
 
     HX_RESULT extractRealmInformation(RTSPResponseMessage*
pMsg);
 -1216,6
+1224,7 
     CHXSimpleList                      
m_activeTransportList;  // RTSPTransport* chosen after SETUP
response
     CHXSimpleList                      
m_UDPResponseHelperList;
     CHXSimpleList                       m_sessionList;
+    CHXSimpleList			m_ResumeRequestPendingReplyList;
     CHXMapLongToObj*                   
m_pTransportStreamMap;  // map streamID->trans
     CHXMapLongToObj*                   
m_pTransportPortMap;    // map port->trans
     CHXMapLongToObj*                   
m_pTransportMPortMap;   // map multicast port->trans
Index: sdp/sdpmdparse.cpp
============================================================
=======
RCS file: /cvsroot/protocol/sdp/sdpmdparse.cpp,v
retrieving revision 1.41
diff -u -w -r1.41 sdpmdparse.cpp
--- sdp/sdpmdparse.cpp	15 May 2006 18:49:24 -0000	1.41
+++ sdp/sdpmdparse.cpp	14 Nov 2006 07:01:19 -0000
 -1594,8
+1594,21 
     char* pCur = 0;
     UINT32 payload = (UINT32)strtol(pFieldValue, &pCur,
10);
     ULONG32 rtpPayloadType = pState->m_uPayloadType;
+    HXBOOL bSetRTPPayloadType = FALSE;
 
     res =
pHdr->GetPropertyULONG32("RTPPayloadType",
rtpPayloadType);
+
+    // If RTP Payload type is not present, we are likely
processing
+    // an "alt" SDP sub-section.   We set RTP
payload type
+    // to what is present in the RTP map since we need to
have
+    // a RTP payload type set.
+    if (FAILED(res))
+    {
+	rtpPayloadType = payload;
+	bSetRTPPayloadType = TRUE;
+	res = HXR_OK;
+    }
+
     if (*pFieldValue && (*pCur == ' '))
     {
         SkipSpaces(pCur);
 -1617,6
+1630,11 
                 AddString(pHdr, "MimeType",
mimeType);
             }
             HX_RELEASE(pMimeType);
+
+	    if (bSetRTPPayloadType)
+	    {
+		res =
pHdr->SetPropertyULONG32("RTPPayloadType",
payload);
+	    }
         }
     }
 
Index: transport/common/system/rtsptran.cpp
============================================================
=======
RCS file:
/cvsroot/protocol/transport/common/system/rtsptran.cpp,v
retrieving revision 1.50
diff -u -w -r1.50 rtsptran.cpp
--- transport/common/system/rtsptran.cpp	9 Feb 2006 01:10:49
-0000	1.50
+++ transport/common/system/rtsptran.cpp	14 Nov 2006
07:01:20 -0000
 -550,6
+550,11 
                
pStreamData->m_pTransportBuffer->EnterPrefetch();
             }
 	}
+
+	if (m_bFastStart)
+	{
+	    EnterFastStart();
+	}
     }
 }
 
 -560,6
+565,12 
     RTSPStreamData* pStreamData = 
 	m_pStreamHandler->getStreamData(uStreamNumber);
 
+    HXLOGL3(HXLOG_RTSP,
"RTSPTransport[%p]::setFirstTimeStamp(uStreamNumber=%hu
, ulTS=%hu, bIsRaw=%c)", 
+	    this, 
+	    uStreamNumber,
+	    ulTS,
+	    bIsRaw ? 'T' : 'F');
+
     if (pStreamData)
     {
 	if (pStreamData->m_pTSConverter)
 -827,6
+838,12 
      */
     HX_RELEASE(clientPacket);    
 
+    HXLOGL4(HXLOG_TRAN, "RTSPTransport::getPacket()
GotPacket: StrmNum=%hu SeqNo=%hu TS=%lu ASMRule=%hu",
+	    pPacket->GetStreamNumber(),
+	    uSeqNum,
+	    pPacket->GetTime(),
+	    pPacket->GetASMRuleNumber());
+
     return HXR_OK;
 }
 
 -945,8
+962,17 
     
     m_bFastStart = TRUE;
 
-    HX_ASSERT(m_pStreamHandler);
-
+    // For protocols that use one channel per stream (e.g.
RTP)
+    // as opposed multiplexing streams into a single
channel (e.g. RDT) it
+    // is possible for this call to arrive before the
transport has
+    // been initialized via addStreamInfo and thus
m_pStreamHandler
+    // created.  This occurs when SETUP pipelining is used
where
+    // only the first SETUP is awaited before proceeding
with initialization
+    // of the playback engine structures.
+    // In such case, we'll simply remember fast start state
and
+    // re-execute this code once the transport information
is added.
+    if (m_pStreamHandler)
+    {
     pStreamData = m_pStreamHandler->firstStreamData();
     while(pStreamData)    
     {
 -956,6
+982,7 
 	}
 	pStreamData = m_pStreamHandler->nextStreamData();
     }
+    }
 
     return;
 }
 -1068,6
+1095,14 
                                                   
startTime,
                                                    FALSE);
     
+    HXLOGL4(HXLOG_TRAN, "RTSPTransport::storePacket()
Strm=%hu SeqNo=%hu ReliableSeqNo=%hu Reliable=%c TS=%lu
ASMRule=%hu", 
+	uStreamNumber,
+	uSeqNo,
+	uReliableSeqNo,
+	isReliable ? 'T' : 'F',
+	pPacket->GetTime(),
+	pPacket->GetASMRuleNumber());
+
     if (pClientPacket)
     {
         pClientPacket->AddRef();
 -1858,10
+1893,15 
 }
 
 HX_RESULT
-RTSPTransport::setFirstSeqNum(UINT16 uStreamNumber, UINT16
uSeqNum)
+RTSPTransport::setFirstSeqNum(UINT16 uStreamNumber, UINT16
uSeqNum, HXBOOL bOnPauseResume)
 {
     RTSPStreamData* pStreamData;
 
+    HXLOGL3(HXLOG_RTSP,
"RTSPTransport[%p]::setFirstSeqNum(uStreamNumber=%hu,
uSeqNum=%hu)", 
+	    this, 
+	    uStreamNumber, 
+	    uSeqNum);
+
     pStreamData =
m_pStreamHandler->getStreamData(uStreamNumber);
 
     if(pStreamData)
 -1885,7
+1925,7 
 	    if (!m_bMulticast)
 	    {
 		pStreamData->m_lastSeqNo = uSeqNum;
-    		pStreamData->m_pTransportBuffer->Init(uSeqNum);
+    		pStreamData->m_pTransportBuffer->Init(uSeqNum,
bOnPauseResume);
 	    }
 	}
     }
Index: transport/common/system/transbuf.cpp
============================================================
=======
RCS file:
/cvsroot/protocol/transport/common/system/transbuf.cpp,v
retrieving revision 1.31
diff -u -w -r1.31 transbuf.cpp
--- transport/common/system/transbuf.cpp	28 Aug 2006
18:51:26 -0000	1.31
+++ transport/common/system/transbuf.cpp	14 Nov 2006
07:01:22 -0000
 -325,7
+325,7 
 }
 
 HX_RESULT
-RTSPTransportBuffer::Init(UINT16 uSeqNo)
+RTSPTransportBuffer::Init(UINT16 uSeqNo, HXBOOL
bOnPauseResume)
 {
     /*
      * The server side of an encoding session will
initialize the scheduler
 -354,7
+354,14 
     }
     else if (m_uSeekCount)
     {
+	// In is done is reponse to resumption after seek as well
+	// as acknowledgement of resumption from pause by the
server.
+	// We do not want to confuse seek actions for
acknowledgement
+	// of resumption from pause.
+	if (!bOnPauseResume)
+	{
         m_uSeekCount--;
+	}
         if (m_uSeekCount > 0)
         {
             return HXR_OK;
 -398,11
+405,13 
 
     if (!m_pPacketDeque)
     {
+	HXLOGL4(HXLOG_TRAN, "RTSPTransportBuffer::Add()
NoQueue: Discard");
         HX_RELEASE(pPacket);
         return HXR_FAIL;
     }
     else if (m_pPacketDeque->size() >=
MAX_DEQUE_SIZE)
     {
+	HXLOGL4(HXLOG_TRAN, "RTSPTransportBuffer::Add()
QueueOverflow: Discard");
         m_pOwner->HandleBufferError();
         
         HX_RELEASE(pPacket);
 -410,6
+419,7 
     }
     else if (m_bStreamDone)
     {
+	HXLOGL4(HXLOG_TRAN, "RTSPTransportBuffer::Add()
StreamDone: Discard");
         /*
          * If we have already returned the last packet,
then don't bother
          * trying to add anymore
 -419,6
+429,10 
     }
     else if (!m_bIsInitialized || m_uSeekCount)
     {
+	HXLOGL4(HXLOG_TRAN, "RTSPTransportBuffer::Add()
NotReady: Queue: Initialized=%c SeekCount=%hu",
+	    m_bIsInitialized ? 'T' : 'F',
+	    m_uSeekCount);
+
         /*
          * Until the first sequence number is set, just
hold the packets
          * as they arrive
 -990,6
+1004,7 
 
     if( m_bStreamDone )
     {
+	HXLOGL4(HXLOG_TRAN, "RTSPTransportBuffer::GetPacket()
StreamDone");
         if( !m_bStreamDoneSent )
         {
             m_bStreamDoneSent = TRUE;
 -1000,6
+1015,12 
     else if (!m_bIsInitialized || m_uSeekCount ||
m_bWaitingForSeekFlush ||
              (m_bPaused && !m_bIsEnded))
     {
+	HXLOGL4(HXLOG_TRAN, "RTSPTransportBuffer::GetPacket()
NoData: Initialized=%c SeekCount=%lu WaitingForSeekFlush=%c
Paused=%c Ended=%c", 
+	    m_bIsInitialized ? 'T' : 'F',
+	    m_uSeekCount,
+	    m_bWaitingForSeekFlush ? 'T' : 'F',
+	    m_bPaused ? 'T' : 'F',
+	    m_bIsEnded ? 'T' : 'F');
         return HXR_NO_DATA;
     }
 
 -1081,13
+1102,16 
         }
     }
 
-    if (pPacket && !m_bFirstPacketGet)
+    if (pPacket)
+    {
+	if (!m_bFirstPacketGet)
     {
         m_bFirstPacketGet = TRUE;
         HXLOGL1(HXLOG_TRAN,
                 "RTSPTransportBuffer[%p]: First Packet
Retrieved %i",
                 this, m_uStreamNumber);
     }
+    }
 
     return rc;
 }
 -1672,6
+1696,8 
 void
 RTSPTransportBuffer::Pause()
 {    
+    HXLOGL3(HXLOG_TRAN,
"RTSPTransportBuffer::Pause()");
+
     HXTimeval lTime =
m_pScheduler->GetCurrentSchedulerTime();
     Timeval now((INT32)lTime.tv_sec, (INT32)lTime.tv_usec);
 
 -1687,6
+1713,8 
 void
 RTSPTransportBuffer::Resume()
 {
+    HXLOGL3(HXLOG_TRAN, "RTSPTransportBuffer::Resume()
Paused=%c", m_bPaused ? 'T' : 'F');
+
     if (m_bPaused)
     {
         HXTimeval lTime =
m_pScheduler->GetCurrentSchedulerTime();
 -1736,6
+1764,8 
 {
     ClientPacket* pPacket;
 
+    HXLOGL3(HXLOG_TRAN,
"RTSPTransportBuffer::Flush()");
+
     //We are flushing all the packets. Empty out pending
list.
     HX_LOCK(m_pPendingLock);
     while( !m_PendingPackets.IsEmpty() )
Index: transport/common/system/pub/rtsptran.h
============================================================
=======
RCS file:
/cvsroot/protocol/transport/common/system/pub/rtsptran.h,v
retrieving revision 1.41
diff -u -w -r1.41 rtsptran.h
--- transport/common/system/pub/rtsptran.h	21 Sep 2005
00:54:45 -0000	1.41
+++ transport/common/system/pub/rtsptran.h	14 Nov 2006
07:01:23 -0000
 -286,13
+286,14 
     UINT32  getTimestamp                (UINT16
streamNumber);
 //    HX_RESULT setMarkerRule           (UINT16
ruleNumber);
     virtual HX_RESULT setFirstSeqNum    (UINT16
streamNumber,
-                                         UINT16 seqNum);
+                                         UINT16 seqNum,
+					 HXBOOL bOnPauseResume = FALSE);
     UINT32  getFirstTimestamp         (UINT16
streamNumber);
     virtual void      setFirstTimeStamp (UINT16
uStreamNumber, UINT32 ulTS,
                                          HXBOOL bIsRaw =
FALSE);
 
     // only in RTPTransport...
-    virtual void notifyRTPInfoProcessed (void) {}
+    virtual void notifyRTPInfoProcessed (HXBOOL
bOnPauseResume = FALSE) {}
     virtual void  setPlayRange          (UINT32 ulFrom,
UINT32 ulTo);
     virtual HX_RESULT setFirstPlayTime  (Timeval* pTv)
{return HXR_OK;};
     virtual void      OnPause  (Timeval* pTv) { };
Index: transport/common/system/pub/transbuf.h
============================================================
=======
RCS file:
/cvsroot/protocol/transport/common/system/pub/transbuf.h,v
retrieving revision 1.13
diff -u -w -r1.13 transbuf.h
--- transport/common/system/pub/transbuf.h	16 Feb 2006
23:06:29 -0000	1.13
+++ transport/common/system/pub/transbuf.h	14 Nov 2006
07:01:23 -0000
 -113,7
+113,7 
 					     UINT32 ulEndTimestamp,
 					     UINT32 ulEndDelayTolerance = 0);
 
-    HX_RESULT		Init(UINT16 uSeqNo);
+    HX_RESULT		Init(UINT16 uSeqNo, HXBOOL bOnPauseResume =
FALSE);
     HX_RESULT		Add(ClientPacket* pPacket);
     HX_RESULT		Insert(ClientPacket* pPacket);
     HX_RESULT		Flush();
Index: transport/rtp/rtptran.cpp
============================================================
=======
RCS file: /cvsroot/protocol/transport/rtp/rtptran.cpp,v
retrieving revision 1.105
diff -u -w -r1.105 rtptran.cpp
--- transport/rtp/rtptran.cpp	1 Apr 2006 07:42:28
-0000	1.105
+++ transport/rtp/rtptran.cpp	14 Nov 2006 07:01:30 -0000
 -80,6
+80,7 
 #include "tconverter.h"
 #include "rtptypes.h"
 #include "hxtlogutil.h"
+#include "hxprefutil.h"
 #include "hxqosinfo.h"
 #include "hxqossig.h"
 #include "hxqos.h"
 -204,9
+205,9 
     , m_ulLastHXTS(0)
     , m_ulLastRawRTPTS(0)
     , m_bLastTSSet(FALSE)
+    , m_ulWaitQueueBytes(0)
     , m_bWaitForStartInfo(TRUE)
     , m_bAbortWaitForStartInfo(FALSE)
-    , m_ulStartInfoWaitStartTime(0)
     , m_bSSRCDetermined(FALSE)
     , m_ulSSRCDetermined(0)
     , m_ulAvgPktSz (0)
 -214,6
+215,7 
     , m_pReflectionHandler(NULL)
     , m_bSeqNoSet(FALSE)
     , m_bRTPTimeSet(FALSE)
+    , m_ulSeekCount(0)
     , m_pFirstPlayTime(NULL)
     , m_pLastPauseTime(NULL)
     , m_lRTPOffset(0)
 -457,7
+459,7 
  */
 
 HX_RESULT
-RTPBaseTransport::setFirstSeqNum(UINT16 uStreamNumber,
UINT16 uSeqNum)
+RTPBaseTransport::setFirstSeqNum(UINT16 uStreamNumber,
UINT16 uSeqNum, HXBOOL bOnPauseResume)
 {
     HXLOGL3(HXLOG_RTSP,
"RTPBaseTransport[%p]::setFirstSeqNum(); str %u first
seq = %u",this, uStreamNumber, uSeqNum);
     HX_RESULT theErr = HXR_UNEXPECTED;
 -466,13
+468,17 
     // havoc in transport buffer
     if (m_bIsSource || (!m_bSeqNoSet))
     {
-        theErr =
RTSPTransport::setFirstSeqNum(uStreamNumber, uSeqNum);
+        theErr =
RTSPTransport::setFirstSeqNum(uStreamNumber, uSeqNum,
bOnPauseResume);
 
 #ifdef RTP_MESSAGE_DEBUG
         messageFormatDebugFileOut("INIT:
StartSeqNum=%u",
                                   uSeqNum);
 #endif  // RTP_MESSAGE_DEBUG
 
+	// In the client, we set for start of stream only if thee
are no more
+	// pipelined seeks outstanding.
+	if (m_bIsSource || (m_ulSeekCount <= 1))
+	{
         if (SUCCEEDED(theErr))
         {
             m_bSeqNoSet = TRUE;
 -494,6
+500,7 
             }
         }
     }
+    }
 
     return theErr;
 }
 -581,6
+588,14 
         }
         else if (!m_bRTPTimeSet)
         {
+	    // If there are outstanding pipelined seeks, we do not
set
+	    // the start time as we wait for the information
provided by
+	    // the last pipelined seek.
+	    if (m_ulSeekCount > 1)
+	    {
+		return;
+	    }
+
             // ulTS is what's reported in rtptime of
RTP-Info PLAY response
             // header in RTP time.  Unit is RTP.
             /*
 -627,16
+642,31 
 }
 
 void
-RTPBaseTransport::notifyRTPInfoProcessed(void)
+RTPBaseTransport::notifyRTPInfoProcessed(HXBOOL
bOnPauseResume)
 {
+    HXLOGL3(HXLOG_RTSP,
"RTPBaseTransport[%p]::notifyRTPInfoProcessed(OnPauseRe
sume=%c) OutstandingSeekCount=%lu", 
+	    this, 
+	    bOnPauseResume ? 'T' : 'F', 
+	    m_ulSeekCount);
+
     // This method is invoked to indicate that RTP-Info has
been processed
     // and transport should no longer expect stream startup
parameters
     // to be communicated to it.
     // Thus there is no point in waiting for out-of-band
     // start info (start seq number and time stamp) since
RTP-Info is the
     // only out-of-band method of communicating start info.
in RTP.
+    // This method also signifies the completion of a seek
or resume
+    // operation.
+    if ((!bOnPauseResume) && (m_ulSeekCount >
0))
+    {
+	m_ulSeekCount--;
+    }
+
+    if (m_ulSeekCount == 0)
+    {
     m_bAbortWaitForStartInfo = TRUE;
 }
+}
 
 void
 RTPBaseTransport::setPlayRange(UINT32 ulFrom, UINT32 ulTo)
 -666,6
+696,12 
     m_lNTPtoHXOffset = 0;
     m_bNTPtoHXOffsetSet = FALSE;
     resetStartInfoWaitQueue();
+    // Every re-setting of the play-range represents start
of a seek.
+    // Since seeks can be pipelined, we need to keep track
+    // of the outstanding seeks to able to restart on
+    // re-start information (RTP-Info) arriving for the
last
+    // pipelined seek.
+    m_ulSeekCount++;
 
 #ifdef RTP_MESSAGE_DEBUG
     messageFormatDebugFileOut("INIT:
PlayRange=%u-%u",
 -1506,7
+1542,6 
         if (m_StartInfoWaitQueue.GetCount() == 0)
         {
             // First packet received
-            m_ulStartInfoWaitStartTime =
HX_GET_TICKCOUNT();
             m_uFirstSeqNum = pkt.seq_no;
             m_ulFirstRTPTS = pkt.timestamp;
             // For Live stream, postpone identification of
first packet until we get
 -1553,21
+1588,40 
 
         pBuffer->AddRef();
         m_StartInfoWaitQueue.AddTail(pBuffer);
+	m_ulWaitQueueBytes += pBuffer->GetSize();
+
+	// Make sure we do not queue more than set tranport byte
limit.
+	// We must allow queueing of
MIN_NUM_PACKETS_SCANNED_FOR_LIVE_START regardless of
+	// the byte limit imposed for proper start-time
processing.
+	if (pStreamData->m_pTransportBuffer)
+	{
+	    UINT32 ulTransportByteLimit =
pStreamData->m_pTransportBuffer->GetByteLimit();
+
+	    if (ulTransportByteLimit != 0)
+	    {
+		IHXBuffer* pSpilledBuffer;
+
+		while ((m_ulWaitQueueBytes > ulTransportByteLimit)
&&
+		       (m_StartInfoWaitQueue.GetCount() >
MIN_NUM_PACKETS_SCANNED_FOR_LIVE_START))
+		{
+		    pSpilledBuffer = (IHXBuffer*)
m_StartInfoWaitQueue.RemoveHead();
+		    m_ulWaitQueueBytes -= pSpilledBuffer->GetSize();
+		    pSpilledBuffer->Release();
+		}
+	    }
+	}
 
         /* If start Info has been at least partially set or
the wait has been
            aborted for some reason (usually when we know it
will not be set
            through out-of band methods <-> RTP Info
did not contain start Info
-           we need) or we time-out, stop waiting and hand
off acumulated
-           packets to the transport buffer.
+           we need).
            Also if starting seq. number is not explicitly
communicated,
            scan through few starting packets until we have
a good starting
            sequence number (contiguous) since some servers
send lossy streams
            in the beginning. */
         if (m_bSeqNoSet ||
             ((m_bRTPTimeSet || m_bAbortWaitForStartInfo)
&&
-             ((!m_bIsLive) ||
(m_StartInfoWaitQueue.GetCount() >=
MIN_NUM_PACKETS_SCANNED_FOR_LIVE_START))) ||
-            ((HX_GET_TICKCOUNT() -
m_ulStartInfoWaitStartTime) >
-             MAX_STARTINFO_WAIT_TIME))
+             ((!m_bIsLive) ||
(m_StartInfoWaitQueue.GetCount() >=
MIN_NUM_PACKETS_SCANNED_FOR_LIVE_START))))
         {
             IHXBuffer* pStoredBuffer;
 
 -1585,6
+1639,8 
                     pStoredBuffer->Release();
                 }
             }
+
+	    m_ulWaitQueueBytes = 0;
         }
 
         return HXR_OK;
 -1901,6
+1957,8 
 
         HX_RELEASE(pStoredBuffer);
     }
+
+    m_ulWaitQueueBytes = 0;
 }
 
 HX_RESULT
Index: transport/rtp/pub/rtptran.h
============================================================
=======
RCS file: /cvsroot/protocol/transport/rtp/pub/rtptran.h,v
retrieving revision 1.52
diff -u -w -r1.52 rtptran.h
--- transport/rtp/pub/rtptran.h	4 Mar 2006 02:23:40
-0000	1.52
+++ transport/rtp/pub/rtptran.h	14 Nov 2006 07:01:30 -0000
 -177,8
+177,8 
                                          const char*
pReasonText = NULL);
 
     /* RTP-Info */
-    HX_RESULT setFirstSeqNum            (UINT16
streamNumber, UINT16 seqNum);
-    void notifyRTPInfoProcessed		(void);
+    HX_RESULT setFirstSeqNum            (UINT16
streamNumber, UINT16 seqNum, HXBOOL bOnPauseResume = FALSE);
+    void notifyRTPInfoProcessed		(HXBOOL bOnPauseResume =
FALSE);
     void setFirstTimeStamp              (UINT16
uStreamNumber, UINT32 ulTS,
                                          HXBOOL bIsRaw =
FALSE);
     void SetFirstTSLive                 (RTSPStreamData*
pStreamData, UINT32 ulTS, HXBOOL bIsRaw);
 -265,9
+265,9 
     HXBOOL                                m_bLastTSSet;
 
     CHXSimpleList                      
m_StartInfoWaitQueue;
+    UINT32				m_ulWaitQueueBytes;
     HXBOOL                               
m_bWaitForStartInfo;
     HXBOOL                               
m_bAbortWaitForStartInfo;
-    ULONG32                            
m_ulStartInfoWaitStartTime;
 
     HXBOOL                               
m_bSSRCDetermined;
     UINT32                              m_ulSSRCDetermined;
 -283,6
+283,8 
     /* m_bRTPTimeSet is used differently on the server and
the client */
     HXBOOL                                m_bRTPTimeSet;
 
+    UINT32				m_ulSeekCount;
+
 
     Timeval*                            m_pFirstPlayTime;
     Timeval*				m_pLastPauseTime;

Index: hxaudply.cpp
============================================================
=======
RCS file: /cvsroot/client/audiosvc/hxaudply.cpp,v
retrieving revision 1.46
diff -u -w -r1.46 hxaudply.cpp
--- hxaudply.cpp	30 Sep 2006 22:32:08 -0000	1.46
+++ hxaudply.cpp	14 Nov 2006 07:03:53 -0000
 -833,8
+833,6 
 
    
((CHXAudioStream*)(*pAudioStream))->SetLive(m_bIsLive);
 
-    m_Owner->CheckIfLastNMilliSecsToBeStored();
-
     /* Already initialized with no streams?*/
     if (m_bInited && !m_bHasStreams)
     {
 -852,6
+850,8 
     // If we were using a clock source, then deactivate it
     DeactivateClockSource();
 
+    m_Owner->CheckIfLastNMilliSecsToBeStored();
+
     /* If we are already initialized, it means
CreateAudioStream was
      * called in the midst of the presentation. In this
case, we already know
      * the granularity and the Device format and thus call
Setup right away
 -2102,6
+2102,9 
 
     m_bHasStreams   = TRUE;
     m_bInited   = FALSE;
+
+    m_Owner->CheckIfLastNMilliSecsToBeStored();
+
     /* internal setup */
     HX_RESULT theErr = Setup(m_ulGranularity);
     if (theErr != HXR_OK)
 -2461,6
+2464,7 
 void
 CHXAudioPlayer::RewindPlayer(UINT32 ulTimeToRewind)
 {
+    // ulTimeToRewind = 0;  MBO Test
     if (m_pStreamList->GetCount() == 0  ||
!m_bCanBeRewound)
     {
         return;
 -2484,6
+2488,14 
     {
         m_llLastWriteTime -= ulTimeToRewind;
     }
+
+    UINT32 ulLastWriteTime =
INT64_TO_UINT32(m_llLastWriteTime);
+    HXLOGL3(HXLOG_ADEV,
"CHXAudioPlayer[%p]::RewindPlayer(TimeToRewind=%lu)
LastWriteTime=%lu APplaybackTime=%lu CurrentTime=%lu", 
+	    this,
+	    ulTimeToRewind,
+	    ulLastWriteTime,
+	    m_ulAPplaybackTime,
+	    m_ulCurrentTime);
 }
 
 HX_RESULT
Index: hxaudstr_new.cpp
============================================================
=======
RCS file: /cvsroot/client/audiosvc/hxaudstr_new.cpp,v
retrieving revision 1.36
diff -u -w -r1.36 hxaudstr_new.cpp
--- hxaudstr_new.cpp	9 Oct 2006 19:59:34 -0000	1.36
+++ hxaudstr_new.cpp	14 Nov 2006 07:03:55 -0000
 -1253,8
+1253,6 
     m_ulInputBytesPerGran  -= m_ulInputBytesPerGran  %
((m_AudioFmt.uBitsPerSample>>3)*m_AudioFmt.uChannels);
     m_ulOutputBytesPerGran -= m_ulOutputBytesPerGran %
((m_DeviceFmt.uBitsPerSample>>3)*m_DeviceFmt.uChannels
);
 
-    HXLOGL3(HXLOG_ADEV,
"CHXAudioStream[%p]::ProcessInfo(): bytes per gran in =
%lu; out = %lu ", this, m_ulInputBytesPerGran,
m_ulOutputBytesPerGran);
-
     if (!theErr)
     {
         // set up the mixing engine
 -1306,6
+1304,13 
     m_llLastWriteTime =
m_Owner->GetLastAudioWriteTime();
    
m_pMixEngine->ResetTimeLineInMillis(m_llLastWriteTime) ;
 
+    UINT32 ulLastWriteTime =
INT64_TO_UINT32(m_llLastWriteTime);
+    HXLOGL3(HXLOG_ADEV,
"CHXAudioStream[%p]::ProcessInfo():
InputBytesPerGran=%lu OutputBytesPerGran=%lu
lastWriteTime=%lu", 
+	    this, 
+	    m_ulInputBytesPerGran, 
+	    m_ulOutputBytesPerGran,
+	    ulLastWriteTime);
+
     if (!theErr && m_bInited)
     {
 	m_Owner->StreamInitialized(this);
 -2466,6
+2471,12 
     }
     if (m_bLastWriteTimeUpdated && m_pMixEngine)
        
m_pMixEngine->ResetTimeLineInMillis(m_llLastWriteTime) ;
+
+    UINT32 ulLastWriteTime =
INT64_TO_UINT32(m_llLastWriteTime);
+    HXLOGL3(HXLOG_ADEV,
"CHXAudioStream[%p]::UpdateStreamLastWriteTime(bForceUp
date=%c): LastWriteTime=%lu", 
+	    this,
+	    bForceUpdate ? 'T' : 'F',
+	    ulLastWriteTime);
 }
 
 void
 -2497,7
+2508,6 
 void
 CHXAudioStream::RewindStream(UINT32 ulTimeToRewind)
 {
-    HXLOGL3(HXLOG_ADEV,
"CHXAudioStream[%p]::RewindStream(); time = %lu",
this, ulTimeToRewind);
     HX_ASSERT(m_bLastNMilliSecsToBeSaved);
 
     if (!m_bCanBeRewound)
 -2538,6
+2548,12 
     UINT32 ulLastWriteTime =
INT64_TO_UINT32(m_llLastWriteTime - CAST_TO_INT64
m_ulTSRollOver * CAST_TO_INT64 MAX_UINT32);
     HXBOOL bTimedToBeSet =
(m_pLastNMilliSecsList->GetCount() > 0);
 
+    HXLOGL3(HXLOG_ADEV,
"CHXAudioStream[%p]::RewindStream(); TimeToRewind=%lu
LastWriteTime=%lu TimedToBeSet=%c", 
+	    this, 
+	    ulTimeToRewind,
+	    ulLastWriteTime,
+	    bTimedToBeSet ? 'T' : 'F');
+
     while (m_pLastNMilliSecsList->GetCount() > 0)
     {
         pInfo = (HXAudioInfo*)
m_pLastNMilliSecsList->RemoveTail();
 -2645,7
+2661,7 
 void
 CHXAudioStream::Seek(UINT32 ulSeekTime)
 {
-    HXLOGL3(HXLOG_ADEV, "CHXAudioStream[%p]::Seek():
to = %lu", this, ulSeekTime);
+    HXLOGL3(HXLOG_ADEV, "CHXAudioStream[%p]::Seek():
SeekTime=%lu LastWriteTime=%lu", this, ulSeekTime,
m_ulBaseTime + ulSeekTime);
     m_llLastWriteTime	= CAST_TO_INT64 (m_ulBaseTime +
ulSeekTime);
 
     // XXX wschildbach: How to account for rollover?
 -2921,6
+2937,12 
     m_ulLastNTailTime += lTimeOffset;  
     m_llLastStartTimePlayed += lTimeOffset;
 
+    UINT32 ulLastWriteTime =
INT64_TO_UINT32(m_llLastWriteTime);
+    HXLOGL3(HXLOG_ADEV,
"CHXAudioStream[%p]::UpdatePacketTimeOffset():
TimeOffset=%ld LastWriteTime=%lu", 
+	    this, 
+	    lTimeOffset, 
+	    ulLastWriteTime);
+
     return rc;
 }
 
_______________________________________________
Protocol-dev mailing list
Protocol-devhelixcommunity.org
http://lists.helixcommunity.org/mailman/listinfo/pr
otocol-dev
[1]

about | contact  Other archives ( Real Estate discussion Medical topics )