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_Receive(BaseInputPin *pin, IMediaSample * pSample) { DSoundRenderImpl *This = (DSoundRenderImpl*)pin->pin.pinInfo.pFilter; LPBYTE pbSrcStream = NULL; LONG cbSrcStream = 0; REFERENCE_TIME tStart, tStop; HRESULT hr; AM_MEDIA_TYPE *amt; TRACE("%p %p\n", pin, 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 */ EnterCriticalSection(&This->filter.csFilter); if (This->pInputPin->end_of_stream || This->pInputPin->flushing) { LeaveCriticalSection(&This->filter.csFilter); return S_FALSE; } if (This->filter.state == State_Stopped) { LeaveCriticalSection(&This->filter.csFilter); return VFW_E_WRONG_STATE; } if (IMediaSample_GetMediaType(pSample, &amt) == S_OK) { AM_MEDIA_TYPE *orig = &This->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)) { LeaveCriticalSection(&This->filter.csFilter); return VFW_E_TYPE_NOT_ACCEPTED; } FreeMediaType(orig); CopyMediaType(orig, amt); IMediaSample_SetMediaType(pSample, NULL); } } else { LeaveCriticalSection(&This->filter.csFilter); return VFW_E_TYPE_NOT_ACCEPTED; } } hr = IMediaSample_GetPointer(pSample, &pbSrcStream); if (FAILED(hr)) { ERR("Cannot get pointer to sample data (%x)\n", hr); LeaveCriticalSection(&This->filter.csFilter); return hr; } hr = IMediaSample_GetTime(pSample, &tStart, &tStop); if (FAILED(hr)) ERR("Cannot get sample time (%x)\n", hr); else MediaSeekingPassThru_RegisterMediaTime(This->seekthru_unk, tStart); if (This->rtLastStop != tStart && (IMediaSample_IsDiscontinuity(pSample) == S_FALSE)) WARN("Unexpected discontinuity: Last: %u.%03u, tStart: %u.%03u\n", (DWORD)(This->rtLastStop / 10000000), (DWORD)((This->rtLastStop / 10000)%1000), (DWORD)(tStart / 10000000), (DWORD)((tStart / 10000)%1000)); This->rtLastStop = tStop; if (IMediaSample_IsPreroll(pSample) == S_OK) { TRACE("Preroll!\n"); LeaveCriticalSection(&This->filter.csFilter); return S_OK; } if (This->filter.state == State_Paused) { SetEvent(This->state_change); LeaveCriticalSection(&This->filter.csFilter); WaitForSingleObject(This->blocked, INFINITE); EnterCriticalSection(&This->filter.csFilter); if (This->filter.state == State_Stopped) { LeaveCriticalSection(&This->filter.csFilter); return VFW_E_WRONG_STATE; } if (This->filter.state == State_Paused) { /* Assuming we return because of flushing */ TRACE("Flushing\n"); LeaveCriticalSection(&This->filter.csFilter); return S_OK; } SetEvent(This->state_change); } cbSrcStream = IMediaSample_GetActualDataLength(pSample); TRACE("Sample data ptr = %p, size = %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 hr = DSoundRender_SendSampleData(This, pbSrcStream, cbSrcStream); SetEvent(This->state_change); LeaveCriticalSection(&This->filter.csFilter); return hr; }
HRESULT WINAPI BaseRendererImpl_Receive(BaseRenderer *This, IMediaSample * pSample) { HRESULT hr = S_OK; REFERENCE_TIME start, stop; AM_MEDIA_TYPE *pmt; TRACE("(%p)->%p\n", This, pSample); if (This->pInputPin->end_of_stream || This->pInputPin->flushing) return S_FALSE; if (This->filter.state == State_Stopped) return VFW_E_WRONG_STATE; if (IMediaSample_GetMediaType(pSample, &pmt) == S_OK) { if (FAILED(This->pFuncsTable->pfnCheckMediaType(This, pmt))) { return VFW_E_TYPE_NOT_ACCEPTED; } } This->pMediaSample = pSample; IMediaSample_AddRef(pSample); if (This->pFuncsTable->pfnPrepareReceive) hr = This->pFuncsTable->pfnPrepareReceive(This, pSample); if (FAILED(hr)) { if (hr == VFW_E_SAMPLE_REJECTED) return S_OK; else return hr; } if (This->pFuncsTable->pfnPrepareRender) This->pFuncsTable->pfnPrepareRender(This); EnterCriticalSection(&This->csRenderLock); if ( This->filter.state == State_Paused ) { if (This->pFuncsTable->pfnOnReceiveFirstSample) This->pFuncsTable->pfnOnReceiveFirstSample(This, pSample); SetEvent(This->evComplete); } /* Wait for render Time */ if (SUCCEEDED(IMediaSample_GetMediaTime(pSample, &start, &stop))) { hr = S_FALSE; RendererPosPassThru_RegisterMediaTime(This->pPosition, start); if (This->pFuncsTable->pfnShouldDrawSampleNow) hr = This->pFuncsTable->pfnShouldDrawSampleNow(This, pSample, &start, &stop); if (hr == S_OK) ;/* Do not wait: drop through */ else if (hr == S_FALSE) { if (This->pFuncsTable->pfnOnWaitStart) This->pFuncsTable->pfnOnWaitStart(This); hr = QualityControlRender_WaitFor(This->qcimpl, pSample, This->RenderEvent); if (This->pFuncsTable->pfnOnWaitEnd) This->pFuncsTable->pfnOnWaitEnd(This); } else { LeaveCriticalSection(&This->csRenderLock); /* Drop Sample */ return S_OK; } } if (SUCCEEDED(hr)) { QualityControlRender_BeginRender(This->qcimpl); hr = This->pFuncsTable->pfnDoRenderSample(This, pSample); QualityControlRender_EndRender(This->qcimpl); } QualityControlRender_DoQOS(This->qcimpl); BaseRendererImpl_ClearPendingSample(This); LeaveCriticalSection(&This->csRenderLock); return hr; }
static HRESULT WINAPI AVICompressorIn_Receive(BaseInputPin *base, IMediaSample *pSample) { AVICompressor *This = impl_from_BasePin(&base->pin); VIDEOINFOHEADER *src_videoinfo; REFERENCE_TIME start, stop; IMediaSample *out_sample; AM_MEDIA_TYPE *mt; IMediaSample2 *sample2; DWORD comp_flags = 0; BOOL is_preroll; BOOL sync_point; BYTE *ptr, *buf; DWORD res; HRESULT hres; TRACE("(%p)->(%p)\n", base, pSample); if(!This->hic) { FIXME("Driver not loaded\n"); return E_UNEXPECTED; } hres = IMediaSample_QueryInterface(pSample, &IID_IMediaSample2, (void**)&sample2); if(SUCCEEDED(hres)) { FIXME("Use IMediaSample2\n"); IMediaSample2_Release(sample2); } is_preroll = IMediaSample_IsPreroll(pSample) == S_OK; sync_point = IMediaSample_IsSyncPoint(pSample) == S_OK; hres = IMediaSample_GetTime(pSample, &start, &stop); if(FAILED(hres)) { WARN("GetTime failed: %08x\n", hres); return hres; } hres = IMediaSample_GetMediaType(pSample, &mt); if(FAILED(hres)) return hres; hres = IMediaSample_GetPointer(pSample, &ptr); if(FAILED(hres)) { WARN("GetPointer failed: %08x\n", hres); return hres; } hres = BaseOutputPinImpl_GetDeliveryBuffer(This->out, &out_sample, &start, &stop, 0); if(FAILED(hres)) return hres; hres = IMediaSample_GetPointer(out_sample, &buf); if(FAILED(hres)) return hres; if((This->driver_flags & VIDCF_TEMPORAL) && !(This->driver_flags & VIDCF_FASTTEMPORALC)) FIXME("Unsupported temporal compression\n"); src_videoinfo = (VIDEOINFOHEADER*)This->in->pin.mtCurrent.pbFormat; This->videoinfo->bmiHeader.biSizeImage = This->max_frame_size; res = ICCompress(This->hic, sync_point ? ICCOMPRESS_KEYFRAME : 0, &This->videoinfo->bmiHeader, buf, &src_videoinfo->bmiHeader, ptr, 0, &comp_flags, This->frame_cnt, 0, 0, NULL, NULL); if(res != ICERR_OK) { WARN("ICCompress failed: %d\n", res); IMediaSample_Release(out_sample); return E_FAIL; } IMediaSample_SetActualDataLength(out_sample, This->videoinfo->bmiHeader.biSizeImage); IMediaSample_SetPreroll(out_sample, is_preroll); IMediaSample_SetSyncPoint(out_sample, (comp_flags&AVIIF_KEYFRAME) != 0); IMediaSample_SetDiscontinuity(out_sample, (IMediaSample_IsDiscontinuity(pSample) == S_OK)); if (IMediaSample_GetMediaTime(pSample, &start, &stop) == S_OK) IMediaSample_SetMediaTime(out_sample, &start, &stop); else IMediaSample_SetMediaTime(out_sample, NULL, NULL); hres = BaseOutputPinImpl_Deliver(This->out, out_sample); if(FAILED(hres)) WARN("Deliver failed: %08x\n", hres); IMediaSample_Release(out_sample); This->frame_cnt++; return hres; }