Maarten Lankhorst : quartz: Make acmwrapper code aware of time, and get rid of its internal buffer.

Alexandre Julliard julliard at winehq.org
Mon Mar 24 07:54:29 CDT 2008


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

Author: Maarten Lankhorst <m.b.lankhorst at gmail.com>
Date:   Fri Mar 21 14:55:03 2008 -0700

quartz: Make acmwrapper code aware of time, and get rid of its internal buffer.

---

 dlls/quartz/acmwrapper.c |   75 +++++++++++++++++++---------------------------
 1 files changed, 31 insertions(+), 44 deletions(-)

diff --git a/dlls/quartz/acmwrapper.c b/dlls/quartz/acmwrapper.c
index de90b81..4d5fbc9 100644
--- a/dlls/quartz/acmwrapper.c
+++ b/dlls/quartz/acmwrapper.c
@@ -41,19 +41,12 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(quartz);
 
-/* FIXME: Improve buffers management */
-#define OUTPUT_BUFFER_SIZE 15000
-#define INPUT_BUFFER_SIZE 4096
-
 typedef struct ACMWrapperImpl
 {
     TransformFilterImpl tf;
     HACMSTREAM has;
     LPWAVEFORMATEX pWfIn;
     LPWAVEFORMATEX pWfOut;
-    BYTE buffer[INPUT_BUFFER_SIZE];
-    DWORD max_size;
-    DWORD current_size;
     BOOL reinit_codec; /* FIXME: Should use sync points instead */
 } ACMWrapperImpl;
 
