Media Foundation Media Session

The Media Session object is the core of the Media Foundation pipeline. It manages the flow of media data from sources, through transform objects, and to sinks. It orchestrates the playback, recording, and processing of media.

Overview

The Media Session object is responsible for:

Key Concepts

Topology

A topology defines the structure of the media pipeline. It is a directed graph consisting of nodes representing sources, transforms, and sinks. The Media Session resolves and builds this topology before media can flow.

Presentation Clock

The presentation clock is crucial for synchronized playback. It provides a time reference for all components in the pipeline, ensuring that audio and video are displayed and played back in the correct order and timing.

Events

The Media Session communicates status updates and errors through a system of events. Applications typically register a callback to receive and handle these events.

Core Interfaces

The primary interface for interacting with the Media Session is IMediaSession. However, several other related interfaces are essential for managing and configuring the pipeline:

Interface Description
IMediaSession The main interface for controlling the Media Session, including starting, stopping, and managing playback.
IMFMediaSource Represents a source of media data (e.g., a file, a network stream, a camera).
IMFMediaSink Represents a sink for media data (e.g., a renderer, a file writer).
IMFTransform Represents a Media Foundation transform (MFT), such as a decoder, encoder, or effect.
IMFPresentationClock The interface for the presentation clock.
IMFMediaEventGenerator An interface implemented by objects that generate media events, including the Media Session.

Creating a Media Session

A Media Session is typically created using the MFCreateMediaSession function:


#include <mfobjects.h>
#include <mfidl.h>
#include <mfapi.h>

// ... Initialize Media Foundation
MFStartup(MF_VERSION);

IMFMediaSession* pSession = nullptr;
HRESULT hr = MFCreateMediaSession(
    nullptr, // Pointer to an IMFClock (nullptr for default clock)
    nullptr, // Pointer to an IMF energética (can be nullptr)
    nullptr, // Pointer to an IMFMediaEventCallback (can be nullptr if using synchronous calls)
    &pSession
);

if (SUCCEEDED(hr)) {
    // Media Session created successfully.
    // Now you can build a topology and add it to the session.
}
            

Building and Loading a Topology

Before playback can occur, a topology must be created and loaded into the Media Session. This involves:

  1. Creating an IMFPresentationDescriptor for the source.
  2. Creating an IMFTopology object.
  3. Adding IMFTopologyNodes to the topology for sources, transforms, and sinks.
  4. Linking these nodes together.
  5. Calling IMFMediaSession::SetTopology to load the topology.

Controlling Playback

Once a topology is loaded, you can control playback using methods like:

Handling Events

To receive asynchronous notifications from the Media Session, you must implement the IMFMediaEventCallback interface and register it with the session.


class CMediaSessionEvents : public IMFMediaEventCallback
{
public:
    // ... IUnknown implementation ...

    // IMFMediaEventCallback methods
    virtual HRESULT STDMETHODCALLTYPE Invoke(
        IMFMediaEvent* pEvent)
    {
        MediaEventType met;
        HRESULT hrStatus = S_OK;

        if (SUCCEEDED(pEvent->GetType(&met)) &&
            SUCCEEDED(pEvent->GetStatus(&hrStatus)))
        {
            if (SUCCEEDED(hrStatus))
            {
                switch (met)
                {
                    case MESessionStarted:
                        // Session started
                        break;
                    case MESessionPaused:
                        // Session paused
                        break;
                    case MESessionStopped:
                        // Session stopped
                        break;
                    case MEEndOfPresentation:
                        // End of media reached
                        break;
                    // ... other event types
                }
            }
            else
            {
                // Handle error hrStatus
            }
        }
        return S_OK;
    }
};

// ... After creating pSession ...
CMediaSessionEvents* pCallback = new CMediaSessionEvents();
IMFMediaEventGenerator* pEventGen = nullptr;
if (SUCCEEDED(pSession->QueryInterface(IID_PPV_ARGS(&pEventGen)))) {
    pSession->RegisterForEvent(MEAllEvents, pCallback); // Register for all events
    pEventGen->Release();
}
            
Note: Proper error handling and reference counting are crucial when working with Media Foundation objects.
Important: The Media Session manages the lifecycle of pipeline components. Ensure you release objects correctly after they are no longer needed.

Related Topics