ビデオファイルからフレームを取得したい。DirectshowのSampleGrabberにいくつかのバグがあるため、同様のフィルター(変換フィルターではなく、レンダラー)を作成することにしました。
Windows SDKダンプフィルター(Microsoft SDKs\Windows\v7.1\Samples\multimedia\directshow\filters\dump
)に基づいてDirectShowフィルターを作成しようとしています。私のフィルターはRGB24フォーマットのみを受け入れます。
class CDumpInputPin : public CRenderedInputPin
{
//...
STDMETHODIMP Receive(IMediaSample *pSample) override {
//...
REFERENCE_TIME tStart=0, tStop=0;
if (FAILED(pSample->GetTime(&tStart, &tStop))) {
LOG(ERROR) << "Unable to get sample time";
}
LOG(INFO) << "tStart=" << tStart << " tStop=" << tStop ;
}
HRESULT CheckMediaType(const CMediaType *pmt){
if (*pmt->Type() != MEDIATYPE_Video) {
return S_FALSE;
}
if ((*pmt->FormatType() != FORMAT_VideoInfo)) {
return S_FALSE;
}
if ((*pmt->Subtype() != MEDIASUBTYPE_RGB24)) {
return S_FALSE;
}
return S_OK;
}
}
正しいRGBフレームを取得しますが、IMediaSample :: GetTime()メソッドから返された値を解釈する方法がわかりません。私pSeeking->SetPositions( &Start, AM_SEEKING_AbsolutePositioning | AM_SEEKING_SeekToKeyFrame, 0, AM_SEEKING_NoPositioning);
はソースファイル内のさまざまな位置を探すために使用します。8フレームを取得しようとすると、ログが表示されます。
tStart=222223 tStop=622223
tStart=266668 tStop=666668
tStart=311113 tStop=711113
tStart=355558 tStop=755558
tStart=3 tStop=400003
tStart=44448 tStop=444448
tStart=88893 tStop=488893
tStart=133338 tStop=533338
これらの数字が何を意味するのか、そしてなぜそれらが増加するシーケンスを構成していないのか理解できません。
これらのフレームの正しいタイムスタンプは次のとおりです。
00:00:12
00:00:37
00:01:01
00:01:26
00:01:51
00:02:15
00:02:40
00:03:05
正しい時刻を取得します-100ns単位の64ビット値。参照してくださいREFERENCE_TIME
とDirectShowの時間と時計を。
REFERENCE_TIMEデータ型は、DirectShowの参照時間の単位を定義します。参照時間の各単位は100ナノ秒です。
..。
タイムスタンプは、ストリーム時間で測定されたメディアサンプルの開始時間と終了時間を定義します。タイムスタンプは、プレゼンテーション時間と呼ばれることもあります
..。
ファイルの再生:最初のサンプルには、開始時刻がゼロのタイムスタンプが付けられます。後続のタイムスタンプは、サンプルの長さと再生速度によって決定されます。再生速度自体は、ファイル形式によって決定されます。ファイルを解析するフィルターは、正しいタイムスタンプを計算する役割を果たします。
そう、
秒単位で正しいフレーム時間を取得する方法...
DOUBLE Time = tStart / 1E7; // <<--- presentation time (see above) in seconds
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加