120 DWORD size1, size2, playpos,
writepos, old_writepos, old_playpos, adv;
124 old_writepos =
filter->writepos;
125 old_playpos =
filter->last_playpos;
126 if (old_writepos <= old_playpos)
127 old_writepos +=
filter->buf_size;
130 if (old_playpos > playpos)
131 adv =
filter->buf_size + playpos - old_playpos;
133 adv = playpos - old_playpos;
134 filter->last_playpos = playpos;
137 TRACE(
"Moving from %lu to %lu: clearing %lu bytes.\n", old_playpos, playpos, adv);
139 (
void **)&buf1, &size1, (
void **)&buf2, &size2, 0);
145 if (!writepos_set || old_writepos <
writepos)
150 FIXME(
"Underrun of data occurred!\n");
155 *seqwritepos =
filter->writepos;
166 playpos =
filter->last_playpos;
192 delta_t = write_at - writepos_t;
193 TRACE(
"Last sample end %s, this sample start %s.\n",
195 if (delta_t <= max_lag)
203 TRACE(
"Difference %s is less than threshold %s; treating sample as continuous.\n",
212 WARN(
"Advancing %lu bytes.\n", aheadbytes);
215 *ret_writepos = (min_writepos + aheadbytes) %
filter->buf_size;
218 if (playpos >= *ret_writepos)
219 *pfree = playpos - *ret_writepos;
221 *pfree =
filter->buf_size + playpos - *ret_writepos;
250 TRACE(
"Flush signaled; discarding sample.\n");
258 (
void **)&buf1, &size1, (
void **)&buf2, &size2, 0);
261 ERR(
"Failed to lock sound buffer, hr %#lx.\n",
hr);
270 data += size1 + size2;
277 memset(buf1, silence, size1);
279 memset(buf2, silence, size2);
283 TRACE(
"Wrote %lu bytes at %lu, next at %lu - (%lu/%lu)\n",
285 size -= size1 + size2;
295 if (IMediaSample_GetMediaType(pSample, &amt) ==
S_OK)
301 TRACE(
"Format change.\n");
304 if (origfmt->
wFormatTag == newfmt->wFormatTag &&
305 origfmt->
nChannels == newfmt->nChannels &&
308 origfmt->
cbSize == newfmt->cbSize)
313 newfmt->nSamplesPerSec);
318 IMediaSample_SetMediaType(pSample,
NULL);
331 LONG cbSrcStream = 0;
334 hr = IMediaSample_GetPointer(pSample, &pbSrcStream);
337 ERR(
"Failed to get buffer pointer, hr %#lx.\n",
hr);
341 if (IMediaSample_IsDiscontinuity(pSample) ==
S_OK
342 &&
FAILED(
hr = IMediaSample_GetTime(pSample, &
start, &stop)))
344 ERR(
"Failed to get sample time, hr %#lx.\n",
hr);
348 cbSrcStream = IMediaSample_GetActualDataLength(pSample);
356 TRACE(
"Render thread started.\n");
360 while (!
filter->render_thread_shutdown)
371 TRACE(
"Render thread exiting.\n");
375 if (!
filter->queued_sample_count)
382 if (--
filter->queued_sample_count)
384 filter->queued_sample_count *
sizeof(*
filter->queued_samples));
389 IMediaSample_Release(
sample);
395 TRACE(
"Render thread exiting.\n");
421 filter->queued_sample_count + 1,
sizeof(*
filter->queued_samples)))
428 IMediaSample_AddRef(
sample);
450 if (!
IsEqualIID(&pmt->majortype, &MEDIATYPE_Audio))
470 buf_desc.dwBufferBytes =
filter->buf_size;
475 ERR(
"Failed to create sound buffer, hr %#lx.\n",
hr);
481 ERR(
"Failed to set volume to %ld, hr %#lx.\n",
filter->volume,
hr);
485 ERR(
"Failed to set pan to %ld, hr %#lx.\n",
filter->pan,
hr);
523 &IID_IMediaEventSink, (
void **)&event_sink)))
527 IMediaEventSink_Release(event_sink);
601 IUnknown_Release(
filter->system_clock);
603 if (
filter->sink.pin.peer)
604 IPin_Disconnect(
filter->sink.pin.peer);
605 IPin_Disconnect(&
filter->sink.pin.IPin_iface);
611 filter->render_cs.DebugInfo->Spare[0] = 0;
637 *
out = &
filter->passthrough.IMediaPosition_iface;
643 return IUnknown_QueryInterface(
filter->system_clock, iid,
out);
658 if (!
filter->sink.pin.peer)
663 filter->render_thread_shutdown =
false;
680 if (
filter->sink.pin.peer)
685 &IID_IMediaEventSink, (
void **)&event_sink)))
689 IMediaEventSink_Release(event_sink);
699 if (
filter->sink.pin.peer)
714 if (
filter->render_thread)
717 filter->render_thread_shutdown =
true;
724 for (
unsigned int i = 0;
i <
filter->queued_sample_count; ++
i)
725 IMediaSample_Release(
filter->queued_samples[
i]);
726 filter->queued_sample_count = 0;
798 TRACE(
"filter %p, iid %s, names %p, count %u, lcid %lu, ids %p.\n",
815 TRACE(
"filter %p, id %ld, iid %s, lcid %lu, flags %u, params %p, result %p, excepinfo %p, error_arg %p.\n",
859 TRACE(
"filter %p, balance %ld.\n",
filter, balance);
875 TRACE(
"filter %p, balance %p.\n",
filter, balance);
1033 FIXME(
"filter %p, sender %p, type %#x, proportion %ld, late %s, timestamp %s, stub!\n",
1066 IDirectSoundBuffer *
buffer;
1071 if (!(
object =
calloc(1,
sizeof(*
object))))
1085 IUnknown_Release(
object->system_clock);
1095 IUnknown_Release(
object->system_clock);
1109 ISeekingPassThru_Init(&
object->passthrough.ISeekingPassThru_iface,
TRUE, &
object->sink.pin.IPin_iface);
1121 object->render_cs.DebugInfo->Spare[0] = (
DWORD_PTR)(__FILE__
": dsound_render.render_cs");
1124 TRACE(
"Created DirectSound renderer %p.\n",
object);
1125 *
out = &
object->filter.IUnknown_inner;
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
static BOOL array_reserve(void **elements, unsigned int *capacity, unsigned int count, unsigned int size)
HRESULT WINAPI DirectSoundCreate8(LPCGUID lpcGUID, LPDIRECTSOUND8 *ppDS, IUnknown *pUnkOuter)
static HRESULT dsound_render_init_stream(struct strmbase_filter *iface)
static HRESULT dsound_render_sink_end_flush(struct strmbase_sink *iface)
static REFERENCE_TIME time_from_pos(struct dsound_render *filter, DWORD pos)
static HRESULT dsound_render_sink_begin_flush(struct strmbase_sink *iface)
static ULONG WINAPI direct_sound_AddRef(IAMDirectSound *iface)
static HRESULT dsound_render_sink_connect(struct strmbase_sink *iface, IPin *peer, const AM_MEDIA_TYPE *mt)
static const IAMDirectSoundVtbl direct_sound_vtbl
static HRESULT WINAPI quality_control_QueryInterface(IQualityControl *iface, REFIID iid, void **out)
static void dsound_render_sink_disconnect(struct strmbase_sink *iface)
static const REFERENCE_TIME DSoundRenderer_Max_Fill
static ULONG WINAPI direct_sound_Release(IAMDirectSound *iface)
static HRESULT dsound_render_sink_eos(struct strmbase_sink *iface)
static const IQualityControlVtbl quality_control_vtbl
HRESULT dsound_render_create(IUnknown *outer, IUnknown **out)
static ULONG WINAPI basic_audio_AddRef(IBasicAudio *iface)
static struct dsound_render * impl_from_IBasicAudio(IBasicAudio *iface)
static void dsound_render_destroy(struct strmbase_filter *iface)
static HRESULT dsound_render_sink_query_interface(struct strmbase_pin *iface, REFIID iid, void **out)
static HRESULT dsound_render_stop_stream(struct strmbase_filter *iface)
static HRESULT WINAPI basic_audio_GetTypeInfo(IBasicAudio *iface, UINT index, LCID lcid, ITypeInfo **typeinfo)
static HRESULT WINAPI direct_sound_GetSecondaryBufferInterface(IAMDirectSound *iface, IDirectSoundBuffer **buf)
static DWORD WINAPI render_thread_run(void *arg)
static HRESULT WINAPI direct_sound_QueryInterface(IAMDirectSound *iface, REFIID riid, void **out)
static HRESULT WINAPI basic_audio_GetIDsOfNames(IBasicAudio *iface, REFIID iid, LPOLESTR *names, UINT count, LCID lcid, DISPID *ids)
static HRESULT send_sample_data(struct dsound_render *filter, REFERENCE_TIME tStart, const BYTE *data, DWORD size)
static HRESULT dsound_render_query_interface(struct strmbase_filter *iface, REFIID iid, void **out)
static HRESULT WINAPI dsound_render_sink_Receive(struct strmbase_sink *iface, IMediaSample *sample)
static HRESULT WINAPI basic_audio_put_Volume(IBasicAudio *iface, LONG volume)
static HRESULT WINAPI basic_audio_get_Volume(IBasicAudio *iface, LONG *volume)
static HRESULT WINAPI direct_sound_GetFocusWindow(IAMDirectSound *iface, HWND *hwnd, BOOL *bgaudible)
static HRESULT dsound_render_sink_query_accept(struct strmbase_pin *iface, const AM_MEDIA_TYPE *pmt)
static HRESULT WINAPI basic_audio_put_Balance(IBasicAudio *iface, LONG balance)
static HRESULT WINAPI basic_audio_GetTypeInfoCount(IBasicAudio *iface, UINT *count)
static HRESULT WINAPI direct_sound_GetPrimaryBufferInterface(IAMDirectSound *iface, IDirectSoundBuffer **buf)
static HRESULT WINAPI basic_audio_Invoke(IBasicAudio *iface, DISPID id, REFIID iid, LCID lcid, WORD flags, DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *error_arg)
static const struct strmbase_sink_ops sink_ops
static HRESULT WINAPI quality_control_Notify(IQualityControl *iface, IBaseFilter *sender, Quality q)
static struct dsound_render * impl_from_IAMDirectSound(IAMDirectSound *iface)
static const struct strmbase_filter_ops filter_ops
static DWORD pos_from_time(struct dsound_render *filter, REFERENCE_TIME time)
static HRESULT WINAPI quality_control_SetSink(IQualityControl *iface, IQualityControl *sink)
static HRESULT WINAPI basic_audio_get_Balance(IBasicAudio *iface, LONG *balance)
static ULONG WINAPI quality_control_AddRef(IQualityControl *iface)
static struct dsound_render * impl_from_IQualityControl(IQualityControl *iface)
static HRESULT render_sample(struct dsound_render *filter, IMediaSample *pSample)
static ULONG WINAPI basic_audio_Release(IBasicAudio *iface)
static struct dsound_render * impl_from_strmbase_pin(struct strmbase_pin *iface)
static const IBasicAudioVtbl basic_audio_vtbl
static HRESULT WINAPI direct_sound_ReleaseDirectSoundInterface(IAMDirectSound *iface, IDirectSound *ds)
static struct dsound_render * impl_from_strmbase_filter(struct strmbase_filter *iface)
static HRESULT WINAPI direct_sound_ReleasePrimaryBufferInterface(IAMDirectSound *iface, IDirectSoundBuffer *buf)
static HRESULT get_write_pos(struct dsound_render *filter, DWORD *ret_writepos, REFERENCE_TIME write_at, DWORD *pfree)
static HRESULT configure_buffer(struct dsound_render *filter, IMediaSample *pSample)
static ULONG WINAPI quality_control_Release(IQualityControl *iface)
static HRESULT WINAPI basic_audio_QueryInterface(IBasicAudio *iface, REFIID riid, void **out)
static void update_positions(struct dsound_render *filter, DWORD *seqwritepos, DWORD *minwritepos)
static HRESULT WINAPI direct_sound_ReleaseSecondaryBufferInterface(IAMDirectSound *iface, IDirectSoundBuffer *buf)
static HRESULT WINAPI direct_sound_GetDirectSoundInterface(IAMDirectSound *iface, IDirectSound **ds)
static HRESULT dsound_render_start_stream(struct strmbase_filter *iface, REFERENCE_TIME start)
static HRESULT WINAPI direct_sound_SetFocusWindow(IAMDirectSound *iface, HWND hwnd, BOOL bgaudible)
static HRESULT dsound_render_cleanup_stream(struct strmbase_filter *iface)
static struct strmbase_pin * dsound_render_get_pin(struct strmbase_filter *iface, unsigned int index)
static HRESULT dsound_render_wait_state(struct strmbase_filter *iface, DWORD timeout)
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
BOOL WINAPI SleepConditionVariableCS(PCONDITION_VARIABLE ConditionVariable, PCRITICAL_SECTION CriticalSection, DWORD Timeout)
VOID WINAPI InitializeConditionVariable(PCONDITION_VARIABLE ConditionVariable)
BOOL WINAPI InitializeCriticalSectionEx(OUT LPCRITICAL_SECTION lpCriticalSection, IN DWORD dwSpinCount, IN DWORD flags)
VOID WINAPI WakeConditionVariable(PCONDITION_VARIABLE ConditionVariable)
#define IDirectSound8_CreateSoundBuffer(p, a, b, c)
struct _DSBUFFERDESC DSBUFFERDESC
#define IDirectSoundBuffer_Unlock(p, a, b, c, d)
#define DSBCAPS_GLOBALFOCUS
#define DSBCAPS_CTRLVOLUME
struct IDirectSoundBuffer * LPDIRECTSOUNDBUFFER
#define IDirectSoundBuffer_GetCurrentPosition(p, a, b)
#define DSBCAPS_GETCURRENTPOSITION2
#define DSBLOCK_ENTIREBUFFER
#define IDirectSoundBuffer_Stop(p)
#define IDirectSoundBuffer_SetPan(p, a)
#define DSBCAPS_CTRLFREQUENCY
#define IDirectSound8_Release(p)
#define IDirectSoundBuffer_Play(p, a, b, c)
#define IDirectSoundBuffer_SetVolume(p, a)
#define IDirectSoundBuffer_SetFrequency(p, a)
#define IDirectSoundBuffer_Lock(p, a, b, c, d, e, f, g)
#define IDirectSoundBuffer_Release(p)
#define DSBCAPS_PRIMARYBUFFER
#define IDirectSound8_SetCooperativeLevel(p, a, b)
GLuint GLuint GLsizei count
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
GLdouble GLdouble GLdouble GLdouble q
GLenum const GLfloat * params
GLenum GLuint GLenum GLsizei const GLchar * buf
GLsizei GLenum GLboolean sink
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
#define memcpy(s1, s2, n)
#define memmove(s1, s2, n)
static EXCEPINFO excepinfo
static VARIANTARG static DISPID
_In_ LPWSTR _In_ DWORD _In_ DWORD _In_ DWORD dwFlags
#define IsEqualGUID(rguid1, rguid2)
#define IsEqualIID(riid1, riid2)
HWND WINAPI GetDesktopWindow(void)
HRESULT system_clock_create(IUnknown *outer, IUnknown **out)
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 strmbase_get_typeinfo(enum strmbase_type_id tid, ITypeInfo **typeinfo)
void strmbase_passthrough_cleanup(struct strmbase_passthrough *passthrough)
void strmbase_dump_media_type(const AM_MEDIA_TYPE *mt)
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_filter_init(struct strmbase_filter *filter, IUnknown *outer, const CLSID *clsid, const struct strmbase_filter_ops *func_table)
size_t queued_samples_capacity
LPDIRECTSOUNDBUFFER dsbuffer
IBasicAudio IBasicAudio_iface
IAMDirectSound IAMDirectSound_iface
REFERENCE_TIME stream_start
bool render_thread_shutdown
IQualityControl IQualityControl_iface
size_t queued_sample_count
IMediaSample ** queued_samples
struct strmbase_passthrough passthrough
CRITICAL_SECTION render_cs
CONDITION_VARIABLE render_cv
IMediaSeeking IMediaSeeking_iface
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
BOOL WINAPI DECLSPEC_HOTPATCH ResetEvent(IN HANDLE hEvent)
#define CONTAINING_RECORD(address, type, field)
#define VFW_E_ALREADY_CONNECTED
#define VFW_E_TYPE_NOT_ACCEPTED
#define VFW_E_WRONG_STATE
#define VFW_S_STATE_INTERMEDIATE
#define VFW_E_NO_AUDIO_HARDWARE
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
DWORD WINAPI GetLastError(void)
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
static HRESULT HRESULT_FROM_WIN32(unsigned int x)
#define RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO