共用方式為


相機方向的驅動程序支援

重要

本主題稍後討論的自動更正方法是相機感測器非參考方向掛接 的建議 解決方案。 這是為了確保應用程式相容性,因為大部分已寫入以使用相機摘要的應用程式不知道要檢查,也不會更正旋轉資訊。 請仔細檢閱下方自動更正一節中的資訊。

引進不同的尺寸規格運算裝置時,某些實體條件約束會導致相機感測器以非傳統方向掛接。 因此,您必須適當地描述 OS 和應用程式,如何掛接感測器,以便正確轉譯/錄製產生的視訊。

從 Window 10 版本 1607 開始,不論相機是否根據 最低硬體需求掛接,所有相機驅動程式都必須明確指定相機方向。 具體而言,相機驅動程式必須在與擷取裝置介面相關聯的 ACPI _PLD 結構中設定新引進的字段 [旋轉]:

typedef struct _ACPI_PLD_V2_BUFFER {

    UINT32 Revision:7;
    UINT32 IgnoreColor:1;
    UINT32 Color:24;
    // …
    UINT32 Panel:3;         // Already supported by camera.
    // …
    UINT32 CardCageNumber:8;
    UINT32 Reference:1;
    UINT32 Rotation:4;      // 0 – Rotate by 0° clockwise
                            // 1 – Rotate by 45° clockwise (N/A to camera)
                            // 2 – Rotate by 90° clockwise
                            // 3 – Rotate by 135° clockwise (N/A to camera)
                            // 4 – Rotate by 180° clockwise
                            // 5 – Rotate by 225° clockwise (N/A to camera)
                            // 6 – Rotate by 270° clockwise
    UINT32 Order:5;
    UINT32 Reserved:4;

    //
    // _PLD v2 definition fields.
    //

    USHORT VerticalOffset;
    USHORT HorizontalOffset;
} ACPI_PLD_V2_BUFFER, *PACPI_PLD_V2_BUFFER;

對於相機,ACPI _PLD 結構的 旋轉 欄位會指定 0° ('0' 的度數、90°的 '2'、180°的 '4',而 270° 的 '6') 擷取的畫面會相對於螢幕旋轉,而顯示器則為原生方向。

根據 [旋轉 ] 欄位中的值,應用程式可以視需要執行額外的旋轉,以便正確轉譯擷取的畫面格。

旋轉值

對於相機和顯示器共用相同房屋 (或 機箱/大小 寫) 的裝置,可以讓這些周邊掛接在不同的介面上,每個周邊都會由固定但任意度在其各自的平面上旋轉。 因此,應用程式需要一個機制來描述兩個周邊之間的空間關聯性,讓擷取的框架可以轉置到正確方向的轉譯介面上。

解決此問題的其中一種方法是使用 ACPI _PLD 結構,其已經定義 表面旋轉程度 的概念。 例如,_PLD 結構已經有 面板 欄位,可指定周邊所在的介面:

ACPI PLD 面板欄位。

ACPI _PLD Panel 字段的定義 (Rev. 5.0a)

接下來的兩個圖表會以可視化方式說明每個面板的定義:

桌面電腦和大部分裝置的面板定義

面板定義 -桌面。

可折疊裝置的面板定義

面板定義 - 可折疊的裝置。

事實上,WINDOWS 已採用 ACPI「面板」的概念,其中:

ACPI _PLD 結構也有定義如下的 [旋轉] 欄位:

ACPI _PLD 旋轉欄位的定義 (Rev 5.0a)

ACPI _PLD旋轉欄位定義。

我們會進一步精簡上述定義,以避免模棱兩可:

  • 若為相機,ACPI _PLD 結構的旋轉欄位會指定 0° ('0' 的度數、90°的 '2'、180°的 '4',而 270° 的 '6') 撷取的畫面會相對於螢幕旋轉,而顯示器則為原生方向。

橫向主要與直向主要

在 Windows 中,您可以藉由呼叫 屬性 Windows.Graphics.Display.DisplayInformation.NativeOrientation 來查詢原生顯示方向,這會傳回 LandscapePortrait

顯示原生方向掃描模式。

