summaryrefslogtreecommitdiffstats
path: root/video/img_format.h
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2020-05-19 23:58:36 +0200
committerwm4 <wm4@nowhere>2020-05-20 00:02:27 +0200
commit176f422213a6a72529f8a6394c34b06ff04f2fb3 (patch)
tree704624347a59a4c04a5858da4310b4ac6fad1c9e /video/img_format.h
parenta20ae0417f2d1e1a2c173f5eaf66a81974df0008 (diff)
downloadmpv-176f422213a6a72529f8a6394c34b06ff04f2fb3.tar.bz2
mpv-176f422213a6a72529f8a6394c34b06ff04f2fb3.tar.xz
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.
Diffstat (limited to 'video/img_format.h')
-rw-r--r--video/img_format.h108
1 files changed, 49 insertions, 59 deletions
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);