Modified by: milko real.com
Date: 10:19:06
Project: Atlas
Synopsis: VS2 Deadlock Fix
Overview:
The change in base video renderer corrects the timing
induced deadlock
condition between base video renderer (and thus all video
renderers) when
operation in VideoSurface2 mode (Windows only). The
deadlock could occur
only on seek.
The deadlock conditions stems from attempt to Flush the
video surface2 and
complete Presentation of video surface 2 frame. The
presentation of
VideoSurface2 frame consists of 2 steps which must be
executed fully before
video surface2 will allow any other commands to be completed
(e.g. Flush):
1.) GetVideoMem
2.) Present or ReleaseVideoMem
Previous code was attenpting to acquire base video renderer
internal
Display mutex between the above two steps. It was possible
for seek
operation to execute such to acquire the base video renderer
internal
display mutex
preventing completion of video surface 2 frame presentation
completion
(step 2 above). Since Seek also invoked Flush on VS2, it
was not able to
complete due to incomplete VS2 frame presentation. Thus,
the deadlock.
The correction removes the base video renderer internal
mutex acquisition
between the presentation steps above.
This issue is present in cayenne as well and fix will need
to be
back-merged there as well.
Files Modified:
/datatype/common/vidrend/vidrend.cpp
/datatype/common/vidrend/pub/vidrend.h
Image Size and Heap Use impact (Client -Only):
insignificant
Platforms and Profiles Affected:
win32 - VS2 mode only
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: vidrend.cpp
============================================================
=======
RCS file: /cvsroot/datatype/common/vidrend/vidrend.cpp,v
retrieving revision 1.86
diff -u -w -r1.86 vidrend.cpp
--- vidrend.cpp 19 Oct 2006 23:18:21 -0000 1.86
+++ vidrend.cpp 20 Oct 2006 05:30:26 -0000
 -417,6
+417,7 
, m_bVS2BufferUnavailableOnLastBlt(FALSE)
, m_bVSBufferUndisplayed(FALSE)
, m_bPresentInProgress(FALSE)
+ , m_bVS2Flushed(FALSE)
, m_ulHWBufCount(DEFAULT_HARDWARE_BUFFER_COUNT)
,
m_ulConfigHWBufCount(DEFAULT_HARDWARE_BUFFER_COUNT)
, m_ulSyncInterval(SYNC_INTERVAL)
 -1371,6
+1372,17 
DisplayMutex_Lock();
+ if (m_pDecoderPump)
+ {
+ m_pDecoderPump->Suspend(FALSE);
+ m_pDecoderPump->Signal();
+ }
+
+ if (m_bUseVideoSurface2 && m_pMISUSSite)
+ {
+ FlushVideoSurface2(m_pMISUSSite);
+ }
+
// clean up the packet lists
m_pVideoFormat->SetStartTime(ulNewTime);
m_pVideoFormat->Reset();
 -1389,17
+1401,6 
m_ulActiveVideoTime = ulNewTime;
m_bVS2BufferUnavailableOnLastBlt = FALSE;
- if (m_pDecoderPump)
- {
- m_pDecoderPump->Suspend(FALSE);
- m_pDecoderPump->Signal();
- }
-
- if (m_bUseVideoSurface2 && m_pMISUSSite)
- {
- FlushVideoSurface2(m_pMISUSSite);
- }
-
DisplayMutex_Unlock();
// PostSeek signals the proper packets are to start
arriving
 -3273,11
+3274,8 
m_ulEarlyFrameTol = GetEarlyFrameTolerance();
HX_DELETE(m_pVSurf2InputBIH);
m_bUseVideoSurface2 = FALSE;
- if (m_bVS2BufferUnavailableOnLastBlt)
- {
m_bVS2BufferUnavailableOnLastBlt = FALSE;
}
- }
ReportStat(VS_SURFACE_MODE, (INT32) 1);
 -4565,6
+4563,16 
// are in in order to wait for the video memory to
become available
// as that is valid to do only when in Bltr thread.
HXBOOL bWaitForVideoMem =
(!m_bVideoSurface2Transition && !bSystemEvent);
+ HXBOOL bVS2BufferUnavailableOnLastBlt = FALSE;
+ // Remove current video packet as active in case we end up
disrrupting
+ // the display mutex below since if we do, we do not wish
current
+ // packet to be destroyed/replaced while we are
presenting.
+ CMediaPacket* pVideoPacket = m_pActiveVideoPacket;
+ HXBOOL bVideoPacketLocalized =
m_bActiveVideoPacketLocalized;
+ m_pActiveVideoPacket = NULL;
+
+ // We use this to detect if VS2 is flushed while
presenting
+ m_bVS2Flushed = FALSE;
m_bPresentInProgress = TRUE;
 -4572,6
+4580,12 
// the display mutex to allow refresh events to be
processed.
if (bWaitForVideoMem)
{
+ // Once we unlock the mutex, we must execute
GetVideoMem
+ // followed by Present/ReleaseVideoMem without any
interceding
+ // display mutex acquisitions. The reason is that
GetVideoMem
+ // locks the surface and site mutex inside the site
object
+ // and releases it only when Present or
ReleaseVideoMem
+ // is called.
DisplayMutex_Unlock();
}
 -4583,28
