解锁 Windows Media 格式 SDK
[与此页面关联的功能 DirectShow 是一项旧功能。 它已被 MediaPlayer、 IMFMediaEngine 和 媒体基金会中的音频/视频捕获取代。 这些功能已针对Windows 10和Windows 11进行了优化。 Microsoft 强烈建议新代码尽可能使用 MediaPlayer、 IMFMediaEngine 和 Media Foundation 中的音频/视频捕获 ,而不是 DirectShow。 如果可能,Microsoft 建议重写使用旧 API 的现有代码以使用新 API。]
若要访问 Windows Media Format SDK 版本 7 或 7.1,应用程序必须在运行时提供软件证书(也称为密钥)。 此密钥包含在名为 wmstub.lib 的静态库中,应用程序在生成时链接到该库。 仅创建或读取受 DRM 保护的文件时,才需要单个密钥。 可以使用 Windows Media 格式 SDK 提供的静态库创建非 DRM 文件。 有关获取 DRM 密钥的详细信息,请参阅 Windows Media Format SDK。 DirectShow 应用程序在添加到筛选器图时向 WM ASF 编写器提供其证书。 应用程序必须使用 COM IServiceProvider 和 IObjectWithSite 接口注册为密钥提供程序。 使用此技术,应用程序实现派生自 IServiceProvider 的密钥提供程序类。 此类实现三个标准 COM 方法(AddRef、 QueryInterface 和 Release),以及筛选器图管理器调用的一个附加方法 QueryService。 QueryService 调用 Windows Media Format SDK 方法 WMCreateCertificate ,并将指向已创建的证书的指针返回到筛选器图管理器。 如果证书有效,筛选器关系图管理器允许图形生成过程继续进行。
注意
若要生成应用程序,请包含 WMCreateCertificate 原型的 Wmsdkidl.h,并链接到 Wmstub.lib 库。
以下代码示例演示了此过程的基本步骤:
// Declare and implement a key provider class derived from IServiceProvider.
class CKeyProvider : public IServiceProvider {
public:
// IUnknown interface
STDMETHODIMP QueryInterface(REFIID riid, void ** ppv);
STDMETHODIMP_(ULONG) AddRef();
STDMETHODIMP_(ULONG) Release();
CKeyProvider();
// IServiceProvider
STDMETHODIMP QueryService(REFIID siid, REFIID riid, void **ppv);
private:
ULONG m_cRef;
};
CKeyProvider::CKeyProvider() : m_cRef(0)
{
}
// IUnknown methods
ULONG CKeyProvider::AddRef()
{
return InterlockedIncrement(&m_cRef);
}
ULONG CKeyProvider::Release()
{
ASSERT(m_cRef > 0);
ULONG lCount = InterlockedDecrement(&m_cRef);
if (m_cRef == 0)
{
delete this;
return (ULONG)0;
}
return (ULONG)lCount;
}
// We only support IUnknown and IServiceProvider.
HRESULT CKeyProvider::QueryInterface(REFIID riid, void ** ppv)
{
if (!ppv) return E_POINTER;
if (riid == IID_IUnknown)
{
*ppv = (void *) static_cast<IUnknown *>(this);
AddRef();
return S_OK;
}
if (riid == IID_IServiceProvider)
{
*ppv = (void *) static_cast<IServiceProvider *>(this);
AddRef();
return S_OK;
}
return E_NOINTERFACE;
}
STDMETHODIMP CKeyProvider::QueryService(REFIID siid, REFIID riid, void **ppv)
{
if (!ppv) return E_POINTER;
if (siid == __uuidof(IWMReader) && riid == IID_IUnknown)
{
IUnknown *punkCert;
HRESULT hr = WMCreateCertificate(&punkCert);
if (SUCCEEDED(hr))
{
*ppv = (void *) punkCert;
}
return hr;
}
return E_NOINTERFACE;
}
////////////////////////////////////////////////////////////////////
//
// These examples illustrate the sequence of method calls
// in your application. Error checking is omitted for brevity.
//
///////////////////////////////////////////////////////////////////
// Create the filter graph manager, but don't add any filters.
IGraphBuilder *pGraph;
hr = CreateFilterGraph(&pGraph);
...
// Instantiate the key provider class, and AddRef it
// so that COM doesn't try to free our static object.
CKeyProvider prov;
prov.AddRef(); // Don't let COM try to free our static object.
// Give the graph an IObjectWithSite pointer for callbacks and QueryService.
IObjectWithSite* pObjectWithSite = NULL;
hr = pGraph->QueryInterface(IID_IObjectWithSite, (void**)&pObjectWithSite);
if (SUCCEEDED(hr))
{
// Use the IObjectWithSite pointer to specify our key provider object.
// The filter graph manager will use this pointer to call
// QueryService to do the unlocking.
// If the unlocking succeeds, then we can build our graph.
pObjectWithSite->SetSite((IUnknown *) (IServiceProvider *) &prov);
pObjectWithSite->Release();
}
// Now build the graph.
相关主题