locked
Reverse playing stream RRS feed

  • Question

  • 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
    Thursday, August 17, 2006 2:03 AM

Answers

  • 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.

     

    Thursday, August 17, 2006 3:33 PM

All replies

  • 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.

     

    Thursday, August 17, 2006 3:33 PM
  • 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
    Thursday, August 17, 2006 4:54 PM