summaryrefslogtreecommitdiffstats
path: root/video/zimg.c
Commit message (Collapse)AuthorAgeFilesLines
* options: change option macros and all option declarationswm42020-03-181-14/+13
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Change all OPT_* macros such that they don't define the entire m_option initializer, and instead expand only to a part of it, which sets certain fields. This requires changing almost every option declaration, because they all use these macros. A declaration now always starts with {"name", ... followed by designated initializers only (possibly wrapped in macros). The OPT_* macros now initialize the .offset and .type fields only, sometimes also .priv and others. I think this change makes the option macros less tricky. The old code had to stuff everything into macro arguments (and attempted to allow setting arbitrary fields by letting the user pass designated initializers in the vararg parts). Some of this was made messy due to C99 and C11 not allowing 0-sized varargs with ',' removal. It's also possible that this change is pointless, other than cosmetic preferences. Not too happy about some things. For example, the OPT_CHOICE() indentation I applied looks a bit ugly. Much of this change was done with regex search&replace, but some places required manual editing. In particular, code in "obscure" areas (which I didn't include in compilation) might be broken now. In wayland_common.c the author of some option declarations confused the flags parameter with the default value (though the default value was also properly set below). I fixed this with this change.
* zimg: fix previous odd sizes commitwm42020-02-131-4/+2
| | | | | | | | | Obviously, we don't want to lose fractions, and the zimg active_region fields in fact have the type double. The integer division was wrong. Also, always set active_region.width/height. It appears zimg behavior does not change if they're set to the normal integer values, so the extra check to not set them in this case was worthless.
* zimg: correct output to odd (chroma un-aligned) sizeswm42020-02-121-10/+18
| | | | | | | | | | As suggested by the zimg author: active_region is not supported on outputs (and the API returns an error), so instead scale to the "full" surface, but adjust the source rectangle such that the cropped output image happens to cover the correct region. Does this even work? Since Balmer Peak doesn't work, I can't really say, but it seems to look correct.
* zimg: fix typos in a commentwm42020-02-121-3/+2
| | | | | | Also remove the "o" case, which was never implemented (probably was an idea to output alpha formats, now obsoleted by zimg's full alpha support).
* zimg: add pal8 unpackerwm42020-02-101-0/+39
| | | | Some pngs are paletted, so this is vaguely interesting.
* zimg: rename zplanes fieldwm42020-02-101-4/+4
| | | | | | | | | This was a confusing name, because 1. there's also a z_planes[] field, and 2. it was not specific to zimg indexes. Possibly there used to be an idea involved about supporting alpha to non-alpha formats by discarding the alpha plane, but zimg does this now (and zimg will correctly blend the alpha component too).
* zimg: support gray/alpha conversionwm42020-02-101-6/+19
| | | | | | | | | | | | | | | | | | | | | | | | | | The special thing about this format is 1. mpv assigns the component ID 4 to alpha, and component IDs 2 and 3 are not present, which causes some messy details. 2. zimg always wants the alpha plane as plane 3, and plane 1 and 2 are not present, while FFmpeg/mpv put the alpha plane as plane 1. In theory, 2. could be avoided, since FFmpeg actually doesn't have a any 2 plane formats (alpha is either packed, or plane 3). But having to skip "empty" planes would break expectations. zplanes is not equivalent to the mpv plane count (actually it was always used this way), while zimg does not really have a plane count, but does, in this case, only use plane 0 and 3, while 2 and 3 are unused and unset. z_planes[] (not zplanes) is now always valid for all 4 array entries (because it uses zimg indexes), but a -1 entry means it's an unused plane. I wonder if these conventions taken by mpv/zimg are not just causing extra work. Maybe component IDs should just be indexes by the "natural" order (e.g. R-G-B-A, Y-U-V-A, Y-A), and alpha should be represented as a field that specifies the component ID for it, or just strictly assume that 2/4 component formats always use the last component for alpha.
* zimg: fix some confusion about plane permutationwm42020-02-101-4/+9
| | | | | | | | | | | | | We reorder the planes between mpv and zimg conventions. It turns out the code still confused when which convention was used. So the way it actually works is that the _only_ place where zimg order is used is the zimg_image_buffer.plane[] array. plane_aligned[] and zmask[] were accessed incorrectly, although I guess it rarely had a reason to fail (plane reordering is mostly for RGB, which has planes of all the same size). Adjust some comments accordingly too.
* zimg: add alpha supportwm42020-02-091-18/+63
| | | | | | | | | | | libzimg recently added direct alpha support and new API for it. (The API change is rather minimal, and it turns out we can easily support old and new zimg versions.) This does not support _all_ alpha formats. For example, gray + alpha is not supported yet, because my stupid design in the zimg wrapper would require a planar gray + alpha format, while ffmpeg provides only a packed one.
* DOCS/contribute.md, zimg: remove 2 instances of an extraneous "s"wm42019-11-071-1/+1
|
* zimg: support subsampled chroma with non-aligned image sizeswm42019-11-021-2/+9
|
* zinmg: stop using GBRP for RGBwm42019-11-021-23/+28
| | | | | | | | | | | | | | | Instead, use a YUV planar format. It doesn't matter, since we use the format only internally and for "management" purposes. We're only interested in the physical layout, not what colorspace FFmpeg "forcibly" associates with it. Also get rid of using the old and slightly sketchy mp_imgfmt_find() function. Yep, the IMGFMT_RGB30 now "constructs" the planar format, instead of using a pixfmt constant. Slightly inconvenient, tricky, and fragile, but I like it, so bugger off. This whole thing gets rid of some of the strange plane permutations that were needed earlier.
* zimg: correct RGB30 order (probably)wm42019-11-021-1/+1
| | | | | | | | According to the definition of the GL format, and the definition in img_format.h, and the actual output by vo_gpu, the order of components was probably wrong. It's exceedingly likely that the vo_drm format (for which this was originally written) has the same layout, so this was probably a bug from when the zimg wrapper code was refactored.
* zimg: make --zimg-fast=yes defaultwm42019-11-021-0/+1
| | | | | | This is mostly just because of the odd RGB default gamma issue, which shouldn't have any real impact. This also sets allow_approximate_gamma, which I hope is fine for normal use cases.
* zimg: pass through Y plane when repacking nv12wm42019-11-021-31/+38
| | | | | | | | | | | | | | | Normally, the Y plane can just be passed directly to zimg, and only the chroma plane needs to be (de)interleaved. It still needs a copy if the Y pointer is not aligned, though. (Whether this is actually a problem depends on the CPU and probably zimg's compiler.) This requires deciding per plane whether the plane should go through the repack buffer or not. This logic is active in non-nv12 cases, because not doing so would require extra code (maybe 2 lines or so). repack_align is now always called, even if it's planar->planar with all input aligned, but it won't actually do anything in that case. The assumption is that zimg won't change behavior if you pass a callback that does nothing versus passing NULL as callback.
* zimg: add semi-planar repackerwm42019-11-021-1/+123
| | | | | | | | | | | | | | | | This is for formats like nv12 (including p010, nv24, etc.). Might be important for hardware decoding. Previously, this would have forced a libswscale fallback. The genericism makes this only slightly more complicated. The main complication is due to the fact that mixing planar and packed stuff is insane (thanks, Nvidia). P010 output will actually happily set any of the 6 bit "padding" LSB, that are normally supposed to be 0 (for unpadded data there is P016). Scaling happens with 16 bit precision. Not going to bother adding an extra packer which zeros them out, or with shifting them in packing/unpacking. Lets just hope nobody notices.
* zimg: fix out of bounds memory accesses due to broken zmaskwm42019-11-021-39/+37
| | | | | | | | | We've set all planes to the same zmask. But for subsampled chroma, the zmask obviously needs to be smaller. This could lead to out of bounds memory read and write accesses. Move the align repacker to a single function, since this is now more convenient.
* zimg: add more packers/unpackerswm42019-10-311-59/+106
| | | | | | | | This probably covers all packed formats which have byte-aligned component, no alpha, and no subsampling. Everything else needs more imgfmt metadata, or something even more complicated. Alpha is primarily not supported, because zimg requires a second scaler instance for it, and handling packing/unpacking with it is an unacceptable mess.
* sws_utils, zimg: destroy vo_x11 and vo_drm performancewm42019-10-311-29/+40
| | | | | | | | | | | | | | | | | | | | | | | | | Raise swscale and zimg default parameters. This restores screenshot quality settings (maybe) unset in the commit before. Also expose some more libswscale and zimg options. Since these options are also used for VOs like x11 and drm, this will make x11/drm/etc. much slower. For compensation, provide a profile that sets the old option values: sw-fast. I'm also enabling zimg here, just as an experiment. The core problem is that we have a single set of command line options which control the settings used for most swscale/zimg uses. This was done in the previous commit. It cannot differentiate between the VOs, which need to be realtime and may accept/require lower quality options, and things like screenshots or vo_image, which can be slower, but should not sacrifice quality by default. Should this have two sets of options or something similar to do the right thing depending on the code which calls libswscale? Maybe. Or should I just ignore the problem, make it someone else's problem (users who want to use software conversion VOs), provide a sub-optimal solution, and call it a day? Definitely, sounds good, pushing to master, goodbye.
* sws_utils: shuffle around some shitwm42019-10-311-4/+19
| | | | | | | | | | | Purpose uncertain. I guess it's slightly better, maybe. The move of the sws/zimg options from VO opts (vo_opt_list) to the top-level option list is tricky. VO opts have some helper code in vo.c, that sends VOCTRL_SET_PANSCAN to the VO on every VO opts change. That's because updating certain VO options used to be this way (and not just the panscan option). This isn't needed anymore for sws/zimg options, so explicitly move them away.
* Use mp_log2() instead of av_log2()wm42019-10-311-3/+3
|
* zimg: minor name consistency improvementwm42019-10-211-3/+3
| | | | | Now these are like x2ccc10_pack: MSB to LSB, with bit width following each component (except for components with the same bit width).
* zimg: support RGB30 outputwm42019-10-201-1/+30
| | | | This may be used later elsewhere.
* zimg: move component order arrays to top of filewm42019-10-201-4/+6
|
* zimg: support 3 component 16 bit pixel unpackingwm42019-10-201-0/+22
| | | | | | Works for RGB (e.g. rgb48le) and XYZ. It's unsure whether XYZ is really correctly converted.
* zimg: avoid theoretical FFmpeg planar RGB/YUV mixupwm42019-10-201-5/+17
| | | | | | | | | | | | | The RGB pack/unpack code in theory supports packed, non-subsampled YUV, although in practice FFmpeg defines no such formats. (Only one with alpha, but all alpha input is rejected by the current code.) This would in theory have failed, because we would have selected a GBRP format (instead of YUV), which makes no sense and would either have been rejected by zimg (inconsistent parameters), or lead to broken output (wrong permutation of planes). Select the correct format and don't permute the planes in the YUV case.
* zimg: add some more colorspace mappingswm42019-10-201-5/+5
| | | | | | | As suggested by the zimg author. This is mostly related to XYZ support. It's unclear whether this works. Using the only XYZ test sample we know, and the next commits to consume the pixfmt, it looks wrong.
* video: add zimg wrapperwm42019-10-201-0/+608
This provides a very similar API to sws_utils.h, which can be used to convert and scale from one mp_image to another. This commit adds only the code, but does not use it anywhere. The code is quite preliminary and barely tested. It supports only a few pixel formats, and will return failure for many others. (Unlike libswscale, which tries to support anything that FFmpeg knows.) zimg itself accepts only planar formats. Supporting other formats requires manual packing/unpacking. (Compared to libswscale, the zimg API is generally lower level, but allows for more flexibility.) Only BGR0 output was actually tested. It appears to work.