[prev in list] [next in list] [prev in thread] [next in thread]
List: helix-server-cvs
Subject: [Server-cvs] engine/session clientsession.cpp,1.209,1.210
From: yijil () helixcommunity ! org
Date: 2013-06-27 2:45:15
[Download RAW message or body]
Update of /cvsroot/server/engine/session
In directory cvs01.internal.helixcommunity.org:/tmp/cvs-serv26012
Modified Files:
clientsession.cpp
Log Message:
Committed to: HEAD, SERVER_15_1_0_RN
Reviewed by: Richard
Synopsis
========
HLXSRV-382 [Vhost][SSPL]Seek a playlist file has error
Branches: HEAD, SERVER_15_1_0_RN
Reviewer: Anyone
Description
===========
Repro:
1. Server vhost configuration
<List Name="Vhost">
<Var EnableVhost="1"/>
<Var EnableCnameOnly="1"/>
<Var UserName="real"/>
<Var Password="real"/>
<Var VhostDirectory="/var/hms/Vhost/"/>
<Var CalcDiskInterval="60000"/>
<List Name="briantest">
<Var IdentifyString="briantest"/>
<Var CNAME="www.briantest.rhel5.com"/>
</List>
<List Name="Account1">
<Var IdentifyString="account1"/>
<Var CNAME="www.account1.rhel5.com"/>
</List>
2. Enable the FCS and SSPL in rmvhost.cfg 3. Request a playlist file in server \
rtsp://www.briantest.rhel5.com/briantest/mix/playlist_mp4.hpl 4. Seek it once
Expected:
Could play the clip form the seek point to the end of playlist
Actual:
Play the clip form the seek point, but the playback will hanging when the current \
clip played over Other Comments:
ROOT CAUSE:
After seek to clip2 as example, clip2 will be player successfully, but after clip2, \
it needs to switch to clip3. But it failed.
CSessionSourceControl::StreamDone()
{
...
m_pClientSession->ClipStreamDoneCalled();
...
}
void ClientSession::ClipStreamDoneCalled()
{
DPRINTF(D_ENTRY, ("ClientSession::ClipStreamDoneCalled() url\n"));
//XXXJJ If we get StreamDone here, the pending switch will not get
//the right packet to switch. We need to switch here.
if(m_pPacketShim && m_pPacketShim->IsSwitchPending())
{
m_pPacketShim->SwitchSourceNow();
}
else if(m_pPlaylistControl)
{
m_pPlaylistControl->GetNextMediaClip();
}
else if (!m_bDone && m_pCurrentSwitch) // if it is a valid fcs switch
{
SwitchSource();
}
}
BasePacketShim::Switch(IUnknown* pSource, HX_SWITCH_TYPE switch_type,
IHXStreamMapper* pMapper) {
...
m_bSwitchPending = TRUE;
...
}
In my test, "CSessionSourceControl::StreamDone" will be called before \
"BasePacketShim::Switch()" is called. In "BasePacketShim::Switch", it will set \
"m_bSwitchPending" to TRUE. When it occurs, "m_pPlaylistControl->GetNextMediaClip();" \
will be called in "ClientSession::ClipStreamDoneCalled" but \
"m_pPacketShim->SwitchSourceNow();". "m_pPlaylistControl->GetNextMediaClip();" will \
switch to clip4, but the right one is clip3. Which cause the playing failed.
MY FIX:
When " ClientSession::ClipStreamDoneCalled " is called, it not call code " \
m_pPacketShim->SwitchSourceNow();" and " m_pPlaylistControl->GetNextMediaClip();" \
directly. It will schedule a call back function to make sure "BasePacketShim::Switch" \
be called first.
Files Affected
==============
server/engine/session/clientsession.cpp
server/engine/session/pub/clientsession.h
Testing Performed
=================
Integration Tests
Index: clientsession.cpp
===================================================================
RCS file: /cvsroot/server/engine/session/clientsession.cpp,v
retrieving revision 1.209
retrieving revision 1.210
diff -u -d -r1.209 -r1.210
--- clientsession.cpp 18 Jun 2013 10:33:43 -0000 1.209
+++ clientsession.cpp 27 Jun 2013 02:45:07 -0000 1.210
@@ -255,6 +255,7 @@
, m_bNPTStartTimeSet(FALSE)
, m_aulSelectedRates (NULL)
, m_bSessionStartTimeSet(FALSE)
+ , m_nSwitchCallbackTimes(0)
{
m_pClient->AddRef();
@@ -6281,6 +6282,104 @@
return HXR_OK;
}
+ClientSession::SwitchCallback::SwitchCallback(ClientSession* pOwner) :
+ m_ulRefCount(0),
+ m_pOwner(pOwner)
+{
+ HX_ASSERT(m_pOwner != NULL);
+ m_pOwner->AddRef();
+}
+
+ClientSession::SwitchCallback::~SwitchCallback()
+{
+ HX_RELEASE(m_pOwner);
+}
+
+STDMETHODIMP
+ClientSession::SwitchCallback::QueryInterface(REFIID riid, void** ppvObj)
+{
+ if (IsEqualIID(riid, IID_IUnknown))
+ {
+ AddRef();
+ *ppvObj = this;
+ return HXR_OK;
+ }
+ else if (IsEqualIID(riid, IID_IHXCallback))
+ {
+ AddRef();
+ *ppvObj = (IHXCallback*)this;
+ return HXR_OK;
+ }
+
+ *ppvObj = NULL;
+ return HXR_NOINTERFACE;
+}
+
+/////////////////////////////////////////////////////////////////////////
+// Method:
+// IUnknown::AddRef
+// Purpose:
+// Everyone usually implements this the same... feel free to use
+// this implementation.
+//
+STDMETHODIMP_(ULONG32)
+ClientSession::SwitchCallback::AddRef()
+{
+ return InterlockedIncrement(&m_ulRefCount);
+}
+
+/////////////////////////////////////////////////////////////////////////
+// Method:
+// IUnknown::Release
+// Purpose:
+// Everyone usually implements this the same... feel free to use
+// this implementation.
+//
+STDMETHODIMP_(ULONG32)
+ClientSession::SwitchCallback::Release()
+{
+ if (InterlockedDecrement(&m_ulRefCount) > 0)
+ {
+ return m_ulRefCount;
+ }
+
+ delete this;
+ return 0;
+}
+
+STDMETHODIMP
+ClientSession::SwitchCallback::Func()
+{
+ m_pOwner->Switch();
+ return HXR_OK;
+}
+
+void
+ClientSession::Switch()
+{
+ m_nSwitchCallbackTimes++;
+
+ if(m_pPacketShim)
+ {
+ if (m_pPacketShim->IsSwitchPending())
+ {
+ m_nSwitchCallbackTimes = 0;
+ m_pPacketShim->SwitchSourceNow();
+ }
+ else if (m_nSwitchCallbackTimes <= 10)
+ {
+ SwitchCallback* pCallback = new SwitchCallback(this);
+ m_pClient->m_pProc->pc->engine->ischedule.enter(m_pClient->m_pProc->pc->engine->now
+ + Timeval(100000), pCallback);
+ }
+ else if(m_pPlaylistControl)
+ {
+ m_pPlaylistControl->GetNextMediaClip();
+ m_nSwitchCallbackTimes = 0;
+ }
+ }
+}
+
HX_RESULT
ClientSession::SessionSendControlBuffer(IHXBuffer* pBuffer)
{
@@ -7748,7 +7847,7 @@
{
if (m_pClientSession->IsStreamSetup(unStreamNumber))
{
- m_usStreamDoneCalled++;
+ m_usStreamDoneCalled++;
}
if(m_usStreamDoneCalled == m_usNumOfStreams)
@@ -8321,17 +8420,22 @@
DPRINTF(D_ENTRY, ("ClientSession::ClipStreamDoneCalled() url\n"));
//XXXJJ If we get StreamDone here, the pending switch will not get
//the right packet to switch. We need to switch here.
- if(m_pPacketShim && m_pPacketShim->IsSwitchPending())
- {
- m_pPacketShim->SwitchSourceNow();
- }
- else if(m_pPlaylistControl)
+ if (!m_pPlaylistControl && !m_bDone && m_pCurrentSwitch) // if it is a valid fcs \
switch {
- m_pPlaylistControl->GetNextMediaClip();
+ SwitchSource();
}
- else if (!m_bDone && m_pCurrentSwitch) // if it is a valid fcs switch
+ else if (m_pPacketShim)
{
- SwitchSource();
+ if (!m_pPacketShim->IsSwitchPending())
+ {
+ SwitchCallback* pCallback = new SwitchCallback(this);
+ m_pClient->m_pProc->pc->engine->ischedule.enter(m_pClient->m_pProc->pc->engine->now
+ + Timeval(100000), pCallback);
+ }
+ else
+ {
+ m_pPacketShim->SwitchSourceNow();
+ }
}
}
_______________________________________________
Server-cvs mailing list
Server-cvs@helixcommunity.org
http://lists.helixcommunity.org/mailman/listinfo/server-cvs
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic