2025-11-28 00:35:46 +09:00

219 lines
5.1 KiB
C++

//////////////////////////////////////////////////////////////////////////
//
// WavByteStreamHandler.cpp: Bytestream handler for .wav files.
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//////////////////////////////////////////////////////////////////////////
#include "WavSource.h"
#include "WavByteStreamHandler.h"
HRESULT WavByteStreamHandler_CreateInstance(REFIID riid, void **ppv)
{
return CWavByteStreamHandler::CreateInstance(riid, ppv);
}
//-------------------------------------------------------------------
// Name: CreateInstance
// Description: Static method to create an instance of the object.
//
// iid: IID of the requested interface on the object.
// ppSource: Receives a ref-counted pointer to the object.
//-------------------------------------------------------------------
HRESULT CWavByteStreamHandler::CreateInstance(REFIID iid, void **ppMEG)
{
if (ppMEG == NULL)
{
return E_POINTER;
}
// Create the object.
HRESULT hr = S_OK;
CWavByteStreamHandler *pHandler = new (std::nothrow) CWavByteStreamHandler(hr);
if (pHandler == NULL)
{
return E_OUTOFMEMORY;
}
// Query for the requested interface.
if (SUCCEEDED(hr))
{
hr = pHandler->QueryInterface(iid, ppMEG);
}
if (FAILED(hr))
{
delete pHandler;
}
return hr;
}
//-------------------------------------------------------------------
// CWavByteStreamHandler constructor
//-------------------------------------------------------------------
CWavByteStreamHandler::CWavByteStreamHandler(HRESULT &hr) : m_nRefCount(0)
{
DllAddRef();
hr = S_OK;
}
//-------------------------------------------------------------------
// CWavByteStreamHandler destructor
//-------------------------------------------------------------------
CWavByteStreamHandler::~CWavByteStreamHandler()
{
assert(m_nRefCount == 0);
DllRelease();
}
// IUnknown methods
ULONG CWavByteStreamHandler::AddRef()
{
return InterlockedIncrement(&m_nRefCount);
}
ULONG CWavByteStreamHandler::Release()
{
ULONG uCount = InterlockedDecrement(&m_nRefCount);
if (uCount == 0)
{
delete this;
}
// For thread safety, return a temporary variable.
return uCount;
}
HRESULT CWavByteStreamHandler::QueryInterface(REFIID iid, void** ppv)
{
static const QITAB qit[] =
{
QITABENT(CWavByteStreamHandler, IMFByteStreamHandler),
{ 0 }
};
return QISearch(this, qit, iid, ppv);
}
// IMFByteStreamHandler methods
HRESULT CWavByteStreamHandler::BeginCreateObject(
/* [in] */ IMFByteStream *pByteStream,
/* [in] */ LPCWSTR pwszURL,
/* [in] */ DWORD /*dwFlags*/,
/* [in] */ IPropertyStore * /*pProps*/, // Can be NULL.
/* [out] */ IUnknown ** ppIUnknownCancelCookie, // Can be NULL.
/* [in] */ IMFAsyncCallback *pCallback,
/* [in] */ IUnknown *punkState // Can be NULL
)
{
if ((pByteStream == NULL) || (pwszURL == NULL) || (pCallback == NULL))
{
return E_INVALIDARG;
}
if (ppIUnknownCancelCookie)
{
*ppIUnknownCancelCookie = NULL; // We don't return a cancellation cookie.
}
IMFMediaSource *pSource = NULL;
IMFAsyncResult *pResult = NULL;
HRESULT hr = S_OK;
hr = WavSource::CreateInstance(IID_IMFMediaSource, (void**)&pSource);
if (SUCCEEDED(hr))
{
hr = ((WavSource*)pSource)->Open(pByteStream);
}
if (SUCCEEDED(hr))
{
hr = MFCreateAsyncResult(pSource, pCallback, punkState, &pResult);
}
if (SUCCEEDED(hr))
{
MFInvokeCallback(pResult);
}
SafeRelease(&pResult);
SafeRelease(&pSource);
return hr;
}
HRESULT CWavByteStreamHandler::EndCreateObject(
/* [in] */ IMFAsyncResult *pResult,
/* [out] */ MF_OBJECT_TYPE *pObjectType,
/* [out] */ IUnknown **ppObject)
{
HRESULT hr = S_OK;
if ((pResult == NULL) || (ppObject == NULL) || (ppObject == NULL))
{
return E_INVALIDARG;
}
IMFMediaSource *pSource = NULL;
IUnknown *pUnk = NULL;
hr = pResult->GetObject(&pUnk);
if (SUCCEEDED(hr))
{
// Minimal sanity check - is it really a media source?
hr = pUnk->QueryInterface(IID_PPV_ARGS(&pSource));
}
if (SUCCEEDED(hr))
{
*ppObject = pUnk;
(*ppObject)->AddRef();
*pObjectType = MF_OBJECT_MEDIASOURCE;
}
SafeRelease(&pSource);
SafeRelease(&pUnk);
return hr;
}
HRESULT CWavByteStreamHandler::CancelObjectCreation(IUnknown * /*pIUnknownCancelCookie*/)
{
return E_NOTIMPL;
}
HRESULT CWavByteStreamHandler::GetMaxNumberOfBytesRequiredForResolution(QWORD* pqwBytes)
{
if (pqwBytes == NULL)
{
return E_INVALIDARG;
}
// In a canonical PCM .wav file, the start of the 'data' chunk is at byte offset 44.
*pqwBytes = 44;
return S_OK;
}