Commit Graph

43 Commits

Author SHA1 Message Date
wm4 8767c46873 img_format: add some mpv-only helper formats
Utterly useless, but the intention is to make dealing with corner case
pixel formats (forced upon us by FFmpeg, very rarely) less of a pain.
The zimg wrapper will use them. (It already supports these formats
automatically, but it will help with its internals.)

Y1 is considered RGB, even though gray formats are generally treated as
YUV for various reasons. mpv will default all YUV formats to limited
range internally, which makes no sense for a 1 bit format, so this is a
problem. I wanted to avoid that mp_image_params_guess_csp() (which
applies the default) explicitly checks for an image format, so although
a bit janky, this seems to be a good solution, especially because I
really don't give a shit about these formats, other than having to
handle them. It's notable that AV_PIX_FMT_MONOBLACK (also 1 bit gray,
just packed) already explicitly marked itself as RGB.
2020-04-23 13:24:35 +02:00
wm4 0f8f6a665b video: change chroma_w/chroma_h fields to use shift instead of size
When I added mp_regular_imgfmt, I made the chroma subsampling use the
actual chroma division factor, instead of a shift (log2 of the actual
value). I had some ideas about how this was (probably?) more intuitive
and general. But nothing ever uses non-power of 2 subsampling (except
jpeg in rare cases apparently, because the world is a bad place).

Change the fields back to use shifts and rename them to avoid mistakes.
2020-04-23 13:24:35 +02:00
wm4 7cb83593c2 img_format: add format description table for mpv-only formats
Make this slightly less ad-hoc. Also correct the missing alpha flag for
yap8/yap16.

Despite reduced redundancy, the LOC is going up anyway... whatever.
2020-04-23 13:24:35 +02:00
wm4 7832204c99 zimg: add support for 1 bit per pixel formats
Again worthless, slow, and only for libswscale parity.

With this, we support all formats libswscale supports, except bayer
input, and rgb4/bgr4 output. We even support some formats libswscale
doesn't.

It's possible that the zimg wrapper isn't always as fast as libswscale.
But there is optimization potential: the inner repack loops are
self-contained enough that they could be reasonably be implemented in
assembler (probably), and doing everything slice-wise should reduce the
overhead of the separate pack/unpack stages.
2020-04-13 20:42:34 +02:00
wm4 afedaf3b61 zimg: add packed YUV bullshit
Just lazily tested.

The comment on AV_PIX_FMT_Y210LE seems to be wrong. It claims it's "like
YUYV422", bit it seems more like YVYU422, at last the way libswscale
input treats it. Maybe Intel pays its developers too much?

The repacker inner lop is probably rather inefficient. In theory we
could optimize it by reading the packed pixels as words, doing the
component reshuffling using compile time values etc., but I'd rather
keep the code size small. It's already bad enough that we have to
support 16 bit per component variants, just because this one Intel guy
couldn't keep it in his pants. In general, I can't be bothered to spend
time on optimizing it; I'm only doing this for fun (i.e. masochistic
obligation).
2020-04-13 20:05:38 +02:00
wm4 56cac2be46 test: add list of zimg/sws conversions
Generic statement about how this is not really appropriate, etc., and
only useful for temporary debugging things, and how I commit it anyway
despite violating my own principles (and how I'd reject this change if
it came from you).
2020-04-13 15:57:05 +02:00
wm4 a8b84c9a1a zimg: add support for big endian input and output
One of the extremely annoying dumb things in ffmpeg is that most pixel
formats are available as little endian and big endian variants. (The
sane way would be having native endian formats only.) Usually, most of
the real codecs use native formats only, while non-native formats are
used by fringe raw codecs only. But the PNG encoders and decoders
unfortunately use big endian formats, and since PNG it such a popular
format, this causes problems for us. In particular, the current zimg
wrapper will refuse to work (and mpv will fall back to sws) when writing
non-8 bit PNGs.

So add non-native endian support to zimg. This is done in a fairly
"generic" way (which means lots of potential for bugs). If input is a
"regular" format (and just byte-swapped), the rest happens
automatically, which happens to cover all interesting formats.

