COPPQueryStatus 函数

示例 COPPQueryStatus 函数检索与 COPP DirectX VA 设备关联的受保护视频会话的状态。

语法

HRESULT COPPQueryStatus(
  _In_  COPP_DeviceData       pThis,
  _In_  DXVA_COPPStatusInput  *pInput,
  _Out_ DXVA_COPPStatusOutput *pOutput
);

参数

pThis [in]

  • 指向 COPP DirectX VA 设备对象的指针。

pInput [in]

  • 提供指向DXVA_COPPStatusInput结构的指针,该结构包含检索特定状态信息的请求。

pOutput [out]

  • 指向DXVA_COPPStatusOutput结构的指针,该结构接收有关正在使用的物理连接器的状态信息。

返回值

如果成功,则返回零 (S_OK 或DD_OK) ;否则,将返回错误代码。

注解

视频会话应设置为保护模式 (也就是说,在关联的 COPP DirectX VA 设备收到对其 COPPQueryStatus 函数的调用之前,视频会话应处于活动状态) 。 也就是说,应在 COPPQueryStatus 之前调用 COPPSequenceStart 函数。 如果在 COPPSequenceStart 之前调用 COPPQueryStatus,则 COPPQueryStatus 应返回E_UNEXPECTED。

COPPQueryStatus 函数在包含状态请求的 pInput 处接收填充DXVA_COPPStatusInput结构。 COPPQueryStatus 函数处理请求,并在 pOutput 的DXVA_COPPStatusOutput结构中返回适当的状态。

将 RenderMoComp 映射到 COPPQueryStatus

示例 COPPQueryStatus 函数直接映射到对 DD_MOTIONCOMPCALLBACKS 结构的 RenderMoComp 成员的调用。 RenderMoComp 成员指向引用 DD_RENDERMOCOMPDATA 结构的显示驱动程序提供的 DdMoCompRender 回调函数。

调用 RenderMoComp 回调函数时不首先调用显示驱动程序提供的 BeginMoCompFrame 或 EndMoCompFrame 函数。

填充DD_RENDERMOCOMPDATA结构如下所示。

成员 Value
dwNumBuffers Zero。
lpBufferInfo NULL。
dwFunction DXVA_COPPQueryStatusFnCode dxva.h) 中定义的常量 (。
lpInputData 指向DXVA_COPPStatusInput结构的指针。
lpOutputData 指向DXVA_COPPStatusOutput结构的指针。

示例代码

以下代码提供了如何实现 COPPQueryStatus 函数的示例:

HRESULT
COPPQueryStatus(
    COPP_DeviceData* pThis,
    DXVA_COPPStatusInput* pStatusInput,
    DXVA_COPPStatusOutput* pStatusOutput
    )
{
    if (pThis->m_COPPDevState != COPP_SESSION_ACTIVE) {
        return E_UNEXPECTED;
    }
    if (pStatusInput->dwSequence != pThis->m_StatusSeqNumber) {
        return E_INVALIDARG;
    }
    //
    // reset the output buffer
    //
    memset(pStatusOutput, 0, sizeof(DXVA_COPPStatusOutput));
    if (IsEqualGUID(&DXVA_COPPQueryConnectorType, &pStatusInput->guidStatusRequestID)) {
        // Verify no input data for this status request.
        if (pStatusInput->cbSizeData != 0) {
            return E_INVALIDARG;
        }
        DXVA_COPPStatusData Tmp;
        Tmp.rApp = pStatusInput->rApp;
        Tmp.dwData = g_ConnectorInfo[pThis->m_DevID].ConnType;
        Tmp.dwFlags = COPP_StatusNormal;
        pStatusOutput->cbSizeData = sizeof(Tmp);
        memcpy(pStatusOutput->COPPStatus, &Tmp,sizeof(Tmp));
    }
    else if (IsEqualGUID(&DXVA_COPPQueryProtectionType, &pStatusInput->guidStatusRequestID)) {
        // verify that there is no input data for this status request
        if (pStatusInput->cbSizeData != 0) {
            return E_INVALIDARG;
        }
        DXVA_COPPStatusData Tmp;
        Tmp.rApp = pStatusInput->rApp;
        Tmp.dwData = g_ConnectorInfo[pThis->m_DevID].ProtectionTypeMask;
        Tmp.dwFlags = COPP_StatusNormal;
        pStatusOutput->cbSizeData = sizeof(Tmp);
        memcpy(pStatusOutput->COPPStatus, &Tmp,sizeof(Tmp));
    }
    else if (IsEqualGUID(&DXVA_COPPQueryLocalProtectionLevel, &pStatusInput->guidStatusRequestID) ||
             IsEqualGUID(&DXVA_COPPQueryGlobalProtectionLevel, &pStatusInput->guidStatusRequestID)) {
        DWORD ProtType;
        DWORD ProtIndex;
        DWORD Level;
        // verify that there is a single DWORD input data for this status request
        if (pStatusInput->cbSizeData != sizeof (DWORD)) {
            return E_INVALIDARG;
        }
        memcpy(&ProtType, (LPVOID)&pStatusInput->StatusData[0], sizeof(DWORD));
        // verify that no invalid protection type bits are set
        if (ProtType & ~COPP_ProtectionType_Mask) {
            return E_INVALIDARG;
        }
        // verify that only the protection level of a single protection type is requested
        ProtIndex = MapProtectionTypeToProtectionIndex(ProtType);
        if (ProtIndex == COPP_ProtectionTypeIndex_Unkonwn) {
            return E_INVALIDARG;
        }
        // verify that the video session supports the protection type
        if (!(g_ConnectorInfo[pThis->m_DevID].ProtectionTypeMask & ProtType)) {
            return E_INVALIDARG;
        }
        if (IsEqualGUID(&DXVA_COPPQueryLocalProtectionLevel,
                        &pStatusInput->guidStatusRequestID)) {
            Level = pThis->m_LocalLevel[ProtIndex];
        }
        else {
            Level = g_nLevels[ProtIndex] - 1;
            for ( ; Level != 0; Level--) {
                if (g_COPPLevels[pThis->m_DevID].Levels[ProtIndex][Level]) {
                    break;
                }
            }
        }
        DXVA_COPPStatusData Tmp;
        Tmp.rApp = pStatusInput->rApp;
        Tmp.dwData = Level;
        Tmp.dwFlags = COPP_StatusNormal;
        pStatusOutput->cbSizeData = sizeof(Tmp);
        memcpy(pStatusOutput->COPPStatus, &Tmp, sizeof(Tmp));
    }
    pThis->m_StatusSeqNumber++;
    pStatusOutput->macKDI = COPP_CalculateMAC(&pThis->m_AesHelper,
                                    (BYTE*)&pStatusOutput->cbSizeData,
                         sizeof(DXVA_COPPStatusOutput) - sizeof(GUID),
                                     &pThis->m_KDI);
    return NO_ERROR;
}

要求

目标平台 版本
桌面 此函数仅适用于带有 SP1 及更高版本的 Windows Server 2003 以及 SP2 及更高版本的 Windows XP。