Commit Graph

710 Commits

Author SHA1 Message Date
Kacper Michajłow e720159f72 player/command: add video-codec-info and audio-codec-info
Adds support for extracting codec profile. Old properties are redirected
to new one and removed from docs. Likely will stay like that forever as
there is no reason to remove them.

As a effect of unification of properties between audio and video,
video-codec will now print codec (format) descriptive name, not decoder
long name as it were before. In practice this change fixes what docs
says. If you really need decoder name, use the `track-list/N/decoder-desc`.
2024-04-15 19:34:40 +02:00
nanahi 9bb7d96bf9 various: make filter internal function names more descriptive
Lots of filters have generic internal function names like "process".
On a stack trace, all of the different filters use this name,
which causes confusion of the actual filter being processed.

This renames these internal function names to carry the filter names.
This matches what had already been done for some filters.
2024-04-10 19:00:22 +02:00
Kacper Michajłow 174df99ffa ALL: use new mp_thread abstraction 2023-11-05 17:36:17 +00:00
Niklas Haas f369e65261 vd_lavc: align buffers to multiple of image size
Fixes: https://github.com/mpv-player/mpv/issues/12672
2023-10-19 18:26:05 +02:00
Kacper Michajłow 6f83529f21 vd_lavc: by default enable cropping by decoder
While this resolves limitations of lavc decoder crop, it also introduces
artifacts with some of the source files or hwdec.

Depending on chroma sampler it is possible to sample outside the decoder
crop area, pulling dirty pixels into the image. Some decoders left them
zeroed, not black. To fix that we would need specifc solution during
mapping of avframes.

As most of the files require the crop only in bottom/right area, the
AVCodecContext::apply_cropping works ok for those.

For all other cases that require more fancy cropping like 1440x1080+240+0
user can manually set `--vd-apply-cropping=no`.

Limitations of the lavc crop are explained here:
https://ffmpeg.org/doxygen/trunk/structAVCodecContext.html#a4745c7455c317272c4e139d6f369936c

Fixes: 826ce82cad
2023-09-10 18:33:50 +02:00
Kacper Michajłow 826ce82cad vd_lavc: disable cropping by decoder
Cropping by decoder has limitations with regards to aligment and hwdec.
It doesn't work to offset top left corner with hwdec and even with
software decoding it don't crop fully when resulting data would not be
aligned.

VO cropping is way more robust.
2023-09-08 02:27:08 +00:00
Philip Langdale e8144ac231 vd_lavc: repeatedly attempt to fallback if hwdec fails in reinit
In the same way that fallback in receive_frame() needs to be repeated
until we get a working decoder, we have to do the same thing in
reinit(). Calling force_fallback() only once can still yield a non
functional decoder.

The reason why we have these multiple paths which each require their
own fallback logic is that we can fail at different stages:
* hwdec init
* decoder init <- repeated fallback was missing here
* frame decoding

Fixes #12084
2023-08-06 04:42:13 -07:00
Dudemanguy ca4192e2df player/video: check for forced eof
It's a bit of an edge case, but since we now allow the disabling of the
software fallback it's possible to have a situation where hwdec
completely fails and the mpv window is still lingering from the previous
item in the playlist. What needs to happen is simply that the vo_chain
should uninit itself and handle force_window if needed. In order to do
that, a new VDCTRL is added that checks vd_lavc if force_eof was set.
player/video will then start the uninit process if needed after getting
this.
2023-07-22 17:42:25 +00:00
Dudemanguy 61f0797557 vd_lavc: respect vd-lavc-software-fallback opt
There's an option that's supposed to stop mpv from falling back to
software decoding if hardware decoding fails. Except that it doesn't
work and can fallback to software decoding anyway. Correct this by
checking if all possible hwdec failed after the loop in
select_and_set_hwdec and that we have this option. If so, flag a bool to
force eof. In decode_frame afterwards, we then simply immediately return
an EOF.
2023-07-22 17:42:25 +00:00
Philip Langdale fbd0be1cf4 vd_lavc: repeatedly attempt to fallback if hwdec fails in receive_frame
There is an additional failure path I didn't account for in my previous
work. While I ensured that a late hwdec failure in receive_frame can be
recovered from by trying the next hwdec, there is a specific
combination where if an hwdec fails in receive_frame, and the next
hwdec is a full decoder (eg: v4l2m2m), and that also fails, we are left
with no decoder and so the entire decoding process ends and playback is
stopped.

