Megosztás a következőn keresztül:


JPEG YCbCr-támogatás

A Windows 8.1-től kezdve a Windows Képalkotó összetevő (WIC) JPEG-kodek támogatja a képadatok natív YC-bCr formájában való olvasását és írását. WIC YCbCr támogatása Direct2D együtt használható az YCbCr képpontadatok képeffektussal való megjelenítéséhez. Emellett a WIC JPEG kodek YCbCr pixeladatokat is képes felhasználni, amelyeket bizonyos kameraillesztők a Media Foundationen keresztül hoznak létre.

YCbCr képpontadatok jelentősen kevesebb memóriát használnak fel, mint a normál BGRA képpontformátumok. Ezenkívül az YCbCr adatokhoz való hozzáférés lehetővé teszi a JPEG dekódolási/kódolási folyamat egyes szakaszainak a Direct2D-be való betöltését, amely a GPU gyorsítása. Az YCbCrhasználatával az alkalmazás csökkentheti a JPEG memóriahasználatát és betöltési idejét azonos méretű és minőségű képek esetén. Vagy az alkalmazás több, nagyobb felbontású JPEG-képet is használhat teljesítménybeli büntetések nélkül.

Ez a témakör azt ismerteti, hogyan működik az YCbCr adatok, és hogyan használhatók WIC-ben és Direct2D-ben.

A JPEG YCbCr Data

Ez a szakasz néhány alapvető fogalmat ismertet, amelyek szükségesek ahhoz, hogy az YCbCr WIC-támogatás működése és fő előnyei.

YCbCr színmodell

A WiC a Windows 8-ban és korábban négy különböző színmodellt támogat, amelyek közül a leggyakoribb az RGB/BGR. Ez a színmodell piros, zöld és kék összetevőkkel határozza meg a színadatokat; egy negyedik alfa összetevő is használható.

Íme egy kép, amely piros, zöld és kék összetevőire bontva van.

egy kép vörös, zöld és kék összetevőire bontva.

YCbCr egy alternatív színmodell, amely színadatokat határoz meg egy fényerejű összetevő (Y) és két kromoszóma-összetevő (Cb és Cr) használatával. Digitális kép- és videoforgatókönyvekben gyakran használják. Az YCbCr gyakran használják felcserélhetően a YUV-val, bár a kettő technikailag eltérő.

Az YCbCr különböző színtér- és dinamikus tartománydefiníciók – a WIC kifejezetten támogatja a JPEG JFIF YCbCr adatokat. További információ: JPEG ITU-T81 specifikáció.

Íme egy kép az Y, a Cbés a Cr összetevőire bontva.

egy kép y, cb és cr összetevőire bontva.

Planar versus Interleaved Memóriaelrendezések

Ez a szakasz az RGB-képpontadatok memóriabeli elérése és tárolása és az YCbCr adatok közötti különbségeket ismerteti.

Az RGB-képpontadatok tárolása általában egy interaktív memóriaelrendezés használatával történik. Ez azt jelenti, hogy az egyetlen színösszetevő adatai képpontok között fonódik össze, és az egyes képpontok egymással párhuzamosan tárolódnak a memóriában.

Íme egy ábra, amely egy RGBA-képpontos adatokat mutat be, amelyeket egy gazdaközi memóriaelrendezés tárol.

egy rgba képpontos adatokat ábrázoló ábra, amely egy interleaved memóriaelrendezésben van tárolva.

Az YCbCr adatokat általában planáris memóriaelrendezéssel tárolják. Ez azt jelenti, hogy minden színösszetevőt külön tárol a rendszer a saját összefüggő síkjában, összesen három síkban. Egy másik gyakori konfigurációban a Cb és a Cr-összetevők össze vannak osztva és tárolva, míg az Y összetevő a saját síkjában marad, összesen két síkban.

Íme egy ábra, amely az Y planáris és az interleaved CbCr pixeles adatokat mutatja, egy gyakori YCbCr memóriaelrendezést.

a planar y és az interleaved cbcr pixel adatokat ábrázoló ábrát, amely egy gyakori ycbcr memóriaelrendezés.

