windows-nt/Source/XPSP1/NT/multimedia/dshow/streams/ddstream/austrm.h
2020-09-26 16:20:57 +08:00

344 lines
8.5 KiB
C++

// Copyright (c) 1997 - 1998 Microsoft Corporation. All Rights Reserved.
// austrm.h : Declaration of the CAudioStream
/*
Basic design
------------
For simplification purposes we will always provide our own
allocator buffer and copy into the application's buffer. This
will fix 2 problems:
1. Confusion caused by the filter no filling the allocator's
buffers.
2. Problems when the application doesn't supply a big enough buffer.
NOTES
-----
Continuous update might be a bit dumb to use for audio
*/
#ifndef __AUSTREAM_H_
#define __AUSTREAM_H_
/////////////////////////////////////////////////////////////////////////////
// CAudioStream
class ATL_NO_VTABLE CAudioStream :
public CComCoClass<CAudioStream, &CLSID_AMAudioStream>,
public CByteStream,
public IAudioMediaStream
{
public:
//
// METHODS
//
CAudioStream();
//
// IMediaStream
//
//
// IMediaStream
//
// HACK HACK - the first 2 are duplicates but it won't link
// without
STDMETHODIMP GetMultiMediaStream(
/* [out] */ IMultiMediaStream **ppMultiMediaStream)
{
return CStream::GetMultiMediaStream(ppMultiMediaStream);
}
STDMETHODIMP GetInformation(
/* [optional][out] */ MSPID *pPurposeId,
/* [optional][out] */ STREAM_TYPE *pType)
{
return CStream::GetInformation(pPurposeId, pType);
}
STDMETHODIMP SetState(
/* [in] */ FILTER_STATE State
)
{
return CByteStream::SetState(State);
}
STDMETHODIMP SetSameFormat(IMediaStream *pStream, DWORD dwFlags);
STDMETHODIMP AllocateSample(
/* [in] */ DWORD dwFlags,
/* [out] */ IStreamSample **ppSample
);
STDMETHODIMP CreateSharedSample(
/* [in] */ IStreamSample *pExistingSample,
/* [in] */ DWORD dwFlags,
/* [out] */ IStreamSample **ppNewSample
);
STDMETHODIMP SendEndOfStream(DWORD dwFlags)
{
return CStream::SendEndOfStream(dwFlags);
}
//
// IPin
//
STDMETHODIMP ReceiveConnection(IPin * pConnector, const AM_MEDIA_TYPE *pmt);
//
// IMemAllocator
//
STDMETHODIMP SetProperties(ALLOCATOR_PROPERTIES* pRequest, ALLOCATOR_PROPERTIES* pActual);
STDMETHODIMP GetProperties(ALLOCATOR_PROPERTIES* pProps);
//
// IAudioMediaStream
//
STDMETHODIMP GetFormat(
/* [optional][out] */ LPWAVEFORMATEX lpWaveFormatCurrent
);
STDMETHODIMP SetFormat(
/* [in] */ const WAVEFORMATEX *lpWaveFormat
);
STDMETHODIMP CreateSample(
/* [in] */ IAudioData *pAudioData,
/* [in] */ DWORD dwFlags,
/* [out] */ IAudioStreamSample **ppSample
);
//
// Special CStream methods
//
HRESULT GetMediaType(ULONG Index, AM_MEDIA_TYPE **ppMediaType);
LONG GetChopSize()
{
#ifdef MY_CHOP_SIZE
if (m_Direction == PINDIR_OUTPUT) {
return MY_CHOP_SIZE;
}
#endif
return 65536;
}
DECLARE_REGISTRY_RESOURCEID(IDR_AUDIOSTREAM)
protected:
HRESULT InternalSetFormat(const WAVEFORMATEX *pFormat, bool bFromPin);
HRESULT CheckFormat(const WAVEFORMATEX *pFormat, bool bForce=false);
BEGIN_COM_MAP(CAudioStream)
COM_INTERFACE_ENTRY(IAudioMediaStream)
COM_INTERFACE_ENTRY_CHAIN(CStream)
END_COM_MAP()
protected:
/* Format */
WAVEFORMATEX m_Format;
bool m_fForceFormat;
};
/////////////////////////////////////////////////////////////////////////////
// CAudioStreamSample
class ATL_NO_VTABLE CAudioStreamSample :
public CByteStreamSample,
public IAudioStreamSample
{
public:
CAudioStreamSample() {}
// DELEGATE TO BASE CLASS
//
// IStreamSample
//
STDMETHODIMP GetMediaStream(
/* [in] */ IMediaStream **ppMediaStream)
{
return CSample::GetMediaStream(ppMediaStream);
}
STDMETHODIMP GetSampleTimes(
/* [optional][out] */ STREAM_TIME *pStartTime,
/* [optional][out] */ STREAM_TIME *pEndTime,
/* [optional][out] */ STREAM_TIME *pCurrentTime)
{
return CSample::GetSampleTimes(
pStartTime,
pEndTime,
pCurrentTime
);
}
STDMETHODIMP SetSampleTimes(
/* [optional][in] */ const STREAM_TIME *pStartTime,
/* [optional][in] */ const STREAM_TIME *pEndTime)
{
return CSample::SetSampleTimes(pStartTime, pEndTime);
}
STDMETHODIMP Update(
/* [in] */ DWORD dwFlags,
/* [optional][in] */ HANDLE hEvent,
/* [optional][in] */ PAPCFUNC pfnAPC,
/* [optional][in] */ DWORD_PTR dwAPCData)
{
return CByteStreamSample::Update(dwFlags, hEvent, pfnAPC, dwAPCData);
}
STDMETHODIMP CompletionStatus(
/* [in] */ DWORD dwFlags,
/* [optional][in] */ DWORD dwMilliseconds)
{
return CSample::CompletionStatus(dwFlags, dwMilliseconds);
}
BEGIN_COM_MAP(CAudioStreamSample)
COM_INTERFACE_ENTRY(IAudioStreamSample)
COM_INTERFACE_ENTRY_CHAIN(CSample)
END_COM_MAP()
// IAudioStreamSample
STDMETHODIMP GetAudioData(IAudioData **ppAudioData)
{
return m_pMemData->QueryInterface(IID_IAudioData, (void **)ppAudioData);
}
// Set the pointer
HRESULT SetSizeAndPointer(BYTE *pbData, LONG lActual, LONG lSize)
{
m_pbData = pbData;
m_cbSize = (DWORD)lSize;
m_cbData = (DWORD)lActual;
return S_OK;
}
};
// Audio data object
class ATL_NO_VTABLE CAudioData :
public CComObjectRootEx<CComMultiThreadModel>,
public IAudioData,
public CComCoClass<CAudioData, &CLSID_AMAudioData>
{
public:
CAudioData();
~CAudioData();
DECLARE_REGISTRY_RESOURCEID(IDR_AUDIODATA)
BEGIN_COM_MAP(CAudioData)
COM_INTERFACE_ENTRY(IAudioData)
END_COM_MAP()
//
// IMemoryData
//
STDMETHODIMP SetBuffer(
/* [in] */ DWORD cbSize,
/* [in] */ BYTE * pbData,
/* [in] */ DWORD dwFlags
)
{
if (dwFlags != 0 || cbSize == 0) {
return E_INVALIDARG;
}
//
// Free anything we allocated ourselves -- We allow multiple calls to this method
//
if (m_bWeAllocatedData) {
CoTaskMemFree(m_pbData);
m_bWeAllocatedData = false;
}
m_cbSize = cbSize;
if (pbData) {
m_pbData = pbData;
return S_OK;
} else {
m_pbData = (BYTE *)CoTaskMemAlloc(cbSize);
if (m_pbData) {
m_bWeAllocatedData = true;
return S_OK;
}
return E_OUTOFMEMORY;
}
}
STDMETHODIMP GetInfo(
/* [out] */ DWORD *pdwLength,
/* [out] */ BYTE **ppbData,
/* [out] */ DWORD *pcbActualData
)
{
if (m_cbSize == 0) {
return MS_E_NOTINIT;
}
if (pdwLength) {
*pdwLength = m_cbSize;
}
if (ppbData) {
*ppbData = m_pbData;
}
if (pcbActualData) {
*pcbActualData = m_cbData;
}
return S_OK;
}
STDMETHODIMP SetActual(
/* [in] */ DWORD cbDataValid
)
{
if (cbDataValid > m_cbSize) {
return E_INVALIDARG;
}
m_cbData = cbDataValid;
return S_OK;
}
//
// IAudioData
//
STDMETHODIMP GetFormat(
/* [out] [optional] */ WAVEFORMATEX *pWaveFormatCurrent
)
{
if (pWaveFormatCurrent == NULL) {
return E_POINTER;
}
*pWaveFormatCurrent = m_Format;
return S_OK;
}
STDMETHODIMP SetFormat(
/* [in] */ const WAVEFORMATEX *lpWaveFormat
)
{
if (lpWaveFormat == NULL) {
return E_POINTER;
}
if (lpWaveFormat->wFormatTag != WAVE_FORMAT_PCM) {
return E_INVALIDARG;
}
m_Format = *lpWaveFormat;
return S_OK;
}
protected:
PBYTE m_pbData;
DWORD m_cbSize;
DWORD m_cbData;
WAVEFORMATEX m_Format;
bool m_bWeAllocatedData;
};
#endif // __AUSTREAM_H_