84 DWORD cbDstStream, cbSrcStream;
91 LONGLONG tStart = -1, tStop = -1, tMed;
92 LONGLONG mtStart = -1, mtStop = -1, mtMed;
98 if (!
This->source.pMemInputPin)
100 WARN(
"Source is not connected, returning VFW_E_NOT_CONNECTED.\n");
104 if (
This->filter.state == State_Stopped)
107 if (
This->sink.flushing)
110 hr = IMediaSample_GetPointer(pSample, &pbSrcStream);
113 ERR(
"Failed to get input buffer pointer, hr %#lx.\n",
hr);
117 preroll = (IMediaSample_IsPreroll(pSample) ==
S_OK);
119 IMediaSample_GetTime(pSample, &tStart, &tStop);
120 if (IMediaSample_GetMediaTime(pSample, &mtStart, &mtStop) !=
S_OK)
121 mtStart = mtStop = -1;
122 cbSrcStream = IMediaSample_GetActualDataLength(pSample);
125 if (IMediaSample_IsDiscontinuity(pSample) ==
S_OK)
127 This->lasttime_real = tStart;
128 This->lasttime_sent = tStart;
130 else if (
This->lasttime_real == tStart)
131 tStart =
This->lasttime_sent;
133 WARN(
"Discontinuity\n");
138 ash.
pbSrc = pbSrcStream;
145 ERR(
"Failed to get sample, hr %#lx.\n",
hr);
148 IMediaSample_SetPreroll(pOutSample, preroll);
150 hr = IMediaSample_SetActualDataLength(pOutSample, 0);
153 hr = IMediaSample_GetPointer(pOutSample, &pbDstStream);
155 ERR(
"Failed to get output buffer pointer, hr %#lx.\n",
hr);
158 cbDstStream = IMediaSample_GetSize(pOutSample);
163 ash.
pbDst = pbDstStream;
167 ERR(
"Cannot prepare header %d\n",
res);
170 unprepare_header =
TRUE;
172 if (IMediaSample_IsDiscontinuity(pSample) ==
S_OK)
175 IMediaSample_SetDiscontinuity(pOutSample,
TRUE);
177 IMediaSample_SetDiscontinuity(pSample,
FALSE);
182 IMediaSample_SetDiscontinuity(pOutSample,
FALSE);
188 ERR(
"Cannot convert data header %d\n",
res);
208 IMediaSample_SetTime(pOutSample, &tStart, &tStop);
209 tStart = tMed = tStop;
211 else if (tStop != tStart)
213 tMed = tStop - tStart;
215 IMediaSample_SetTime(pOutSample, &tStart, &tMed);
220 ERR(
"No valid timestamp found\n");
221 IMediaSample_SetTime(pOutSample,
NULL,
NULL);
225 IMediaSample_SetMediaTime(pOutSample,
NULL,
NULL);
227 IMediaSample_SetMediaTime(pOutSample, &mtStart, &mtStop);
228 mtStart = mtMed = mtStop;
229 }
else if (mtStop >= mtStart) {
230 mtMed = mtStop - mtStart;
232 IMediaSample_SetMediaTime(pOutSample, &mtStart, &mtMed);
235 IMediaSample_SetMediaTime(pOutSample,
NULL,
NULL);
240 hr = IMemInputPin_Receive(
This->source.pMemInputPin, pOutSample);
243 ERR(
"Failed to send sample, hr %#lx.\n",
hr);
249 ERR(
"Cannot unprepare header %d\n",
res);
250 unprepare_header =
FALSE;
254 IMediaSample_Release(pOutSample);
259 This->lasttime_real = tStop;
260 This->lasttime_sent = tMed;
267 return !
memcmp(&
guid->Data2, &MEDIATYPE_Audio.Data2,
sizeof(
GUID) -
sizeof(
int));
278 || !
IsEqualGUID(&
mt->formattype, &FORMAT_WaveFormatEx) || !wfx
286 filter->pWfOut->wBitsPerSample = 16;
287 filter->pWfOut->nBlockAlign =
filter->pWfOut->wBitsPerSample *
filter->pWfOut->nChannels / 8;
288 filter->pWfOut->cbSize = 0;
289 filter->pWfOut->nAvgBytesPerSec =
filter->pWfOut->nChannels *
filter->pWfOut->nSamplesPerSec
290 * (
filter->pWfOut->wBitsPerSample / 8);
294 ERR(
"Failed to open stream, error %u.\n",
res);
328 *
out = &
filter->source_IQualityControl_iface;
366 if (!ppropInputRequest->
cbAlign)
367 ppropInputRequest->
cbAlign = 1;
369 if (ppropInputRequest->
cbBuffer <
filter->pWfOut->nAvgBytesPerSec / 2)
370 ppropInputRequest->
cbBuffer =
filter->pWfOut->nAvgBytesPerSec / 2;
375 return IMemAllocator_SetProperties(pAlloc, ppropInputRequest, &actual);
397 return IPin_QueryInterface(&
filter->source.pin.IPin_iface, iid,
out);
403 return IPin_AddRef(&
filter->source.pin.IPin_iface);
409 return IPin_Release(&
filter->source.pin.IPin_iface);
419 TRACE(
"filter %p, sender %p, type %#x, proportion %ld, late %s, timestamp %s.\n",
422 if (
filter->source_qc_sink)
423 return IQualityControl_Notify(
filter->source_qc_sink, &
filter->
filter.IBaseFilter_iface,
q);
426 &&
SUCCEEDED(IPin_QueryInterface(
filter->sink.pin.peer, &IID_IQualityControl, (
void **)&peer)))
428 hr = IQualityControl_Notify(peer, &
filter->
filter.IBaseFilter_iface,
q);
429 IQualityControl_Release(peer);
461 return &
filter->source.pin;
469 if (
filter->sink.pin.peer)
470 IPin_Disconnect(
filter->sink.pin.peer);
471 IPin_Disconnect(&
filter->sink.pin.IPin_iface);
473 if (
filter->source.pin.peer)
474 IPin_Disconnect(
filter->source.pin.peer);
475 IPin_Disconnect(&
filter->source.pin.IPin_iface);
492 ERR(
"Failed to commit allocator, hr %#lx.\n",
hr);
500 if (
filter->source.pin.peer)
501 IMemAllocator_Decommit(
filter->source.pAllocator);
517 if (!(
object =
calloc(1,
sizeof(*
object))))
530 ISeekingPassThru_Init(&
object->passthrough.ISeekingPassThru_iface,
FALSE,
531 &
object->sink.pin.IPin_iface);
533 object->lasttime_real =
object->lasttime_sent = -1;
535 TRACE(
"Created ACM wrapper %p.\n",
object);
536 *
out = &
object->filter.IUnknown_inner;
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
static BOOL is_audio_subtype(const GUID *guid)
static HRESULT WINAPI acm_wrapper_source_DecideBufferSize(struct strmbase_source *iface, IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *ppropInputRequest)
HRESULT acm_wrapper_create(IUnknown *outer, IUnknown **out)
static HRESULT acm_wrapper_sink_query_accept(struct strmbase_pin *iface, const AM_MEDIA_TYPE *mt)
static ULONG WINAPI acm_wrapper_source_qc_Release(IQualityControl *iface)
static HRESULT acm_wrapper_sink_connect(struct strmbase_sink *iface, IPin *peer, const AM_MEDIA_TYPE *mt)
static const IQualityControlVtbl source_qc_vtbl
static struct acm_wrapper * impl_from_strmbase_filter(struct strmbase_filter *iface)
static HRESULT WINAPI acm_wrapper_source_qc_Notify(IQualityControl *iface, IBaseFilter *sender, Quality q)
static HRESULT acm_wrapper_init_stream(struct strmbase_filter *iface)
static HRESULT acm_wrapper_source_get_media_type(struct strmbase_pin *iface, unsigned int index, AM_MEDIA_TYPE *mt)
static const struct strmbase_source_ops source_ops
static HRESULT acm_wrapper_source_query_interface(struct strmbase_pin *iface, REFIID iid, void **out)
static const struct strmbase_sink_ops sink_ops
static const struct strmbase_filter_ops filter_ops
static HRESULT acm_wrapper_source_query_accept(struct strmbase_pin *iface, const AM_MEDIA_TYPE *mt)
static struct strmbase_pin * acm_wrapper_get_pin(struct strmbase_filter *iface, unsigned int index)
static HRESULT acm_wrapper_cleanup_stream(struct strmbase_filter *iface)
static HRESULT WINAPI acm_wrapper_source_qc_QueryInterface(IQualityControl *iface, REFIID iid, void **out)
static struct acm_wrapper * impl_from_source_IQualityControl(IQualityControl *iface)
static ULONG WINAPI acm_wrapper_source_qc_AddRef(IQualityControl *iface)
static HRESULT WINAPI acm_wrapper_sink_Receive(struct strmbase_sink *iface, IMediaSample *pSample)
static HRESULT acm_wrapper_sink_query_interface(struct strmbase_pin *iface, REFIID iid, void **out)
static HRESULT WINAPI acm_wrapper_source_qc_SetSink(IQualityControl *iface, IQualityControl *sink)
static void acm_wrapper_sink_disconnect(struct strmbase_sink *iface)
static void acm_wrapper_destroy(struct strmbase_filter *iface)
MMRESULT WINAPI acmStreamClose(HACMSTREAM has, DWORD fdwClose)
MMRESULT WINAPI acmStreamPrepareHeader(HACMSTREAM has, PACMSTREAMHEADER pash, DWORD fdwPrepare)
MMRESULT WINAPI acmStreamConvert(HACMSTREAM has, PACMSTREAMHEADER pash, DWORD fdwConvert)
MMRESULT WINAPI acmStreamUnprepareHeader(HACMSTREAM has, PACMSTREAMHEADER pash, DWORD fdwUnprepare)
MMRESULT WINAPI acmStreamOpen(PHACMSTREAM phas, HACMDRIVER had, PWAVEFORMATEX pwfxSrc, PWAVEFORMATEX pwfxDst, PWAVEFILTER pwfltr, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen)
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
GLdouble GLdouble GLdouble GLdouble q
GLsizei GLenum GLboolean sink
#define MMSYSERR_MOREDATA
#define ACM_STREAMCONVERTF_START
#define IsEqualGUID(rguid1, rguid2)
static const char * debugstr_time(REFERENCE_TIME time)
HRESULT WINAPI CopyMediaType(AM_MEDIA_TYPE *pDest, const AM_MEDIA_TYPE *pSrc)
void WINAPI FreeMediaType(AM_MEDIA_TYPE *pMediaType)
HRESULT WINAPI BaseOutputPinImpl_DecideAllocator(struct strmbase_source *pin, IMemInputPin *peer, IMemAllocator **allocator)
void strmbase_passthrough_cleanup(struct strmbase_passthrough *passthrough)
void strmbase_source_init(struct strmbase_source *pin, struct strmbase_filter *filter, const WCHAR *name, const struct strmbase_source_ops *func_table)
void strmbase_sink_cleanup(struct strmbase_sink *pin)
void strmbase_sink_init(struct strmbase_sink *pin, struct strmbase_filter *filter, const WCHAR *name, const struct strmbase_sink_ops *ops, IMemAllocator *allocator)
void strmbase_filter_cleanup(struct strmbase_filter *filter)
void strmbase_passthrough_init(struct strmbase_passthrough *passthrough, IUnknown *outer)
void strmbase_source_cleanup(struct strmbase_source *pin)
void strmbase_filter_init(struct strmbase_filter *filter, IUnknown *outer, const CLSID *clsid, const struct strmbase_filter_ops *func_table)
HRESULT WINAPI BaseOutputPinImpl_AttemptConnection(struct strmbase_source *pin, IPin *peer, const AM_MEDIA_TYPE *mt)
struct strmbase_passthrough passthrough
IQualityControl * source_qc_sink
IQualityControl source_IQualityControl_iface
IMediaSeeking IMediaSeeking_iface
struct strmbase_filter * filter
#define CONTAINING_RECORD(address, type, field)
#define VFW_E_TYPE_NOT_ACCEPTED
#define VFW_E_WRONG_STATE
#define VFW_S_NO_MORE_ITEMS
#define VFW_E_NOT_CONNECTED
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out