Basically, we must keep re-attempting the fallback in receive_frame
until we get a valid decoder (software or hardware). This edge case
will rarely be encountered as there are only a couple of decoder based
hwdecs.

Fixes #11947
2023-07-17 18:37:41 -07:00
Philip Langdale e64ef6089f vd_lavc: map `hwdec=yes` to `hwdec=auto-safe`
To remain consistent with our belief that `auto-safe` should be the
recommended mode when turning on hw decoding, let's remap `yes` from
`auto` to `auto-safe`.
2023-07-14 20:41:24 -07:00
Philip Langdale 7fe2a76621 vd_lavc: add `drm` and `drm-copy` to the `auto-safe` list
We have supported `hwdec=drm` for some time now, and on devices where
this method is present, it is the preferred, and only, method
available. Combine that with the fact that software decoding on
embedded devices will not turn out well, and it's clear that we should
put `drm` and `drm-copy` on the `auto-safe` list to maximise usability
in simple configurations.
2023-07-14 20:41:24 -07:00
Philip Langdale 4501e07996 vd_lavc: try other hwdecs when falling back after an hwdec failure
Today, if hwdec initialisation succeeds, we move on to attempting
decoding, and if decoding fails, we enter a fallback path that will
only do software decoding.

This is suboptimal because some hwdecs and codec combinations can
pass hwdec init, but then fail at hwaccel init, or even frame decoding.
In these situations, we will never attempt other hwdecs in the `auto`
or manually specified lists which might work.

One good example is someone tries to use `vulkan,auto` and tries to
play av1 content. The vulkan decoding will fail at hwaccel init time,
and then fallback to software instead of going through the auto list
which would allow vaapi, nvdec, etc to play the file.

Instead, let's not give up immediately, and try the next hwdec after
a failure, just like we do if hwdec init fails.

The key part of this change is to keep track of the hwdecs we have
tried, so that each time we run through hwdec selection, we don't try
the same one over and over again. If we really get through the whole
list with no success, we will then fall back to software decoding.

Fixes #11865
2023-07-14 20:41:24 -07:00
Kacper Michajłow fc3e28f1e9 vd_lavc: fix delay_queue for videos with frames < max_delay_queue
In case there are no packets from demuxer we cannot send EAGAIN, because
we will not proceed and get stuck with one frame in queue and never
output it. Just respect avcodec_receive_frame ret code and act
accordingly. The only case to care about is EOF when we have to drain
already queued frames.

Fixes playback of 1-2 frame videos.
2023-07-09 11:59:32 +02:00
Kacper Michajłow bf77f1ae74 vd_lavc: prefer d3d11va-copy over dxva2-copy
There is no reason to prefer dxva2. I believe it was mistake from
initial commit that added the hwdec list that has been propagated
through years.
2023-07-09 11:59:32 +02:00
Philip Langdale 40a1b0066e vd_lavc: do inline string array initialisation for hwdec_api
I couldn't work out the correct syntax, but NRK0 pointed out an example
of where we'd done it elsewhere in the codebase.
2023-06-29 15:03:05 -07:00
Philip Langdale 9ff8c9e780 vd_lavc: let the user provide a priority list of hwdecs to consider
Today, the only way to make mpv consider multiple hwdecs and pick the
first one that works is to use one of the `auto` modes. But the list
that is considered in those cases is hard-coded. If the user wants to
provide their own list, they are out of luck.

And I think that there is now a significant reason to support this -
the new Vulkan hwdec is definitely not ready to be in the auto list,
but if you want to use it by default, it will not work with many codecs
that are normally hardware decodable (only h.264, hevc and av1 if you
are very lucky). Everything else will fall back to software decoding.

Instead, what you really want to say is: use Vulkan for whatever it
supports, and fall back to my old hwdec for everything else.

