COPPCommand function
The sample COPPCommand function performs an operation on a COPP DirectX VA device.
HRESULT COPPCommand(
_In_ COPP_DeviceData pThis,
_In_ DXVA_COPPCommand *pCommand
);
pThis [in]
- Pointer to the COPP DirectX VA device object.
pCommand [in]
- Supplies a pointer to a DXVA_COPPCommand structure that contains information about the operation to perform on the COPP device.
Returns zero (S_OK or DD_OK) if successful; otherwise, returns an error code.
The video session should be set to protected mode (that is, it should be active) before the associated COPP DirectX VA device receives a call to its COPPCommand function. That is, the COPPSequenceStart function should be called before COPPCommand. If COPPCommand is called before COPPSequenceStart, COPPCommand should return E_UNEXPECTED.
The COPPCommand function receives a populated DXVA_COPPCommand structure that contains a COPP command. The following COPP commands are supported:
- DXVA_COPPSetProtectionLevel
An instruction from the video session to set the protection level on the physical connector associated with the COPP device. A video miniport driver should be able to support multiple video sessions all playing back content through the same physical connector. - DXVA_COPPSetSignaling
An instruction about how to protect the signal that goes through the physical connector associated with the DirectX VA COPP device.
The COPPCommand function should verify that the parameters passed to it are valid for the given physical connector being used and should return E_INVALIDARG if one or more of the parameters are not valid.
If the protection command that is passed to COPPCommand is incompatible with the display resolution of the monitor, COPPCommand should return DDERR_TOOBIGSIZE.
The sample COPPCommand function maps directly to a call to the RenderMoComp member of the DD_MOTIONCOMPCALLBACKS structure. The RenderMoComp member points to the display driver-supplied DdMoCompRender callback function that references the DD_RENDERMOCOMPDATA structure.
The RenderMoComp callback function is called without the display driver-supplied BeginMoCompFrame or EndMoCompFrame function being called first.
The DD_RENDERMOCOMPDATA structure is filled as follows.
Member | Value |
---|---|
dwNumBuffers | Zero. |
lpBufferInfo | NULL. |
dwFunction | DXVA_COPPCommandFnCode constant (defined in dxva.h). |
lpInputData | Pointer to a DXVA_COPPCommand structure. |
lpOutputData | NULL. |
The following code provides an example of how you can implement your COPPCommand function:
GUID
COPP_CalculateMAC(
AESHelper* pAesHelper,
BYTE* pInputData,
DWORD dwDataLength,
GUID* pKDI
)
{
GUID rgbTag;
memset(&rgbTag, 0, sizeof(GUID));
SignData(pAesHelper, pInputData, dwDataLength, (BYTE*)&rgbTag);
return rgbTag;
}
HRESULT
COPPCommand(
COPP_DeviceData* pThis,
DXVA_COPPCommand* pCommand
)
{
DXVA_COPPSetProtectionLevelCmdData CmdData;
DWORD ProtIndex = COPP_ProtectionTypeIndex_Unkonwn;
if (pThis->m_COPPDevState != COPP_SESSION_ACTIVE) {
return E_UNEXPECTED;
}
if (pCommand->dwSequence != pThis->m_CmdSeqNumber) {
return E_INVALIDARG;
}
if (!IsEqualGUID(&pCommand->guidCommandID, &DXVA_COPPSetProtectionLevel)) {
return E_INVALIDARG;
}
//
// ensure that enough data is passed
//
if (pCommand->cbSizeData < sizeof(DXVA_COPPSetProtectionLevelCmdData)) {
return E_INVALIDARG;
}
//
// verify that the command message was sent by the application
// over the secure channel by validating the MAC on the message
//
GUID macCalculated = COPP_CalculateMAC(&pThis->m_AesHelper,
(BYTE*)&pCommand->guidCommandID,
sizeof(DXVA_COPPCommand) - sizeof(GUID),
&pThis->m_KDI);
if (!IsEqualGUID(&macCalculated, &pCommand->macKDI)) {
return E_UNEXPECTED;
}
memcpy(&CmdData, pCommand->CommandData, sizeof(DXVA_COPPSetProtectionLevelCmdData));
//
// determine which protection level (CmdData.ProtType) was passed and
// set ProtIndex accordingly (for example, ProtIndex = COPP_ProtectionTypeIndex_ACP)
//
//
// ensure that the request is valid
//
if (CmdData.ProtLevel >= g_nLevels[ProtIndex]) {
return E_INVALIDARG;
}
// set the new local level and store the former local level
DWORD oldLevel = pThis->m_LocalLevel[ProtIndex];
pThis->m_LocalLevel[ProtIndex] = CmdData.ProtLevel;
// decrement the former global level and increment the new
g_COPPLevels[pThis->m_DevID].Levels[ProtIndex][oldLevel]--;
g_COPPLevels[pThis->m_DevID].Levels[ProtIndex][CmdData.ProtLevel]++;
pThis->m_CmdSeqNumber++;
return NO_ERROR;
}
Requirements
Target platform | Version |
---|---|
Desktop | This function applies only to Windows Server 2003 with SP1 and later, and Windows XP with SP2 and later. |