無論您傳回哪個 值 NativeOrientation ,邏輯顯示器掃描模式都會從從左至右向下行動的顯示器左上角開始, (請參閱圖 5) 。 對於默認實體方向為不重複的裝置,此屬性不僅表示ACPI Top 面板的位置,也提供相機輸出緩衝區與轉譯介面之間的空間關聯性。

請注意,與相機不同, NativeOrientation 屬性不是以 ACPI 為基礎,因此沒有_PLD結構。 即使顯示器以靜態方式掛接至裝置,也是如此。

在直向主要裝置上掛接時,相機驅動程式必須注意,大部分的應用程式都會將裝置視為輸出橫向相機輸出緩衝區,而不論實際的相機輸出緩衝區方向為何。 因此,我們建議相機驅動程式在直向主要裝置上時,輸出與 NativeOrientation Portrait 有 90 度方向位移的相機緩衝區。 然後,這可讓在直向裝置上執行此額外旋轉的應用程式,以將旋轉更正為預期的方向。 這可以使用 相機應用程式搭配旋轉範例進行驗證。

位移掛接

強烈建議 IHV/OEM 避免在非 0 度位移中掛接感測器,以維持應用程式相容性。 許多現有和舊版應用程式不知道要尋找 ACPI 的 PLD 數據表,也不會嘗試更正非 0 度位移。 因此,針對這類應用程式,產生的視訊會轉譯不正確。

