Maarten Lankhorst : quartz: Implement VideoRenderer_GetCurrentImage.

Alexandre Julliard julliard at winehq.org
Tue Jun 24 06:44:07 CDT 2008


Module: wine
Branch: master
Commit: dae09d000c96d1f26ef20585a4eb864b8e1d9bb2
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=dae09d000c96d1f26ef20585a4eb864b8e1d9bb2

Author: Maarten Lankhorst <m.b.lankhorst at gmail.com>
Date:   Tue Jun 10 18:45:25 2008 +0200

quartz: Implement VideoRenderer_GetCurrentImage.

---

 dlls/quartz/videorenderer.c |   80 +++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 78 insertions(+), 2 deletions(-)

diff --git a/dlls/quartz/videorenderer.c b/dlls/quartz/videorenderer.c
index fa3905e..bda9fdf 100644
--- a/dlls/quartz/videorenderer.c
+++ b/dlls/quartz/videorenderer.c
@@ -87,6 +87,9 @@ typedef struct VideoRendererImpl
     BOOL bAggregatable;
     REFERENCE_TIME rtLastStop;
     MediaSeekingImpl mediaSeeking;
+
+    /* During pause we can hold a single sample, for use in GetCurrentImage */
+    IMediaSample *sample_held;
 } VideoRendererImpl;
 
 static LRESULT CALLBACK VideoWndProcA(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
@@ -408,6 +411,15 @@ static HRESULT VideoRenderer_Sample(LPVOID iface, IMediaSample * pSample)
     }
 #endif
 
+    if (This->state == State_Paused)
+    {
+        if (This->sample_held)
+            IMediaSample_Release(This->sample_held);
+
+        This->sample_held = pSample;
+        IMediaSample_AddRef(pSample);
+    }
+
     if (This->pClock && This->state == State_Running)
     {
         REFERENCE_TIME time, trefstart, trefstop;
@@ -585,6 +597,7 @@ HRESULT VideoRenderer_create(IUnknown * pUnkOuter, LPVOID * ppv)
         MediaSeekingImpl_Init((IBaseFilter*)pVideoRenderer, VideoRendererImpl_Change, VideoRendererImpl_Change, VideoRendererImpl_Change, &pVideoRenderer->mediaSeeking, &pVideoRenderer->csFilter);
         pVideoRenderer->mediaSeeking.lpVtbl = &VideoRendererImpl_Seeking_Vtbl;
 
+        pVideoRenderer->sample_held = NULL;
         *ppv = (LPVOID)pVideoRenderer;
     }
     else
@@ -774,9 +787,15 @@ static HRESULT WINAPI VideoRenderer_Stop(IBaseFilter * iface)
     EnterCriticalSection(&This->csFilter);
     {
         This->state = State_Stopped;
+
+        if (This->sample_held)
+        {
+            IMediaSample_Release(This->sample_held);
+            This->sample_held = NULL;
+        }
     }
     LeaveCriticalSection(&This->csFilter);
-    
+
     return S_OK;
 }
 
@@ -812,6 +831,12 @@ static HRESULT WINAPI VideoRenderer_Run(IBaseFilter * iface, REFERENCE_TIME tSta
 
         This->rtStreamStart = tStart;
         This->state = State_Running;
+
+        if (This->sample_held)
+        {
+            IMediaSample_Release(This->sample_held);
+            This->sample_held = NULL;
+        }
     }
     LeaveCriticalSection(&This->csFilter);
 
@@ -1438,8 +1463,59 @@ static HRESULT WINAPI Basicvideo_GetCurrentImage(IBasicVideo *iface,
 						 long *pBufferSize,
 						 long *pDIBImage) {
     ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
+    BITMAPINFOHEADER *bmiHeader;
+    LONG needed_size;
+    AM_MEDIA_TYPE *amt = &This->pInputPin->pin.mtCurrent;
+    char *ptr;
+
+    EnterCriticalSection(&This->csFilter);
+
+    if (!This->sample_held)
+    {
+         LeaveCriticalSection(&This->csFilter);
+         return (This->state == State_Paused ? E_UNEXPECTED : VFW_E_NOT_PAUSED);
+    }
+
+    FIXME("(%p/%p)->(%p, %p): partial stub\n", This, iface, pBufferSize, pDIBImage);
 
-    FIXME("(%p/%p)->(%p, %p): stub !!!\n", This, iface, pBufferSize, pDIBImage);
+    if (IsEqualIID(&amt->formattype, &FORMAT_VideoInfo))
+    {
+        bmiHeader = &((VIDEOINFOHEADER *)amt->pbFormat)->bmiHeader;
+    }
+    else if (IsEqualIID(&amt->formattype, &FORMAT_VideoInfo2))
+    {
+        bmiHeader = &((VIDEOINFOHEADER2 *)amt->pbFormat)->bmiHeader;
+    }
+    else
+    {
+        FIXME("Unknown type %s\n", debugstr_guid(&amt->subtype));
+        LeaveCriticalSection(&This->csFilter);
+        return VFW_E_RUNTIME_ERROR;
+    }
+
+    needed_size = bmiHeader->biSize;
+    needed_size += IMediaSample_GetActualDataLength(This->sample_held);
+
+    if (!pDIBImage)
+    {
+        *pBufferSize = needed_size;
+        LeaveCriticalSection(&This->csFilter);
+        return S_OK;
+    }
+
+    if (needed_size < *pBufferSize)
+    {
+        ERR("Buffer too small %u/%lu\n", needed_size, *pBufferSize);
+        LeaveCriticalSection(&This->csFilter);
+        return E_FAIL;
+    }
+    *pBufferSize = needed_size;
+
+    memcpy(pDIBImage, bmiHeader, bmiHeader->biSize);
+    IMediaSample_GetPointer(This->sample_held, (BYTE **)&ptr);
+    memcpy((char *)pDIBImage + bmiHeader->biSize, ptr, IMediaSample_GetActualDataLength(This->sample_held));
+
+    LeaveCriticalSection(&This->csFilter);
 
     return S_OK;
 }




More information about the wine-cvs mailing list