Reverse playing stream

I am trying to reverse the stream while it is playing by using SetRate. I am getting the slowest, fastest and nearest supported rate for MF_RATE_REVERSE without any errors.

It can also SetRate forward without problems.

Now, for reverse, if I dont stop the stream I rightfully get MF_E_UNSUPPORTED_RATE_TRANSITION. So I get the playing position, stop the stream, SetRate and start the stream again. I dont see any errors, except that the session ends immidiately.

Is there anything special I am missing

Here is the code I am using (SetPlaybackRate was taken from the docs):

HRESULT hr = S_OK;

IMFRateControl *pRateControl = NULL;
hr = MFGetService(m_pSession, MF_RATE_CONTROL_SERVICE, IID_IMFRateControl, (void**) &pRateControl);

if (!SUCCEEDED(hr))
{
return hr;
}

BOOL bThin;
float rate;
hr = pRateControl->GetRate(&bThin, &rate);

if (!SUCCEEDED(hr))
{
return hr;
}

bool reverseDirection = false;
// If we are not going the same direction, stop the playback
if (((rate < 0) && (playrate > 0)) || ((rate > 0) && (playrate < 0)))
reverseDirection = true;

MFTIME phnsCurrentTime = 0;

if (reverseDirection)
{
MFTIME phnsSegmentDuration = 0;

GetSegmentInfo(&phnsCurrentTime, &phnsSegmentDuration);

hr = m_pSession->Stop();

// Wait for the stop event
if (!m_hSessionStoppedEvent->WaitOne(1000, false))
{
System::Diagnostics::Debug::WriteLine("Session Stopped Event Timed Out");
}
}

hr = SetPlaybackRate(m_pSession, playrate, true);

if (reverseDirection)
{
PROPVARIANT var;
PropVariantInit(&var);

var.vt = VT_I8;
var.hVal.QuadPart = phnsCurrentTime;

hr = m_pSession->Start(&GUID_NULL, &var);

// Not strictly needed here but good form...
PropVariantClear(&var);

if (!m_hSessionStartedEvent->WaitOne(1000, false))
{
System::Diagnostics::Debug::WriteLine("Session Started Timeout");
}
}

return hr;

Thanks!

Marc


Answer this question

Reverse playing stream

  • WilliamStacey

    I am using mp3 files so I guess that would work as a WMA. Which explains why that wont work after all.

    Thanks for your usual prompt response.

    Marc

  • Indigox3

    Hi Marc,

    Your code looks pretty much right... You get the playback position before stopping, and then you Stop, SetRate, and Start at that saved position.

    Here are the two things that occur to me:

    1) Are you playing WMV content Because if you're playing WMA (audio-only) content and try to play it in reverse, you'll get nothing; Media Foundation doesn't play any audio when going in reverse, so reverse playback of WMA content isn't so useful.

    2) Assuming you are playing WMV content... When we do reverse playback of audio+video content, we play only the video key frames. In a typical WMV file, the key frames can be several seconds apart. So if your hnsCurrentTime is only a couple seconds into the file, it's possible that you would see only one frame as you try to play back from there in reverse.

    3) Just to narrow down the problem, you might want to just try opening the content, doing SetRate( -1.0 ), and doing Start() from a position near the end of the file and see what happens.



  • Reverse playing stream