步骤 2:创建 CPlayer 对象

本主题是教程 如何使用 Media Foundation 播放媒体文件的步骤 2。 完整的代码显示在主题 媒体会话播放示例中。

若要创建 类的 CPlayer 实例,应用程序会调用静态 CPlayer::CreateInstance 方法。 此方法采用以下参数:

  • hVideo 指定显示视频的窗口。
  • hEvent 指定接收事件的窗口。 为两个窗口句柄传递相同的句柄是有效的。
  • ppPlayer 接收指向新 CPlayer 实例的指针。

下面的代码演示了 CreateInstance 方法:

//  Static class method to create the CPlayer object.

HRESULT CPlayer::CreateInstance(
    HWND hVideo,                  // Video window.
    HWND hEvent,                  // Window to receive notifications.
    CPlayer **ppPlayer)           // Receives a pointer to the CPlayer object.
{
    if (ppPlayer == NULL)
    {
        return E_POINTER;
    }

    CPlayer *pPlayer = new (std::nothrow) CPlayer(hVideo, hEvent);
    if (pPlayer == NULL)
    {
        return E_OUTOFMEMORY;
    }

    HRESULT hr = pPlayer->Initialize();
    if (SUCCEEDED(hr))
    {
        *ppPlayer = pPlayer;
    }
    else
    {
        pPlayer->Release();
    }
    return hr;
}

HRESULT CPlayer::Initialize()
{
    // Start up Media Foundation platform.
    HRESULT hr = MFStartup(MF_VERSION);
    if (SUCCEEDED(hr))
    {
        m_hCloseEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
        if (m_hCloseEvent == NULL)
        {
            hr = HRESULT_FROM_WIN32(GetLastError());
        }
    }
    return hr;
}

以下代码演示构造 CPlayer 函数:

CPlayer::CPlayer(HWND hVideo, HWND hEvent) : 
    m_pSession(NULL),
    m_pSource(NULL),
    m_pVideoDisplay(NULL),
    m_hwndVideo(hVideo),
    m_hwndEvent(hEvent),
    m_state(Closed),
    m_hCloseEvent(NULL),
    m_nRefCount(1)
{
}

构造函数执行以下操作:

  1. 调用 MFStartup 以初始化 Media Foundation 平台。
  2. 创建自动重置事件。 关闭媒体会话时使用此事件;请参阅 步骤 7:关闭媒体会话

析构函数关闭媒体会话,如 步骤 7:关闭媒体会话中所述。

CPlayer::~CPlayer()
{
    assert(m_pSession == NULL);  
    // If FALSE, the app did not call Shutdown().

    // When CPlayer calls IMediaEventGenerator::BeginGetEvent on the
    // media session, it causes the media session to hold a reference 
    // count on the CPlayer. 
    
    // This creates a circular reference count between CPlayer and the 
    // media session. Calling Shutdown breaks the circular reference 
    // count.

    // If CreateInstance fails, the application will not call 
    // Shutdown. To handle that case, call Shutdown in the destructor. 

    Shutdown();
}

请注意,构造函数和析构函数都是受保护的类方法。 应用程序使用静态 CreateInstance 方法创建 对象。 它通过调用 IUnknown::Release 来销毁对象,而不是显式使用 delete

下一 步:步骤 3:打开媒体文件

音频/视频播放

如何使用 Media Foundation 播放媒体文件