Ausgeben von unformatierten AV/C-Befehlen

[Das dieser Seite zugeordnete Feature DirectShow ist ein Legacyfeature. Es wurde durch MediaPlayer, IMFMediaEngine und Audio/Video Capture in Media Foundation ersetzt. Diese Features wurden für Windows 10 und Windows 11 optimiert. Microsoft empfiehlt dringend, dass neuer Code nach Möglichkeit MediaPlayer, IMFMediaEngine und Audio/Video Capture in Media Foundation anstelle von DirectShow verwendet. Microsoft schlägt vor, vorhandenen Code, der die Legacy-APIs verwendet, um nach Möglichkeit die neuen APIs zu verwenden.]

Die Schnittstellen IAMExtDevice, IAMExtTransport und IAMTimecodeReader übersetzen die Methodenaufrufe in Befehle für den Treiber, interpretieren dann die Antwort des Treibers und geben sie über ein HRESULT oder einen Ausgabeparameter zurück. Auf einige Gerätefunktionen kann jedoch möglicherweise nicht über diese Methoden zugegriffen werden. Daher unterstützt MSDV das Senden von unformatierten AV/C-Befehlen an das Gerät.

Beachten Sie bei der Verwendung dieses Features die folgenden Punkte:

  • Der Befehl wird ohne Fehlerüberprüfung oder Parameterüberprüfung direkt an das Gerät übergeben. Aus diesem Grund sollten Sie nur unformatierte AV/C-Befehle ausgeben, wenn die DirectShow-Schnittstellen die benötigten Funktionen nicht implementieren.
  • Alle unformatierten AV/C-Befehle sind synchron. Der Thread, der den Befehl ausgibt, blockiert, bis der Befehl zurückgibt.
  • Es kann jeweils nur ein Befehl erteilt werden. Während der Verarbeitung des Befehls lehnt das Gerät alle zusätzlichen Befehle ab.
  • Der UVC-Treiber unterstützt keine unformatierten AV/C-Befehle.

Um einen AV/C-Befehl zu senden, formatieren Sie den Befehl als Bytearray. Rufen Sie dann IAMExtTransport::GetTransportBasicParameters auf. Übergeben Sie das flag ED_RAW_EXT_DEV_CMD, die Arraygröße und das Array. Sie müssen die Arrayadresse in einen LPOLESTR* -Typ umwandeln, da der ursprüngliche Zweck dieses Parameters darin bestand, einen Zeichenfolgenwert zurückzugeben.

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

Der Inhalt des Arrays wird direkt an das Gerät übergeben, daher müssen Sie darauf achten, es richtig zu formatieren. Ein Befehl kann auf die Einheit (Camcorder) oder eine Untereinheit (Band oder Kamera) abzielen. Die entsprechenden Standards sind auf der Website 1394 der Trade Association verfügbar.

  • Av/C Digital Interface Command Set – Allgemeine Spezifikation
  • AV/C Tape Recorder/Player-Untereinheit Spezifikation

Ersteres beschreibt das Formatieren von AV/C-Befehlen und listet die Einheitenbefehle auf. In der letztgenannten Spezifikation sind die Untereinheitsbefehle aufgeführt.

Die GetTransportBasicParameters-Methode gibt möglicherweise einen der folgenden Fehlercodes zurück:

Fehlercode BESCHREIBUNG
ERROR_TIMEOUT Für den Befehl wurde ein Timeout ausgeführt.
ERROR_REQ_NOT_ACCEP Das Gerät hat den Befehl nicht akzeptiert.
ERROR_NOT_SUPPORTED Das Gerät unterstützt den Befehl nicht.
ERROR_REQUEST_ABORTED Der Befehl wurde abgebrochen. Possbly wurde das Gerät entfernt oder es wurde eine Buszurücksetzung durchgeführt.

 

Hinweis

Diese Fehler werden als Win32-Fehlercodes und nicht als HRESULTs zurückgegeben. Daher sollten Sie diese Werte direkt testen, anstatt die Makros SUCCEEDED und FAILED zu verwenden.

 

Wenn die Methode S_OK zurückgibt, wird die Antwort vom Gerät in das Array kopiert. Die Antwortnutzlast kann größer als der Befehl sein, daher müssen Sie einen Puffer zuordnen, der groß genug ist, um ihn zu halten. Die maximale Nutzlastgröße beträgt 512 Bytes. Beachten Sie, dass ein Rückgabewert von S_OK nicht immer bedeutet, dass das Gerät den Befehl erfolgreich ausgeführt hat. Die Anwendung muss die Antwortnutzlast untersuchen, um die status zu ermitteln.

Das folgende Beispiel zeigt den Befehl zum Suchen nach einer absoluten Spurnummersuche:

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

Steuern eines DV-Camcorders