mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-15 09:40:20 +00:00
quartz: Pass the media sample to the individual transform filter callbacks.
This is so the filters can pass on and use timing, discontinuity, and other information stored in the sample as needed.
This commit is contained in:
parent
e6e4056e1e
commit
eda96fa7f9
|
@ -59,21 +59,32 @@ typedef struct ACMWrapperImpl
|
||||||
BOOL reinit_codec; /* FIXME: Should use sync points instead */
|
BOOL reinit_codec; /* FIXME: Should use sync points instead */
|
||||||
} ACMWrapperImpl;
|
} ACMWrapperImpl;
|
||||||
|
|
||||||
static HRESULT ACMWrapper_ProcessSampleData(TransformFilterImpl* pTransformFilter, LPBYTE data, DWORD size)
|
static HRESULT ACMWrapper_ProcessSampleData(TransformFilterImpl* pTransformFilter, IMediaSample *pSample)
|
||||||
{
|
{
|
||||||
ACMWrapperImpl* This = (ACMWrapperImpl*)pTransformFilter;
|
ACMWrapperImpl* This = (ACMWrapperImpl*)pTransformFilter;
|
||||||
AM_MEDIA_TYPE amt;
|
AM_MEDIA_TYPE amt;
|
||||||
HRESULT hr;
|
IMediaSample* pOutSample = NULL;
|
||||||
IMediaSample* pSample = NULL;
|
|
||||||
DWORD cbDstStream;
|
DWORD cbDstStream;
|
||||||
LPBYTE pbDstStream;
|
LPBYTE pbDstStream;
|
||||||
|
DWORD cbSrcStream = 0;
|
||||||
|
LPBYTE pbSrcStream = NULL;
|
||||||
ACMSTREAMHEADER ash;
|
ACMSTREAMHEADER ash;
|
||||||
DWORD offset = 0;
|
DWORD offset = 0;
|
||||||
BOOL stop = FALSE;
|
BOOL stop = FALSE;
|
||||||
BOOL unprepare_header = FALSE;
|
BOOL unprepare_header = FALSE;
|
||||||
MMRESULT res;
|
MMRESULT res;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
TRACE("(%p)->(%p,%d)\n", This, data, size);
|
hr = IMediaSample_GetPointer(pSample, &pbSrcStream);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
ERR("Cannot get pointer to sample data (%x)\n", hr);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
cbSrcStream = IMediaSample_GetActualDataLength(pSample);
|
||||||
|
|
||||||
|
TRACE("Sample data ptr = %p, size = %ld\n", pbSrcStream, (long)cbSrcStream);
|
||||||
|
|
||||||
hr = IPin_ConnectionMediaType(This->tf.ppPins[0], &amt);
|
hr = IPin_ConnectionMediaType(This->tf.ppPins[0], &amt);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
|
@ -84,33 +95,33 @@ static HRESULT ACMWrapper_ProcessSampleData(TransformFilterImpl* pTransformFilte
|
||||||
while(hr == S_OK && !stop)
|
while(hr == S_OK && !stop)
|
||||||
{
|
{
|
||||||
DWORD rem_buf = This->max_size - This->current_size;
|
DWORD rem_buf = This->max_size - This->current_size;
|
||||||
DWORD rem_smp = size - offset;
|
DWORD rem_smp = cbSrcStream - offset;
|
||||||
DWORD copy_size = min(rem_buf, rem_smp);
|
DWORD copy_size = min(rem_buf, rem_smp);
|
||||||
|
|
||||||
memcpy(This->buffer + This->current_size, data + offset, copy_size);
|
memcpy(This->buffer + This->current_size, pbSrcStream + offset, copy_size);
|
||||||
This->current_size += copy_size;
|
This->current_size += copy_size;
|
||||||
offset += copy_size;
|
offset += copy_size;
|
||||||
|
|
||||||
if (offset >= size)
|
if (offset >= cbSrcStream)
|
||||||
stop = TRUE;
|
stop = TRUE;
|
||||||
if (This->current_size < This->max_size)
|
if (This->current_size < This->max_size)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
hr = OutputPin_GetDeliveryBuffer((OutputPin*)This->tf.ppPins[1], &pSample, NULL, NULL, 0);
|
hr = OutputPin_GetDeliveryBuffer((OutputPin*)This->tf.ppPins[1], &pOutSample, NULL, NULL, 0);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
ERR("Unable to get delivery buffer (%x)\n", hr);
|
ERR("Unable to get delivery buffer (%x)\n", hr);
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = IMediaSample_SetActualDataLength(pSample, 0);
|
hr = IMediaSample_SetActualDataLength(pOutSample, 0);
|
||||||
assert(hr == S_OK);
|
assert(hr == S_OK);
|
||||||
|
|
||||||
hr = IMediaSample_GetPointer(pSample, &pbDstStream);
|
hr = IMediaSample_GetPointer(pOutSample, &pbDstStream);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
ERR("Unable to get pointer to buffer (%x)\n", hr);
|
ERR("Unable to get pointer to buffer (%x)\n", hr);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
cbDstStream = IMediaSample_GetSize(pSample);
|
cbDstStream = IMediaSample_GetSize(pOutSample);
|
||||||
|
|
||||||
ash.cbStruct = sizeof(ash);
|
ash.cbStruct = sizeof(ash);
|
||||||
ash.fdwStatus = 0;
|
ash.fdwStatus = 0;
|
||||||
|
@ -135,7 +146,7 @@ static HRESULT ACMWrapper_ProcessSampleData(TransformFilterImpl* pTransformFilte
|
||||||
|
|
||||||
TRACE("used in %u, used out %u\n", ash.cbSrcLengthUsed, ash.cbDstLengthUsed);
|
TRACE("used in %u, used out %u\n", ash.cbSrcLengthUsed, ash.cbDstLengthUsed);
|
||||||
|
|
||||||
hr = IMediaSample_SetActualDataLength(pSample, ash.cbDstLengthUsed);
|
hr = IMediaSample_SetActualDataLength(pOutSample, ash.cbDstLengthUsed);
|
||||||
assert(hr == S_OK);
|
assert(hr == S_OK);
|
||||||
|
|
||||||
if (ash.cbSrcLengthUsed < ash.cbSrcLength) {
|
if (ash.cbSrcLengthUsed < ash.cbSrcLength) {
|
||||||
|
@ -145,7 +156,7 @@ static HRESULT ACMWrapper_ProcessSampleData(TransformFilterImpl* pTransformFilte
|
||||||
else
|
else
|
||||||
This->current_size = 0;
|
This->current_size = 0;
|
||||||
|
|
||||||
hr = OutputPin_SendSample((OutputPin*)This->tf.ppPins[1], pSample);
|
hr = OutputPin_SendSample((OutputPin*)This->tf.ppPins[1], pOutSample);
|
||||||
if (hr != S_OK && hr != VFW_E_NOT_CONNECTED) {
|
if (hr != S_OK && hr != VFW_E_NOT_CONNECTED) {
|
||||||
ERR("Error sending sample (%x)\n", hr);
|
ERR("Error sending sample (%x)\n", hr);
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -156,9 +167,9 @@ error:
|
||||||
ERR("Cannot unprepare header %d\n", res);
|
ERR("Cannot unprepare header %d\n", res);
|
||||||
unprepare_header = FALSE;
|
unprepare_header = FALSE;
|
||||||
|
|
||||||
if (pSample)
|
if (pOutSample)
|
||||||
IMediaSample_Release(pSample);
|
IMediaSample_Release(pOutSample);
|
||||||
pSample = NULL;
|
pOutSample = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return hr;
|
return hr;
|
||||||
|
|
|
@ -72,19 +72,30 @@ static HRESULT AVIDec_ProcessBegin(TransformFilterImpl* pTransformFilter)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT AVIDec_ProcessSampleData(TransformFilterImpl* pTransformFilter, LPBYTE data, DWORD size)
|
static HRESULT AVIDec_ProcessSampleData(TransformFilterImpl* pTransformFilter, IMediaSample *pSample)
|
||||||
{
|
{
|
||||||
AVIDecImpl* This = (AVIDecImpl*)pTransformFilter;
|
AVIDecImpl* This = (AVIDecImpl*)pTransformFilter;
|
||||||
VIDEOINFOHEADER* format;
|
VIDEOINFOHEADER* format;
|
||||||
AM_MEDIA_TYPE amt;
|
AM_MEDIA_TYPE amt;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
DWORD res;
|
DWORD res;
|
||||||
IMediaSample* pSample = NULL;
|
IMediaSample* pOutSample = NULL;
|
||||||
DWORD cbDstStream;
|
DWORD cbDstStream;
|
||||||
LPBYTE pbDstStream;
|
LPBYTE pbDstStream;
|
||||||
|
DWORD cbSrcStream;
|
||||||
|
LPBYTE pbSrcStream;
|
||||||
|
|
||||||
|
hr = IMediaSample_GetPointer(pSample, &pbSrcStream);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
ERR("Cannot get pointer to sample data (%x)\n", hr);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
cbSrcStream = IMediaSample_GetActualDataLength(pSample);
|
||||||
|
|
||||||
|
TRACE("Sample data ptr = %p, size = %ld\n", pbSrcStream, (long)cbSrcStream);
|
||||||
|
|
||||||
TRACE("(%p)->(%p,%d)\n", This, data, size);
|
|
||||||
|
|
||||||
hr = IPin_ConnectionMediaType(This->tf.ppPins[0], &amt);
|
hr = IPin_ConnectionMediaType(This->tf.ppPins[0], &amt);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
ERR("Unable to retrieve media type\n");
|
ERR("Unable to retrieve media type\n");
|
||||||
|
@ -93,42 +104,42 @@ static HRESULT AVIDec_ProcessSampleData(TransformFilterImpl* pTransformFilter, L
|
||||||
format = (VIDEOINFOHEADER*)amt.pbFormat;
|
format = (VIDEOINFOHEADER*)amt.pbFormat;
|
||||||
|
|
||||||
/* Update input size to match sample size */
|
/* Update input size to match sample size */
|
||||||
This->pBihIn->biSizeImage = size;
|
This->pBihIn->biSizeImage = cbSrcStream;
|
||||||
|
|
||||||
hr = OutputPin_GetDeliveryBuffer((OutputPin*)This->tf.ppPins[1], &pSample, NULL, NULL, 0);
|
hr = OutputPin_GetDeliveryBuffer((OutputPin*)This->tf.ppPins[1], &pOutSample, NULL, NULL, 0);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
ERR("Unable to get delivery buffer (%x)\n", hr);
|
ERR("Unable to get delivery buffer (%x)\n", hr);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = IMediaSample_SetActualDataLength(pSample, 0);
|
hr = IMediaSample_SetActualDataLength(pOutSample, 0);
|
||||||
assert(hr == S_OK);
|
assert(hr == S_OK);
|
||||||
|
|
||||||
hr = IMediaSample_GetPointer(pSample, &pbDstStream);
|
hr = IMediaSample_GetPointer(pOutSample, &pbDstStream);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
ERR("Unable to get pointer to buffer (%x)\n", hr);
|
ERR("Unable to get pointer to buffer (%x)\n", hr);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
cbDstStream = IMediaSample_GetSize(pSample);
|
cbDstStream = IMediaSample_GetSize(pOutSample);
|
||||||
if (cbDstStream < This->pBihOut->biSizeImage) {
|
if (cbDstStream < This->pBihOut->biSizeImage) {
|
||||||
ERR("Sample size is too small %d < %d\n", cbDstStream, This->pBihOut->biSizeImage);
|
ERR("Sample size is too small %d < %d\n", cbDstStream, This->pBihOut->biSizeImage);
|
||||||
hr = E_FAIL;
|
hr = E_FAIL;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = ICDecompress(This->hvid, 0, This->pBihIn, data, This->pBihOut, pbDstStream);
|
res = ICDecompress(This->hvid, 0, This->pBihIn, pbSrcStream, This->pBihOut, pbDstStream);
|
||||||
if (res != ICERR_OK)
|
if (res != ICERR_OK)
|
||||||
ERR("Error occurred during the decompression (%x)\n", res);
|
ERR("Error occurred during the decompression (%x)\n", res);
|
||||||
|
|
||||||
hr = OutputPin_SendSample((OutputPin*)This->tf.ppPins[1], pSample);
|
hr = OutputPin_SendSample((OutputPin*)This->tf.ppPins[1], pOutSample);
|
||||||
if (hr != S_OK && hr != VFW_E_NOT_CONNECTED) {
|
if (hr != S_OK && hr != VFW_E_NOT_CONNECTED) {
|
||||||
ERR("Error sending sample (%x)\n", hr);
|
ERR("Error sending sample (%x)\n", hr);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
error:
|
error:
|
||||||
if (pSample)
|
if (pOutSample)
|
||||||
IMediaSample_Release(pSample);
|
IMediaSample_Release(pOutSample);
|
||||||
|
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,42 +57,10 @@ static const IPinVtbl TransformFilter_OutputPin_Vtbl;
|
||||||
static HRESULT TransformFilter_Sample(LPVOID iface, IMediaSample * pSample)
|
static HRESULT TransformFilter_Sample(LPVOID iface, IMediaSample * pSample)
|
||||||
{
|
{
|
||||||
TransformFilterImpl *This = (TransformFilterImpl *)iface;
|
TransformFilterImpl *This = (TransformFilterImpl *)iface;
|
||||||
LPBYTE pbSrcStream = NULL;
|
|
||||||
long cbSrcStream = 0;
|
|
||||||
REFERENCE_TIME tStart, tStop;
|
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
TRACE("%p %p\n", iface, pSample);
|
TRACE("%p %p\n", iface, pSample);
|
||||||
|
|
||||||
hr = IMediaSample_GetPointer(pSample, &pbSrcStream);
|
return This->pFuncsTable->pfnProcessSampleData(This, pSample);
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
|
||||||
ERR("Cannot get pointer to sample data (%x)\n", hr);
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
hr = IMediaSample_GetTime(pSample, &tStart, &tStop);
|
|
||||||
if (FAILED(hr))
|
|
||||||
ERR("Cannot get sample time (%x)\n", hr);
|
|
||||||
|
|
||||||
cbSrcStream = IMediaSample_GetActualDataLength(pSample);
|
|
||||||
|
|
||||||
TRACE("Sample data ptr = %p, size = %ld\n", pbSrcStream, cbSrcStream);
|
|
||||||
|
|
||||||
#if 0 /* For debugging purpose */
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for(i = 0; i < cbSrcStream; i++)
|
|
||||||
{
|
|
||||||
if ((i!=0) && !(i%16))
|
|
||||||
TRACE("\n");
|
|
||||||
TRACE("%02x ", pbSrcStream[i]);
|
|
||||||
}
|
|
||||||
TRACE("\n");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return This->pFuncsTable->pfnProcessSampleData(This, pbSrcStream, cbSrcStream);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT TransformFilter_Input_QueryAccept(LPVOID iface, const AM_MEDIA_TYPE * pmt)
|
static HRESULT TransformFilter_Input_QueryAccept(LPVOID iface, const AM_MEDIA_TYPE * pmt)
|
||||||
|
|
|
@ -22,7 +22,7 @@ typedef struct TransformFilterImpl TransformFilterImpl;
|
||||||
|
|
||||||
typedef struct TransformFuncsTable {
|
typedef struct TransformFuncsTable {
|
||||||
HRESULT (*pfnProcessBegin) (TransformFilterImpl* This);
|
HRESULT (*pfnProcessBegin) (TransformFilterImpl* This);
|
||||||
HRESULT (*pfnProcessSampleData) (TransformFilterImpl* This, LPBYTE data, DWORD size);
|
HRESULT (*pfnProcessSampleData) (TransformFilterImpl* This, IMediaSample *pSample);
|
||||||
HRESULT (*pfnProcessEnd) (TransformFilterImpl* This);
|
HRESULT (*pfnProcessEnd) (TransformFilterImpl* This);
|
||||||
HRESULT (*pfnQueryConnect) (TransformFilterImpl* This, const AM_MEDIA_TYPE * pmt);
|
HRESULT (*pfnQueryConnect) (TransformFilterImpl* This, const AM_MEDIA_TYPE * pmt);
|
||||||
HRESULT (*pfnConnectInput) (TransformFilterImpl* This, const AM_MEDIA_TYPE * pmt);
|
HRESULT (*pfnConnectInput) (TransformFilterImpl* This, const AM_MEDIA_TYPE * pmt);
|
||||||
|
|
Loading…
Reference in a new issue