Megosztás a következőn keresztül:


Eseménykövetés a DirectShow-ban

[A laphoz társított funkció, DirectShowegy régi funkció. MediaPlayer, IMFMediaEngineés Audio/Video Capture a Media Foundation. Ezek a funkciók Windows 10-hez és Windows 11-hez lettek optimalizálva. A Microsoft határozottan javasolja, hogy az új kód MediaPlayer, IMFMediaEngine és Audio/Video Capture eszközt használja a Media FoundationDirectShowhelyett, ha lehetséges. A Microsoft javasolja, hogy az örökölt API-kat használó meglévő kódot át kell írni az új API-k használatára, ha lehetséges.]

A DirectShow támogatja a Windows (ETW) eseménykövetését, amely az eseménynaplók létrehozására használható a rendszerezéshez vagy a hibakereséshez. Az ETW-ről további információt a Windows SDK dokumentációjában talál. Ha ETW-eseményeket szeretne használni Egy DirectShow-alkalmazásban, engedélyeznie kell a nyomkövetést, majd fel kell dolgoznia a nyomkövetési eseményeket. Kövesse az alábbi lépéseket.

A szükséges beállításkulcsok beállítása

Ha engedélyezni szeretné a nyomkövetést a felhasználó számítógépén, először állítsa be a következő beállításkulcsokat:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\DirectX
    GlitchInstrumentation = 0x00000001 (REG_DWORD)
HKEY_LOCAL_MACHINE\SOFTWARE\DEBUG\Quartz.dll
    PERFLOG = 0x00000001 (REG_DWORD) 

Ezek a kulcsok a bináris fájlok kiadására és hibakeresésére egyaránt érvényesek.

Nyomkövetés engedélyezése az alkalmazásban

Ha engedélyezni szeretné a nyomkövetést az alkalmazásban, hajtsa végre a következő lépéseket:

  1. Új nyomkövetési munkamenet indításához hívja meg StartTrace.
  2. A nyomkövetés engedélyezéséhez hívja meg EnableTrace. A DirectShow szolgáltatói GUID azonosítója GUID_DSHOW_CTL.
  3. Mielőtt az alkalmazás kilép, hívja meg StopTrace a nyomkövetési munkamenet bezárásához.

Események feldolgozása

Az események feldolgozásához hajtsa végre a következő lépéseket:

  1. A nyomkövetés feldolgozásra való megnyitásához hívja meg OpenTrace.
  2. Az események feldolgozásához hívja meg ProcessTrace.
  3. A ProcessTrace visszahívásban az esemény GUID azonosítóját használva keresse meg az esemény típusát. Az esemény GUID azonosítója az eseményadatokhoz használt struktúrát jelzi. Lásd: nyomkövetési esemény grafikus azonosítói.
  4. A nyomkövetési leíró bezárásához hívja meg CloseTrace.

példakód

Az alábbi kód egy nyomkövetést lehetővé tevő segédosztályt mutat be. Ez a kód bemutatja, hogyan írhat eseményeket egy naplófájlba, amely a munkamenet befejezése után feldolgozható. Az eseményeket valós időben is feldolgozhatja. További információkért tekintse meg az ETW dokumentációját a Windows SDK-ban.

#include <wmistr.h>
#include <evntrace.h>
#include <perfstruct.h>

// Event classes. These are defined in dxmperf.h.
#ifndef DXMPERF_VIDEOREND
#define DXMPERF_VIDEOREND   0x00000001
#endif

#ifndef AUDIOBREAK_BIT
#define AUDIOBREAK_BIT      0x00000010
#endif

// This structure extends the EVENT_TRACE_PROPERTIES by adding fields
// for the name of the WMI session name and the log file.
struct PERFMON_LOGGERINFO
{
    EVENT_TRACE_PROPERTIES TraceProperties;
    WCHAR wcSessionName[ MAX_PATH ];    // Session name.
    WCHAR wcLogFileName[ MAX_PATH ];    // Log file.
};

// Helper class for DirectShow event tracing.
class CTrace
{
public:
    CTrace() : m_SessionLogger((TRACEHANDLE) INVALID_HANDLE_VALUE)
    {
        ZeroMemory(&m_LogInfo, sizeof(&m_LogInfo));
    }

