ReactOS 0.4.17-dev-934-g091855f
dsoundrender.c File Reference
#include "quartz_private.h"
#include "uuids.h"
#include "vfwmsgs.h"
#include "windef.h"
#include "winbase.h"
#include "dshow.h"
#include "evcode.h"
#include "strmif.h"
#include "dsound.h"
#include "amaudio.h"
#include "wine/debug.h"
Include dependency graph for dsoundrender.c:

Go to the source code of this file.

Classes

struct  dsound_render
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (quartz)
 
static struct dsound_render * impl_from_strmbase_pin (struct strmbase_pin *iface)
 
static struct dsound_render * impl_from_strmbase_filter (struct strmbase_filter *iface)
 
static struct dsound_render * impl_from_IBasicAudio (IBasicAudio *iface)
 
static struct dsound_render * impl_from_IAMDirectSound (IAMDirectSound *iface)
 
static REFERENCE_TIME time_from_pos (struct dsound_render *filter, DWORD pos)
 
static DWORD pos_from_time (struct dsound_render *filter, REFERENCE_TIME time)
 
static void update_positions (struct dsound_render *filter, DWORD *seqwritepos, DWORD *minwritepos)
 
static HRESULT get_write_pos (struct dsound_render *filter, DWORD *ret_writepos, REFERENCE_TIME write_at, DWORD *pfree)
 
static HRESULT send_sample_data (struct dsound_render *filter, REFERENCE_TIME tStart, const BYTE *data, DWORD size)
 
static HRESULT configure_buffer (struct dsound_render *filter, IMediaSample *pSample)
 
static HRESULT render_sample (struct dsound_render *filter, IMediaSample *pSample)
 
static DWORD WINAPI render_thread_run (void *arg)
 
static HRESULT WINAPI dsound_render_sink_Receive (struct strmbase_sink *iface, IMediaSample *sample)
 
static HRESULT dsound_render_sink_query_interface (struct strmbase_pin *iface, REFIID iid, void **out)
 
static HRESULT dsound_render_sink_query_accept (struct strmbase_pin *iface, const AM_MEDIA_TYPE *pmt)
 
static HRESULT dsound_render_sink_connect (struct strmbase_sink *iface, IPin *peer, const AM_MEDIA_TYPE *mt)
 
static void dsound_render_sink_disconnect (struct strmbase_sink *iface)
 
static HRESULT dsound_render_sink_eos (struct strmbase_sink *iface)
 
static HRESULT dsound_render_sink_begin_flush (struct strmbase_sink *iface)
 
static HRESULT dsound_render_sink_end_flush (struct strmbase_sink *iface)
 
static void dsound_render_destroy (struct strmbase_filter *iface)
 
static struct strmbase_pin * dsound_render_get_pin (struct strmbase_filter *iface, unsigned int index)
 
static HRESULT dsound_render_query_interface (struct strmbase_filter *iface, REFIID iid, void **out)
 
static HRESULT dsound_render_init_stream (struct strmbase_filter *iface)
 
static HRESULT dsound_render_start_stream (struct strmbase_filter *iface, REFERENCE_TIME start)
 
static HRESULT dsound_render_stop_stream (struct strmbase_filter *iface)
 
static HRESULT dsound_render_cleanup_stream (struct strmbase_filter *iface)
 
static HRESULT dsound_render_wait_state (struct strmbase_filter *iface, DWORD timeout)
 
static HRESULT WINAPI basic_audio_QueryInterface (IBasicAudio *iface, REFIID riid, void **out)
 
static ULONG WINAPI basic_audio_AddRef (IBasicAudio *iface)
 
static ULONG WINAPI basic_audio_Release (IBasicAudio *iface)
 
static HRESULT WINAPI basic_audio_GetTypeInfoCount (IBasicAudio *iface, UINT *count)
 
static HRESULT WINAPI basic_audio_GetTypeInfo (IBasicAudio *iface, UINT index, LCID lcid, ITypeInfo **typeinfo)
 
static HRESULT WINAPI basic_audio_GetIDsOfNames (IBasicAudio *iface, REFIID iid, LPOLESTR *names, UINT count, LCID lcid, DISPID *ids)
 
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 HRESULT WINAPI basic_audio_put_Volume (IBasicAudio *iface, LONG volume)
 
static HRESULT WINAPI basic_audio_get_Volume (IBasicAudio *iface, LONG *volume)
 
static HRESULT WINAPI basic_audio_put_Balance (IBasicAudio *iface, LONG balance)
 
static HRESULT WINAPI basic_audio_get_Balance (IBasicAudio *iface, LONG *balance)
 
static HRESULT WINAPI direct_sound_QueryInterface (IAMDirectSound *iface, REFIID riid, void **out)
 
static ULONG WINAPI direct_sound_AddRef (IAMDirectSound *iface)
 
static ULONG WINAPI direct_sound_Release (IAMDirectSound *iface)
 
static HRESULT WINAPI direct_sound_GetDirectSoundInterface (IAMDirectSound *iface, IDirectSound **ds)
 
static HRESULT WINAPI direct_sound_GetPrimaryBufferInterface (IAMDirectSound *iface, IDirectSoundBuffer **buf)
 
static HRESULT WINAPI direct_sound_GetSecondaryBufferInterface (IAMDirectSound *iface, IDirectSoundBuffer **buf)
 
static HRESULT WINAPI direct_sound_ReleaseDirectSoundInterface (IAMDirectSound *iface, IDirectSound *ds)
 
static HRESULT WINAPI direct_sound_ReleasePrimaryBufferInterface (IAMDirectSound *iface, IDirectSoundBuffer *buf)
 
static HRESULT WINAPI direct_sound_ReleaseSecondaryBufferInterface (IAMDirectSound *iface, IDirectSoundBuffer *buf)
 
static HRESULT WINAPI direct_sound_SetFocusWindow (IAMDirectSound *iface, HWND hwnd, BOOL bgaudible)
 
static HRESULT WINAPI direct_sound_GetFocusWindow (IAMDirectSound *iface, HWND *hwnd, BOOL *bgaudible)
 
static struct dsound_render * impl_from_IQualityControl (IQualityControl *iface)
 
static HRESULT WINAPI quality_control_QueryInterface (IQualityControl *iface, REFIID iid, void **out)
 
static ULONG WINAPI quality_control_AddRef (IQualityControl *iface)
 
static ULONG WINAPI quality_control_Release (IQualityControl *iface)
 
static HRESULT WINAPI quality_control_Notify (IQualityControl *iface, IBaseFilter *sender, Quality q)
 
static HRESULT WINAPI quality_control_SetSink (IQualityControl *iface, IQualityControl *sink)
 
HRESULT dsound_render_create (IUnknown *outer, IUnknown **out)
 

Variables

static const REFERENCE_TIME DSoundRenderer_Max_Fill = 150 * 10000
 
static const struct strmbase_sink_ops sink_ops
 
static const struct strmbase_filter_ops filter_ops
 
static const IBasicAudioVtbl basic_audio_vtbl
 
static const IAMDirectSoundVtbl direct_sound_vtbl
 
static const IQualityControlVtbl quality_control_vtbl
 

Function Documentation

◆ basic_audio_AddRef()

static ULONG WINAPI basic_audio_AddRef ( IBasicAudio *  iface)
static

Definition at line 759 of file dsoundrender.c.

760{
762 return IUnknown_AddRef(filter->filter.outer_unk);
763}
static struct dsound_render * impl_from_IBasicAudio(IBasicAudio *iface)
Definition: dsoundrender.c:88
Definition: filter.c:165
IBaseFilter * filter
Definition: filtergraph.c:75

◆ basic_audio_get_Balance()

static HRESULT WINAPI basic_audio_get_Balance ( IBasicAudio *  iface,
LONG *  balance 
)
static

Definition at line 871 of file dsoundrender.c.

872{
874
875 TRACE("filter %p, balance %p.\n", filter, balance);
876
877 if (!balance)
878 return E_POINTER;
879
880 *balance = filter->pan;
881 return S_OK;
882}
#define S_OK
Definition: intsafe.h:52
#define TRACE(s)
Definition: solgame.cpp:4
#define E_POINTER
Definition: winerror.h:3480