One side-effect of this implementation is that you can freely mix
hwdec names and special values like `auto` and `no`. The behaviour will
be correct, so I didn't try and prohibit any combinations. However,
some combinations will be silly - eg: sticking any further values after
`no` will result in them being ignored. On the other hand, a
combination like `vulkan,auto` could be very useful as that will use
Vulkan if possible, and if not, run the normal auto routine.

Fixes #11797
2023-06-29 11:58:51 -07:00
Kacper Michajłow a5b9290261 vd_lavc: check if av_device_ref is available
Fixes crashes when hwdevice failed to create.

Fixes: #11769
2023-06-26 19:07:29 +02:00
sfan5 5a83745316 vd_lavc: sort hwdecs without hwdevices last for autoprobing
For hwdecs without devices we can't get instant feedback during probing
whether the hwdec can possibly work or not, so we definitely want to try them last.
Independently this would also have solved the issue addressed by the previous commit.
2023-02-26 16:40:59 +01:00
sfan5 1dda09b817 vd_lavc: prioritize mediacodec for hwdec autoprobe
This fixes an issue where mpv would try mediacodec (which may not
be available depending on Android version) and pick v4l2m2m next
which ends up failing even though mediacodec-copy would have been available.
2023-02-26 16:40:59 +01:00
Christoph Heinrich 91cc0d8cf6 options: transition options from OPT_FLAG to OPT_BOOL
c784820454 introduced a bool option type
as a replacement for the flag type, but didn't actually transition and
remove the flag type because it would have been too much mundane work.
2023-02-21 17:15:17 +00:00
Thomas Weißschuh 9efce6d4ae various: drop unused #include "config.h"
Most sources don't need config.h.
The inclusion only leads to lots of unneeded recompilation if the
configuration is changed.
2023-02-20 14:21:18 +00:00
sfan5 c7ea0cd68f vd_lavc: add "auto" choice for vd-lavc-dr
--vd-lavc-dr defaulted to "yes", which caused issues on certain
hardware. Instead of disabling it, add a new "auto" value and
make it the default.

The "auto" choice will enable DR only when we can request host-cached
buffers (as signalled by the new VO_DR_FLAG_HOST_CACHED).

Co-authored-by: Nicolas F. <ovdev@fratti.ch>
Co-authored-by: Niklas Haas <git@haasn.dev>
2023-01-23 14:13:34 +01:00
Niklas Haas f8c17f55f9 vo: add `int flags` to the get_image signature
This is a huge disgusting mess to thread through everywhere. Maybe I'm
stupid for attempting to solve the problem this way.
2023-01-23 14:13:34 +01:00
Philip Langdale eeefa8aec0 vd_lavc: Set AV_HWACCEL_FLAG_UNSAFE_OUTPUT flag
This new hwaccel flag was added to allow us to request that an hwaccel
decode not implicitly copy output frames before passing them out. The
only hwaccel that would implicitly copy frames is nvdec due to how it
has a small output pool that cannot be grown very much. However, we
already copy frames as soon as we get our hands on them (in our hwdec)
so we're already safe from pool exhaustion, and the extra copy doesn't
help us.
2022-12-12 10:07:43 -08:00
Philip Langdale 4574dd5dc6 ffmpeg: update to handle deprecation of `av_init_packet`
This has been a long standing annoyance - ffmpeg is removing
sizeof(AVPacket) from the API which means you cannot stack-allocate
AVPacket anymore. However, that is something we take advantage of
because we use short-lived AVPackets to bridge from native mpv packets
in our main decoding paths.

We don't think that switching these to `av_packet_alloc` is desirable,
given the cost of heap allocation, so this change takes a different
approach - allocating a single packet in the relevant context and
reusing it over and over.

That's fairly straight-forward, with the main caveat being that
re-initialising the packet is unintuitive. There is no function that
does exactly what we need (what `av_init_packet` did). The closest is
`av_packet_unref`, which additionally frees buffers and side-data.
However, we don't copy those things - we just assign them in from our
own packet, so we have to explicitly clear the pointers before calling
`av_packet_unref`. But at least we can make a wrapper function for
that.

