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