@@ -62,16 +55,14 @@ static HRESULT ACMWrapper_ProcessSampleData(TransformFilterImpl* pTransformFilte
     ACMWrapperImpl* This = (ACMWrapperImpl*)pTransformFilter;
     AM_MEDIA_TYPE amt;
     IMediaSample* pOutSample = NULL;
-    DWORD cbDstStream;
+    DWORD cbDstStream, cbSrcStream;
     LPBYTE pbDstStream;
-    DWORD cbSrcStream = 0;
     LPBYTE pbSrcStream = NULL;
     ACMSTREAMHEADER ash;
-    DWORD offset = 0;
-    BOOL stop = FALSE;
     BOOL unprepare_header = FALSE;
     MMRESULT res;
     HRESULT hr;
+    LONGLONG tStart = -1, tStop = -1, tMed;
 
     hr = IMediaSample_GetPointer(pSample, &pbSrcStream);
     if (FAILED(hr))
@@ -80,6 +71,7 @@ static HRESULT ACMWrapper_ProcessSampleData(TransformFilterImpl* pTransformFilte
 	return hr;
     }
 
+    IMediaSample_GetTime(pSample, &tStart, &tStop);
     cbSrcStream = IMediaSample_GetActualDataLength(pSample);
 
     TRACE("Sample data ptr = %p, size = %ld\n", pbSrcStream, (long)cbSrcStream);
@@ -90,21 +82,11 @@ static HRESULT ACMWrapper_ProcessSampleData(TransformFilterImpl* pTransformFilte
 	return hr;
     }
 
-    while(hr == S_OK && !stop)
+    ash.pbSrc = pbSrcStream;
+    ash.cbSrcLength = cbSrcStream;
+
+    while(hr == S_OK && ash.cbSrcLength)
     {
-	DWORD rem_buf = This->max_size - This->current_size;
-	DWORD rem_smp = cbSrcStream - offset;
-	DWORD copy_size = min(rem_buf, rem_smp);
-
-	memcpy(This->buffer + This->current_size, pbSrcStream + offset, copy_size);
-	This->current_size += copy_size;
-	offset += copy_size;
-
-	if (offset >= cbSrcStream)
-	    stop = TRUE;
-	if (This->current_size < This->max_size)
-	    break;
-  
 	hr = OutputPin_GetDeliveryBuffer((OutputPin*)This->tf.ppPins[1], &pOutSample, NULL, NULL, 0);
 	if (FAILED(hr)) {
 	    ERR("Unable to get delivery buffer (%x)\n", hr);
@@ -124,8 +106,6 @@ static HRESULT ACMWrapper_ProcessSampleData(TransformFilterImpl* pTransformFilte
 	ash.cbStruct = sizeof(ash);
 	ash.fdwStatus = 0;
 	ash.dwUser = 0;
-	ash.pbSrc = This->buffer;
-	ash.cbSrcLength = This->current_size;
 	ash.pbDst = pbDstStream;
 	ash.cbDstLength = cbDstStream;
 
@@ -133,7 +113,6 @@ static HRESULT ACMWrapper_ProcessSampleData(TransformFilterImpl* pTransformFilte
 	    ERR("Cannot prepare header %d\n", res);
 	    goto error;
 	}
-
 	unprepare_header = TRUE;
 
 	if ((res = acmStreamConvert(This->has, &ash, This->reinit_codec ? ACM_STREAMCONVERTF_START : 0))) {
@@ -143,17 +122,31 @@ static HRESULT ACMWrapper_ProcessSampleData(TransformFilterImpl* pTransformFilte
 	}
 	This->reinit_codec = FALSE;
 
-	TRACE("used in %u, used out %u\n", ash.cbSrcLengthUsed, ash.cbDstLengthUsed);
+	TRACE("used in %u/%u, used out %u/%u\n", ash.cbSrcLengthUsed, ash.cbSrcLength, ash.cbDstLengthUsed, ash.cbDstLength);
 
 	hr = IMediaSample_SetActualDataLength(pOutSample, ash.cbDstLengthUsed);
 	assert(hr == S_OK);
 
-	if (ash.cbSrcLengthUsed < ash.cbSrcLength) {
-	    This->current_size = ash.cbSrcLength - ash.cbSrcLengthUsed;
-	    memmove(This->buffer, This->buffer + ash.cbSrcLengthUsed, This->current_size);
-	}
-	else
-	    This->current_size = 0;
+        assert(ash.cbSrcLengthUsed);
+        TRACE("Sample start time: %lld.%03lld\n", (tStart/10000000), (tStart/10000)%1000);
+        if (ash.cbSrcLengthUsed == cbSrcStream)
+        {
+            IMediaSample_SetTime(pOutSample, &tStart, &tStop);
+            tStart = tStop;
+        }
+        else if (tStop != tStart)
+        {
+            tMed = tStop - tStart;
+            tMed = tStart + tMed * ash.cbSrcLengthUsed / cbSrcStream;
+            IMediaSample_SetTime(pOutSample, &tStart, &tMed);
+            tStart = tMed;
+        }
+        else
+        {
+            ERR("No valid timestamp found\n");
+            IMediaSample_SetTime(pOutSample, NULL, NULL);
+        }
+        TRACE("Sample stop time: %lld.%03lld\n", (tStart/10000000), (tStart/10000)%1000);
 
         hr = OutputPin_SendSample((OutputPin*)This->tf.ppPins[1], pOutSample);
         if (hr != S_OK && hr != VFW_E_NOT_CONNECTED) {
@@ -166,6 +159,8 @@ error:
         if (unprepare_header && (res = acmStreamUnprepareHeader(This->has, &ash, 0)))
             ERR("Cannot unprepare header %d\n", res);
         unprepare_header = FALSE;
+        ash.pbSrc += ash.cbSrcLengthUsed;
+        ash.cbSrcLength -= ash.cbSrcLengthUsed;
 
         if (pOutSample)
             IMediaSample_Release(pOutSample);
@@ -210,16 +205,8 @@ static HRESULT ACMWrapper_ConnectInput(TransformFilterImpl* pTransformFilter, co
         {
             This->has = drv;
 
-	    if ((res = acmStreamSize(drv, OUTPUT_BUFFER_SIZE, &This->max_size, ACM_STREAMSIZEF_DESTINATION))) {
-		ERR("Cannot retrieve input buffer size error %d!\n", res);
-		This->max_size = INPUT_BUFFER_SIZE;
-	    }
-
-	    TRACE("input buffer size %d\n", This->max_size);
-
             /* Update buffer size of media samples in output */
-            ((OutputPin*)This->tf.ppPins[1])->allocProps.cbBuffer = OUTPUT_BUFFER_SIZE;
-	    
+            ((OutputPin*)This->tf.ppPins[1])->allocProps.cbBuffer = This->pWfOut->nAvgBytesPerSec / 2;
             TRACE("Connection accepted\n");
             return S_OK;
         }




More information about the wine-cvs mailing list