wavdest.cpp
上传用户:xjjlds
上传日期:2015-12-05
资源大小:22823k
文件大小:9k
- /*
- * Copyright (C) 2003-2005 Gabest
- * http://www.gabest.org
- *
- * This Program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This Program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- */
- #include "stdafx.h"
- #include <streams.h>
- #include <aviriff.h>
- #include "wavdest.h"
- #include "......DSUtilDSUtil.h"
- #ifdef REGISTER_FILTER
- const AMOVIESETUP_MEDIATYPE sudPinTypesIn[] =
- {
- {&MEDIATYPE_Audio, &MEDIASUBTYPE_WAVE},
- };
- const AMOVIESETUP_MEDIATYPE sudPinTypesOut[] =
- {
- {&MEDIATYPE_Stream, &MEDIASUBTYPE_WAVE},
- };
- const AMOVIESETUP_PIN sudpPins[] =
- {
- {L"Input", FALSE, FALSE, FALSE, FALSE, &CLSID_NULL, NULL, countof(sudPinTypesIn), sudPinTypesIn},
- {L"Output", FALSE, TRUE, FALSE, FALSE, &CLSID_NULL, NULL, countof(sudPinTypesOut), sudPinTypesOut}
- };
- const AMOVIESETUP_FILTER sudFilter[] =
- {
- {&__uuidof(CWavDestFilter), L"WavDest", MERIT_DO_NOT_USE, countof(sudpPins), sudpPins}
- };
- CFactoryTemplate g_Templates[] =
- {
- {L"WavDest", &__uuidof(CWavDestFilter), CreateInstance<CWavDestFilter>, NULL, &sudFilter[0]}
- };
- int g_cTemplates = countof(g_Templates);
- STDAPI DllRegisterServer()
- {
- return AMovieDllRegisterServer2(TRUE);
- }
- STDAPI DllUnregisterServer()
- {
- return AMovieDllRegisterServer2(FALSE);
- }
- extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);
- BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
- {
- return DllEntryPoint((HINSTANCE)hModule, dwReason, 0); // "DllMain" of the dshow baseclasses;
- }
- #endif
- //
- // CWavDestFilter
- //
- CWavDestFilter::CWavDestFilter(LPUNKNOWN pUnk, HRESULT* phr)
- : CTransformFilter(NAME("WavDest filter"), pUnk, __uuidof(this))
- {
- if(SUCCEEDED(*phr))
- {
- if(CWavDestOutputPin* pOut = new CWavDestOutputPin(this, phr))
- {
- if(SUCCEEDED(*phr)) m_pOutput = pOut;
- else delete pOut;
- }
- else
- {
- *phr = E_OUTOFMEMORY;
- return;
- }
- if(CTransformInputPin* pIn = new CTransformInputPin(NAME("Transform input pin"), this, phr, L"In"))
- {
- if(SUCCEEDED(*phr)) m_pInput = pIn;
- else delete pIn;
- }
- else
- {
- *phr = E_OUTOFMEMORY;
- return;
- }
- }
- }
- CWavDestFilter::~CWavDestFilter()
- {
- }
- HRESULT CWavDestFilter::CheckTransform(const CMediaType* mtIn, const CMediaType* mtOut)
- {
- return CheckInputType(mtIn);
- }
- HRESULT CWavDestFilter::Receive(IMediaSample* pSample)
- {
- ULONG cbOld = m_cbWavData;
- HRESULT hr = CTransformFilter::Receive(pSample);
- // don't update the count if Deliver() downstream fails.
- if(hr != S_OK)
- m_cbWavData = cbOld;
- return hr;
- }
- HRESULT CWavDestFilter::Transform(IMediaSample* pIn, IMediaSample* pOut)
- {
- REFERENCE_TIME rtStart, rtEnd;
-
- HRESULT hr = Copy(pIn, pOut);
- if(FAILED(hr))
- return hr;
- // Prepare it for writing
- LONG lActual = pOut->GetActualDataLength();
- if(m_cbWavData + m_cbHeader + lActual < m_cbWavData + m_cbHeader ) // overflow
- return E_FAIL;
- rtStart = m_cbWavData + m_cbHeader;
- rtEnd = rtStart + lActual;
- m_cbWavData += lActual;
- EXECUTE_ASSERT(pOut->SetTime(&rtStart, &rtEnd) == S_OK);
-
- return S_OK;
- }
- HRESULT CWavDestFilter::Copy(IMediaSample* pSource, IMediaSample* pDest) const
- {
- BYTE* pSourceBuffer, * pDestBuffer;
- long lSourceSize = pSource->GetActualDataLength();
- #ifdef DEBUG
- long lDestSize = pDest->GetSize();
- ASSERT(lDestSize >= lSourceSize);
- #endif
-
- pSource->GetPointer(&pSourceBuffer);
- pDest->GetPointer(&pDestBuffer);
- CopyMemory((PVOID)pDestBuffer, (PVOID)pSourceBuffer, lSourceSize);
- // Copy the sample times
- REFERENCE_TIME TimeStart, TimeEnd;
- if(NOERROR == pSource->GetTime(&TimeStart, &TimeEnd))
- pDest->SetTime(&TimeStart, &TimeEnd);
- LONGLONG MediaStart, MediaEnd;
- if(pSource->GetMediaTime(&MediaStart, &MediaEnd) == NOERROR)
- pDest->SetMediaTime(&MediaStart, &MediaEnd);
- // Copy the media type
- AM_MEDIA_TYPE* pMediaType;
- pSource->GetMediaType(&pMediaType);
- pDest->SetMediaType(pMediaType);
- DeleteMediaType(pMediaType);
- // Copy the actual data length
- long lDataLength = pSource->GetActualDataLength();
- pDest->SetActualDataLength(lDataLength);
- return NOERROR;
- }
- HRESULT CWavDestFilter::CheckInputType(const CMediaType* mtIn)
- {
- return mtIn->formattype == FORMAT_WaveFormatEx ? S_OK : S_FALSE;
- }
- HRESULT CWavDestFilter::GetMediaType(int iPosition, CMediaType* pMediaType)
- {
- ASSERT(iPosition == 0 || iPosition == 1);
- if(iPosition == 0)
- {
- pMediaType->SetType(&MEDIATYPE_Stream);
- pMediaType->SetSubtype(&MEDIASUBTYPE_WAVE);
- return S_OK;
- }
- return VFW_S_NO_MORE_ITEMS;
- }
- HRESULT CWavDestFilter::DecideBufferSize(IMemAllocator* pAlloc, ALLOCATOR_PROPERTIES* pProperties)
- {
- if(m_pInput->IsConnected() == FALSE)
- return E_UNEXPECTED;
- ASSERT(pAlloc);
- ASSERT(pProperties);
- HRESULT hr = NOERROR;
- pProperties->cBuffers = 1;
- pProperties->cbAlign = 1;
-
- CComPtr<IMemAllocator> pInAlloc;
- ALLOCATOR_PROPERTIES InProps;
- if(SUCCEEDED(hr = m_pInput->GetAllocator(&pInAlloc))
- && SUCCEEDED(hr = pInAlloc->GetProperties(&InProps)))
- {
- pProperties->cbBuffer = InProps.cbBuffer;
- }
- else
- {
- return hr;
- }
- ASSERT(pProperties->cbBuffer);
- ALLOCATOR_PROPERTIES Actual;
- if(FAILED(hr = pAlloc->SetProperties(pProperties,&Actual)))
- return hr;
- ASSERT(Actual.cBuffers == 1);
- if(pProperties->cBuffers > Actual.cBuffers
- || pProperties->cbBuffer > Actual.cbBuffer)
- {
- return E_FAIL;
- }
- return NOERROR;
- }
- // Compute the header size to allow space for us to write it at the end.
- //
- // 00000000 RIFF (00568BFE) 'WAVE'
- // 0000000C fmt (00000010)
- // 00000024 data (00568700)
- // 0056872C
- //
- HRESULT CWavDestFilter::StartStreaming()
- {
- // leave space for the header
- m_cbHeader = sizeof(RIFFLIST) +
- sizeof(RIFFCHUNK) +
- m_pInput->CurrentMediaType().FormatLength() +
- sizeof(RIFFCHUNK);
-
- m_cbWavData = 0;
- return S_OK;
- }
- HRESULT CWavDestFilter::StopStreaming()
- {
- IStream* pStream;
- if (m_pOutput->IsConnected() == FALSE)
- return E_FAIL;
- IPin* pDwnstrmInputPin = m_pOutput->GetConnected();
- if (!pDwnstrmInputPin)
- return E_FAIL;
- HRESULT hr = ((IMemInputPin *) pDwnstrmInputPin)->QueryInterface(IID_IStream, (void **)&pStream);
- if(SUCCEEDED(hr))
- {
- BYTE *pb = (BYTE *)_alloca(m_cbHeader);
- RIFFLIST *pRiffWave = (RIFFLIST *)pb;
- RIFFCHUNK *pRiffFmt = (RIFFCHUNK *)(pRiffWave + 1);
- RIFFCHUNK *pRiffData = (RIFFCHUNK *)(((BYTE *)(pRiffFmt + 1)) + m_pInput->CurrentMediaType().FormatLength());;
- pRiffData->fcc = FCC('data');
- pRiffData->cb = m_cbWavData;
- pRiffFmt->fcc = FCC('fmt ');
- pRiffFmt->cb = m_pInput->CurrentMediaType().FormatLength();
- CopyMemory(pRiffFmt + 1, m_pInput->CurrentMediaType().Format(), pRiffFmt->cb);
- pRiffWave->fcc = FCC('RIFF');
- pRiffWave->cb = m_cbWavData + m_cbHeader - sizeof(RIFFCHUNK);
- pRiffWave->fccListType = FCC('WAVE');
- LARGE_INTEGER li;
- ZeroMemory(&li, sizeof(li));
-
- hr = pStream->Seek(li, STREAM_SEEK_SET, 0);
- if(SUCCEEDED(hr)) {
- hr = pStream->Write(pb, m_cbHeader, 0);
- }
- pStream->Release();
- }
- return hr;
- }
- CWavDestOutputPin::CWavDestOutputPin(CTransformFilter* pFilter, HRESULT* phr)
- : CTransformOutputPin(NAME("WavDest output pin"), pFilter, phr, L"Out")
- {
- }
- STDMETHODIMP CWavDestOutputPin::EnumMediaTypes(IEnumMediaTypes** ppEnum)
- {
- return CBaseOutputPin::EnumMediaTypes(ppEnum);
- }
- HRESULT CWavDestOutputPin::CheckMediaType(const CMediaType* pmt)
- {
- if(pmt->majortype == MEDIATYPE_Stream && pmt->subtype == MEDIASUBTYPE_WAVE)
- return S_OK;
- else
- return S_FALSE;
- }