Some things could be more efficient; for example, unpacking is done on
the data before it's passed to the unpacker. You could make endian
swapping part of the actual unpacking process, which might be slightly
faster. You could avoid copying twice in some cases (such as when
there's no actual repacker, or if alignment needs to be corrected). But
I don't really care. It's reasonably fast for the normal case.

Not entirely sure whether this is correct. Some (but not many) formats
are covered by the tests, some I tested manually. Some I can't even
test, because libswscale doesn't support them (like nv20*).
2020-04-13 15:56:27 +02:00
wm4 a8f4ca587d test: update img_formats.txt
This explicitly depends on the pixfmt list from FFmpeg (done so to
easily spot regression, incompatible changes, and other unexpected
things).

Some local changes in mpv change some of the output. For pal8 an alias
was added back, and the [GENERIC] markers are removed because the mpv
aliases are not dependent on the mpv config anymore (which was
unnecessary).

The other changes are due to ffmpeg adding some new formats.
2020-02-29 01:23:20 +01:00
wm4 a841fe9484 img_format: add gray/alpha planar formats
The zimg wrapper "needs" these formats as intermediary when repacking
the normal gray/alpha packed format. The packed format is used by the
png decoder and encoder, and is thus interesting.

Unfortunately, mpv-only formats are a mess right now, because all the
existing code is focused around using the FFmpeg metadata for pixel
formats. This should be improved, but not now, so make the mess worse.

This commit doesn't add support for it to the zimg wrapper yet.
2020-02-10 17:38:54 +01:00
wm4 cca02e51ef zimg: add alpha support
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.
2020-02-09 19:16:54 +01:00
wm4 1dc3507474 path: add mp_path_is_absolute()
Just move it from mp_path_join_bstr() to this new function.
2020-02-06 14:14:35 +01:00
wm4 31acec5438 path: change win32 semantics for joining drive-relative paths
win32 is a cursed abomination which has "drive letters" at the root of
the filesystem namespace for no reason. This requires special handling
beyond tolerating the idiotic "\" path separator.

Even more cursed is the fact that a path starting with a drive letter
can be a relative path. For example, "c:billsucks" is actually a
relative path to the current working directory of the C drive. So for
example if the current working directory is "c:/windowsphone", then
"c:billsucks" would reference "c:/windowsphone/billsucks".

You should realize that win32 is a ridiculous satanic trash fire by the
point you realize that win32 has at least 26 current working
directories, one for each drive letter.

Anyway, the actual problem is that mpv's mp_path_join() function would
return a relative path if an absolute relative path is joined with a
drive-relative path. This should never happen; I bet it breaks a lot of
assumptions (maybe even some security or safety relevant ones, but
probably not).

Since relative drive paths are such a fucked up shit idea, don't try to
support them "properly", and just solve the problem at hand. The
solution produces a path that should be invalid on win32.

Joining two relative paths still behaves the same; this is probably OK
(maybe).

The change isn't very minimal due to me rewriting parts of it without
strict need, but I don't care.

Note that the Python os.path.join() function (after which the mpv
function was apparently modeled) has the same problem.
2020-02-06 14:10:40 +01:00
wm4 1293c40623 test: add some path handling tests
Exhaustive tests would be nice, but I'm only adding a test for a
function I'm going to change.
2020-02-06 13:50:41 +01:00
wm4 94d853d3a3 test: add tests for zimg RGB repacking
This tests the RGB repacker code in zimg, which deserves to be tested
because it's tricky and there will be more formats.

scale_test.c contains some code that can be used to test any scaler. Or
at least that would be great; currently it can only test repacking of
some byte-aligned-component RGB formats. It should be called
repack_test.c, but I'm too lazy to change the filename now.

The idea is that libswscale is used to cross-check the conversions
performed by the zimg wrapper. This is why it's "OK" that scale_test.c
does libswscale calls.

scale_sws.c is the equivalent to scale_zimg.c, and is of course
worthless (because it tests libswscale by comparing the results with
libswscale), but still might help with finding bugs in scale_test.c.

This borrows a sorted list of image formats from test/img_format.c, for
the same reason that file sorts them.

There's a slight possibility that this can be used to test vo_gpu.c too
some times in the future.
2019-11-09 01:55:13 +01:00
wm4 27d88e4a9b test: fix --unittest matching
Hurrr.
2019-11-08 21:22:49 +01:00
wm4 1edb3d061b test: add dumping of img_format metadata
This is fragile enough that it warrants getting "monitored".

This takes the commented test program code from img_format.c, makes it
output to a text file, and then compares it to a "ref" file stored in
git.

Originally, I wanted to do the comparison etc. in a shell or Python
script. But why not do it in C. So mpv calls /usr/bin/diff as a
sub-process now.

This test will start producing different output if FFmpeg adds new pixel
formats or pixel format flags, or if mpv adds new IMGFMT (either aliases
to FFmpeg formats or own formats). That is unavoidable, and requires
manual inspection of the results, and then updating the ref file.

The changes in the non-test code are to guarantee that the format ID
conversion functions only translate between valid IDs.
2019-11-08 21:22:49 +01:00
wm4 a6c8b4efa5 test: merge test_helpers.c and index.c
No need to keep them separate. Originally I thought index.c was only
going to contain the list of tests, but that didn't happen.
2019-11-08 20:34:07 +01:00
wm4 3e401bf652 test: make build fail if NDEBUG is defined
Defining NDEBUG via CFLAGS is the canonical way to disable assertions in
C. mpv respects this (and ta.c actually disables some debugging
machinery if it's defined).

But for tests, this is not useful at all. So if --enable-tests is passed
to configure, the user must not define NDEBUG, even if the rest of the
player does not care.

(We could just #undef NDEBUG, but let's not. Tests calling into the rest
of the player might depend on asserts there, or so.)
2019-11-08 14:23:56 +01:00
wm4 3ed9c1c970 test: just always provide a context for all entrypoints 2019-11-08 14:21:40 +01:00
wm4 fb56896319 test: make tests part of the mpv binary
Until now, each .c file in test/ was built as separate, self-contained
binary. Each binary could be run to execute the tests it contained.

Change this and make them part of the normal mpv binary. Now the tests
have to be invoked via the --unittest option. Do this for two reasons:

- Tests now run within a "properly" initialized mpv instance, so all
  services are available.
- Possibly simplifying the situation for future build systems.

The first point is the main motivation. The mpv code is entangled with
mp_log and the option system. It feels like a bad idea to duplicate some
of the initialization of this just so you can call code using them.

I'm also getting rid of cmocka. There wouldn't be any problem to keep it
(it's a perfectly sane set of helpers), but NIH calls. I would have had
to aggregate all tests into a CMUnitTest list, and I don't see how I'd
get different types of entry points easily. Probably easily solvable,
but since we made only pretty basic use of this library, NIH-ing this is
actually easier (I needed a list of tests with custom metadata anyway,
so all what was left was reimplement the assert_* helpers).

Unit tests now don't output anything, and if they fail, they'll simply
crash and leave a message that typically requires inspecting the test
code to figure out what went wrong (and probably editing the test code
to get more information). I even merged the various test functions into
single ones. Sucks, but here you go.

chmap_sel.c is merged into chmap.c, because I didn't see the point of
this being separate. json.c drops the print_message() to go along with
the new silent-by-default idea, also there's a memory leak fix unrelated
to the rest of this commit.

The new code is enabled with --enable-tests (--enable-test goes away).
Due to waf's option parser, --enable-test still works, because it's a
unique prefix to --enable-tests.
2019-11-08 00:26:37 +01:00
Stefano Pigozzi 899e0bd16b input: add gamepad support through SDL2
The code is very basic:

- only handles gamepads, could be extended for generic joysticks in the
  future.
- only has button mappings for controllers natively supported by SDL2.
  I heard more can be added through env vars, there's also ways to load
  mappings from text files, but I'd rather not go there yet. Common ones
  like Dualshock are supported natively.
- analog buttons (TRIGGER and AXIS) are mapped to discrete buttons using an
  activation threshold.
- only supports one gamepad at a time. the feature is intented to use
  gamepads as evolved remote controls, not play multiplayer games in mpv :)
2019-10-23 09:40:30 +02:00
Stefano Pigozzi cb32ad68f3 command: add sub-start & sub-end properties
These properties contain the current subtitle's start and end times.
Can be useful to cut sample audio through the scripting interface.
2019-09-22 09:19:45 +02:00
wm4 0b127312be test/linked_list: silence nonsense warnings
../misc/linked_list.h:71:34: warning: the address of ‘e6’ will always
evaluate as ‘true’ [-Waddress]

No shit, e6 is on the stack. But the macro argument is also allowed to
be NULL. Add some dumb nonsense to shut up the useless warning. (It's
probably useful in other contexts though, so don't disable it
completely.)
2019-09-21 22:30:38 +02:00
wm4 293dfc7825 test: fix cmocka assert_float_equal shadowing warnings
Just use cmocka's function. It takes an epsilon argument, which we now
provide directly.

There's no assert_double_equal() in cmocka (and the float variant
actually forces a conversion to the float type), but fortunately we
didn't use it.
2019-09-21 22:11:52 +02:00
wm4 782e428284 misc: add linked list helpers
This provides macros for managing intrusive doubly linked lists.

There are many ways how to do those in a "generic" way in C. For example
Solaris style lists are pretty nice:

https://github.com/illumos/illumos-gate/blob/master/usr/src/uts/common/sys/list.h
https://github.com/illumos/illumos-gate/blob/master/usr/src/common/list/list.c

I even have an independent implementation of this, which could be ISC
licensed. But I think it's easier to vomit ~100 lines of preprocessor
garbage, which has a lower footprint, and I think it wins slightly on
the side of type safety, simplicity, and ease of use, even if it doesn't
look as magically nice.
2018-05-24 19:56:35 +02:00
wm4 d36b85cfdf json: add some non-standard extensions
Also clarify this and previously existing differences to standard JSON
in ipc.rst.
2018-05-24 19:56:34 +02:00
wm4 76bff1a000 json: format slightly nicer escape sequences
Make use the escape sequences allowed by JSON.

Also update the linked RFC to the newest one.
2018-05-24 19:56:34 +02:00
wm4 711858377c test: add tests for json parser/formatter
This should have been done sooner.
2018-05-24 19:56:34 +02:00
Ilya Tumaykin f4f24c105f
tests: stop comparing floats against DBL_EPSILON, use FLT_EPSILON
Fixes #5253.
2018-02-03 13:56:08 -08:00
Ilya Tumaykin c7824f7c9d tests: fix include after 6597998 2017-10-17 09:29:02 +02:00
wm4 dac5b598f5 chmap_sel: prefer inexact equivalents over perfect upmix
Given 5.1(side), this lets it pick 5.1 from [5.1, 7.1]. Which was
probably the original intention of this replacement stuff. Until now,
the opposite was done in some cases.

Keep the old heuristic if the replacement is not perfect. This would
mean that a subset of the channel layout is an inexact equivalent, but
not all of it.

(My conclusion is that audio output APIs should be designed to simply
take any channel layout, like the PulseAudio API does.)
2016-01-04 19:17:56 +01:00
Ilya Tumaykin 8673343957 tests: fix #include 2015-12-22 15:18:50 +01:00
wm4 fd1194de3c audio: fix channel map fallback selection (again)
The speaker replacement nonsense sometimes made blatantly incorrect
decisions. In this case, it prefered a 7.1(rear) upmix over outputting
5.1(side) as 5.1, which makes no sense at all. This happened because 5.1
and 7.1(rear) appeared equivalent to the final selection, as both of
them lose the sl-sr channels. The old code was too stupid to select the
one with the lower number of channels as well.

Redo this. There's really no reason why there should be a separate final
decision, so move the speaker replacement logic into the
mp_chmap_is_better() function.

Improve some other details. For example, we never should compare the
plain number of channels for deciding upmix/downmix, because due to NA
channels this is essentially meaningless. Remove the NA channels when
doing this comparison. Also, explicitly handle exact matches.
Conceptually this is not necessary, but it avoids that we have to
needlessly shuffle audio data around.
2015-06-25 17:32:00 +02:00
Stefano Pigozzi 63e4cb5163 test: update cmocka version to 1.0 2015-06-13 00:01:58 +02:00
wm4 afdc060bb3 chmap_sel: improve speaker replacement handling
This didn't really work since the last time the channel map fallback
code was touched. In some cases, quite bad results were selected.
2015-06-12 19:23:46 +02:00
wm4 00130651da audio: simplify further
Drop mp_chmap_diff() (which is unused too now), and implement
mp_chmap_diffn() in a slightly simpler way. (Too bad there is no
standard function for counting set bits.)
2015-05-08 21:22:39 +02:00
wm4 8d5924f2c9 audio: remove mp_chmap_contains()
It's unsued now.
2015-05-08 21:14:23 +02:00
wm4 3560a50029 audio: redo channel map fallback selection
Instead of somehow having 4 different cases with each their own weight,
do it with a single function that decides which channel layout is the
better fallback.

This is simpler, and also introduces new (fixed) semantics. The new test
added to test/chmap_sel.c actually works now. This is a mixed case with
no perfect upmix or downmix, but the better choice is the one which
loses the least channels from the original layout.

One test also changes. If the input is 7.1(wide-side), and the available
layouts are 7.1 and 5.1(side), the latter is now chosen instead of the
former. This makes sense: both layouts contain 6 out of 8 channels from
the original layout, but the 5.1(side) one is smaller. This follows the
general logic. The 7.1 layout has FLC/RLC speakers instead of BL/BR,
and judging by the names, "front left center" is completely different
from "back left". If these should be exchangeable, a separate exception
would have to be added.
2015-05-08 19:33:17 +02:00
wm4 5142b0e3f3 test: simplify chmap_sel tests 2015-05-08 19:29:46 +02:00
wm4 55e777f10b audio: remove UNKNOWN pseudo speakers
Reuse MP_SPEAKER_ID_NA for this. If all mp_chmap entries are set to NA,
the channel layout has special "unknown channel layout" semantics, which
are used to deal with some corner cases.
2015-05-07 23:20:06 +02:00
wm4 d3c7fd9d7c audio: avoid downmixing in a certain special-case
As indicated by the added test. In this case, fallback and downmix have
the same score, but fallback happens to give better results. So prefer
fallback over downmix.

(This is probably not a correct solution.)
2015-04-27 23:21:58 +02:00
Stefano Pigozzi c028d782c1 vo_opengl: add gamma-auto option
This automatically sets the gamma option depending on lighting conditions
measured from the computer's ambient light sensor.

sRGB – arguably the “sibling” to BT.709 for still images – has a reference
viewing environment defined in its specification (IEC 61966-2-1:1999, see
http://www.color.org/chardata/rgb/srgb.xalter). According to this data, the
assumed ambient illuminance is 64 lux. This is the illuminance where the gamma
that results from ICC color management is correct.

On the other hand, BT.1886 formalizes that the gamma level for dim environments
to be 2.40, and Apple resources (WWDC12: 2012 Session 523: Best practices for
color management) define the BT.1886 dim at 16 lux.

So the logic we apply is:

  * >= 64lux -> 1.961 gamma
  * =< 16lux -> 2.400 gamma
  * 16lux < x < 64lux -> logaritmic rescale of lux to gamma. The human
    perception of illuminance roughly follows a logaritmic scale of lux [1].

[1]: https://msdn.microsoft.com/en-us/library/windows/desktop/dd319008%28v=vs.85%29.aspx
2015-03-04 10:06:08 +01:00
Stefano Pigozzi 54aea7d5de chmap_sel: add multichannel fallback heuristic
Instead of just failing during channel map selection, try to select a close
layout that makes most sense and upmix/downmix to that instead of failing AO
initialization. The heuristic is rather simple, and uses the following steps:

1) If mono is required always prefer stereo to a multichannel upmix.
2) Search for an upmix that is an exact superset of the required channel map.
3) Search for a downmix that is the exact subset of the required channel map.
4) Search for either an upmix or downmix that is the closest (minimum difference
   of channels) to the required channel map.
2014-12-29 17:56:53 +01:00