2

これは本当に私の髪を引っ張っています。CTransformFilter から派生した DirectShow 変換フィルターを作成しました。CTransformInputPin から入力ピンを派生させました。入力ピンの Receive メソッドが呼び出されると、IMediaSample のプレゼンテーション時間がファイルに記録されます。グラフを停止して再度開始するまで、これはすべて正常に機能します(MSのgraphedtを使用しています)。ほとんどの場合、再実行しても問題はありません。しかし、グラフを停止してから再度実行する回数の約 10 分の 1 で、プレゼンテーションの開始時間がマイナスになります。グラフが実行されると、最終的にはゼロまで増加し、ゼロを超えますが、ストリーム時間に追いつくことはなく、その結果、ストリーム時間はすべてのサンプルのプレゼンテーション開始時間よりも大幅に遅れたままになります。

Logitech Webcam Pro 9000 と Logitech C600 カメラでこれを確認しましたが、Winbook カメラでは確認できませんでした。したがって、これが Logitech の問題であるかどうか疑問に思っています。停止して再度実行した後、ビデオ IMediaSamples で負のプレゼンテーション時間を見た人はいますか? (IMediaSample のプリロール フラグを確認しました。常に S_FALSE です。)

アップデート:

CTransformFilter の (実際には、CBaseFilter の) Run メソッドを次のようにオーバーライドしました。

STDMETHODIMP MyTransformFilter::Run(REFERENCE_TIME tStart)
{
    char buff[1000];
    REFERENCE_TIME rTime;

    m_pClock->GetTime(&rTime);
    sprintf(buff, "Run tstart = %lld, rTime = %lld", tStart, rTime);
    Trace(buff); // open my log file, add buff, close my log file
    return CTransformFilter::Run(tStart);
}

graphedt を使用してグラフを開始し、10 秒間実行し、5 秒間一時停止してから、再び開始しました。出力は次のとおりです。

Run tstart = 7855978550000, rTime = 7855978450000
Run tstart = 7856030610000, rTime = 7856126960000

Run に渡された 2 つの時間は、5.2 秒 (私が一時停止した時間とほぼ同じ) 異なります。2 つの参照クロック時間は、14.6 秒 (Run の呼び出し間の合計時間とほぼ同じ) 異なります。フィルター グラフ マネージャーが Run に渡される時間 (最初の呼び出しで 10 ミリ秒) に追加するわずかな増加を除いて、これらは Run が呼び出されるたびにほぼ同じであると予想されます。代わりに、2 回目の呼び出しで Run に渡される時間は、参照クロックより約 10 秒遅れています。2 番目の呼び出しで Run に渡された時間が、2 番目の呼び出しで参照クロックによって返された時間と (ほぼ) 同じではない理由を理解するのに非常に役立ちます。

更新 2:

問題は Logitech バージョン 13.31.1044.0 ドライバーにあるようです。以下の回答を参照してください。

4

2 に答える 2

4

負の時間は大したことではありません。本質的には、「メディア サンプルは少し前に提示されるべきだった」という意味です。では、メディア サンプルは破棄される可能性があると考えるかもしれません。これは正しい場合もあれば、そうでない場合もあります。キー フレームの後に 10 個のデルタ フレームが続く、一時的に圧縮されたビデオ フレームのシーケンスを想像してみてください。フレーム #5 からプレゼンテーションを開始したいのですが、どうすればよいでしょうか? デコーダーがスプライス ポイントから効果的にデコードできるように、キー フレームからプッシュ スルーする必要があります。そうしないと、デルタ フレームから開始できません。デコーダーは、フレームが遅れているかどうかに関係なく出力フレームを配信する場合があり、これが最終的にこれらのフレームがユーザーに到達する方法です。

負の時間になる別のシナリオは、スレッド、ストリーミング、および制御の競合状態によって引き起こされます。キャプチャ スレッドが操作を開始しているが、ハンドにベース "開始時間" がない可能性があります。

于 2012-04-11T15:41:43.877 に答える
1

