Fanruten
Fanruten

Reputation: 3782

SetPosition get wrong result

Task: grabbing arbitrary frames from mpeg2 video files. Now I use custom render filter for grabbing, but problem with positioning video on required frame.

I use SetPosition(), after Pause() for passing frames through graph, wait for filter receive first frame and Stop().

If I get frame by frame, first i receive exact for this time frame, after this frame repeat some times, and again exact frame.

Why SetPosition get wrong result?

Upvotes: 2

Views: 701

Answers (2)

AndreiM
AndreiM

Reputation: 113

You need to pause the graph after you have rendered the graph. After that you can change the frame you want to show using SetPositions.

Something like this:

int ShowFrame(long lFrame)
{
    if (FAILED(m_pMC->Pause()))
       return -1;
    LONGLONG llUnknown = 0;
    LONGLONG  llTime = LONGLONG(m_lFrameTime) * lFrame + m_lFrameTime / 2;
    GUID TimeFormat;
    if (FAILED(m_pMS->GetTimeFormat(&TimeFormat))) return -1;
    if (TimeFormat == TIME_FORMAT_MEDIA_TIME)
    {
       llUnknown = llTime;
    }
    else
    {
       if (FAILED(m_pMS->ConvertTimeFormat(&llUnknown, &TimeFormat, llTime, &TIME_FORMAT_MEDIA_TIME))) return -1;
    }
    if (FAILED(m_pMS->SetPositions(&llUnknown, AM_SEEKING_AbsolutePositioning, 0, AM_SEEKING_NoPositioning))) return -1;
    return 0;
}

m_lFrameTime is the time per one frame, you can get in your custom renderer. When video renderer pin is connected you can get the VIDEOINFO::AvgTimePerFrame on that pin.

Upvotes: 0

Geraint Davies
Geraint Davies

Reputation: 2847

The decoder needs to start decoding at the previous i frame. Typically, the demux will start pushing data at least a second before that. When you start receiving frames, you should check the timestamp to see if they are the one you want. Your filter will receive a "NewSegment" call which gives the seek start position in the file. If you add this start time to the sample time on the frame, you will get the absolute position of the frame within the file and you can compare that to your requested location.

G

Upvotes: 3

Related Questions