Emitindo comandos AV/C brutos

[O recurso associado a esta página, DirectShow, é um recurso herdado. Ele foi substituído por MediaPlayer, IMFMediaEngine e Captura de Áudio/Vídeo na Media Foundation. Esses recursos foram otimizados para Windows 10 e Windows 11. A Microsoft recomenda fortemente que o novo código use MediaPlayer, IMFMediaEngine e Captura de Áudio/Vídeo no Media Foundation em vez de DirectShow, quando possível. A Microsoft sugere que o código existente que usa as APIs herdadas seja reescrito para usar as novas APIs, se possível.]

As interfaces IAMExtDevice, IAMExtTransport e IAMTimecodeReader funcionam traduzindo as chamadas de método em comandos para o driver, interpretando a resposta do driver e retornando-a por meio de um HRESULT ou um parâmetro de saída. No entanto, algumas funções de dispositivo podem não estar acessíveis por meio desses métodos. Portanto, o MSDV dá suporte ao envio de comandos brutos de AV/C para o dispositivo.

Você deve ter os seguintes pontos em mente ao usar esse recurso:

  • O comando é passado diretamente para o dispositivo, sem verificação de erro ou validação de parâmetro. Por esse motivo, você deve emitir comandos AV/C brutos somente quando as interfaces DirectShow não implementarem a funcionalidade necessária.
  • Todos os comandos AV/C brutos são síncronos. O thread que emite os blocos de comando até que o comando retorne.
  • Somente um comando pode ser dado por vez. Enquanto o comando estiver sendo processado, o dispositivo rejeitará quaisquer comandos adicionais.
  • O driver UVC não dá suporte a comandos AV/C brutos.

Para enviar um comando AV/C, formate o comando como uma matriz de bytes. Em seguida, chame IAMExtTransport::GetTransportBasicParameters. Passe o sinalizador ED_RAW_EXT_DEV_CMD, o tamanho da matriz e a matriz. Você deve converter o endereço da matriz em um tipo LPOLESTR* , pois a finalidade original desse parâmetro era retornar um valor de cadeia de caracteres.

BYTE AvcCmd[] = { ... }; // Contains the AV/C command (not shown)
long cbCmd = sizeof(AvcCmd);
hr = pTransport->GetTransportBasicParameters(
    ED_RAW_EXT_DEV_CMD, 
    &cbCmd,
    (LPOLESTR*) AvcCmd);

O conteúdo da matriz é passado diretamente para o dispositivo, portanto, você deve ter cuidado para formatá-lo corretamente. Um comando pode direcionar a unidade (camcorder) ou uma subunidade (fita ou câmera). Os padrões relevantes estão disponíveis no site da 1394 Trade Association.

  • Especificação geral do conjunto de comandos da interface digital AV/C
  • Especificação de subunidade do gravador/player/gravador de vídeo AV/C

O primeiro descreve como formatar comandos AV/C e lista os comandos de unidade. A última especificação lista os comandos de subunidade.

O método GetTransportBasicParameters pode retornar um dos seguintes códigos de erro:

Código do Erro Descrição
ERROR_TIMEOUT O comando atingiu o tempo limite.
ERROR_REQ_NOT_ACCEP O dispositivo não aceitou o comando.
ERROR_NOT_SUPPORTED O dispositivo não dá suporte ao comando .
ERROR_REQUEST_ABORTED O comando foi anulado. Possbly o dispositivo foi removido ou ocorreu uma redefinição de barramento.

 

Observação

Esses erros são retornados como códigos de erro Win32, não HRESULTs, portanto, você deve testar esses valores diretamente, em vez de usar as macros SUCCEEDED e FAILED .

 

Se o método retornar S_OK, a resposta do dispositivo será copiada para a matriz. A carga de resposta pode ser maior que o comando, portanto, você deve alocar um buffer grande o suficiente para mantê-lo. O tamanho máximo da carga é de 512 bytes. Observe que um valor retornado de S_OK nem sempre significa que o dispositivo executou o comando com êxito. O aplicativo deve examinar o conteúdo da resposta para determinar o status.

O exemplo a seguir mostra o comando para pesquisar uma pesquisa de número de faixa absoluta:

// Set up the ATN search command.
BYTE AvcCmd[] = 
{ 
    0x00,   // ctype = "control"
    0x20,   // subunit_type, subunit_id
    0x52,   // opcode (ATN)
    0x20,   // operand 0 = "search"
    0x00,   // operand 1 = ATN
    0x00,   // operand 2 = ATN
    0x00,   // operand 3 = ATN
    0xFF   //  operand 4 = D-VCR medium type.
};
// Specify a track number.
ULONG ulTrackNumber = track_number; // Specify the track number here.
// Shift over by 1 (LSB of operand 1 is a 1-bit blank flag)
ulTrackNumber = ulTrackNumber << 1; 
// Plug this number into operands 1 - 3.
AvcCmd[4] = (BYTE) (ulTrackNumber & 0x000000FF);
AvcCmd[5] = (BYTE)((ulTrackNumber & 0x0000FF00) >> 8);
AvcCmd[6] = (BYTE)((ulTrackNumber & 0x00FF0000) >> 16);

Controlando uma gravação de DV