The weirdest part of the change is the handling of the vtt subtitle
conversion. This requires two packets, so I had to pre-allocate two in
the context struct. That sounds excessive, but if allocating the
primary packet is too expensive, then allocating the secondary one for
vtt subtitles must also be too expensive.

This change is not conditional as heap allocated AVPackets were
available for years and years before the deprecation.
2022-12-03 14:44:18 -08:00
Philip Langdale 83257be693 vd_lavc: update to handle deprecation of `pkt_duration`
This has been replaced by `duration`.
2022-12-01 10:45:47 -08:00
Philip Langdale e50db42927 vo: hwdec: do hwdec interop lookup by image format
It turns out that it's generally more useful to look up hwdecs by image
format, rather than device type. In the situations where we need to
find one, we generally know the image format we're dealing with. Doing
this avoids us having to create mappings from image format to device
type.

The most significant part of this change is filling in the image format
for the various hw interops. There is a hw_imgfmt field today today, but
only a couple of the interops fill it in, and that seems to be because
we've never actually used this piece of metadata before. Well, now we
have a good use for it.
2022-09-21 09:39:34 -07:00
Cœur bb5b4b1ba6 various: fix typos 2022-04-25 09:07:18 -04:00
Jan Ekström 305332f8a0 vd_lavc: fixup unchecked usage of AV_CODEC_EXPORT_DATA_FILM_GRAIN
This fixes build failures with avcodec 58.113.100 or before,
matching FFmpeg release versions 4.0 to 4.3.

This flag was added in between avcodec 58.113.100 and 58.114.100
during the FFmpeg 4.4 development cycle. It lacks its own version bump,
so instead a check for the define is utilized instead.

Additionally, warn the user if they request GPU film grain with
too old of an FFmpeg.

Fixes #10088
2022-04-13 00:52:08 +03:00
Jan Ekström 1a597ea987 vd_lavc: fix decoder initialization when no VO is available
The VO is available during decoder initialization mostly for direct
rendering purposes, so if f.ex. a complex filter chain is utilized,
there is no video renderer information available via
mp_filter_find_stream_info during creation of the decoder filter.

Thus, check for whether the VO is available before attempting to
check the capabilities flag from it.

Additionally - to simplify logic - makes explicitly requesting GPU
film grain to always disable decoder film grain functionality. The
warning is still shown if the VO is available and no support for
film grain application is available.

Fixes #10079
2022-04-11 23:54:22 +03:00
Jan Ekström eddc0bfe25 vd_lavc: remove duplicate vd_ffmpeg_ctx pointer from init_avctx
Seems like in some functions this was called p and in others ctx,
and thus it was added as the `p` pointer was not available.
2022-04-11 23:54:22 +03:00
Lynne f61eda0f5e vd_lavc: add vo caps and option to set GPU film grain application 2022-04-05 15:02:18 +02:00
Jan Ekström 083ae8e736 vd_lavc: hide a deprecation warning in already handled compatible code
The field has been deprecated, yet the upcoming new default is not yet
the default. Thus, until lavc major hits 60 and the default behavior
finally gets changed, we have to explicitly set the field's value.

The deprecation had already been handled by adding the required
version limitation for this code in bbbf3571ed ,
this change merely just removes the warning which would otherwise
appear until lavc major version gets bumped to 60.
2022-04-03 00:23:58 +03:00
Philip Langdale fcc81cd940 vo_gpu[_next]: hwdec: fix logging regression when probing
When I introduced the concept of lazy loading of hwdecs by img format,
I did not propagate the probing flag correctly, leading to the new
normal loading path not runnng with probing set, meaning that any
errors would show up, creating unnecessary noise.

This change fixes this regression.
2022-03-21 09:53:37 -07:00
Avi Halachmi (:avih) 836e87e6d4 hwdec: warn on unsupported hwdec option value
Previously, when mpv was invoked with unsupported hwdec value, such
as --hwdec=foobar, there was no indication that it doesn't exist.

The reason it's not validated during options parsing is that the name
is only evaluated when selecting hwdec for actual decoding, by
matching it against runtime list of names from ffmpeg.

