Class YuvConverter
Any bit depth in, eight bits out. The matrix is worked in the picture's own code space,
which is what VideoColor's depth-taking accessors describe, and the result is scaled to
[0..255] at the very end, so a 10-bit picture is decoded at 10 bits and quantized once,
rather than being quantized to eight and then decoded. The output is deliberately eight bits
because this path exists to produce an ordinary RGBA image; a consumer that wants the extra
precision uploads the planes to a device instead.
Allocation-free: the destination is supplied by the caller and reused, and the conversion itself creates nothing. A 1080p picture is about 8 MB of output, so allocating one per picture is roughly 250 MB a second at 30 per second.
Chroma is upsampled by replication: the chroma sample for a pixel is the one at that pixel's coordinates shifted down by the format's subsampling, with no interpolation. That is exact for odd sizes by construction, because a chroma plane's dimensions are the frame's rounded up. It is also reproducible elsewhere: a device sampler in nearest-neighbour mode produces identical results, whereas interpolation weights differ between implementations and could not be matched exactly. Interpolating additionally requires knowing where chroma samples sit relative to luma, which a stream signals and which nothing here carries.
Output is straight (non-premultiplied) RGBA, row-major, row 0 at the top, alpha a constant
255. Each channel is rounded half-up and then clamped to [0..255]; the clamp is not
defensive, because legal studio-range codes decode outside that interval by design and a cast
without it wraps a highlight to a dark speckle.
-
Method Summary
Modifier and TypeMethodDescriptionstatic voidconvertPixel(VideoColor color, int bitDepth, int y, int cb, int cr, int[] out) Converts one YCbCr triple, for a test or a single-pixel probe.static voidtoRgba8(VideoFrame frame, byte[] dst, int dstOffset, int dstStride) Converts the whole offrameintodst.
-
Method Details
-
toRgba8
Converts the whole offrameintodst.Sample codes are read unsigned; the frame's own layout supplies the plane geometry, so a caller never re-derives a chroma size and cannot round it differently from the producer that filled it. The planes are read by absolute index, so their position and limit are left exactly as they were and a caller may convert a frame whose planes it is also reading relatively.
- Parameters:
dst- destination, at leastdstOffset + dstStride * (height - 1) + width * 4bytes; never allocated here and never resizeddstOffset- index indstof the first byte of row 0, at least 0dstStride- bytes between the starts of consecutive destination rows, at leastwidth * 4- Throws:
IllegalStateException- if the frame has been releasedIllegalArgumentException- if the stride is below the row's byte width, the offset is negative, or the destination is too smallNullPointerException- ifframeordstis null
-
convertPixel
Converts one YCbCr triple, for a test or a single-pixel probe. Codes are taken as unsigned values in[0..(1 << bitDepth) - 1]; results outside that range are clamped, so footroom and headroom codes give clamped black and white rather than wrapping.The output stays in the picture's code space rather than being brought to eight bits: this is the matrix alone, which is what makes it the reference
toRgba8(VideoFrame, byte[], int, int)is asserted against; that method is this arithmetic followed by one scale to eight bits.- Parameters:
bitDepth- valid bits per component, in[8..16](PixelFormat.bitDepth())out- a four-element array receiving red, green, blue and an opaque alpha, each in[0..(1 << bitDepth) - 1]- Throws:
IllegalArgumentException- if any code is outside the depth's range,bitDepthis outside[8..16], oroutis shorter than fourNullPointerException- ifcolororoutis null
-