static HRESULT WINAPI DSoundRender_PrepareReceive(BaseRenderer *iface, IMediaSample *pSample) { DSoundRenderImpl *This = impl_from_BaseRenderer(iface); HRESULT hr; AM_MEDIA_TYPE *amt; if (IMediaSample_GetMediaType(pSample, &amt) == S_OK) { AM_MEDIA_TYPE *orig = &This->renderer.pInputPin->pin.mtCurrent; WAVEFORMATEX *origfmt = (WAVEFORMATEX *)orig->pbFormat; WAVEFORMATEX *newfmt = (WAVEFORMATEX *)amt->pbFormat; if (origfmt->wFormatTag == newfmt->wFormatTag && origfmt->nChannels == newfmt->nChannels && origfmt->nBlockAlign == newfmt->nBlockAlign && origfmt->wBitsPerSample == newfmt->wBitsPerSample && origfmt->cbSize == newfmt->cbSize) { if (origfmt->nSamplesPerSec != newfmt->nSamplesPerSec) { hr = IDirectSoundBuffer_SetFrequency(This->dsbuffer, newfmt->nSamplesPerSec); if (FAILED(hr)) return VFW_E_TYPE_NOT_ACCEPTED; FreeMediaType(orig); CopyMediaType(orig, amt); IMediaSample_SetMediaType(pSample, NULL); } } else return VFW_E_TYPE_NOT_ACCEPTED; } return S_OK; }
static HRESULT WINAPI DSoundRender_DoRenderSample(BaseRenderer *iface, IMediaSample * pSample) { DSoundRenderImpl *This = impl_from_BaseRenderer(iface); LPBYTE pbSrcStream = NULL; LONG cbSrcStream = 0; REFERENCE_TIME tStart, tStop; HRESULT hr; TRACE("%p %p\n", iface, pSample); /* Slightly incorrect, Pause completes when a frame is received so we should signal * pause completion here, but for sound playing a single frame doesn't make sense */ hr = IMediaSample_GetPointer(pSample, &pbSrcStream); 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); tStart = tStop = -1; } IMediaSample_IsDiscontinuity(pSample); if (IMediaSample_IsPreroll(pSample) == S_OK) { TRACE("Preroll!\n"); return S_OK; } cbSrcStream = IMediaSample_GetActualDataLength(pSample); TRACE("Sample data ptr = %p, size = %d\n", pbSrcStream, cbSrcStream); hr = DSoundRender_SendSampleData(This, tStart, tStop, pbSrcStream, cbSrcStream); if (This->renderer.filter.state == State_Running && This->renderer.filter.pClock && tStart >= 0) { REFERENCE_TIME jitter, now = 0; Quality q; IReferenceClock_GetTime(This->renderer.filter.pClock, &now); jitter = now - This->renderer.filter.rtStreamStart - tStart; if (jitter <= -DSoundRenderer_Max_Fill) jitter += DSoundRenderer_Max_Fill; else if (jitter < 0) jitter = 0; q.Type = (jitter > 0 ? Famine : Flood); q.Proportion = 1000; q.Late = jitter; q.TimeStamp = tStart; IQualityControl_Notify((IQualityControl *)This->renderer.qcimpl, (IBaseFilter*)This, q); } return hr; }
static HRESULT WINAPI DSoundRender_BeginFlush(BaseRenderer* iface) { DSoundRenderImpl *This = impl_from_BaseRenderer(iface); TRACE("\n"); BaseRendererImpl_BeginFlush(iface); SetEvent(This->blocked); return S_OK; }
static VOID WINAPI DSoundRender_OnStopStreaming(BaseRenderer * iface) { DSoundRenderImpl *This = impl_from_BaseRenderer(iface); TRACE("(%p/%p)->()\n", This, iface); IDirectSoundBuffer_Stop(This->dsbuffer); This->writepos = This->buf_size; SetEvent(This->blocked); }
static VOID WINAPI VideoRenderer_OnStopStreaming(BaseRenderer* iface) { VideoRendererImpl *This = impl_from_BaseRenderer(iface); TRACE("(%p)->()\n", This); SetEvent(This->hEvent); if (This->baseControlWindow.AutoShow) /* Black it out */ RedrawWindow(This->baseControlWindow.baseWindow.hWnd, NULL, NULL, RDW_INVALIDATE|RDW_ERASE); }
static HRESULT WINAPI DSoundRender_CompleteConnect(BaseRenderer * iface, IPin * pReceivePin) { DSoundRenderImpl *This = impl_from_BaseRenderer(iface); const AM_MEDIA_TYPE * pmt = &This->renderer.pInputPin->pin.mtCurrent; HRESULT hr = S_OK; WAVEFORMATEX *format; DSBUFFERDESC buf_desc; TRACE("(%p)->(%p)\n", This, pReceivePin); dump_AM_MEDIA_TYPE(pmt); TRACE("MajorType %s\n", debugstr_guid(&pmt->majortype)); TRACE("SubType %s\n", debugstr_guid(&pmt->subtype)); TRACE("Format %s\n", debugstr_guid(&pmt->formattype)); TRACE("Size %d\n", pmt->cbFormat); format = (WAVEFORMATEX*)pmt->pbFormat; This->buf_size = format->nAvgBytesPerSec; memset(&buf_desc,0,sizeof(DSBUFFERDESC)); buf_desc.dwSize = sizeof(DSBUFFERDESC); buf_desc.dwFlags = DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLPAN | DSBCAPS_CTRLFREQUENCY | DSBCAPS_GLOBALFOCUS | DSBCAPS_GETCURRENTPOSITION2; buf_desc.dwBufferBytes = This->buf_size; buf_desc.lpwfxFormat = format; hr = IDirectSound_CreateSoundBuffer(This->dsound, &buf_desc, &This->dsbuffer, NULL); This->writepos = This->buf_size; if (FAILED(hr)) ERR("Can't create sound buffer (%x)\n", hr); if (SUCCEEDED(hr)) { hr = IDirectSoundBuffer_SetVolume(This->dsbuffer, This->volume); if (FAILED(hr)) ERR("Can't set volume to %d (%x)\n", This->volume, hr); hr = IDirectSoundBuffer_SetPan(This->dsbuffer, This->pan); if (FAILED(hr)) ERR("Can't set pan to %d (%x)\n", This->pan, hr); hr = S_OK; } if (FAILED(hr) && hr != VFW_E_ALREADY_CONNECTED) { if (This->dsbuffer) IDirectSoundBuffer_Release(This->dsbuffer); This->dsbuffer = NULL; } return hr; }
static HRESULT WINAPI VideoRenderer_DoRenderSample(BaseRenderer* iface, IMediaSample * pSample) { VideoRendererImpl *This = impl_from_BaseRenderer(iface); LPBYTE pbSrcStream = NULL; LONG cbSrcStream = 0; HRESULT hr; TRACE("(%p)->(%p)\n", This, pSample); 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("val %p %d\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 SetEvent(This->hEvent); if (This->renderer.filter.state == State_Paused) { VideoRenderer_SendSampleData(This, pbSrcStream, cbSrcStream); SetEvent(This->hEvent); if (This->renderer.filter.state == State_Paused) { /* Flushing */ return S_OK; } if (This->renderer.filter.state == State_Stopped) { return VFW_E_WRONG_STATE; } } else { VideoRenderer_SendSampleData(This, pbSrcStream, cbSrcStream); } return S_OK; }
static VOID WINAPI VideoRenderer_OnStartStreaming(BaseRenderer* iface) { VideoRendererImpl *This = impl_from_BaseRenderer(iface); TRACE("(%p)\n", This); if (This->renderer.pInputPin->pin.pConnectedTo && (This->renderer.filter.state == State_Stopped || !This->renderer.pInputPin->end_of_stream)) { if (This->renderer.filter.state == State_Stopped) { ResetEvent(This->hEvent); VideoRenderer_AutoShowWindow(This); } } }
static HRESULT WINAPI VideoRenderer_CheckMediaType(BaseRenderer *iface, const AM_MEDIA_TYPE * pmt) { VideoRendererImpl *This = impl_from_BaseRenderer(iface); if (!IsEqualIID(&pmt->majortype, &MEDIATYPE_Video)) return S_FALSE; if (IsEqualIID(&pmt->subtype, &MEDIASUBTYPE_RGB32) || IsEqualIID(&pmt->subtype, &MEDIASUBTYPE_RGB24) || IsEqualIID(&pmt->subtype, &MEDIASUBTYPE_RGB565) || IsEqualIID(&pmt->subtype, &MEDIASUBTYPE_RGB8)) { LONG height; if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo)) { VIDEOINFOHEADER *format = (VIDEOINFOHEADER *)pmt->pbFormat; This->SourceRect.left = 0; This->SourceRect.top = 0; This->SourceRect.right = This->VideoWidth = format->bmiHeader.biWidth; height = format->bmiHeader.biHeight; if (height < 0) This->SourceRect.bottom = This->VideoHeight = -height; else This->SourceRect.bottom = This->VideoHeight = height; } else if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo2)) { VIDEOINFOHEADER2 *format2 = (VIDEOINFOHEADER2 *)pmt->pbFormat; This->SourceRect.left = 0; This->SourceRect.top = 0; This->SourceRect.right = This->VideoWidth = format2->bmiHeader.biWidth; height = format2->bmiHeader.biHeight; if (height < 0) This->SourceRect.bottom = This->VideoHeight = -height; else This->SourceRect.bottom = This->VideoHeight = height; } else { WARN("Format type %s not supported\n", debugstr_guid(&pmt->formattype)); return S_FALSE; } return S_OK; } return S_FALSE; }
static VOID WINAPI DSoundRender_OnStartStreaming(BaseRenderer * iface) { DSoundRenderImpl *This = impl_from_BaseRenderer(iface); TRACE("(%p)\n", This); if (This->renderer.pInputPin->pin.pConnectedTo) { if (This->renderer.filter.state == State_Paused) { /* Unblock our thread, state changing from paused to running doesn't need a reset for state change */ SetEvent(This->blocked); } IDirectSoundBuffer_Play(This->dsbuffer, 0, 0, DSBPLAY_LOOPING); ResetEvent(This->blocked); } }
static HRESULT WINAPI DSoundRender_EndOfStream(BaseRenderer* iface) { DSoundRenderImpl *This = impl_from_BaseRenderer(iface); HRESULT hr; TRACE("(%p)->()\n",iface); hr = BaseRendererImpl_EndOfStream(iface); if (hr != S_OK) { ERR("%08x\n", hr); return hr; } hr = DSoundRender_HandleEndOfStream(This); return hr; }
static HRESULT WINAPI DSoundRender_BreakConnect(BaseRenderer* iface) { DSoundRenderImpl *This = impl_from_BaseRenderer(iface); TRACE("(%p)->()\n", iface); if (This->threadid) { PostThreadMessageW(This->threadid, WM_APP, 0, 0); LeaveCriticalSection(This->renderer.pInputPin->pin.pCritSec); WaitForSingleObject(This->advisethread, INFINITE); EnterCriticalSection(This->renderer.pInputPin->pin.pCritSec); CloseHandle(This->advisethread); } if (This->dsbuffer) IDirectSoundBuffer_Release(This->dsbuffer); This->dsbuffer = NULL; return S_OK; }
static HRESULT WINAPI VideoRenderer_EndFlush(BaseRenderer* iface) { VideoRendererImpl *This = impl_from_BaseRenderer(iface); TRACE("(%p)->()\n", iface); if (This->renderer.pMediaSample) { ResetEvent(This->hEvent); LeaveCriticalSection(iface->pInputPin->pin.pCritSec); LeaveCriticalSection(&iface->csRenderLock); LeaveCriticalSection(&iface->filter.csFilter); WaitForSingleObject(This->hEvent, INFINITE); EnterCriticalSection(&iface->filter.csFilter); EnterCriticalSection(&iface->csRenderLock); EnterCriticalSection(iface->pInputPin->pin.pCritSec); } if (This->renderer.filter.state == State_Paused) { ResetEvent(This->hEvent); } return BaseRendererImpl_EndFlush(iface); }
static HRESULT WINAPI DSoundRender_EndFlush(BaseRenderer* iface) { DSoundRenderImpl *This = impl_from_BaseRenderer(iface); TRACE("\n"); BaseRendererImpl_EndFlush(iface); if (This->renderer.filter.state != State_Stopped) ResetEvent(This->blocked); if (This->dsbuffer) { LPBYTE buffer; DWORD size; /* Force a reset */ IDirectSoundBuffer_Lock(This->dsbuffer, 0, 0, (LPVOID *)&buffer, &size, NULL, NULL, DSBLOCK_ENTIREBUFFER); memset(buffer, 0, size); IDirectSoundBuffer_Unlock(This->dsbuffer, buffer, size, NULL, 0); This->writepos = This->buf_size; } return S_OK; }