◆ basic_audio_get_Volume()

static HRESULT WINAPI basic_audio_get_Volume ( IBasicAudio *  iface,
LONG *  volume 
)
static

Definition at line 842 of file dsoundrender.c.

843{
845
846 TRACE("filter %p, volume %p.\n", filter, volume);
847
848 if (!volume)
849 return E_POINTER;
850
851 *volume = filter->volume;
852 return S_OK;
853}

◆ basic_audio_GetIDsOfNames()

static HRESULT WINAPI basic_audio_GetIDsOfNames ( IBasicAudio *  iface,
REFIID  iid,
LPOLESTR *  names,
UINT  count,
LCID  lcid,
DISPID *  ids 
)
static

Definition at line 791 of file dsoundrender.c.

793{
796 HRESULT hr;
797
798 TRACE("filter %p, iid %s, names %p, count %u, lcid %lu, ids %p.\n",
800
802 {
803 hr = ITypeInfo_GetIDsOfNames(typeinfo, names, count, ids);
804 ITypeInfo_Release(typeinfo);
805 }
806 return hr;
807}
HRESULT hr
Definition: delayimp.cpp:582
LCID lcid
Definition: locale.c:5660
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint * ids
Definition: glext.h:5907
GLuint GLuint * names
Definition: glext.h:11545
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define debugstr_guid
Definition: kernel32.h:35
@ IBasicAudio_tid
Definition: strmbase.h:225
HRESULT strmbase_get_typeinfo(enum strmbase_type_id tid, ITypeInfo **typeinfo)
Definition: dispatch.c:38

◆ basic_audio_GetTypeInfo()

static HRESULT WINAPI basic_audio_GetTypeInfo ( IBasicAudio *  iface,
UINT  index,
LCID  lcid,
ITypeInfo **  typeinfo 
)
static

Definition at line 781 of file dsoundrender.c.

783{
785
786 TRACE("filter %p, index %u, lcid %lu, typeinfo %p.\n", filter, index, lcid, typeinfo);
787
789}
GLuint index
Definition: glext.h:6031

◆ basic_audio_GetTypeInfoCount()

static HRESULT WINAPI basic_audio_GetTypeInfoCount ( IBasicAudio *  iface,
UINT *  count 
)
static

Definition at line 771 of file dsoundrender.c.

772{
774
775 TRACE("filter %p, count %p.\n", filter, count);
776
777 *count = 1;
778 return S_OK;
779}

◆ basic_audio_Invoke()

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

Definition at line 809 of file dsoundrender.c.

811{
813 HRESULT hr;
814
815 TRACE("filter %p, id %ld, iid %s, lcid %lu, flags %u, params %p, result %p, excepinfo %p, error_arg %p.\n",
816 iface, id, debugstr_guid(iid), lcid, flags, params, result, excepinfo, error_arg);
817
819 {
820 hr = ITypeInfo_Invoke(typeinfo, iface, id, flags, params, result, excepinfo, error_arg);
821 ITypeInfo_Release(typeinfo);
822 }
823 return hr;
824}
GLenum const GLfloat * params
Definition: glext.h:5645
GLbitfield flags
Definition: glext.h:7161
GLuint64EXT * result
Definition: glext.h:11304
static EXCEPINFO excepinfo
Definition: automation.c:47

◆ basic_audio_put_Balance()

static HRESULT WINAPI basic_audio_put_Balance ( IBasicAudio *  iface,
LONG  balance 
)
static

Definition at line 855 of file dsoundrender.c.

856{
858
859 TRACE("filter %p, balance %ld.\n", filter, balance);
860
861 if (balance < DSBPAN_LEFT || balance > DSBPAN_RIGHT)
862 return E_INVALIDARG;
863
864 if (filter->dsbuffer && FAILED(IDirectSoundBuffer_SetPan(filter->dsbuffer, balance)))
865 return E_FAIL;
866
867 filter->pan = balance;
868 return S_OK;
869}
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_FAIL
Definition: ddrawi.h:102
#define IDirectSoundBuffer_SetPan(p, a)
Definition: dsound.h:589
#define DSBPAN_RIGHT
Definition: dsound.h:228
#define FAILED(hr)
Definition: intsafe.h:51

◆ basic_audio_put_Volume()

static HRESULT WINAPI basic_audio_put_Volume ( IBasicAudio *  iface,
LONG  volume 
)
static

Definition at line 826 of file dsoundrender.c.

827{
829
830 TRACE("filter %p, volume %ld.\n", filter, volume);
831
833 return E_INVALIDARG;
834
835 if (filter->dsbuffer && FAILED(IDirectSoundBuffer_SetVolume(filter->dsbuffer, volume)))
836 return E_FAIL;
837
838 filter->volume = volume;
839 return S_OK;
840}
#define DSBVOLUME_MAX
Definition: dsound.h:229
#define DSBVOLUME_MIN
Definition: dsound.h:230
#define IDirectSoundBuffer_SetVolume(p, a)
Definition: dsound.h:588

◆ basic_audio_QueryInterface()

static HRESULT WINAPI basic_audio_QueryInterface ( IBasicAudio *  iface,
REFIID  riid,
void **  out 
)
static

Definition at line 753 of file dsoundrender.c.

754{
756 return IUnknown_QueryInterface(filter->filter.outer_unk, riid, out);
757}
REFIID riid
Definition: atlbase.h:39
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383

◆ basic_audio_Release()

static ULONG WINAPI basic_audio_Release ( IBasicAudio *  iface)
static

Definition at line 765 of file dsoundrender.c.

766{
768 return IUnknown_Release(filter->filter.outer_unk);
769}

◆ configure_buffer()

static HRESULT configure_buffer ( struct dsound_render *  filter,
IMediaSample *  pSample 
)
static

Definition at line 290 of file dsoundrender.c.

291{
292 HRESULT hr;
293 AM_MEDIA_TYPE *amt;
294
295 if (IMediaSample_GetMediaType(pSample, &amt) == S_OK)
296 {
297 AM_MEDIA_TYPE *orig = &filter->sink.pin.mt;
298 WAVEFORMATEX *origfmt = (WAVEFORMATEX *)orig->pbFormat;
299 WAVEFORMATEX *newfmt = (WAVEFORMATEX *)amt->pbFormat;
300
301 TRACE("Format change.\n");
303
304 if (origfmt->wFormatTag == newfmt->wFormatTag &&
305 origfmt->nChannels == newfmt->nChannels &&
306 origfmt->nBlockAlign == newfmt->nBlockAlign &&
307 origfmt->wBitsPerSample == newfmt->wBitsPerSample &&
308 origfmt->cbSize == newfmt->cbSize)
309 {
310 if (origfmt->nSamplesPerSec != newfmt->nSamplesPerSec)
311 {
313 newfmt->nSamplesPerSec);
314 if (FAILED(hr))
316 FreeMediaType(orig);
317 CopyMediaType(orig, amt);
318 IMediaSample_SetMediaType(pSample, NULL);
319 }
320 }
321 else
323 }
324 return S_OK;
325}
#define NULL
Definition: types.h:112
#define IDirectSoundBuffer_SetFrequency(p, a)
Definition: dsound.h:590
HRESULT WINAPI CopyMediaType(AM_MEDIA_TYPE *pDest, const AM_MEDIA_TYPE *pSrc)
Definition: mediatype.c:150
void WINAPI FreeMediaType(AM_MEDIA_TYPE *pMediaType)
Definition: mediatype.c:165
void strmbase_dump_media_type(const AM_MEDIA_TYPE *mt)
Definition: mediatype.c:58
WORD wBitsPerSample
Definition: audioclient.idl:45
DWORD nSamplesPerSec
Definition: audioclient.idl:42
#define VFW_E_TYPE_NOT_ACCEPTED
Definition: vfwmsgs.h:81

Referenced by dsound_render_sink_Receive().

◆ direct_sound_AddRef()

static ULONG WINAPI direct_sound_AddRef ( IAMDirectSound *  iface)
static

Definition at line 905 of file dsoundrender.c.

