Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Os exemplos de código a seguir são baseados no AVSHwS (Driver de Exemplo de Hardware Simulado) do AVStream. Eles demonstram o seguinte:
Como especificar as taxas de bits com suporte do codificador
Como especificar os modos de codificação de taxa de bits compatíveis com um codificador
Como especificar valores de metadados em tempo de execução sob a chave de registro Parâmetros de Dispositivo\Funcionalidades do dispositivo codificador
Implementando taxas de bits suportadas
Os snippets de código a seguir demonstram como implementar o suporte para a propriedade ENCAPIPARAM_BITRATE . Use uma estrutura KSPROPERTY_STEPPING_LONG para especificar uma granularidade de 400 bits por segundo (bps) com um limite inferior de 400 bps e um limite superior de 4.000.000 bps.
const KSPROPERTY_STEPPING_LONG BitRateRanges [] = {
{
400,
0,
400,
4000000
}
};
Se você acessar a página de propriedades do filtro de codificador clicando com o botão direito do mouse no filtro em uma ferramenta como o GraphEdit, verá a barra deslizante de Bit Rate onde esses valores são usados.
Em seguida, especifique a taxa de bits de codificação padrão do filtro do codificador quando uma instância dele for criada. Observe que o tipo de dados usado é um ULONG que corresponde ao tipo de valor de propriedade exigido pela propriedade ENCAPIPARAM_BITRATE. Esse valor é a codificação padrão "Taxa de Bits" exibida na página de propriedades do codificador:
const ULONG BitRateValues [] = {
1000000
};
Especifique a lista de intervalos legais e um valor padrão para a propriedade ENCAPIPARAM_BITRATE:
const KSPROPERTY_MEMBERSLIST BitRateMembersList [] = {
{
{
KSPROPERTY_MEMBER_STEPPEDRANGES,
sizeof (BitRateRanges),
SIZEOF_ARRAY (BitRateRanges),
0
},
BitRateRanges
},
{
{
KSPROPERTY_MEMBER_VALUES,
sizeof (BitRateValues),
SIZEOF_ARRAY (BitRateValues),
KSPROPERTY_MEMBER_FLAG_DEFAULT
},
BitRateValues
}
};
const KSPROPERTY_VALUES BitRateValuesSet = {
{
STATICGUIDOF (KSPROPTYPESETID_General),
VT_UI4,
0
},
SIZEOF_ARRAY (BitRateMembersList),
BitRateMembersList
};
Especifique a propriedade única definida para o conjunto de propriedades ENCAPIPARAM_BITRATE:
DEFINE_KSPROPERTY_TABLE(ENCAPI_BitRate) {
DEFINE_KSPROPERTY_ITEM (
0,
GetBitRateHandler, //Get-property handler supported
sizeof (KSPROPERTY),
sizeof (ULONG),
SetBitRateHandler, //Set-property handler supported
&BitRateValuesSet,
0,
NULL,
NULL,
sizeof (ULONG)
)
};
Observação
O manipulador de propriedade get retorna a taxa de bits de codificação e o manipulador set-property deve testar se o valor aprovado de entrada é válido antes de usá-lo.
Implementando modos suportados de taxa de bits de codificação
Os snippets de código a seguir demonstram como implementar o suporte para a propriedade ENCAPIPARAM_BITRATE_MODE .
Defina os modos de codificação compatíveis com o codificador:
const VIDEOENCODER_BITRATE_MODE BitRateModeValues [] = {
ConstantBitRate,
VariableBitRateAverage
};
Especifique o modo de taxa de bits de codificação padrão como taxa média de bits variáveis:
const VIDEOENCODER_BITRATE_MODE BitRateModeDefaultValues [] = {
VariableBitRateAverage
};
Especifique a lista de intervalos legais e o valor padrão da propriedade ENCAPIPARAM_BITRATE_MODE:
const KSPROPERTY_MEMBERSLIST BitRateModeMembersList [] = {
{
{
KSPROPERTY_MEMBER_VALUES,
sizeof (BitRateModeValues),
SIZEOF_ARRAY (BitRateModeValues),
0
},
BitRateModeValues
},
{
{
KSPROPERTY_MEMBER_VALUES,
sizeof (BitRateModeDefaultValues),
SIZEOF_ARRAY (BitRateModeDefaultValues),
KSPROPERTY_MEMBER_FLAG_DEFAULT
},
BitRateModeDefaultValues
}
};
const KSPROPERTY_VALUES BitRateModeValuesSet = {
{
STATICGUIDOF (KSPROPTYPESETID_General),
VT_I4,
0
},
SIZEOF_ARRAY (BitRateModeMembersList),
BitRateModeMembersList
};
Especifique a propriedade única definida para o conjunto de propriedades ENCAPIPARAM_BITRATE_MODE:
DEFINE_KSPROPERTY_TABLE(ENCAPI_BitRateMode) {
DEFINE_KSPROPERTY_ITEM (
0,
GetBitRateModeHandler, //Get-property handler supported
sizeof (KSPROPERTY),
sizeof (VIDEOENCODER_BITRATE_MODE),
SetBitRateModeHandler, //Set-property handler supported
&BitRateModeValuesSet,
0,
NULL,
NULL,
sizeof (VIDEOENCODER_BITRATE_MODE)
)
};
Observação
O manipulador de propriedade get deve retornar o modo de taxa de bits de codificação e o manipulador set-property deve testar se o valor aprovado de entrada é válido antes de usá-lo.
Os conjuntos de propriedades são então especificados como a tabela de automação da estrutura KSFILTER_DESCRIPTOR.
DEFINE_KSPROPERTY_SET_TABLE(PropertyTable) {
DEFINE_KSPROPERTY_SET(
&ENCAPIPARAM_BITRATE_MODE,
SIZEOF_ARRAY (ENCAPI_BitRateMode),
ENCAPI_BitRateMode,
0,
NULL
),
DEFINE_KSPROPERTY_SET(
&ENCAPIPARAM_BITRATE,
SIZEOF_ARRAY (ENCAPI_BitRate),
ENCAPI_BitRate,
0,
NULL
)
};
DEFINE_KSAUTOMATION_TABLE(FilterTestTable) {
DEFINE_KSAUTOMATION_PROPERTIES(PropertyTable),
DEFINE_KSAUTOMATION_METHODS_NULL,
DEFINE_KSAUTOMATION_EVENTS_NULL
};
const
KSFILTER_DESCRIPTOR
FilterDescriptor = {
...,
&FilterTestTable, // Automation Table
...,
...
};
Especificando os recursos do codificador no Registro
O exemplo de código a seguir demonstra como criar uma chave do Registro Recursos na chave do Registro Parâmetros de Dispositivo e como criar e especificar subchaves e valores na chave Recursos. Execute o código quando o driver é inicializado.
Observação
O código a seguir pressupõe a presença de um único codificador de hardware por dispositivo físico. Se o hardware contiver mais de um codificador, você deverá iterar por meio da lista retornada na chamada para a função IoGetDeviceInterfaces e registrar os recursos para cada codificador.
/**************************************************************************
CreateDwordValueInCapabilityRegistry()
IN Pdo: PhysicalDeviceObject
IN categoryGUID: Category GUID eg KSCATEGORY_CAPTURE
1. Get Symbolic name for interface
2. Open registry key for storing information about a
particular device interface instance
3. Create Capabilities key under "Device Parameters" key
4. Create a DWORD value "TestCapValueDWORD" under Capabilities
Must be running at IRQL = PASSIVE_LEVEL in the context of a system thread
**************************************************************************/
NTSTATUS CreateDwordValueInCapabilityRegistry(IN PDEVICE_OBJECT pdo, IN GUID categoryGUID)
{
// 1. Get Symbolic name for interface
// pSymbolicNameList can contain multiple strings if pdo is NULL.
// Driver should parse this list of string to get
// the one corresponding to current device interface instance.
PWSTR pSymbolicNameList = NULL;
NTSTATUS ntStatus = IoGetDeviceInterfaces(
&categoryGUID,
pdo,
DEVICE_INTERFACE_INCLUDE_NONACTIVE,
&pSymbolicNameList);
if (NT_SUCCESS(ntStatus) && (NULL != pSymbolicNameList))
{
HANDLE hDeviceParametersKey = NULL;
UNICODE_STRING symbolicName;
// 2. Open registry key for storing information about a
// particular device interface instance
RtlInitUnicodeString(&symbolicName, pSymbolicNameList);
ntStatus = IoOpenDeviceInterfaceRegistryKey(
&symbolicName,
KEY_READ|KEY_WRITE,
&hDeviceParametersKey);
if (NT_SUCCESS(ntStatus))
{
OBJECT_ATTRIBUTES objAttribSubKey;
UNICODE_STRING subKey;
// 3. Create Capabilities key under "Device Parameters" key
RtlInitUnicodeString(&subKey,L"Capabilities");
InitializeObjectAttributes(&objAttribSubKey,
&subKey,
OBJ_KERNEL_HANDLE,
hDeviceParametersKey,
NULL);
HANDLE hCapabilityKeyHandle = NULL;
ntStatus = ZwCreateKey(&hCapabilityKeyHandle,
KEY_READ|KEY_WRITE|KEY_SET_VALUE,
&objAttribSubKey,
0,
NULL,
REG_OPTION_NON_VOLATILE,
NULL);
if (NT_SUCCESS(ntStatus))
{
OBJECT_ATTRIBUTES objAttribDwordKeyVal;
UNICODE_STRING subValDword;
// 4. Create a DWORD value "TestCapValueDWORD" under Capabilities
RtlInitUnicodeString(&subValDword,L"TestCapValueDWORD");
ULONG data = 0xaaaaaaaa;
ntStatus = ZwSetValueKey(hCapabilityKeyHandle,&subValDword,0,REG_DWORD,&data,sizeof(ULONG));
ZwClose(hCapabilityKeyHandle);
}
}
ZwClose(hDeviceParametersKey);
ExFreePool(pSymbolicNameList);
}
return ntStatus;
}