00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "stdafx.h"
00023 #include <streams.h>
00024 #include <aviriff.h>
00025 #include "wavdest.h"
00026 #include "..\..\..\DSUtil\DSUtil.h"
00027
00028 #ifdef REGISTER_FILTER
00029
00030 const AMOVIESETUP_MEDIATYPE sudPinTypesIn[] =
00031 {
00032 {&MEDIATYPE_Audio, &MEDIASUBTYPE_WAVE},
00033 };
00034
00035 const AMOVIESETUP_MEDIATYPE sudPinTypesOut[] =
00036 {
00037 {&MEDIATYPE_Stream, &MEDIASUBTYPE_WAVE},
00038 };
00039
00040 const AMOVIESETUP_PIN sudpPins[] =
00041 {
00042 {L"Input", FALSE, FALSE, FALSE, FALSE, &CLSID_NULL, NULL, countof(sudPinTypesIn), sudPinTypesIn},
00043 {L"Output", FALSE, TRUE, FALSE, FALSE, &CLSID_NULL, NULL, countof(sudPinTypesOut), sudPinTypesOut}
00044 };
00045
00046 const AMOVIESETUP_FILTER sudFilter[] =
00047 {
00048 {&__uuidof(CWavDestFilter), L"WavDest", MERIT_DO_NOT_USE, countof(sudpPins), sudpPins}
00049 };
00050
00051 CFactoryTemplate g_Templates[] =
00052 {
00053 {L"WavDest", &__uuidof(CWavDestFilter), CreateInstance<CWavDestFilter>, NULL, &sudFilter[0]}
00054 };
00055
00056 int g_cTemplates = countof(g_Templates);
00057
00058 STDAPI DllRegisterServer()
00059 {
00060 return AMovieDllRegisterServer2(TRUE);
00061 }
00062
00063 STDAPI DllUnregisterServer()
00064 {
00065 return AMovieDllRegisterServer2(FALSE);
00066 }
00067
00068 extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);
00069
00070 BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
00071 {
00072 return DllEntryPoint((HINSTANCE)hModule, dwReason, 0);
00073 }
00074
00075 #endif
00076
00077
00078
00079
00080
00081 CWavDestFilter::CWavDestFilter(LPUNKNOWN pUnk, HRESULT* phr)
00082 : CTransformFilter(NAME("WavDest filter"), pUnk, __uuidof(this))
00083 {
00084 if(SUCCEEDED(*phr))
00085 {
00086 if(CWavDestOutputPin* pOut = new CWavDestOutputPin(this, phr))
00087 {
00088 if(SUCCEEDED(*phr)) m_pOutput = pOut;
00089 else delete pOut;
00090 }
00091 else
00092 {
00093 *phr = E_OUTOFMEMORY;
00094 return;
00095 }
00096
00097 if(CTransformInputPin* pIn = new CTransformInputPin(NAME("Transform input pin"), this, phr, L"In"))
00098 {
00099 if(SUCCEEDED(*phr)) m_pInput = pIn;
00100 else delete pIn;
00101 }
00102 else
00103 {
00104 *phr = E_OUTOFMEMORY;
00105 return;
00106 }
00107 }
00108 }
00109
00110 CWavDestFilter::~CWavDestFilter()
00111 {
00112 }
00113
00114 HRESULT CWavDestFilter::CheckTransform(const CMediaType* mtIn, const CMediaType* mtOut)
00115 {
00116 return CheckInputType(mtIn);
00117 }
00118
00119 HRESULT CWavDestFilter::Receive(IMediaSample* pSample)
00120 {
00121 ULONG cbOld = m_cbWavData;
00122 HRESULT hr = CTransformFilter::Receive(pSample);
00123
00124
00125 if(hr != S_OK)
00126 m_cbWavData = cbOld;
00127
00128 return hr;
00129 }
00130
00131 HRESULT CWavDestFilter::Transform(IMediaSample* pIn, IMediaSample* pOut)
00132 {
00133 REFERENCE_TIME rtStart, rtEnd;
00134
00135 HRESULT hr = Copy(pIn, pOut);
00136 if(FAILED(hr))
00137 return hr;
00138
00139
00140 LONG lActual = pOut->GetActualDataLength();
00141
00142 if(m_cbWavData + m_cbHeader + lActual < m_cbWavData + m_cbHeader )
00143 return E_FAIL;
00144
00145 rtStart = m_cbWavData + m_cbHeader;
00146 rtEnd = rtStart + lActual;
00147 m_cbWavData += lActual;
00148
00149 EXECUTE_ASSERT(pOut->SetTime(&rtStart, &rtEnd) == S_OK);
00150
00151 return S_OK;
00152 }
00153
00154 HRESULT CWavDestFilter::Copy(IMediaSample* pSource, IMediaSample* pDest) const
00155 {
00156 BYTE* pSourceBuffer, * pDestBuffer;
00157 long lSourceSize = pSource->GetActualDataLength();
00158
00159 #ifdef DEBUG
00160 long lDestSize = pDest->GetSize();
00161 ASSERT(lDestSize >= lSourceSize);
00162 #endif
00163
00164 pSource->GetPointer(&pSourceBuffer);
00165 pDest->GetPointer(&pDestBuffer);
00166
00167 CopyMemory((PVOID)pDestBuffer, (PVOID)pSourceBuffer, lSourceSize);
00168
00169
00170
00171 REFERENCE_TIME TimeStart, TimeEnd;
00172 if(NOERROR == pSource->GetTime(&TimeStart, &TimeEnd))
00173 pDest->SetTime(&TimeStart, &TimeEnd);
00174
00175 LONGLONG MediaStart, MediaEnd;
00176 if(pSource->GetMediaTime(&MediaStart, &MediaEnd) == NOERROR)
00177 pDest->SetMediaTime(&MediaStart, &MediaEnd);
00178
00179
00180 AM_MEDIA_TYPE* pMediaType;
00181 pSource->GetMediaType(&pMediaType);
00182 pDest->SetMediaType(pMediaType);
00183 DeleteMediaType(pMediaType);
00184
00185
00186 long lDataLength = pSource->GetActualDataLength();
00187 pDest->SetActualDataLength(lDataLength);
00188
00189 return NOERROR;
00190 }
00191
00192 HRESULT CWavDestFilter::CheckInputType(const CMediaType* mtIn)
00193 {
00194 return mtIn->formattype == FORMAT_WaveFormatEx ? S_OK : S_FALSE;
00195 }
00196
00197 HRESULT CWavDestFilter::GetMediaType(int iPosition, CMediaType* pMediaType)
00198 {
00199 ASSERT(iPosition == 0 || iPosition == 1);
00200
00201 if(iPosition == 0)
00202 {
00203 pMediaType->SetType(&MEDIATYPE_Stream);
00204 pMediaType->SetSubtype(&MEDIASUBTYPE_WAVE);
00205 return S_OK;
00206 }
00207
00208 return VFW_S_NO_MORE_ITEMS;
00209 }
00210
00211 HRESULT CWavDestFilter::DecideBufferSize(IMemAllocator* pAlloc, ALLOCATOR_PROPERTIES* pProperties)
00212 {
00213 if(m_pInput->IsConnected() == FALSE)
00214 return E_UNEXPECTED;
00215
00216 ASSERT(pAlloc);
00217 ASSERT(pProperties);
00218
00219 HRESULT hr = NOERROR;
00220
00221 pProperties->cBuffers = 1;
00222 pProperties->cbAlign = 1;
00223
00224 CComPtr<IMemAllocator> pInAlloc;
00225 ALLOCATOR_PROPERTIES InProps;
00226 if(SUCCEEDED(hr = m_pInput->GetAllocator(&pInAlloc))
00227 && SUCCEEDED(hr = pInAlloc->GetProperties(&InProps)))
00228 {
00229 pProperties->cbBuffer = InProps.cbBuffer;
00230 }
00231 else
00232 {
00233 return hr;
00234 }
00235
00236 ASSERT(pProperties->cbBuffer);
00237
00238 ALLOCATOR_PROPERTIES Actual;
00239 if(FAILED(hr = pAlloc->SetProperties(pProperties,&Actual)))
00240 return hr;
00241
00242 ASSERT(Actual.cBuffers == 1);
00243
00244 if(pProperties->cBuffers > Actual.cBuffers
00245 || pProperties->cbBuffer > Actual.cbBuffer)
00246 {
00247 return E_FAIL;
00248 }
00249
00250 return NOERROR;
00251 }
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261 HRESULT CWavDestFilter::StartStreaming()
00262 {
00263
00264 m_cbHeader = sizeof(RIFFLIST) +
00265 sizeof(RIFFCHUNK) +
00266 m_pInput->CurrentMediaType().FormatLength() +
00267 sizeof(RIFFCHUNK);
00268
00269 m_cbWavData = 0;
00270
00271 return S_OK;
00272 }
00273
00274 HRESULT CWavDestFilter::StopStreaming()
00275 {
00276 IStream* pStream;
00277 if (m_pOutput->IsConnected() == FALSE)
00278 return E_FAIL;
00279
00280 IPin* pDwnstrmInputPin = m_pOutput->GetConnected();
00281
00282 if (!pDwnstrmInputPin)
00283 return E_FAIL;
00284
00285 HRESULT hr = ((IMemInputPin *) pDwnstrmInputPin)->QueryInterface(IID_IStream, (void **)&pStream);
00286 if(SUCCEEDED(hr))
00287 {
00288 BYTE *pb = (BYTE *)_alloca(m_cbHeader);
00289
00290 RIFFLIST *pRiffWave = (RIFFLIST *)pb;
00291 RIFFCHUNK *pRiffFmt = (RIFFCHUNK *)(pRiffWave + 1);
00292 RIFFCHUNK *pRiffData = (RIFFCHUNK *)(((BYTE *)(pRiffFmt + 1)) + m_pInput->CurrentMediaType().FormatLength());;
00293
00294 pRiffData->fcc = FCC('data');
00295 pRiffData->cb = m_cbWavData;
00296
00297 pRiffFmt->fcc = FCC('fmt ');
00298 pRiffFmt->cb = m_pInput->CurrentMediaType().FormatLength();
00299 CopyMemory(pRiffFmt + 1, m_pInput->CurrentMediaType().Format(), pRiffFmt->cb);
00300
00301 pRiffWave->fcc = FCC('RIFF');
00302 pRiffWave->cb = m_cbWavData + m_cbHeader - sizeof(RIFFCHUNK);
00303 pRiffWave->fccListType = FCC('WAVE');
00304
00305 LARGE_INTEGER li;
00306 ZeroMemory(&li, sizeof(li));
00307
00308 hr = pStream->Seek(li, STREAM_SEEK_SET, 0);
00309 if(SUCCEEDED(hr)) {
00310 hr = pStream->Write(pb, m_cbHeader, 0);
00311 }
00312 pStream->Release();
00313 }
00314
00315 return hr;
00316 }
00317
00318 CWavDestOutputPin::CWavDestOutputPin(CTransformFilter* pFilter, HRESULT* phr)
00319 : CTransformOutputPin(NAME("WavDest output pin"), pFilter, phr, L"Out")
00320 {
00321 }
00322
00323 STDMETHODIMP CWavDestOutputPin::EnumMediaTypes(IEnumMediaTypes** ppEnum)
00324 {
00325 return CBaseOutputPin::EnumMediaTypes(ppEnum);
00326 }
00327
00328 HRESULT CWavDestOutputPin::CheckMediaType(const CMediaType* pmt)
00329 {
00330 if(pmt->majortype == MEDIATYPE_Stream && pmt->subtype == MEDIASUBTYPE_WAVE)
00331 return S_OK;
00332 else
00333 return S_FALSE;
00334 }