Delen via


JPEG YCbCr-ondersteuning

Vanaf Windows 8.1 ondersteunt de WIC-codec (Windows Imaging Component) JPEG-codec het lezen en schrijven van afbeeldingsgegevens in de systeemeigen YC-bCr formulier. WIC YCbCr ondersteuning kan worden gebruikt in combinatie met Direct2D- om YC-bCr pixelgegevens weer te geven met een afbeeldingseffect. Bovendien kan de WIC JPEG-codec YCbCr pixelgegevens gebruiken die door bepaalde camerastuurprogramma's worden geproduceerd via Media Foundation.

YCbCr pixelgegevens verbruikt aanzienlijk minder geheugen dan standaard-BGRA-pixelindelingen. Bovendien kunt u met toegang tot YCbCr gegevens enkele fasen van de JPEG-decodeer-/coderingspijplijn offloaden naar Direct2D. Dit is gpu versneld. Door YCbCrte gebruiken, kan uw app het JPEG-geheugenverbruik en de laadtijden voor afbeeldingen met dezelfde grootte en kwaliteit verminderen. Of uw app kan meer JPEG-afbeeldingen met een hogere resolutie gebruiken zonder dat u last hebt van prestatiestraffen.

In dit onderwerp wordt beschreven hoe YCbCr gegevens werkt en hoe u deze kunt gebruiken in WIC en Direct2D.

Over JPEG YCbCr Data

In deze sectie worden enkele belangrijke concepten uitgelegd die nodig zijn om te begrijpen hoe YCbCr ondersteuning in WIC werkt en de belangrijkste voordelen ervan.

YCbCr kleurenmodel

WIC in Windows 8 en eerder ondersteunt vier verschillende kleurenmodellen, waarvan de meest voorkomende RGB/BGR is. Dit kleurenmodel definieert kleurgegevens met behulp van rode, groene en blauwe componenten; een vierde alfacomponent kan ook worden gebruikt.

Hier volgt een afbeelding die is uitgevouwen in de rode, groene en blauwe componenten.

een afbeelding opgesplitst in de rode, groene en blauwe componenten.

YCbCr is een alternatief kleurenmodel waarmee kleurgegevens worden gedefinieerd met behulp van een luminantiecomponent (Y) en twee chrominantieonderdelen (Cb en Cr). Het wordt vaak gebruikt in digitale beeld- en videoscenario's. De term YCbCr wordt vaak door elkaar gebruikt met YUV, hoewel de twee technisch uniek zijn.

Er zijn verschillende variaties van YCbCr die verschillen in kleurruimte en dynamische bereikdefinities: WIC ondersteunt specifiek JPEG JFIF YCbCr gegevens. Raadpleeg de JPEG ITU-T81 specificatievoor meer informatie.

Hier volgt een afbeelding die is uitgevouwen in de onderdelen Y, Cben Cr.

een afbeelding in de onderdelen y, cb en cr.

Planar Versus Interleaved Memory Layouts

In deze sectie worden enkele verschillen beschreven tussen het openen en opslaan van RGB-pixelgegevens in het geheugen en YCbCr gegevens.

RGB-pixelgegevens worden doorgaans opgeslagen met behulp van een interleaved geheugenindeling. Dit betekent dat gegevens voor één kleuronderdeel tussen pixels worden gekruist en dat elke pixel aaneengesloten wordt opgeslagen in het geheugen.

Hier volgt een afbeelding met RGBA-pixelgegevens die zijn opgeslagen in een interleaved geheugenindeling.

een afbeelding met rgba pixelgegevens die zijn opgeslagen in een interleaved geheugenindeling.

YCbCr gegevens worden doorgaans opgeslagen met behulp van een planaire geheugenindeling. Dit betekent dat elk kleuronderdeel afzonderlijk wordt opgeslagen in een eigen aaneengesloten vlak, voor een totaal van drie vlakken. In een andere gemeenschappelijke configuratie worden de onderdelen Cb en Cr samen opgeslagen, terwijl het Y-onderdeel in zijn eigen vlak blijft staan voor in totaal twee vliegtuigen.

