2

タスク: mpeg2 ビデオ ファイルから任意のフレームを取得します。現在、グラブにカスタムレンダーフィルターを使用していますが、必要なフレームにビデオを配置する際に問題があります。

グラフを介してフレームを渡すために Pause() の後に SetPosition() を使用し、フィルターが最初のフレームを受信するのを待ち、Stop() を使用します。

フレームごとに取得する場合、最初にこの時間フレームの正確な値を取得し、このフレームが何度か繰り返された後、再び正確なフレームを取得します。

SetPosition が間違った結果になるのはなぜですか?

4

2 に答える 2

3

デコーダーは、前の i フレームでデコードを開始する必要があります。通常、demux は少なくともその 1 秒前にデータのプッシュを開始します。フレームの受信を開始したら、タイムスタンプをチェックして、必要なフレームであるかどうかを確認する必要があります。フィルタは、ファイル内のシーク開始位置を指定する「NewSegment」呼び出しを受け取ります。この開始時間をフレームのサンプル時間に追加すると、ファイル内のフレームの絶対位置が得られ、それを要求された位置と比較できます。

G

于 2009-06-15T18:37:14.207 に答える
0

グラフをレンダリングした後、グラフを一時停止する必要があります。その後、SetPositions を使用して表示するフレームを変更できます。

このようなもの:

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 は 1 フレームあたりの時間で、カスタム レンダラーで取得できます。ビデオ レンダラー ピンが接続されている場合、そのピンで VIDEOINFO::AvgTimePerFrame を取得できます。

于 2009-10-27T12:29:25.983 に答える