有谁知道Win7的Microsoft MFT是否可以用C#编写?如果是这样,是否有任何书籍或网站可以帮助我.
感谢您花些时间阅读我的问题.
我正在使用Qt和Windows API开发C++应用程序.
我正在以原始格式录制小型10s音频文件中的麦克风输出,我想将它们转换为aac格式.
我试图尽可能多地阅读,并认为从windows media foundation转码API开始是一个好主意.
问题是,我似乎无法在"CreateObjectFromUrl"函数中使用.raw或.pcm文件,因此我暂时停留在这里.它一直在失败.hr返回代码等于3222091460.我试图将.mp3文件传递给函数,当然它可以工作,所以不涉及url-human-failure.
MF_OBJECT_TYPE ObjectType = MF_OBJECT_INVALID;
IMFSourceResolver* pSourceResolver = NULL;
IUnknown* pUnkSource = NULL;
// Create the source resolver.
hr = MFCreateSourceResolver(&pSourceResolver);
if (FAILED(hr))
{
qDebug() << "Failed !";
}
// Use the source resolver to create the media source.
hr = pSourceResolver->CreateObjectFromURL(
sURL, // URL of the source.
MF_RESOLUTION_MEDIASOURCE, // Create a source object.
NULL, // Optional property store.
&ObjectType, // Receives the created object type.
&pUnkSource // Receives a pointer to the …Run Code Online (Sandbox Code Playgroud) 我正在使用windows media foundation api来枚举我的麦克风和可用的相机,两者都有效.
这是我的枚举代码:
class deviceInput {
public:
deviceInput( REFGUID source );
~deviceInput();
int listDevices(bool refresh = false);
IMFActivate *getDevice(unsigned int deviceId);
const WCHAR *getDeviceName(unsigned int deviceId);
private:
void Clear();
HRESULT EnumerateDevices();
UINT32 m_count;
IMFActivate **m_devices;
REFGUID m_source;
};
deviceInput::deviceInput( REFGUID source )
: m_devices( NULL )
, m_count( 0 )
, m_source( source )
{ }
deviceInput::~deviceInput()
{
Clear();
}
int deviceInput::listDevices(bool refresh)
{
if ( refresh || !m_devices ) {
if ( FAILED(this->EnumerateDevices()) ) return -1;
} …Run Code Online (Sandbox Code Playgroud) 我试图让我的编码器工作已经一周了......
所以事情是:
我使用 MF 的 Sink Writer 创建一个文件。
我写了所有的视频样本。
--> (如果我停在那里并调用 Finish 方法,我可以使用 VLC 读取该文件,但如果我执行以下操作,该文件将被“损坏”)
我写了所有的音频样本。
我调用完成函数,得到一个 HRESULT 代码:“接收器无法创建有效的输出文件,因为未向接收器提供所需的标头”。我完全理解这个错误,只是我不知道如何解决它......
如果你们需要任何代码,我很乐意将其放在这里。
在我的WPF项目中,我创建了一个包含多个MediaElements播放视频的视图.有时,在一个或所有MediaElements之间的任何地方都将无法播放分配给它们的视频,而是显示黑色矩形,或根本不显示.发生这种情况时不会发生MediaFailed事件.MediaOpened事件会在所有MediaElements上出现,即使他们不播放视频也是如此.
我已经为我的显卡安装了最新的驱动程序,这对此问题没有任何影响.
是否有一个程序可用于确保每个MediaElement始终如一地播放?
示例源代码如下.包含视频文件的完整示例项目位于github,网址为https://github.com/duggulous/MediaElementIssueExample
MainWindow.xaml
<Window x:Class="VideoDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="1920" Width="1080">
<Grid Name="rootContainer" Background="Pink">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="404" />
<ColumnDefinition Width="136" />
<ColumnDefinition Width="136" />
<ColumnDefinition Width="134" />
<ColumnDefinition Width="270" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="270" />
<RowDefinition Height="30" />
<RowDefinition Height="412" />
<RowDefinition Height="416"/>
<RowDefinition Height="526"/>
<RowDefinition Height="264"/>
</Grid.RowDefinitions>
<MediaElement x:Name="panel1" Margin="-1"
Grid.Column="0" Grid.Row="0"
Grid.ColumnSpan="2" Grid.RowSpan="2"
Source="media/1-ekg.mp4"
MediaOpened="panel1_MediaOpened"
MediaFailed="panel1_MediaFailed"
MediaEnded="panel1_MediaEnded"/>
<MediaElement x:Name="panel2" Margin="-1"
Grid.Column="2" Grid.Row="0"
Grid.ColumnSpan="3" Grid.RowSpan="1"
Source="media/2-star.mp4"
MediaOpened="panel1_MediaOpened"
MediaFailed="panel1_MediaFailed"
MediaEnded="panel1_MediaEnded"/>
<MediaElement x:Name="panel3" Margin="-1"
Grid.Column="0" Grid.Row="2"
Grid.ColumnSpan="2" …Run Code Online (Sandbox Code Playgroud) 在使用Media Foundation将视频录制最终录制为.mp4的视频时,出现问题,而该调用IMFSinkWriter->Finalize();将永远挂起。它并非总是会发生,并且几乎可以在任何计算机上发生(在Windows服务器上看到的7、8、10)。Flush()会先在音频和视频流上调用,并且不会在Flush和之间添加新样本Finalize。关于什么可能导致Finalize永远死机的任何想法?
我尝试过的事情:
HRESULTs以检查是否有任何问题(在进行下一行代码之前已经检查了它们)一切恢复为
S_OK,没有看到任何问题
IMFSinkWriterCallback在流上添加,以在流处理标记(每10个样本添加一个标记)并完成处理时获取回调Finalize()自添加此功能以来一直无法复制,但这将为我提供有关工作时发生的一切的最佳信息。
Finalize()使用找不到很多样本,看起来我的代码与发现的代码相似
在可能重现此问题的计算机上,编码器在AMD H.264硬件MFT编码器和H264编码器MFT之间有所不同。版本似乎无关紧要,有些机器是最新的视频驱动程序。
这是一些未经任何HRESULT检查的代码示例(使代码量加倍,所以我取出了它)
构建接收器样本:
CComPtr<IMFAttributes> pAttr;
::MFCreateAttributes( &pAttr, 4 );
pAttr->SetGUID( MF_TRANSCODE_CONTAINERTYPE, GetFileContainerType() );
pAttr->SetUINT32( MF_LOW_LATENCY, FALSE ); // Allows better multithreading
pAttr->SetUINT32( MF_SINK_WRITER_DISABLE_THROTTLING, TRUE ); // Does not block
pAttr->SetUINT32( MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, TRUE );
m_pCallback.Attach( new MFSinkWriterCallback() );
pAttr->SetUnknown( MF_SINK_WRITER_ASYNC_CALLBACK, m_pCallback );
::MFCreateSinkWriterFromURL( m_strFilename.c_str(), NULL, pAttr, &m_pSink );
if …Run Code Online (Sandbox Code Playgroud) 我正在使用Media Foundation的Source Reader编写硬件加速的h264解码器,但遇到了问题.我按照本教程使用Windows SDK Media Foundation示例支持自己.
当硬件加速关闭时,我的应用似乎工作正常,但它不提供我需要的性能.当我通过传递一个用来创建阅读器IMFDXGIDeviceManager来加速加速时IMFAttributes,事情就变得复杂了.
如果我创建ID3D11Device使用D3D_DRIVER_TYPE_NULL驱动程序,应用程序工作正常,帧处理速度比在软件模式下更快,但从CPU和GPU使用情况来看,它仍然在CPU上进行大部分处理.
另一方面,当我创建ID3D11Device使用D3D_DRIVER_TYPE_HARDWARE驱动程序并运行应用程序时,可能会发生以下四种情况之一.
在IMFMediaBuffer::Lock函数返回0x887a0005 之前,我只得到一个不可预测的帧数(通常为1-3),这被描述为"GPU设备实例已被暂停.GetDeviceRemovedReason用于确定适当的操作".当我打电话时ID3D11Device::GetDeviceRemovedReason,我得到0x887a0020,这被描述为"驱动程序遇到问题,并被置于设备移除状态",这没有我希望的那样有用.
应用程序在外部dll中随时崩溃IMFMediaBuffer::Lock.似乎dll取决于所使用的GPU.对于Intel集成GPU,它是igd10iumd32.dll,对于Nvidia移动GPU,它是mfplat.dll.此特定崩溃的消息如下:"在decoder_ tester.exe中0x53C6DB8C(mfplat.dll)抛出异常:0xC0000005:访问冲突读取位置0x00000024".执行之间的地址不同,有时涉及阅读,有时甚至是写作.
图形驱动程序停止响应,系统暂停一小段时间,然后应用程序崩溃,如第2点或完成第1点.
该应用程序工作正常,并通过硬件加速处理所有帧.
大部分时间是1或2,很少3或4.
以下是我的机器上不同模式下处理时不受限制的CPU/GPU使用情况(英特尔酷睿i5-6500与HD Graphics 530,Windows 10 Pro).
我在三台机器上测试了应用程序.他们都拥有英特尔集成GPU(HD 4400,HD 4600,HD 530).其中一个还有可切换的Nvidia专用GPU(GF 840M).它在所有这些方面完全相同,唯一的区别是当使用Nvidia的GPU时它会在不同的dll中崩溃.
我以前没有使用COM或DirectX的经验,但所有这些都是不一致和不可预测的,所以它看起来像是一个内存损坏我.不过,我不知道我在哪里弄错了.你能帮我找一下我做错的事吗?
我能想出的最小代码示例如下.我正在使用Visual Studio Professional 2015将其编译为C++项目.我准备了定义以启用硬件加速并选择硬件驱动程序.评论它们以改变行为.此外,代码期望此视频文件存在于项目目录中.
#include <iostream>
#include <string>
#include <atlbase.h>
#include <d3d11.h>
#include <mfapi.h>
#include <mfidl.h>
#include <mfreadwrite.h>
#include <windows.h> …Run Code Online (Sandbox Code Playgroud) 我正在尝试将 H.264 视频源流式传输到网络浏览器。Media Foundation 用于对分段的 MPEG4 流进行编码(MFCreateFMPEG4MediaSink使用MFTranscodeContainerType_FMPEG4、MF_LOW_LATENCY和MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS启用)。然后,该流通过 .NET 连接到 Web 服务器IMFByteStream。
当 H.264 视频被标签使用时,它的流式传输工作正常<video src=".."/>。然而,产生的延迟约为 2 秒,这对于相关应用程序来说太大了。我怀疑客户端缓冲导致了大部分延迟。因此,我正在尝试使用媒体源扩展 (MSE) 对浏览器内流进行编程控制。但是,当通过 MSE 使用相同的 MPEG4 流时,Chrome 会失败并出现以下错误:
解析 MP4 失败:MSE 不允许 TFHD 基本数据偏移。请参阅 https://www.w3.org/TR/mse-byte-stream-format-isobmff/#movie-fragment-relative-addressing
MPEG4 流中 moof/mdat 片段的 mp4dump。这清楚地表明 TFHD 包含“非法”base data offset参数:
[moof] size=8+200
[mfhd] size=12+4
sequence number = 3
[traf] size=8+176
[tfhd] size=12+16, flags=1
track ID = 1
base data offset = 36690
[trun] size=12+136, version=1, flags=f01 …Run Code Online (Sandbox Code Playgroud) 在Windows 10上,需要访问网络摄像头的应用程序,与之通信frame server的服务进行通信svchost.
我过滤掉了网络摄像头流和我得到的进程ID svchost.我想确定使用网络摄像头的实际过程.
有没有明确的方法来以编程方式识别使用网络摄像头的实际应用程序是什么?我已经研究了枚举进程的句柄(也必须处理NtQueryObject()挂起),但我正在寻找更好的解决方案.
我使用Intel硬件MFT将NV12帧编码为H264流,并使用Live555通过LAN上的RTP通过流传输编码的帧,并在另一端进行ffplay设置以解码和显示它们。该设置可以与软件编码器(SYNC或ASYNC软件MFT)配合使用,但是ffplay抱怨当在Intel硬件MFT中完成编码时,SPS / PPS不可用,并且仅显示一个乱码。我发现英特尔硬件编码器在馈入初始样本并通过MF_MT_MPEG_SEQUENCE_HEADER使SPS / PPS可用之后触发MF_E_TRANSFORM_STREAM_CHANGE事件。我能够捕获该MF_E_TRANSFORM_STREAM_CHANGE事件并获取序列标头blob。
问题是,Live555需要分别设置SPS和PPS。但是,我对于从MF_MT_MPEG_SEQUENCE_HEADER blob中提取SPS和PPS感到非常困惑。
根据我的理解以及在其他线程中的进一步查找,SPS和PPS分别以00 00 00 01 67和0 00 00 01 68开头。但是,我在从英特尔编码器收到的Blob中找不到任何序列。
https://github.com/cisco/openh264/issues/756 SPS的开始:00 00 00 01 67 PPS的开始:00 00 00 01 68
从intel MFT获得的序列头:
序列头大小50
冒号头:0 0 1 27 64 0 28 ac 2b 40 3c 1 13 f2 e0 22 0 0 3 0 2 0 0 3 0 79 d0 80 f 42 0 3 d0 93 7b df 7 68 70 ca 80 0 0 0 1 28 ee 3c b0 …