List Info

Thread: CR-Client: VS2 Deadlock Fix




CR-Client: VS2 Deadlock Fix
user name
2006-10-20 05:58:03
Modified by: milkoreal.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-devhelixcommunity.org
http://lists.helixcommunity.org/mailman/listinf
o/helix-client-dev
CR-Client: VS2 Deadlock Fix
user name
2006-10-20 15:26:45
This looks good to me.

=============================================
Eric Hyche (ehychereal.com)
Technical Lead
RealNetworks, Inc.  

> -----Original Message-----
> From: helix-client-dev-bounceshelixcommunity.org 
> [mailto:helix-client-dev-bounceshelixcommunity.org] On 
> Behalf Of Milko Boic
> Sent: Friday, October 20, 2006 1:58 AM
> To: helix-client-devhelixcommunity.org
> Subject: [Helix-client-dev] CR-Client: VS2 Deadlock Fix
> 
> Modified by: milkoreal.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
> 


_______________________________________________
Helix-client-dev mailing list
Helix-client-devhelixcommunity.org
http://lists.helixcommunity.org/mailman/listinf
o/helix-client-dev
[1-2]

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