Hier volgt een afbeelding met planar Y en interleaved CbCr pixelgegevens, een gemeenschappelijke YC-bCr geheugenindeling.

een afbeelding met planaire y- en interleaved cbcr pixelgegevens, een gemeenschappelijke ycbcr-geheugenindeling.

In zowel WIC als Direct2D wordt elk kleurenvlak behandeld als een eigen afzonderlijk object (ofwel een IWICBitmapSource of ID2D1Bitmap), en vormen deze vlakken gezamenlijk de backinggegevens voor een YC-bCr afbeelding.

Hoewel WIC toegang biedt tot YCbCr gegevens in zowel de configuraties van 2 als 3 vliegtuigen, ondersteunt Direct2D alleen de voormalige (Y en CbCr). Daarom moet u bij het gebruik van WIC en Direct2D altijd de 2 vlak YC-bCr configuratie gebruiken.

Chroma-subsampling

Het YCbCr kleurenmodel is geschikt voor digitale beeldscenario's omdat het kan profiteren van bepaalde aspecten van het menselijke visuele systeem. In het bijzonder zijn mensen gevoeliger voor wijzigingen in de luminantie (helderheid) van een afbeelding en minder gevoelig voor chrominantie (kleur). Door de kleurgegevens te splitsen in afzonderlijke luminantie- en chrominantieonderdelen, kunnen we selectief alleen de chrominantiecomponenten comprimeren om ruimtebesparingen te bereiken met een minimaal verlies van kwaliteit.

Eén techniek hiervoor wordt chroma-subsampling genoemd. De C-b- en Cr- vlakken worden in een of beide horizontale en verticale dimensies subsampled (omlaag geschaald). Om historische redenen wordt elke chroma-subsamplingmodus vaak aangeduid met behulp van een verhouding van drie delen J:a:b.

Subsampling-modus Horizontale omlaag schalen Verticale omlaag schalen Bits per pixel*
4:4:4 1x 1x 24
4:2:2 2x 1x 16
4:4:0 1x 2x 16
4:2:0 2x 2x 12

 

* Bevat Y-gegevens.

Als u in de bovenstaande tabel YCbCr gebruikt om niet-gecomprimeerde afbeeldingsgegevens op te slaan, kunt u 25% tot 62,5% versus 32 bits per pixel RGBA-gegevens besparen, afhankelijk van welke chroma-subsamplingmodus wordt gebruikt.

JPEG-gebruik van YC-bCr

Op hoog niveau bestaat de JPEG-decompressiepijplijn uit de volgende fasen:

  1. Entropie uitvoeren (bijvoorbeeld Huffman) decompressie
  2. Dequantization uitvoeren
  3. Inverse discrete cosinustransformatie uitvoeren
  4. Chroma-upsampling uitvoeren op CbCr gegevens
  5. YC-bCr gegevens converteren naar RGBA (indien nodig)

Door de JPEG-codec YC te laten producerenbCr gegevens, kunnen we de laatste twee stappen van het decodeerproces vermijden of ze uitstellen naar de GPU. Naast de geheugenbesparingen die in de vorige sectie worden vermeld, vermindert dit de totale tijd die nodig is om de afbeelding te decoderen. Dezelfde besparingen gelden voor het coderen van YCbCr gegevens.

JPEG YCbCr Data gebruiken

In deze sectie wordt uitgelegd hoe u WIC en Direct2D gebruikt om te werken op YCbCr gegevens.

Zie de JPEG YCbCr-optimalisaties in Direct2D- en WIC-voorbeeld om de richtlijnen van dit document te zien die alle stappen laten zien die nodig zijn om YC-bCr-inhoud in een Direct2D-app te decoderen en weer te geven.

YCbCr JPEG-afbeeldingen gebruiken

De overgrote meerderheid van JPEG-afbeeldingen worden opgeslagen als YCbCr. Sommige JPEG's bevatten CMYK- of grijswaardengegevens en gebruiken geen YC-bCr. Dit betekent dat u doorgaans, maar niet altijd, rechtstreeks bestaande JPEG-inhoud kunt gebruiken zonder wijzigingen.