Additionally, when selecting hwdec for decoding, matching the name
came after filtering by codec, hence overall never-matched-name did
not necessarily indicate it's unsupported (doesn't exist at all).

Now we check the name before filtering by codec, and when done,
warn if no hwdec with that name exists at all.

This means that an unsupported name will now generate such warning
whenever we try to choose a hwdec, i.e. possibly more than once.

It's much better than no notification at all, and arguably adequate
for a sort of configuration error (linked ffmpeg has no such hwdec
name) which we don't validate during option parsing.
2022-03-07 01:05:20 +02:00
Philip Langdale 5186651f30 vo_gpu: hwdec: load hwdec interops on-demand by default
Historically, we have treated hwdec interop loading as a completely
separate step from loading the hwdecs themselves. Some hwdecs need an
interop, and some don't, and users generally configure the exact
hwdec they want, so interops that aren't relevant for that hwdec
shouldn't be loaded to save time and avoid warning/error spam.

The basic approach here is to recognise that interops are tied to
hwdecs by imgfmt. The hwdec outputs some format, and an interop is
needed to get that format to the vo without read back.

So, when we try to load an hwdec, instead of just blindly loading all
interops as we do today, let's pass the imgfmt in and only load
interops that work for that format. If more than one interop is
available for the format, the existing logic (whatever it is) will
continue to be used to pick one.

We also have one callsite in filters where we seem to pre-emptively
load all the interops. It's probably possible to trace down a specific
format but for now I'm just letting it keep loading all of them; it's
no worse than before.

You may notice there is no documentation update - and that's because
the current docs say that when the interop mode is `auto`, the interop
is loaded on demand. So reality now reflects the docs. How nice.
2022-02-17 20:02:32 -08:00
rcombs f40d66f624 vd_lavc: enable hwdec for prores by default 2021-12-29 01:04:09 +02:00
Philip Langdale 3f006eced4 options: Make validation and help possible for all option types
Today, validation is only possible for string type options. But there's
no particular reason why it needs to be restricted in this way, and
there are potential uses, to allow other options to be validated
without forcing the option to have to reimplement parsing from
scratch.

The first part, simply making the validation function an explicit
field instead of overloading priv is simple enough. But if we only do
that, then the validation function still needs to deal with the raw
pre-parsed string. Instead, we want to allow the value to be parsed
before it is validated. That in turn leads to us having validator
functions that should be type aware. Unfortunately, that means we need
to keep the explicit macro like OPT_STRING_VALIDATE() as a way to
enforce the correct typing of the function. Otherwise, we'd have to
have the validator take a void * and hope the implementation can cast
it correctly.

For help, we don't have this problem, as help doesn't look at the
value.

Then, we turn validators that are really help generators into explicit
help functions and where a validator is help + validation, we split
them into two parts.

I have, however, left functions that need to query information for both
help and validation as single functions to avoid code duplication.

In this change, I have not added an other OPT_FOO_VALIDATE() macros as
they are not needed, but I will add some in a separate change to
illustrate the pattern.
2021-03-28 19:46:27 +03:00
sfan5 bbbf3571ed vd_lavc: wrap use of deprecated AVCodecContext.thread_safe_callbacks in #if
For compatibility once FFmpeg removes it entirely.
2021-03-02 15:00:37 +01:00
Emmanuel Gil Peyrot 5f2b60a645 vd_lavc: add VP8 to the default allowed hwdec codec list
It is supported at least on Intel, from gen8 to gen11, and still gives a
pretty welcome reduction of CPU usage on my gen9.
2020-12-30 17:30:01 +02:00
Jan Ekström 172146e9f7 vd_lavc: add AV1 to the default allowed hwdec codec list
Now that the first hwaccel implementations are coming in, it makes
sense to allow this format.
2020-11-03 15:07:26 +01:00
wm4 823e5205ea options: make imgfmt options always accept "no"
This was optional, with the intention that normally such options require
a valid format. But there is no reason for this (at least not anymore),
and it's actually more logical to accept "no" in all situations this
option type is used. This also gets rid of the weird min field special
use.
2020-04-09 11:20:45 +02:00
wm4 e31fbbeeee vd_lavc: make hwdec fallback message more consistent
The "rule" is that a fallback warning message should be shown only shown
if software decoding was used before, or in other words when either
hwdec was enabled before, but the stream suddenly falls back, or it was
attempted to enable it at runtime, and it didn't work.

