在C++中使用 DirectShow 解码带有 H.264 流的 MP4 视频
Using DirectShow in C++ to decode an MP4 video with a H.264 stream
我有一个包含单个H.264流的MP4视频,没有音频流。我想将 DirectShow 与C++一起使用来解码视频,但我在设置 DirectShow 过滤器时遇到问题,希望有人能够提供帮助?
这是我使用 DirectShow 解码 WMV3 流的设置代码,我运行良好:
hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&m_pGraph);
if (SUCCEEDED(hr)) hr = CoCreateInstance(CLSID_VideoMixingRenderer9, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&m_pFilter);
if (SUCCEEDED(hr)) hr = m_pFilter->QueryInterface(IID_IVMRFilterConfig9, reinterpret_cast<void**>(&filterConfig));
if (SUCCEEDED(hr)) hr = filterConfig->SetRenderingMode( VMR9Mode_Renderless );
if (SUCCEEDED(hr)) hr = filterConfig->SetNumberOfStreams(2);
if (SUCCEEDED(hr)) hr = SetAllocatorPresenter( m_pFilter, g_pMainWindow );
if (SUCCEEDED(hr)) hr = m_pGraph->AddFilter(m_pFilter, L"Video Mixing Renderer 9");
if (SUCCEEDED(hr)) hr = m_pGraph->QueryInterface(IID_IMediaControl, reinterpret_cast<void**>(&m_pMediaControl));
if (SUCCEEDED(hr)) hr = m_pGraph->QueryInterface(IID_IBasicAudio, reinterpret_cast<void**>(&m_pBasicAudio));
if (SUCCEEDED(hr)) hr = m_pGraph->RenderFile( lpFilename, NULL );
但是,我无法找出解码MP4的正确设置。我已经安装了在其他帖子中发现的 3ivx 和 ffdshow,现在 GraphEdit 可以打开我的文件并显示正确的图形(认为 - 我在 64 位机器上,当我运行 64 位版本的 GraphEdit 时,这不起作用,但 32 位的......这可能与它有关吗?VLC可以很好地播放我的视频。
我已经在整个互联网上搜索了与此相关的示例,但找不到任何示例。
我的视频文件格式如下(ffmpeg输出):
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'test.mp4':
Metadata:
major_brand : mp42
minor_version : 0
compatible_brands: mp42mp41
creation_time : 2013-01-16 19:14:52
Duration: 00:05:25.62, start: 0.033367, bitrate: 3396 kb/s
Stream #0:0(eng): Video: h264 (Main) (avc1 / 0x31637661), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], 3393 kb/s, 29.97 fps, 29.97 tbr, 30k tbn, 59.94 tbc
Metadata:
creation_time : 2013-01-16 19:14:52
handler_name : ?Mainconcept Video Media Handler
任何帮助将不胜感激!
问候格雷厄姆
Windows中没有标准/默认的MP4解复用器,因此您必须安装一个扩展的DirectShow以覆盖MP4。
- 您需要安装适当位数(32 位与 64 位)的解复用器,以匹配代码/应用程序(或 GraphEdit)的位数
- VLC 无关紧要,因为它内置了自己的解复用器 您
- 还需要H.264解码器,而且您似乎已经有一个
你的代码是正确的,但这种图形构建方法并不完全实现。首先,您需要查看是否收到任何有用的错误代码(您可能在RenderFile
通话中)。
如果 GraphEdit Win32 在此系统上工作,则所有必需的组件(筛选器)都应可用。不同之处在于,GraphEdit不会像你那样构建图形。相反,它使用给定文件的IGraphBuilder::AddSourceFilter
来添加起始筛选器,然后呈现其引脚。如果您采用相同的方法,并在最后一步添加用于视频演示的 VMR 筛选器,这将很好地工作。
相关文章:
- std::当在256字节边界上写入整数时,流的奇怪行为
- 如何在c++中录制具有精确帧时间戳的视频
- 将时间戳打印到流的最简单方法
- 使用 IMFSinkWriter 编码的视频的播放速度会根据宽度而变化
- 什么是流的标记,为什么流中只有 1 个标记?
- 字符串流的部分副本
- 有什么方法可以包装自动类型扣除的助推"tee"流的构造?
- put_time流的怪异行为
- 如何实时捕获相机的视频?
- showbase和字符串流的前导零
- 帧提取 使用OpenCV的视频文件开头只有几秒钟
- 树莓派上的端口音频,找不到输入流的设备
- 用于 c++ 媒体流的 N-API 连续回调
- 使用 OpenCV C++ 每 1 分钟创建新的视频文件
- 如何通过自定义的流设置流的坏位
- visual如何在C++中将捕获的流媒体视频保存到avi文件中
- 在 Qt 中播放来自 BYTE* 流的视频
- 我可以将处理后的视频输出从 PC 上的 OpenCV 流式传输到安卓平板电脑吗?
- 添加增强的视频渲染流
- 在C++中使用 DirectShow 解码带有 H.264 流的 MP4 视频