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

253 lines
6.1 KiB
C++

//////////////////////////////////////////////////////////////////////////
//
// MPEG1ByteStreamHandler.cpp
// Implements the byte-stream handler for the MPEG1 source.
//
// 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 "MPEG1Source.h"
#include "MPEG1ByteStreamHandler.h"
//-------------------------------------------------------------------
// MPEG1ByteStreamHandler class
//-------------------------------------------------------------------
//-------------------------------------------------------------------
// CreateInstance
// Static method to create an instance of the oject.
//
// This method is used by the class factory.
//
// pUnkOuter: Aggregating IUnknown.
//
//-------------------------------------------------------------------
HRESULT MPEG1ByteStreamHandler::CreateInstance(IUnknown *pUnkOuter, REFIID iid, void **ppv)
{
if (ppv == NULL)
{
return E_POINTER;
}
// This object does not support aggregation.
if (pUnkOuter != NULL)
{
return CLASS_E_NOAGGREGATION;
}
HRESULT hr = S_OK;
MPEG1ByteStreamHandler *pHandler = new MPEG1ByteStreamHandler(hr);
if (pHandler == NULL)
{
return E_OUTOFMEMORY;
}
if (SUCCEEDED(hr))
{
hr = pHandler->QueryInterface(iid, ppv);
}
SAFE_RELEASE(pHandler);
return hr;
}
//-------------------------------------------------------------------
// Constructor
//-------------------------------------------------------------------
MPEG1ByteStreamHandler::MPEG1ByteStreamHandler(HRESULT& hr)
: m_pSource(NULL), m_pResult(NULL)
{
}
//-------------------------------------------------------------------
// Destructor
//-------------------------------------------------------------------
MPEG1ByteStreamHandler::~MPEG1ByteStreamHandler()
{
SAFE_RELEASE(m_pSource);
SAFE_RELEASE(m_pResult);
}
//-------------------------------------------------------------------
// IUnknown methods
//-------------------------------------------------------------------
ULONG MPEG1ByteStreamHandler::AddRef()
{
return RefCountedObject::AddRef();
}
ULONG MPEG1ByteStreamHandler::Release()
{
return RefCountedObject::Release();
}
HRESULT MPEG1ByteStreamHandler::QueryInterface(REFIID riid, void** ppv)
{
static const QITAB qit[] =
{
QITABENT(MPEG1ByteStreamHandler, IMFByteStreamHandler),
QITABENT(MPEG1ByteStreamHandler, IMFAsyncCallback),
{ 0 }
};
return QISearch(this, qit, riid, ppv);
}
//-------------------------------------------------------------------
// IMFByteStreamHandler methods
//-------------------------------------------------------------------
//-------------------------------------------------------------------
// BeginCreateObject
// Starts creating the media source.
//-------------------------------------------------------------------
HRESULT MPEG1ByteStreamHandler::BeginCreateObject(
/* [in] */ IMFByteStream *pByteStream,
/* [in] */ LPCWSTR pwszURL,
/* [in] */ DWORD dwFlags,
/* [in] */ IPropertyStore *pProps,
/* [out] */ IUnknown **ppIUnknownCancelCookie, // Can be NULL
/* [in] */ IMFAsyncCallback *pCallback,
/* [in] */ IUnknown *punkState // Can be NULL
)
{
if (pByteStream == NULL)
{
return E_POINTER;
}
if (pCallback == NULL)
{
return E_POINTER;
}
if ((dwFlags & MF_RESOLUTION_MEDIASOURCE) == 0)
{
return E_INVALIDARG;
}
HRESULT hr = S_OK;
IMFAsyncResult *pResult = NULL;
MPEG1Source *pSource = NULL;
// Create an instance of the media source.
CHECK_HR(hr = MPEG1Source::CreateInstance(&pSource));
// Create a result object for the caller's async callback.
CHECK_HR(hr = MFCreateAsyncResult(NULL, pCallback, punkState, &pResult));
// Start opening the source. This is an async operation.
// When it completes, the source will invoke our callback
// and then we will invoke the caller's callback.
CHECK_HR(hr = pSource->BeginOpen(pByteStream, this, NULL));
if (ppIUnknownCancelCookie)
{
*ppIUnknownCancelCookie = NULL;
}
m_pSource = pSource;
m_pSource->AddRef();
m_pResult = pResult;
m_pResult->AddRef();
done:
SAFE_RELEASE(pSource);
SAFE_RELEASE(pResult);
return hr;
}
//-------------------------------------------------------------------
// EndCreateObject
// Completes the BeginCreateObject operation.
//-------------------------------------------------------------------
HRESULT MPEG1ByteStreamHandler::EndCreateObject(
/* [in] */ IMFAsyncResult *pResult,
/* [out] */ MF_OBJECT_TYPE *pObjectType,
/* [out] */ IUnknown **ppObject)
{
if (pResult == NULL || pObjectType == NULL || ppObject == NULL)
{
return E_POINTER;
}
HRESULT hr = S_OK;
*pObjectType = MF_OBJECT_INVALID;
*ppObject = NULL;
CHECK_HR(hr = pResult->GetStatus());
*pObjectType = MF_OBJECT_MEDIASOURCE;
assert(m_pSource != NULL);
hr = m_pSource->QueryInterface(IID_PPV_ARGS(ppObject));
done:
SAFE_RELEASE(m_pSource);
SAFE_RELEASE(m_pResult);
return hr;
}
HRESULT MPEG1ByteStreamHandler::CancelObjectCreation(IUnknown *pIUnknownCancelCookie)
{
return E_NOTIMPL;
}
HRESULT MPEG1ByteStreamHandler::GetMaxNumberOfBytesRequiredForResolution(QWORD* pqwBytes)
{
return E_NOTIMPL;
}
//-------------------------------------------------------------------
// Invoke
// Callback for the media source's BeginOpen method.
//-------------------------------------------------------------------
HRESULT MPEG1ByteStreamHandler::Invoke(IMFAsyncResult* pResult)
{
HRESULT hr = S_OK;
if (m_pSource)
{
hr = m_pSource->EndOpen(pResult);
}
else
{
hr = E_UNEXPECTED;
}
m_pResult->SetStatus(hr);
hr = MFInvokeCallback(m_pResult);
return hr;
}