906{
908 return IUnknown_AddRef(filter->filter.outer_unk);
909}
static struct dsound_render * impl_from_IAMDirectSound(IAMDirectSound *iface)
Definition: dsoundrender.c:93

◆ direct_sound_GetDirectSoundInterface()

static HRESULT WINAPI direct_sound_GetDirectSoundInterface ( IAMDirectSound *  iface,
IDirectSound **  ds 
)
static

Definition at line 917 of file dsoundrender.c.

918{
920
921 FIXME("(%p/%p)->(%p): stub\n", filter, iface, ds);
922
923 return E_NOTIMPL;
924}
#define FIXME(fmt,...)
Definition: precomp.h:53
#define E_NOTIMPL
Definition: ddrawi.h:99
#define ds
Definition: i386-dis.c:443

◆ direct_sound_GetFocusWindow()

static HRESULT WINAPI direct_sound_GetFocusWindow ( IAMDirectSound *  iface,
HWND *  hwnd,
BOOL *  bgaudible 
)
static

Definition at line 980 of file dsoundrender.c.

981{
983
984 FIXME("(%p/%p)->(%p,%p): stub\n", filter, iface, hwnd, bgaudible);
985
986 return E_NOTIMPL;
987}
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023

◆ direct_sound_GetPrimaryBufferInterface()

static HRESULT WINAPI direct_sound_GetPrimaryBufferInterface ( IAMDirectSound *  iface,
IDirectSoundBuffer **  buf 
)
static

Definition at line 926 of file dsoundrender.c.

927{
929
930 FIXME("(%p/%p)->(%p): stub\n", filter, iface, buf);
931
932 return E_NOTIMPL;
933}
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751

◆ direct_sound_GetSecondaryBufferInterface()

static HRESULT WINAPI direct_sound_GetSecondaryBufferInterface ( IAMDirectSound *  iface,
IDirectSoundBuffer **  buf 
)
static

Definition at line 935 of file dsoundrender.c.

936{
938
939 FIXME("(%p/%p)->(%p): stub\n", filter, iface, buf);
940
941 return E_NOTIMPL;
942}

◆ direct_sound_QueryInterface()

static HRESULT WINAPI direct_sound_QueryInterface ( IAMDirectSound *  iface,
REFIID  riid,
void **  out 
)
static

Definition at line 899 of file dsoundrender.c.

900{
902 return IUnknown_QueryInterface(filter->filter.outer_unk, riid, out);
903}

◆ direct_sound_Release()

static ULONG WINAPI direct_sound_Release ( IAMDirectSound *  iface)
static

Definition at line 911 of file dsoundrender.c.

912{
914 return IUnknown_Release(filter->filter.outer_unk);
915}

◆ direct_sound_ReleaseDirectSoundInterface()

static HRESULT WINAPI direct_sound_ReleaseDirectSoundInterface ( IAMDirectSound *  iface,
IDirectSound *  ds 
)
static

Definition at line 944 of file dsoundrender.c.

945{
947
948 FIXME("(%p/%p)->(%p): stub\n", filter, iface, ds);
949
950 return E_NOTIMPL;
951}

◆ direct_sound_ReleasePrimaryBufferInterface()

static HRESULT WINAPI direct_sound_ReleasePrimaryBufferInterface ( IAMDirectSound *  iface,
IDirectSoundBuffer *  buf 
)
static

Definition at line 953 of file dsoundrender.c.

954{
956
957 FIXME("(%p/%p)->(%p): stub\n", filter, iface, buf);
958
959 return E_NOTIMPL;
960}

◆ direct_sound_ReleaseSecondaryBufferInterface()

static HRESULT WINAPI direct_sound_ReleaseSecondaryBufferInterface ( IAMDirectSound *  iface,
IDirectSoundBuffer *  buf 
)
static

Definition at line 962 of file dsoundrender.c.

963{
965
966 FIXME("(%p/%p)->(%p): stub\n", filter, iface, buf);
967
968 return E_NOTIMPL;
969}

◆ direct_sound_SetFocusWindow()

static HRESULT WINAPI direct_sound_SetFocusWindow ( IAMDirectSound *  iface,
HWND  hwnd,
BOOL  bgaudible 
)
static

Definition at line 971 of file dsoundrender.c.

972{
974
975 FIXME("(%p/%p)->(%p,%d): stub\n", filter, iface, hwnd, bgaudible);
976
977 return E_NOTIMPL;
978}

◆ dsound_render_cleanup_stream()

static HRESULT dsound_render_cleanup_stream ( struct strmbase_filter *  iface)
static

Definition at line 707 of file dsoundrender.c.

708{
710
711 SetEvent(filter->state_event);
712 SetEvent(filter->flush_event);
713
714 if (filter->render_thread)
715 {
716 EnterCriticalSection(&filter->render_cs);
717 filter->render_thread_shutdown = true;
718 LeaveCriticalSection(&filter->render_cs);
719 WakeConditionVariable(&filter->render_cv);
720 WaitForSingleObject(filter->render_thread, INFINITE);
721 CloseHandle(filter->render_thread);
722 filter->render_thread = NULL;
723
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;
727 }
728
729 return S_OK;
730}
static struct dsound_render * impl_from_strmbase_filter(struct strmbase_filter *iface)
Definition: dsoundrender.c:83
#define CloseHandle
Definition: compat.h:739
VOID WINAPI WakeConditionVariable(PCONDITION_VARIABLE ConditionVariable)
Definition: sync.c:98
#define INFINITE
Definition: serial.h:102
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
Definition: glfuncs.h:248
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:669
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)

◆ dsound_render_create()

HRESULT dsound_render_create ( IUnknown *  outer,
IUnknown **  out 
)

Definition at line 1057 of file dsoundrender.c.

