Поделиться через


Выдача необработанных команд AV/C

[Функция, связанная с этой страницей, DirectShow, является устаревшей функцией. Он был заменен MediaPlayer, IMFMediaEngineи захват аудио/видео в Media Foundation. Эти функции оптимизированы для Windows 10 и Windows 11. Корпорация Майкрософт настоятельно рекомендует использовать новый программный код MediaPlayer, IMFMediaEngine и Audio/Video Capture в Media Foundation вместо DirectShow, по возможности. Корпорация Майкрософт предлагает, что существующий код, использующий устаревшие API, будет перезаписан для использования новых API, если это возможно.]

IAMExtDevice, IAMExtTransportи IAMTimecodeReader работают путем преобразования вызовов метода в команды драйвера, а затем интерпретации ответа драйвера и возврата его через HRESULT или выходной параметр. Однако некоторые функции устройств могут быть недоступны с помощью этих методов. Поэтому MSDV поддерживает отправку необработанных команд AV/C на устройство.

При использовании этой функции следует учитывать следующие моменты:

  • Команда передается непосредственно устройству без проверки ошибок или проверки параметров. По этой причине следует выдавать необработанные команды AV/C, только если интерфейсы DirectShow не реализуют необходимые функции.
  • Все необработанные команды AV/C синхронны. Поток, выдавающий блоки команд, пока не будет возвращена команда.
  • Одновременно можно указать только одну команду. Во время обработки команды устройство отклонит все дополнительные команды.
  • Драйвер UVC не поддерживает необработанные команды AV/C.

Чтобы отправить команду AV/C, отформатируйте команду в виде массива байтов. Затем вызовите IAMExtTransport::GetTransportBasicParameters. Передайте флаг ED_RAW_EXT_DEV_CMD, размер массива и массив. Необходимо привести адрес массива к типу LPOLESTR*, так как исходная цель этого параметра — возвращать строковое значение.

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

Содержимое массива передается непосредственно устройству, поэтому необходимо тщательно отформатировать его. Команда может нацелиться на устройство (видеокамеру) или подразделение (ленту или камеру). Соответствующие стандарты доступны на веб-сайте 1394 торговой ассоциации.

  • Общая спецификация командного интерфейса AV/C
  • Спецификация блока магнитофона/плейера AV/C

В предыдущем разделе описывается форматирование команд AV/C и перечисление команд единиц. В последней спецификации перечислены команды subunit.

Метод GetTransportBasicParameters может вернуть один из следующих кодов ошибок:

Код ошибки Описание
Ошибка: Время ожидания истекло Время ожидания команды истекло.
ERROR_REQ_NOT_ACCEP (Запрос не принят) Устройство не приняло команду.
ОШИБКА: НЕ ПОДДЕРЖИВАЕТСЯ Устройство не поддерживает команду.
ОШИБКА_ЗАПРОС_ОТМЕНЕН Команда была прервана. Возможно, устройство было удалено или произошел сброс шины.

 

Заметка

Эти ошибки возвращаются как коды ошибок Win32, а не HRESULTs, поэтому эти значения следует проверять напрямую, а не использовать макросы SUCCEEDED и FAILED.

 

Если метод возвращает S_OK, то ответ устройства копируется в массив. Полезная нагрузка ответа может быть больше, чем команда, поэтому необходимо выделить достаточно большой буфер, чтобы её вместить. Максимальный размер полезных данных составляет 512 байт. Обратите внимание, что возвращаемое значение S_OK не всегда означает, что устройство успешно выполнило команду. Чтобы определить состояние, приложение должно проверить полезные данные ответа.

В следующем примере показана команда для выполнения поиска по абсолютному номеру трека:

// 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);

Управление видеокамерой DV