A WIC és a Direct2D esetében az egyes színsíkok saját különálló objektumként vannak kezelve (vagy egy IWICBitmapSource vagy ID2D1Bitmap), és együttesen ezek a síkok alkotják az YCbCr kép háttéradatait.

Bár a WIC támogatja az YCbCr adatok elérését mind a 2- mind a 3 sík konfigurációjában, a Direct2D csak az előbbieket támogatja (Y és CbCr). Ezért a WIC és a Direct2D együttes használatakor mindig a 2 sík YCbCr konfigurációt kell használnia.

Chroma-részminta-osztás

Az YCbCr színmodell kiválóan alkalmas digitális képalkotó forgatókönyvekhez, mert kihasználhatja az emberi vizuális rendszer bizonyos aspektusait. Az emberek különösen érzékenyebbek a kép fényerejének (fényerejének) változásaira, és kevésbé érzékenyek a kromoszómára (színre). A színadatok külön fény- és krominancia-összetevőkre való felosztásával szelektíven tömöríthetjük csak a krominancia-összetevőket, hogy minimális minőségveszteség mellett helymegtakarítást érjünk el.

Ennek egyik technikája a chroma subsampling. A Cb és Cr síkok a vízszintes és a függőleges dimenziók egyikében vagy mindkettőben le vannak osztva (leskálázva). Előzményként az egyes chroma-részminta-módban általában három rész J:a:b arányt használnak.

Részminta-osztási mód Vízszintes lefelé skálázás Függőleges lefelé skálázás Bitek képpontonként*
4:4:4 1x 1x 24
4:2:2 2x 1x 16
4:4:0 1x 2x 16
4:2:0 2x 2x 12

 

* Y-adatokat tartalmaz.

A fenti táblázatból, ha YCbCr használ a tömörítetlen képadatok tárolására, akkor a memória 25% és 62,5% közötti memóriamegtakarítást érhet el, szemben a képpontonkénti RGBA-adatok 32 bites értékével, attól függően, hogy melyik chroma-almintaezési módot használja.

YCbCr JPEG-használata

Magas szinten a JPEG dekompressziós folyamat a következő szakaszokból áll:

  1. Entrópia (pl. Huffman) dekompresszió végrehajtása
  2. Dekantizálás végrehajtása
  3. Inverz különálló koszinusz átalakítás végrehajtása
  4. CbCr adatokon végzett chroma-erősítő műveletek
  5. YCbCr adatok konvertálása RGBA-ra (ha szükséges)

Ha a JPEG-kodek YC-t hoz létrebCr adatokat, elkerülhetjük a dekódolási folyamat utolsó két lépését, vagy elhalaszthatjuk őket a GPU-ra. Az előző szakaszban felsorolt memóriamegtakarítások mellett ez jelentősen csökkenti a kép dekódolásához szükséges teljes időt. Ugyanez a megtakarítás vonatkozik az YCbCr adatok kódolására.

JPEG YCbCr data használata

Ez a szakasz bemutatja, hogyan használható a WIC és a Direct2D az YCbCr adatokon való működésre.

A jelen dokumentumban a gyakorlatban használt útmutatást a Direct2D- és WIC-minta JPEG YCbCr-optimalizálási tekinti meg, amely bemutatja az YC-bCr tartalom dekódolásához és rendereléséhez szükséges lépéseket a Direct2D-alkalmazásokban.

YCbCr JPEG-képek használata

A JPEG-képek túlnyomó többsége YCbCr. Egyes JPEG-k CMYK- vagy szürkeárnyalatos adatokat tartalmaznak, és nem használják az YCbCr. Ez azt jelenti, hogy általában, de nem mindig, közvetlenül használhatja a már meglévő JPEG-tartalmakat módosítások nélkül.

A WIC és a Direct2D nem támogat minden lehetséges YC-bCr konfigurációt, és az YCbCr támogatása a Direct2D-ben a mögöttes grafikus hardvertől és illesztőprogramtól függ. Emiatt egy általános célú képalkotó folyamatnak robusztusnak kell lennie az YCbCr (beleértve az egyéb gyakori képformátumokat, például a PNG-t vagy a BMP-t), vagy olyan esetekben, amikor az YCbCr támogatása nem érhető el. Javasoljuk, hogy tartsa meg a meglévő BGRA-alapú képalkotó folyamatot, és ha elérhető, engedélyezze az YCbCr teljesítményoptimalizálásként.