1058{
1059 static const DSBUFFERDESC buffer_desc =
1060 {
1061 .dwSize = sizeof(DSBUFFERDESC),
1063 };
1064
1065 struct dsound_render *object;
1066 IDirectSoundBuffer *buffer;
1067 HRESULT hr;
1068
1069 TRACE("outer %p, out %p.\n", outer, out);
1070
1071 if (!(object = calloc(1, sizeof(*object))))
1072 return E_OUTOFMEMORY;
1073
1074 strmbase_filter_init(&object->filter, outer, &CLSID_DSoundRender, &filter_ops);
1075
1076 if (FAILED(hr = system_clock_create(&object->filter.IUnknown_inner, &object->system_clock)))
1077 {
1079 free(object);
1080 return hr;
1081 }
1082
1083 if (FAILED(hr = DirectSoundCreate8(NULL, &object->dsound, NULL)))
1084 {
1085 IUnknown_Release(object->system_clock);
1087 free(object);
1089 }
1090
1093 {
1095 IUnknown_Release(object->system_clock);
1097 free(object);
1098 return hr;
1099 }
1100
1102 &buffer_desc, &buffer, NULL)))
1103 {
1106 }
1107
1108 strmbase_passthrough_init(&object->passthrough, (IUnknown *)&object->filter.IBaseFilter_iface);
1109 ISeekingPassThru_Init(&object->passthrough.ISeekingPassThru_iface, TRUE, &object->sink.pin.IPin_iface);
1110
1111 strmbase_sink_init(&object->sink, &object->filter, L"Audio Input pin (rendered)", &sink_ops, NULL);
1112
1113 object->state_event = CreateEventW(NULL, TRUE, TRUE, NULL);
1114 object->flush_event = CreateEventW(NULL, TRUE, TRUE, NULL);
1115
1116 object->IBasicAudio_iface.lpVtbl = &basic_audio_vtbl;
1117 object->IAMDirectSound_iface.lpVtbl = &direct_sound_vtbl;
1118 object->IQualityControl_iface.lpVtbl = &quality_control_vtbl;
1119
1121 object->render_cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": dsound_render.render_cs");
1123
1124 TRACE("Created DirectSound renderer %p.\n", object);
1125 *out = &object->filter.IUnknown_inner;
1126
1127 return S_OK;
1128}
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define free
Definition: debug_ros.c:5
HRESULT WINAPI DirectSoundCreate8(LPCGUID lpcGUID, LPDIRECTSOUND8 *ppDS, IUnknown *pUnkOuter)
Definition: directsound.c:504
#define TRUE
Definition: types.h:120
static const IAMDirectSoundVtbl direct_sound_vtbl
Definition: dsoundrender.c:989
static const IQualityControlVtbl quality_control_vtbl
static const struct strmbase_sink_ops sink_ops
Definition: dsoundrender.c:578
static const struct strmbase_filter_ops filter_ops
Definition: dsoundrender.c:741
static const IBasicAudioVtbl basic_audio_vtbl
Definition: dsoundrender.c:884
VOID WINAPI InitializeConditionVariable(PCONDITION_VARIABLE ConditionVariable)
Definition: sync.c:22
BOOL WINAPI InitializeCriticalSectionEx(OUT LPCRITICAL_SECTION lpCriticalSection, IN DWORD dwSpinCount, IN DWORD flags)
Definition: sync.c:107
#define L(x)
Definition: resources.c:13
#define IDirectSound8_CreateSoundBuffer(p, a, b, c)
Definition: dsound.h:509
struct _DSBUFFERDESC DSBUFFERDESC
#define DSSCL_PRIORITY
Definition: dsound.h:248
#define IDirectSound8_Release(p)
Definition: dsound.h:507
#define IDirectSoundBuffer_Play(p, a, b, c)
Definition: dsound.h:585
#define DSBPLAY_LOOPING
Definition: dsound.h:189
#define IDirectSoundBuffer_Release(p)
Definition: dsound.h:574
#define DSERR_NODRIVER
Definition: dsound.h:128
#define DSBCAPS_PRIMARYBUFFER
Definition: dsound.h:206
#define IDirectSound8_SetCooperativeLevel(p, a, b)
Definition: dsound.h:512
GLuint buffer
Definition: glext.h:5915
static IUnknown * outer
Definition: compobj.c:82
_In_ LPWSTR _In_ DWORD _In_ DWORD _In_ DWORD dwFlags
Definition: netsh.h:141
HWND WINAPI GetDesktopWindow(void)
Definition: window.c:628
HRESULT system_clock_create(IUnknown *outer, IUnknown **out)
Definition: systemclock.c:327
#define calloc
Definition: rosglue.h:14
void strmbase_sink_init(struct strmbase_sink *pin, struct strmbase_filter *filter, const WCHAR *name, const struct strmbase_sink_ops *ops, IMemAllocator *allocator)
Definition: pin.c:1168
void strmbase_filter_cleanup(struct strmbase_filter *filter)
Definition: filter.c:540
void strmbase_passthrough_init(struct strmbase_passthrough *passthrough, IUnknown *outer)
Definition: pospass.c:725
void strmbase_filter_init(struct strmbase_filter *filter, IUnknown *outer, const CLSID *clsid, const struct strmbase_filter_ops *func_table)
Definition: filter.c:517
DWORD dwSize
Definition: dsound.h:288
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:587
#define DWORD_PTR
Definition: treelist.c:76
#define VFW_E_NO_AUDIO_HARDWARE
Definition: vfwmsgs.h:109
#define RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO
Definition: winnt_old.h:1156

◆ dsound_render_destroy()

static void dsound_render_destroy ( struct strmbase_filter *  iface)
static

Definition at line 590 of file dsoundrender.c.

591{
593
594 if (filter->dsbuffer)
596 filter->dsbuffer = NULL;
597 if (filter->dsound)
599 filter->dsound = NULL;
600
601 IUnknown_Release(filter->system_clock);
602
603 if (filter->sink.pin.peer)
604 IPin_Disconnect(filter->sink.pin.peer);
605 IPin_Disconnect(&filter->sink.pin.IPin_iface);
607
608 CloseHandle(filter->state_event);
609 CloseHandle(filter->flush_event);
610
611 filter->render_cs.DebugInfo->Spare[0] = 0;
612 DeleteCriticalSection(&filter->render_cs);
613
616 free(filter);
617}
void strmbase_passthrough_cleanup(struct strmbase_passthrough *passthrough)
Definition: pospass.c:738
void strmbase_sink_cleanup(struct strmbase_sink *pin)
Definition: pin.c:1185
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)

◆ dsound_render_get_pin()

static struct strmbase_pin * dsound_render_get_pin ( struct strmbase_filter *  iface,
unsigned int  index 
)
static

Definition at line 619 of file dsoundrender.c.

620{
622
623 if (index == 0)
624 return &filter->sink.pin;
625 return NULL;
626}

◆ dsound_render_init_stream()

static HRESULT dsound_render_init_stream ( struct strmbase_filter *  iface)
static

Definition at line 651 of file dsoundrender.c.

652{
654
655 filter->eos = FALSE;
656 ResetEvent(filter->flush_event);
657
658 if (!filter->sink.pin.peer)
659 return S_OK;
660
661 ResetEvent(filter->state_event);
662
663 filter->render_thread_shutdown = false;
664 if (!(filter->render_thread = CreateThread(NULL, 0, render_thread_run, filter, 0, NULL)))
666
667 return S_FALSE;
668}
#define FALSE
Definition: types.h:117
static DWORD WINAPI render_thread_run(void *arg)
Definition: dsoundrender.c:352
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)
Definition: thread.c:137
BOOL WINAPI DECLSPEC_HOTPATCH ResetEvent(IN HANDLE hEvent)
Definition: synch.c:650
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define S_FALSE
Definition: winerror.h:3451
static HRESULT HRESULT_FROM_WIN32(unsigned int x)
Definition: winerror.h:210

◆ dsound_render_query_interface()

static HRESULT dsound_render_query_interface ( struct strmbase_filter *  iface,
REFIID  iid,
void **  out 
)
static

Definition at line 628 of file dsoundrender.c.

629{
631
632 if (IsEqualGUID(iid, &IID_IAMDirectSound))
633 *out = &filter->IAMDirectSound_iface;
634 else if (IsEqualGUID(iid, &IID_IBasicAudio))
635 *out = &filter->IBasicAudio_iface;
636 else if (IsEqualGUID(iid, &IID_IMediaPosition))
637 *out = &filter->passthrough.IMediaPosition_iface;
638 else if (IsEqualGUID(iid, &IID_IMediaSeeking))
639 *out = &filter->passthrough.IMediaSeeking_iface;
640 else if (IsEqualGUID(iid, &IID_IQualityControl))
641 *out = &filter->IQualityControl_iface;
642 else if (IsEqualGUID(iid, &IID_IReferenceClock))
643 return IUnknown_QueryInterface(filter->system_clock, iid, out);
644 else
645 return E_NOINTERFACE;
646
647 IUnknown_AddRef((IUnknown *)*out);
648 return S_OK;
649}
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
IMediaSeeking IMediaSeeking_iface
Definition: filter.c:167
#define E_NOINTERFACE
Definition: winerror.h:3479

◆ dsound_render_sink_begin_flush()

static HRESULT dsound_render_sink_begin_flush ( struct strmbase_sink *  iface)
static

Definition at line 534 of file dsoundrender.c.

535{
537
538 SetEvent(filter->flush_event);
539 return S_OK;
540}
static struct dsound_render * impl_from_strmbase_pin(struct strmbase_pin *iface)
Definition: dsoundrender.c:78
struct strmbase_pin pin
Definition: strmbase.h:106

◆ dsound_render_sink_connect()

static HRESULT dsound_render_sink_connect ( struct strmbase_sink *  iface,
IPin *  peer,
const AM_MEDIA_TYPE *  mt 
)
static

Definition at line 456 of file dsoundrender.c.

