How to implement loop playback using IMFSequenceSource as a playlist in a video player written with Media Foundation?
I called function SkipTo(0) after I received MESessionEnded media session event,the function Invoke outputed the following events in sequence: MESessionCapabilitiesChanged,MESessionStarted,MEEndOfPresentationSegment,MESessionTopologySet and MESessionTopologyStatus media session events. BUT the Window didn't display video .
Why ?How to implement loop playback?
PLEASE tell me!!!
HRESULT CPlaylist::SkipTo(DWORD index)
{
if (index >= segmentCount)
{
****return E_INVALIDARG;
}
MFSequencerElementId ID = segments[index].SegmentID;
PROPVARIANT var;
String debugStr(">>>>Segment ID is:"+IntToStr((int)ID) );
OutputDebugString(debugStr.w_str());
HRESULT hr = MFCreateSequencerSegmentOffset(ID, 0, &var);
if (SUCCEEDED(hr))
{
hr = mediaSession->Start(&MF_TIME_FORMAT_SEGMENT_OFFSET, &var);
PropVariantClear(&var);
}
return hr;
}
I expected that the vide display the window like first play.
Answers
It seems like you are using Microsoft Media Foundation (MF) to play back a playlist of segments. The SkipTo
function you provided attempts to skip to a specific segment in the playlist based on its index.
However, the fact that you receive certain media session events (MESessionCapabilitiesChanged
, MESessionStarted
, MEEndOfPresentationSegment
, MESessionTopologySet
, and MESessionTopologyStatus
) without the video being displayed indicates that there might be an issue with the playback setup or the media session topology.
To implement loop playback, you need to handle the end of the presentation segment (MEEndOfPresentationSegment
event) by looping back to the beginning of the playlist when it occurs. Here's a high-level approach to achieve this:
- When you receive the
MEEndOfPresentationSegment
event, check if it is the last segment in the playlist. - If it is the last segment, reset the playback to the beginning of the playlist.
- Otherwise, proceed to the next segment in the playlist.
You can achieve this by maintaining the current index of the segment being played and updating it accordingly. Here's an example of how you can modify your SkipTo
function to implement loop playback:
HRESULT CPlaylist::SkipTo(DWORD index)
{
if (index >= segmentCount)
{
return E_INVALIDARG;
}
MFSequencerElementId ID = segments[index].SegmentID;
PROPVARIANT var;
String debugStr(">>>>Segment ID is:"+IntToStr((int)ID) );
OutputDebugString(debugStr.w_str());
HRESULT hr = MFCreateSequencerSegmentOffset(ID, 0, &var);
if (SUCCEEDED(hr))
{
hr = mediaSession->Start(&MF_TIME_FORMAT_SEGMENT_OFFSET, &var);
PropVariantClear(&var);
// Check if the segment is the last one in the playlist
if (index == segmentCount - 1)
{
// Reset to the beginning of the playlist for loop playback
hr = SkipTo(0); // Recursive call to restart playback from the beginning
}
}
return hr;
}
This modified SkipTo
function will recursively restart playback from the beginning of the playlist when the last segment is reached, enabling loop playback. Make sure to handle any error conditions appropriately in your application.