かなりの実験を行った結果、この問題は Logitech 13.31.1044.0 カメラ ドライバーに固有のものである可能性が最も高いという結論に達しました。以前の Logitech 12.10.1110 ドライバー、Winbook DC-6120 カメラ (およびそのドライバー)、および Chicony USB 2.0 カメラ (およびそのドライバー) では、問題を再発させることはできませんでした。明確な理由はありませんが、Logitech 13 ドライバーは、グラフの再起動を含めて、グラフの約 10 回に 1 回 (つまり、graphedt で停止してから再度開始した後) に負のプレゼンテーション時間で始まるサンプルを配信します。 )。これらの時間をストリーム時間と比較しても、サンプルが過去、現在、または将来に表示されるようにスケジュールされているかどうかに関して、MSDN が説明する情報は提供されません。再起動するたびに、ストリーム時間は、カメラのプレゼンテーション時間の開始時刻に関係なく、予想どおりゼロから再び開始されます。(Logitech は圧縮フレームなしで RGB24 サブタイプでストリーミングしていることに注意してください。)

私は、ストリーム時間に基づいた値でプレゼンテーション時間を再割り当てできる可能性のあるマルチスレッド パススルー フィルターに取り組んでおり、正しい値を「偽造」するのに十分な速さで実行します。結果。また、テストを文書化し、ロジクールに伝えます。反応があれば、こちらにも掲載します。

他の誰かが上記のドライバーを使用する Logicool 製品を使用している場合 (または、私が説明した動作を観察している場合)、ここにコメントしてください。時間、フレームなどを記録するフィルターのコピーをお送りします。これに対処するための良い方法を一緒に見つけることができるかもしれません。

アップデート

できる限り単純な Tranform フィルター (入力 IMediaSample のネガティブ イメージを出力に単純にコピーするフィルター) を作成することで、この動作をかなり一貫して再現することができました。Camera->Filter->Renderer で構成されるグラフを再起動するのは 5 ~ 6 回に 1 回程度です。最初のいくつかのサンプルは、ストリーム時間よりはるかに遅れており、決して追いつかない負のフレーム時間で配信されます。(つまり、ストリーム時間は、サンプルのプレゼンテーション時間よりも常に進んでいます)。繰り返しますが、これは他のカメラや古い Logitech ドライバーでは決して起こりません。

興味深い点は次のとおりです。フィルターの Run メソッドに遅延を追加すると (CTransformFilter::Run をオーバーライドした後)、問題は解決します。コードは次のとおりです。

STDMETHODIMP DLPassThrough::Run(REFERENCE_TIME tStart)
{
    Sleep(10);

    return CTransformFilter::Run(tStart);
}

その「Sleep(10)」呼び出しをコメントアウトまたは復元することで、問題を解決できます。私が推測できるのは、カメラのコードがマルチスレッド化されており、常に「実行」呼び出しに先行する「一時停止」呼び出しと次の「実行」呼び出しの間に、実行中の処理をクリーンアップするために時間がかかるということです。MSDNのドキュメントを理解しているように、グラフマネージャーはレンダラー、フィルター、カメラの順に「一時停止」を呼び出してから、レンダラー、フィルター、カメラの順に「実行」を呼び出します。これらの呼び出しはそれぞれ同期していると思いますが、カメラ コードがマルチスレッドの場合、「実行」メソッドが呼び出されたときに、グラフ マネージャーからの最新の「一時停止」呼び出しがまだ実行されている可能性があります。フィルターの「実行」メソッドに遅延を追加することで、

これについてロジクールからの連絡をまだ待っています/期待しています. その間、取得した最新のサンプルへの参照を追加し、そのプレゼンテーション時間を現在のストリーム時間に置き換え、ダウンストリーム フィルターが次にダウンストリームを使用するためにそれを保存する、マルチスレッドのトランスフォーム インプレース フィルターを作成しました。フィルターはそれを受信する準備ができてから、次の着信サンプルの待機に戻ります。(ダウンストリーム フィルターが 1 つ取得する前に複数のサンプルが入ってきた場合、前のサンプルが解放され、最新のサンプルに置き換えられます。) これまでのところ、機能しているようです。

更新 2

Logitechの回答は次のとおりです。

このデバイスは、主にビデオ ストリーミング用の IM アプリケーションで動作するように作成されており、ソフトウェアやフィルターを開発する対象としては作成されていません。

于 2012-04-19T12:28:46.567 に答える