2013-02-07 61 views
0

我希望能够在MPEG-2文件中寻找任意帧(来自DVD,我想它被称为MPEG-2节目流)。到目前为止,我一直在使用OpenCV 2.1来访问这些帧,但是这只能在一帧接一帧的基础上进行(只有正向搜索)。稍后当我安装OpenCV 2.3.1时,尽管可能性有所减少,即仅限于AVI。无论如何,我想这样做没有OpenCV。我设法寻找关键帧(我想)或每隔一段时间(例如每隔12帧)。现在,看VirtualDub帧准确查找是可能的。它说:''解析交错的MPEG-2文件''。这到底意味着什么,我将在哪里开始做同样的事情?它甚至是合法的,我记得在某个地方阅读了某些东西,但是不能真正记住。我使用directshow在C++中进行编程。据我所知directshow不会这样做。然后,我正在研究CBaseFilter,streamtime方法等,但在深入探讨这个复杂的主题之前,我想知道这是否是正确的方法。期待你的回答,谢谢!MPEG-2寻找,从哪里开始?

@杰兰特:filter图表的代码片段:

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寻求的VID。我也试过帧步进(因此上面的参考)。

+0

你说你想寻求一个任意的框架。但是你想在寻求之后做什么?例如,该框架应该显示在屏幕上吗?基本上我想知道你想在压缩的MPEG比特流中寻找,还是想在解码的视频帧内搜索? – wimh

+0

好吧,我提到了OpenCV(电脑'视觉'),所以你可以想象我想寻找解码帧:-) – user1331044

回答

3

DirectShow能够提供帧精确搜索。但是,如果没有索引,则基于文件开始的时间偏移,而不是帧数。

使用IMediaSeeking设置开始时间。 demux将在某种程度上开始传送压缩帧。解码器将在前一关键帧处开始解码,但会丢弃所选起始点之前的任何帧。

G

+0

嗨Geraint,我已经实现了一个显示所选帧的搜索栏。为此,我一直在使用IMediaSeeking :: SetPositions和TIME_FORMAT_MEDIA_TIME(默认),我想这就是你的建议,对吧?使用AVI这很好,但当我寻找MPEG-2视频时,即使我指出另一个时间(=帧),它也只会将我带到关键帧。不过,我想获得任何任意框架,而不仅仅是关键帧。以下是我如何设置位置:pMediaSeeking-> SetPositions(&llPlay,AM_SEEKING_AbsolutePositioning,NULL,AM_SEEKING_NoPositioning);} ll媒体播放时间。 – user1331044

+0

你的图表是什么样的?如果您在回放图中寻找任意帧(demux => decoder => renderer),则解码器将从关键帧解码到所选帧,并将所选帧输出到渲染器,丢弃它需要解码才能到达的帧。 –

+0

我觉得我缺少demux和解码器部分(至少是解码器)。我编辑了原始帖子以显示代码。那我该如何实现demux和解码器呢? – user1331044