    // Start: Starts a trace session.
    HRESULT Start(WCHAR *wszLogFile)
    {
        const WCHAR* wszSessionName = L"PerfMon_DirectShow"; 
        HRESULT hr = S_OK;
        ULONG result; 

        ZeroMemory(&m_LogInfo, sizeof(m_LogInfo));
        
        EVENT_TRACE_PROPERTIES& prop = m_LogInfo.TraceProperties;

        prop.Wnode.BufferSize = sizeof(m_LogInfo);  // Size of the structure.
        prop.Wnode.Flags = WNODE_FLAG_TRACED_GUID;  // Must be this value.

        // Use the QPC (high resolution timer).
        prop.Wnode.ClientContext = 1;        

        prop.Wnode.Guid = GUID_DSHOW_CTL;           // Event provider GUID.
        prop.LogFileMode = 
            EVENT_TRACE_FILE_MODE_CIRCULAR | EVENT_TRACE_USE_PAGED_MEMORY; 
        prop.EnableFlags = 
            EVENT_TRACE_FLAG_PROCESS;   // Process events.

        // Set the offset from the start of the structure to the log file name.
        prop.LogFileNameOffset = 
            sizeof(m_LogInfo.TraceProperties) + sizeof(m_LogInfo.wcSessionName);  

        // Set the offset from the start of the structure to the session name.
        prop.LoggerNameOffset = sizeof(m_LogInfo.TraceProperties); 

        // Copy the names into the structure.
        StringCchCopy(m_LogInfo.wcSessionName, MAX_PATH, wszSessionName);
        StringCchCopy(m_LogInfo.wcLogFileName, MAX_PATH, wszLogFile);

        // Start the trace.
        result = StartTrace(
            &m_SessionLogger, 
            m_LogInfo.wcSessionName, 
            &m_LogInfo.TraceProperties
            );

        if (result == ERROR_SUCCESS)
        {
            result = EnableTrace(
                TRUE,                                   // Enable.
                AUDIOBREAK_BIT | DXMPERF_VIDEOREND,     // Event classes.
                TRACE_LEVEL_VERBOSE,                    // Trace level.
                &GUID_DSHOW_CTL,                        // Event provider.
                m_SessionLogger                         // Session handle.
                );
        }
        if (result != ERROR_SUCCESS)
        { 
            hr = __HRESULT_FROM_WIN32(result);
        }
        return hr;
    }

    HRESULT Stop()
    {
        HRESULT hr = S_OK;

        // Stop the trace.
        if (m_SessionLogger != (TRACEHANDLE)INVALID_HANDLE_VALUE)
        {
            LONG result = 0;

            result = EnableTrace(FALSE, 0, 0, &GUID_DSHOW_CTL, m_SessionLogger);
            if (result == ERROR_SUCCESS)
            {
                result = StopTrace(
                    m_SessionLogger, 
                    m_LogInfo.wcSessionName, 
                    &m_LogInfo.TraceProperties);
            }

            m_SessionLogger = (TRACEHANDLE)INVALID_HANDLE_VALUE;
            if (result != ERROR_SUCCESS)
            { 
                hr = __HRESULT_FROM_WIN32(result);
            }
        }
        return hr;
    }

protected:
    TRACEHANDLE         m_SessionLogger;
    PERFMON_LOGGERINFO  m_LogInfo;
};

Az alábbi kód bemutatja, hogyan dolgozhatja fel az eseménynaplót:

// Callback for event processing.
VOID WINAPI EventCallback(PEVENT_TRACE pEvent)
{
    PERFINFO_DSHOW_STREAMTRACE  *pStreamTrace = NULL;
    PERFINFO_DSHOW_AVREND       *pVideoRender = NULL;
    PERFINFO_DSHOW_AUDIOBREAK   *pAudioBreak = NULL;

    if (pEvent->Header.Guid == GUID_STREAMTRACE) 
    {
        pStreamTrace = (PPERFINFO_DSHOW_STREAMTRACE)pEvent->MofData;

        switch (pStreamTrace->id)
        {
            // TODO: Handle the event.
        }
    }
    else if(pEvent->Header.Guid == GUID_VIDEOREND)
    {      
        pVideoRender = (PPERFINFO_DSHOW_AVREND)pEvent->MofData;
        // TODO: Handle the event.
    }
    else if(pEvent->Header.Guid == GUID_AUDIOBREAK)
    {
        pAudioBreak = (PPERFINFO_DSHOW_AUDIOBREAK)pEvent->MofData;
        // TODO: Handle the event.
    }
}

void ProcessTraceEvents(WCHAR *wszLogFile)
{
    ULONG result = 0;        
    EVENT_TRACE_LOGFILE logfile;

    ZeroMemory(&logfile, sizeof(logfile));
    logfile.LogFileName = wszLogFile;
    logfile.EventCallback  = EventCallback;   

    TRACEHANDLE handle = OpenTrace(&logfile);
    if (handle != (TRACEHANDLE)INVALID_HANDLE_VALUE)
    {
        result = ProcessTrace(&handle, 1, NULL, NULL);
        CloseTrace(handle);
    }
}

Hibakeresés a DirectShow