Windows képalkotó összetevő API-k

A WiC a Windows 8.1-ben három új felületet ad hozzá, hogy hozzáférést biztosítson a JPEG YCbCr adatokhoz.

IWICPlanarBitmapSourceTransform

IWICPlanarBitmapSourceTransform hasonló az IWICBitmapSourceTransform, azzal a kivételével, hogy síkkonfigurációban állít elő képpontokat, beleértve az YCbCr adatokat. Ezt a felületet úgy szerezheti be, hogy meghívja a QueryInterface-t IWICBitmapSource implementációján, amely támogatja a planáris hozzáférést. Ez magában foglalja a JPEG-kodek implementációját IWICBitmapFrameDecode, valamint IWICBitmapScaler, IWICBitmapFlipRotatorés IWICColorTransform.

IWICPlanarBitmapFrameEncode

IWICPlanarBitmapFrameEncode lehetővé teszi a planáris képpontadatok kódolását, beleértve az YCbCr adatokat. Ezt a felületet a QueryInterface meghívásával szerezheti be a JPEG-kodek IWICBitmapFrameEncode.

IWICPlanarFormatConverter

IWICPlanarFormatConverter lehetővé teszi, hogy IWICFormatConverter használjon planáris képpontadatokat, beleértve az YCbCr, és átalakítsa a képpontok közötti formátumba. Nem teszi elérhetővé az interleaved pixeladatok planáris formátummá alakításának lehetőségét. Ezt a felületet a QueryInterface meghívásával szerezheti be a IWICFormatConverterwindowsos verziójában.

Direct2D API-k

A Windows 8.1-ben a Direct2D támogatja az YCbCr planar pixeladatokat az új YCbCr képeffektussal. Ez az effektus lehetővé teszi az YCbCr adatok megjelenítését. Az effektus bemenetként két ID2D1Bitmap interfészt használ: az egyik a planáris Y adatokat tartalmazza DXGI_FORMAT_R8_UNORM formátumban, a másik pedig a DXGI_FORMAT_R8G8_UNORM formátumú, interleaved CbCr-adatokat. Ezt az effektust általában az ID2D1Bitmap helyett használja, amely BGRA képpontadatokat tartalmazott volna.

Az YCbCr képeffektust a WIC YCbCr API-kkal együtt kell használni, amelyek az YCbCr adatokat biztosítják. Ez hatékonyan működik a dekódolási munka egy részének kiszervezéséhez a PROCESSZORról a GPU-ra, ahol sokkal gyorsabban és párhuzamosan feldolgozható.

Annak meghatározása, hogy az YCbCr Konfiguráció támogatott-e

Ahogy korábban említettük, az alkalmazásnak robusztusnak kell lennie azokban az esetekben, amikor az YCbCr támogatása nem érhető el. Ez a szakasz azokat a feltételeket ismerteti, amelyeket az alkalmazásnak ellenőriznie kell. Ha az alábbi ellenőrzések bármelyike sikertelen, az alkalmazásnak vissza kell esnie egy szabványos BGRA-alapú folyamatra.

Támogatja a WIC-összetevő az YCbCr adathozzáférést?

Csak a Windows által biztosított JPEG-kodek és bizonyos WIC-átalakítások támogatják az YCbCr adathozzáférést. A teljes listát a Windows képalkotó összetevő API-k szakaszában találja.

Az YCbCr interfészek egyikének beszerzéséhez hívja meg a QueryInterface-t az eredeti felületen. Ez sikertelen lesz, ha az összetevő nem támogatja az YCbCr adathozzáférést.

Támogatott a kért WIC-átalakítás az YCbCr?

