From 176f422213a6a72529f8a6394c34b06ff04f2fb3 Mon Sep 17 00:00:00 2001 From: wm4 Date: Tue, 19 May 2020 23:58:36 +0200 Subject: video: shuffle imgfmt metadata code around I guess I decided to stuff it all into mp_imgfmt_desc (the "old" struct). This is probably a mistake. At first I was afraid that this struct would get too fat (probably justified, and hereby happened), but on the other hand mp_imgfmt_get_desc() (which builds the struct) calls the former mp_imgfmt_get_layout(), and the separation doesn't make too much sense anyway. Just merge them. Still, try to keep out the extra info for packed YUV bullshit. I think the result is OK, and there's as much information as there was before. The test output changes a little. There's no independent bits[] array anymore, so formats which did not previously have set this now show it. (These formats are mpv-only and are still missing the metadata. To be added later). Also, the output for the cursed packed formats changes. --- video/img_format.h | 108 ++++++++++++++++++++++++----------------------------- 1 file changed, 49 insertions(+), 59 deletions(-) (limited to 'video/img_format.h') diff --git a/video/img_format.h b/video/img_format.h index 712937292e..92e1716ca9 100644 --- a/video/img_format.h +++ b/video/img_format.h @@ -34,6 +34,10 @@ // All pixels start in byte boundaries #define MP_IMGFLAG_BYTE_ALIGNED 0x1 +// mp_imgfmt_desc.comps[] is set to useful values. Some types of formats will +// use comps[], but not set this flag, because it doesn't cover all requirements +// (for example MP_IMGFLAG_PACKED_SS_YUV). +#define MP_IMGFLAG_HAS_COMPS (1 << 1) // set if (possibly) alpha is included (might be not definitive for packed RGB) #define MP_IMGFLAG_ALPHA 0x80 // set if it's YUV colorspace @@ -63,6 +67,30 @@ // Semi-planar YUV formats, like AV_PIX_FMT_NV12. #define MP_IMGFLAG_YUV_NV 0x80000 +// Packed, sub-sampled YUV format. Does not apply to packed non-subsampled YUV. +// These formats pack multiple pixels into one sample with strange organization. +// In this specific case, mp_imgfmt_desc.align_x gives the size of a "full" +// pixel, which has align_x luma samples, and 1 chroma sample of each Cb and Cr. +// mp_imgfmt_desc.comps describes the chroma samples, and the first luma sample. +// All luma samples have the same configuration as the first one, and you can +// get their offsets with mp_imgfmt_get_packed_yuv_locations(). Note that the +// component offsets can be >= bpp[0]; the actual range is bpp[0]*align_x. +// These formats have no alpha. +#define MP_IMGFLAG_PACKED_SS_YUV (1 << 20) + +#define MP_NUM_COMPONENTS 4 + +struct mp_imgfmt_comp_desc { + // Plane on which this component is. + uint8_t plane; + // Bit offset of first sample, from start of the pixel group (little endian). + uint8_t offset : 6; + // Number of bits used by each sample. + uint8_t size : 6; + // Internal padding. See mp_regular_imgfmt.component_pad. + int8_t pad : 4; +}; + struct mp_imgfmt_desc { int id; // IMGFMT_* int avformat; // AV_PIX_FMT_* (or AV_PIX_FMT_NONE) @@ -80,10 +108,31 @@ struct mp_imgfmt_desc { // addition to chroma, and thus is not sub-sampled (uses align_x=2 instead). int8_t xs[MP_MAX_PLANES]; int8_t ys[MP_MAX_PLANES]; + + // Description for each component. Generally valid only if flags has + // MP_IMGFLAG_HAS_COMPS set. + // This is indexed by component_type-1 (so 0=R, 1=G, etc.), see + // mp_regular_imgfmt_plane.components[x] for component_type. Components not + // present, or which have an unknown layout, use size=0. Bits not covered by + // any component are random and not interpreted by any software. + // In particular, don't make the mistake to index this by plane. + struct mp_imgfmt_comp_desc comps[MP_NUM_COMPONENTS]; + + // log(2) of the word size in bytes for endian swapping that needs to be + // performed for converting to native endian. This is performed before any + // other unpacking steps, and for all data covered by bits. + // Always 0 if IMGFLAG_NE is set. + uint8_t endian_shift : 2; }; struct mp_imgfmt_desc mp_imgfmt_get_desc(int imgfmt); +// For MP_IMGFLAG_PACKED_SS_YUV formats (packed sub-sampled YUV): positions of +// further luma samples. luma_offsets must be an array of align_x size, and the +// function will return the offset (like in mp_imgfmt_comp_desc.offset) of each +// luma pixel. luma_offsets[0] == mp_imgfmt_desc.comps[0].offset. +bool mp_imgfmt_get_packed_yuv_locations(int imgfmt, uint8_t *luma_offsets); + // MP_CSP_AUTO for YUV, MP_CSP_RGB or MP_CSP_XYZ otherwise. // (Because IMGFMT/AV_PIX_FMT conflate format and csp for RGB and XYZ.) enum mp_csp mp_imgfmt_get_forced_csp(int imgfmt); @@ -96,8 +145,6 @@ enum mp_component_type { enum mp_component_type mp_imgfmt_get_component_type(int imgfmt); -#define MP_NUM_COMPONENTS 4 - struct mp_regular_imgfmt_plane { uint8_t num_components; // 1 is red/luminance/gray, 2 is green/Cb, 3 is blue/Cr, 4 is alpha. @@ -141,63 +188,6 @@ struct mp_regular_imgfmt { bool mp_get_regular_imgfmt(struct mp_regular_imgfmt *dst, int imgfmt); int mp_find_regular_imgfmt(struct mp_regular_imgfmt *src); -struct mp_imgfmt_comp_desc { - // Plane on which this component is. - uint8_t plane; - // Bit offset of first sample, from start of the pixel group (little endian). - uint8_t offset : 6; - // Number of bits used by each sample. - uint8_t size : 6; - // Internal padding. See mp_regular_imgfmt.component_pad. - int8_t pad : 4; -}; - -// Describes component layout of a specific image format. -// Complements struct mp_imgfmt_desc, mp_imgfmt_get_component_type(), and -// mp_imgfmt_get_forced_csp(). -// struct mp_regular_imgfmt provides a simpler description in some cases. -struct mp_imgfmt_layout { - // Size of a pixel on each plane. If bits is not a multiple of 8, this is - // what FFmpeg calls a bitstream format. - // For planar sub-sampled formats, this describes a sub-sample. For - // example, with yuv420p, both luma and chroma planes use bits=8, extra_w=0. - // mp_imgfmt_desc.align_x gives the number of pixels needed to reach byte - // align. - // If extra_w>0, this is the size of extra_w+1 pixels (bundled together). - uint8_t bits[MP_MAX_PLANES]; - - // Description for each component. This is indexed by component_type-1, - // where component_type is as in mp_regular_imgfmt_plane.components[x] (so - // 1=R, 2=G, etc.). Components not present, or which have an unknown layout, - // use size=0. - struct mp_imgfmt_comp_desc comps[MP_NUM_COMPONENTS]; - - // If !=0, this gives the word size in bytes for endian swapping that needs - // to be performed for converting to native endian. This is performed before - // any other unpacking steps, and for all data covered by bits. - uint8_t endian_bytes : 4; - - // Number of extra pixels in a pixel group. Packed, sub-sampled YUV formats - // use extra_w>0. There are no other types of formats that use this. Packed - // sub-sampled is defined as mixed non-sub-sampled (luma, alpha) and sub- - // sampled (chroma) components on the same plane. There are extra_w+1 luma - // samples in the pixel group, but only 1 chroma sample of each type. - // NB: mp_imgfmt_desc.align_x gives the number of pixels needed to get a - // "super pixel" with full chroma information, even for w=1 formats. - uint8_t extra_w : 4; - - // For packed sub-sampled YUV: positions of further luma samples. Generally, - // you can access extra_luma_offsets[x] for (x >= 0 && x < extra_w). Luma - // sample 0 is described in comps[0]; luma sample N (N>1) uses all fields in - // comps[0], except offset=extra_luma_offsets[N-1]. - // In theory, alpha also requires extra offsets, but we do not support any - // packed YUV formats with alpha and sub-sampled chroma. - uint8_t extra_luma_offsets[3]; -}; - -// Return description for the given format, or desc={0} if unavailable. -void mp_imgfmt_get_layout(int imgfmt, struct mp_imgfmt_layout *desc); - // If imgfmt is valid, and there exists a format that is exactly the same, but // has inverse endianness, return this other format. Otherwise return 0. int mp_find_other_endian(int imgfmt); -- cgit v1.2.3