blob: bd1dca1f851fc9b57cf1b8f2aebc8bbb20a01c84 [file] [log] [blame]
// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
library fuchsia.images2;
using fuchsia.math;
/// Describes the format of images.
type ImageFormat = table {
/// Describes the manner in which pixels are encoded.
1: pixel_format PixelFormat;
/// Vendor-specific pixel format modifier. See format_modifier.fidl.
//
// Re. changing the type, in this particular case we'll change any impacted
// client code that needs to compile with < 19 and >= 19 SDK to make sure it
// compiles either way. The old/new types are wire compatible and there's no
// change to any defined/permitted values.
2: pixel_format_modifier PixelFormatModifier;
/// Indicates the color space used to interpret pixel values.
3: color_space ColorSpace;
/// The size of the image in pixels.
///
/// See also `bytes_per_row` which is also necessary (along with `size`) to
/// find where each pixel's data is within a buffer.
///
/// Not all of the addressable pixel positions in the buffer are necessarily
/// populated with valid pixel data. See `valid_size` for the
/// potentially-smaller rectangle of valid pixels.
///
/// The right and bottom of the image may have some valid pixels which are
/// not to be displayed. See `display_rect`.
4: size fuchsia.math.SizeU;
/// Number of bytes per row. For multi-plane YUV formats, this is the number
/// of bytes per row in the Y plane.
///
/// When this field is not set, there is no padding at the end of each row
/// of pixels. In other words, when not set, the stride is equal to the
/// "stride bytes per width pixel" times the `size.width`.
///
/// When set, the value in this field must be >= the "stride bytes per width
/// pixel" times the `size.width`. If equal, there is no padding at
/// the end of each row of pixels. If greater, the difference is how much
/// padding is at the end of each row of pixels, in bytes.
///
/// This is also known as the "stride", "line to line offset", "row to row
/// offset", and other names.
///
/// As a specific example, it's not uncommon (but also not always required)
/// for BGR24 (3 bytes per pixel) to have some padding at the end of each
/// row so that each row of pixels starts at a 4 byte aligned offset from
/// the start of the image (the upper left pixel). That padding's size is
/// not necessarily divisible by the size in bytes of a pixel ("stride bytes
/// per width pixel"), so we indicate the padding using this field rather
/// than trying to incorporate the padding as a larger "fake"
/// `size.width`.
5: bytes_per_row uint32;
/// The rect within a frame that's for display. This is the location and
/// size in pixels of the rectangle of pixels that should be displayed, when
/// displaying the "whole image" in a UI display sense.
///
/// The `x` + `width` must be <= `size.width`, and the `y` + `height` must
/// be <= `size.height`.
///
/// For output from a video decoder, pixels outside the display_rect are
/// never to be displayed (outside of test programs), but must be preserved
/// for correct decoder function. The `display_rect` will always fall
/// within the rect starting at (0, 0) and having `valid_size` size, when
/// `valid_size` is set. In other words, `display_rect` is a subset (not
/// necessarily a proper subset) of `valid_size`, and `valid_size` is a
/// subset (not necessarily a proper subset) of `size`.
///
/// Downstream texture filtering operations should avoid letting any pixel
/// outside of display_rect influence the visual appearance of any displayed
/// pixel, to avoid the potential for the right or bottom edge leaking in
/// arbitrary pixels defined by the decode process but not intended for
/// display.
///
/// Behavior when this field is not set is protocol-specific. In some
/// protocols, fallback to `valid_size`, then to `size` may be implemented.
/// In others, fallback directly to `size` may be implemented. In others,
/// this field must be set or the channel will close.
///
/// WARNING: fuchsia.sysmem.Images2 (V1) doesn't handle non-zero x, y, so
/// any non-zero x, y here (V2) will prevent conversion to V1. Due to the
/// rarity of non-zero x, y in practice, even components that have moved to
/// V2 may in some cases still assume both x and y are 0, until there's a
/// practical reason to implment and test handling of non-zero x, y. The
/// symptom of sending non-zero x, y to a downstream render and/or display
/// pipeline that assumes 0, 0 will be incorrect display, but not a crash,
/// since assuming 0, 0 for x, y does not cause reading out of buffer
/// bounds.
//
// See math.fidl for context.
@available(added=18)
6: display_rect fuchsia.math.RectU;
@available(replaced=18)
6: display_rect RectU;
/// The size of a frame in terms of the number of pixels that have valid
/// pixel data in terms of video decoding, but not in terms of which pixels
/// are intended for display.
///
/// To convert valid_size into a rect that's directly comparable to
/// `display_rect`, one can make a rect with (`x`: 0, `y`: 0, `width`:
/// `valid_size.width`, `height`: `valid_size.height`).
///
/// In the case of a video decoder, `valid_size` can include some pixels
/// outside `display_rect`. The extra pixels are not meant to be displayed,
/// and may or may not contain any real image data. Typically anything that
/// looks like real image data in these regions is only an artifact of video
/// compression and the existence of the remainder of a macroblock which can
/// be referenced by later frames despite not being within the displayed
/// region, and not really any additional "real" pixels from the source. The
/// pixel values in this region are defined by the codec decode process and
/// must be retained for correct decoder operation. Typically the pixels
/// inside valid_size but outside display_rect will be up to the size of a
/// macroblock minus 1. The `valid_size` is can be useful for testing video
/// decoders and for certain transcoding scenarios.
7: valid_size fuchsia.math.SizeU;
/// Aspect ratio of a single pixel as the video is intended to be displayed.
///
/// For YUV formats, this is the pixel aspect ratio (AKA sample aspect ratio
/// aka SAR) for the luma (AKA Y) samples.
///
/// Producers should ensure the width and height values are relatively prime
/// by reducing the fraction (dividing both by GCF) if necessary.
///
/// A consumer should interpret this field being un-set as an unknown pixel
/// aspect ratio. A default of 1:1 can be appropriate in some cases, but a
/// consumer may determine the actual pixel aspect ratio by OOB means.
8: pixel_aspect_ratio fuchsia.math.SizeU;
};
/// Expresses the manner in which video pixels are encoded.
///
/// The ordering of the channels in the format name reflects the actual layout
/// of the channel.
///
/// Each of these values is opinionated re. the color spaces that should be
/// contained within (in contrast with Vulkan).
type PixelFormat = flexible enum {
INVALID = 0;
/// RGB only, 8 bits per each of R/G/B/A sample
///
/// Compatible with VK_FORMAT_R8G8B8A8_UNORM.
R8G8B8A8 = 1;
/// RGB only, 8 bits per each of R/G/B/X sample
///
/// Compatible with VK_FORMAT_R8G8B8A8_UNORM, when treated as opaque.
R8G8B8X8 = 119;
/// 32bpp BGRA, 1 plane. RGB only, 8 bits per each of B/G/R/A sample.
///
/// Compatible with VK_FORMAT_B8G8R8A8_UNORM.
///
/// In sysmem(1), this is BGRA32.
B8G8R8A8 = 101;
/// 32bpp BGRA, 1 plane. RGB only, 8 bits per each of B/G/R/X sample.
///
/// Compatible with VK_FORMAT_B8G8R8A8_UNORM, when treated as opaque.
B8G8R8X8 = 120;
/// YUV only, 8 bits per Y sample
///
/// Compatible with VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM.
I420 = 102;
/// YUV only, 8 bits per Y sample
///
/// Not compatible with any vulkan format.
M420 = 103;
/// YUV only, 8 bits per Y sample
///
/// Compatible with VK_FORMAT_G8_B8R8_2PLANE_420_UNORM.
NV12 = 104;
/// YUV only, 8 bits per Y sample
///
/// Compatible with VK_FORMAT_G8B8G8R8_422_UNORM.
YUY2 = 105;
/// This value is reserved, and not currently used.
MJPEG = 106;
/// YUV only, 8 bits per Y sample
///
/// Compatible with VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM with B and R
/// swizzled.
YV12 = 107;
/// 24bpp BGR, 1 plane. RGB only, 8 bits per each of B/G/R sample
///
/// Compatible with VK_FORMAT_B8G8R8_UNORM.
///
/// In sysmem(1), this is BGR24.
B8G8R8 = 108;
/// 16bpp RGB, 1 plane. 5 bits R, 6 bits G, 5 bits B
///
/// Compatible with VK_FORMAT_R5G6B5_UNORM_PACK16.
///
/// In sysmem(1), this is RGB565.
R5G6B5 = 109;
/// 8bpp RGB, 1 plane. 3 bits R, 3 bits G, 2 bits B
///
/// Not compatible with any vulkan format.
///
/// In sysmem(1), this is RGB332.
R3G3B2 = 110;
/// 8bpp RGB, 1 plane. 2 bits R, 2 bits G, 2 bits B
///
/// Not compatible with any vulkan format.
///
/// In sysmem(1), this is RGB2220.
R2G2B2X2 = 111;
/// 8bpp, Luminance-only (red, green and blue have identical values.)
///
/// Compatible with VK_FORMAT_R8_UNORM.
///
/// Most clients will prefer to use R8 instead.
L8 = 112;
/// 8bpp, Red-only (Green and Blue are to be interpreted as 0).
///
/// Compatible with VK_FORMAT_R8_UNORM.
R8 = 113;
/// 16bpp RG, 1 plane. 8 bits R, 8 bits G.
///
/// Compatible with VK_FORMAT_R8G8_UNORM.
R8G8 = 114;
/// 32bpp RGBA, 1 plane. 2 bits A, 10 bits R/G/B.
///
/// Compatible with VK_FORMAT_A2R10G10B10_UNORM_PACK32.
A2R10G10B10 = 115;
/// 32bpp BGRA, 1 plane. 2 bits A, 10 bits R/G/B.
///
/// Compatible with VK_FORMAT_A2B10G10R10_UNORM_PACK32.
A2B10G10R10 = 116;
/// YUV only, 16 bits per Y sample
///
/// This is like NV12 but with 16 bit samples that have the bottom 6 bits of
/// each sample set to zero and/or ignored. The endianess of each 16 bit
/// sample is host endian-ness (LE on LE system, BE on BE system). The CbCr
/// plane has 16 bit Cb first, then 16 bit Cr, interleaved Cb Cr Cb Cr etc.
///
/// Compatible with VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16.
P010 = 117;
/// 24bpp RGB, 1 plane. RGB only, 8 bits per each of R/G/B sample
///
/// Compatible with VK_FORMAT_R8G8B8_UNORM.
R8G8B8 = 118;
/// A client is explicitly indicating that the client does not care which
/// pixel format is chosen / used. When setting this value, the client must
/// not set `pixel_format_modifier`.
DO_NOT_CARE = 0xFFFFFFFE;
};
/// Expresses the color space used to interpret video pixel values.
///
/// This list has a separate entry for each variant of a color space standard.
///
/// For this reason, should we ever add support for the RGB variant of 709, for
/// example, we'd add a separate entry to this list for that variant. Similarly
/// for the RGB variants of 2020 or 2100. Similarly for the YcCbcCrc variant of
/// 2020. Similarly for the ICtCp variant of 2100.
///
/// See ImageFormatIsSupportedColorSpaceForPixelFormat() for whether a
/// combination of `PixelFormat` and `ColorSpace` is potentially supported.
///
/// Generally, a `ColorSpace` is not supported for any `PixelFormat` whose
/// bits-per-sample isn't compatible with the color space's spec, nor for any
/// `PixelFormat` which is a mismatch in terms of RGB vs. YUV.
///
/// The "limited range" in comments below refers to where black and white are
/// defined to be (and simimlar for chroma), but should not be interpreted as
/// guaranteeing that there won't be values outside the nominal "limited range".
/// In other words, "limited range" doesn't necessarily mean there won't be any
/// values below black or above white, or outside the "limited" chroma range.
/// For "full range", black is 0 and white is the max possible/permitted numeric
/// value (and similar for chroma).
type ColorSpace = flexible enum {
/// Not a valid color space type.
INVALID = 0;
/// sRGB, gamma transfer function and full range, per spec
SRGB = 1;
/// 601 NTSC ("525 line") YCbCr primaries, limited range
REC601_NTSC = 2;
/// 601 NTSC ("525 line") YCbCr primaries, full range
REC601_NTSC_FULL_RANGE = 3;
/// 601 PAL ("625 line") YCbCr primaries, limited range
REC601_PAL = 4;
/// 601 PAL ("625 line") YCbCr primaries, full range
REC601_PAL_FULL_RANGE = 5;
/// 709 YCbCr (not RGB), limited range
REC709 = 6;
/// 2020 YCbCr (not RGB, not YcCbcCrc), 10 or 12 bit according to
/// `PixelFormat`, with primaries, limited range (not full range), transfer
/// function ("gamma"), etc all per spec, wide color gamut SDR
REC2020 = 7;
/// 2100 YCbCr (not RGB, not ICtCp), 10 or 12 bit according to
/// `PixelFormat`, BT.2020 primaries (same wide color gamut as REC2020),
/// limited range (not full range), PQ (aka SMPTE ST 2084) HDR transfer
/// function (not HLG, not SDR "gamma" used by REC2020 and REC709), wide
/// color gamut HDR
REC2100 = 8;
/// Either the pixel format doesn't represent a color, or it's in an
/// application-specific colorspace that isn't describable by another entry
/// in this enum.
PASSTHROUGH = 9;
/// A client is explicitly indicating that the client does not care which
/// color space is chosen / used.
DO_NOT_CARE = 0xFFFFFFFE;
};