Egy IWICPlanarBitmapSourceTransformbeszerzése után először meg kell hívnia DoesSupportTransform. Ez a metódus bemeneti paraméterekként veszi figyelembe az YC planáris YC-re alkalmazni kívánt átalakítások teljes készletét,bCr adatokat, és egy logikai értéket ad vissza, amely a támogatást jelzi, valamint a visszaadható kért mérethez legközelebbi dimenziókat. A képpontadatok IWICPlanarBitmapSourceTransform::CopyPixels.

Ez a minta hasonló az IWICBitmapSourceTransformhasználatához.

Támogatja a grafikus illesztőprogram az YCbCr a Direct2D-vel való használatához szükséges funkciókat?

Ez az ellenőrzés csak akkor szükséges, ha a Direct2D YCbCr effektust használja az YCbCr tartalom megjelenítéséhez. A Direct2D az YCbCr adatokat tárolja a DXGI_FORMAT_R8_UNORM és DXGI_FORMAT_R8G8_UNORM képpontformátumok használatával, amelyek nem minden grafikus illesztőprogramból érhetők el.

Az YCbCr képeffektus használata előtt hívja meg ID2D1DeviceContext::IsDxgiFormatSupported, hogy az illesztőprogram mindkét formátumot támogassa.

Mintakód

Az alábbiakban egy kód példája mutatja be az ajánlott ellenőrzéseket. Ez a példa a JPEG YCbCr-optimalizálásokból származik a Direct2D- és WIC-minta.

bool DirectXSampleRenderer::DoesWicSupportRequestedYCbCr()
{
    ComPtr<IWICPlanarBitmapSourceTransform> wicPlanarSource;
    HRESULT hr = m_wicScaler.As(&wicPlanarSource);
    if (SUCCEEDED(hr))
    {
        BOOL isTransformSupported;
        uint32 supportedWidth = m_cachedBitmapPixelWidth;
        uint32 supportedHeight = m_cachedBitmapPixelHeight;
        DX::ThrowIfFailed(
            wicPlanarSource->DoesSupportTransform(
                &supportedWidth,
                &supportedHeight,
                WICBitmapTransformRotate0,
                WICPlanarOptionsDefault,
                SampleConstants::WicYCbCrFormats,
                m_planeDescriptions,
                SampleConstants::NumPlanes,
                &isTransformSupported
                )
            );

        // The returned width and height may be larger if IWICPlanarBitmapSourceTransform does not
        // exactly support what is requested.
        if ((isTransformSupported == TRUE) &&
            (supportedWidth == m_cachedBitmapPixelWidth) &&
            (supportedHeight == m_cachedBitmapPixelHeight))
        {
            return true;
        }
    }

    return false;
}

bool DirectXSampleRenderer::DoesDriverSupportYCbCr()
{
    auto d2dContext = m_deviceResources->GetD2DDeviceContext();

    return (d2dContext->IsDxgiFormatSupported(DXGI_FORMAT_R8_UNORM)) &&
        (d2dContext->IsDxgiFormatSupported(DXGI_FORMAT_R8G8_UNORM));
}

YC-bCr Pixel-adatok dekódolása

Ha YCbCr képpontos adatokat szeretne beszerezni, hívja meg IWICPlanarBitmapSourceTransform::CopyPixels. Ez a módszer a képpontadatokat a kitöltött WICBitmapPlane struktúrák tömbjába másolja, egyet az egyes adatsíkokhoz (például Y és CbCr). A WICBitmapPlane információkat tartalmaz a képpontadatokról, és az adatokat fogadó memóriapufferre mutat.

Ha az YCbCr pixeladatokat szeretné használni más WIC API-kkal, hozzon létre egy megfelelően konfigurált IWICBitmap, hívja meg a Zárolási a mögöttes memóriapuffer beszerzéséhez, és társítsa a puffert az YCbCr képpontadatok fogadásához használt WICBitmapPlane. Ezután használhatja a IWICBitmap normál módon.

Végül, ha meg szeretné jeleníteni az YCbCr adatait a Direct2D-ben, minden IWICBitmap létre kell hoznia egy ID2D1Bitmap, és forrásként kell használnia őket az YCbCr képeffektushoz. A WIC lehetővé teszi több planáris konfiguráció kérését. A Direct2D-vel való együttműködés során két síkot kell igényelnie, az egyiket GUID_WICPixelFormat8bppY, a másikat GUID_WICPixelFormat16bppCbCr, mivel ez a Direct2D által várt konfiguráció.

