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:
- Starting, stopping, and pausing media playback or recording.
- Managing the topology of the media pipeline.
- Coordinating the execution of pipeline components.
- Handling playback control commands and events.
- Managing the presentation clock for synchronized playback.
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:
- Creating an
IMFPresentationDescriptorfor the source. - Creating an
IMFTopologyobject. - Adding
IMFTopologyNodes to the topology for sources, transforms, and sinks. - Linking these nodes together.
- Calling
IMFMediaSession::SetTopologyto load the topology.
Controlling Playback
Once a topology is loaded, you can control playback using methods like:
IMFMediaSession::StartIMFMediaSession::PauseIMFMediaSession::StopIMFMediaSession::Seek
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();
}