457{
459 const WAVEFORMATEX *format = (WAVEFORMATEX *)mt->pbFormat;
460 HRESULT hr = S_OK;
461 DSBUFFERDESC buf_desc;
462
463 filter->buf_size = format->nAvgBytesPerSec;
464
465 memset(&buf_desc,0,sizeof(DSBUFFERDESC));
466 buf_desc.dwSize = sizeof(DSBUFFERDESC);
467 buf_desc.dwFlags = DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLPAN |
470 buf_desc.dwBufferBytes = filter->buf_size;
471 buf_desc.lpwfxFormat = (WAVEFORMATEX *)format;
472 hr = IDirectSound8_CreateSoundBuffer(filter->dsound, &buf_desc, &filter->dsbuffer, NULL);
473 filter->writepos = filter->buf_size;
474 if (FAILED(hr))
475 ERR("Failed to create sound buffer, hr %#lx.\n", hr);
476
477 if (SUCCEEDED(hr))
478 {
479 hr = IDirectSoundBuffer_SetVolume(filter->dsbuffer, filter->volume);
480 if (FAILED(hr))
481 ERR("Failed to set volume to %ld, hr %#lx.\n", filter->volume, hr);
482
483 hr = IDirectSoundBuffer_SetPan(filter->dsbuffer, filter->pan);
484 if (FAILED(hr))
485 ERR("Failed to set pan to %ld, hr %#lx.\n", filter->pan, hr);
486 hr = S_OK;
487 }
488
490 {
491 if (filter->dsbuffer)
493 filter->dsbuffer = NULL;
494 }
495
496 return hr;
497}
#define ERR(fmt,...)
Definition: precomp.h:57
#define DSBCAPS_GLOBALFOCUS
Definition: dsound.h:219
#define DSBCAPS_CTRLVOLUME
Definition: dsound.h:213
#define DSBCAPS_GETCURRENTPOSITION2
Definition: dsound.h:220
#define DSBCAPS_CTRLPAN
Definition: dsound.h:212
#define DSBCAPS_CTRLFREQUENCY
Definition: dsound.h:211
#define memset(x, y, z)
Definition: compat.h:39
#define VFW_E_ALREADY_CONNECTED
Definition: vfwmsgs.h:43

◆ dsound_render_sink_disconnect()

static void dsound_render_sink_disconnect ( struct strmbase_sink *  iface)
static

Definition at line 499 of file dsoundrender.c.

500{
502
503 TRACE("filter %p.\n", filter);
504
505 if (filter->dsbuffer)
507 filter->dsbuffer = NULL;
508}

◆ dsound_render_sink_end_flush()

static HRESULT dsound_render_sink_end_flush ( struct strmbase_sink *  iface)
static

Definition at line 542 of file dsoundrender.c.

543{
545
547 if (filter->eos && filter->filter.state != State_Stopped)
548 {
549 WaitForSingleObject(filter->render_thread, INFINITE);
550 CloseHandle(filter->render_thread);
551
552 if (!(filter->render_thread = CreateThread(NULL, 0, render_thread_run, filter, 0, NULL)))
553 {
556 }
557 filter->eos = FALSE;
558 }
559
560 ResetEvent(filter->flush_event);
561
562 if (filter->dsbuffer)
563 {
564 void *buffer;
565 DWORD size;
566
567 /* Force a reset */
569 memset(buffer, 0, size);
571 filter->writepos = filter->buf_size;
572 }
573
575 return S_OK;
576}
#define IDirectSoundBuffer_Unlock(p, a, b, c, d)
Definition: dsound.h:592
#define DSBLOCK_ENTIREBUFFER
Definition: dsound.h:204
#define IDirectSoundBuffer_Lock(p, a, b, c, d, e, f, g)
Definition: dsound.h:584
unsigned long DWORD
Definition: ntddk_ex.h:95
GLsizeiptr size
Definition: glext.h:5919

◆ dsound_render_sink_eos()

static HRESULT dsound_render_sink_eos ( struct strmbase_sink *  iface)
static

Definition at line 510 of file dsoundrender.c.

511{
514 IMediaEventSink *event_sink;
515
516 EnterCriticalSection(&filter->render_cs);
517 filter->eos = TRUE;
518 LeaveCriticalSection(&filter->render_cs);
519 WakeConditionVariable(&filter->render_cv);
520
521 if (filter->filter.state == State_Running && graph
522 && SUCCEEDED(IFilterGraph_QueryInterface(graph,
523 &IID_IMediaEventSink, (void **)&event_sink)))
524 {
525 IMediaEventSink_Notify(event_sink, EC_COMPLETE, S_OK,
526 (LONG_PTR)&filter->filter.IBaseFilter_iface);
527 IMediaEventSink_Release(event_sink);
528 }
529 SetEvent(filter->state_event);
530
531 return S_OK;
532}
#define EC_COMPLETE
Definition: evcode.h:17
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
Definition: graph.c:32

◆ dsound_render_sink_query_accept()

static HRESULT dsound_render_sink_query_accept ( struct strmbase_pin *  iface,
const AM_MEDIA_TYPE *  pmt 
)
static

Definition at line 448 of file dsoundrender.c.

449{
450 if (!IsEqualIID(&pmt->majortype, &MEDIATYPE_Audio))
451 return S_FALSE;
452
453 return S_OK;
454}
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95

◆ dsound_render_sink_query_interface()

static HRESULT dsound_render_sink_query_interface ( struct strmbase_pin *  iface,
REFIID  iid,
void **  out 
)
static

Definition at line 435 of file dsoundrender.c.

436{
438
439 if (IsEqualGUID(iid, &IID_IMemInputPin))
440 *out = &filter->sink.IMemInputPin_iface;
441 else
442 return E_NOINTERFACE;
443
444 IUnknown_AddRef((IUnknown *)*out);
445 return S_OK;
446}

◆ dsound_render_sink_Receive()

static HRESULT WINAPI dsound_render_sink_Receive ( struct strmbase_sink *  iface,
IMediaSample *  sample 
)
static

Definition at line 399 of file dsoundrender.c.

400{
402 HRESULT hr;
403
404 TRACE("filter %p, sample %p.\n", filter, sample);
405
406 if (filter->eos || filter->sink.flushing)
407 return S_FALSE;
408
409 if (filter->filter.state == State_Stopped)
410 return VFW_E_WRONG_STATE;
411
413 return hr;
414
415 if (filter->filter.state == State_Paused)
416 SetEvent(filter->state_event);
417
418 EnterCriticalSection(&filter->render_cs);
419
420 if (!array_reserve((void **)&filter->queued_samples, &filter->queued_samples_capacity,
421 filter->queued_sample_count + 1, sizeof(*filter->queued_samples)))
422 {
423 LeaveCriticalSection(&filter->render_cs);
424 return E_OUTOFMEMORY;
425 }
426
427 filter->queued_samples[filter->queued_sample_count++] = sample;
428 IMediaSample_AddRef(sample);
429
430 LeaveCriticalSection(&filter->render_cs);
431 WakeConditionVariable(&filter->render_cv);
432 return S_OK;
433}
static BOOL array_reserve(void **elements, unsigned int *capacity, unsigned int count, unsigned int size)
static HRESULT configure_buffer(struct dsound_render *filter, IMediaSample *pSample)
Definition: dsoundrender.c:290
Definition: wave.c:25
#define VFW_E_WRONG_STATE
Definition: vfwmsgs.h:78

◆ dsound_render_start_stream()

static HRESULT dsound_render_start_stream ( struct strmbase_filter *  iface,
REFERENCE_TIME  start 
)
static

Definition at line 670 of file dsoundrender.c.

671{
674 IMediaEventSink *event_sink;
675
676 filter->stream_start = start;
677
678 SetEvent(filter->state_event);
679
680 if (filter->sink.pin.peer)
682
683 if ((filter->eos || !filter->sink.pin.peer) && graph
684 && SUCCEEDED(IFilterGraph_QueryInterface(graph,
685 &IID_IMediaEventSink, (void **)&event_sink)))
686 {
687 IMediaEventSink_Notify(event_sink, EC_COMPLETE, S_OK,
688 (LONG_PTR)&filter->filter.IBaseFilter_iface);
689 IMediaEventSink_Release(event_sink);
690 }
691
692 return S_OK;
693}
GLuint start
Definition: gl.h:1545

◆ dsound_render_stop_stream()

static HRESULT dsound_render_stop_stream ( struct strmbase_filter *  iface)
static

Definition at line 695 of file dsoundrender.c.

696{
698
699 if (filter->sink.pin.peer)
700 {
702 filter->writepos = filter->buf_size;
703 }
704 return S_OK;
705}
#define IDirectSoundBuffer_Stop(p)
Definition: dsound.h:591

