Modified by: milko real.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-dev helixcommunity.org
http://lists.helixcommunity.org/mailman/listinfo/pr
otocol-dev
|