Kódminta

Az alábbiakban egy példakód látható, amely bemutatja az YCbCr adatainak a Direct2D-ben való dekódolását és renderelését. Ez a példa a JPEG YCbCr-optimalizálásokból származik a Direct2D- és WIC-minta.

void DirectXSampleRenderer::CreateYCbCrDeviceResources()
{
    auto wicFactory = m_deviceResources->GetWicImagingFactory();
    auto d2dContext = m_deviceResources->GetD2DDeviceContext();

    ComPtr<IWICPlanarBitmapSourceTransform> wicPlanarSource;
    DX::ThrowIfFailed(
        m_wicScaler.As(&wicPlanarSource)
        );

    ComPtr<IWICBitmap> bitmaps[SampleConstants::NumPlanes];
    ComPtr<IWICBitmapLock> locks[SampleConstants::NumPlanes];
    WICBitmapPlane planes[SampleConstants::NumPlanes];

    for (uint32 i = 0; i < SampleConstants::NumPlanes; i++)
    {
        DX::ThrowIfFailed(
            wicFactory->CreateBitmap(
                m_planeDescriptions[i].Width,
                m_planeDescriptions[i].Height,
                m_planeDescriptions[i].Format,
                WICBitmapCacheOnLoad,
                &bitmaps[i]
                )
            );

        LockBitmap(bitmaps[i].Get(), WICBitmapLockWrite, nullptr, &locks[i], &planes[i]);
    }

    DX::ThrowIfFailed(
        wicPlanarSource->CopyPixels(
            nullptr, // Copy the entire source region.
            m_cachedBitmapPixelWidth,
            m_cachedBitmapPixelHeight,
            WICBitmapTransformRotate0,
            WICPlanarOptionsDefault,
            planes,
            SampleConstants::NumPlanes
            )
        );

    DX::ThrowIfFailed(d2dContext->CreateEffect(CLSID_D2D1YCbCr, &m_d2dYCbCrEffect));

    ComPtr<ID2D1Bitmap1> d2dBitmaps[SampleConstants::NumPlanes];
    for (uint32 i = 0; i < SampleConstants::NumPlanes; i++)
    {
        // IWICBitmapLock must be released before using the IWICBitmap.
        locks[i] = nullptr;

        // First ID2D1Bitmap1 is DXGI_FORMAT_R8 (Y), second is DXGI_FORMAT_R8G8 (CbCr).
        DX::ThrowIfFailed(d2dContext->CreateBitmapFromWicBitmap(bitmaps[i].Get(), &d2dBitmaps[i]));
        m_d2dYCbCrEffect->SetInput(i, d2dBitmaps[i].Get());
    }
}

void DirectXSampleRenderer::LockBitmap(
    _In_ IWICBitmap *pBitmap,
    DWORD bitmapLockFlags,
    _In_opt_ const WICRect *prcSource,
    _Outptr_ IWICBitmapLock **ppBitmapLock,
    _Out_ WICBitmapPlane *pPlane
    )
{
    // ComPtr guarantees the IWICBitmapLock is released if an exception is thrown.
    ComPtr<IWICBitmapLock> lock;
    DX::ThrowIfFailed(pBitmap->Lock(prcSource, bitmapLockFlags, &lock));
    DX::ThrowIfFailed(lock->GetStride(&pPlane->cbStride));
    DX::ThrowIfFailed(lock->GetDataPointer(&pPlane->cbBufferSize, &pPlane->pbBuffer));
    DX::ThrowIfFailed(lock->GetPixelFormat(&pPlane->Format));
    *ppBitmapLock = lock.Detach();
}

YCbCr Pixel-adatok átalakítása

Az YCbCr adatok átalakítása majdnem megegyezik a dekódolással, mivel mindkettő IWICPlanarBitmapSourceTransform. Az egyetlen különbség az, hogy melyik WIC-objektumból szerezte be a felületet. A Windows által biztosított skálázó, tükröző forgató és színátalakítás mind támogatja az YCbCr hozzáférést.