◆ dsound_render_wait_state()

static HRESULT dsound_render_wait_state ( struct strmbase_filter *  iface,
DWORD  timeout 
)
static

Definition at line 732 of file dsoundrender.c.

733{
735
736 if (WaitForSingleObject(filter->state_event, timeout) == WAIT_TIMEOUT)
738 return S_OK;
739}
#define WAIT_TIMEOUT
Definition: dderror.h:14
Definition: dhcpd.h:248
#define VFW_S_STATE_INTERMEDIATE
Definition: vfwmsgs.h:21

◆ get_write_pos()

static HRESULT get_write_pos ( struct dsound_render *  filter,
DWORD *  ret_writepos,
REFERENCE_TIME  write_at,
DWORD *  pfree 
)
static

Definition at line 158 of file dsoundrender.c.

160{
161 DWORD writepos, min_writepos, playpos;
162 REFERENCE_TIME max_lag = 50 * 10000;
163 REFERENCE_TIME cur, writepos_t, delta_t;
164
165 update_positions(filter, &writepos, &min_writepos);
166 playpos = filter->last_playpos;
167 if (filter->filter.clock)
168 {
169 IReferenceClock_GetTime(filter->filter.clock, &cur);
170 cur -= filter->stream_start;
171 }
172 else
173 write_at = -1;
174
175 if (writepos == min_writepos)
176 max_lag = 0;
177
178 if (write_at < 0)
179 {
180 *ret_writepos = writepos;
181 goto end;
182 }
183
184 if (writepos >= playpos)
185 writepos_t = cur + time_from_pos(filter, writepos - playpos);
186 else
187 writepos_t = cur + time_from_pos(filter, filter->buf_size + writepos - playpos);
188
189 /* write_at: Starting time of sample */
190 /* cur: current time of play position */
191 /* writepos_t: current time of our pointer play position */
192 delta_t = write_at - writepos_t;
193 TRACE("Last sample end %s, this sample start %s.\n",
194 debugstr_time(writepos_t), debugstr_time(write_at));
195 if (delta_t <= max_lag)
196 {
197 /* If the stream time of a sample is in the past (i.e. the sample is
198 * late, in which case write_at < min_writepos), or earlier than the
199 * last sample's end time, or there is a gap between the last sample's
200 * end time and this sample less than a certain threshold, native
201 * simply treats the two as continuous, ignoring this sample's play time
202 * and rendering the whole sample even if it's late. */
203 TRACE("Difference %s is less than threshold %s; treating sample as continuous.\n",
204 debugstr_time(delta_t), debugstr_time(max_lag));
205 *ret_writepos = writepos;
206 }
207 else
208 {
209 DWORD aheadbytes;
210 WARN("Delta too big %s/%s, too far ahead.\n", debugstr_time(delta_t), debugstr_time(max_lag));
211 aheadbytes = pos_from_time(filter, delta_t);
212 WARN("Advancing %lu bytes.\n", aheadbytes);
213 if (delta_t >= DSoundRenderer_Max_Fill)
214 return S_FALSE;
215 *ret_writepos = (min_writepos + aheadbytes) % filter->buf_size;
216 }
217end:
218 if (playpos >= *ret_writepos)
219 *pfree = playpos - *ret_writepos;
220 else
221 *pfree = filter->buf_size + playpos - *ret_writepos;
222 if (time_from_pos(filter, filter->buf_size - *pfree) >= DSoundRenderer_Max_Fill)
223 {
224 TRACE("Blocked: too full %s / %s\n", debugstr_time(time_from_pos(filter, filter->buf_size - *pfree)),
226 return S_FALSE;
227 }
228 return S_OK;
229}
#define WARN(fmt,...)
Definition: precomp.h:61
static REFERENCE_TIME time_from_pos(struct dsound_render *filter, DWORD pos)
Definition: dsoundrender.c:98
static const REFERENCE_TIME DSoundRenderer_Max_Fill
Definition: dsoundrender.c:40
static DWORD pos_from_time(struct dsound_render *filter, REFERENCE_TIME time)
Definition: dsoundrender.c:106
static void update_positions(struct dsound_render *filter, DWORD *seqwritepos, DWORD *minwritepos)
Definition: dsoundrender.c:116
LONGLONG REFERENCE_TIME
Definition: dmusicks.h:9
FxCollectionEntry * cur
GLuint GLuint end
Definition: gl.h:1545
static const char * debugstr_time(REFERENCE_TIME time)
Definition: strmbase.h:32

Referenced by send_sample_data().

◆ impl_from_IAMDirectSound()

◆ impl_from_IBasicAudio()

◆ impl_from_IQualityControl()

static struct dsound_render * impl_from_IQualityControl ( IQualityControl *  iface)
static

Definition at line 1004 of file dsoundrender.c.

1005{
1006 return CONTAINING_RECORD(iface, struct dsound_render, IQualityControl_iface);
1007}

Referenced by quality_control_AddRef(), quality_control_Notify(), quality_control_QueryInterface(), quality_control_Release(), and quality_control_SetSink().

◆ impl_from_strmbase_filter()

◆ impl_from_strmbase_pin()

◆ pos_from_time()

static DWORD pos_from_time ( struct dsound_render *  filter,
REFERENCE_TIME  time 
)
static

Definition at line 106 of file dsoundrender.c.

107{
108 WAVEFORMATEX *wfx = (WAVEFORMATEX *)filter->sink.pin.mt.pbFormat;
110 ret *= wfx->nAvgBytesPerSec;
111 ret /= 10000000;
112 ret -= ret % wfx->nBlockAlign;
113 return ret;
114}
return ret
Definition: mutex.c:147
__u16 time
Definition: mkdosfs.c:8
DWORD nAvgBytesPerSec
Definition: audioclient.idl:43

Referenced by get_write_pos().

◆ quality_control_AddRef()

static ULONG WINAPI quality_control_AddRef ( IQualityControl *  iface)
static

Definition at line 1016 of file dsoundrender.c.

1017{
1019 return IUnknown_AddRef(filter->filter.outer_unk);
1020}
static struct dsound_render * impl_from_IQualityControl(IQualityControl *iface)

◆ quality_control_Notify()

static HRESULT WINAPI quality_control_Notify ( IQualityControl *  iface,
IBaseFilter *  sender,
Quality  q 
)
static

Definition at line 1028 of file dsoundrender.c.

1030{
1032
1033 FIXME("filter %p, sender %p, type %#x, proportion %ld, late %s, timestamp %s, stub!\n",
1034 filter, sender, q.Type, q.Proportion, debugstr_time(q.Late), debugstr_time(q.TimeStamp));
1035
1036 return E_NOTIMPL;
1037}
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063

◆ quality_control_QueryInterface()

static HRESULT WINAPI quality_control_QueryInterface ( IQualityControl *  iface,
REFIID  iid,
void **  out 
)
static

Definition at line 1009 of file dsoundrender.c.

1011{
1013 return IUnknown_QueryInterface(filter->filter.outer_unk, iid, out);
1014}

◆ quality_control_Release()

static ULONG WINAPI quality_control_Release ( IQualityControl *  iface)
static

Definition at line 1022 of file dsoundrender.c.

1023{
1025 return IUnknown_Release(filter->filter.outer_unk);
1026}

◆ quality_control_SetSink()

static HRESULT WINAPI quality_control_SetSink ( IQualityControl *  iface,
IQualityControl *  sink 
)
static

Definition at line 1039 of file dsoundrender.c.

1040{
1042
1043 FIXME("filter %p, sink %p, stub!\n", filter, sink);
1044
1045 return E_NOTIMPL;
1046}

◆ render_sample()

static HRESULT render_sample ( struct dsound_render *  filter,
IMediaSample *  pSample 
)
static

Definition at line 327 of file dsoundrender.c.

328{
329 REFERENCE_TIME start = -1, stop = -1;
330 LPBYTE pbSrcStream = NULL;
331 LONG cbSrcStream = 0;
332 HRESULT hr;
333
334 hr = IMediaSample_GetPointer(pSample, &pbSrcStream);
335 if (FAILED(hr))
336 {
337 ERR("Failed to get buffer pointer, hr %#lx.\n", hr);
338 return hr;
339 }
340
341 if (IMediaSample_IsDiscontinuity(pSample) == S_OK
342 && FAILED(hr = IMediaSample_GetTime(pSample, &start, &stop)))
343 {
344 ERR("Failed to get sample time, hr %#lx.\n", hr);
345 start = stop = -1;
346 }
347
348 cbSrcStream = IMediaSample_GetActualDataLength(pSample);
349 return send_sample_data(filter, start, pbSrcStream, cbSrcStream);
350}
static HRESULT send_sample_data(struct dsound_render *filter, REFERENCE_TIME tStart, const BYTE *data, DWORD size)
Definition: dsoundrender.c:231
long LONG
Definition: pedump.c:60
unsigned char * LPBYTE
Definition: typedefs.h:53

Referenced by render_thread_run().

◆ render_thread_run()

static DWORD WINAPI render_thread_run ( void *  arg)
static

Definition at line 352 of file dsoundrender.c.

353{
354 struct dsound_render *filter = arg;
355
356 TRACE("Render thread started.\n");
357
358 EnterCriticalSection(&filter->render_cs);
359
360 while (!filter->render_thread_shutdown)
361 {
363
364 if (filter->eos)
365 {
366 LeaveCriticalSection(&filter->render_cs);
367 TRACE("Got EOS.\n");
368 /* Clear the buffer. */
369 send_sample_data(filter, -1, NULL, filter->buf_size);
370
371 TRACE("Render thread exiting.\n");
372 return 0;
373 }
374
375 if (!filter->queued_sample_count)
376 {
377 SleepConditionVariableCS(&filter->render_cv, &filter->render_cs, INFINITE);
378 continue;
379 }
380
381 sample = filter->queued_samples[0];
382 if (--filter->queued_sample_count)
383 memmove(filter->queued_samples, filter->queued_samples + 1,
384 filter->queued_sample_count * sizeof(*filter->queued_samples));
385
386 LeaveCriticalSection(&filter->render_cs);
387
389 IMediaSample_Release(sample);
390
391 EnterCriticalSection(&filter->render_cs);
392 }
393
394 LeaveCriticalSection(&filter->render_cs);
395 TRACE("Render thread exiting.\n");
396 return 0;
397}
static HRESULT render_sample(struct dsound_render *filter, IMediaSample *pSample)
Definition: dsoundrender.c:327
BOOL WINAPI SleepConditionVariableCS(PCONDITION_VARIABLE ConditionVariable, PCRITICAL_SECTION CriticalSection, DWORD Timeout)
Definition: sync.c:59
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
void * arg
Definition: msvc.h:10

Referenced by dsound_render_init_stream(), and dsound_render_sink_end_flush().

◆ send_sample_data()

static HRESULT send_sample_data ( struct dsound_render *  filter,
REFERENCE_TIME  tStart,
const BYTE *  data,
DWORD  size 
)
static

Definition at line 231 of file dsoundrender.c.

233{
234 HRESULT hr;
235
236 while (size && filter->filter.state != State_Stopped)
237 {
238 DWORD writepos, free, size1, size2;
239 BYTE *buf1, *buf2;
240
241 if (filter->filter.state == State_Running)
242 hr = get_write_pos(filter, &writepos, tStart, &free);
243 else
244 hr = S_FALSE;
245
246 if (hr != S_OK)
247 {
248 if (!WaitForSingleObject(filter->flush_event, 10))
249 {
250 TRACE("Flush signaled; discarding sample.\n");
251 return VFW_E_WRONG_STATE;
252 }
253 continue;
254 }
255 tStart = -1;
256
257 hr = IDirectSoundBuffer_Lock(filter->dsbuffer, writepos, min(free, size),
258 (void **)&buf1, &size1, (void **)&buf2, &size2, 0);
259 if (hr != DS_OK)
260 {
261 ERR("Failed to lock sound buffer, hr %#lx.\n", hr);
262 break;
263 }
264
265 if (data)
266 {
267 memcpy(buf1, data, size1);
268 if (size2)
269 memcpy(buf2, data + size1, size2);
270 data += size1 + size2;
271 }
272 else
273 {
274 const WAVEFORMATEX *wfx = (const WAVEFORMATEX *)filter->sink.pin.mt.pbFormat;
275 char silence = (wfx->wBitsPerSample == 8 ? 0x80 : 0);
276
277 memset(buf1, silence, size1);
278 if (size2)
279 memset(buf2, silence, size2);
280 }
281 IDirectSoundBuffer_Unlock(filter->dsbuffer, buf1, size1, buf2, size2);
282 filter->writepos = (writepos + size1 + size2) % filter->buf_size;
283 TRACE("Wrote %lu bytes at %lu, next at %lu - (%lu/%lu)\n",
284 size1 + size2, writepos, filter->writepos, free, size);
285 size -= size1 + size2;
286 }
287 return S_OK;
288}
static HRESULT get_write_pos(struct dsound_render *filter, DWORD *ret_writepos, REFERENCE_TIME write_at, DWORD *pfree)
Definition: dsoundrender.c:158
#define DS_OK
Definition: dsound.h:116
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define min(a, b)
Definition: monoChain.cc:55
unsigned char BYTE
Definition: xxhash.c:193

Referenced by render_sample(), and render_thread_run().

◆ time_from_pos()

static REFERENCE_TIME time_from_pos ( struct dsound_render *  filter,
DWORD  pos 
)
static

Definition at line 98 of file dsoundrender.c.

99{
100 WAVEFORMATEX *wfx = (WAVEFORMATEX *)filter->sink.pin.mt.pbFormat;
101 REFERENCE_TIME ret = 10000000;
102 ret = ret * pos / wfx->nAvgBytesPerSec;
103 return ret;
104}

Referenced by get_write_pos().

◆ update_positions()

static void update_positions ( struct dsound_render *  filter,
DWORD *  seqwritepos,
DWORD *  minwritepos 
)
static

Definition at line 116 of file dsoundrender.c.

117{
118 WAVEFORMATEX *wfx = (WAVEFORMATEX *)filter->sink.pin.mt.pbFormat;
119 BYTE *buf1, *buf2;
120 DWORD size1, size2, playpos, writepos, old_writepos, old_playpos, adv;
121 BOOL writepos_set = filter->writepos < filter->buf_size;
122
123 /* Update position and zero */
124 old_writepos = filter->writepos;
125 old_playpos = filter->last_playpos;
126 if (old_writepos <= old_playpos)
127 old_writepos += filter->buf_size;
128
129 IDirectSoundBuffer_GetCurrentPosition(filter->dsbuffer, &playpos, &writepos);
130 if (old_playpos > playpos)
131 adv = filter->buf_size + playpos - old_playpos;
132 else
133 adv = playpos - old_playpos;
134 filter->last_playpos = playpos;
135 if (adv)
136 {
137 TRACE("Moving from %lu to %lu: clearing %lu bytes.\n", old_playpos, playpos, adv);
138 IDirectSoundBuffer_Lock(filter->dsbuffer, old_playpos, adv,
139 (void **)&buf1, &size1, (void **)&buf2, &size2, 0);
140 memset(buf1, wfx->wBitsPerSample == 8 ? 128 : 0, size1);
141 memset(buf2, wfx->wBitsPerSample == 8 ? 128 : 0, size2);
142 IDirectSoundBuffer_Unlock(filter->dsbuffer, buf1, size1, buf2, size2);
143 }
144 *minwritepos = writepos;
145 if (!writepos_set || old_writepos < writepos)
146 {
147 if (writepos_set)
148 {
149 filter->writepos = filter->buf_size;
150 FIXME("Underrun of data occurred!\n");
151 }
152 *seqwritepos = writepos;
153 }
154 else
155 *seqwritepos = filter->writepos;
156}
#define IDirectSoundBuffer_GetCurrentPosition(p, a, b)
Definition: dsound.h:577
unsigned int BOOL
Definition: ntddk_ex.h:94
if(dx< 0)
Definition: linetemp.h:194

Referenced by get_write_pos().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( quartz  )

Variable Documentation

◆ basic_audio_vtbl

const IBasicAudioVtbl basic_audio_vtbl
static
Initial value:
=
{
}
static ULONG WINAPI basic_audio_AddRef(IBasicAudio *iface)
Definition: dsoundrender.c:759
static HRESULT WINAPI basic_audio_GetTypeInfo(IBasicAudio *iface, UINT index, LCID lcid, ITypeInfo **typeinfo)
Definition: dsoundrender.c:781
static HRESULT WINAPI basic_audio_GetIDsOfNames(IBasicAudio *iface, REFIID iid, LPOLESTR *names, UINT count, LCID lcid, DISPID *ids)
Definition: dsoundrender.c:791
static HRESULT WINAPI basic_audio_put_Volume(IBasicAudio *iface, LONG volume)
Definition: dsoundrender.c:826
static HRESULT WINAPI basic_audio_get_Volume(IBasicAudio *iface, LONG *volume)
Definition: dsoundrender.c:842
static HRESULT WINAPI basic_audio_put_Balance(IBasicAudio *iface, LONG balance)
Definition: dsoundrender.c:855
static HRESULT WINAPI basic_audio_GetTypeInfoCount(IBasicAudio *iface, UINT *count)
Definition: dsoundrender.c:771
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)
Definition: dsoundrender.c:809
static HRESULT WINAPI basic_audio_get_Balance(IBasicAudio *iface, LONG *balance)
Definition: dsoundrender.c:871
static ULONG WINAPI basic_audio_Release(IBasicAudio *iface)
Definition: dsoundrender.c:765
static HRESULT WINAPI basic_audio_QueryInterface(IBasicAudio *iface, REFIID riid, void **out)
Definition: dsoundrender.c:753