WIC en Direct2D ondersteunen niet alle mogelijke YC-bCr configuratie, en YCbCr ondersteuning in Direct2D is afhankelijk van de onderliggende grafische hardware en het stuurprogramma. Daarom moet een pijplijn voor afbeelding voor algemeen gebruik robuust zijn voor afbeeldingen die geen gebruikmaken van YCbCr (inclusief andere algemene afbeeldingsindelingen zoals PNG of BMP) of in gevallen waarin YCbCr ondersteuning niet beschikbaar is. U wordt aangeraden uw bestaande op BGRA gebaseerde imaging-pijplijn te behouden en YCbCr in te schakelen als prestatieoptimalisatie, indien beschikbaar.

Windows Imaging Component-API's

WIC in Windows 8.1 voegt drie nieuwe interfaces toe om toegang te bieden tot JPEG YC-bCr gegevens.

IWICPlanarBitmapSourceTransform

IWICPlanarBitmapSourceTransform is vergelijkbaar met IWICBitmapSourceTransform, behalve dat er pixels in een planarconfiguratie worden geproduceerd, met inbegrip van YCbCr gegevens. U kunt deze interface verkrijgen door QueryInterface aan te roepen voor een implementatie van IWICBitmapSource die ondersteuning biedt voor planaire toegang. Dit omvat de implementatie van de JPEG-codec van IWICBitmapFrameDecode en IWICBitmapScaler, IWICBitmapFlipRotatoren IWICColorTransform.

IWICPlanarBitmapFrameEncode

IWICPlanarBitmapFrameEncode biedt de mogelijkheid om planar pixelgegevens te coderen, waaronder YCbCr gegevens. U kunt deze interface verkrijgen door QueryInterface aan te roepen voor de implementatie van de JPEG-codec van IWICBitmapFrameEncode.

IWICPlanarFormat Converter

IWICPlanarFormatConverter kunt IWICFormatConverter planaire pixelgegevens gebruiken, waaronder YCbCren converteren naar een interleaved pixelindeling. Het biedt geen mogelijkheid om interleaved pixelgegevens te converteren naar een planaire indeling. U kunt deze interface verkrijgen door QueryInterface aan te roepen op de door Windows geleverde implementatie van IWICFormatConverter.

Direct2D-API's

Direct2D in Windows 8.1 ondersteunt YCbCr planaire pixelgegevens met het nieuwe YC-bCr afbeeldingseffect. Dit effect biedt de mogelijkheid om YC-bCr gegevens weer te geven. Het effect krijgt als invoer twee ID2D1Bitmap interfaces: één met planar Y-gegevens in de DXGI_FORMAT_R8_UNORM-indeling en één met interleaved CbCr-gegevens in de DXGI_FORMAT_R8G8_UNORM-indeling. Doorgaans gebruikt u dit effect in plaats van de ID2D1Bitmap die BGRA-pixelgegevens zouden bevatten.

Het effect YCbCr afbeelding moet worden gebruikt in combinatie met de WIC YCbCr-API's die de YC-bCr gegevens leveren. Dit werkt effectief om een deel van het decoderen van werk van de CPU naar de GPU te offloaden, waar het veel sneller en parallel kan worden verwerkt.

Bepalen of de YC-bCr-configuratie wordt ondersteund

Zoals eerder vermeld, moet uw app robuust zijn voor gevallen waarin YCbCr ondersteuning niet beschikbaar is. In deze sectie worden de voorwaarden besproken waarop uw app moet controleren. Als een van de volgende controles mislukt, moet uw app terugvallen op een standaardpijplijn op basis van BGRA.

Ondersteunt het WIC-onderdeel YCbCr gegevenstoegang?

Alleen de door Windows geleverde JPEG-codec en bepaalde WIC-transformaties ondersteunen YCbCr gegevenstoegang. Raadpleeg de sectie Windows Imaging Component API's voor een volledige lijst.

Als u een van de planar YC-bCr-interfaces wilt verkrijgen, roept u QueryInterface aan op de oorspronkelijke interface. Dit mislukt als het onderdeel geen ondersteuning biedt voor YCbCr gegevenstoegang.

Wordt de aangevraagde WIC-transformatie ondersteund voor YCbCr?