Az átalakítások összeláncolása

A WIC támogatja a több átalakítás összekapcsolásának fogalmát. Létrehozhatja például a következő WIC-folyamatot:

egy jpeg dekóderrel kezdődő wic-folyamat diagramját.

Ezután meghívhatja a QueryInterface-t az IWICColorTransform a IWICPlanarBitmapSourceTransformlekéréséhez. A színátalakítás képes kommunikálni az előző átalakításokkal, és elérhetővé teheti a folyamat minden szakaszának összesítő képességeit. A WIC biztosítja, hogy az YCbCr adatai a teljes folyamat során megmaradnak. Ez a láncolás csak akkor működik, ha olyan összetevőket használ, amelyek támogatják az YCbCr hozzáférést.

JPEG-kodekoptimalizálások

Az IWICBitmapSourceTransformJPEG-keretének dekódolási implementációihoz hasonlóan a JPEG-keret dekódolja IWICPlanarBitmapSourceTransform támogatja a natív JPEG DCT-tartományméretezést és -forgatást. Két leskálázási vagy forgatási teljesítményt kérhet közvetlenül a JPEG-dekóderből. Ez általában jobb minőséget és teljesítményt eredményez, mint a különálló átalakítások használata.

Emellett, ha egy vagy több WIC-átalakítást a JPEG-dekóder után láncba kapcsol, a natív JPEG skálázást és forgatást is használhatja az összesített kért művelet kielégítése érdekében.

Átalakítások formázása

A IWICPlanarFormatConverter használatával YC planáris YC-bCr képpontos adatokká alakíthatók át, például GUID_WICPixelFormat32bppPBGRA. A Windows 8.1 WIC nem teszi lehetővé a sík YC-vé való konvertálást,bCr képpontformátumba.

YCbCr Pixel-adatok kódolása

A IWICPlanarBitmapFrameEncode használatával YCbCr képpontadatokat kódolhat a JPEG-kódolóba. Az YCbCr adatok IWICPlanarBitmapFrameEncode kódolása hasonló, de nem azonos az IWICBitmapFrameEncodehasználatával történő kódolással. A planáris felület csak a planáris keret képadatainak írását teszi lehetővé, és továbbra is a keretkódoló felület használatával állítsa be a metaadatokat vagy a miniatűröket, és véglegesítse a művelet végén.

A tipikus esetben kövesse az alábbi lépéseket:

  1. Szerezze be a IWICBitmapFrameEncode a szokásos módon. Ha a chroma-részminta-készítést szeretné konfigurálni, állítsa be a JpegYCrCbSubsampling kódolót a keret létrehozásakor.
  2. Ha metaadatokat vagy miniatűröket kell beállítania, ezt a szokásos módon IWICBitmapFrameEncode használatával teheti meg.
  3. QueryInterface a IWICPlanarBitmapFrameEncode.
  4. Állítsa be az YCbCr képpontadatokat IWICPlanarBitmapFrameEncode::WriteSource vagy IWICPlanarBitmapFrameEncode::WritePixels. A IWICBitmapFrameEncode megfelelőiktől eltérően ezeket a metódusokat IWICBitmapSource vagy WICBitmapPlane tömbje biztosítja, amelyek az YCbCr képpontsíkokat tartalmazzák.
  5. Ha végzett, hívja meg IWICBitmapFrameEncode::Commit.

YCbCr képpontadatok dekódolása Windows 10-ben

A Windows 10 1507-beli buildjétől kezdve a Direct2D ID2D1ImageSourceFromWicbiztosít, amely egyszerűbb módja a JPEG-k Direct2D-be való dekódolásának, miközben kihasználja az YCbCr optimalizálásokat. ID2D1ImageSourceFromWic automatikusan elvégzi az összes szükséges YC-bCr képesség-ellenőrzést; lehetőség szerint az optimalizált codepathot használja, máskülönben tartalékot használ. Emellett új optimalizálásokat is lehetővé tesz, például csak a kép egy adott időpontban szükséges alrégióit gyorsítótárazhatja.

Az ID2D1ImageSourceFromWichasználatáról a Direct2D Fényképbeállítási SDK mintatalál.