小编Ram*_*san的帖子

桌面复制(DirectX)屏幕捕获无法提供屏幕更新

我正在开发一个应用程序,它将通过桌面复制API(使用DirectX 11)捕获屏幕(仅对前一个屏幕更新的差异)并在另一个窗口上呈现它(查看器可能在通过LAN连接的另一台机器上运行) .该代码是MSDN中提供的示例的改进版本.一切正常,除了设备没有给出任何屏幕更新,虽然在中间有一次,大约10%的时间在一些机器上发生(大多数在Windows 8/8.1机器上,很少在Windows 10机器上).我尝试了所有可能的方法来解决这个问题.减少了设备重置的次数,这为我提供了一些可靠的输出,但并不总能正常工作100%.

设备有时无法提供初始屏幕(全屏)(这种情况在所有支持桌面复制的Windows操作系统上有60%的时间发生),我想出了一个可以重新进行初步更新的工作.设备,直到它提供一个,但也导致多个问题,设备可能甚至不提供初始屏幕.

我已经投入了数周的时间来解决这个问题,但没有找到合适的解决方案,而且我所知道的论坛没有讨论这些问题.任何帮助,将不胜感激.

下面是我的代码,以获得前一个屏幕差异,初始化设备,填充适配器和监视器.

请耐心等待一段很长的代码片段,在此先感谢.

要获取屏幕更新:

INT getChangedRegions(int timeout, rectangles &dirtyRects, std::vector <MOVE_RECT> &moveRects, UINT &rect_count, RECT ScreenRect)
{
UINT diffArea           = 0;
FRAME_DATA currentFrameData;

bool isTimeOut          = false;

TRY
{

    m_LastErrorCode = m_DuplicationManager.GetFrame(&currentFrameData, timeout, &isTimeOut);

    if(SUCCEEDED(m_LastErrorCode) && (!isTimeOut))
    {
        if(currentFrameData.FrameInfo.TotalMetadataBufferSize)
        {

            m_CurrentFrameTexture = currentFrameData.Frame;

            if(currentFrameData.MoveCount)
            {
                DXGI_OUTDUPL_MOVE_RECT* moveRectArray = reinterpret_cast<DXGI_OUTDUPL_MOVE_RECT*> (currentFrameData.MetaData);

                if (moveRectArray)
                {
                    for(UINT index = 0; index < currentFrameData.MoveCount; index++)
                    {
                        //WebRTC
                        // DirectX capturer API may randomly return unmoved move_rects, …
Run Code Online (Sandbox Code Playgroud)

directx-11 visual-c++ dxgi webrtc desktop-duplication

18
推荐指数
1
解决办法
1453
查看次数

Windows Media Foundation MFT缓冲和视频质量问题(颜色丢失,而不是平滑的曲线,尤其是文本)

我正在尝试使用Windows Media Foundation将从图像(RGBA)源(桌面/相机)捕获的RGBA缓冲区编码为原始H264,传输它们并实时解码在另一端接收的原始H264帧。我正在尝试至少达到30 fps。编码器工作得很好,但解码器却不能。

我了解Microsoft WMF MFT在发出编码/解码数据之前最多缓冲30帧。

图像源仅在发生变化时才会发出帧,而不是连续的RGBA缓冲区流,因此,我的目的是为每个MFT的每个输入缓冲区获得一个编码/解码数据的缓冲区,以便我可以流式传输实时数据并进行渲染。

当我使图像源发送连续更改(通过刺激更改)时,编码器和解码器均能够发出至少10到15 fps的帧。编码器能够利用硬件加速支持。我能够在编码器端达到30 fps,并且还没有使用DirectX表面实现硬件辅助解码。这里的问题不是帧速率,而是MFT对数据的缓冲。

因此,我尝试通过发送MFT_MESSAGE_COMMAND_DRAIN命令并反复调用ProcessOutput直到解码器返回MF_E_TRANSFORM_NEED_MORE_INPUT来消耗解码器MFT 。现在发生的事情是,解码器现在每30个输入h264缓冲区仅发出一帧,我甚至用连续的数据流对其进行了测试,其行为是相同的。好像解码器将所有中间帧都丢弃在GOP中。

如果只缓冲前几个帧,这对我来说是可以的,但是即使在SPS和PPS解析阶段之后,我的解码器实现也仅在其缓冲区一直充满时才输出。

我遇到了Google的铬源代码(https://github.com/adobe/chromium/blob/master/content/common/gpu/media/dxva_video_decode_accelerator.cc),它们遵循相同的方法。

mpDecoder->ProcessMessage(MFT_MESSAGE_COMMAND_DRAIN, NULL);
Run Code Online (Sandbox Code Playgroud)

我的实现基于 https://github.com/GameTechDev/ChatHeads/blob/master/VideoStreaming/EncodeTransform.cpp

https://github.com/GameTechDev/ChatHeads/blob/master/VideoStreaming/DecodeTransform.cpp

我的问题是,我想念什么吗?Windows Media Foundation是否适合实时流?排干编码器和解码器是否适用于实时用例?

对于我来说,只有两个选择,使此WMF可以作为实时用例工作,或者与Intel的QuickSync等一起使用。我选择WMF作为我的POC,因为在任何MFT不可用的情况下Windows Media Foundation隐式支持硬件/ GPU /软件后备,并且在内部无需太多编码即可选择最佳的MFT。

我遇到了视频质量问题,尽管bitrate属性设置为3Mbps。但是与缓冲问题相比,它的优先级最低。数周来,我一直在敲打键盘,这很难修复。任何帮助,将不胜感激。

码:

编码器设置:

IMFAttributes* attributes = 0;
    HRESULT  hr = MFCreateAttributes(&attributes, 0);

    if (attributes)
    {
        //attributes->SetUINT32(MF_SINK_WRITER_DISABLE_THROTTLING, TRUE);
        attributes->SetGUID(MF_TRANSCODE_CONTAINERTYPE, MFTranscodeContainerType_MPEG4);
    }//end if (attributes)

    hr = MFCreateMediaType(&pMediaTypeOut);
    // Set the output media type.
    if (SUCCEEDED(hr))
    {
        hr = MFCreateMediaType(&pMediaTypeOut);
    }
    if (SUCCEEDED(hr))
    {
        hr = pMediaTypeOut->SetGUID(MF_MT_MAJOR_TYPE, …
Run Code Online (Sandbox Code Playgroud)

c++ directx video-streaming h.264 ms-media-foundation

9
推荐指数
1
解决办法
949
查看次数

ffplay中出现绿屏:使用Live555通过RTP流将桌面(DirectX表面)作为H264视频流

我正在尝试使用Windows10上的Live555和Windows Media Foundation的硬件编码器通过RTP流将桌面(NV12格式的DirectX表面)流化为H264视频,并期望由ffplay(ffmpeg 4.2)渲染。但是只有如下所示的绿屏,

在此处输入图片说明

在此处输入图片说明

在此处输入图片说明

在此处输入图片说明

使用硬件MFT引用了MFWebCamToRTP mediafoundation-sampleEncoding DirectX表面,以实现live555的FramedSource并将输入源更改为DirectX表面而不是webCam。

这是我的Live555的doGetNextFrame回调实现的摘录,以从directX表面提供输入样本:

virtual void doGetNextFrame()
{
    if (!_isInitialised)
    {
        if (!initialise()) {
            printf("Video device initialisation failed, stopping.");
            return;
        }
        else {
            _isInitialised = true;
        }
    }

    //if (!isCurrentlyAwaitingData()) return;

    DWORD processOutputStatus = 0;
    HRESULT mftProcessOutput = S_OK;
    MFT_OUTPUT_STREAM_INFO StreamInfo;
    IMFMediaBuffer *pBuffer = NULL;
    IMFSample *mftOutSample = NULL;
    DWORD mftOutFlags;
    bool frameSent = false;
    bool bTimeout = false;

    // Create sample
    CComPtr<IMFSample> videoSample = NULL;

    // Create buffer
    CComPtr<IMFMediaBuffer> …
Run Code Online (Sandbox Code Playgroud)

directx ffmpeg video-streaming h.264 ms-media-foundation

9
推荐指数
1
解决办法
311
查看次数

提供少量输入样本后,英特尔图形硬件H264 MFT ProcessInput调用失败,在Nvidia硬件MFT上也可以正常工作

我正在使用DesktopDuplication API捕获桌面,并将示例从RGBA转换为GPU中的NV12,并将其提供给MediaFoundation硬件H264 MFT。这在Nvidia图形以及软件编码器上都可以正常工作,但是在只有Intel图形硬件MFT可用时失败。如果我退回到Software MFT,该代码在同一台Intel图形计算机上也可以正常工作。我还确保了编码实际上是在Nvidia图形计算机上的硬件中完成的。

在Intel图形上,MFT返回MEError(“未指定错误”),仅在馈入第一个样本后才发生,随后对ProcessInput的调用(当事件生成器触发METransformNeedInput时)返回“被调用方当前不接受进一步的输入”。MFT很少会在返回这些错误之前消耗更多的样本。这种行为令人困惑,仅当事件生成器通过IMFAsyncCallback异步触发METransformNeedInput时,我才提供示例,并且还应检查提供示例后是否立即触发METransformHaveOutput。当相同的异步逻辑与Nvidia硬件MFT和Microsoft软件编码器一起正常工作时,这真让我感到困惑。

英特尔论坛本身也有一个类似的未解决问题。我的代码类似于intel线程中提到的代码,除了我还将d3d设备管理器设置为如下所示的编码器这一事实。

并且,还有其他三个堆栈溢出线程报告了类似的问题,但没有给出解决方案(MFTransform编码器-> ProcessInput返回E_FAIL如何从D11纹理为Intel MFT编码器创建IMFSample异步MFT没有发送MFTransformHaveOutput事件(Intel硬件MJPEG解码器MFT))。我尝试了所有可能的选择,对此没有任何改进。

颜色转换器代码取自intel media sdk示例。我也在这里上传了完整的代码。

设置d3d管理器的方法:

void SetD3dManager() {

    HRESULT hr = S_OK;

    if (!deviceManager) {

        // Create device manager
        hr = MFCreateDXGIDeviceManager(&resetToken, &deviceManager);
    }

    if (SUCCEEDED(hr)) 
    {
        if (!pD3dDevice) {

            pD3dDevice = GetDeviceDirect3D(0);
        }
    }

    if (pD3dDevice) {

        // NOTE: Getting ready for multi-threaded operation
        const CComQIPtr<ID3D10Multithread> pMultithread = pD3dDevice;
        pMultithread->SetMultithreadProtected(TRUE);

        hr = deviceManager->ResetDevice(pD3dDevice, resetToken);
        CHECK_HR(_pTransform->ProcessMessage(MFT_MESSAGE_SET_D3D_MANAGER, reinterpret_cast<ULONG_PTR>(deviceManager.p)), …
Run Code Online (Sandbox Code Playgroud)

directx video-streaming h.264 hardware-acceleration ms-media-foundation

9
推荐指数
1
解决办法
249
查看次数

使用DirectX11像素着色器将颜色从DXGI_FORMAT_B8G8R8A8_UNORM转换为GPU中的NV12

我正在编写一个代码,以使用桌面复制捕获桌面,并使用英特尔hardwareMFT将其编码为h264。编码器仅接受NV12格式作为输入。我有一个DXGI_FORMAT_B8G8R8A8_UNORM到NV12转换器(https://github.com/NVIDIA/video-sdk-samples/blob/master/nvEncDXGIOutputDuplicationSample/Preproc.cpp)可以正常工作,并且基于DirectX VideoProcessor。

问题是某些英特尔图形硬件上的VideoProcessor仅支持从DXGI_FORMAT_B8G8R8A8_UNORM到YUY2的转换,但不支持NV12的转换,我已经通过GetVideoProcessorOutputFormats枚举支持的格式来确认了相同的转换。尽管VideoProcessor Blt成功实现,没有任何错误,而且我可以看到输出视频中的帧有些像素化,但是如果仔细观察它,我会注意到它。

我猜想,VideoProcessor只是故障转移到了下一个受支持的输出格式(YUY2),而我在不知不觉中将其馈送到认为输入已按照配置在NV12中的编码器。NV12和YUY2之间几乎没有像字节顺序和子采样之类的差异,因此不会出现帧故障或严重损坏的情况。另外,在支持NV12转换的硬件上我也没有像素化问题。

所以我决定使用基于此代码的像素着色器进行颜色转换(https://github.com/bavulapati/DXGICaptureDXColorSpaceConversionIntelEncode/blob/master/DXGICaptureDXColorSpaceConversionIntelEncode/DuplicationManager.cpp)。我能够使像素着色器正常工作,我也已经在这里上传了我的代码(https://codeshare.io/5PJjxP)供参考(尽可能简化了它)。

现在,我剩下两个通道,分别是色度和亮度(ID3D11Texture2D纹理)。对于将两个独立的通道有效地打包到一个ID3D11Texture2D纹理中,以便将其提供给编码器,我确实感到困惑。有没有一种方法可以将Y和UV通道有效地打包到GPU中的单个ID3D11Texture2D中?我非常厌倦基于CPU的方法,因为它价格昂贵,并且无法提供最佳的帧速率。实际上,我什至不愿意将纹理复制到CPU。我正在考虑一种在GPU中执行此操作的方法,而无需在CPU和GPU之间来回复制。

我已经对此进行了相当长时间的研究,没有任何进展,我们将不胜感激。

/**
* This method is incomplete. It's just a template of what I want to achieve.
*/

HRESULT CreateNV12TextureFromLumaAndChromaSurface(ID3D11Texture2D** pOutputTexture)
{
    HRESULT hr = S_OK;

    try
    {
        //Copying from GPU to CPU. Bad :(
        m_pD3D11DeviceContext->CopyResource(m_CPUAccessibleLuminanceSurf, m_LuminanceSurf);

        D3D11_MAPPED_SUBRESOURCE resource;
        UINT subresource = D3D11CalcSubresource(0, 0, 0);

        HRESULT hr = m_pD3D11DeviceContext->Map(m_CPUAccessibleLuminanceSurf, subresource, D3D11_MAP_READ, 0, &resource);

        BYTE* sptr = reinterpret_cast<BYTE*>(resource.pData);
        BYTE* dptrY = nullptr; // point to the address of …
Run Code Online (Sandbox Code Playgroud)

directx yuv directx-11 pixel-shader ms-media-foundation

8
推荐指数
1
解决办法
95
查看次数

Python:Django TypeError:object()不带参数

我正在将一个django应用程序从1.x移植到2.1,并且遇到了错误,即"TypeError:object()不带参数".我试图解决这个问题很长一段时间,但即使经过数天的调试和在线搜索,也没有得到任何线索

已安装的应用:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.sites',
    'allauth',
    'allauth.account',
    'allauth.socialaccount',
    'allauth.socialaccount.providers.github',
    'timezone_field',
    'axes',
    'humans',
    'boxes',
    'pages',
]
Run Code Online (Sandbox Code Playgroud)

中间件设置:

MIDDLEWARE = [
    'whitenoise.middleware.WhiteNoiseMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.locale.LocaleMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'django.middleware.security.SecurityMiddleware',
]
Run Code Online (Sandbox Code Playgroud)

压痕没有问题,

芹菜版:4.2.1
乌鸦版:6.9.0
django版:2.1

这是我的wsgi.py

import os
from raven.contrib.django.raven_compat.middleware.wsgi import Sentry

from django.core.wsgi import get_wsgi_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings")
application=Sentry(get_wsgi_application())
Run Code Online (Sandbox Code Playgroud)

以下是错误日志的摘录

File "/usr/lib/python3.5/importlib/__init__.py", line 126, in import_module
        return _bootstrap._gcd_import(name[level:], package, level)   
File "<frozen importlib._bootstrap>", line 986, in _gcd_import   
File "<frozen importlib._bootstrap>", line 969, in _find_and_load   
File …
Run Code Online (Sandbox Code Playgroud)

python django python-3.x django-rest-framework python-3.5

7
推荐指数
1
解决办法
2189
查看次数

与Nvidia相比,Intel H264硬件MFT性能较差

我正在尝试使用Windows10机器上的MediaFoundation H264硬件编码器将NV12样本编码为视频,并在LAN内实时传输和呈现它们。

最初,我在编码器处面临太多缓冲,因为编码器在提供输出样本之前最多缓冲25帧(GOP大小)。经过一些研究,我发现设置CODECAPI_AVLowLatencyMode可以减少延迟,但要花一些质量和带宽。

设置CODECAPI_AVLowLatencyMode属性有点改善了性能,但没有达到实时要求。现在看来,编码器至少在生成样本之前仍至少缓冲15帧(在输出中引入大约2秒钟的延迟)。并且仅当配置了低帧速率时,此行为才明显。在60FPS时,输出几乎是实时的,没有视觉上明显的延迟。

实际上,只有当帧频设置为低于30FPS时,人眼才能看到缓冲。并且,延迟与FPS配置成反比增加,在25FPS时,延迟在几百毫秒内,而当FPS配置为10(恒定速率)时,延迟增加到3秒。我猜想,将FPS设置为大于30(说60FPS)实际上会导致编码器缓冲区足够快地溢出,以产生明显延迟的采样。

但是问题是,如果需要,我希望FPS可以配置为低至10FPS(恒定速率),同时由于我的输入源是台式机并且仅在有台式机的情况下才产生样本,因此还具有实时流式传输的经验。屏幕内容有变化吗?

我的实验:

为了保持恒定的帧速率,并强制编码器产生实时输出,我以30FPS / 60FPS的恒定速率将相同的样本(以前保存的样本)馈送到编码器。我这样做的方式是,最多只能捕获10FPS(或任何所需的FPS),并通过以相同的三次或完全基于EMULATED_FRAME_RATE / ACTUAL_FRAME_RATE的比率(例如:30 / 10、60 / 15)提供相同的样本来伪造30 / 60FPS (例如60/20)以完全恒定的间隔填充空白。例如,如果10秒钟内没有任何变化,我将给编码器提供30 * 10次(30FPS)的相同样本。这将产生近乎实时的输出,但消耗的数据却比我预期的要多,即使我仅将先前保存的样本馈入编码器。

无论屏幕内容以30FPS还是0F​​PS更改,在Intel上,输出比特率似乎一直保持在350KBps至500KBps之间,而在NVidia GTX 1070(具有30FPS和500KB比特率配置)上,输出比特率一直在80KBps至400KBps之间变化。NVidia编码器似乎要好一些。

实际上,编码器消耗的带宽超过了上述带宽。通过设置更大的GOP大小(当前配置的GOP大小为16K),我已经能够减少NVidia机器上的数据消耗。但是,在具有“ 500KB比特率和30FPS”配置的NVidia GTX 1070上,数据消耗在Intel图形620硬件上大约保持300KBps,在NVidia GTX 1070上从50KBps到80KBps,输入样本之间几秒钟没有发生任何变化(我猜英特尔硬件不是完全遵守GOP设置,否则改进不明显)。

通过设置非常低的比特率,我还能够将Intel和Nvidia硬件上的数据消耗分别降低到100KBps和40KBps(当屏幕内容没有变化时),但这仍然是不可接受的,并且还会降低视频质量。

当样本之间没有变化时,是否可以将编码器配置为产生小于10KBps的输出?当没有变化但10KBps可以接受时,我实际上的目标是0KB输出。

更新: 我做了很多尝试。我想,无论是否发生了变化,NVidia编码器仍会产生某种额外的信息或其他信息,从而导致高数据消耗,但比英特尔好几个数量级。我完全不知道可能会有什么额外的数据。并且还认为Intel编码器根本不遵守GOP设置或不擅长压缩,我什至尝试将GOP在256到INT_MAX之间进行更改,似乎在Intel硬件上没有任何改变。

这是Microsoft网站(https://docs.microsoft.com/zh-cn/windows/win32/medfound/codecapi-avlowlatencymode)上的CODECAPI_AVLowLatencyMode的描述

“低延迟模式对于实时通信或实时捕获很有用,应将延迟最小化。但是,低延迟模式也可能会降低解码或编码质量。

由于编码过程中的帧重新排序,预计编码器不会增加任何采样延迟,并且一个输入采样将产生一个输出采样。只要没有在编码器中引入任何帧重新排序,就可以存在B条/帧。”

但是,这不能提供所描述的实时性能。

最近,我还尝试了CODECAPI_AVEncCommonRealTime属性(https://docs.microsoft.com/en-us/windows/win32/directshow/avenccommonrealtime-property)来检查它在降低输入帧速率以避免带宽消耗时是否提高了性能。 ,但该调用失败,并显示 “参数不正确”错误。

编码器配置:

参考:http//alax.info/blog/1586

const int EMULATED_FRAME_RATE = 30;//
const int TARGET_FPS = 10;
const int FPS_DENOMINATOR = 1;
const unsigned long long time_between_capture = 1000 / TARGET_FPS;
const unsigned long …
Run Code Online (Sandbox Code Playgroud)

c++ windows directx video-streaming ms-media-foundation

7
推荐指数
1
解决办法
146
查看次数

桌面复制屏幕捕获 - DuplicateOutput返回E_ACCESSDENIED错误

我正在使用桌面复制API(DirectX11)捕获屏幕.DuplicateOutput API返回访问被拒绝的错误,并且在登录屏幕上的Windows 8.1计算机上发生的情况非常罕见(可能是10%),尽管我的应用程序正在以SYSTEM级别权限运行并正确调用SetThreadDesktop.我曾经在我收到的每一个错误之后重置并调用SetThreadDesktop,但是即使在多个设备重置和启动之后,应用程序也无法从错误中恢复.在多次重试或重新启动应用程序后,我不得不回退到GDI(应用程序在从directx切换到GDI之后工作正常),但这个想法似乎很糟糕.

注意:我确实在Windows 10/Windows 8计算机上遇到了同样的问题,但与特定的Windows 8.1计算机相比并不常见.

这里是E_ACCESSDENIED错误的描述,该错误仅告知此错误可能的情况(没有系统级权限或SetThreadDesktop未被正确调用).我尝试了所有可能的方法来找出问题,但不能.

任何帮助将不胜感激,提前致谢.

以下是初始化设备的代码:

    //
// Initialize duplication interfaces
//
HRESULT cDuplicationManager::InitDupl(_In_ ID3D11Device* Device, _In_ IDXGIAdapter *_pAdapter, _In_ IDXGIOutput *_pOutput, _In_ UINT Output)
{
    HRESULT hr = E_FAIL;

    if(!_pOutput || !_pAdapter || !Device)
    {
        return hr;
    }

    m_OutputNumber = Output;

    // Take a reference on the device
    m_Device = Device;
    m_Device->AddRef();

    _pOutput->GetDesc(&m_OutputDesc);
     // QI for Output 1
    IDXGIOutput1* DxgiOutput1 = nullptr;
    hr = _pOutput->QueryInterface(__uuidof(DxgiOutput1), reinterpret_cast<void**>(&DxgiOutput1));

    if (FAILED(hr))
    {
        return ProcessFailure(nullptr, _T("Failed to QI …
Run Code Online (Sandbox Code Playgroud)

screen-capture directx-11 visual-c++ dxgi desktop-duplication

6
推荐指数
0
解决办法
595
查看次数

MediaFoundation SinkWriter:启用 MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS 会导致 WriteSample 失败并出现 E_FAIL 错误

我正在尝试将 RGB/NV12 样本编码为 h264,并通过实现 IMFByteStream 通过 SinkWriter 通过 WebSocket 流式传输编码的视频。在这个实验中,我使用像素着色器将 RGB32 样本转换为 NV12 样本。输出格式为带有 FMPEG4 容器的 H264。

我也尝试过直接输入 RGB 样本。通过软件方法它对 RGB 和 NV12 样本都可以正常工作,但是当取消注释下面提到的行时,WriteSample 失败并出现 E_FAIL 错误。不过,我正在正确设置 MF_SINK_WRITER_D3D_MANAGER。

COM_CHECK(attribs->SetUINT32(MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, TRUE));
Run Code Online (Sandbox Code Playgroud)

MFtrace 日志:

59980,EB60 10:18:27.65002 ### Exiting: traced process has exited
CMFPlatExportDetours::MFStartup @ Version=0x00020070, dwFlags=0x00000000
59980,EB60 10:18:27.65448 COle32ExportDetours::CoCreateInstance @ Created {60F9F51E-4613-4B35-AE88-332542B567B8} MF Fragmented MPEG4 Sink Class Factory (C:\WINDOWS\System32\mfmp4srcsnk.dll) @04B80148 - traced interfaces:
59980,EB60 10:18:27.65700 COle32ExportDetours::CoCreateInstance @ Created {9A02E012-6303-4E1E-B9A1-630F802592C5} Packed Property Storage Object (C:\WINDOWS\system32\propsys.dll) @012D5FEC - traced interfaces:
59980,EB60 10:18:27.65931 COle32ExportDetours::CoCreateInstance @ …
Run Code Online (Sandbox Code Playgroud)

directx mpeg h.264 ms-media-foundation

6
推荐指数
0
解决办法
352
查看次数

OpenSSL SSL_read失败(错误:00000005:lib(0):func(0):DH lib)

我正在使用OpenSSL版本1.1.0f来加密我的客户端和我没有任何访问权限的中继服务器之间的连接.有时客户端的连接会因客户端的readLine故障而突然终止.

这是错误代码:

readLine:readString返回-1,错误消息 - 错误:00000005:lib(0):func(0):DH lib

我确实搜索了这种错误代码的适当原因,每个人(例如线程)都说在连接建立期间似乎存在Diffie-Helman密钥交换的问题.但连接正常几分钟(有时可能甚至不会发生,并且可能在连接成功2到3分钟后经常发生一次),直到它突然终止.

以下是我的日志中的一些错误

SSL_read失败,错误 - 5,字节收到-1,错误字符串错误:00000005:lib(0):func(0):DH lib,wsaError 0

SSL错误 - 5:错误:FFFFFFFF:lib(255):func(4095):reason(4095)

这是来自SSL客户端的套接字读取代码

if ((isSecureMode() == true) && (lpSSL != NULL))
{
    bytesReceived = SSL_read(lpSSL, receiveBuf, bufferSize) ;

    if ((bytesReceived <= 0))
    {
        int sslErrorCode = lpSSL ? SSL_get_error(lpSSL, bytesReceived) : -1;

        char sslErrorString[MAX_ERROR_MSG_LEN] = {'\0'};

        ERR_error_string(sslErrorCode, sslErrorString);
        setLastError(sslErrorCode, std::string(sslErrorString));

        int wsaError = WSAGetLastError();

        if(isShutdownInitiated == false)
        {
            if (Logger)
            {
                Logger->log(LOG_WARNING, "receiveString - SSL_read failed with error - %d, bytes received %d, error …
Run Code Online (Sandbox Code Playgroud)

c++ windows ssl openssl tcp

5
推荐指数
1
解决办法
3608
查看次数

从 RDP 会话上运行的应用程序检测快速用户切换事件(RDP 窗口最小化)

我正在开发一个记录屏幕的应用程序,它应该支持终端服务,问题实际上是当 RDP 窗口最小化时,用户会话进入无 UI 模式,并且在该应用程序上运行的应用程序无法捕获屏幕特定会议。

\n\n

有一种方法可以通过设置注册表值来保留 UI 来处理此问题,如此处所述

\n\n

但我不想这样做,并且想捕获 UI less 模式状态并向用户显示一条消息,表明 RDP 窗口已最小化/已发生快速用户切换并且录制已暂停。

\n\n

因此,我决定枚举活动会话并检查用户会话是否空闲或 UI less。但这没有帮助。在几乎花了一天时间后,我没有找到任何关于在 RDP 窗口最小化时检测快速用户切换的线索。

\n\n

我找不到任何可以调用的事件或 API,以确保屏幕捕获因快速用户切换/最小化 RDP 窗口而失败。

\n\n

这是我的代码,

\n\n
bool bActive = false;\n\n{\n    DWORD dwCurrentProcessSessionID = 0;\n\n    ProcessIdToSessionId(GetCurrentProcessId(), &dwCurrentProcessSessionID);\n\n    PWTS_SESSION_INFO pSessionInfo = 0;\n    DWORD dwCount = 0;\n\n    // Get the list of all terminal sessions    \n    WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &pSessionInfo, &dwCount);\n\n    int dataSize = sizeof(WTS_SESSION_INFO);\n\n    // look over obtained list in search of the active session\n    for …
Run Code Online (Sandbox Code Playgroud)

rdp remote-desktop gdi screen-capture visual-c++

5
推荐指数
0
解决办法
260
查看次数

媒体基金会:英特尔硬件MFT的SPS / PPS问题

我使用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 …

rtp video-streaming mft live555 ms-media-foundation

5
推荐指数
1
解决办法
43
查看次数

MediaFoundation:注册自定义 ClassFactory 不起作用

背景: 我正在使用 SinkWriter 将 NV12 缓冲区编码为包装在 MPEG4 容器中的 h264 视频流。一切正常,但有一个问题,因为 SinkWriter 抽象了低级编码器配置,我无法控制 GOP 大小、B 画面计数、CODECAPI_AVEncCommonRateControlMode 等属性。

问题是因为SinkWriter仅在SetInputMediaType调用之后实例化编码器转换,并且只有在该点之后我们才能获得CodecAPI实例。因此,在这一切发生之前,我们无法控制编码器并配置必要的道具,它也永远不会通过 CodecAPI 实例对编码器进行进一步更改。

实验: 我尝试了 PropertyStore( MF_SINK_WRITER_ENCODER_CONFIG ) 方法,但似乎没有任何变化(这可能是平台/编码器特定的行为),我还看到很多人抱怨这些 API 的不可预测行为。然后,我遇到了这个MSDN 线程(将近 7 年前的帖子),其中用户描述了他如何通过在 Windows7 机器上本地注册自定义类工厂来处理这个问题。

问题:在MSDN线程作为参考,我想实现的IClassFactory并通过注册它MFTRegisterLocal但功能的CreateInstance永远不会得到所谓的对我(的Windows 10的机器)。我只得到为 IID_IClassFactory 和 IID_IMFAttributes 接口调用的 QueryInterface 方法。而且,SinkWriter 似乎正在自行获取 MFT。

我知道我可能做错了什么,而且我不是 COM 专家。有没有其他方法可以实现这一目标?

自定义类工厂实现:

class MyClassFactory : public IClassFactory  {

public:
MyClassFactory () : _cRef(1) {}

~MyClassFactory() {}

// Only this method is getting called …
Run Code Online (Sandbox Code Playgroud)

mpeg video-encoding h.264 ms-media-foundation

5
推荐指数
1
解决办法
134
查看次数