Nadat u een IWICPlanarBitmapSourceTransformhebt verkregen, moet u eerst DoesSupportTransformaanroepen. Deze methode gebruikt als invoerparameters de volledige set transformaties die u wilt toepassen op de planar YCbCr gegevens en retourneert een Booleaanse waarde die ondersteuning aangeeft, evenals de dichtstbijzijnde dimensies voor de aangevraagde grootte die kan worden geretourneerd. Controleer alle drie de waarden voordat u toegang krijgt tot de pixelgegevens met IWICPlanarBitmapSourceTransform::Copy Pixels.

Dit patroon is vergelijkbaar met hoe IWICBitmapSourceTransform- wordt gebruikt.

Ondersteunt het grafische stuurprogramma de functies die nodig zijn voor het gebruik van YCbCr met Direct2D?

Deze controle is alleen nodig als u de Direct2D YCbCr effect gebruikt om YC-bCr-inhoud weer te geven. Direct2D slaat YC-bCr gegevens op met behulp van de DXGI_FORMAT_R8_UNORM- en DXGI_FORMAT_R8G8_UNORM pixelindelingen, die niet beschikbaar zijn in alle grafische stuurprogramma's.

Voordat u de YCbCr afbeeldingseffect gebruikt, moet u ID2D1DeviceContext::IsDxgiFormatSupported aanroepen om ervoor te zorgen dat beide indelingen worden ondersteund door het stuurprogramma.

Voorbeeldcode

Hieronder ziet u een codevoorbeeld waarin de aanbevolen controles worden gedemonstreerd. Dit voorbeeld is genomen uit de JPEG YCbCr-optimalisaties in Direct2D- en WIC-voorbeeld.

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

Decodering van YCbCr pixelgegevens

Als u YCbCr pixelgegevens wilt verkrijgen, moet u IWICPlanarBitmapSourceTransform::Copy Pixelsaanroepen. Met deze methode worden pixelgegevens gekopieerd naar een matrix met ingevulde WICBitmapPlane structuren, één voor elk gewenste gegevensvlak (bijvoorbeeld Y en CbCr). Een WICBitmapPlane- bevat informatie over de pixelgegevens en verwijst naar de geheugenbuffer die de gegevens ontvangt.

Als u de YCbCr pixelgegevens wilt gebruiken met andere WIC-API's, moet u een correct geconfigureerde IWICBitmapmaken, vergrendelen aanroepen om de onderliggende geheugenbuffer te verkrijgen, en koppelt de buffer aan de WICBitmapPlane- die wordt gebruikt voor het ontvangen van de YC-bCr pixelgegevens. Vervolgens kunt u de IWICBitmap normaal gebruiken.

Als u ten slotte de YC-bCr gegevens in Direct2D wilt weergeven, moet u een ID2D1Bitmap maken van elke IWICBitmap en deze gebruiken als bron voor de YC-bCr afbeeldingseffect. Met WIC kunt u meerdere planaire configuraties aanvragen. Wanneer u met Direct2D werkt, moet u twee vliegtuigen aanvragen, één met behulp van GUID_WICPixelFormat8bppY en de andere met behulp van GUID_WICPixelFormat16bppCbCr, omdat dit de configuratie is die door Direct2D wordt verwacht.

Codevoorbeeld

Hieronder ziet u een codevoorbeeld waarin de stappen voor het decoderen en weergeven van YC-bCr gegevens in Direct2D worden gedecodeerd en weergegeven. Dit voorbeeld is genomen uit de JPEG YCbCr-optimalisaties in Direct2D- en WIC-voorbeeld.

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();
}

YC transformerenbCr pixelgegevens

Het transformeren van YCbCr gegevens is bijna identiek aan de decodering, omdat beide betrekking hebben op IWICPlanarBitmapSourceTransform. Het enige verschil is van welk WIC-object u de interface hebt verkregen. De door Windows geleverde scaler, flip rotator en kleurtransformatie ondersteunen YCbCr toegang.

Ketentransformaties samen

WIC ondersteunt het concept van het koppelen van meerdere transformaties. U kunt bijvoorbeeld de volgende WIC-pijplijn maken:

een diagram van een wic-pijplijn die begint met een jpeg-decoder.

Vervolgens kunt u QueryInterface aanroepen op de IWICColorTransform- om IWICPlanarBitmapSourceTransform-te verkrijgen. De kleurtransformatie kan communiceren met de voorgaande transformaties en kan de statistische mogelijkheden van elke fase in de pijplijn beschikbaar maken. WIC zorgt ervoor dat de YC-bCr- gegevens gedurende het hele proces behouden blijven. Deze koppeling werkt alleen wanneer u onderdelen gebruikt die ondersteuning bieden voor YC-bCr toegang.

JPEG-codecoptimalisaties

Net als bij de JPEG-framedecodeer implementatie van IWICBitmapSourceTransform, ondersteunt het JPEG-frame de implementatie van IWICPlanarBitmapSourceTransform systeemeigen JPEG DCT-domeinschalen en -rotatie. U kunt een stroom van twee downscale of een draaiing rechtstreeks vanaf de JPEG-decoder aanvragen. Dit resulteert doorgaans in hogere kwaliteit en prestaties dan het gebruik van de discrete transformaties.

Bovendien, wanneer u een of meer WIC-transformaties na de JPEG-decoder koppelt, kan deze gebruikmaken van systeemeigen JPEG-schaalaanpassing en -rotatie om te voldoen aan de geaggregeerde aangevraagde bewerking.

Conversies opmaken

Gebruik IWICPlanarFormatConverter om planar YCbCr pixelgegevens te converteren naar een interleaved pixelindeling zoals GUID_WICPixelFormat32bppPBGRA. WIC in Windows 8.1 biedt niet de mogelijkheid om te converteren naar een planar YCbCr pixelformaat.

Encoding YCbCr Pixel Data

Gebruik IWICPlanarBitmapFrameEncode om YC-bCr pixelgegevens te coderen naar de JPEG-encoder. Encoding YCbCr data IWICPlanarBitmapFrameEn code is vergelijkbaar, maar is niet identiek aan het coderen van interleaved gegevens met behulp van IWICBitmapFrameEncode. De planaire interface biedt alleen de mogelijkheid om planarframe-afbeeldingsgegevens te schrijven en u moet de interface voor framecode blijven gebruiken om metagegevens of een miniatuur in te stellen en aan het einde van de bewerking door te voeren.

Voor de gebruikelijke situatie moet u de volgende stappen uitvoeren:

  1. Haal de IWICBitmapFrameEncode normaal op. Als u chroma-subsampling wilt configureren, stelt u de optie JpegYCrCbSubsampling encoder in bij het maken van het frame.
  2. Als u metagegevens of een miniatuur wilt instellen, doet u dit met behulp van IWICBitmapFrameEncode als normaal.
  3. QueryInterface voor de IWICPlanarBitmapFrameEncode.
  4. Stel de YC-bCr pixelgegevens in met behulp van IWICPlanarBitmapFrameEncode::WriteSource of IWICPlanarBitmapFrameEncode::Write Pixels. In tegenstelling tot hun IWICBitmapFrameEncode tegenhangers, biedt u deze methoden een matrix van IWICBitmapSource of WICBitmapPlane- die de YC-bCr pixelvlakken bevatten.
  5. Wanneer u klaar bent, roept u IWICBitmapFrameEncode::Commitaan.

Decodering van YCbCr pixelgegevens in Windows 10

Vanaf Windows 10 build 1507 biedt Direct2D ID2D1ImageSourceFromWic, een eenvoudigere manier om JPEG's te decoderen in Direct2D terwijl u gebruikmaakt van YCbCr optimalisaties. ID2D1ImageSourceFromWic automatisch alle benodigde YC-bCr mogelijkheidscontroles voor u uitvoert; het gebruikt het geoptimaliseerde codepad indien mogelijk en maakt gebruik van een terugval anders. Het maakt ook nieuwe optimalisaties mogelijk, zoals alleen subregio's in de cache opslaan van de installatiekopieën die tegelijk nodig zijn.

Voor meer informatie over het gebruik van ID2D1ImageSourceFromWicraadpleegt u de Direct2D Photo Adjustment SDK voorbeeld.