如果 IHV/OEM 無法以 0 度方向掛接感測器,如上所述,建議依照喜好設定順序執行下列風險降低步驟:

  1. 使用AV串流迷你埠驅動程式或在使用者模式中使用裝置MFT或 MFT) 0 等外掛程式,自動更正數位相機 (驅動程式內非 0 度方向,讓產生的輸出畫面處於 0 度方向。

  2. 透過 FSSensorOrientation 標籤宣告非 0 度方向,讓相機管線可以更正擷取的影像。

  3. 如上所述,在 ACPI 的 PLD 數據表中宣告非 0 度方向。

壓縮/編碼媒體類型

對於壓縮和/或編碼媒體類型 (,例如 MJPG、JPEG、H264、HEVC) ,無法使用管線更正。 因此,如果 FSSensorOrientation 設定為非零值,則會篩選掉壓縮/編碼的媒體類型。

在 MJPG 媒體類型 (例如來自 UVC 相機) 的媒體類型的情況下,Frame Server 管線會針對 DShow 型應用程式提供自動譯碼媒體類型 (NV12 或 YUY2) 。 系統會顯示自動譯碼和更正的媒體類型,但原始的 MJPG 格式將不會顯示。

[!注意!] 如果壓縮/編碼媒體類型必須公開給應用程式,IHV/ODM 不得利用 FSSensorOrientation 修正。 相反地,相機驅動程式必須透過AV Stream驅動程式或透過 DMFT/MFT0) 在核心模式中 (更正。

透過AV Stream Miniport/Device MFT/MFT0 自動更正

如果感測器無法以 0 度位移掛接,建議的案例是讓 AV Stream 迷你埠驅動程式 (或使用者模式外掛程式以 DMFT 或 MFT0 的形式插入,) 更正產生的擷取框架,使其在 0 度位移中公開至管線。

從 AV Stream Miniport 和/或 Device MFT/MFT0 外掛程式更正視訊畫面時,產生的媒體類型宣告必須以更正的畫面為基礎。 如果感測器以90度位移掛接,因此產生的視訊是感測器的9:16外觀比例,但更正的視訊會是16:9,媒體類型必須宣告16:9的外觀比例。

這包括產生的步進資訊。 這是必要的,因為負責進行更正的元件是由 IHV/OEM 所控制,而且相機管線無法看見視訊畫面,但修正之後除外。

強烈建議您在使用者模式中完成更正,而且必須遵循管線與使用者模式外掛程式之間的 API 合約。 具體而言,使用 DMFT 或 MFT0 時,當 IMFDeviceTransform::P rocessMessage 或 IMFTransform::P rocessMessage 使用MFT_MESSAGE_SET_D3D_MANAGER訊息叫用時,使用者模式外掛程式必須遵循下列指導方針:

  • 如果未提供 D3D 管理員 (訊息的 ulParam 為 0) ,則使用者模式外掛程式不得叫用任何 GPU 作業來處理旋轉更正。 而且產生的框架必須在系統記憶體中提供。
  • 如果提供 D3D 管理員 (訊息的 ulParam 是 DXGI 管理員的 IUnknown) ,則 DXGI 管理員必須用於旋轉修正,且產生的畫面必須是 GPU 記憶體。
  • 使用者模式外掛程式也必須在運行時間期間處理 D3D 管理員訊息。 發出MFT_MESSAGE_SET_D3D_MANAGER訊息時,外掛程式所產生的下一個畫面格必須對應至要求的記憶體類型 (,亦即如果提供 DXGI 管理員,則 GPU,否則為 CPU) 。
  • 當AV Stream驅動程式 (或使用者模式外掛程式) 處理旋轉修正時,ACPI的 PLD 結構的 [旋轉] 字段必須設定為 0。

注意

使用 [自動更正] 時,OEM 和 IHD 不得透過 [_PLD 旋轉 ] 欄位公告感測器的實際方向。 在此情況下, [旋轉 ] 字段必須指出校正之後的方向:0 度。

透過 FSSensorOrientation 宣告

; Defines the sensor mounting orientation offset angle in
; degrees clockwise.
FSSensorOrientation: REG_DWORD: 90, 180, 270

藉由透過 FSSensorOrientation 登錄標籤宣告感測器的非 0 度方向,相機管線可以修正所擷取的畫面,再向應用程式呈現它。

管線會根據使用案例和應用程式要求/案例,利用 GPU 或 CPU 資源來優化旋轉邏輯。

ACPI PLD 旋轉

ACPI PLD 結構的 [旋轉] 字段必須是 0。 這是為了避免使用 PLD 資訊來更正框架的混淆應用程式。

媒體類型資訊

驅動程式呈現的媒體類型必須是未更正的媒體類型。 使用 FSSensorOrientation 專案通知相機管線非 0 度位移時,感測器呈現的媒體類型信息必須是未更正的媒體類型。 例如,如果感測器掛接 90 度順時針位移,因此,而不是 16:9 外觀比例,產生的視訊為 9:16,9:16 外觀比例媒體類型必須呈現給相機管線。

這是確保管線可以正確設定計數器輪替程式的必要條件:管線需要輸入媒體類型和應用程式所需的輸出媒體類型。

這包括步進資訊。 對於相機管線的未更正媒體類型,必須顯示跨步資訊。

登錄子機碼

FSSensorOrientation 登錄項目必須在 [裝置介面] 節點上發佈。 建議的方法是在數位相機驅動程式 INF 的 AddInterface 指示詞宣告期間,將此宣告為 AddReg 指示詞。

FSSensorOrientation 中顯示的數據必須是REG_DWORD,且唯一接受的有效值為 90、180 和 270。 任何其他值都會被視為 0 度位移 (,也就是忽略) 。

每個值都以順時針方向表示感測器方向。 相機管線會藉由逆時針旋轉視訊的計數器來更正產生的視訊畫面:亦即,90 度順時針宣告會導致 90 度逆時針旋轉,讓產生的視訊畫面回到 0 度位移。

MS OS 描述元 1.0

針對USB型相機,FSSensorOrientation也可以透過 MSOS 描述元發佈。

MS OS 描述項 1.0 有兩個元件:

  • 固定長度標頭區段
  • 一或多個可變長度的自定義屬性區段,其遵循標頭區段

MS OS DESCRIPTOR 1.0 標頭區段

標頭區段描述臉部驗證配置檔) (單一自定義屬性。

Offset 欄位 大小 (位元組) 描述
0 dwLength 4 <>
4 bcdVersion 2 0x0100 版本 1.0
6 wIndex 2 0x0005 擴充屬性OS描述項
8 wCount 2 0x0001 一個自定義屬性

自定義 MS OS DESCRIPTOR 1.0 屬性區段

Offset 欄位 大小 (位元組) 描述
0 dwSize 4 0x00000036 (54) 此屬性的大小總計 (以位元組為單位) 。
4 dwPropertyDataType 4 0x00000004 REG_DWORD_LITTLE_ENDIAN
8 wPropertyNameLength 2 0x00000024 (36) 屬性名稱) 以位元組為單位的大小 (。
10 bPropertyName 50 UVC-FSSensorOrientation Unicode 中的 “UVC-FSSensorOrientation” 字串。
60 dwPropertyDataLength 4 0x00000004 屬性數據 (sizeof (DWORD) ) 的 4 個字節。
64 bPropertyData 4 順時針以度為單位的位移角度。 有效值為 90、180 和 270。

MS OS 描述元 2.0

MSOS 擴充描述元 2.0 可用來定義登錄值,以新增 FSSensorOrientation 支援。 這是使用 Microsoft OS 2.0 登錄屬性描述元來完成。

針對 UVC-FSSensorOrientation 登錄專案,下列範例顯示 MSOS 2.0 描述項集:

UCHAR Example2_MSOS20DescriptorSet_UVCFSSensorOrientationForFutureWindows[0x3C] =
{
    //
    // Microsoft OS 2.0 Descriptor Set Header
    //
    0x0A, 0x00,                 // wLength - 10 bytes
    0x00, 0x00,                 // MSOS20_SET_HEADER_DESCRIPTOR
    0x00, 0x00, 0x0?, 0x06,     // dwWindowsVersion – 0x060?0000 for future Windows version
    0x4A, 0x00,                 // wTotalLength – 74 bytes

    //
    // Microsoft OS 2.0 Registry Value Feature Descriptor
    //
    0x40, 0x00,                 // wLength - 64 bytes
    0x04, 0x00,                 // wDescriptorType – 4 for Registry Property
    0x04, 0x00,                 // wPropertyDataType - 4 for REG_DWORD_LITTLE_ENDIAN
    0x32, 0x00,                 // wPropertyNameLength – 50 bytes
    0x55, 0x00, 0x56, 0x00,     // Property Name - "UVC-FSSensorOrientation"
    0x43, 0x00, 0x2D, 0x00,
    0x46, 0x00, 0x53, 0x00,
    0x53, 0x00, 0x65, 0x00,
    0x6E, 0x00, 0x73, 0x00,
    0x6F, 0x00, 0x72, 0x00,
    0x4F, 0x00, 0x72, 0x00,
    0x69, 0x00, 0x65, 0x00,
    0x6E, 0x00, 0x74, 0x00,
    0x61, 0x00, 0x74, 0x00,
    0x69, 0x00, 0x6F, 0x00,
    0x6E, 0x00, 0x00, 0x00,
    0x00, 0x00,
    0x04, 0x00,                 // wPropertyDataLength – 4 bytes
    0x5A, 0x00, 0x00, 0x00      // PropertyData – 0x0000005A (90 degrees offset)
}

透過 ACPI PLD 資訊宣告

作為最後一個選擇,可以如上所述利用 PLD 資訊,向應用程式指出必須先更正視訊畫面,才能轉譯/編碼。 不過,如前所述,許多現有的應用程式不會使用 PLD 資訊,也不會處理畫面旋轉,因此在某些情況下,應用程式可能無法正確轉譯產生的視訊。

下圖說明每個硬體組態_PLD輪替欄位的值:

旋轉:順時針方向0度

0 度旋轉圖。

在上圖中:

  • 左側圖片說明要擷取的場景。

  • 中間的圖片描述由實體讀出順序從左下角向右往上移動的 URL 感測器如何檢視場景。

  • 右邊的圖片代表相機驅動程序的輸出。 在此範例中,可以直接轉譯媒體緩衝區的內容,而顯示器是其原生方向,而不需要額外的旋轉。 因此,ACPI _PLD Rotation 欄位的值為 0。

旋轉:順時針旋轉 90 度

90 度旋轉圖。

在此情況下,相較於原始場景,媒體緩衝區的內容會順時針旋轉 90 度。 因此,ACPI _PLD Rotation 欄位的值為 2。

旋轉:順時針 180 度

180 度旋轉圖。

在此情況下,相較於原始場景,媒體緩衝區的內容會順時針旋轉 180 度。 因此,ACPI _PLD [旋轉] 欄位的值為 4。

旋轉:順時針方向 270 度

270 度旋轉圖。

在此情況下,相較於原始場景,媒體緩衝區的內容會順時針旋轉 270 度。 因此,ACPI _PLD [旋轉] 欄位的值為 6。