Definition at line 884 of file dsoundrender.c.

Referenced by dsound_render_create().

◆ direct_sound_vtbl

const IAMDirectSoundVtbl direct_sound_vtbl
static
Initial value:
=
{
}
static ULONG WINAPI direct_sound_AddRef(IAMDirectSound *iface)
Definition: dsoundrender.c:905
static ULONG WINAPI direct_sound_Release(IAMDirectSound *iface)
Definition: dsoundrender.c:911
static HRESULT WINAPI direct_sound_GetSecondaryBufferInterface(IAMDirectSound *iface, IDirectSoundBuffer **buf)
Definition: dsoundrender.c:935
static HRESULT WINAPI direct_sound_QueryInterface(IAMDirectSound *iface, REFIID riid, void **out)
Definition: dsoundrender.c:899
static HRESULT WINAPI direct_sound_GetFocusWindow(IAMDirectSound *iface, HWND *hwnd, BOOL *bgaudible)
Definition: dsoundrender.c:980
static HRESULT WINAPI direct_sound_GetPrimaryBufferInterface(IAMDirectSound *iface, IDirectSoundBuffer **buf)
Definition: dsoundrender.c:926
static HRESULT WINAPI direct_sound_ReleaseDirectSoundInterface(IAMDirectSound *iface, IDirectSound *ds)
Definition: dsoundrender.c:944
static HRESULT WINAPI direct_sound_ReleasePrimaryBufferInterface(IAMDirectSound *iface, IDirectSoundBuffer *buf)
Definition: dsoundrender.c:953
static HRESULT WINAPI direct_sound_ReleaseSecondaryBufferInterface(IAMDirectSound *iface, IDirectSoundBuffer *buf)
Definition: dsoundrender.c:962
static HRESULT WINAPI direct_sound_GetDirectSoundInterface(IAMDirectSound *iface, IDirectSound **ds)
Definition: dsoundrender.c:917
static HRESULT WINAPI direct_sound_SetFocusWindow(IAMDirectSound *iface, HWND hwnd, BOOL bgaudible)
Definition: dsoundrender.c:971