+4597,14 
bWaitForVideoMem ?
HX_WAIT_FOREVER : HX_WAIT_NEVER);
- m_bVS2BufferUnavailableOnLastBlt =
FAILED(retVal);
- }
-
- // If we have been waiting for video memory, we
have unlocked the
- // display mutex and we need to relock it to
proceed.
- if (bWaitForVideoMem)
- {
- DisplayMutex_Lock();
-
- // If the switch to VS1 occured after we
successfully obtained video
- // memory, fail this VS2 Blt
- if ((!m_bUseVideoSurface2) &&
SUCCEEDED(retVal))
- {
- retVal = HXR_FAIL;
- }
+ bVS2BufferUnavailableOnLastBlt = FAILED(retVal);
}
if (SUCCEEDED(retVal))
{
retVal = TransferOptimizedVideo(pVideoSurface2,
&videoMemoryInfo,
-
m_pActiveVideoPacket,
+ pVideoPacket,
m_BitmapInfoHeader,
sorcRect,
sorcRect);
 -4612,10
+4612,8 
if (SUCCEEDED(retVal))
{
- if (m_bFirstSurfaceUpdate)
+ if (m_bFirstSurfaceUpdate || m_bVS2Flushed)
{
- m_bFirstSurfaceUpdate = FALSE;
-
// If this is not a system event processing, than we are
not under the
// protection of TLS mutex. Present immediate will atemt
acquisition of TLS
// mutex which may cause a deadlock since Site may
already be holding a TLS
 -4634,7
+4632,7 
}
retVal = pVideoSurface2->Present(&videoMemoryInfo,
-
m_pActiveVideoPacket->m_ulTime,
+
pVideoPacket->m_ulTime,
HX_MODE_IMMEDIATE,
&destRect,
&sorcRect);
 -4649,7
+4647,7 
******/
{
HXLOGL4(HXLOG_BVID,
"CVideoRenderer::UpdateVideoSurface2()
PresentFirstFrame PTS=%lu",
- m_pActiveVideoPacket->m_ulTime);
+ pVideoPacket->m_ulTime);
retVal =
pVideoSurface2->Present(&videoMemoryInfo,
((ULONG32) -ComputeTimeAhead(0, 0)), // Current time
 -4661,10
+4659,10 
else
{
HXLOGL4(HXLOG_BVID,
"CVideoRenderer::UpdateVideoSurface2() PresentFrame
PTS=%lu",
- m_pActiveVideoPacket->m_ulTime);
+ pVideoPacket->m_ulTime);
retVal =
pVideoSurface2->Present(&videoMemoryInfo,
-
m_pActiveVideoPacket->m_ulTime,
+
pVideoPacket->m_ulTime,
HX_MODE_TIMED,
&destRect,
&sorcRect);
 -4676,6
+4674,50 
}
}
+ if (videoMemoryInfo.pVidMem != NULL)
+ {
+
pVideoSurface2->ReleaseVideoMem(&videoMemoryInfo);
+ }
+
+ // If we have been waiting for video memory, we have
unlocked the
+ // display mutex and we need to relock it to
proceed.
+ if (bWaitForVideoMem)
+ {
+ DisplayMutex_Lock();
+
+ // If the switch to VS1 occured after we
successfully obtained video
+ // memory, fail this VS2 Blt
+ if ((!m_bUseVideoSurface2) &&
SUCCEEDED(retVal))
+ {
+ retVal = HXR_FAIL;
+ }
+ }
+
+ // Restore the presented video packet back as the active
video packet
+ // to be used for refersh purposes unless onother packet
was made active
+ // in the mean-time.
+ if (m_pActiveVideoPacket)
+ {
+ // There is another video packet - discard our since
it is out of date.
+ ReleasePacket(pVideoPacket, bVideoPacketLocalized);
+ }
+ else
+ {
+ m_pActiveVideoPacket = pVideoPacket;
+ }
+
+ // We indicate this not the first surface update or if VS2
buffer was not
+ // available but only if VS2 has not been flushed while
presenting the
+ // frame above.
+ // If VS2 has been flushed, it inidcates a new sequence
and a new
+ // UpdateVideoSurface call is needed to clear the first
surface update
+ // state.
+ if (!m_bVS2Flushed)
+ {
+ m_bFirstSurfaceUpdate = FALSE;
+ m_bVS2BufferUnavailableOnLastBlt =
bVS2BufferUnavailableOnLastBlt;
+ }
+
m_bPresentInProgress = FALSE;
}
else if ((!m_bPresentInProgress) &&
bSystemEvent)
 -4744,12
+4786,12 
&sorcRect);
}
}
- }
if (videoMemoryInfo.pVidMem != NULL)
{
pVideoSurface2->ReleaseVideoMem(&videoMemoryInfo);
}
+ }
HX_RELEASE(pVideoSurface2);
 -4779,6
+4821,7 
if
(SUCCEEDED(pVideoSurface->QueryInterface(IID_IHXVideoSurf
ace2,
(void**) &pVideoSurface2)))
{
+ m_bVS2Flushed = TRUE;
pVideoSurface2->Flush();
pVideoSurface2->Release();
retVal = HXR_OK;
Index: pub/vidrend.h
============================================================
=======
RCS file: /cvsroot/datatype/common/vidrend/pub/vidrend.h,v
retrieving revision 1.43
diff -u -w -r1.43 vidrend.h
--- pub/vidrend.h 29 Sep 2006 03:15:57 -0000 1.43
+++ pub/vidrend.h 20 Oct 2006 05:30:26 -0000
 -225,6
+225,7 
HXBOOL m_bVS2BufferUnavailableOnLastBlt;
HXBOOL m_bVSBufferUndisplayed;
HXBOOL m_bPresentInProgress;
+ HXBOOL m_bVS2Flushed;
ULONG32 m_ulHWBufCount;
ULONG32 m_ulConfigHWBufCount;
ULONG32 m_ulSyncInterval;
_______________________________________________
Helix-client-dev mailing list
Helix-client-dev helixcommunity.org
http://lists.helixcommunity.org/mailman/listinf
o/helix-client-dev
|