How to implement loop playback using IMFSequenceSource as a play

ghz 8months ago ⋅ 92 views

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:

  1. When you receive the MEEndOfPresentationSegment event, check if it is the last segment in the playlist.
  2. If it is the last segment, reset the playback to the beginning of the playlist.
  3. 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.