Definition at line 989 of file dsoundrender.c.

Referenced by dsound_render_create().

◆ DSoundRenderer_Max_Fill

const REFERENCE_TIME DSoundRenderer_Max_Fill = 150 * 10000
static

Definition at line 40 of file dsoundrender.c.

Referenced by get_write_pos().

◆ filter_ops

const struct strmbase_filter_ops filter_ops
static
Initial value:
=
{
.filter_destroy = dsound_render_destroy,
.filter_get_pin = dsound_render_get_pin,
.filter_query_interface = dsound_render_query_interface,
.filter_init_stream = dsound_render_init_stream,
.filter_start_stream = dsound_render_start_stream,
.filter_stop_stream = dsound_render_stop_stream,
.filter_cleanup_stream = dsound_render_cleanup_stream,
.filter_wait_state = dsound_render_wait_state,
}
static HRESULT dsound_render_init_stream(struct strmbase_filter *iface)
Definition: dsoundrender.c:651
static void dsound_render_destroy(struct strmbase_filter *iface)
Definition: dsoundrender.c:590
static HRESULT dsound_render_stop_stream(struct strmbase_filter *iface)
Definition: dsoundrender.c:695
static HRESULT dsound_render_query_interface(struct strmbase_filter *iface, REFIID iid, void **out)
Definition: dsoundrender.c:628
static HRESULT dsound_render_start_stream(struct strmbase_filter *iface, REFERENCE_TIME start)
Definition: dsoundrender.c:670
static HRESULT dsound_render_cleanup_stream(struct strmbase_filter *iface)
Definition: dsoundrender.c:707
static struct strmbase_pin * dsound_render_get_pin(struct strmbase_filter *iface, unsigned int index)
Definition: dsoundrender.c:619
static HRESULT dsound_render_wait_state(struct strmbase_filter *iface, DWORD timeout)
Definition: dsoundrender.c:732

Definition at line 741 of file dsoundrender.c.

Referenced by dsound_render_create().

◆ quality_control_vtbl

const IQualityControlVtbl quality_control_vtbl
static
Initial value:
=
{
}
static HRESULT WINAPI quality_control_QueryInterface(IQualityControl *iface, REFIID iid, void **out)
static HRESULT WINAPI quality_control_Notify(IQualityControl *iface, IBaseFilter *sender, Quality q)
static HRESULT WINAPI quality_control_SetSink(IQualityControl *iface, IQualityControl *sink)
static ULONG WINAPI quality_control_AddRef(IQualityControl *iface)
static ULONG WINAPI quality_control_Release(IQualityControl *iface)

Definition at line 1048 of file dsoundrender.c.

Referenced by dsound_render_create().

◆ sink_ops

const struct strmbase_sink_ops sink_ops
static
Initial value:
=
{
.base.pin_query_interface = dsound_render_sink_query_interface,
.base.pin_query_accept = dsound_render_sink_query_accept,
.sink_connect = dsound_render_sink_connect,
.sink_disconnect = dsound_render_sink_disconnect,
.sink_begin_flush = dsound_render_sink_begin_flush,
.sink_end_flush = dsound_render_sink_end_flush,
}
static HRESULT dsound_render_sink_end_flush(struct strmbase_sink *iface)
Definition: dsoundrender.c:542
static HRESULT dsound_render_sink_begin_flush(struct strmbase_sink *iface)
Definition: dsoundrender.c:534
static HRESULT dsound_render_sink_connect(struct strmbase_sink *iface, IPin *peer, const AM_MEDIA_TYPE *mt)
Definition: dsoundrender.c:456
static void dsound_render_sink_disconnect(struct strmbase_sink *iface)
Definition: dsoundrender.c:499
static HRESULT dsound_render_sink_eos(struct strmbase_sink *iface)
Definition: dsoundrender.c:510
static HRESULT dsound_render_sink_query_interface(struct strmbase_pin *iface, REFIID iid, void **out)
Definition: dsoundrender.c:435
static HRESULT WINAPI dsound_render_sink_Receive(struct strmbase_sink *iface, IMediaSample *sample)
Definition: dsoundrender.c:399
static HRESULT dsound_render_sink_query_accept(struct strmbase_pin *iface, const AM_MEDIA_TYPE *pmt)
Definition: dsoundrender.c:448

Definition at line 578 of file dsoundrender.c.

Referenced by dsound_render_create().