C# 媒体基础H.264高CPU使用率 在媒体Foundation .NET中,我在CPU上写下了流的高CPU使用率。下面是我如何初始化sinkwriter的 private int InitializeSinkWriter(String outputFile, int videoWidth, int videoHeight) { IMFMediaType mediaTypeIn = null; IMFMediaType mediaTypeOut = null; IMFAttributes attributes = null; int hr = 0; if (Succeeded(hr)) hr = (int)MFExtern.MFCreateAttributes(out attributes, 1); if (Succeeded(hr)) hr = (int)attributes.SetUINT32(MFAttributesClsid.MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, 1); if (Succeeded(hr)) hr = (int)attributes.SetUINT32(MFAttributesClsid.MF_SINK_WRITER_DISABLE_THROTTLING, 1); if (Succeeded(hr)) hr = (int)attributes.SetUINT32(MFAttributesClsid.MF_LOW_LATENCY, 1); // Create the sink writer if (Succeeded(hr)) hr = (int)MFExtern.MFCreateSinkWriterFromURL(outputFile, null, attributes, out sinkWriter); // Create the output type if (Succeeded(hr)) hr = (int)MFExtern.MFCreateMediaType(out mediaTypeOut); if (Succeeded(hr)) hr = (int)mediaTypeOut.SetGUID(MFAttributesClsid.MF_MT_MAJOR_TYPE, MFMediaType.Video); if (Succeeded(hr)) hr = (int)mediaTypeOut.SetGUID(MFAttributesClsid.MF_TRANSCODE_CONTAINERTYPE, MFTranscodeContainerType.MPEG4); if (Succeeded(hr)) hr = (int)mediaTypeOut.SetGUID(MFAttributesClsid.MF_MT_SUBTYPE, MFMediaType.H264); if (Succeeded(hr)) hr = (int)mediaTypeOut.SetUINT32(MFAttributesClsid.MF_MT_AVG_BITRATE, videoBitRate); if (Succeeded(hr)) hr = (int)mediaTypeOut.SetUINT32(MFAttributesClsid.MF_MT_INTERLACE_MODE, (int)MFVideoInterlaceMode.Progressive); if (Succeeded(hr)) hr = (int)MFExtern.MFSetAttributeSize(mediaTypeOut, MFAttributesClsid.MF_MT_FRAME_SIZE, videoWidth, videoHeight); if (Succeeded(hr)) hr = (int)MFExtern.MFSetAttributeRatio(mediaTypeOut, MFAttributesClsid.MF_MT_FRAME_RATE, VIDEO_FPS, 1); if (Succeeded(hr)) hr = (int)MFExtern.MFSetAttributeRatio(mediaTypeOut, MFAttributesClsid.MF_MT_PIXEL_ASPECT_RATIO, 1, 1); if (Succeeded(hr)) hr = (int)sinkWriter.AddStream(mediaTypeOut, out streamIndex); // Create the input type if (Succeeded(hr)) hr = (int)MFExtern.MFCreateMediaType(out mediaTypeIn); if (Succeeded(hr)) hr = (int)mediaTypeIn.SetGUID(MFAttributesClsid.MF_MT_MAJOR_TYPE, MFMediaType.Video); if (Succeeded(hr)) hr = (int)mediaTypeIn.SetGUID(MFAttributesClsid.MF_MT_SUBTYPE, MFMediaType.RGB32); if (Succeeded(hr)) hr = (int)mediaTypeIn.SetUINT32(MFAttributesClsid.MF_MT_INTERLACE_MODE, (int)MFVideoInterlaceMode.Progressive); if (Succeeded(hr)) hr = (int)MFExtern.MFSetAttributeSize(mediaTypeIn, MFAttributesClsid.MF_MT_FRAME_SIZE, videoWidth, videoHeight); if (Succeeded(hr)) hr = (int)MFExtern.MFSetAttributeRatio(mediaTypeIn, MFAttributesClsid.MF_MT_FRAME_RATE, VIDEO_FPS, 1); if (Succeeded(hr)) hr = (int)MFExtern.MFSetAttributeRatio(mediaTypeIn, MFAttributesClsid.MF_MT_PIXEL_ASPECT_RATIO, 1, 1); if (Succeeded(hr)) hr = (int)sinkWriter.SetInputMediaType(streamIndex, mediaTypeIn, null); // Start accepting data if (Succeeded(hr)) hr = (int)sinkWriter.BeginWriting(); COMBase.SafeRelease(mediaTypeOut); COMBase.SafeRelease(mediaTypeIn); return hr; } IMFSample sample = null; IMFMediaBuffer buffer = null; IntPtr data = new IntPtr(); int bufferMaxLength; int bufferCurrentLength; int hr = (int)MFExtern.MFCreateMemoryBuffer(frameSizeBytes, out buffer); if (Succeeded(hr)) hr = (int)buffer.Lock(out data, out bufferMaxLength, out bufferCurrentLength); if (Succeeded(hr)) { hr = (int)MFExtern.MFCopyImage( data, // Destination buffer. videoWidth * BYTES_PER_PIXEL, // Destination stride. (IntPtr)(frame.frame.DataPointer + (videoHeight - 1) * frame.frame.RowPitch), // First row in source image. -frame.frame.RowPitch, // Source stride. videoWidth * BYTES_PER_PIXEL, // Destination stride. videoHeight // Image height in pixels ); } if (Succeeded(hr)) hr = (int)buffer.Unlock(); if (Succeeded(hr)) hr = (int)buffer.SetCurrentLength(frameSizeBytes); if (Succeeded(hr)) hr = (int)MFExtern.MFCreateSample(out sample); if (Succeeded(hr)) hr = (int)sample.AddBuffer(buffer); if (Succeeded(hr)) hr = (int)sample.SetSampleTime(frame.prevRecordingDuration); if (Succeeded(hr)) hr = (int)sample.SetSampleDuration((frame.recordDuration-frame.prevRecordingDuration)); if (Succeeded(hr)) hr = (int)sinkWriter.WriteSample(streamIndex, sample); COMBase.SafeRelease(sample); COMBase.SafeRelease(buffer);
这就是在sinkwriter上添加示例的方式C# 媒体基础H.264高CPU使用率 在媒体Foundation .NET中,我在CPU上写下了流的高CPU使用率。下面是我如何初始化sinkwriter的 private int InitializeSinkWriter(String outputFile, int videoWidth, int videoHeight) { IMFMediaType mediaTypeIn = null; IMFMediaType mediaTypeOut = null; IMFAttributes attributes = null; int hr = 0; if (Succeeded(hr)) hr = (int)MFExtern.MFCreateAttributes(out attributes, 1); if (Succeeded(hr)) hr = (int)attributes.SetUINT32(MFAttributesClsid.MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, 1); if (Succeeded(hr)) hr = (int)attributes.SetUINT32(MFAttributesClsid.MF_SINK_WRITER_DISABLE_THROTTLING, 1); if (Succeeded(hr)) hr = (int)attributes.SetUINT32(MFAttributesClsid.MF_LOW_LATENCY, 1); // Create the sink writer if (Succeeded(hr)) hr = (int)MFExtern.MFCreateSinkWriterFromURL(outputFile, null, attributes, out sinkWriter); // Create the output type if (Succeeded(hr)) hr = (int)MFExtern.MFCreateMediaType(out mediaTypeOut); if (Succeeded(hr)) hr = (int)mediaTypeOut.SetGUID(MFAttributesClsid.MF_MT_MAJOR_TYPE, MFMediaType.Video); if (Succeeded(hr)) hr = (int)mediaTypeOut.SetGUID(MFAttributesClsid.MF_TRANSCODE_CONTAINERTYPE, MFTranscodeContainerType.MPEG4); if (Succeeded(hr)) hr = (int)mediaTypeOut.SetGUID(MFAttributesClsid.MF_MT_SUBTYPE, MFMediaType.H264); if (Succeeded(hr)) hr = (int)mediaTypeOut.SetUINT32(MFAttributesClsid.MF_MT_AVG_BITRATE, videoBitRate); if (Succeeded(hr)) hr = (int)mediaTypeOut.SetUINT32(MFAttributesClsid.MF_MT_INTERLACE_MODE, (int)MFVideoInterlaceMode.Progressive); if (Succeeded(hr)) hr = (int)MFExtern.MFSetAttributeSize(mediaTypeOut, MFAttributesClsid.MF_MT_FRAME_SIZE, videoWidth, videoHeight); if (Succeeded(hr)) hr = (int)MFExtern.MFSetAttributeRatio(mediaTypeOut, MFAttributesClsid.MF_MT_FRAME_RATE, VIDEO_FPS, 1); if (Succeeded(hr)) hr = (int)MFExtern.MFSetAttributeRatio(mediaTypeOut, MFAttributesClsid.MF_MT_PIXEL_ASPECT_RATIO, 1, 1); if (Succeeded(hr)) hr = (int)sinkWriter.AddStream(mediaTypeOut, out streamIndex); // Create the input type if (Succeeded(hr)) hr = (int)MFExtern.MFCreateMediaType(out mediaTypeIn); if (Succeeded(hr)) hr = (int)mediaTypeIn.SetGUID(MFAttributesClsid.MF_MT_MAJOR_TYPE, MFMediaType.Video); if (Succeeded(hr)) hr = (int)mediaTypeIn.SetGUID(MFAttributesClsid.MF_MT_SUBTYPE, MFMediaType.RGB32); if (Succeeded(hr)) hr = (int)mediaTypeIn.SetUINT32(MFAttributesClsid.MF_MT_INTERLACE_MODE, (int)MFVideoInterlaceMode.Progressive); if (Succeeded(hr)) hr = (int)MFExtern.MFSetAttributeSize(mediaTypeIn, MFAttributesClsid.MF_MT_FRAME_SIZE, videoWidth, videoHeight); if (Succeeded(hr)) hr = (int)MFExtern.MFSetAttributeRatio(mediaTypeIn, MFAttributesClsid.MF_MT_FRAME_RATE, VIDEO_FPS, 1); if (Succeeded(hr)) hr = (int)MFExtern.MFSetAttributeRatio(mediaTypeIn, MFAttributesClsid.MF_MT_PIXEL_ASPECT_RATIO, 1, 1); if (Succeeded(hr)) hr = (int)sinkWriter.SetInputMediaType(streamIndex, mediaTypeIn, null); // Start accepting data if (Succeeded(hr)) hr = (int)sinkWriter.BeginWriting(); COMBase.SafeRelease(mediaTypeOut); COMBase.SafeRelease(mediaTypeIn); return hr; } IMFSample sample = null; IMFMediaBuffer buffer = null; IntPtr data = new IntPtr(); int bufferMaxLength; int bufferCurrentLength; int hr = (int)MFExtern.MFCreateMemoryBuffer(frameSizeBytes, out buffer); if (Succeeded(hr)) hr = (int)buffer.Lock(out data, out bufferMaxLength, out bufferCurrentLength); if (Succeeded(hr)) { hr = (int)MFExtern.MFCopyImage( data, // Destination buffer. videoWidth * BYTES_PER_PIXEL, // Destination stride. (IntPtr)(frame.frame.DataPointer + (videoHeight - 1) * frame.frame.RowPitch), // First row in source image. -frame.frame.RowPitch, // Source stride. videoWidth * BYTES_PER_PIXEL, // Destination stride. videoHeight // Image height in pixels ); } if (Succeeded(hr)) hr = (int)buffer.Unlock(); if (Succeeded(hr)) hr = (int)buffer.SetCurrentLength(frameSizeBytes); if (Succeeded(hr)) hr = (int)MFExtern.MFCreateSample(out sample); if (Succeeded(hr)) hr = (int)sample.AddBuffer(buffer); if (Succeeded(hr)) hr = (int)sample.SetSampleTime(frame.prevRecordingDuration); if (Succeeded(hr)) hr = (int)sample.SetSampleDuration((frame.recordDuration-frame.prevRecordingDuration)); if (Succeeded(hr)) hr = (int)sinkWriter.WriteSample(streamIndex, sample); COMBase.SafeRelease(sample); COMBase.SafeRelease(buffer);,c#,h.264,ms-media-foundation,hardware-acceleration,C#,H.264,Ms Media Foundation,Hardware Acceleration,这就是在sinkwriter上添加示例的方式 private int InitializeSinkWriter(String outputFile, int videoWidth, int videoHeight) { IMFMediaType mediaTypeIn = null; IMFMediaType mediaTypeOut = null; IMFAttributes attributes = null; int
private int InitializeSinkWriter(String outputFile, int videoWidth, int videoHeight)
{
IMFMediaType mediaTypeIn = null;
IMFMediaType mediaTypeOut = null;
IMFAttributes attributes = null;
int hr = 0;
if (Succeeded(hr)) hr = (int)MFExtern.MFCreateAttributes(out attributes, 1);
if (Succeeded(hr)) hr = (int)attributes.SetUINT32(MFAttributesClsid.MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, 1);
if (Succeeded(hr)) hr = (int)attributes.SetUINT32(MFAttributesClsid.MF_SINK_WRITER_DISABLE_THROTTLING, 1);
if (Succeeded(hr)) hr = (int)attributes.SetUINT32(MFAttributesClsid.MF_LOW_LATENCY, 1);
// Create the sink writer
if (Succeeded(hr)) hr = (int)MFExtern.MFCreateSinkWriterFromURL(outputFile, null, attributes, out sinkWriter);
// Create the output type
if (Succeeded(hr)) hr = (int)MFExtern.MFCreateMediaType(out mediaTypeOut);
if (Succeeded(hr)) hr = (int)mediaTypeOut.SetGUID(MFAttributesClsid.MF_MT_MAJOR_TYPE, MFMediaType.Video);
if (Succeeded(hr)) hr = (int)mediaTypeOut.SetGUID(MFAttributesClsid.MF_TRANSCODE_CONTAINERTYPE, MFTranscodeContainerType.MPEG4);
if (Succeeded(hr)) hr = (int)mediaTypeOut.SetGUID(MFAttributesClsid.MF_MT_SUBTYPE, MFMediaType.H264);
if (Succeeded(hr)) hr = (int)mediaTypeOut.SetUINT32(MFAttributesClsid.MF_MT_AVG_BITRATE, videoBitRate);
if (Succeeded(hr)) hr = (int)mediaTypeOut.SetUINT32(MFAttributesClsid.MF_MT_INTERLACE_MODE, (int)MFVideoInterlaceMode.Progressive);
if (Succeeded(hr)) hr = (int)MFExtern.MFSetAttributeSize(mediaTypeOut, MFAttributesClsid.MF_MT_FRAME_SIZE, videoWidth, videoHeight);
if (Succeeded(hr)) hr = (int)MFExtern.MFSetAttributeRatio(mediaTypeOut, MFAttributesClsid.MF_MT_FRAME_RATE, VIDEO_FPS, 1);
if (Succeeded(hr)) hr = (int)MFExtern.MFSetAttributeRatio(mediaTypeOut, MFAttributesClsid.MF_MT_PIXEL_ASPECT_RATIO, 1, 1);
if (Succeeded(hr)) hr = (int)sinkWriter.AddStream(mediaTypeOut, out streamIndex);
// Create the input type
if (Succeeded(hr)) hr = (int)MFExtern.MFCreateMediaType(out mediaTypeIn);
if (Succeeded(hr)) hr = (int)mediaTypeIn.SetGUID(MFAttributesClsid.MF_MT_MAJOR_TYPE, MFMediaType.Video);
if (Succeeded(hr)) hr = (int)mediaTypeIn.SetGUID(MFAttributesClsid.MF_MT_SUBTYPE, MFMediaType.RGB32);
if (Succeeded(hr)) hr = (int)mediaTypeIn.SetUINT32(MFAttributesClsid.MF_MT_INTERLACE_MODE, (int)MFVideoInterlaceMode.Progressive);
if (Succeeded(hr)) hr = (int)MFExtern.MFSetAttributeSize(mediaTypeIn, MFAttributesClsid.MF_MT_FRAME_SIZE, videoWidth, videoHeight);
if (Succeeded(hr)) hr = (int)MFExtern.MFSetAttributeRatio(mediaTypeIn, MFAttributesClsid.MF_MT_FRAME_RATE, VIDEO_FPS, 1);
if (Succeeded(hr)) hr = (int)MFExtern.MFSetAttributeRatio(mediaTypeIn, MFAttributesClsid.MF_MT_PIXEL_ASPECT_RATIO, 1, 1);
if (Succeeded(hr)) hr = (int)sinkWriter.SetInputMediaType(streamIndex, mediaTypeIn, null);
// Start accepting data
if (Succeeded(hr)) hr = (int)sinkWriter.BeginWriting();
COMBase.SafeRelease(mediaTypeOut);
COMBase.SafeRelease(mediaTypeIn);
return hr;
}
IMFSample sample = null;
IMFMediaBuffer buffer = null;
IntPtr data = new IntPtr();
int bufferMaxLength;
int bufferCurrentLength;
int hr = (int)MFExtern.MFCreateMemoryBuffer(frameSizeBytes, out buffer);
if (Succeeded(hr)) hr = (int)buffer.Lock(out data, out bufferMaxLength, out bufferCurrentLength);
if (Succeeded(hr))
{
hr = (int)MFExtern.MFCopyImage(
data, // Destination buffer.
videoWidth * BYTES_PER_PIXEL, // Destination stride.
(IntPtr)(frame.frame.DataPointer + (videoHeight - 1) * frame.frame.RowPitch), // First row in source image.
-frame.frame.RowPitch, // Source stride.
videoWidth * BYTES_PER_PIXEL, // Destination stride.
videoHeight // Image height in pixels
);
}
if (Succeeded(hr)) hr = (int)buffer.Unlock();
if (Succeeded(hr)) hr = (int)buffer.SetCurrentLength(frameSizeBytes);
if (Succeeded(hr)) hr = (int)MFExtern.MFCreateSample(out sample);
if (Succeeded(hr)) hr = (int)sample.AddBuffer(buffer);
if (Succeeded(hr)) hr = (int)sample.SetSampleTime(frame.prevRecordingDuration);
if (Succeeded(hr)) hr = (int)sample.SetSampleDuration((frame.recordDuration-frame.prevRecordingDuration));
if (Succeeded(hr)) hr = (int)sinkWriter.WriteSample(streamIndex, sample);
COMBase.SafeRelease(sample);
COMBase.SafeRelease(buffer);
当我注释掉if(succeed(hr))hr=(int)sinkWriter.WriteSample(streamIndex,sample)代码>
CPU只得到10%以下,但当我激活writesample时,它上升到50%。有人能帮我如何使用硬件编码吗?谢谢,我正在使用c#。您需要添加Direct3D 9或11纹理样本。由您创建或由IMFVideoSampleAllocator(Ex)分配。检查此项:是的,我正在为编写器提供directx纹理。我可以产生一个视频没有问题,除了高CPU使用率。我尝试将H.264更改为NV12,但我的输出文件变大,几乎达到1G,无法播放。不,您没有。您使用MFCreateMoryBuffer。嗨,对不起,我是DirectX编程新手。这是我在frame.frame varibale设备.ImmediateContext.MapSubresource上传递的内容(screenTexture,0,SharpDX.Direct3D11.MapMode.Read,SharpDX.Direct3D11.MapFlags.None);我也不知道该如何实施你的建议,因为这是我第一次使用这种应用程序。感谢幸运的是,MFCreateDXSurfaceBuffer在Mediafoundation.Net上不可用,该代码的包装器尚未实现。这方面有什么工作吗?