0

MPEG-2ファイル内の任意のフレームを検索できるようにしたいと思います(DVDから、MPEG-2プログラムストリームと呼ばれていると思います)。これまで私はこれらのフレームにアクセスするためにOpenCV2.1を使用していましたが、それはフレームごとにのみ機能します(フォワードシークのみ)。後でOpenCV2.3.1をインストールしたとき、その可能性は失われました。つまり、AVIに限定されていました。とにかく、OpenCVなしでやりたいです。私はなんとかキーフレーム(私が思うに)またはそういうフレーム(例えば12番目のフレームごと)を探すことができました。これで、VirtualDubフレームを正確に探すことができます。「インターリーブされたMPEG-2ファイルの解析」と書かれています。それは正確にはどういう意味で、どこで同じことを始めなければならないのでしょうか?それは合法でさえありますか、私はそれについてどこかで何かを読んだことを覚えていますが、実際には覚えていません。私はdirectshowを使用してC++でプログラミングしています。私の知る限り、directshowはそれを行いません。次に、CBaseFilter、streamtimeメソッドなどを調べていましたが、その複雑なトピックに飛び込む前に、それが正しい方法であるかどうかを知りたいと思います。あなたの答えを楽しみにしています、ありがとう!

@ Geraint:フィルターグラフのコードスニペット:

CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC,IID_IGraphBuilder,(LPVOID *)&pGraphBuilder);
 CoCreateInstance(CLSID_MPEG2Demultiplexer,NULL,CLSCTX_INPROC,IID_IBaseFilter,(LPVOID *)&pib);
 CoCreateInstance(CLSID_CMPEG2VidDecoderDS,NULL,CLSCTX_INPROC,IID_IBaseFilter,(LPVOID *)&pib2);

 pGraphBuilder->AddFilter(pib,L"Sample Splitter");
 pGraphBuilder->AddFilter(pib2,L"Sample Decoder");

 ZeroMemory(&am_media_type, sizeof(am_media_type));
am_media_type.majortype = MEDIATYPE_Video;
am_media_type.subtype = MEDIASUBTYPE_MPEG2_VIDEO;
am_media_type.formattype = FORMAT_MPEG2Video;

pGraphBuilder->QueryInterface(IID_IMediaControl,(LPVOID *)&pMediaControl);
pGraphBuilder->QueryInterface(IID_IMediaSeeking, (void**)(&pMediaSeeking));
pGraphBuilder->QueryInterface(__uuidof(IVideoFrameStep), (PVOID *)&fst); 
pGraphBuilder->QueryInterface(IID_IMediaEvent, (void **)&imev);
pGraphBuilder->QueryInterface(IID_IBasicVideo,(LPVOID *)&ibv);

pGraphBuilder->RenderFile(FILENAME,0);

次に、ビデオを探すためにIMediaSeekingを使用します。フレームステッピングも試しました(したがって、上記の参照)。

4

1 に答える 1

3

DirectShow は、フレーム単位で正確なシークを実現できます。ただし、インデックスがない場合、これはフレーム カウントではなく、ファイル開始からの時間オフセットに基づいています。

IMediaSeeking を使用して開始時間を設定します。demux は、その少し前に圧縮フレームの配信を開始します。デコーダーは前のキー フレームからデコードを開始しますが、選択した開始点より前のフレームはすべて破棄します。

G

于 2013-02-08T15:14:39.970 に答える