The message wasn't printed the first time in the latter case, because
hwdec_notified was not set in forced software decoding mode. Fix it with
this commit. Fortunately, the logic becomes simpler.
2020-03-24 23:40:01 +01:00
wm4 26f4f18c06 options: change option macros and all option declarations
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.
2020-03-18 19:52:01 +01:00
wm4 8d965a1bfb options: change how option range min/max is handled
Before this commit, option declarations used M_OPT_MIN/M_OPT_MAX (and
some other identifiers based on these) to signal whether an option had
min/max values. Remove these flags, and make it use a range implicitly
on the condition if min<max is true.

This requires care in all cases when only M_OPT_MIN or M_OPT_MAX were
set (instead of both). Generally, the commit replaces all these
instances with using DBL_MAX/DBL_MIN for the "unset" part of the range.

This also happens to fix some cases where you could pass over-large
values to integer options, which were silently truncated, but now cause
an error.

This commit has some higher potential for regressions.
2020-03-13 17:34:46 +01:00
wm4 7d11eda72e Remove remains of Libav compatibility
Libav seems rather dead: no release for 2 years, no new git commits in
master for almost a year (with one exception ~6 months ago). From what I
can tell, some developers resigned themselves to the horrifying idea to
post patches to ffmpeg-devel instead, while the rest of the developers
went on to greener pastures.

Libav was a better project than FFmpeg. Unfortunately, FFmpeg won,
because it managed to keep the name and website. Libav was pushed more
and more into obscurity: while there was initially a big push for Libav,
FFmpeg just remained "in place" and visible for most people. FFmpeg was
slowly draining all manpower and energy from Libav. A big part of this
was that FFmpeg stole code from Libav (regular merges of the entire
Libav git tree), making it some sort of Frankenstein mirror of Libav,
think decaying zombie with additional legs ("features") nailed to it.
"Stealing" surely is the wrong word; I'm just aping the language that
some of the FFmpeg members used to use. All that is in the past now, I'm
probably the only person left who is annoyed by this, and with this
commit I'm putting this decade long problem finally to an end. I just
thought I'd express my annoyance about this fucking shitshow one last
time.

The most intrusive change in this commit is the resample filter, which
originally used libavresample. Since the FFmpeg developer refused to
enable libavresample by default for drama reasons, and the API was
slightly different, so the filter used some big preprocessor mess to
make it compatible to libswresample. All that falls away now. The
simplification to the build system is also significant.
2020-02-16 15:14:55 +01:00
wm4 67650446b5 vd_lavc: remove hwdec-by-default special case for RPI 2019-12-24 09:24:56 +01:00
wm4 380f01567d vd_lavc: more hwdec autoselect nonsense
Add an "auto-safe" mode, mostly triggered by Ubuntu's nonsense to force
hwdec=vaapi in the global config file in their mpv package. But to be
honest it's probably something more people want.

This is implemented as explicit whitelist. On Windows, HEVC/Intel is
sometimes broken, but it's still whitelisted, and in theory we'd need a
detailed whitelist of device names etc. (like for example browsers tend
to do). On OSX, videotoolbox is a pretty bad choice, but unfortunately
the only one, so it's whitelisted too. There may be a larger number of
hwdec wrappers that work anyway, and I'm for example ignoring Android.
2019-12-24 09:24:22 +01:00
wm4 bd96b97170 vd_lavc: add gross workaround for nvdec/libavcodec broken API issue
libavcodec's nvdec wrapper can return invalid frames, that do not have
any data fields set. This is not allowed by the API, but why would they
follow their own API?

Add a workaround to specifically detect this situation. In practice,
this should fall back to software decoding if it happens too often in a
row. (But single errors are still tolerated, because I don't know why.)

Untested due to lack of hardware from the regrettable graphics company.

Better do this here than deal with the moronic project we unfortunately
depend on.

See: #7185
2019-12-18 01:56:50 +01:00