WGL_NV_DX_interop is widely supported by Nvidia and AMD drivers. It
allows a texture to be shared between Direct3D and WGL, so that
rendering can be done with WGL and presentation can be done with
Direct3D. This should allow us to work around some persistent WGL
issues, such as dropped frames with some driver/OS combos, drivers that
buffer frames to increase performance at the cost of latency, and the
inability to disable exclusive fullscreen mode when using WGL to render
to a fullscreen window.
The addition of a DX_interop backend might also enable some cool
Direct3D-specific enhancements in the future, such as using the
GetPresentStatistics API to get accurate frame presentation timestamps.
Note that due to a driver bug, this backend is currently broken on
Intel. It will appear to work as long as the window is not resized too
often, but after a few changes of size it will be unable to share the
newly created renderbuffer with GL. See:
https://software.intel.com/en-us/forums/graphics-driver-bug-reporting/topic/562051
All of these are supported by FFmpeg now. It was disabled by default
too (with FFmpeg).
If compiled against Libav, mpv will lose the ability to read some
subtitle formats (but the most important ones, srt and ass, still should
work).
This is only for specific Hauppage cards. According to the comments in
who is actively using this feature. Get it out of the way.
Anyone who still wants to use this should complain. Keeping this code
would not cause terribly much additional work, and it could be restored
again. (But not if the request comes months later.)
With default setting, the matrix for fruit dithering requires 12 bits
precision (values from 0/4096 to 4095/4096). But 16-bit float
provides only 10 bits. In addition, when `dither-size-fruit=8` is
set, 16 bits are required from the texture format.
Fix this by attempting to use 16 bit integer texture first. This is
still not precise, but should be better than using a half float.
This has no reason to be there. Put the functionality into another
function instead. While we're at it, also adjust for possible accuracy
issues with high bit depth YUV (matters for rendering subtitles into
screenshots only).
The recent LUT adjustment changes broke interpolation.
The concatenation of the shader stages is a bit messy, and it seems like
sampler_prelude is not a good place to add this macro. Always add the
macro to every shader instead. (While this doesn't seem too elegant,
this isn't too inelegant either, and goes these problems out of the
way.)
The computation of the tex_mul variable was broken in multiple ways.
This variable is used e.g. by debanding for moving expansion of 10 bit
fixed-point input to normalized range to another stage of processing.
One obvious bug was that the rgb555 pixel format was broken. This format
has component_bits=5, but obviously it's already sampled in normalized
range, and does not need expansion. The tex_mul-free code path avoids
this by not using the colormatrix. (The code was originally designed to
work around dealing with the generally complicated pixel formats by only
using the colormatrix in the YUV case.)
Another possible bug was with 10 bit input. It expanded the input by
bringing the [0,2^10) range to [0,1], and then treating the expanded
input as 16 bit input. I didn't bother to check what this actually
computed, but it's somewhat likely it was wrong anyway. Now it uses
mp_get_csp_mul(), and disables expansion when computing the YUV matrix.
It turns out that with accurate lookup we can decrease the
default size of texture now. Do it to compensate the performance
loss introduced by the LUT_POS macro.
Define a macro to correct the coordinate for lookup texture. Cache
the corrected coordinate for 1D filter and use mix() to minimize the
performance impact.
It always was a weird artifact - VOCTRLs are meant _not_ to require
special handling in the code that passes them through (like in vo.c).
Removing it is also interesting to further reduce the dependency of
backends on struct vo. Just get rid of it.
Removing it is somewhat inconvenient, because in many situations the UI
window is created after the first VOCTRL_UPDATE_WINDOW_TITLE. This means
these backends have to store it in a new field in their own context.
Fixes a reported sample, that has a sign interrupted by a few frames
(for which --sub-fix-timing would remove the wanted gap).
The list of tags in has_overrides() is taken from libass. It has a
similar function (which even checks whether the tag are within the { }
delimiters). Unfortunately, this function is not public, so we just have
a simpler one which does roughly the same. It doesn't matter that this
function sometimes returns false positives.
The awkward "preprocess" step of putting the subtitles through single
filters before doing something else was made unnecessary by the recent
changes.
(Fun fact: I originally planned to move these extra things, like fixing
subtitle gaps/overlaps, to filters - but this would suffer from various
complications, and moving them to the renderers seems much simpler.)
I feel like it's better there. Note that there is no reduced
functionality, as bitmaps subs (i.e. not handled by sd_ass.c) were never
fully read on init, and thus never went through sub_read_all_packets().
On the other hand, this might lead to confusion, as --sub-fps etc. will
now also affect muxed subtitles (which makes not much sense).
Instead of messing with the subtitle packet timestamps, do it on output.
We work on the libass event list. If there is an unwanted gap or
overlap, we render the timestamp at another position where there is no
gap or overlap.
This is somewhat more robust, and even works with demuxed subs (to some
degree - depends whether the subs are prefected soon enough).
It's active even for native ASS subs. I wonder if this is a problem with
extended type setting. If it is, the heuristic that tries to avoid
interrupting such cases has to be improved.
While it probably would be ideal to do this after the subtitle decoder,
certain aspects are at least currently handled better in this place.
Image subtitles often use a "signaling" packet to set the end time of
the previous subtitle. As far as the libavcodec API is concerned, such
packets decode to empty AVSubtitles. Discard these after the end time of
the previous subtitle has been set.
Keep track of the per-subtitle end time better. This is for the sake of
improving sub_step/sub_seek. Without this, it would seek to the sub
before the previous sub, if the current sub has ended displaying.
Works roughly the same as the one in sd_ass for text subtitles. While
sub_step is very uninteresting, it comes for free with the support for
sub_seek.
The implementation is taken from ass_step_sub() from libass, with some
modifications
Until now, feeding packets to the decoder in advance was done for text
subtitles only. This was possible because libass buffers all subtitle
data anyway (in ASS_Track). sd_lavc, responsible for bitmap subs, does
not do this. But it can buffer a small number of subtitle frames ahead.
Enable this.
Repurpose the sub_accept_packets_in_advance(). Instead of "can take all
packets" it means "can take 1 packet" now. (The old meaning is still
needed locally in dec_sub.c; keep it there.) It asks the decoder whether
there is place for at least 1 subtitle packet. sd_lavc implements it and
returns true if its internal fixed-size subtitle queue still has a free
slot. (The implementation of this in dec_sub.c isn't entirely clean.
For one, decode_chain() ignores this mechanism, so it's implied that
bitmap subtitles do not use the subtitle filter chain in any advanced
way.)
Also fix 2 bugs in the sd_lavc queue handling. Subtitles must be checked
in reverse, because the first entry will often have endpts==NOPTS, which
would always match. alloc_sub() must cycle the queue buffer, because it
reuses memory allocations (like sub.imgs) by design.
If reinit after a fallback from hardware fails, this field can be NULL.
The check in control() was broken due to a typo (found by Coverity), and
decode() lacked the check entirely.
If the sampling point is placed diagonally, the radius difference
could be as large as sqrt(2.0). And a loosened check with (radius - 1)
would potentially include pixels out of the range.
Fix the check to handle those corner case properly to avoid
unnecessary texture lookup and improve the performance a bit.
reopen_console_handle() was never properly tested because mpv overrides
printf in most source files. Turns out that when there's no console on
startup, the CRT sets the fds of stdout and stderr to -2, so the old
method of using dup2 to manipulate these fds didn't work. As far as I
can tell, the only way to give stdout and stderr valid fds is to use
freopen, so this uses freopen to set them both to the console output.
This also uses dup2 to change STDOUT_FILENO and STDERR_FILENO, so low-
level functions like isatty still work.
Note that this means fileno(stdout) != STDOUT_FILENO. I don't think this
will cause any problems.
This should fix MPV_LEAK_REPORT on the Windows console.
Helps with files that have occasional broken timestamps. For larger
discontinuities, e.g. caused by actual timestamp resets, we still want
to realign audio.
(I guess in general, this should be removed and replaced by a more
general resync-on-desync logic, but not now.)
Sometimes QOpenGLWidget may be redirecting it's output to a framebuffer
object rather than the frontbuffer, in which case the current thread's
context render fbo is different from the widget's. Use the widget's
desired fbo instead.
There are claims that nnedi3.c doesn't constitute its own new
implementation, but is derived from existing HLSL or OpenCL shaders
distributed under the LGPLv3 license.
Until these are resolved, do the "correct" thing and require
--enable-gpl3 to build nnedi.
This makes no sense, because the client is obligated to react to this
event.
This also happens to fix a deadlock with JSON IPC clients sending
"disable_event all", because MPV_EVENT_SHUTDOWN was used to stop the
thread driving the socket connection (fixes#2558).
Approximately reverts commit 3ccac74d. This failed with some avi files,
which do pseudo-VFR by sending packets with empty frames (or repeat
frames, depending on point of view). Specifically, these packets are not
0 bytes, so they don't get skipped by libavformat, as with the usual VFR
avi hack. Instead, the packet contains a VOP with vop_coded=0, so
libavcodec will just return no frame. We could probably distinguish such
skipped frames and delayed frames by explicitly measuring the codec
delay by counting how long it takes to get the very first frame (and
then treat skips as explicit drops), but we may as well simply reinstate
the old code.
To appease to at least one semi-broken case, do not enable this logic on
the RPI, as the FFmpeg MMAL wrapper has arbitrary buffering (and MMAL
itself is asynchronous).
I guess gl_video->global was originally meant to be optional, but now it
crashes in some newer code with vo_opengl_cb, which tries to init it
with this field set to NULL (because normally it's not needed).
Probably fixes#2542.
Requested. Don't overwrite permanent OSD text set with e.g. --osd-msg1.
Instead, append the OSD message to it (on the next line).
Note that with --osd-msg1, seeking will still overwrite the OSD with the
playback status for a while. If you do not want this, use --osd-msg3
--osd-level=3 instead.
Don't use the average FPS if there are likely skipped vsyncs. Note that
we don't use the normal skip detection, as it is unreliable if the real
and assumed display FPS differ too much. The normal skip detection is
still in place as it's more reliable in the case when vsync jitters
much, but the display FPS is relatively exact.
Further improvement over commit 41f2c653.
Commit 2b07d3eb merged progbar and OSD text renderer into one ASS_Track,
but it confused the styles. Specifically, if both progbar and OSD are
visible, the create_ass_track() call made by the progbar code will reset
the style adjusted by the OSD text code.
Change create_ass_track() not to add any styles. Instead let the caller
manage the styles. They are now referenced by name, and lazily added if
they don't exist yet. This is also much cleaner.
Reduces memory usage and startup times. The implementation is a bit
weird, because both OSD parts have conflicting requirements on the used
ASS styles.
At least I hope so.
Deriving the duration from the pts was not really correct. It doesn't
include speed adjustments, and becomes completely wrong of the user e.g.
changes the playback speed by a huge amount. Pass through the accurate
duration value by adding a new vo_frame field.
The value for vsync_offset was not correct either. We don't need the
error for the next frame, but the error for the current one. This wasn't
noticed because it makes no difference in symmetric cases, like 24 fps
on 60 Hz.
I'm still not entirely confident in the correctness of this, but it sure
is an improvement.
Also, remove the MP_STATS() calls - they're not really useful to debug
anything anymore.
This was just converting back and forth between int64_t/microseconds and
double/seconds. Remove this stupidity. The pts/duration fields are still
in microseconds, but they have no meaning in the display-sync case (also
drop printing the pts field from opengl/video.c - it's always 0).
If we switched away from the system FPS, we were remaining in this mode
ssentially forever. There's no reason to do so; switch back if the
estimated FPS gets worse again. Improvement over commit 41f2c653.
Commit 12eb8b2d accidentally disabled framedropping in the audio timing
case. It tried to replace the last_flip field with the prev_vsync one,
which didn't work because prev_sync is reset to 0 if the timing code is
used. Fix it by always setting it properly. This field must (or should)
be reinitialized to something sensible when switching to display sync
timing mode; since prev_vsync is not reset anymore, the check when to
reinitialize this field has to be adjusted as well.
It's a bit weird that update_vsync_timing_after_swap() now does some
minor work for timing mode too, but I guess it's ok, if only to avoid
additional fields and timer calls.
If there were many AO drivers without device selection, this added a
"Default" entry for each AO. These entries were not distinguishable, as
the device list feature is meant not to require to display the "raw"
device name in GUIs.
Disambiguate them by adding the driver name. If the AO is the first, the
name will remain just "Default". (The condition checks "num > 1",
because the very first entry is the dummy for AO autoselection.)
Instead of periodically trying to enable it again. There are two cases
that can happen:
1. A random discontinuity messed everything up,
2. Things are just broken and will desync all the time
Until now, it tried to deal with case 1 - but maybe this is really rare,
and we don't really need to care about it. On the other hand, case 2 is
kind of hard to diagnose if the user doesn't use the terminal.
Seeking will reenable display-sync, so you can fix playback if case 1
happens, but still get predictable behavior in case 2.
If the system-reported display FPS (returned by the VO backends, or
forced with --display-fps) is too imprecise (deviating frame duration by
more than 1%). This works if the display FPS is off by almost 1 (typical
for old/bad/broken OS APIs). Actually it even works if the FPs is
completely wrong.
Is it a good idea? Probably not. It might be better to only output a
warning message. But unless there are reports about it going terribly
wrong, I'll go with this for now.
Actually I'm not content with the detection added in commit 44376d2d. It
triggers too often if vsync is very jittery. It's easy to avoid this: we
add more samples to the detection by reusing the drift computation loop.
If there's a significant step in the drift, we consider it a drop.
This adds basic support for ICC profiles. Per-monitor profiles are
supported. WCS profiles are not supported, but there is an API for
converting WCS profiles to ICC, so they might be supported in future.
I'm just not sure if anyone actually uses them.
Reloading the ICC profile when it's changed in the control panel is also
not supported. This might be possible by using the WCS APIs and watching
the registry for changes, but there is no official API for it, and as
far as I can tell, no other Windows programs can do it.
Of course, only FFmpeg has av_clipd(), while Libav does not. (Nevermind
that it doesn't do much more than the mpv MPCLAMP() macro. Supposedly,
libavutil can provide optimized platform-specific versions for av_clip*,
but of course nothing actually does for av_clipf() or av_clipd().)
Return the estimated/ideal flip time to the timing logic (meaning
vo_get_delay() returns a smoothed out time). In addition to this add
some lame but working drift compensation. (Useful especially if the
display FPS is wrong by a factor such as 1.001.)
Also remove some older leftovers. The vsync_interval_approx and
last_flip fields are redundant or unneeded.
For the vo-delayed-frame-count property.
Slightly less dumb than the previous one (which was removed earlier),
but still pretty dumb. But this also seems to be relatively robust, even
with strong vsync jittering.
This logic was kind of questionable anyway, and --display-sync should
give much better results. (I would even go as far as saying that the
FPS-dependent framedrop code made things worse in some situations. Not
all, though.)
This is simply the average refresh rate. Including "bad" samples is
actually an advantage, because the property exists only for
informational purposes, and will reflect problems such as the driver
skipping a vsync.
Also export the standard deviation of the vsync frame duration
(normalized to the range 0-1) as vsync-jitter property.
libswresample doesn't do it - although it should, but the patch is stuck
in limbo.
Probably reduces problems with artifacts on downmixing in some cases.
The OSD takes up an entire fullscreen dispmanx layer. Although the GPU
should be able to handle it (possibly even without any disadvantages),
it'll still be useful for debugging performance issues.
This is a hack, but unfortunately the DwmGetCompositionTimingInfo
heuristic does not work in all cases (with multiple-monitors on Windows
8.1 and even with a single monitor in Windows 10.) See the comment in
mp_w32_is_in_exclusive_mode() for more details.
It should go without saying that if any better method of doing this
reveals itself, this hack should be dropped.
Remove known useless device entries from the --audio-device list (and
corresponding property). Do this because the list is supposed to be a
high level list of devices the user can select. ALSA does not provide
such a list (in an useable manner), and ao_alsa.c is still in the best
position to improve the situation somewhat.
The ALSA doxygen says:
IOID - input / output identification ("Input" or "Output"), NULL
means both
This bug was blatantly introduced with commit cf94fce4.
It doesn't have any real purpose anymore. Up until now, it was still
implemented by vo_wayland, but since we changed how the frame callbacks
work, even that appears to be pointless.
Originally, the plan was to somehow extend this mechanism to all
backends and to magically fix frame scheduling, but since we can't hope
for proper mechanisms even on wayland, this idea looks way less
interesting.
10 bit HEVC would require DXVA2_ModeHEVC_VLD_Main10, and most a
different surface type (judging by lavfsplitter source code, both
P010 and P016 would work). Since I'm unable to test this stuff,
exclude 10 bit for now.
See #2516.
If a second subtitle is shown, it should be forced to display on top
of the screen. This was working only if --no-ass was passed, because
otherwise the subtitle was rendered normally (i.e. usually on the
bottom).
This is actually all bullshit. There are many factors that can ruin the
video playback experience (and most outside of our or the user's
control).
One thing that makes sense is that this declares incompatibility with
Windows XP (fixes#2473).
The D3D9 backend does not support GLES 3, which makes it pretty useless.
But it still might be a legitimate replacement of vo_direct3d.c on
Windows 7 machines.
Note that we could just use:
eglGetDisplay(EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE)
But for now I'll leave the old code. Maybe this can exclude use of
software rendering backends (EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE).
Since I'm not sure, I won't touch it.
Running mpv with default config will now pick up ANGLE by default. Since
some think ANGLE is still not good enough for hq features, extend the
"es" option to reject GLES backends, and add to to the opengl-hq preset.
One consequence is that mpv will by default use libswscale to convert
10 bit video to 8 bit, before it reaches the VO.
I decided that I actually can't stand how vo_opengl unnecessarily puts
the video through 3 shader stages (instead of 1). Thus, what was meant
to be a fallback for weak OpenGL implementations, the dumb-mode, now
becomes default if the user settings allow it.
The code required to check for the settings isn't so wild, so I guess
it's manageable. I still hope that one day, our rendering logic can
generate ideal shader stages for this case too.
Note that in theory, dumb-mode could be reenabled at runtime due to a
color management 3D LUT being set, so a separate dumb_mode field is
required. The dumb-mode option can't just be overwritten.
Unfortunately, color management can still not work, because no GLES
version specified so far support fixed-point 16 bit textures. Maybe
we could use integer textures, but these don't support filtering.
Using float textures would be another possibility.
Polar scalers use 1D textures, because they're slightly faster on some
GPUs than 2D textures. But 2D textures work too, so add support for
them.
Allows using these scalers with ANGLE.
Just like commit f9a2fc59. There are probably some more such cases.
The vec2 constructor calls are probably fine, but don't bother with
confusing inconsistencies.
While desktop GL's glTexImage2D() essentially accepts anything, GLES is
much stricter. The combination of allowed formats/types/internal formats
is exactly specified. The GLES 3.0.4 specification lists them in
table 3.2. (The ANGLE API validation code references this table.)
The table could probably be extended into a general declarative table
about GL formats covering other uses, but this would be a big
non-trivial project, so don't bother and accept a minor degree
of duplication with other tables.
Note that the format and type do (or should) not matter here, because
no image data is transferred to the GPU.
We don't only need float textures for advanced scaling - we also need
them to be filterable with GL_LINEAR. On GLES, this is not supported
until GLES 3.1, but some implementation expose them with extensions.
This makes advanced scaling sort-of work for GLES 3.0 (on ANGLE). It's
still not very advisable, as 8 bits might not be enough to avoid
debanding. (Ironically, the debanding filter can be enabled, and does
not raise any GL errors - but probably doesn't do anything useful.)
Turns out glGetTexLevelParameter, which is missing in ANGLE, is a
GLES3.1 function. Removing it from the list of core GLES3 functions
makes ANGLE work in GLES3 mode.
Apparently, some audio drivers do not support the DTS subtype, but
passthrough works anyway if the AC3 subtype is set. Just retry with
AC3 if the proper format doesn't work. The audio device which
exposed this behavior reported itself as
"M601d-A3/A3R (Intel(R) Display Audio)".
xbmc/kodi even always passes DTS as AC3.
ANGLE is a GLES2 implementation for Windows that uses Direct3D 11 for
rendering, enabling vo_opengl to work on systems with poor OpenGL
drivers and bypassing some of the problems with native GL, such as VSync
in fullscreen mode.
Unfortunately, using GLES2 means that most of vo_opengl's advanced
features will not work, however ANGLE is under rapid development and
GLES3 support is supposed to be coming soon.
This is another regression of the recently added start time probing. If
a seek is executed after opening the file (but before reading any
packets), the first block is discarded instead of indexed. If there are
no other keyframes in the file, seeking will fail completely.
Fix it by seeking to the cluster start if there aren't any index entries
yet. This will read the skipped packet again.
Fixes#2498.
This was used with --no-sub-ass (aka --no-ass). This option (which is
not yet removed) strips all styling from the subtitles, and renders them
as plaintext only. For some reason, it originally seemed convenient to
reuse all the OSD text rendering code (osd_libass.c). While this was
indeed simple, it had a bad influence on the rest of the code. For
example, it had to decide whether to go through the OSD code path, or
the proper subtitle renderer in sd_ass.c.
Kill the OSD subtitle renderer. Reimplement --no-sub-ass and also
"secondary" subtitles in sd_ass.c. fill_plaintext() contains some rather
minor code duplication with osd_libass.c for setting up a dummy
ASS_Event and escaping the stripped text. Since sd_ass.c already has to
handle "normal" text subtitles, and has code for stripping ASS tags,
this remains all relatively simple.
Remove all the unnecessary crap from the rest of the code.
Use the demux_set_ts_offset() added in the previous commit to base each
timeline segment to use timestamps according to its relative position
within the overall timeline. As a consequence we don't need to care
about these timestamps anymore, and everything becomes simpler.
(Another minor but delicious nugget of sanity.)
Most of this is explained in the DOCS additions.
This gives us slightly more sanity, because there is less interaction
between the various parts. The goal is getting rid of the video_offset
entirely.
The simplification extends to the user API. In particular, we don't need
to fix missing parts in the API, such as the lack for a seek command
that seeks relatively to the start time. All these things are now
transparent.
(If someone really wants to know the real timestamps/start time, new
properties would have to be added.)
Something goes wrong somewhere. Don't bother, it's only needed for
compatibility with our absolute baseline (GL 2.1/GLES 2).
On the other hand, we can process nv12 formats just fine.
For the sake of vaapi interop, we want to use EGL, but on the other
hand, but because driver developers are full of shit, vdpau interop will
not work on EGL (even if the driver supports EGL). The latter happens
with both nvidia and AMD Mesa drivers.
Additionally, EGL vaapi interop support can apparently only detected at
runtime by actually using it. While hwdec_vaegl.c already does this, it
would require initializing libva on _every_ system, which will cause
libav to print an unpreventable bullshit message to the terminal.
Try to counter these huge loads of bullshit by adding more fucking
bullshit.
We want the following behavior:
- VO probed, backend probed: only accept non-sw, fail completely
otherwise
- VO forced, backend probed: use the first non-sw, or if none is found,
fall back to the first working sw backend
- VO probed, backend forced: (I don't care about this case)
- VO forced, backend forced: just use that backend
Also, on backend probe failure the vo->probed field was left in its old
state.
This adds support for the progress indicator taskbar extension
that was introduced with Windows 7 and Windows Server 2008 R2.
I don’t like this solution because it keeps its own state and
introduces another VOCTRL, but I couldn’t come up with anything
less messy.
closes#2399
In the display-sync, non-interpolation case, and if the display refresh
rate is higher than the video framerate, we duplicate display frames by
rendering exactly the same screen again. The redrawing is cached with a
FBO to speed up the repeat.
Use glBlitFramebuffer() instead of another shader pass. It should be
faster.
For some reason, post-process was run again on each display refresh.
Stop doing this, which should also be slightly faster. The only
disadvantage is that temporal dithering will be run only once per video
frame, but I can live with this.
One aspect is messy: clearing the background is done at the start on the
target framebuffer, so to avoid clearing twice and duplicating the code,
only copy the part of the framebuffer that contains the rendered video.
(Which also gets slightly messy - needs to compensate for coordinate
system flipping.)
Currently, vo.c will always continue to render the currently queued
frame, which sets last_flip, which in turn confuses vo_get_delay(),
which in turn will show a bogus A/V desync message on unpause. So just
reset it again on unpause.
I guess the removed code is an old leftover, and makes no sense anymore.
Should fix weird A/V diff dropouts when frames are being dropped with
display-sync.
If the player sends a frame with duration==0 to the VO, it can trivially
underrun. Don't panic, but keep the correct time.
Also, returning the absolute time from vo_get_next_frame_start_time()
just to turn it into a float with relative time was silly. Rename it and
make it return what the caller needs.
80ms allowable desync was a bit too much. It'd allow for a range of
160ms, which everyone can notice. It might also be a bother to apply
compensation resampling speed for that long.
We always let audio slowly desync until a threshold is reached, and then
pushed it back by applying a maximum compensation speed. Refine what
comes afterwards: instead of playing with the nominal video speed, use
the actual required audio speed for keeping sync as measured by the A/V
difference. (The "actual" speed is the ideal speed with A/V differences
added.)
Although this works in theory, it's somewhat questionable how much this
works in practice. The ideal time value is actually not exact, but is
the time at which the frame is scheduled (could be compensated by using
the time_left calculations in handle_display_sync_frame()). It doesn't
account for speed changes or catastrophic discontinuities. It uses only
10 past frames.
As long as it's within the desync tolerance, do not change the audio
speed at all for resampling. This reduces speed changes which might be
caused by jittering timestamps and similar cases.
(While in theory you could just not care and change speed every single
frame, I'm afraid that such changes could possibly cause audio
artifacts. So better just avoid it in the first place.)
This is very "illustrative", unlike the video-speed-correction
property, and thus useful. It can also be used to observe scheduling
errors, which are not detected by the core. (These happen due to
rounding errors; possibly not evne our fault, but coming from
files with rounded timestamps and so on.)
Instead of looking at the current frame duration for the intended
speedup, look at all past frames, and find a good average speed. This
ties in with not wanting to average _all_ frame durations, which
doesn't make sense in VFR situations.
This is currently done in the most naive way possible, but already sort
of works for VFR which switches between frame durations that are
integer multiples of a base rate. Certainly more improvements could
be made, such as trying to adjust directly on FPS changes, instead of
averaging everything, but for now this is not needed at all.
Helps somewhat with muxer-rounded timestamps.
There is some danger that this introduces a timestamp drift. But since
they are averaged values (unlike as when using an incorrect container
framerate hint), any potential drift shouldn't be too brutal, or
compensate itself soon. So I won't bother yet with comparing the results
with the real timestamp, unless we run into actual problems.
Of course we still prefer potentially real timestamps over the
approximated ones. But unless the timestamps match the container FPS,
we can't know whether they are (no, checking whether the they have
microsecond components would be cheating). Perhaps in future, we could
let the demuxer export the timebase - if the timebase is not 1000 (or
divisible by it), we know that millisecond-rounded timestamps won't
happen.
Get rid of get_past_frame_durations(), which was a bit too messy. Add
a past_frames array, which contains the same information in a more
reasonable way. This also means that we can get the exact current and
past frame durations without going through awful stuff. (The main
problem is that vo_pts_history contains future frames as well, which is
needed for frame backstepping etc., but gets in the way here.)
Also disable the automatic disabling of display-sync if the frame
duration changes, and extend the frame durations allowed for display
sync. To allow arbitrarily high durations, vo.c needs to be changed
to pause and potentially redraw OSD while showing a single frame, so
they're still limited.
In an attempt to deal with VFR, calculate the overall speed using the
average FPS. The frame scheduling itself does not use the average FPS,
but the duration of the current frame. This does not work too well,
but provides a good base for further improvements.
Where this commit actually helps a lot is dealing with rounded
timestamps, e.g. if the container framerate is wrong or unknown, or
if the muxer wrote incorrectly rounded timestamps. While the rounding
errors apparently can't be get rid of completely in the general case,
this is still much better than e.g. disabling display-sync completely
just because some frame durations go out of bounds.
We need a frame duration even on start, because the number of vsyncs
the frame is shown is predetermined. (vo_opengl actually makes use of
this property in certain cases.)
"Missed" implies the frame was dropped, but what really happens is that
the following frame will be shown later than intended (due to the
current frame skipping a vsync).
(As of this commit, this property is still inactive and always
returns 0. See git blame for details.)
Apparently Windows treats windows that use OpenGL, cover an entire
screen and have the WS_POPUP style set or are topmost windows as
exclusive fullscreen windows that bypass DWM and cannot be covered
by other windows.
This means we can’t use dwmflush in fullscreen mode, and it also
means that no other window can cover mpv, and it makes the screen
flicker when switching to fullscreen mode.
This can be avoided by not setting the WS_POPUP flag.
Users can still access the old behavior by enabling stay-on-top
(which IMO at least makes sense—now we just need to get dwmflush
autodetection right to avoid nasty surprises).
fixes#2177
This loaded external .ass files via libass. libavformat's .ass reader is
now good enough, so use that instead.
Apparently libavformat still doesn't support fonts embedded into text
.ass files, but support for this has been accidentally broken in mpv for
a while anyway. (And only 1 person complained.)
Just set the ratio directly by working around the intended semantics of
the API function. The silly rounding stuff we had isn't needed anymore
(and not entirely correct anyway).
Note that since the compensation is virtually active forever, we need to
reset if it's not needed. So always run this code to be sure to reset
it.
Also note that libswresample itself had a precision issue, until it
was fixed in FFmpeg commit 351e625d.
When the audio format is not known yet and the audio chain is still
initializing, filter reinit will fail. Normally, attempts to
reinitialize filters at this stage should be rare (e.g. user commands
editing the filter chain). But it sometimes happened with track
switching in combination with the video code calling
update_playback_speed() at arbitrary times.
Get rid of the message by not trying to change the filters for the sake
of playback speed update while decoding is still being initialized.
Until now, we've relied on the following things:
- you can send flush packets to the decoder even if it's fully flushed,
- you can send new packets to a flushed decoder,
- you can send new packers to a partially flushed decoder.
("flushing" refers to sending flush packets to the decoder until the
decoder does not return new pictures, not avcodec_flush_buffers().)
All of these are questionable. The libavcodec API probably doesn't
guarantee that these work well or at all, even though most decoders have
no issue with these. But especially with hardware decoding wrappers
(like MMAL), real problems can be expected. Isolate us from these corner
cases by handling them explicitly.
This applies to unexpected freezes or deadlocks, not e.g. normal
framedrops. The verbose messages also might remind an API user if the
API usage is incorrect, such as not calling mpv_opengl_cb_draw() when a
redraw request was issued.
This commit introduces logic to read other volumes from the same source
as the primary archive. Both .rar formats as well as 7z are supported for now.
It also changes the libarchive callback structure to be per-volume
consistent with the libarchive intenal client data array constructed
with archive_read_append_callback_data.
Added open, close and switch callbacks. Only the latter is strictly
required to make sure that the streams always start at position 0, but
leaving all volumes open can eat a lot of memory for archives with many
parts.
The nnedi3 prescaler requires a normalized range to work properly,
but the original implementation did the range normalization after
the first step of the first pass. This could lead to severe quality
degradation when debanding is not enabled for NNEDI3.
Fix this issue by passing `tex_mul` into the shader code.
Fixes#2464
vo_opengl_cb is a special case, because we somehow have to render video
asynchronously, all while "trusting" the API user to do it correctly.
This didn't quite work, and a while ago a compromise using a timeout to
prevent theoretically possible deadlocks was added.
Make it even more synchronous. Basically, go all the way, and
synchronize rendering between VO and user renderer thread to the
full extent possible.
This means the silly frame queue is dropped, and we event attempt to
synchronize the GL SwapBuffer call (via mpv_opengl_cb_report_flip()).
The changes introduced with commit dc33eb56 are effectively dropped. I
don't even remember if they mattered.
In the future, we might make all VOs fetch asynchronously from a frame
queue, which would mostly remove the differences between vo_opengl and
vo_opengl_cb, but this will take a while (if it will even be done).
Pick the correct GLSL version from the GL_SHADING_LANGUAGE_VERSION
string. Might be somewhat questionable, as we expect the minor version
number not to have leading 0s.
Should help with cases when the reported GLSL version is much higher
than the equivalent of the reported GL version. This problem was
observed in combination with GL_ARB_uniform_buffer_object, which
can't be used if the declared GLSL version is too low.
Has the same function as setting the option.
This commit changes the property in a bunch of other ways. For example
if the VO is not created, it will return the option value.
Simplifies some auto detection matters.
I _still_ don't want to remove the lazy loading mechanism, because it's
still slightly useful for filters using the hwdec APIs. My main
motivation for not always preloading them is actually that libva prints
random useless crap to the terminal with no way to prevent this.
The examples demonstrates use with optical media, which is far from
mpv's main purpose.
The authors section is a leftover from MPlayer times. There are enough
other places which reiterate how mpv is based on mplayer2/MPlayer,
copyright statements, and so on.
Hint that the linked section contains information for Windows. (Well,
that's a lie, but it has a link to the Windows section.)
Avoid implying that lines in the config file end with ';'. Also, the <>
are probably just confusing.
Deal with jittering Matroska crap timestamps. This reuses the mechanism
that is needed for frames without PTS, and adds a heuristic to it. If
the interpolated timestamp is less than 1ms away from the real one, it
might be due to Matroska timestamp rounding (or other file formats with
such rounding, or files remuxed from Matroska).
While there actually isn't much of a need to do this (audio PTS
jittering by such a low amount doesn't negatively influence much), it
helps with identifying jitter from other sources.
Instead of requiring the decoder to set the PTS directly on the
dec_audio context (including handling absence of PTS etc.), transfer the
packet PTS to the decoded audio frame. Marginally simpler, and gives
more control to the generic code.
Notes:
- Unfortunately the only way to talk to EGL from within DRM I could find
involves linking with GBM (generic buffer management for Mesa.)
Because of this, I'm pretty sure it won't work with proprietary NVidia
drivers, but then again, last time I checked NVidia didn't offer
proper screen resolution for VT.
- VT switching doesn't seem to work at all. It's worth mentioning that
using vo_drm before introduction of VT switcher had an anomaly where
user could switch to another VT and input text to it, while video
played on top of that VT. However, that isn't the case with drm_egl:
I can't switch to other VT during playback like this. This makes me
think that it's either a limitation coming from my firmware or from
EGL/KMS itself rather than a bug with my code. Nonetheless, I still
left (untestable) VT switching code in place, in case it's useful to
someone else.
- The mode_id, connector_id and device_path should be configurable for
power users and people who wish to watch videos on nonprimary screen.
Unfortunately I didn't see anything that would allow OpenGL backends
to register their own set of options. At the same time, adding them to
global namespace is pointless.
- A few dozens of lines could be shared with vo_drm (setting up VT
switching, most of code behind page flipping). I don't have any strong
opinion on this.
- Sometimes I get minor visual glitches. I'm not sure if there's a race
condition of some sort, unitialized variable (doubtful), or if it's
buggy driver. (I'm using integrated Intel HD Graphics 4400 with Mesa)
- .config and .control are very minimal.
Signed-off-by: wm4 <wm4@nowhere>
While it seemed like a pretty good idea at first, it's just a dead end
and works only in the simplest cases. While it may or may not help
slightly with audio sync mode, the display-sync mode already compensates
this in a better way. The main issue is that timestamps at this layer
are not in order, so it can look at single timestamps only.
Essentially we'd use something random, just because it's part of the srt
of traditionally used ALSA channel mappings. But each driver can do its
own things.
This doesn't let me sleep at night, so remove it.
This could accidentally change some spdif formats to AAC (because AAC is
the first on the list and will match first). spdif formats are
inherently uninterchangeable, so treat them as their own class of
formats (like int vs. float).
Might fix some issues with ao_wasapi.c.
glXCreateContextAttribsARB() by design can throw some X11 errors. We
ignore these, but we generally still print error messages to the
terminal. This was confusing/annoying users, so silence it. The stupid
part is that the Xlib error handler is global, so we have to be slightly
careful here.
They are evil and should be eradicated. Some of these were pretty dumb
anyway.
There are probably some more around in platform specific code or other
code not enabled by default on Linux.
This is based on an older patch by James Ross-Gowan. It was rebased and
cleaned up. Also, the DWM API usage present in the older patch was
removed, because DWM reports nonsense rates at least on Windows 8.1
(they are rounded to integers, just like with the old GDI API - except
the GDI API had a good excuse, as it could report only integers).
Signed-off-by: wm4 <wm4@nowhere>
This simplifies update_screen_rect a bit. Unless --fs-screen=all is
used, it will always get an HMONITOR and call GetMonitorInfo to
determine its dimensions. This will make it easier for the next few
commits to determine the colour profile and the refresh rate from the
HMONITOR.
There is a slight change in behaviour. When selecting a screen that is
out of range, such as --screen=9 on a machine with only two monitors,
the old code would silently select the last existing monitor. The new
code prints an error message and falls back to the default screen (same
as the Cocoa code.)
Signed-off-by: wm4 <wm4@nowhere>
The call to EnumDisplaySettings seems to be a relic from when MPlayer
ran on systems that didn't have GetMonitorInfo or SM_CX/CYVIRTUALSCREEN.
GetMonitorInfo was loaded dynamically, so it was possible for MPlayer to
run without it and use the values returned by EnumDisplaySettings.
These are always present in modern versions of Windows, so the values
returned from EnumDisplaySettings are always overwritten. Remove the
call to EnumDisplaySettings and assume SM_CX/CYVIRTUALSCREEN is always
present.
Signed-off-by: wm4 <wm4@nowhere>
Commit 27dc834f added it as such.
Also remove the check for glUniformBlockBinding() - it's part of an
extension, and the check glGetUniformBlockIndex() already checks whether
the extension is fully available.
Implement NNEDI3, a neural network based deinterlacer.
The shader is reimplemented in GLSL and supports both 8x4 and 8x6
sampling window now. This allows the shader to be licensed
under LGPL2.1 so that it can be used in mpv.
The current implementation supports uploading the NN weights (up to
51kb with placebo setting) in two different way, via uniform buffer
object or hard coding into shader source. UBO requires OpenGL 3.1,
which only guarantee 16kb per block. But I find that 64kb seems to be
a default setting for recent card/driver (which nnedi3 is targeting),
so I think we're fine here (with default nnedi3 setting the size of
weights is 9kb). Hard-coding into shader requires OpenGL 3.3, for the
"intBitsToFloat()" built-in function. This is necessary to precisely
represent these weights in GLSL. I tried several human readable
floating point number format (with really high precision as for
single precision float), but for some reason they are not working
nicely, bad pixels (with NaN value) could be produced with some
weights set.
We could also add support to upload these weights with texture, just
for compatibility reason (etc. upscaling a still image with a low end
graphics card). But as I tested, it's rather slow even with 1D
texture (we probably had to use 2D texture due to dimension size
limitation). Since there is always better choice to do NNEDI3
upscaling for still image (vapoursynth plugin), it's not implemented
in this commit. If this turns out to be a popular demand from the
user, it should be easy to add it later.
For those who wants to optimize the performance a bit further, the
bottleneck seems to be:
1. overhead to upload and access these weights, (in particular,
the shader code will be regenerated for each frame, it's on CPU
though).
2. "dot()" performance in the main loop.
3. "exp()" performance in the main loop, there are various fast
implementation with some bit tricks (probably with the help of the
intBitsToFloat function).
The code is tested with nvidia card and driver (355.11), on Linux.
Closes#2230
Add the Super-xBR filter for image doubling, and the prescaling framework
to support it.
The shader code was ported from MPDN extensions project, with
modification to process luma only.
This commit is largely inspired by code from #2266, with
`gl_transform_trans()` authored by @haasn taken directly.
This check disables the display-sync resample method. If the filters
convert PCM to AC3, we can still insert a filter to change speed. This
is because filters are inserted at the beginning of the filter chain.
Actually, it didn't really require that before (most work was avoided),
but some bits had to be run anyway. Separate the speed change into a
light-weight function, which merely updates already created filters, and
a heavy-weight one which messes with filter insertion.
This also happens to fix the case where the filters would "forget" the
current speed (force resampling, change speed, hit a volume control to
force af_volume insertion - it will reset speed and desync).
Since we now always run the light-weight function, remove the
af_scaletempo verbose message that is printed on speed setting. Other
than that, all setters are cheap.
Move it (in a cosmetic sense), and also move its invocation to below all
the video handling.
All other changes remain cosmetic, including moving the framedrop
calculation code, and getting rid of the video_speed_correction
variable.
For some reason, the encoder didn't like that the AVPacket already had
fields set. I'm not quite sure, but this might just be invalid API
usage. Do it as it's recommended.
We still have a sample-based buffer between filters and audio outputs.
In order to avoid cutting frames into half (which can upset receivers),
we strictly need to align the boundaries on which we cut the audio.
Update msg.c state immediately if a terminal or logging setting is set.
Until now, this was delayed until mp[v]_initialize() was called. When
using the client API, you could easily miss logged error messages, even
when logging was initialized early on by calling
mpv_request_log_messages().
(Properties can't be used for this either, because properties do not
work before mpv_initialize().)
The noframe event is logged whenever there is no new frame. This can
happen due to normal redraws, but also due to video frame queue
underflow.
The mpv_opengl_cb_report_flip() API function is currently pretty
useless, because blocking on the video frame queue is more reliable and
simpler. But at least we can log the actual vsync.
next_vsync/prev_vsync was only used to retrieve the vsync duration. We
can get this in a simpler way.
This also removes the vsync duration estimation from vo_opengl_cb.c,
which is probably worthless anyway. (And once interpolation is made
display-sync only, this won't matter at all.)
We need to effectively swap the last channel pair. See commit 4e358a96
and 5a18c5ea for details.
Doing this seems rather strange, as 7.1 just extends 5.1 with 2 new
speakers, and 5.1 doesn't need this change. Going by the HDMI standard
and the Intel HDA sources (cited in the referenced commits), it also
looks like 7.1 should simply append two channels to 5.1 as well. But
swapping them is apparently correct. This is also what XBMC does. (I
didn't find any other applications doing 7.1 PCM using the ALSA channel
map API. VLC seems to ignore the 7.1 case.) Testing reveals that at
least the end result is correct.
"Normal" ALSA 7.1 is unaffected by this, as it reports a different
(and saner) channel layout.
Instead of constructing an ALSA channel map from mpv ones from scratch,
try to find the original ALSA channel map again. Th result is that we
need to convert channel maps only in one direction. If we need to map
a mp_chmap to ALSA, we fetch the device's channel map list, convert
each entry to mp_chmap, and find the first one which fits.
This seems helpful for the following commit. For now, this only gets rid
of mapping back the trivial MONO mapping, which alone would still be
acceptable, but with other channel layout mogrifications it gets messy
fast. While we need to do something awkward to keep our channel map
reordering for VAR chmaps (which basically gives nicer output and
possibly slightly better performance), this is still the better
solution.
This reverts commit 4e358a9636.
Testing shows the channel pairs must indeed be swapped (details see
commit message of the reverted commit). Making the downmix code move
sl/sr to sdl/sdr is not an appropriate solution anymore, and it's
better to fix the unusual channel layout in ao_alsa.c directly.
(Not reverting the change in chmap.c; this is still correct.)
This affects only the display-sync code path, as for normal timing the
wakeup_pts stuff handles proper wakeup. It's probably mostly a
theoretical issue.
Discontinuities (like toggling fullscreen) can cause multiple frames to
be dropped in succession, which sounds very weird. It's better to drop
some video frames instead to compensate for larger desyncs.
We roughly base it on the maximum allowed speed changes (audio change is
"additional" to the video change to account for deviations when playing
at max. video speed change).
A hw decoder might fail to decode a frame for multiple reasons, and not
always just because decoding is impossible. We can't generally
distinguish these reasons well. Make it more tolerant by accepting
failures of 3 frames, but not more. The threshold can be adjusted by the
repurposed --vd-lavc-software-fallback option.
(This behavior was suggested much earlier in some PR, but at the time
the "proper" hwdec fallback was indistinguishable from decoding error.
With the current situation, "proper" fallback is still instantious.)
ao_alsa: attempt to fix 7.1 over HDMI
The last 2 channels of 7.1 (RLC/RRC in ALSA) were exported as sdl/sdr
instead of sl/sr (I don't even know why I chose sdl/sdr, but SL/SR
and RLC/RRC are different in the ALSA API). libsw/avresample do not
move the sl/sr channels to sdl/sdr when rematrixing, so silence was
sent for 2 channels. If my selection of sdl/sdr is essentially API
abuse, there's no reason why they should do this differently.
The mess here is really that ALSa doesn't map the HDMI layouts cleanly.
Most ALSA drivers export 7.1 in a way compatible to our expectations,
but Intel HDA/HDMI does not:
mpv/ffmpeg: fl-fr-fc-lfe-bl-br-sl-sr
ALSA/generic: FL FR FC LFE RL RR SL SR [1]
ALSA/HDMI: FL FR LFE FC RL RR RLC RRC [2]
The HDMI layout is layout 0x13 (going by CEA-861-B). The comment in
the kernel code has to be correct too. The early standard defines only
1 other layout, which replaces RLC/RRC with FRC/FLC - this probably
corresponds to what we call "7.1(wide)".
So it appears when ALSA requests RLC/RRC, we should feed it sl/sr.
To make it more complicated, Kodi/xbmc apparently also have to deal with
ALSA being special, but instead of sending sl/sr to RLC/RRC, they swap
the last two pairs of the layout, and send sl/sr to RL/RR and bl/br to
RLC/RRC. Or I might have misunderstood their code. I don't have a
7.1-capable A/V receiver, so I can't test this.
For now, go with the simpler solution, and wait until someone tests it.
If the speakers end up swapped, a completely different solution will be
needed.
[1] https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/sound/core/pcm_lib.c?id=refs/tags/v4.3#n2434
[2] https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/sound/pci/hda/patch_hdmi.c?id=refs/tags/v4.3#n307
These calls actually can leave the ALSA configuration space empty (how
very useful), which is why snd_pcm_hw_params() can fail. An earlier
change intended to make this non-fatal, but it didn't work for this
reason.
Backup the old parameters, so we can retry with the non-empty
configuration space. (It has to be non-empty, because the previous
setters didn't fail.)
Note that the buffer settings are not very important to us. They're
a leftover from MPlayer, which needed to write enough data to the
audio device to not underrun while decoding and displaying a video
frame. In mpv, most of these things happen asynchronously, _and_
there is a dedicated thread just for feeding the audio device, so
we should be pretty imune even against extreme buffer settings. But
I suppose it's still useful to prevent PulseAudio from making the
buffer too large, so still keep this code.
Again, this could have bad access, is unlikely, and has no bad
consequences. It's noteworthy that vlc and the ALSA PCM example both do
this first, even if they set the sample rate later.
I'm worried that not restricting the access type before restricting the
format will cause problems. While it's unlikely, it might prevent
failures in some corner cases. Also, since we by default always use
interleaved access (buggy ALSA plugins), this will have no effects at
all.
If the API doesn't list padded channel maps, but the final device
channel map is padded, and if unpadded output is not possible (unlike in
the somewhat similar dmix case), then we shouldn't apply the channel
count mismatch fallback in the beginning. Do it after channel map
negotiation instead.
Doesn't matter much; effectively this prevents just log spam in some
cases where the map is legitimately padded. Normally this is really
only needed for the dmix ALSA case. (See git blame for details.)
The uninit() function was called twice if the uninit() function failed
(once by init(), once by vd_lavc.c code), which caused crashes due to
double-free. (This failure is a corner case, and all other hwdec
backends appear to handle this case gracefully.)
I do not think this code should be able to deal with uninit() being
called other than once. Guarantee that it's called exactly once.
Quoting MSDN: "Notifies the Desktop Window Manager (DWM) to opt in to or
out of Multimedia Class Schedule Service (MMCSS) scheduling while the
calling process is alive.". Whatever this means. (An application can
change the scheduling priority of the window manager?)
Does this improve anything? I have no idea. Certainly this is a program
that does multimedia and graphics, so we seem to be a good match for
this.
Is it bad if we enable this even while playback is inactive or paused? I
have no idea either.
Is there a magic cargo cult function that will mark our renderer thread
as multimedia thing? I have no idea. (We use a function to enable MMCSS
for our audio thread in ao_wasapi.)
Enable it by default, but not unconditionally. Add an "auto" mode, which
disable DwmFlush if the compositor is (probably) inactive. Let's see how
this goes.
Since I accidentally enabled DwmFlush always by default (more or less)
in a previous commit touching this code, this is probably mostly just
cargo-culting, and it's uncertain whether it does anything.
Note that I still got bad vsync behavior when fullscreening mpv, and
making another window visible on the same screen. This happens even if
forcing DWM.
update_av_diff() works on the timestamps, while time_left is in real
time. When playing at not-1 speed, these are very different, and cause
the A/V difference to jitter. Fix this by scaling the expected A/V
desync to the correct range.
Commit acd5816a broke this. It was stopping playback occasionally.
Another case where the non-display-sync interpolation mode
(in->vsync_timed==true) is causing a lot of subtle issues and will be
removed soon.
PAL8 is the only format that is RGB, has only 1 component, is byte-
aligned. It was accidentally detected by the GBRP case as planar RGB.
(It would have been ok if it were gray; what ruins it is that it's
actually paletted, and the color values do not correspond to colors (but
palette entries).
Pseudo-pal formats are ok; in fact AV_PIX_FMT_GRAY is rightfully marked
as MP_IMGFLAG_YUV_P.
This didn't show up with cases where the frame pattern has a cycle of 1
or 2 like it is the case with 24-on-24 fps, or 24-on-60 fps. It did show
up with 25-on-60 fps. (We don't slow down 25 fps video to 24 on default
settings.)
In this case, we must not add the timing error of the next frame to the
A/V difference estimation of the current frame. Use the previous timing
error instead.
This is another bug resulting from the confusion about whether we
calculate parameters for the currently playing frame, or the one we're
about to queue.
Regression since commit 93db4233. I think the bit that was forgotten
here was to remove the vo_w32_config() return value completely. The VO
failed to init because that function always returned 0. This commit
removes these bits and fixes the VO.
Fixes#2434.
Yet another relatively useless option that tries to make OpenGL's sync
behavior somewhat sane. The results are not too encouraging. With a
value of 1, vsync jitter is gone on nVidia, but there are frame drops
(less than with glfinish). With 2, I get the usual vsync jitter _and_
frame drops.
There's still some hope that it might prevent too deep queuing with some
GPUs, I guess.
The timeout for the wait call is 1 second. The value is pretty
arbitrary; it should just not be too high to freeze the process (if
the GPU is un-nice), and not too low to trigger the timeout in normal
cases, even if the GPU load is very high. So I guess 1 second is ok
as a timeout.
The idea to use fences this way to control the queue depth was stolen
from RetroArch:
https://github.com/libretro/RetroArch/blob/df01279cf318e7ec90ace039d60515296e3de908/gfx/drivers/gl.c#L1856
Commit a1315c76 broke this slightly. Frame drops got counted multiple
times, and also vo.c was actually trying to "render" the dropped frame
over and over again (normally not a problem, since frames are always
queued "tightly" in display-sync mode, but could have caused 100% CPU
usage in some rare corner cases).
Do not repeat already dropped frames, but still treat new frames with
num_vsyncs==0 as dropped frames. Also, strictly count dropped frames in
the VO. This means we don't count "soft" dropped frames anymore (frames
that are shown, but for fewer vsyncs than intended). This will be
adjusted in the next commit.
vo_frame.num_vsyncs can be != 1 in some cases in normal sync mode too.
This is not a very exact fix, but in exchange it's robust. (These
vo_frame flags are way too tricky in combination with redrawing and
such.)
There were occasional shader compilation and rendering failures if FBOs
were unavailable. This is caused by the FBO caching code getting active,
even though FBOs are unavailable (i.e. dumb-mode).
Boken by commit 97fc4f.
Fixes#2432.
Fixes linker failure. How did this ever work? Apparently it did most of
the time, but apparently we just got the first case where it didn't.
Fixes#2433.
Bump it to 80, and 2 vsyncs. This is another measure against vsync
jitter. Admittedly this is a bit simplistic (and we should probably
estimate a stable estimated vsync phase instead), but for now this will
do.
It's not needed, because the additional data is not appended, but is the
total size of the audio buffer. The maximum size is the static audio
drop size (or twice, if the audio is duplicated).
Calculate the A/V difference directly in the display sync code, instead
of the awkward current way, which reuses the fields for audio sync.
We still set time_frame, because it makes falling back to audio sync
somewhat smoother.
When dropping or repeating frames, we essentially influence when the
frame after the next frame will be shown, not the next frame. This led
to dropping/repeating frames 2 times, because the A/V difference had a
delay of one frame. Compensate it with the expected value.
av_free_packet() got finally deprecated. Use av_packet_unref() instead,
which has almost the same semantics, has existed for a while, and is
available in all FFmpeg and Libav versions we support.
This was not very reliable.
In the normal vo_opengl case, this didn't deal well enough with vsync
jitter. Vsync timings can jitter quite extremely, up to a whole vsync
duration, in which case the "missed" frame counter keeps growing, even
though nothing is wrong. This behavior also messes up the A/V difference
calculation, but as long as it's within tolerance, it won't provoke
extra frame dropping/repeating. Real misses are harder to detect, and I
might add such detection later.
In the vo_opengl_cb case, this was additionally broken due to the
asynchronity between renderer and VO threads.
This is all kinds of stupid - update_avsync_after_frame() will multiply
this value with the speed at a later point, and we only update this
field for this function. (This should be refactored.)
Until recently, the channel layout code happened to catch this, but now
an explicit check is needed. Otherwise, it'd try to pad the missing
channels with NA in the channel map fallback code.
This is intended for the case when CoreAudio returns only unknown
channel layouts, or no channel layout matches the number of channels the
CoreAudio device forces. Assume that outputting stereo or mono to the
first channels is safe, and that it's better than outputting nothing.
It's notable that XBMC/kodi falls back to a static channel layout in
this case. For some messed up reason, the layout it uses happens to
match with the channel order in ALSA's/mpv's "7.1(alsa)" layout.
Share some code between ca_init_chmap() and ca_get_active_chmap(), which
also makes it look slightly nicer. No functional changes, other than the
additional log message.
If no channel layouts were determined (which can actually happen with
some "strange" devices), the selection code was falling back to mono,
because mono is always added as a fallback. This doesn't seem quite
right.
Allow a fallback to stereo too, if no channel layout could be retrieved
at all. So we always assume that mono and stereo work, if no other
layouts are available.
(I still don't know what the CoreAudio stereo layout is supposed to do.
It could be used to swap left and right channels. It could also be used
to pad/move the channels, but I have never seen that. And it can be set
to non-stereo channels, which breaks mpv. Whatever.)
The main reason is that ao_coreaudio_exclusive needs this for some OSX
devices. They want packed audio, and special-casing this in the
coreaudio code would be too much of a pain.
The maximum of channels we can support is 64 (because FFmpeg uses 64 bit
masks for channel layouts), but since struct mp_audio can get pretty
big (has static allocations of 2 pointers for each channel for planar
mode), it's less wasteful to stay lower for now.
av_get_default_channel_layout() fails with channel counts larger than 8.
The channel layout doesn't need to make sense, so pick an arbitrary
fallback.
libswresample also has options for setting the channel counts directly,
but better not introduce new concepts in the code. Also, libavresample
doesn't have these options.
Change it so that it will always return a bitmask with the correct
number of channels set if an unknown channel map is passed. This didn't
work for channel counts larger than 8, as there are not any standard
channel layouts defined with more than 8 channels (both in mpv and
FFmpeg). Instead, it returned 0.
This will help when raising the maximum allowed channel count in mpv.
Some code in af_lavrresample relies on it, more or less.
One change is that unknown channel maps won't result in lavc standard
channel layouts anymore, just a set of random speakers. This should be
fine, as the caller of mp_chmap_to_lavc_unchecked() should handle these
cases. For mp_chmap_reorder_to_lavc() this is not so clear anymore, but
should also be ok.
For normal channel maps, simply dropping NA channels is still the
correct and wanted behavior.
Currently, the mpv maximum channel count is 8. This commit is
preparation for raising this limit.
mNumberChannelDescriptions being 0 is pretty much an error, but if it
can happen, then the code checking the chmap below will trigger UB, as
chmap is not initialized at all.
Also, simplify the code a little: we never change the number of
channels, so this is just fine.
This code removes filters which can not take spdif inout. This was made
so that PCM filters are transparently dropped in spdif mode.
This entered an endless loop with:
--af=lavcac3enc:::2 --audio-channels=5.1
The forced number of output channels is incompatible with spdif. It's
trying to insert af_lavrresample as conversion filter to compensate for
it. Of course this doesn't work, which triggers the PCM filter removal.
Then it goes on normally - since the new state is exactly as before, it
will try the same thing again, forever.
Fix by reusing the retry counter, which is a very dumb but very
effective measure against these cases of filter negotiation failure. We
could try to be more clever (for example, if the removed filter is a
conversion filter, we can be sure this won't work, and error out
immediately). But better keep it simple and robust.
This speeds up redraws considerably (improving eg. <60 Hz material on a 60 Hz
monitor with display-sync active, or redraws while paused), but slightly
slows down the worst case (eg. video FPS = display FPS).
The IME is not useful for key-bindings. Handle the base ASCII chars
instead and don't show the IME window. For the sake of libmpv users, the
IME should only be disabled on mpv's GUI thread and not application-
wide.
No IME on the GUI thread should also mean that VK_PROCESSKEY will never
have to be handled, so the logic for that can be removed as well.
Older systems have certain EGL extension definitions missing. We
redefine them to make the build system easier, and because it's trivial.
But we forgot to define the EGL_LINUX_DMA_BUF_EXT identifier. (I hope
it's the only missing one.)
This makes the bitrate properties unavailable, instead of
returning 0 when:
1. No track is selected, or
2. Not enough packets have been read to have a bitrate estimate yet
Some mkv files can have this. The chapter times are still timestamps
(and thus not affected by the start time), but it misplaces the OSD
chapter ticks.
The equalizer code as it exists in vo_opengl works perfectly fine. The
situation in vo_opengl_cb is pretty different. The playback thread can't
communicate with the renderer thread synchronously (essentially to give
the API user more flexibility). So the equalizer communication has to be
done in an asynchronous way too.
There were two problems. First, the eq capabilities can change with the
pixel format, and the renderer initializes them on config only. This
means equalizers were disabled on the first config run, and options like
--video-output-levels or --brightness would not work. So we just
initialize the caps with a known superset. The player will not correctly
indicate when setting an eq doesn't work, but we're fine with it, as it
is a relatively cosmetic issue.
Second, it copied back the eq settings in the "wrong" moment (what
for?), which overwrote the settings in some cases.
Third, the eq was not reset correctly on vo init. This is needed to make
it behave the same as vo_opengl.
If the aspect ratio of the video resolution and the subtitle resolution
(the implied subtitle coordinate system) mismatch, the subtitles
obviously can't be overlayed over the video perfectly. Either you get
video that can't be covered by subtitles, or the subtitles could go
beyond the video. We don't want to stretch the subtitle to compensate
for the aspect ratio, because it would look terrible.
Until now, mpv used to fit the subtitle rectangle into the video
rectangle (letterboxing/pillarboxing). This looks odd with some sample
files with subtitle canvas being wider than the video. Also, mpc-hc
displays them in a better way. vlc stretches them, which looks bad.
While you probably can't win this game with all those broken files
around, pick the mpc-hc method to handle this.
There was a complaint that the naming is inaccurate. That's probably
right. Just use the official name instead, which is a bit clunky, but
surely correct.
Helps with broken vobsubs, which have an incorrect resolution header
set.
So we just extend the subtitle resolution to the video size, if the
video size is larger. This helps somewhat with readability, or makes
them visible at all. It should be a pretty safe change, because normally
no sub pictures are supposed to go outside of the area. It should make a
difference with broken files only.
The sample in question had a video resolution of 1888x1072, and a
subtitle resolution of 720x480. Note that always using video resolution
as subtitle resolution would break other files.
Coreaudio gives us a channel map with all entries set to
kAudioChannelLabel_Unknown. This is translated to a mpv channel map with
all channels set to NA, which has special meaning: it's an "unknown"
channel map, which acts as wildcard and can be converted from/to any
channel layout. Not really what we want.
I've got this with USB audio, playing stereo. The multichannel layout
consisted of 2 unknown channels, while the stereo channel map was
stereo (as expected).
Note that channel maps with _some_ NA entries are not affected by this,
and must still work.
If the device returns an unexpected number of channels instead of the
requested count on init, don't immediately error out. Instead, look if
there's a channel map with the given number of channels.
If there isn't, still error out, because we don't want to guess the
channel layout.
It's great that the new algorithm supports multiple placebo iterations
and all, but it's really not necessary and hurts performance in the
general case for the sake of the 0.1% that actually pause the screen
and look for minute differences.
Signed-off-by: wm4 <wm4@nowhere>
Reportedly fixes operation with "USB connected Parasound ZDAC v.2". (OSX
and USB audio sure is not nice at all.)
This might be perceived as hang by some users, so it's quite possible
that this will have to be adjusted again somehow.
Fixes#2409.
This reverts commit c10fb4ce9f.
This is already done in vo_wayland.c:resize,324 doing it here makes the window bigger before the video resizes showing a black area while dragging the border.
Apparently this function caused weird problems to me. I have no idea
why. The usage of the function looks perfectly fine to me, and even
rounding issues can be excluded. In any case, getting rid of this solved
my problem, and makes the code actually more readable.
The previous commit moved the av_frame_unref() after the got_picture
check. This accidentally also deferred the software fallback
reinitialization to until a software picture was decoded (instead of the
exact time of the fallback), which is not ideal.
Just rely on the fact that calling av_frame_unref() on a frame is ok
even if nothing was decoded.
Commit 12cd48a8 started setting the hwdec_failed field even if hwdec was
not active, and because it also checked this field even if hwdec was not
active, broke decoding forever.
Fix this, and also avoid a memory leak or API misuse by releasing the
decoded picture. Passing an unreleased frame to the decoder has as far
as I know no defined effects.
This fixes initial decoding of some samples. See #1341.
According to Libav devs, this should be considered a libavcodec bug, but
as it's hard to fix, here we go.
Adds support for AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRP12,
AV_PIX_FMT_GBRP14, AV_PIX_FMT_GBRP16, AV_PIX_FMT_GBRAP, and
AV_PIX_FMT_GBRAP16.
(Not that it matters, because nobody uses these anyway.)
This VA_FOURCC isn't even defined by latest drivers, so I'm just
assuming it doesn't exist and never existed. For planar 4:2:0,
VA_FOURCC_YV12 is normally preferred, and there's even a VA_FOURCC_IYUV
for 4:2:0 with unswapped planes.
0.34 and 0.35 don't have the buffer API, such as vaAcquireBufferHandle.
This is only needed for the EGL interop, but why bother staying
compatible for such old things (0.36 was released over a year ago).
We also can drop some minor compatibility ifdeffery.
MKV files can very well start with timestamps other than 0. While mpv
has support for such files in general, and demux_lavf enables this
feature, demux_mkv didn't export a start time.
Implement this by simply reading the first cluster timestamp. This in
turn is done by reading 1 block. While we don't need the block for this
prupose at all, it's the easiest way to get the cluster timestamp read
correctly without code duplication. In theory this could be wrong, and
a packet could start at a much later time, but in practice this won't
happen.
This commit also adds an option to disable this feature. It's not
documented because nobody should use it. (But I happen to have a need
for this.)
Let's hope this doesn't confuse client API users too much. It's still
the best solution to get rid of corner cases where it actually return
the wrong timestamp on start, and then suddenly jump.
matplotlib is pathetically slow, which makes using stats-conv.py to view
dumps longer than a few seconds a huge pain.
pyqtgraph is slightly faster than matplotlib. Other than that, it seems
to be worse in every aspect (at least for plotting), but such is life.
When seeking, the current frame will have the wrong timestamp, until the
seek is done and a new frame from the seek target is shown. We still use
the "old" frame for redrawing during seeks. This frame has to be
explicitly marked with still=true in order not to confuse the
interpolation queue. If this is not done, it will ignore frames until a
frame with approximately the same timestamp as the "old" frame is
reached. (Does this mean interpolation handles timestamp resets
incorrectly? I have no idea.)
Of course we also have to clear possibly queued frames on seeks.
Also, in pausing, explicitly let the frame redraw.
This adjustment is supposed to improve the audio speed calculation in
case of unexpected desync. The flipped sign made it actually worse,
although the total impact of this bug was very minor.
Small adjustments to the playback speed use swr_set_compensation()
to stretch the audio as it is required. But since large adjustments
are now handled by actually reinitializing libswresample, the small
adjustments get rounded off completely with typical frame sizes.
Compensate for this by accounting for the rounding error and keeping
track of fractional samples that should have been output to achieve
the correct ratio.
This fixes display sync mode behavior, which requires these adjustments
to be relatively accurate.
Newer nVidia drivers support EGL, but they seem to work badly,
apparently don't support some needed features or not in a form we want
(such as swap control), and vdpau interop is not available. Disable it
by default, because I'm tired of explaining this issue.
Can be reverted as soon as nVidia release working drivers.
The libavcodec h264 decoder contains some idiotic code with unknown
purpose (no sample or explanation known that necessitates its
existence), that causes the AVCodecContext.get_format callback to be
invoked at a time when hwaccels can't be initialized. By definition, the
get_format callback is supposed to initialize hwaccels (another idiotic
thing now part of the API, but different story). This causes hwdec
initialization sometimes to fail (WolfensteinTwitch.mp4): the first
get_format callback will mark it as failed, so the second get_format
(the "proper" normal one) will not bother restoring the state, and hwdec
init fails.
While this should be fixed in libavcodec (good luck with that), it's
quite easy to workaround.
This affects the subtitle preroll mode during seeking. It could matter
somewhat with insane files with ten-thousands of subtitle events, which
now seem to pop up, and will avoid packet queue overflow.
swr/avresample_set_compensation() was made for small speed adjustments.
Non-documentation says it should be used for changes not larger than 1%,
so reinitialize the sampler if the change is larger than that.
This fixes a regression since commit f4d62da8. The original code run
vo_cocoa_config_window() once without creating the window, which had the
effect that the last part of the function was run at least once before
the actual window was created. Fix the regression by moving it to before
the window is created.
The regression itself is hard to describe. One test case: start mpv from
a fullscreened terminal window. It should switch to another desktop,
with the mpv window visible. This didn't happen anymore.
mpv_opengl_cb_uninit_gl() still needs the OpenGL context. It makes calls
to free OpenGL objects. Strictly speaking, this is probably unnecessary,
because the OpenGL context is destroyed afterwards (implicitly freeing
all related objects). But mpv_opengl_cb_uninit_gl() does not require the
destruction of the OpenGL context, and thus has to free resources
manually.
It's also true that OpenGL normally simply ignores API calls (or returns
errors) if no context is set, but doing it properly is cleaner.
That makeCurrent() can be called in the destructor is explicitly allowed
and recommended for freeing GL resources in the Qt docs.
This fixes a mpv error message on exit.
Thanks to rcombs, ffmpeg now properly supports DASH and we can
remove our hacks for it and use it by default whenever
available. If you don't like this for whatever reason, you
can get the "normal" streams back with --ytdl-format=best .
Closes#579Closes#1321Closes#2359
If video EOF happens during playback restart, and audio is syncing, and
the demuxer packet queue overflows (i.e. no new packets will be read),
then it could happen that the player accidentally enters sleeping, and
continues playing anything only after e.g. user input wakes it up.
libass 0.13.0 breaks this due to removal of fontconfig from its core
(instead, fontconfig is one possible backend, and pattern lookup is
apparently not possible anymore).
FFmpeg supports all formats the old subreader code does, and is better
at it. On the other hand, subreader.c's probing is bad and can lead to
false positives easily.
swr_set_compensation() changes the apparent sample rate on the fly (who
would have guessed). It is thus very well-suited for adjusting audio
speed on the fly during playback (like needed by the display-sync mode).
It skips the relatively slow resampler reinitialization.
If this doesn't work (libswresample soxr backend), then fall back to the
old method.
The previous commit handled not falling back to normal decoding if the
AO was reloaded (I think...), and this tries to re-engage spdif pass-
through if it was previously falling back to normal decoding (e.g.
because it temporarily switched to an audio device incapable of
passthrough).
The stop command didn't always stop. In this case, opening a HLS URL and
then sending "stop" during loading would actually make it fallback to
parsing it as a playlist, and then continued to play the playlist items.
(This corner case makes several unfortunate factors come together to
produce this really odd behavior.)
Another issue is that the "stop" was not always explicitly set. This
could be a problem when sending several commands at once. Only the
"quit" command should have priority over the "stop" command, so this is
still checked.
The Copyright file explains the whole license mess. The earlier change
was apparently confusing, because the link reading "details" merely
linked to the GPLv2 license instead of explaining anything. In fact, I
meant to link to the Copyright file in the first place.
Use the first encountered packet PTS/DTS as base, instead of the last
one. This does not add the amount of frames buffered in the codec to the
PTS offset, and thus is better.
Also, don't add the frame time if there was no decoded frame yet. The
first frame should obviously have the timestamp of the first packet
(going by this heuristic).
While b-frame reordering limits the maximum required number to around
16, the number of additionally buffered frames can be much higher.
Guess when this actually matters? (For the libavcodec MMAL wrapper.)
Useless. Sometimes it might be useful to make some extremely broken
files work, but on the other hand --no-correct-pts is sufficient for
these cases.
While we still need some of the code for AVI, the "auto" mode in
particular inflated the size of the code.
This can't be handled correctly at all. Other cases when the decoder
might drop a frame (such as completely failing to decode a frame) will
shift timestamps by a frame, and it can't be avoided.
While we could maybe find a better way to handle this with libavcodec's
main decoders, this seems to be much harder if it should work with
certain HW decoders, which don't passthrough the DTS field (such as
MMAL). Another problem are .avi files with b-frames. So just leave it
as it is.
The manpage entry explains this.
(Maybe this option could be always enabled and removed. I don't quite
remember what valid use-cases there are for just disabling audio
entirely, other than that this is also needed for audio decoder init
failure.)
Make the code a bit more uniform. Always build a "dummy" audio output
list before probing, which means that opening preferred devices and
pure auto-probing is done with the same code. We can drop the second
ao_init() call.
This also makes the next commit easier, which wants to selectively
fallback to ao_null. This could have been implemented by passing a
different requested audio output list (instead of reading it from
MPOptions), but I think it's better if this rather special feature
is handled internally in the AO code. This also makes sure the AO
code can handle its own options (such as the audio output list) in
a self-contained way.
This was used only by the timestamp sorting code, which is a fallback
for avi files (as well as avi-muxed mkv files). This was supposed to
prevent accumulating timestamps in case the decoder consumes more
packets than it outputs frames (i.e. frames are dropped). This didn't
work very well (timestamps could be off by a large amount), the
estimation of the delay was fragile, and the interdependencies with the
decoder were annoying, so kill it.
This parameter has been unused for years (the last flag was removed in
commit d658b115). Get rid of it.
This affects the general VO API, as well as the vo_opengl backend API,
so it touches a lot of files.
The VOFLAGs are still used to control OpenGL context creation, so move
them to the OpenGL backend code.
Make handling of metadata slightly more generic, and add reading of the
"PERFORMER" fields. There are some more fields, but for now let's leave
it at this.
TRACK-specific PERFORMER fields have to be read from the per-chapter
metadata (somewhat obscure).
Fixes#2328.
This gets rid of an old hack, VOFLAG_HIDDEN. Although handling of it has
been sane for a while, it used to cause much pain, and is still
unintuitive and weird even today.
The main reason for this hack is that OpenGL selects a X11 Visual for
you, and you're supposed to use this Visual when creating the X window
for the OpenGL context. Which means the X window can't be created early
in the common X11 init code, but the OpenGL code needs to do something
before that. API-wise you need separate functions for X11 init and X11
window creation. The VOFLAG_HIDDEN hack conflated window creation and
the entrypoint for resizing on video resolution change into one
function, vo_x11_config_vo_window(). This required all platform backends
to handle this flag, even if they didn't need this mechanism.
Wayland still uses this for minor reasons (alpha support?), so the
wayland backend must be changed before the flag can be entirely removed.
If interpolation is enabled, then this causes heavy artifacts if done
while unpaused. It's preferable to allow a latency of a few frames for
the change to take full effect instead. If this is done paused, the
frame is fully redrawn anyway.
This reverts commit d11184a256.
Unfortunately, there was a lot of unexpected resistance.
Do note that this is still extremely slow, crappy, etc.
Note that vo_x11.c was further edited. Compared to the removed vo_x11.c,
an additional ~200 lines of code was removed in order to simplify it. I
tried to strip it down as much as possible. In particular, support for
odd non-32 bit formats (24, 16, 15, 8 bit) is dropped.
Closes#2300.
Don't print the URL that is opened twice. stream.c and stream_lavf.c
each printed it once. Remove the logging from stream_lavf.c, and move
the log call to a more interesting point.
The vf_format suboption is replaced with --video-output-levels (a global
option and property). In particular, the parameter is removed from
mp_image_params. The mechanism is moved to the "video equalizer", which
also handles common video output customization like brightness and
contrast controls.
The new code is slightly cleaner, and the top-level option is slightly
more user-friendly than as vf_format sub-option.
This AVPacket field was a hack against the fact that the duration field
was merely an int (too small for things like subtitle durations). Newer
libavcodec drops this field and makes duration 64 bit.
This essentially reverts commit 009dfbe3. FFmpeg VideoToolbox support
is being wacky, and can cause major issues, such as not being able
to decode a single frame. (E.g. by playing a .ts file. This should be
fixed in FFmpeg eventually.)
This is not a straight revert of the commit; just a functional one. We
keep the slightly simpler code structure.
It doesn't deal with VDA at all anymore. Rename it to hwdec_osx.c. Not
using hwdec_videotoolbox.c, because that would give it the longest
source path in this project yet. (Also, this code isn't even
VideoToolox-specific, other than the name of the pixel format used.)
VideoToolbox is preferred. Now that FFmpeg released 2.8, there's no
reason to support VDA anymore. In fact, we had a bug that made VDA not
useable with older FFmpeg versions in some newer mpv releases.
VideoToolbox is supported even on slightly older OSX versions, and if
not, you still can run mpv without hw decoding.
Definitely not needed anymore, and fixes a crash in some weird corner-
cases.
The extradata freeing is apparently still needed, though. (Because a
codec context can be opened again, which makes no sense, but ok.)
This can happen with USB audio. There was already code for this, but
something in mpv and ALSA changed - and now the old code is not
necessarily triggered anymore. It probably depends on the exact
situation.
This could sometimes cause crashes in hotplug events. (Apparently in
cases when CoreAudio changes its state asynchronously, or such.)
CA_GET_STR() does not set the string if there was an error, so errors
have to be strictly checked before using it.
There are at least 2 ways of using VAAPI without X11 (Wayland, DRM).
Remove the X11 requirement from the decoder part and the EGL interop.
This will be used by a following commit, which adds Wayland support.
The worst about this is the decoder part, which includes a bad hack for
using the decoder without any VO interop (also known as "vaapi-copy"
mode). Separate the X11 parts so that they're self-contained. For the
EGL interop code we do something similar (it's kept slightly simpler,
because it essentially only has to translate between our silly
MPGetNativeDisplay abstraction and the vaGetDisplay...() call).
It looks like my hope that we can unconditionally include EGL headers in
the OpenGL code is not coming true, because OSX does not support EGL at
all. So I prefer loading the VAAPI EGL/GL specific extensions manually,
because it's less of a mess. Partially reverts commit d47dff3f.
While EGL 1.4 seemed a bit ambiguous about this to me, it actually says
quite clearly that core functions are not supported with
eglGetProcAddress() in the following paragraph.
Normally, we prefer GLX on X11. But for the VAAPI EGL interop, we
obviously want EGL. Since nvidia does not provide EGL with desktop GL
yet, we can leave it to the autoprobing. Just make sure some failure
messages don't unnecessarily show up in the nvidia case.
This breaks VAAPI GLX interop by default, but I don't care much. If
you use --hwdec=auto (which you should if you want hw decoding), this
should fallback to vaapi-copy instead.
Probe the surface format, and check whether it's really something we
support. This also does a complete check whether the EGL interop works
at all (the only way to find this out is actually running this code).
Also, support YV12. Under some circumstances, vaapi (with Intel
drivers) can be made to use this format.
Unfortunately, the Intel drivers show some very weird behavior, which
is hopefully a bug. insane_hack() provides a very evil workaround (see
comments). A proper solution might be passing the hw format as part of
mp_image_params, but as long as hw surfaces appear to be able to change
the format on the fly, attempting this is probably not worth the extra
complexity and likely fragility. The hack allows us to pretend that
there is sane behavior for now.
This makes it much faster if the surface is really mapped from GPU
memory. It's slightly slower than system memcpy if used on system
memory. We don't really know definitely in which type of memory
it's located, so we use the GPU memcpy in all cases.
Fixes#2317.
Make the GPU memcpy from the dxva2 code generally useful to other parts
of the player.
We need to check at configure time whether SSE intrinsics work at all.
(At least in this form, they won't work on clang, for example. It also
won't work on non-x86.)
Introduce a mp_image_copy_gpu(), and make the dxva2 code use it. Do some
awkward stuff to share the existing code used by mp_image_copy(). I'm
hoping that FFmpeg will sooner or later provide a function like this, so
we can remove most of this again. (There is a patch, bit it's stuck in
limbo since forever.)
All this is used by the following commit.
Broken by commit d47dff3f. If something is going to include EGL.h,
header_fixes.h has to know. This definitely affected vo_rpi, and
probably affects wayland builds (with x11egl didabled) as well.
Checking and resetting the VAImage.buf field is non-sense, even if it
happened to work out in the normal case. buf is actually freed when
vaDestroyImage() is called (not quite intuitive), and we need an extra
field to know whether vaReleaseBufferHandle() has to be called.
Printing "Using vaDeriveImage()" every frame is too verbose, so raise
the log level.
mp_image strides are in int and not unsigned int; fix this. It's not
like it actually matters, though.
Finish a comment.
Add the upstream symbolic names as comments. Normally, these should be
defined in libdrm's drm_fourcc.h header. But DRM_FORMAT_R8 and
DRM_FORMAT_GR88 are not defined anywhere, except in the kernel userland
headers of Linux 4.3 (!). We don't want mpv to depend on bleeding-edge
Linux kernel headers, so this will have to do.
Also, just for completeness, add fourccs for the 3 and 4 channel
formats. I didn't manage to test them, though.
Reduces the amount of hardcoded assumptions about the layout
drastically. (Now adding yuv420 support would be just adjusting an if,
if you ignore the other problems, such as determining the hw format at
all early enough.)
Don't call eglDestroyImageKHR() on the same ID possibly more than once.
Clear the image reference on termination, or we would leak up to 1 image
per VO recreation.
Should work much better than the old GLX interop code. Requires Mesa 11,
and explicitly selecting the X11 EGL backend with:
--vo=opengl:backend=x11egl
Should it turn out that the new interop works well, we will try to
autodetect EGL by default.
This code still uses some bad assumptions, like expecting surfaces to be
in NV12. (This is probably ok, because virtually all HW will use this
format. But we should at least check this on init or so, instead of
failing to render an image if our assumption doesn't hold up.)
This repo was a lot of help: https://github.com/gbeauchesne/ffvademo
The kodi code was also helpful (the magic FourCC it uses for
EGL_LINUX_DRM_FOURCC_EXT are nowhere documented, and
EGL_IMAGE_INTERNAL_FORMAT_EXT as used in ffvademo does
not actually exist).
(This is the 3rd VAAPI GL interop that was implemented in this player.)
The VAAPI EGL interop code will need access to the X11 Display. While
GLX could return it from the current GLX context, EGL has no such
mechanism. (At least no standard one supported by all implementations.)
So mpv makes up such a mechanism.
For internal purposes, this is very rather awkward solution, but it's
needed for libmpv anyway.
These extensions use a bunch of EGL types, so we need to include the EGL
headers in common.h to use our GL function loader with this.
In the future, we should probably require presence of the EGL headers to
reduce the hacks. This might be not so simple at least with OSX, so for
now this has to do.
Surfaces used by hardware decoding formats can be mapped exactly like a
specific software pixel format, e.g. RGBA or NV12. p->image_params is
supposed to be set to this format, but it wasn't.
(How did this ever work?)
Also, setting params->imgfmt in the hwdec interop drivers is pointless
and redundant. (Change them to asserts, because why not.)
This is a pseudo-OpenGL extension for letting libmpv query native
windowing system handles from the API user. (It uses the OpenGL
extension mechanism because I'm lazy. In theory it would be nicer to let
the user pass them with mpv_opengl_cb_init_gl(), but this would require
a more intrusive API change to extend its argument list.)
The naming of the extension and associated function was unnecessarily
Windows specific (using "D3D"), even though it would work just fine for
other platforms. So deprecate the old names and introduce new ones. The
old ones still work.
This turns the old scalers (inherited from MPlayer) into a pre-
processing step (after color conversion and before scaling). The code
for the "sharpen5" scaler is reused for this.
The main reason MPlayer implemented this as scalers was perhaps because
FBOs were too expensive, and making it a scaler allowed to implement
this in 1 pass. But unsharp masking is not really a scaler, and I would
guess the result is more like combining bilinear scaling and unsharp
masking.
Usually, libavcodec ignores errors reported by the hardware decoding
API, so it's not like we can actually escape if the hardware is somehow
acting up.
For normal fallback purposes, or if parts of the hw decoding API which
we actually check fails, we do this by setting and checking the
hwdec_failed flag anyway.
This can happen if the hw decoder allocates padded surfaces (e.g.
mod16), but the VPP output surface was allocated with the exact size.
Apparently VPP requires matching input and output sizes, or it will add
artifacts. In this case, it added mirrored pixels to the bottom few
pixels.
Note that the previous commit should have fixed this. But it didn't
work, while this commit does.
Fixes#2320.
If not set, VPP will use the whole surface. This is a problem if the
surfaces are padded, and especially if the surfaces are padded by
different amounts.
This is an attempt to fix#2320, but it appears to do nothing at all.
The comment was largely outdated, and described the old situation when
we used a "violent" fallback by making get_buffer2 fail completely.
Also, for the case when the hw decoder initialization succeeded (in
get_format), but get_buffer2 for some reason requests something
unexpected, we also can fallback more gracefully and in the same way.
Window classes are process-wide (or at least DLL-wide), so you can't
have 2 classes with the same name. Our code attempted to do this when
for example 2 libmpv instances were created within the same process.
This failed, because RegisterWindowEx() fails if the class already
exists.
Fix this by ignoring RegisterWindowEx() errors. If the class can really
not be registered, we will fail on CreateWindowEx() instead. Of course
we also can't unregister the class, as another thread might be using it.
Windows will free the class automatically if the DLL is unloaded or the
process terminates.
Fixes#2319 (hopefully).
It's possible to build vf_vapoursynth with either the Python or Lua
backend (or both or none). The check for the vapoursynth core itself was
hidden away and couldn't be disabled, which would link mpv with
vapoursynth even if all backends were disabled.
Rearrange the checks so that the core will be disabled if no backend is
found (or both are disabled). This duplicates the check for
vapoursynth.pc, but since it's trivial, this is not that bad.
Caused by one of the --force-window commits. The unconditional
uninit_video_out() call (which normally should be idempotent) raised
sporadic MPV_EVENT_VIDEO_RECONFIG events. This is ok, except for the
fact that clients (like a Lua script or libmpv users) would cause the
event loop to run again after receiving it, triggering a feedback loop.
Fix it by sending the events really only on a change.
Sigh... After the recent changes, another regression appeared. This
time, the VO window wasn't cleared when changing from video to a non-
video file (such as audio-only with no cover art). Fix this by properly
taking the handle_force_window() bool parameter into account.
Also, the info message could be printed twice, which is harmless but
ugly. So just remove the message.
Also, do some more minor cleanups (like fixing the comment, which was
completely outdated).
If --force-window wasn't used, this would destroy the VO while a file
is still being loaded, resulting in flicker and other interruptions
when switching from one playlist entry to another. Recent regression.
The condition used here is pretty tricky, but it boils down to that it
should trigger either in idle mode, or when loading has been fully done
(at these points we definitely know whether the VO will be needed).
This was in sub/, because the code used to be specific to subtitles. It
was extended to automatically load external audio files too, and moving
the file and renaming it was long overdue.
The previous commit was incomplete (and I didn't notice due to a broken
test procedure).
The annoying part is that actually creating the VO was separate; redo
this and merge the code for this into handle_force_window() as well.
This will also make implementing proper reaction to runtime option
changes easier. (Only the part for actually listening to option changes
is missing.)
This is a bad hack; the correct way to handle this would be implementing
profiles differently, and then listen to option changes and act on them
dynamically.
This flag was used by some filters and made sure none of these filters
were inserted twice. This triggers only if the user explicitly tries to
add multiple filters (and not e.g. due to auto-insertion), so at best
this warned the user from doing something potentially pointless. At
worst, it blocked some (mildly) legitimate use-cases. Get rid of it.
Also see #2322.
I took this out because I thought the filter chain would auto-negotiate
using nv12 without the explicit hint, and it does in the basic case
with no intermediate filter, but once you start adding filters, it
can end up negotiating a different format and then failing.
Today, vdpaurb will fail if it's used with non-hardware-decoded
content. This created work for the user as they have to explicitly
add or not add it, depending on the content.
As an improvement, we can make vdpaurb pass through any frames
that aren't hardware decoded, so that it can always be present in the
filter chain, if desired.
I see no point in keeping these around. Keeping wrappers for some select
libavfilter filters just because MPlayer had these filters is not a good
reason.
Ultimately, all real filtering work should go to libavfilter, and users
should get used to using vf_lavfi directly. We might even not require
the awful double-nested syntax for using libavfilter one day.
vf_rotate, vf_yadif, vf_stereo3d are kept because mpv uses them
internally. (They all extend the lavfi filters or change their
defaults.) vf_mirror is kept for symmetry with vf_flip. vf_gradfun and
vf_pullup are probably semi-popular, so I'll remove them not yet - only
after some more discussion.
The reason MPlayer traditionally duplicated them all over the place is
that it wanted every component to be a self-contained library (e.g.
audio filters were in "libaf"). But this is not necessarily helpful, and
this change makes the following commit a bit simpler.
The "PWD" enviornment variable is described by POSIX. We don't go to
length to verify its contents, but just trust it.
This affects the logic for resuming playback.
* (de)planarize -1
* pad 1 byte -8
* truncate 1 byte -1024
* float -> int 1048576 * (8 - dst_bytes)
* int -> float -512
Now the score is negative if and only if the conversion is lossy
(e.g. previously s24 -> float was given a negative (lossy) score),
However, int->float is still considered bad
(s16->float is worse than than s16->s32).
This penalizes any loss of precision more than performance / bandwidth hits.
For example, previously s24->s16p was considered equal to s24->u8.
Finally, we penalize padding more than (de)planarizing as this will
increase the output size for example with ao_lavc.
This is just a refactor, which makes it use the previously introduced
function, and allows us to make af_format_conversion_score() private.
(We drop 2 unlikely warning messages too... who cares.)
This mixed up the returned score for some interleaved/non-interleaved
comparisons. Changing interleaving subtracted 1 point, while extending
sample size by 1 byte also subtracted 1 point.
(This scoring system is not ideal - it'd be much cleaner to do a 3-way
sample format comparison instead, and sort the formats according to the
comparison instead of the score.)
These were normalized and are saner now. We want to use the new fields,
and also get rid of the deprecation warnings, so use them. There's no
release yet which uses these, so some ifdeffery is unfortunately needed.
2 things are being stupid here: Apple for requiring rectangle textures
with their IOSurface interop for no reason, and OpenGL having a
different sampler type for rectangle textures.
The value 0 was treated specially, and effectively forced the increment
to 1. Interestingly, passing 0 or no value also does not include the
scale (from touchpads etc.), but this is probably an accidental behavior
that was never intentionally added.
Simplify it and make the default increment 1. 0 now means what it
should: the value will not be changed. This is not particularly useful,
but on the other hand there is no need for surprising and unintuitive
semantics.
OARG_CYCLEDIR() failed to apply the default value, because
m_option_type_cycle_dir was missing a copy handler - add this too.
This causes weirdness with the "cache-size" property and option. Only
the read handler of the property included the backbuffer, while all
others did not. Make it consistent, and subtract the backbuffer size
from the cache size.
Fixes#2305.
Make it so that they don't need to be edited on release (no change in
tense). Also, move the "stray" changes after client API version 1.19 to
1.19 itself.
The removal of source-shader is a side effect, since this effectively
replaces it - and the video-reading code has been significantly
restructured to make more sense and be more readable.
This means users no longer have to constantly download and maintain a
separate deband.glsl installation alongside mpv, which was the only real
use case for source-shader that we found either way.
This is mostly to cut down somewhat on the amount of code bloat in
video.c by moving out helper functions (including scaler kernels and
color management routines) to a separate file.
It would certainly be possible to move out more functions (eg. dithering
or CMS code) with some extra effort/refactoring, but this is a start.
Signed-off-by: wm4 <wm4@nowhere>
Instead of the other way around of disabling disallowed options. This is
more robust and also slightly simpler, at least conceptually. If new
vo_opengl features are added, they don't need to be explicitly disabled
for dumb-mode just to avoid that it accidentally breaks.
Sigh...
Hopefully this code will be completely unnecessary one day, as it's
only needed due to the sub-option parser craziness.
Move dumb_mode to the top of the struct, so the C universal initializer
doesn't cause warnings with all those broken compilers.
Not sure why struct af_resample_opts even exists. It seems useful to
group the fields set by user options. But storing the current format
conversion parameters doesn't seem very elegant, and having a separate
instance in the "ctx" field isn't helpful either.
The single path optimization, rendering the video in one shader pass and
without FBO indirections, was removed soem commits ago. It didn't have a
place in this code, and caused considerable complexity and maintenance
issues.
On the other hand, it still has some worth, such as for use with
extremely crappy hardware (GLES only or OpenGL 2.1 without FBO
extension). Ideally, these use cases would be handled by a separate VO
(say, vo_gles). While cleaner, this would still cause code duplication
and other complexity.
The third option is making the single-pass optimization a completely
separate code path, with most vo_opengl features disabled. While this
does duplicate some functionality (such as "unpacking" the video data
from textures), it's also relatively unintrusive, and the high quality
code path doesn't need to take it into account at all. On another
positive node, this "dumb-mode" could be forced in other cases where
OpenGL 2.1 is not enough, and where we don't want to care about versions
this old.
This change makes vo_opengl slightly less compatible (ancient devices
without FBOs will no longer work) and decreases performance in the
simplest case (vo=opengl), in exchange for significantly reducing code
complexity and making everything easier to reason about.
Until now, most OSD objects created the associated ASS_Renderer instance
as soon as possible, even if nothing was going to be rendered. Maybe
this was even intentional.
Change this for the sake of lowering resource usage, and strictly
initialize ASS_Renderer only when it's really needed.
For the OSC, initialization has to be forced, because of the insane
mechanism for translating mouse coordinates to OSD coordinates.
This was completely broken. It was checked manually in some config
loading paths, so it appeared to work. But the intention was always to
completely disable reading from the normal config dir. This logic was
broken in commit 2263f37d.
The manual checks are actually redundant, and are not needed if
--no-config is implemented properly - remove them.
Additionally, the change to load the libmpv defaults from an embedded
profile also failed to set "config=no". The option is marked as not
being settable by a config file, and the libmpv default profile is
parsed as a config file, so this option was rejected. Fix it by removing
the CONF_NOCFG flag. (Alternatively, m_config_set_profile() could be
changed not to set the "config file" flag by default, but I'm not
bothering with this.)
This didn't seem entirely sane. It probably worked by accident, because
"position" is always the first attribute, and thus the default value 0
for the location was always correct.
Some users still use this filter, so the filter was going to be kept.
But I overlooked that libavfilter provides this filter. Remove the
redundant wrapper from mpv. Something like --af=lavfi=bs2b should work
and give exactly the same results.
All of these filters are considered not useful anymore by us. Some have
replacements in libavfilter (useable through af_lavfi).
af_center, af_extrastereo, af_karaoke, af_sinesuppress, af_sub,
af_surround, af_sweep: pretty simple and useless filters which probably
nobody ever wants.
af_ladspa: has a replacement in libavfilter.
af_hrtf: the algorithm doesn't work properly on most sources, and the
implementation was buggy and complicated. (The filter was inherited from
MPlayer; but even in mpv times we had to apply fixes that fixed major
issues with added noise.) There is a ladspa filter if you still want to
use it.
af_export: I'm not even sure what this is supposed to do. Possibly it
was meant for GUIs rendering audio visualizations, but it couldn't
really work well. For example, the size of the audio depended on the
samplerate (fixed number of samples only), and it couldn't retrieve the
complete audio, only fragments. If this is really needed for GUIs, mpv
should add native visualization, or a proper API for it.
While unknown lengths are supported in some important cases like
segments and clusters, they are not for small and complex metadata
elements like the track list. Such elements are simply rejected.
This case was caught by the size sanity check below, but the message is
misleading and wrong.
(There are likely no files in the wild which require support for this.
The sample file I've seen was muxed by libavformat, but in a case where
it aborted when writing the header. Clearly a broken file.)
Often, we don't know whether hardware decoding will work until we've
tried. (This used to be different, but API changes and improvements in
libavcodec led to this situation.) We will often output that we're going
to use hardware decoding, and then print a fallback warning.
Instead, print the status once we have decoded a frame.
Some of the old messages are turned into verbose messages, which should
be helpful for debugging. Also add some new ones.
The fallback at initialization time was basically duplicated, maybe for
the sake of showing a different error message. This doesn't matter
anymore; not much can fail at initialization anymore. Most meaningful
and common errors happen either at probing or in get_format (when the
actual hw decoder is initialized).
If PBO upload fails, disable PBOs and revert to the normal codepath. In
theory we should retry PBO upload on failure (because OpenGL specifies
that it can sporadically fail), but since it normally doesn't happen,
and the fallback will work, I'm not bothering.
Some restructuring is needed, since glUnmapBuffer needs to be called
earlier. In fact, the old code structure didn't make too much sense, and
is a leftover from MPlayer's direct rendering support, which let the
decoder decode to a PBO-mapped region. This means the buffer_ptr field
can be dropped. Drop buffer_size as well, since it only had 2 possible
values (0 or the size required for the current config).
Can significantly help with very large video resolutions on nvidia
drivers. It doesn't seem to have negative effects on Intel drivers
either. (Although it could have on Intel drivers for older hardware.)
For now, this is only for --vo=opengl-hq. Maybe --vo=opengl should use
it too, but it's still meant to be the crappy, fail-safe default.
Setup a dummy image for the given image params, and get the plane sizes
from that. Admittedly not much of a simplification, but conceptually
it's simpler and less error-prone, as the image layout is guaranteed to
be the same, rather than essentially duplicating the way it is
determined.
This is from times when we supported padded/non-NPOT textures. The
difference is not useful anymore, and theoretical support for different
sizes is most likely buggy and unmaintained. So remove it.
Also remove the tex_ prefix wherever it appears.
Use mp_image_copy() instead of copying manually. (This function checks
whether the destination is regarded writeable, which it is not, because
the destination is the source image with changed pointers, so
refcounting has to be removed from the destination image by resetting
mpi->bufs.)
This shouldn't be needed anymore. Textures are now always allocated with
the exact size. Any padding (including non-NPOT support) is gone. The
texture sizes will always match the memory plane sizes.
Drop the unused and forgotten "npot" field from the option struct too.
Previously, with mpv --force-window=yes --idle=yes --screenshot-template="%f",
mpv would display an error saying that the template was incorrect, which it
isn't, there's just no file to put in the format. In this case, just use the
string "NO_FILE".
Drop the whitelist. It's annoying to maintain. Instead, accept any
subtitle decoder. Since this code path will now also be taken by bitmap
subtitle decoders not whitelisted by sd_lavc.c, add a warning when
bitmap subtitles are decoded. (To reduce or increase potential user
confusion.)
To some degree, a whitelist is needed to distinguish text and bitmap
subtitles. FFmpeg has an API to distinguish them in a generic way to
some degree, but Libav doesn't. So we just stick with this for now.
Undo 292266f2. Reapply 3e12e79b.
An additional copy is not really justified, as it could reduce
performance. On the other hand, we can force API users to create
a GL 3.x context.
eglTerminate() affects the EGLDisplay in all threads. Since the RPI
firmware apparently only ever uses EGL_DEFAULT_DISPLAY, this means it
will trash all other contexts on other threads in the same process.
Thus we don't call eglTerminate() at all, at least on RPI. Call
eglReleaseThread() instead (which may or may not be a NOP).
yuva444p worked, yuva420p didn't. This happened because the chroma pass
discards the alpha plane, which is referenced by the alpha blend code
later.
Add a terrible hack to work this around, actually using the same hack as
was used for the Y plane. (A terrible hack for terrible code.)
If the drag and drop action is anything other than
XdndActionCopy, append the dropped files rather than
replacing the existing playlist. With most file managers,
this will mean at least pressing shift while dropping.
This puts in place the machinery to merely append dropped file to the playlist
instead of replacing the existing playlist. In this commit, all front-ends
set this to false preserving the existing behaviour.
This takes care of the corner case where the player is started with a
single playlist entry so that the next/prev arrows are greyed out, but
remain that way even after new elements are added to the playlist.
Even after it has been disabled with the `disable-osc` message, the OSC
continues to run the tick function. Completely preventing tick from
being called is impractical since there are several different places
that it's called in the code, so just make it immediately return if the
OSC has been disabled.
This prevents the OSC from continuing the clear the OSD on every tick,
allowing other scripts to disable it so that they may draw to the OSD.
The FFmpeg can officially not distinguish between unknown subtitle
durations, and subtitle durations being 0. (It documents the value 0
meaning unknown duration.)
In practice, at least the LRC demuxer signals unknown subtitle durations
with a negative value.
Assume negative durations mean unknown duration. Show subtitles with
unknown duration forever. Unless there's a subtitle event following it;
then reset the duration so that it ends on the new subtitle event.
Fixes#2244.
Add a simplistic heuristic for detecting broken indexes. This includes
indexes with very few elements (apparently libavformat sometimes writes
such indexes, or used to), and indexes with broken timestamps.
The latter was apparently produced by very old HandBrake versions:
| + Muxing application: libmkv 0.6.1.2
| + Writing application: HandBrake 0.9.1
These broken files seem to be common enough that libavformat added a
workaround for them in 2008 (and maybe again in 2015). Apparently all
timestamps are multiplied with the file's tc_scale twice, and FFmpeg
attempts to fix them. We should throw away the whole thing.
Actually, this never happened, because there's logic for ignoring
duplicate header elements (which includes the seek index). This is
mostly for robustness and readability.
This might fix some problems when framestepping with interpolation
enabled. The problem here is that we want to show the non-interpolated
frame while paused. Framestepping is like unpausing the video for a
frame, and then pausing again. This draws an interpolated frame, and
redrawing on pausing is supposed to take care of this.
This possibly didn't always work, because vo->want_redraw is not checked
by the vo_control() code path. So wake up the VO thread (which takes
care of servicing redraw requests, kind of) explicitly.
The correct solution is getting rid of the public-writable want_redraw
field and replacing it with a new vo_request_redraw() function, but this
can come later.
So snd_device_name_get_hint() return values do in fact have to be freed.
Also, change listing semantics slightly: if io==NULL, skip the entry,
instead of assuming it's an output device.
libavcodec does not support HEVC via VAAPI yet, so this won't work.
However, there is ongoing work to add HEVC support to VAAPI, and this
change might help with testing. (Or maybe not - but there is no harm in
this change.)
Instead, allow reading 2KB only. This seems to be sufficient for
libarchive to recognize zip, 7z, rar, tar. Good enough.
This is implemented by creating an in-memory stream with a copy of
the file header. If libarchive succeeds opening this, the actual
stream is opened.
Allowing unlimited reading could break unseekable streams, such as
playing from http servers with no range request support or pipes.
Also, we try not to read too much data in the first probe pass. Some
slow network streams like shoutcast services could make probing much
slower if we allow it to read too much. In the second probing pass,
actually allow 200KB.
Should not happen, but since we don't control decoder video surface
allocation, anything could happen, and the code should be able to deal
with it. Untested.
This should avoid unnecessary sleeping when audio playback start resync
has finished and goes into the normal playback state.
This is tricky; see e.g. commit 402fe381.
As expected, probing with libarchive is a disaster. Both libavformat and
libarchive are too eager to misdetect file formats just because files
"might" be of a specific type. In this case, it's mp3 vs. tar. To be
fair, neither file format has an actual header. I'm not sure why we'd
need tar support, but since libarchive provides it, and idiots on the
internet apparently pack media files in tar sometimes (really, idiots),
keep it for now, and probe tar last.
Provides a simplistic way to seek without having to care about weird
situations like timestamp vs. playback time. This is good, because the
seek command is currently timestamp based, so when using the seek
command the user _does_ have to care.
Always compute the estimated absolute time of the seek target, and
display this as playback time during seeks.
Improves behavior with e.g. .ts files, for which we try to avoid seeks
by timestamp.
Fixes regression in dfd8a5f that made autoload not add more files
at the end of the current playlist if playlist was made by the
script.
This still prevents loading the script if more than one (media or
playlist) file was manually added.
This significantly reduces the amount of noticeable flashing when using
tscale kernels with negative lobes, by cutting them off completely.
I'm not sure if this has any negative effects. It needs a bit of
subjective testing over a period of time, so I just made it an option.
Fixes#2155.
A client API user might count on the fact that audio and video outputs
have already been uninitialized. (They remain uninitialized before
entering idle mode in order to allow smooth transition to the next
playlist entry.) Since event delivery is asynchronous, this has to
happen after actually doing the uninitialization, or the client will
essentially run into a race condition.
libarchive uses a quite confusing ifdeffery mess for some of the types
used in callbacks. Currently, archive_read_set_seek_callback() causes a
warning at least on Windows due to mismatching return type. The header
file uses __LA_INT64_T as return type, so I think the user is intended
to use int64_t.
(The ssize_t return type for the read_cb seems correct, on the other
hand.)
Some particular checks can define the HAVE_ key on their own. To make sure
they work correctly when composed (with compose_checks) we force the HAVE_
key to be undefined if a check fails.
Since vo_rpi uses MMAL for video output, which is completely
independent from the GLES overlay, we can just not redraw the
GLES screen if subtitles do not change.
(As a furhter optimization, the dispmanx overlay could be removed
if nothing is visible. But I'm not sure if adding and removing the
overlay frequently is a good idea for performance, so this could
just as well go the other way.)
Slightly faster than using the dispmanx mess (perhaps to a large amount
due to the rather stupid C-only unoptimized ASS->RGBA blending code).
Do this by reusing vo_opengl's subtitle renderer, and vo_opengl's RPI
backend.
Things like .gz etc., which have no real file header. A mixed bag,
because it e.g. tends to misdetect mp3 files as compressed files or
something (of course it has no mp3 support - I don't know as what it
detects them). But requested by someone (or maybe not, I'm not sure
how to interpret that).
This affects vo_opengl_cb in particular: it'll most likely auto-load
VDA, and then the VideoToolbox decoder won't work. And everything fails.
This is mainly caused by FFmpeg using separate pixfmts for the _same_
thing (CVPixelBuffers), simply because libavcodec's architecture demands
that hwaccel backends are selected by pixfmts. (Which makes no sense,
but now we have the mess.)
So instead of duplicating FFmpeg's misdesign, just change the format to
our own canonical one on the image output by the decoder. Now the GL
interop code is exactly the same for VDA and VT, and we use the VT name
only.
This works similar to the existing .rar support, but uses libarchive.
libarchive supports a number of formats, including zip and (most of)
rar.
Unfortunately, seeking does not work too well. Most libarchive readers
do not support seeking, so it's emulated by skipping data until the
target position. On backwards seek, the file is reopened. This works
fine on a local machine (and if the file is not too large), but will
perform not so well over network connection.
This is disabled by default for now. One reason is that we try
libarchive on every file we open, before trying libavformat, and I'm not
sure if I trust libarchive that much yet. Another reason is that this
breaks multivolume rar support. While libarchive supports seeking in
rar, and (probably) supports multivolume archive, our support of
libarchive (probably) does not. I don't care about multivolume rar, but
vocal users do.
The waf build system generates this already. No point in redoing it in
the header file.
The legacy build system (which we really should drop) didn't; fix it.
Make a difference between different mpv_handles pointing to the same mpv
core, or different mpv cores. While we're not explicit about it, at
least avoid that someone could misunderstand when really looking for the
case of mpv_handles pointing to the same core.
Instead, force everyone to use the metadata struct and set a "title"
field. This is only a problem for the timeline producers, which set up
chapters manually. (They do this because a timeline is a separate
struct.)
This fixes the behavior of the chapter-metadata property, which never
returned a "title" property for e.g. ordered chapters.
We must not use the frame PTS in any case. In this case, it fails
because nothing sets it up to wake up. This typically caused the player
to apparently "pause", until something else waked it up, like moving the
mouse and other events.
enable_key_bindings()/disable_key_bindings() now prints a log message on
each call, thus we should avoid makign redundant calls.
This could probably be solved more elegantly, but since this is all
legacy/private API, don't bother.
This VO is special because it normally doesn't block on vsync, but can
be made to do so. Supposedly the MMAL video output API merely sets a
"current frame" field when sending an output frame, and the firmware
will pick up whatever frame that field is set to at the time of a
vsync.
If this mode is enabled, the player tries to strictly synchronize video
to display refresh. It will adjust playback speed to match the display,
so if you play 23.976 fps video on a 24 Hz screen, playback speed is
increased by approximately 1/1000. Audio wll be resampled to keep up
with playback.
This is different from the default sync mode, which will sync video to
audio, with the consequence that video might skip or repeat a frame once
in a while to make video keep up with audio.
This is still unpolished. There are some major problems as well; in
particular, mkv VFR files won't work well. The reason is that Matroska
is terrible and rounds timestamps to milliseconds. This makes it rather
hard to guess the framerate of a section of video that is playing. We
could probably fix this by just accepting jittery timestamps (instead
of explicitly disabling the sync code in this case), but I'm not ready
to accept such a solution yet.
Another issue is that we are extremely reliant on OS video and audio
APIs working in an expected manner, which of course is not too often
the case. Consequently, the new sync mode is a bit fragile.
For video sync, we want separate playback speed controls for user-
requested speed and the "correction" speed for video timing. Further, we
use this separation to make sure only a resampler is inserted if
playback speed is only changed for video sync correction.
As of this commit, this is basically inactive code. It's just
preparation for the video sync code (the following commit).
Additionally to taking the average, this tries to use the demuxer FPS to
eliminate jitter, and applies some other heuristics to check if the
result is sane.
This code will also be used for the display sync code (it will actually
make use of the require_exact parameter).
(The value of doing this over keeping the simpler demux_mkv hack is
somewhat questionable. But at least it allows us to deal with other
container formats that use jittery timestamps, such as mp4 remuxed
from mkv.)
This doesn't work too well if sections of the file change to a different
framerate. It lowers our chances to guess the correct FPS in the display
sync code.
For normal playback, this (probably) doesn't help that much anyway,
except that the "estimated-vf-fps" property will regress in the simplest
mkv case. This will be fixed with the next commit.
The now disabled code will probably be removed; it's not useful anymore.
While the "old" libavcodec vdpau API is not deprecated (only the very-
old API is), it's still relatively complicated code that badly
duplicates the much simpler newer vdpau code. It exists only for the
sake of older FFmpeg releases; get rid of it.
Lua script that enables handling of certain commands depending on where
the mouse pointer is. Mostly useful for mouse-wheel handling via
input.conf.
Example:
MOUSE_BTN3 script-message-to zones commands "*-left: add volume +5"
"default: seek +10"
MOUSE_BTN4 script-message-to zones commands "*-left: add volume -5"
"default: seek -10"
Will changes behavior of Mouse Wheel Up/Down to alter volume if mouse is
in the left zone of the window, but re-adds the default to seek if wheel
is used on other parts.
Since we're on the topic of consistency, I've seen multiple users
complain about the presence of this period, which does not really match
other programs' behavior.
As the removed comment says, not copying this field may cause problems
on older libav* releases. See also commit 5f7de399.
Remove this, as newer FFmpeg releases are available. As of this commit,
use of mpv with FFmpeg 2.5.x and below, or Libav 11 and below is not
recommended, and may lead to random video decoding issues. (Although the
failure cases are apparently somewhat obscure.)
Removes some more internal API calls from the Lua scripting backend.
Which is good, because ideally the scripting backend would use libmpv
functions only.
One awkwardness is that mouse sections are still not supported by the
public commands (and probably will never), so flags like allow-hide-
cursor make no sense to an outside user.
Also, the way flags are passed to the Lua function changes. But that's
ok, because they're only undocumented internal functions, and not
supposed to be used by script users. osc.lua only does due to historical
reasons.
This was requested. It was more or less present internally already and
used for Lua scripting. Lua will switch to the "public" functions in
the following commits.
Add --demuxer-max-packets and --demuxer-max-bytes, which control the
maximum size of the packet queue. These can be helpful to avoid
excessive memory usage.
Memory usage is the reason why there's a limit in the first place. If a
file is more or less broken, and audio and video don't line up, the
decoders will fill up the packet queue trying to read more audio or
video, and the maximum sizes are required to avoid unbounded memory
allocation. Being able to override the maximum sizes is useful; either
for restricting memory usage further, or enlarging the sizes when
attempting to play various broken files.
Remove --demuxer-readahead-packets and --demuxer-readahead-bytes. These
were a bit useless. They could force a minimum packet queue size, but
controlling the queue size with --demuxer-readahead-secs is much nicer.
It's fairly certain nobody ever used these options.
Also add a note that you should not use the old build system. (It's only
kept because of the "asshole maintainer" rule: no matter how broken or
pointless someting is, as long as you're the maintainer and want to keep
it, it stays in the repo.)
VDA is being deprecated in OS X 10.11 so this is needed to keep hwdec working.
The code needs libavcodec support which was added recently (to FFmpeg git,
libav doesn't support it).
Signed-off-by: Stefano Pigozzi <stefano.pigozzi@gmail.com>
Pretty stupid: vo_get_vsync_interval() returns a negative value if the
display FPS is unknown (e.g. xrandr not compiled), and the comparison
whether the value is below 0 fails later because it's assigned to an
unsigned int.
Regression since commit e3d85ad4.
Also, fix some comments in vo.c.
Some charsets can look like valid UTF-8, but aren't UTF-8. One example
is ISO-2022-JP. While ENCA apparently likes to get misdetect real UTF-8,
this is not the case with uchardet. uchardet can detect ISO-2022-JP
correctly, but didn't even get to try, because our own UTF-8 check
succeeded. So run the UTF-8 check when using ENCA only.
Fixes#2195.
Now it can always be read. Normally returns the value of the video-
aspect option. Writing it sets the option. If the aspect is not forced,
it will attempt to return whatever is the current video aspect.
That just makes no sense, but seems to be a somewhat common user error.
The detection is not perfect. It's conceivable that EXT-X-... headers
are used in normal m3u playlists. After all, HLS playlists are by
definition a compatible extension to m3u playlists, as stupid as it
sounds.
Drop d for toggling framedrop. Toggling this is way too special to be at
such a prominent place, and in fact I believe toggling it is pointless.
Remap deinterlacing from D to d. It's relatively useful and non-
destructive.
As suggested in #973 (almost).
Instead of opening a stream and then a demuxer, do both at once with
demux_open_url().
This requires some awkward additions to demuxer_params, because there
are some weird features associated with opening the main file. E.g. the
relatively useless --stream-capture features requires enabling capturing
on the stream before the demuxer is opened, but on the other hand
shouldn't be done on secondary files like external subtitles.
Also relatively bad: since demux_open_url() returns just a demuxer
pointer or NULL, additional error reporting is done via demuxer_params.
Still, at least conceptually, it's ok, and simpler than before.
Nobody wanted to restore this, so it gets the boot.
If anyone still wants to volunteer to restore menu support, this would
be welcome. (I might even try it myself if I feel masochistic and like
wasting a lot of time for nothing.) But if it does get restored, it
should be done differently. There were many stupid things about how it
was done. For example, it somehow tried to pull mp_nav_events through
all the layers (including needing to "buffer" them in the demuxer),
which was needlessly complicated. It could be done simpler.
This code was already inactive, so this commit actually changes nothing.
Also keep in mind that normal DVD/BD playback still works.
Normally when there's a timestamp reset, we make audio resync to make
sure audio and video line up (again). But in video-only mode, just
setting audio to resyncing breaks EOF detection, because there's no code
which would get audio_status out of this bogus state.
When full_redraw is set, we always need to take the draw_image path. If
it's not set, we can try VOCTRL_REDRAW_FRAME (and fallback to draw_image
if that fails).
Fixes#2184.
Commit c5818046 fixed one case of audio EOF handling, and caused a new
one. This time, the ao_buffer doesn't actually contain everyting that
should be played - because if --end is used, only a part of it is
played. Of course this is stupid, and it will be changed later. For now,
this smaller change fixes the bug.
Fixes#2189.
The jpeg-optimize and jpeg-baseline options were undocumented, and
they're also pretty useless. There's no reason to ever change them.
Also, don't write jpeg baseline images. This just makes compression
worse for the sake of rather questionable compatibility with ancient
decoders.
For now, it needs to be explicitly selected. ENCA is still the default.
This assumes uchardet returns iconv names. This doesn't seem to be
always the case, and the result are lots of iconv errors. So
explicitly check for this situation, and print a warning if it
occurs. It's entirely possible that uchardet support is actually
useless, because names are not necessarily iconv-compatible (but
uchardet doesn't seem to document whether it attempts to return
iconv-compatible names if possible).
Fixes#908.
uchardet is written in C++, and thus doesn't appreciate the value of
using static strings, and internally stores the guessed charset as
allocated std::string. Add a minimal hack to deal with this. (I don't
appreciate that the code is potentially harder to understand by
returning either a static or allocated string, but I do appreciate for
not having to litter the existing code with strdups.)
time_frame is when the next video frame should be shown. It's normally
overwritten by the video timing code. This also says something about
"nosound mode" (--no-audio today), but at least these days we don't use
it at all if video is disabled.
Remove it; it likely has no function at all.
If the framedrop count happens to be incremented with
vo_increment_drop_count() during rendering, these increments were
counted twice, because these events also set in->dropped_frame.
This was originally done for zsh; but zsh can manage the terminal state
correctly when foregrounding/backgrounding applications if you enable it
with "ttyctl -f". So I see no reason to wake up the mpv process once
every second anymore.
Revert "win32: more wchar_t -> WCHAR replacements"
Revert "win32: replace wchar_t with WCHAR"
Doing a "partial" port of this makes no sense anymore from my
perspective. Revert the changes, as they're confusing without
context, maintenance, and progress. These changes were a bit
premature anyway, and might actually cause other issues
(locale neutrality etc. as it was pointed out).
This was essentially missing from commit 0b52ac8a.
Since L"..." string literals have the type wchar_t[], we can't use them
for UTF-16 strings. Use C11 u"..." string literals instead. These have
the type char16_t[], but we simply assume char16_t is the same
underlying type as WCHAR. In practice, they're both unsigned short.
For this reason use -std=c11 on Windows. Since Windows is a "special"
environment (we require either MinGW or Cygwin), we don't need to worry
too much about compiler compatibility.
A user complains that it leads to the dxva driver failing, leading to
messages like this:
[ffmpeg/video] h264: Failed to execute: 0x8007000e
[ffmpeg/video] h264: hardware accelerator failed to decode picture
Reportedly, this happens only with vo_direct3d, not with vo_opengl. The
only difference is that vo_direct3d attempts to share the D3D device
with the decoder. Possibly the error is that the device in the VO is not
created with D3DCREATE_MULTITHREADED. Change this.
Probably fixes#2178.
The user probably doesn't want these. Conveniently, this also skips the
unwanted "." and ".." entries.
(This code is triggered if the input stream is a directory - and it's in
demux_playlist.c because it's convenient.)
WCHAR is more portable. While at least MinGW, Cygwin, and MSVC actually
use 16 bit wchar_t, Midipix will have 32 bit wchar_t. In that context,
using WCHAR instead is more portable.
This affects only non-MinGW parts, so not all uses of wchar_t need to
be changed. For example, terminal-win.c won't be used on Midipix at
all. (Most of io.c won't either, so the search & replace here is more
than necessary, but also not harmful.)
(Midipix is not useable yet, so this is just preparation.)
We used double-checked locking on pthread_mutex_t.requires_init in order
to lazily initialize static mutexes (since CRITICAL_SECTION has no
native way to do this). This was kind of unclean: we relied on MSVC
semantics for volatile (which apparently means all accesses are weakly
atomic), which is not such a good idea since mpv can't even be compiled
with MSVC.
Since it's too much of a pain to get weak atomics, just use INIT_ONCE
for initializing the CRITICAL_SECTION. Microsoft most likely implemented
this in an extremely efficient way. Essentially, it provides a mechanism
for correct double-checked locking without having to deal with the
tricky details. We still use an extra flag to avoid calling it at all
for normal locks.
(To get weak atomics, we could have used stdatomic.h, which modern MinGW
provides just fine. But I don't want this wrapper depend on MinGW
specifics if possible.)
See manpage additions.
The main reason for adding this is that we can't guess whether the user
wants his config in his Windows profile or not. The user basically has
to tell mpv what should be done, and the "portable_config" directory
does this implicitly.
Fixes#2042 (approximately).
Remove the exception for decoding only 1 frame if VO framedrop is
disabled. This was originally done to be able to test potential
regressions when we enabled VO framedrop and decoding 2 frames by
default. It's not needed anymore.
Instead of special-casing hwdec in the place where the video textures
are used, just set the textures in the image upload function. The
renderer code doesn't need to know whether hwdec interop is used at all.
This is an unfortunate fact of life. Maybe making this the default
wasn't such a good idea after all.
Also update etc/example.conf. It used an obsolete alias for "auto".
As suggested in #2033.
Additionally, change "LGPLv2+" to "LGPLv2.1+". Since this was always
used with the "and later" phrase, this doesn't require any further
discussion.
Also clarify that the "+" means "or later". This should be clear to
anyone with a brain, but you never know with copyright.
This detected whether an OpenGL context still provided legacy OpenGL if
the OpenGL version is modern (>= 3.0). This was actually only needed for
vo_opengl_old, because it relied on legacy functions. Since it's gone,
this code isn't needed either.
(Also, the removed comment about OpenGL 3.0 was wrong: you could just
query GL_CONTEXT_FLAGS and see if the forward compatible bit was set.)
In paused mode, we never entered the audio EOF state. This shows e.g. in
--keep-open mode, which will not set the eof-reached property correctly.
Regression since commit c06cd1b9. This commit was the wrong fix. We need
to respect the buffer state, and pausing has nothing to do with this.
Fixes#2167.
This reverts commit fb8d158366.
Reallocating the FBOs on every resize is very slow. It affects resizing
the window, as well as changing the video size itself with e.g.
panscan. Since the original change was done based on a single user
complaint, but the change itself caused a lot of complaints, we decided
to just revert it.
Allow setting an arbitrary amount, instead of the fixed 50%.
This is nto striclty backwards compatible. The defaults don't change,
but the --cache/--cache-default options now set the readahead portion.
So in practice, users who configured this until now will see the
double amount of cache being used, _plus_ the 75MB default backbuffer
will be in use.
Currently, this is perfectly equivalent, because back_size is hardcoded
to buffer_size/2. But this fixes the logic for the case the back_size
can be configured freely.
If filters are disabled or reconfigured, attempt to remove and probe the
deinterlace filter again. This fixes behavior if e.g. a software deint
filter was automatically inserted, and then hardware decoding is enabled
during playback. Without this commit, initializing hw decoding would
fail because of the software filter; with this commit, it'll replace it
with the hw deinterlacer instead.
Instead of calling it "future frames" and adding or subtracting 1 from
it, always call it "requested frames". This simplifies it a bit.
MPContext.next_frames had 2 added to it; this was mainly to ensure a
minimum size of 2. Drop it and assume VO_MAX_REQ_FRAMES is at least 2;
together with the other changes, this can be the exact size of the
array.
Handle a relatively recently introduced hack, that allows FLAC audio to
have arbitrary channel layouts, instead of just the predefined fixed
ones. This is actually supported by FFmpeg, but since the demuxer
(instead of the decoder) handles this in FFmpeg, we need to add special-
code to our mkv demuxer.
(The way FFmpeg does this seems a bit backwards, since now every demuxer
for a format that can handle FLAC needs to contain this logic as well.)
The FLAC hack is relatively terrible: we need to parse the FLAC headers,
look for a VorbisComment, parse the VorbisComment, and then retrieve
the magic WAVEFORMATEXTENSIBLE_CHANNEL_MASK entry. But the hack is
officially endorsed, as the official FLAC tools use it. (Although I
couldn't find a trace of it in the format specification. Should I be
surprised?)
This was a minor optimization to potentially avoid resampler
reconfiguration when the filter is reinitialized. But filter
reinitialization is a rare event, and the case when no reconfiguration
is needed is even rarer. As such, this is an unnecessary micro-
optimization and only adds potential for bugs.
This message bloats verbose log output if e.g. audio speed is frequently
readjusted, such as when syncing audio to video. So don't print the
message if only speed is changed. (This case requires reconfiguration,
but can't change the input/output channel maps.)
Also do not print the message if no remixing is done at all.
This was requested by someone.
All code was written by myself; some minor changes by 2 contributors who
agreed to general LGPL relicensing. 1 line of code is by someone unknown
who possibly wasn't asked (setting the "display_fps" variable), and
which can be reasonably ignored as it makes up only 0.1% of the file.
I still have no idea why this is needed, maybe some weird off-by-one
in some shitty driver? Either way, the difference for a working setup
shouldn't be too major, the most noticeable effect would be somewhat worse
performance when resizing the video during playback with interpolation
enabled using the mouse.
That's a specific enough side effect for me to not care as much about it.
Fixes#1814.
Probably makes users happy who want bitmap subtitles to show up in the
screen margins, and stops them from doing idiotic crap with vf_expand.
Fixes#2098.
There are some situations when redrawing is requested, but the current
frame was deleted. This could happen when switching e.g. hw decoding
mid-stream.
Separate uploading/drawing and fix the condition.
Just avoid some code duplication. Also, gl_video_set_options() having a
queue size output parameter is weird at best. While I don't appreciate
that this commit suddenly requires gl_video.c to deal with vo.c directly
in a special case, it's simply the best place to put this function.
The VO will be provided with future frames even if the format changes
mid-stream. This caused a crash if these frames were actually used (i.e.
interpolation mode was enabled).
Fixes a crash when deinterlacing is toggled during playback, and the
deinterlacer changes the stream format (as it can happen e.g. if the
decoder outputs nv12, which in turn happens with hw decoding).
(On a side note, future frames are always non-NULL. Also, the current
frame is of course always in the correct format.)
vaQueryImageFormats() returns a randomly ordered list - so we shouldn't
assume the first format on the list which works is the best. This
effectively switches to nv12 instead of yuv420p on some drivers.
We handle this by reusing va_to_imgfmt[], and ordering it by preference.
We hardcode that GPUs prefer nv12 pver yuv420p. In theory we could do
complicated probing (allocate dummy surface + use vaDeriveImage on it,
then retrieve the FourCC) - but all things which could break assumption
in the future are not supported yet (like 10 bit or 4:4:4), so this is
fine.
Fixes problems with --vo=opengl:interpolation. The issue here is that
vo_opengl retains more surfaces than what was preallocated for the
decoder. Until now, we just explicitly failed to decode frames for which
no additional surfaces are available. Since modern drivers usually are
fine with not "registering" surfaces before the decoder is created, just
allow allocating additional surfaces if needed.
(We also could probably recreate the HW decoder, since the HW decoder
should be stateless. But let's try to avoid raising the overall
complexity of the code.)
The interlaced frame test needs to be aware that the input mpi might be
NULL - this happens at the end of a stream when the input frames have
all been submitted but frames still need to be drained from the
decoder.
ass_set_fonts() is called by mp_ass_configure_fonts(), which was called
every time a subtitle renderer was initialized. I'm not sure why this
was done - I can't find a good reason, and most likely there's none.
However, it did cause problems with an experimental libass branch. It
crashed some time after switching to a second subtitle track. The branch
will hopefully be merged soon, and it seems unlikely that libass wants
to fix its problems with its ridiculous API (rather it should normalize
its API so that the issue doesn't happen in the first place), so just
apply this change. It makes our code simpler too.
Outputting the detected OpenGL features was useless and redundant with
the extension loading output.
Also, remove MPGL_CAP_3D_TEX from OpenGL(ES) 3.0. This block didn't
include the glTexImage3D function, so that was pointless and couldn't
have worked. The OpenGL 2.1 block does it correctly.
VDPAU has explicit support for rotating surfaces, and it is far less
expensive than using the normal rotation filter (which would require
reading video frames back into system memory), it is desirable to
implement the VO rotation capability.
To do this, we need to render the video frames to an output surface,
without rotation, and then render from that surface to the final
output surface to apply the rotation. It is important that the
intermediate surface is the same size as the final one (only not
rotated) so that hqscaling can be applied if requested by the user.
(hqscaling is a mixer capability and so takes effect when the video
surface is rendered to an output surface)
Finally, we must remember to explicitly clear the final output
surface as VDPAU only auto-clears output surfaces when rendering video
surfaces.
Normally, vdpau decoded frames are passed directly to a suitable
vo (vo_vdpau or vo_opengl) without ever touching system memory. This
is efficient for output purposes, but prevents any of the regular
filters from being used with such frames.
This new filter implements a read-back step to pull the frames back
into system memory where they can be acted on by other filters.
Eventually the frames will be sent to the vo as if they were normal
software-decoded frames.
Note that a vdpau compatible vo must still be used to ensure that
the decoder is properly initialised.
Signed-off-by: wm4 <wm4@nowhere>
mp_seek_chapter() had only 1 caller. Also the code was rather
roundabout; the entire function can be compressed to 5 lines of code.
(The new code is functionally the same - "mpctx->last_chapter_seek =
-2;" was effectively a dead assingment.)
Extend the --demuxer-mkv-probe-video-duration behavior to work with
files that are partial and are missing an index. Do this by finding a
cluster 10MB before the end of the file, and if that fails, just read
the entire file. This is actually pretty trivial to do and requires only
5 lines of code.
Also add a mode that always reads the entire file to estimate the video
duration.
Until now, if a stream wasn't seekable, but the stream cache was enabled
(--cache), we've enabled seeking anyway. The idea was that at least
short seeks would typically fall within the cache. And if not, the user
was out of luck and terrible things happened. In other words, it was
unreliable.
Be stricter about it and remove this behavior. Effectively, this will
for example disable seeking in piped data.
Instead of trying to be clever, add an --force-seekable option, which
will always enable seeking if the user really wants it.
This is a real pain: if a quit command is received, it's set to PT_QUIT.
And then other code could overwrite it, making it not quit. The annoying
bit is that stop_play is written and read in many places. Just not
overwriting it unconditionally seems to be the best course of action.
Some code called by vf_vdpaupp.c calls mp_image_new_custom_ref(), but
out of convenience doesn't reset the buffers. Make this behavior ok.
(The assert() was there to catch usage errors, but the same error could
already happen before the refcount changes were made, so the check is
not overly helpful.)
Fixes#2115.
Drop libva versions below 0.34.0. These are ancient, so I don't care.
Drop the vo_vaapi deinterlacer as well. With 0.34.0, VPP is always
available, and deinterlacing is done with vf_vavpp.
The vaCreateSurfaces() function changes its signature - actually it did
in 0.34.0 or so, and the <va/va_compat.h> defined a macro to make it use
the old signature.
Sometime recently, hardware decoding started to fail if h264 with full
reference frames was decoded, and --vo=vaapi was used. VAAPI requires
registering all surfaces that the decoder will ever use in advance, so
if the playback chain uses more surfaces than originally allocated, we
fail and drop back to software decoding.
I'm not really sure why or when this started happening. Commit 7b9d7265
for one is not the cause - it can be reproduced with earlier commits. It
also seems to be timing dependent. Possibly it has to do with the way
vo.c retains previous surfaces, and the way they can be queued/unqueued
asynchronously.
Increasing the number of reserved additional surfaces by 1 fixes it.
(Though I have no idea where exactly all these surfaces are being used.
Or rather, _when_.)
See manpage additions. This is mainly useful for vo_opengl_cb, but can
also be applied to vo_opengl.
On a side note, gl_hwdec_load_api() should stop using a name string, and
instead always use the IDs. This should be cleaned up another time.
Now there's a "canonical" table for mapping the names, that other code
can use, without having to rely too much on option code magic.
Also, use the central HWDEC constants, instead of magic values. (There
used to be semi-ok reasons to do this, but now it makes no sense
anymore.)
Some filter chains require a huge number of auto-inserted conversion
filters. There is an overly stupid safeguard against infinite filter
insertions, which counts the number of conversion filters inserted. This
triggered accidentally in this case. Fix by resetting this counter after
a non-conversion filter was successfully configured.
Each subtitle track gets its own decoder instance (sd_ass). But they use
a shared ASS_Renderer. This is done mainly because of fontconfig.
Initializing fontconfig is very slow when using it with memory fonts, so
there's a practical need to cache this memory font state, which is done
by not creating separate ASS_Renderers. This is very dirty and very
evil, but we probably can't get rid of it any time soon.
The shared ASS_Renderer was not properly synchronized. While the program
logic guarantees that only one sd_ass instance is visible at a time,
there are other interactions that require synchronization. In
particular, I suspect concurrent execution of mp_ass_configure_fonts()
and sd_ass.get_bitmaps cause issues in a newer libass development
branch.
So here's a shitty hack that hopefully fixes things, hopefully only
until libass becomes less dependent on fontconfig.
Basically, we need to make sure to allocate enough data for the pretty
dumb copy_nv12 function. (It could be avoided by making the function
less dumb, but this fix is simpler.)
ao_coreaudio (using AudioUnit) accounted only for part of the latency -
move the code in ao_coreaudio_exclusive to utils, and use that for the
AudioUnit code.
(There's still the question why CoreAudio and AudioUnit require you to
jump through hoops this much, but apparently that's how it is.)
mpv had refcounted frames before libav*, so we were not using
libavutil's facilities. Change this and drop our own code.
Since AVFrames are not actually refcounted, and only the image data
they reference, the semantics change a bit. This affects mainly
mp_image_pool, which was operating on whole images instead of buffers.
While we could work on AVBufferRefs instead (and use AVBufferPool),
this doesn't work for use with hardware decoding, which doesn't
map cleanly to FFmpeg's reference counting. But it worked out. One
weird consequence is that we still need our custom image data
allocation function (for normal image data), because AVFrame's uses
multiple buffers.
There also seems to be a timing-dependent problem with vaapi (the
pool appears to be "leaking" surfaces). I don't know if this is a new
problem, or whether the code changes just happened to cause it more
often. Raising the number of reserved surfaces seemed to fix it, but
since it appears to be timing dependent, and I couldn't find anything
wrong with the code, I'm just going to assume it's not a new bug.
This caused issues with hardware decoding. The VOs by definition dictate
the lifetime of the hardware context, so no surface allocations must
survive the VO. Fixes assertions on exit with vdpau.
It's conceivable that the OS time source is subject to clock changes.
The time could jump back to before when mpv was started, which would
cause mp_time_us() to return values smaller than 1. This is unexpected
by the code and could trigger assertions. If there's no monotonic time
source there's not much we can do anyway, so just sanitize the return
value. It will cause strange behavior until the "lost" time offset has
passed, but if you make such huge changes to the system clock while
everything is running, you're asking for trouble anyway.
(Normally we try to get a monotonic time source, though. This problem
sometimes happened on Windows when compiled without winpthreads, when
the code was falling back to gettimeofday(). This was already fixed by
always using another method.)
clock_gettime is implemented in winpthreads, so it's unavailable when
mpv is compiled with its internal pthreads implementation. This makes
mp_raw_time_us fall back to gettimeofday(), which can cause an assert
failure in mp_add_timeout() when the system clock is changed. Use
QueryPerformanceCounter instead.
The clock_gettime(CLOCK_MONOTONIC) implementation in winpthreads uses
QueryPerformanceCounter anyway, so there shouldn't be any change in
behaviour.
If the request contains a "request_id", copy it back into the
response. There is no interpretation of the request_id value by mpv; the
only purpose is to make it easier on the requester by providing an
ability to match up responses with requests.
Because the IPC mechanism sends events continously, it's possible for
the response to a request to arrive several events after the request was
made. This can make it very difficult on the requester to determine
which response goes to which request.
Until now, this was for AC3 only. For PCM, we used AudioUnit in
ao_coreaudio, and the only reason ao_coreaudio_exclusive exists
is that there is no other way to passthrough AC3.
PCM support is actually rather simple. The most complicated
issue is that modern OS X versions actually do not support
copying through the data; instead everything must go through
float. So we have to deal with virtual and physical format
being different, which causes some complications.
This possibly also doesn't support some other things correctly.
For one, if the device allows non-interleaved output only, we
will probably fail. (I couldn't test it, so I don't even know
what is required. Supporting it would probably be rather
simple, and we already do it with AudioUnit.)
Mapping of spdif formats was imperfect. Since the first format on the
list is somehow AAC, it was returned first, which is confusing, because
CoreAudio calls all spdif formats AC3. Since the spdif formats have some
rather arbitrary, reverse mapping the formats didn"t actually work
either. Fix by explicitly ignoring these when spdif is used.
Also, don't forget to set the samplerate in ca_asbd_to_mpformat(), or it
will work only in some cases.
This is basically a hack for drivers which prevent the mpv DXVA2 decoder
glue from working if OpenGL is in fullscreen mode.
Since it doesn't add any "hard" new API to the client API, some of the
code would be required for a true zero-copy hw decoding pipeline, and
sine it isn't too much code after all, this is probably acceptable.
For the sake of removing the separate stream/demuxer loading code.
This could probably be reimplemented in some other way, but I have no
DVB hardware for testing. The most preferred way would be making DVB to
not quit, and just rerun the stream selection.
The final goal is making opening the demuxer and opening the stream the
same operation.
Stream dumping is a rather uninteresting feature, but has a small
number of vocal users, and it's easy to keep.
When seeking to a different position, and seeking takes long, the OSD
might get redrawn. This means that the VO will receive a request to
redraw an old frame using whatever the previous PTS was. This breaks the
interpolation logic: the old frame will be added to the queue, and then
the next frames (with lower PTS if you seeked backwards) are not drawn
as the logic assumes they're past frames.
Fix this by using the non-interpolation code path when redrawing after a
seek reset, and no "real" frame has been drawn yet.
It's a recent regression caused by the redrawing code simplification.
The old code simply sent a VOCTRL for redrawing the frame, and the VO
had to deal with retaining the old frame on its own.
This is a hack as in there's probably a better solution.
Fixes#2097.
Less code, and avoids a black flash on start.
In theory it could happen that we map the window, and then don't have a
frame to draw - but mapping the window is done in the exact moment we
have a new frame to display.
This flags stuff tried to be too clever - if there are overlapping flags
(e.g. exclusive or combined flags), the one matching with most bits has
to be chosen.
This fixes logging of the seek command. E.g. "relative" and "absolute"
overlap to make them exclusive, but "relative" was always printed as it
happened to match first.
This is not the most theoretically perfect solution, ideally we could
check to see if the frame in question has already been rendered
somewhere in the queue and then avoid re-rendering it, at the cost of a
few extra lines of code. But I don't think the performance trade-off is
dramatic enough here.
draw_image_timed is renamed to draw_frame. struct frame_timing is
renamed to vo_frame. flip_page_timed is merged into draw_frame (the
additional parameters are part of struct vo_frame). draw_frame also
deprecates VOCTRL_REDRAW_FRAME, and replaces it with a method that
works for both VOs which can cache the current frame, and VOs which
need to redraw it anyway.
This is preparation to making the interpolation and (work in progress)
display sync code saner.
Lots of other refactoring, and also some simplifications.
This should make interpolation work much better in general, although
there still might be some side effects for unusual framerates (eg. 35 Hz
or 48 Hz). Most of the common framerates are tested and working fine.
(24 Hz, 30 Hz, 60 Hz)
The new code doesn't have support for oversample yet, so it's been
removed (and will most likely be reimplemented in a cleaner way if
there's enough demand). I would recommend using something like robidoux
or mitchell instead of oversample, though - they're much
smoother for the common cases.
For now, this is trivial (and actually redundant). The future display
sync code will make better use of it. The main point is that the new
internal API pretty much makes this transparent to the vo_opengl
interpolation code.
Now the VO can request a number of future frames with the last parameter
of vo_set_queue_params(). This will be helpful to fix the interpolation
code.
Note that the first frame (after playback start or seeking) will usually
not have any future frames (to make seeking fast). Near the end of the
file, the number of future frames will become lower as well.
Until now, it only used the hash from the previous configure run,
instead of trying to get the latest hash. The "old" build system did
this correctly - we just have to use the existing logic in version.sh.
Since waf supports separate build dirs, extend version.sh with an
argument for setting the path of version.h.
May help with (supposedly) bad drivers, which can put the device into
some sort of broken state when trying to set a different physical
format. When the previous format is restored, it apparently recovers.
This might make the change-physical-format suboption more robust.
We can be pretty sure that AudioUnit will remix for us.
Before this commit, we usually upmixed to stereo, because the
stereo and multichannel layouts were the only whitelisted ones.
Again. With the old OpenGL interop dropped, this probably works better
than vaapi-copy now. Last time we defaulted to vaapi-copy, because the
OpenGL interop could swap U/V planes and other stupid crap. We'll see.
Work around that FFmpeg doesn't distinguish between surface and cropped
size. The decoder always aligns the surface size to something
"convenient" (e.g. 16 for h264), and to get to the correct cropped size,
the output image's width/height is reduced. Using the cropped size
instead of the real surface size breaks the libva API in certain cases,
so we simply store and use the original size in our per-surface struct.
(If data is cropped on the left/top borders, hw decoding will simply
display these - FFmpeg doesn't let us do better.)
In theory, this code path avoids a copy. In practice, it never seems
to get enabled at all. But it does have potential for weird bugs or
performance issues (like being mapped from non-cacheable memory),
so kill it.
Some window managers let you change the fullscreen state of any window
using a key combination. For example, on XFWM you can use Alt+F11 and
on Compiz you can configure a key combination with the
"Extra WM actions" plugin.
With this change mpv will handle these fullscreen state changes. So, if
you enter into fullscreen mode using the WM's shortcut and then you use
mpv's fullscreen toggle, you will get back into window mode.
Merges PR #2081.
Signed-off-by: wm4 <wm4@nowhere>
If the EditionFlagOrdered is set, chapters without ChapterTimeEnd make
no sense. Ordered chapters will play the chapters in the order they
appear, but will play the ranges the chapters cover. So if the end time
is missing, the range is incomplete and it's not clear what should be
played. If you assume the start of the next chapter as end time, the
ordered flag will have no observable effect, so that's not a useful
assumption.
This fixes playback of a file which (apparently) had the
EditionFlagOrdered set accidentally, with normal chapters.
At least Matroska files have a "forced" flag (in addition to the
"default" flag). Export this flag. Treat it almost like the default
flag, but with slightly higher priority.
The "FrameRate" element is probably deprecated (it's greyed out in the
"spec", and described as "Informational only" in bold). Normally files
use DefaultDuration. In fact, the FrameRate field was preferred over
DefaultDuration for determining framerate if present. Do not do this and
rely on DefaultDuration only.
Also, if no framerate is set, do not assume PAL (25 FPS). Such a
fallback makes little sense and will cause more problems than it solves.
We want to distinguish actual errors, and just aborting the program
intentionally.
Also be a bit more careful with handling the wait() exit status: do not
called WEXITSTATUS() without checking WIFEXITED() first.
mpv usually sets the terminal to non-canonical mode (which in particular
disables line buffering). But the old mode is restored if the process is
not foregrounded. This is supposed to make mpv behave nicer when it is
backgrounded.
getch2_poll() enables canonical mode. Unfortunately, this was only
called after the poll timeout elapsed, so non-canonical mode is first
enabled after about a second after program start. Fix this by moving the
poll call before the timeout.
(As far as we're aware, there's no event-based way to determine when the
FD's process group changes, thus we're polling.)
DVD/BD menu support never worked right, and are a pain to maintain. In
particular, DVD menus never actually worked correctly, because
highlights were not rendered correctly. Fixing this requires major
effort, which I'm not interested to spend.
Most importantly, the requirement to switch streams without losing the
DVD/BD state caused major weirdness in the playback core. It was
implemented by somehow syncing the playback state to the DVD/BD
implementation (in stream_dvdnav.c etc.), and then reloading the demuxer
without destroying and recreating the stream. This caused a bunch of
special-cases which I'm looking forward to remove.
For now, don't just remove everything related to menu support and just
disable it. If someone volunteers, it can be restored (i.e. rewritten)
in a reasonable way. If nobody volunteers soon, it goes.
Replace all the check macros with function calls. Give them all the
same case and naming schema.
Drop af_fmt2bits(). Only af_fmt2bps() survives as af_fmt_to_bytes().
Introduce af_fmt_is_pcm(), and use it in situations that used
!AF_FORMAT_IS_SPECIAL. Nobody really knew what a "special" format
was. It simply meant "not PCM".
Audio formats used a semi-clever schema to encode the properties of the
PCM encoding as bitfields into the format integer value.
The af_fmt_change_bits() implementation becomes a bit weird, but it's
an improvement to the rest of the code.
(I've always disliked it, so why not get rid of it.)
This may or may not fix some issues with the format switching
code. Actually, it seems somewhat unlikely, but then checking
the stream type isn't incorrect either, and is probably
something the API user should always be doing.
Originally, this was written for comparing the sample format only, but
ca_change_physical_format_sync() actually expects that the full format
is compared. (For all other uses it doesn't matter.)
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.
This reverts commit fc9695e63b.
Users were complaining that both mpv and something else (what? I don't
know) respond to some multimedia keys, such as volume change.
Integer and float elements are encoded as a sequence of bytes prefixed
by a variable-length encoded length specifier. If the length is 0, then
there is no data. Whether this is valid or not is not really clear, but
some sample files which do this have surfaced. It's not particularly
hard to handle this, so just do it.
Use char* for strings instead of bstr (data ptr + length pair). Matroska
actually (probably) allows "padding" strings with \0 bytes, so using
normal C strings instead of byte strings is more appropriate.
500ms is a bit too high. Change it to 50ms. This improves client API
(and Lua) playback state update frequency.
Updating absolutely every time the audio PTS changes would be possible,
but is not helpful. Audio samplerates are high to trigger a wakeup
feedback loop, so the process would waste CPU time on updating the
playback position all the time.
(If a client application wants to ensure smooth update of the playback
position, it should update the position manually using a timer and by
reading the property - the application can make a much better decision
at how often the playback has to happen.)
This avoids keeping "bad" state from previous reconfig calls, such as
the internal_sample_format option (which is set only on the first
reconfig call).
There's no advantage to keeping the resample contexts around anyway.
Basically, af_fix_format_conversion() behaves stupid you insert a
conversion filter that won't work, and adding back the conversion test
function is the simplest fix to it.
So apparently, this essentially happens when the kernel driver doesn't
implement write accesses in the channel map control. Which doesn't
necessarily mean that the channel map is unsupported, or that there is a
bug - it's just lazyness and a consequence of the terrible ALSA kernel
API for the channel mapping stuff.
In these cases, the channel count implicitly selects the channel map,
and snd_pcm_set_chmap() always fails with ENXIO.
I'm actually not sure what happens if dmix is on top of e.g. HDMI, which
actually lets you change the channel mapping.
I'm also not sure why commit d20e24e5d1614354e9c8195ed0b11fe089c489e4
(alsa-lib git repository) does not take care of this.
MPlayer traditionally had completely separate sh_ structs for
audio/video/subs, without a good way to share fields. This meant that
fields shared across all these headers had to be duplicated. This commit
deduplicates essentially the last remaining duplicated fields.
Always use the already existing extradata[_len] variable, instead of the
awkward switch between manually changed extradata and falling back to
passing through extradata at the end.
When using --hwdec=auto, about half of all systems will print:
"[vdpau] Error when calling vdp_device_create_x11: 1"
this happens because usually mpv will be linked against both vdpau and
vaapi libs, but the drivers are not necessarily available. Then trying
to load a driver will fail. This is a normal part of probing, but the
error messages were printed anyway. Silence them by explicitly
distinguishing probing.
This pretty much goes through all the layers. We actually consider
loading hw backends for vo_opengl always "auto probed", even if a hw
backend is explicitly requested. In this case vd_lavc will print a
warning message anyway (adjust this message a bit).
Client API users can enable log output with mpv_request_log_messages().
But you can enable only a single log level. This is normally enough, but
the --msg-level option (which controls the terminal log level) provides
more flexibility. Due to internal complexity, it would be hard to
provide the same flexibility for each client API handle. But there's a
simple way to achieve basically the same thing: add an option that sends
log messages to the API handle, which would also be printed to the
terminal as by --msg-level.
The only change is that we don't disable this logic if the terminal is
disabled. Instead we check for this before the message is output, which
in theory can lower performance if messages are being spammed. It could
be handled with some more effort, but the gain would be negligible.
This happens with av_log(NULL, ...) calls. Drop the "?: " fallback
prefix, because it was confusing.
(Of course FFmpeg should not do this at all, but it's a very long way to
making the FFmpeg log callback sane.)
That's how mime types are.
(This makes redirection with a specific HLS URL work, because some idiot
thought it'd be a great idea to spell the mime type as
"application/x-mpegURL".)
No particular reason, but it's still possible that it causes additional
corner cases, and it's not really needed to test this on wine (other
than testing fullscreen stuff, which should be done on a real Windows
anyway).
The only decoders I could find and which (possibly) require this field
are codecs which can be used via VfW only, and realaudio sipr. For VfW
we still passthrough this field.
Native Matroska codec support has to map the Matroska codec IDs to
libavcodec ones, and also has to undo codec-specific Matroska
strangeness, such as restoring AAC extradata and realaudio handling. The
VfW codec support doesn't need it, because AVI maps well enough to
libavcodec conventions (possibly because AVI was a dominant codec when
libavcodec was created). But there's still some need for generic codec
handling, such as enabling parsers and messing with various codec
parameters.
Separate these two, and move the parts which are guaranteed not to be
needed by VfW to the if-else tree that handles the VfW case
("A_MS/ACM"), making the cases exclusive.
(This should probably be done more radically, since it's very unlikely
that we should or have to mess with the VfW parameters at all - they
should just be passed through to the decoder.)
This removes the last traces of the old MPlayer FourCC-based codec
mapping code. Forcing all codec IDs through a FourCC table and then
back to codec names was confusing at best, so this is a nice cleanup.
Handling of PCM (non-VfW case) is redone to some degree.
Handling of AC3 is moved below realaudio handling, since "A_REAL/DNET"
is apparently AC3, and we must not skip realaudio-specific handling.
(It seems unlikely that anything would actually break, but on the other
hand I don't have any A_REAL/DNET samples for testing.)
Instead of explicitly matching all the specific AAC codec names, just
match them all as prefix.
Some codecs don't need special handling other than their mapping
entries, so they fall away (like Vorbis and Opus).
The prores check in mkv_parse_and_add_packet() is not strictly related
to this, but is done for consistency with the wavpack check above.
When showing cover art, the decoding logic pretends that the source has
an infinite number of frames. This slightly simplifies dealing with
filter data flow. It was done by feeding the same packet repeatedly to
the decoder (each decode run produces new output).
Change this by decoding once at the video initialization. This is easier
to follow, and increases robustness in case of broken images. Usually,
we try to tolerate decoding errors, so decoding normally continues, but
in this case it would just burn the CPU for no reason.
Fixes#2056.
This is slightly "dangerous", because it could overwrite a log callback
another library has set, after we've set our own callback. But it's
probably still slightly better than leaving our own callback, which will
run the fallback code if no mpv instance is set. (Multiple mpv instances
sharing the same global state will safely avoid overwriting each other's
log callback.)
Note that we can't do much better, because the global state in FFmpeg is
obviously insane.
The previous behavior is confusing if the B point is near EOF (consider
B being the duration of the file, which is strictly speaking past the
last video timestamp). The new behavior is fine as well for B being far
past EOF.
Achieve this by checking the EOF state in addition to whether playback
has reached the B point. Also, move the A-B loop code out of
command_event(). It just isn't useful anymore, and obfuscates the code
more than it makes it loop simple.
Fixes#2046.
Seems logical.
Note that if playback otherwise ends while playback is active and a seek
is still queued, we still exit. Otherwise you couldn't end playback by
seeking past the end of the file (which is classic MPlayer and mpv
behavior).
This attempted to find a minimal filter graph for a format conversion
involving multiple conversion filters. With the last 2 commits it
becomes dead code - remove it.
Now af_lavrresample can output 24 bit samples directly, by doing the
conversion "inline". Luckily, S32->S24 can be done in-place, so this
isn't too much work. But the output conversion logic (which seems to be
adding up) gets slightly more complicated again.
Normally this is done by af_convert24. But having multiple conversion
filters complicates some aspects of the filter chain. S24 output is the
only thing the code for multiple conversion filters is still needed for,
and getting rid of that is preferable.
If the code path for additional output conversion is active,
reorder_planes() is always called, even if the reorder_out array wasn't
filled. This is obviously wrong - always fill this array.
They are useless. Not only are they actually rarely in use; but
libavcodec doesn't even output them, as libavcodec has no such sample
formats for decoded audio.
Even if it should happen that we actually still need them (e.g. if doing
direct hardware output), there are better solutions. Swapping the sign
is a fast and lossless operation and can be done inplace, so AO actually
needing it could do this directly.
If you wonder why we keep U8 instead of S8: because libavcodec does it.
The existing code avoided doing this for some codecs. I see no point in
this, and it seems the original reason this exists was due to some
cleanup in 2007. libavformat doesn't do this. So just drop it.
It's well possible that we've always ended up invoking the
AV_CODEC_ID_MPEG1VIDEO codec, but it's hard to tell. Mangling everything
through FourCCs (and then back) makes it hard to analyze. Also,
libavformat's Matroska demuxer uses AV_CODEC_ID_MPEG2VIDEO here, so it
should be quite safe to do anyway.
Inherited from MPlayer times, we used FourCCs to identify video codecs.
This was later changed to libavcodec codec names (which made life a
whole lot simpler). But demux_mkv still uses FourCCs a lot.
Change this for video. It's pretty simple, because some preparation was
done in the past. We just have to replace some "internal" FourCCs with
different handling.
One potentially complicated issue is that there is no natural way to
set the sh->format (AVCodecContext.codec_tag) field anymore. Most
decoders do not need it, though mjpeg is an exception.
Note that the AVI compatibility code still requires codec mappings, but
these are provided by FFmpeg. Also, the audio code is not changed.
For the MKV_V_MPEG2 -> mpeg1video thing see next commit.
Channel maps reported by the device as SND_CHMAP_TYPE_VAR can be freely
reordered. We don't use this much (out of laziness), but in this case
it's a simple way to reduce necessary reordering (which would be an
extra libavresample invocation), and to make debug output more readable.
Until now, we didn't do this, because it required some effort, and
didn't seem to be necessary. It probably still isn't, but it sounds
like a good idea not to output arbitrary data on these channels.
The situation is complicated by the fact that just adding new channels
to a planar frame would require messing with buffers. So we would have
to allocate new buffers and add them to the frame. We could have to
maintain an extra buffer pool for this. Avoid this by being "clever",
and just allocate a frame with enough channels in the first place.
libav/swresample won't know about these channels and won't write to
them, but we can grab them in reorder_planes() and use them for the
NA channels.
This is just a conceptual issue, since for now every channel count has
an associated standard layout.
But should the max. channel count ever be bumped, some things would stop
function if mp_chmap_from_channels() refused to work for any channel
count within the allowed range.
In the AVFrame-style system (which we inreasingly map our internal data
stuctures on), buffers and plane pointers don't necessarily have a 1:1
correspondence. For example, a single buffer could cover 2 or more
planes, all while other planes are covered by a second buffer, and so
on. They don't need to be ordered in the same way.
Change mp_audio_get_allocated_size() to retrieve the maximum size all
planes provide. This also considers the case of planes not pointing to
buffer start.
Change mp_audio_realloc() to reset all planes, even if corresponding
buffers are not reallocated. (The caller has to be careful anyway if it
wants to be sure the contents are preserved on realloc calls.)
If you try to play surround with dmix, it will advertise surround and
lets you set more than 2 channels, but will report a stereo channel map,
with the extra channels identified as NA. We could handle this now, but
we don't want to (because it's excessively stupid).
Do it only if the channel map is not what we requested, instead of just
acting if it contains NA entries at all. This avoids that we hurt
ourselves in the unlikely but possible case we actually have to use
channel maps with NA entries.
So successful playback and user quit can be distinguished, for whatever
reason you may want to do this.
Normally, the "quit" command can be customized, but this does not work
for quit commands sent by the terminal signal handler. One solution
would be introducing something like "ON_SIGNAL" (equivalent to
"CLOSE_WIN"), but considering there are a bunch of possible signals, I'd
rather not get into this. So go with the dumb solution.
Probably fixes#2029.
gl_video_set_options() does not acquire ownership of the opts parameter
or its contents. In case of vo_cmdline, opts will point to temporary
memory. This memory will be free'd at a later point, and p->opts will
point to free'd memory on the next reinitialization.
The fix is pretty ugly, but it's a quick bug fix. This can probably be
removed once VO sub-options are exposed as properties.
Fixes#2035.
If the audio API takes a while for starting the audio callback, the
current heuristic can be off. In particular, with very short files, it
can happen that the audio callback is not called before playback is
stopped, so no audio is output at all.
Change draining so that it essentially waits for the ringbuffer to
empty. The assumption is that once the audio API has read the data
via the callback, it will always output it, even if the audio API
is stopped right after the callback has returned.
If a frame could only be partially filled with real audio data, the
silence wasn't written at the correct offset. It could have happened
that the remainder of the frame contained garbage.
(This didn't happen in the more common case of playing dummy silence.)
Used a wrong condition, and I suppose it could crash in some situations.
Change it to lazily initialize the hotplug stuff, like the
audio-device-list property does.
This was matching e.g. both "foo/bar" and "foobar" against "foo", when
only the former should match. This could cause more property
notifications than necessary.
Absence of license header implies LGPL, as mentioned in the "Copyright"
file. But vaapi.h contains some code taken from the mplayer-vaapi
patch, which was under the typical MPlayer license.
All vo_gl.c related code has been GPL+LGPL dual-licensed. The OSD code
is no exception and is also derived from vo_gl.c. Thus it should have
the same license (although I think technically speaking sub-licensing
it by removing one of the licenses is ok).
Commits 92b27be and f4ce99d removed high-fps logic to to a bug. That bug was
a missing parenthesis around everything after duration >= 0 && ... at the
removed code.
This patch restores the removed code, fixes the bug and then refactors the
code a bit.
This reverts commit f1746741de.
Together with the other revert, this fixes#2023 (the reason being
broken framedrop handling - it was dropping frames when it shouldn't).
read_output_surface() could fail and return NULL.
Also, make sure we don't set the image to a size larger than the
allocated size. Normally this shouldn't happen, but in theory it could
in corner cases; this is for robustness.
This provides a new method for enabling spdif passthrough. The old
method via --ad (--ad=spdif:ac3 etc.) is deprecated. The deprecated
method will probably stop working at some point.
This also supports PCM fallback. One caveat is that it will lose at
least 1 audio packet in doing so. (I don't care enough to prevent this.)
(This is named after the old S/PDIF connector, because it uses the same
underlying technology as far as the higher level protoco is concerned.
Also, the user should be renamed that passthrough is backwards.)
This deprecates the --ad-spdif-dtshd option, and replaces it with a
pseudo decoder. This means ad_spdif will report two decoders, "dts" and
"dts-hd", of which the second simply enables what the option did.
The --ad-spdif-dtshd option will actually be deprecated in the next
commit.
This makes no sense, because the format can't be converted anyway. It
just sets up the filter chain init code, which will vomit a bunch of
useless and confusing messages. So uninit and fail explicitly when this
happens.
We can't do much in this case, but at least we can not call the vdpau
API functions with too large sizes. Apparently the API considers this
undefined behavior, and random stuff might happen.
The previous code was not wrong, but I'd claim this makes the code more
robust. If a situation could happen in which the passed surface size is
incorrect, we could have passed a too small image, and
VdpOutputSurfaceGetBitsNative could have randomly overwritten memory.
Check the maximum size of video surfaces, and refuse initialization if
the video is too large for them.
Maybe we could do something more sophisticated, like inserting a
software scaler. On the other hand, this would have a very questionable
benefit, as it would be guaranteed to be too slow.
When starting in paused mode, no audio is written to the device at all,
because writing audio implicitly unpauses the AO. If the file is very
small, and all audio fits within the AO buffer, this accidentally
triggered the EOF condition. (In unpaused mode, it would write all
audio, end playback, and then wait until the AO has everything played.)
This is better, because now we call swr_get_delay() with the output
samplerate, instead of with the input samplerate and then multiplying it
with the ratio and rounding it up.
Apparently, just running ./waf and hoping that it will be run with a
Python interpreter doesn't necessarily work. The workaround is pretty
simple and reliable.
The "osd" command cycles between 4 states (OSD level 0-3), which is
probably confusing and inconvenient. OSD levels 0 and 2 are rarely
needed. I would claim there is normally not much of a need to completely
disable OSD by setting level 0 during playback. Level 2 is just slightly
less information than level 3, and I'm not sure why it exists at all.
Change it so that it toggles between level 3 and 1. Note that this
ignores the default OSD level. If the default is 3, the first use of
this key will set it to 3 again. Just assume 1 is the default. If
someone complains, this could be improved.
There's a short time during loading where external commands can add
external streams even before the main file is loaded (like during ytdl
hook execution). The track list is printed every time an external track
is added via commands. This was quite awkward when ytdl was adding
multiple streams, so don't print it in this stage. They are printed
anyway at the end of the loading process.
Listening to kAudioDevicePropertyDeviceHasChanged does not send any
property change notifications when the device dies. Makes no sense,
but I suppose in CoreAudio logic a dead/removed device can't send
any notifications.
This caused the player to essentially pause playback if the audio
device was removed during playback.
Fix by listening to the kAudioHardwarePropertyDevices property too,
which will actually be sent in this specific case. Then, if
querying the already dead device fails, we know we have to reload.
In short, instead of letting the coreaudio property listener set atomic
flags (which are then polled), make the property listeners actually
active.
The format change listener used during audio output now simply calls
ao_request_reload() on its own. All code involved is thread-safe, so
there's no need to do it during this audio callback (we assumed the
callback was never run concurrently with itself).
The listener installed temporarily during ca_change_format() is changed
to post a semaphore. Get rid of the weird retry logic and replace it
with a flat loop + timeout. It appears the maximum wait time could be
2500ms; reduce the total timeout to 500ms instead.
This manually retrieved the remaining audio from the resampler. It
subtly missed a conversion which could leave to an unsubtle crash.
This could happen if reorder_planes() was supposed to insert NA
channels, and the resampler/actual output format were different.
Simplify it by reusing the normal drain path. One oddness is that
the filter will add an output frame outside of normal filtering,
but that should be fine.
This was missing for extended deinterlacer.
Unfortunately, these deinterlacer still do not work. The provided future
frame (which is all the deinterlacers want) seems to be correct, though.
One minor behavioral change is that this always keeps the previous frame
for PTS computations. This could be avoided (in order to keep exactly
the same behavior as before), but it seems more elegant and should not
do any harm. (Also, if we really cared about reducing hw frame refs,
a more worthy goal is producing the field output incrementally.)
The mapped data (pointed to by the param variable) is not needed before,
so the call can be moved down. Also, this prevents that the buffer
remains mapped forever if the other vaMapBuffer() call above fails (the
cleanup code forgets to unmap the buffer - this commit makes it
unnecessary).
This used a do-while loop, which runs only once, as replacement for a
cleanup goto. While this is ok, doing a goto directly is easier to
follow and is closer to idiomatic C. But mainly remove it so that the
indentation can be reduced.
Reconfiguring with the same video size should never cause the window to
resize back to the video size (if the user changed its size). This was
broken and it resized anyway.
We do not fill them, so we would pass random IDs to the driver. The code
was originally written to handle bob deinterlacing only, so I guess it
originally passed always 0 anyway, despite having code for reference
surface list allocation.
Also, move down the vaUnmapBuffer() call. This call actually "unmaps"
the param pointer, so accessing it after the unmap call would be
undefined behavior. The "example" in <va/vavpp.h> does this too, but
it's most likely an error.
(Additionally, not even bob deinterlacing worked correctly in my test,
sigh.)
Normally, the cache keeps 50% of the buffer for seeking backwards. Until
now, the cache just used the full buffer size at the beginning of a
file, because the 50% normally reserved for the backbuffer are unused.
This caused a problem: when streaming from http, the player would first
read about 150MB (default cache size), then stop until 75MB of the cache
has been played. (Until the 75MB position, the cache is fully used, so
nothing new can be read. After that, part of the backbuffer starts
getting unreserved, and can be used for readahead.) This long read pause
can cause the server to terminate the connection. Reconnecting may be
possible, but if youtube-dl is used, the media URL may have become
invalid.
Fix this by limiting readahead to 50% even if unnecessary. The only
exception is when the whole file would fit in the cache. In this case,
it won't matter if we can't reconnect, because the cache covers
everything anyway, and hopefully the cache will stay valid.
Likely fixes#2000.
This must have been some non-sense in the original vaapi mplayer patch.
While I still have no good idea what this "direct mapping" business is
about, it appears to be pretty much pointless. Nothing can hold
additional "real" surface references (due to how the API and mpv/lavc
refcounting work), so removing the additional surfaces won't break
anything. It still could be that this was for achieving additional
buffering (not reusing surfaces as soon), but we buffer some additional
data anyway. Plus, the original intention of the vaapi mplayer code was
probably increasing surface count just by 1 or 2, not actually doubling
it, and/or it was a "trick" to get to the maximum count of 21 when h264
is in use.
gstreamer-vaapi uses "ref_frames + SCRATCH_SURFACES_COUNT" here, with
SCRATCH_SURFACES_COUNT defined to 4. It doesn't appear to check the
overlay attributes at all in the decoder.
In any case, remove this non-sense.
It polluted the global namespace, instead of exporting the function
properly.
For now, keep it compatible by explicitly keeping the bogus export.
Also fix a mistake in the manpage example.
On hw decoder reinit failure we did not actually always return a sw
format, because the first format (fmt[0]) is not always a sw format.
This broke some cases of fallback. We must go through the trouble to
determine the first actual sw format.
This reduces spam while preempted a bit.
The remaining message, "hardware accelerator failed to decode picture"
on every frame, can not be prevented because it's hardcoded in
libavcodec.
If gl_hwdec_driver.map_image fails, all textures will be set to 0. This
in turn makes pass_prepare_src_tex() skip generation of the texture
uniforms, which leads to a shader compilation error, as e.g. texture0 is
not defined but expected to exist and accessed.
Set the textures to an invalid non-0 ID instead. OpenGL can deal with
it.
Yet another of these dozens of hwaccel changes. This time, libavcodec
provides utility functions, which initialize the vdpau decoder and map
codec profiles. So a lot of work the API user had to do falls away.
This also will give us support for high bit depth profiles, and possibly
HEVC once libavcodec supports it.
...instead of relying on the hw decoding API to align it for us. The old
method could in theory have gone wrong if the video is cropped by an
amount large enough to step over several blocks.
Always configure the vdpau mixer based on the current surface sent to
it. Before this, we just hardcoded the chroma type, and the surface size
was essentially a guess.
Calling VdpVideoSurfaceGetParameters() on every surface is a bit
suspicious, but it appears it's a cheap function (just requiring some
locks and a table lookup). This way we avoid creating another
complicated mechanism to carry around the actual surface parameters
with a mp_image/AVFrame.
There's not much of a reason to keep get_surface_hwdec() and
get_buffer2_hwdec() separate. Actually, the way the mpi->AVFrame
referencing is done makes this confusing. The separation is probably
an artifact of the pre-libavcodec-refcounting compatibility glue.
Most of hardware decoding is initialized lazily. When the first packet
is parsed, libavcodec will call get_format() to check whether hw or sw
decoding is wanted. Until now, we've returned AV_PIX_FMT_NONE from
get_format() if hw decoder initialization failed. This caused the
avcodec_decode_video2() call to fail, which in turn let us trigger the
fallback. We didn't return a sw format from get_format(), because we
didn't want to continue decoding at all. (The reason being that full
reinitialization is more robust when continuing sw decoding.)
This has some disadvantages. libavcodec vomited some unwanted error
messages. Sometimes the failures are more severe, like it happened with
HEVC. In this case, the error code path simply acted up in a way that
was extremely inconvenient (and had to be fixed by myself). In general,
libavcodec is not designed to fallback this way.
Make it a bit less violent from the API usage point of view. Return a sw
format if hw decoder initialization fails. In this case, we let
get_buffer2() call avcodec_default_get_buffer2() as well. libavcodec is
allowed to perform its own sw fallback. But once the decode function
returns, we do the full reinitialization we wanted to do.
The result is that the fallback is more robust, and doesn't trigger any
decoder error codepaths or messages either. Change our own fallback
message to a warning, since there are no other messages with error
severity anymore.
Vobsubs come as .idx/.sub pair of files. The .idx file is the one that
should be opened, but the name of the .sub file is unknown. We can now
make our own guess what the name of that file is. In particular, improve
support with URLs (as these can have the file extension in the middle of
the filename string if there are HTTP parameters).
Note that this works only with newer ffmpeg versions, because the
recently added sub_name demuxer option is used for this.
This command has been deprecated in the 0.8.x and 0.9.x releases - get
rid of it. Its only point ever was MPlayer compatibility, which broke
years ago anyway.
They're completely orthogonal concepts, merged in the past due to
convenience and ease of implementing it in the old #ifdef hell renderer.
Especially after the CMS stuff was generalized by 634b4a, this was a
trivial change to implement and also means color management will be much
higher quality when enabled with vo=opengl (which had quantization
issues in the past due to the 8 bit FBO format and upscaling), since it
can be done in a single pass now.
While all functions of input_ctx are inherently thread-safe, access to
the _inputContext field itself is not. It could be unset any time by
cocoa_set_input_context(). So even trivial input_ctx calls must be under
a lock, so that the input_ctx can not be destroyed while the function
call is "starting". (Even a function call in progress wouldn't be fine,
because mp_input_uninit() requires the caller to "own" the object, i.e.
no other threads can access it at this point.)
For certain reasons, we allow adding external tracks even before the
main file is loaded. This somewhat breaks in old assumption, which uses
mpctx->num_sources to determine whether a command can be applied in the
current state. Use the newer playback_initialized instead, which is a
much better choice for this purpose.
The previous commit removed this. Although mp_switch_track() can now be
called in all situations, we still don't want it to be called here.
Setting a track property while no file is loaded would simply deselect
the track instead of setting the underlying option to the requested
value.
Likewise, if the "cycle" command (M_PROPERTY_SWITCH) is used, don't just
deselect the track.
Adding an external audio track before loading the main file didn't work
right. For one, mp_switch_track() assumes it is called after the main
file is loaded. (The difference is that decoders are only initialized
once the main file is loaded, and we avoid doing this before that for
whatever reason.)
To avoid further messiness, just allow mp_switch_track() to be called at
any time. Also make it do what mp_mark_user_track_selection() did, since
the latter requires current_track to be set. (One could probably simply
allow current_track to be set at this point, but it'd interfere with
default track selection anyway and thus would be pointless.)
Fixes#1984.
Wnile it seems quite logical to me that commands use _ as word
separator, while properties use -, I can't really explain the
difference, and it tends to confuse users as well. So always
prefer - as separator for everything.
Using _ still works, and will probably forever. Not doing so would
probably create too much chaos and confusion.
Now it simply changes the options, i.e. what will be requested, instead
of returning M_PROPERTY_UNAVAILABLE.
This is another minor step towards unifying options and properties.
Still a bit weird: it will always return "no" if no file is loaded, and
disregards the option value.
Also replace their implementation with the recently introduced
properties. One significant difference is that audio-channels using OSD
formatting does not print the channel layout. The user can just use the
replacement property instead.
This brings the volume control closer to what is percepted as linear
volume change.
Adjust the --softvol-max default to roughly the old maximum (roughly
doubles the gain).
Now --volume takes an absolute volume, meaning it doesn't depend on
--softvol-max. 0 is still silence, and 100 now always means unchanged
volume. The OSD and the "volume" property are changed accordingly.
Also raise the minimum value of --softvol-max. A value below 100 makes
no sense and breaks the OSD.
Adding a "yes" choice makes the option parser consider this option as a
multi-state flag option, and without argument "yes" is implicitly
selected. "yes" is made an alias for "inf", so it will loop infinitely.
As a negative side effect, the old syntax "-loop inf" does not work
anymore. Since this is ambiguous, the option parser prefers interpreting
the "inf" as filename.
Fixes#1970.
This was called for formal reasons at best. The way it does this is
somewhat dangerous, because if libmpv is unloaded as DLL, this would
attempt to call a dangling function pointer.
(No, we don't want an extra DllMain entrypoint just for win32.)
A rather dumb hack to copy the problematic rectangle textures (mandated
by VDA) into 2D ones.
(This isn't done yet for OpenGL 3.0+. We need to make sure the
performance isn't reduced too much by it.)
The code checking for the type of seeking contained some if else
statements. To improve readability, I decided to refactor those
statements to a switch statement.
Reduce the default tolerance for timestamp jumps from 60 to 15 seconds.
For .ts files, where ts_resets_possible coming from AVFMT_TS_DISCONT is
set, apply a more sophisticated heuristic. It's clear that such a file
wouldn't have a framerate below, say, 23hz. If the demuxer reports a
lower fps, we allow longer PTS jumps.
This should replace long pauses on discontinuities with .ts files with
at most a short stutter.
Of course, all kinds of things could go wrong anyway if the source is
VFR, or FFmpeg's frame rate detection fails in some other way. I haven't
found such a file yet, though.
Commit 10915000 attempted to fix wasting CPU when resyncing and no new
data was actually coming from the demuxer. The fix assumed that at this
point it would have reached the sync point, but since the code attempts
weird incremental decoding, this wasn't actually true. So it broke
seeking in addition to removing the CPU waste.
Try something else. This time, we essentially only wakeup again if
data was read (i.e. audio_decode() returned successfully).
The OSD symbol for seeking to an absolute percentage was always OSD_FFW,
even when it should be OSD_REW. It uses the correct OSD symbols now, by
checking the current position ratio.
Note: The symbol is still incorrectly given when the absolute percentage
is very close to the current position ratio. Fortunately, that's a rare
use case.
This reads the "CUESHEET" tag, and attempts to parse it as .cue data. If
any is found, the cue tracks are added as chapters.
This reuses the parser written for demux_cue.c.
Fixes#1957.
Apparently some A/V receivers do not behave well if "normal" DTS is
passed through using the high bitrate spdif format normally used for
DTS-HD (other receivers are fine with it).
Parse the first packet passed to ad_spdif by decoding it with libavcodec
in order to get the profile. Ignore the --ad-spdif-dtshd if it's not
DTS-HD. (If the codec profile changes midstream, the user is out of
luck. But this is probably an insignificant corner case.)
I thought about parsing the bitstream, but let's not. While it probably
wouldn't be that much effort, we are trying to keep it down on codec
details here - otherwise we could just do our own spdif framing instead
of using libavformat's spdif pseudo-muxer.
Another possibility, using the codec parameters signalled by
libavformat, is disregarded. Our builtin Matroska decoder doesn't do
this, and also we do not want on the demuxer having to decode some
packets in order to retrieve codec params (as libavformat does).
Fixes#1949.
Thsi code path happens during seeking. If video is still being decoded
to get to the first video frame, audio has nothing to do, as it is
synchronized against the first video frame. We only want to wake up if
there's an actual state change.
Fixes#1958.
Only absolute percentage seeking was permitted first. It is now also
possible to seek by relative percentage.
MPSEEK_FACTOR is used as seek_type.
Fixes#1950.
Signed-off-by: wm4 <wm4@nowhere>
It sometimes happens on exit, and it's probably a bad idea. If the
process hangs on exit (possibly due to stupid hardcoded timeouts it's
doing), mpv will also hang now, unfortunately.
It appears some WMs have a problem with out method of setting initial
fullscreen mode. We assume that if the window's _NET_WM_STATE includes
_NET_WM_STATE_FULLSCREEN before mapping the window, the WM will show it
as fullscreen at mapped. EWMH doesn't say anything that this should
work, although one could argue that it's implied.
In any case, since it's not standard behavior without at least some
doubt, it's probably a good idea to try the "old" method as well.
Fortunately, it should be idempotent.
See #1937, #1920.
This is pretty much copy&pasted from Libav commit
a7e0380497306d9723dec8440a4c52e8bf0263cf.
Note that if FFmpeg was not compiled with HEVC DXVA2 support or your
video drivers do not support HEVC, the player will not fallback and
just fail decoding any video. This is because libavcodec appears not
to return an error in this case. The situation is made worse by the
fact that MSYS2 is on an ancient MinGW-w64 release, which does not
have the required headers for HEVC DXVA2 support.
An attempt to get rid of the weird mix of callbacks that take either
struct vo or MPGLCopntext as parameter. This is not perfect, and the
API will probably change a bit until all other code is ported to it.
the main question is how to separate struct vo completely from the
windowing code, which actually needs vo for very little.
In the end, the legacy callbacks will be dropped.
Instead of having separate backends, make use of GLES a flag. This
reduces the number of backends and the resulting annoyances.
Also, nobody cares about using GLES, so there's no backward
compatibility either.
Before this change, Cocoa state was accessed from both the VO and the
Cocoa main thread. This was probably not a good idea. There was some
locking as well as implicit synchronization using the dispatch
mechanism, but it wasn't watertight.
Change this completely. Now Cocoa things are always accessed from the
main thread only. The old mutex falls away, as well as the
vo_cocoa_set_current_context() function, which implicitly used the lock
to coordinate VO accesses. With the new code, the VO thread generally
has to wait for the main thread, while the main thread never waits for
the VO and rarely accesses it. Fortunately, this is rather straight
forward, and most of this is achieved by making vo_cocoa_control() run
on the main thread. The logic of the code does generally not change.
Some aspects are trickier. Apparently we can't access the
NSOpenGLContext from the VO thread, because this object is not thread-
safe. We use some CGLContextObj functions instead, such as for making
the context current and swapping the buffers.
The hardware always decodes to nv12 so using this image format causes less cpu
usage than uyvy (which we are currently using, since Apple examples and other
free software use that). The reduction in cpu usage can add up to quite a bit,
especially for 4k or high fps video.
This needs an accompaning commit in libavcodec.
Arch linux is about to update to lua 5.3.x, but lua 5.2.x will be
provided by package lua52, which contains pkg-config file lua52.pc.
Signed-off-by: wm4 <wm4@nowhere>
Some code always calls vo_event(), even with event==0, which leads to
immediate wakeup, which in turn causes the function to be called again.
This would burn CPU, which was especially noticeable when paused.
Until now, we just blocked SIGPIPE globally. Fix it properly to get away
from it.
MSG_NOSIGNAL should be widely available and is part of the POSIX.1-2008
standard. But it's not available on OSX, because Apple is both evil and
retarded. Thus we continue to ignore the problem on such shitty systems.
Interrupt video timing. This means the Cocoa event loop does not have
to up to 2 video frame durations until redrawing the frame finally has
finished.
We abuse the VO event flags for this. Eventually this should use
wait_vo() or so in the video timing wait function, but for now the
interaction this would require with the code of other VOs/backends
would cause too much of a mess.
Instead of requiring a complicated mechanism to share the entire OpenGL
and renderer state between VO and Cocoa thread just to do the redrawing
during live-resize on the Cocoa thread, let the Cocoa thread wait on the
VO thread. This wil allow some major simplifications and cleanups in the
future.
One problem with this is that it can enter a deadlock whenever the VO
tries to sync with the Cocoa thread. To deal with this, the Cocoa thread
waits with a timeout. This can probably be improved later, though in
general this situation can always happen, unless the Cocoa thread waits
in a reentrant way.
Some other details aren't completely clean either. For example,
pending_events should be accessed atomically. This will also be fixed
later.
Will be used to make video waiting interruptible with Cocoa (see the
following commit).
One worry was that this could cause hangs if the system clock jumps
backwards. Normally we don't support such behavior, because it's
almost impossible to handle it reasonably. E.g. we would have to
change the default clock type for condition variables, which in turn
would require a custom function for creating condition variables,
or so. If the OS even supports different clocks.
But it turns out that this is no issue, because other events seem
to wakeup the wait call anyway, and mpv internal absolute times use
a monotonic clock.
This uses the OpenGL frame interpolation code, which before could be
used by vo_opengl only.
Some effort was made to make it behave like vo_opengl, for the better or
the worse. As a consequence, there is a minor duplication of code and
mechanism. Hopefully this can all be wiped as soon as the VO frame
queue/timing mechanism is cleaned up.
This also attempts to use mpv_opengl_cb_report_flip() (as called by the
API user) to determine the vsync interval. This might need refinement as
well.
(In general, we simply expect the API user to work in vsync-blocking
manner.)
(I have no idea why there are different modes.)
Instead of risking to drop frames too early, give it some margin. Since
there are situations this could deadlock, wait with a timeout. This can
happen if e.g. the API user is refusing to render anything, or if
uninitialization is happening.
There is not much of a reason to have these wrappers around. Use POSIX
standard functions directly, and use a separate utility function to take
care of the timespec calculations. (Course POSIX for using this weird
format for time values.)
As usual, we prefer plain C11 names and semantics, and have to emulate
them if C11 atomics are not available.
For the non-atomic fallback (which is just there to make code compile in
situations the atomic property is not overly important), we require a
gross hack to make the generic macros work without using compiler-
specific extensions.
OpenSSL and GnuTLS are still causing this problem (although FFmpeg could
be blamed as well - but not really). In particular, it was happening to
libmpv users and in cases the pseudo-gui profile is used. This was
because all signal handling is in the terminal code, so if terminal is
disabled, it won't be set. This was obviously a questionable shortcut.
Avoid further problems by always blocking the signal. This is done even
for libmpv, despite our policy of not messing with global state.
Explicitly document this in the libmpv docs. It turns out that a version
bump to 1.17 was forgotten for the addition of MPV_FORMAT_BYTE_ARRAY, so
document that change as part of 1.16.
It's useless, and creates a bogus warning in subprocess-posix.c.
Since I don't know which compilers might have it by default, just change
it to -Wno-redundant-decls.
mp_find_config_file() will print the filename lookup and its result in
verbose mode. This is wanted, but gets inconvenient when it is done for
every playlist entry (for resuming).
Lookup the watch_later subdir only once and cache the result instead.
This drops the logic for loading the resume file from other locations,
which should generally be unnecessary, though might lead to confusion if
the user has mixed old and new config paths (which the user shouldn't).
Also add a mp_find_user_config_file() function for a more
straightforward and reliable way to get actual local configpaths,
instead of possibly global and unwritable locations.
Also, for symmetry, check the resume option in mp_load_playback_resume()
just like mp_check_playlist_resume() does.
Share most of the implementation of config file lookup between
mp_find_all_config_files() and mp_find_config_file().
Also move the check for config path overrides to mp_get_platform_path()
directly. From the point of view of config file lookup, this is a bit
stupid, but on the other hand increases consistency, as user path
resolution exposes the mp_get_platform_path() functionality directly to
the user.
Now among other things panscan can be changed during playback.
Unfortunately, it flickers. The issue is that reconfig() clears the
framebuffer. Removing the clearing shows that the "unused" parts of
the picture are not cleared - even though OSD could render there. As
such, this is a separate issue.
When running with --panscan=1, this could crash - because the current
frame was reduced in size each time the image was redrawn, which would
result in a failed assertion the second time it's drawn.
This creates the window before the first file is loaded. This was
requested a bunch of times, but on the other hand a change to make this
behavior the default was reverted some time ago, because other users
hated it.
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.)
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.
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.
The client API (libmpv) and encoding (--o) have slightly different
defaults from the command line player. Instead of doing a bunch of calls
to set the options explicitly, use profiles. This is simpler and has the
advantage that they can be listed on command line (instead of possibly
forcing the user to find and read the code to know all the details).
Sometimes, ALSA will return channel layouts with padded channels (NA
speakers). Use them instead of failing.
This still includes the old "braindeath" code to retry with a layout
without NA channels. This might be helpful for performance, and also the
padded channel layout string looks confusing.
To be fair, I have not encountered a case yet which would really need
this, and for which the old "braindeath" code did not fix it.
volatile barely means anything.
The polling is kind of bad too, but relatively harmless as device
opening/closing is a rare event, and the format change is not expected
to take long.
Remove the pointless talloc call too (must have been a leftover
from previous refactoring).
No reason to keep them separate. It's an artifact from the old
ao_coreaudio.c, which kept usage of two different APIs in the same file.
Removes a forward reference too.
This should fix some crashes due to dangling pointers.
The problem was that with_cocoa_lock_on_main_thread() is asynchronous.
It will not wait until it is finished. In the uninit case, this means
the VO could be deallocated and destroyed while cocoa was still running
uninit code.
So simply wait until it is done by using dispatch_sync(). There were
concerns that this could introduce a deadlock by the main thread trying
to wait for something on the VO thread. But from what I can see, this
never happens, and even if it does, it would crash anyway since the VO
is already gone.
One remaining worry is the video_resize_redraw_callback. From what I can
see, it still can mess things up, and will need a more elaborate fix.
Instead of trying to use af_format_conversion_score() (which tries to be
all kinds of clever), just compare the raw bits as a quality measure. Do
this because otherwise, weird formats like padded 24 bit formats will be
excluded, even though they might be the highest precision formats for
some hardware.
This means that for now, the user would have to check whether the format
is usable at all before calling ca_asbd_is_better(). But since this is
currently only used for ao_coreaudio.c and for the physical format, it
doesn't matter.
If coreaudio-exclusive should get PCM support, the best would be to
revert this change, and to add support for 24 bit formats directly.
Some time ago, a mechanism was added for automatically removing PCM-only
filters if the input format is spdif.
This could cause an infinite loop if the AO did not support spdif, but
was falling back to some PCM format. Then this code tried to remove the
last filter, which is a dummy filter for receiving and queuing filter
output. af_remove() simply fails gracefully in this case, so this
happens over and over again.
Fix by explicitly checking whether the filter to remove is a dummy
filter. (af_remove() also fails only if the dummy filters are attempted
to be removed - checking this directly is simpler.)
Move all of the channel map retrieval/negotiation code to a separate
file. This will (probably) be helpful when extending
ao_coreaudio_exclusive.c.
Nothing else changes, other than some minor cosmetics and renaming,
and changing some details for decoupling it from the ao_coreaudio.c
internals.
It appears this is the reason coreaudio-exclusive does not work without
explicitly specifying a device, even if the default device maps to
something passthrough-capable.
Instead of always picking a somehow better format over the previous one,
select a format that is equal to or better the requested format, but is
also reasonably close.
Drop the mFormatID comparison - checking the sample format handles this
already.
Make sure to exclude channel counts that can't be used.
If for example the physical format is set to stereo, the reported
multichannel layout will actually be stereo. It fixes itself only after
the physical format is changed.
Reduces (but likely does not remove) the danger of rounding intermediate
values down to 8 bit. This is important for cscale, or any other
processing that might store raw YUV values in framebuffers.
Fixes#1918.
ao_coreaudio uses AudioUnit - the OSX software mixer. In theory, it
supports multichannel audio just fine. But in practice, this might be
disabled by default, and the user is supposed to select a multichannel
base format in the "Audio MIDI Setup" utility.
This option attempts to change this setting automatically. Some possible
disadvantages and caveats are listed in the manpage additions. It is off
by default, since changing this might be rather bad behavior for a
normal application.
They are not really interesting. At least one user complained about the
noise resulting from use with shell scripts, which connect and
disconnect immediately.
If for example the audio settings are set to 5.1 output, but the
hardware does 8 channels natively (HDMI), the reported channel
layout will have 2 dummy channels. To avoid falling back to stereo,
we have to write audio in this format to the device.
Some audio APIs explicitly require you to add dummy channels. These are
not rendered, and only exist for the sake of the audio API or hardware
strangeness. At least ALSA, Sndio, and CoreAudio seem to have them.
This commit is preparation for using them with ao_coreaudio.
The result is a bit messy. libavresample/libswresample don't have good
API for this; avresample_set_channel_mapping() is pretty useless.
Although in theory you can use it to add and remove channels, you
can't set the channel counts. So we do the ordering ourselves by making
sure the audio data is planar, and by swapping the plane pointers. This
requires lots of messiness to get the conversions in place. Also, the
input reordering is still done with the "old" method, and doesn't
support padded channels - hopefully this will never be needed. (I tried
to come up with cleaner solutions, but compared to my other attempts,
the final commit is not that bad.)
ca_label_to_mp_speaker_id() checked whether the last entry was >= 0, but
actually this condition was never true, and MP_SPEAKER_ID_UNKNOWN0 is
not negative.
This was a mistake, it should definitely be using the device namespace
rather than the file namespace. As it says in the docs, all pipe names
must start with \\.\pipe\
Path expansion (like "~/dir/" in config file) was used inconsistently,
so the cache directory wasn't always created correctly. Fix this by
moving the path expansion from load_file() to its callers.
Since commit 7381db60, strings like "~desktop/" were expanded as
platform-specific paths by mpv. Apparently this similarity to standard
Unix shell expansion caused confusion, so change it to "~~desktop/". The
shell doesn't expand this, so it should be better.
And split the Cocoa and Unix cases. Simplify the Cocoa case slightly by
calling mpv_main directly, instead of passing a function pointer. Also
add a comment explaining why Cocoa needs a special case at all.
This unbreaks compiling command line player and libmpv at the same
time. The problem was that doing so silently disabled the OSX
application thing - but the command line player can not use the
vo_opengl Cocoa backend without it.
The OSX application code is basically dead in libmpv, but it's not
that much code anyway.
If you want a mpv binary that does not create an OSX application
singleton (and creates a menu etc.), you must disable cocoa
completely, as cocoa can't be used anyway in this case.
This now stores caches for multiple ICC profiles, potentially all the
user has ever used. The big use case for this is for users with multiple
monitors. The old logic would mandate recomputing the LUT and discarding
the cache whenever dragging mpv from one screen to another.
This also avoids having to save and check the ICC profile itself, since
the file name already uniquely determines it.
This will essentially make screenshot-tag-colorspace also affect the
"screenshot window" command, where possible.
Unfortunately, it's completely incompatible with icc-profile, due to API
limitations of ffmpeg (we can only give it an enum of well-known
primaries, rather than an actual ICC profile or primaries).
This should take care of the endless complaints about the default
location for screenshots (and will of course create new ones).
If the screenshot-template is set to an absolute path, the directory
won't be used. So this should be reasonably compatible.
So that the user realizes where they come from, or can find them at all.
This was a common complaint, and this is the most lazy solution. Better
suggestions for a default template are welcome.
win32 has a special function for this.
I'm not sure about OSX - it seems ~/Desktop can be hardcoded, and the
OSX GUI actually localizes the _displayed_ path in its UI.
For Unix, there is not much to be done, or is there.
Somewhat less ifdeffery, higher flexibility. Now there are 3 separate
config file resolvers for 3 platforms (unix, win, osx), and they can
still interact with each other somewhat. For example, OSX for now uses
most of Unix, but adds the OSX bundle path.
This can be extended to resolve very specific platform paths, such as
location of the desktop.
Most of the Unix specific code moves to path-unix.c.
The behavior should be the same - if not, it is likely a bug.
(Not sure why it worked without this when I tested the previous
changes.)
Untested, but should be fine. This is equivalent what is done on e.g.
panscan changes.
I think this used to be quite important, because the ancient VfW support
in MPlayer used to output flipped frames. This code has been dead in mpv
for quite some time (because VfW decoders were removed, and the --flip
option was dropped too), so get rid of it.
Currently, the wayland backend needs extra work to avoid drawing more
often than the wayland frame callback allows. (This is not ideal, but
will be fixed at a later time.)
Unify this with the start_frame callback added for cocoa. Some details
change for the better. For example, if a frame is dropped, and a redraw
is done afterwards, the actually correct frame is redrawn, instead
whatever was in the textures from before the dropped frame.
With --idle --force-window, or when started from the bundle, the cocoa
code dropped the first frame. This resulted in a black frame on start
sometimes.
The reason was that the live resizing/redrawing code was invoked, which
simply set skip_swap_buffer to false, blocking redrawing whatever was
going to be rendered next. Normally this is done so that the following
works:
1. vo_opengl draw a frame, releases GL lock
2. live resizing kicks in, redraw the frame
3. vo_opengl wants to call SwapBuffers, drawing a stale buffer
overwritten by the live resizing code
This is solved by setting skip_swap_buffer in 2., and querying it in 3.
Fix this by resetting the skip_swap_buffer at a known good point: when
vo_opengl starts drawing a new frame.
The start_frame function returns bool, so that it can be merged with
is_active in a following commit.
Commit f1746741de changed the drop
logic to have more slack (drop more frames but less frequent) to prevent
drops due to timing jitter when the clip and screen have similar rates.
However, if the clip has higher rate than the screen (or just higher
playback rate), then that policy hurts smoothness since these "chunked
drops" look worse than one frame drop at a time.
This patch restores the old drop logic when the playback frame rate is
higher than ~5% above the screen refresh rate, and solves this issue.
Fixes#1897
Also factor the display size initialization into a separate function.
For some reason this seems to work, although setting the background
color using this 1x1 pixel bitmap does not work. I blame the RPI
beign a terrible piece of hardware with even worse drivers.
This should for now be equivalent; it's merely more explicit and will
be required if we add PCM support.
Note that the property listeners actually tell you what property
exactly changed, but resolving the current listener mess would be too
hard. So check for changes manually.
Useful with some of the following commits.
ca_fill_asbd() should behave exactly as before.
Instead of actually implementing the inverse function of ca_fill_asbd(),
just loop over the (small) list of mpv functions and check if any mpv
equivalent to a given ASBD exists.
kAudioFormatFlagIsSignedInteger implicates that it's only used with
integer formats. The mpv internal flag on the other hand signals the
presence of a sign, and this is set on float formats.
Until now, this probably worked fine, because at least AudioUnit is
ignoring the uncorrect flag.
It's weird that this basically adjusts the contrast between luma and
chroma, and not blackness.
This is more in line with the behavior of libswscale, the vdpau
"procamp" (which mpv doesn't use), and Xv.
This code does not know whether the stream supports reconnecting until
STREAM_CTRL_RECONNECT is called. So the message should be printed after
it. To avoid that reconnects that succeed on the first try go unnoticed,
print a warning on success.
Right now, the default behavior is to pick the numerically lowest screen
ID that overlaps the window in any way - but this means that mpv will
decide to pick an ICC profile in a pretty arbitrary way even if the
window only overlaps another screen by a single pixel.
The new behavior is to query it based on the center of the window
instead.
In the most simple case, this prevents the track ID from changing. One
disadvantage is that if the file fails loading, the track is gone for
good and would have to be re-added explicitly by the user.
Now the rescan_external_files command will by default reselect the audio
and subtitle streams. This should be more intuitive.
Client API users and Lua scripts might break, but can be fixed in a
backward-compatible way by setting the mode explicitly.
Should help with debugging, and might be slightly more userfriendly.
Note that this is called manually in multiple entry-points, instead of
the functions doing the actual work (like mp_remove_track()). This is
done so that exiting the player or calling the sub_reload command won't
print redundant in-between states.
During seeking, and there is momemtarily no new data available yet, the
player will display the seek target as current time. Clamp this time to
the known time range as implied by the start time and the duration of
the file.
This improves behavior especially when seeking in audio files, for which
this for some reason triggers rather often. There were some users
complaining about this.
This makes behavior worse for files with timestamp resets, or
incorrectly reported duration. (The latter is relatively common,
e.g. libavformat shortcomings, or incomplete files.)
We always want to prefer upmix to downmix, as long as it makes sense.
Even if the upmix is not "perfect" (not just adding channels), we want
to prefer the upmix.
Cleanup for commit d3c7fd9d.
We escape only characters below 32, plus " and \. UTF-8 should be apssed
through verbatim. Since char can be signed (and usually is), the check
broke and happened to escape UTF-8 encoded bytes too. This broke UTF-8
completely.
Note that we don't check for broken or invalid UTF-8, such as described
both in the client API and IPC docs.
Fixes#1874.
This will change the format option to "bestaudio/best" instead of
passing the "-x" argument to yt-dl.
Prevents the video still being downloaded in the new mpv versions where
the yt-dl format is set to "best" by default.
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.)
This could make the player crash on exit if the "sub_reload" command was
used successfully. the reason was that the mpctx->sources array could
have dangling pointers to the unloaded demuxers.
Also fix a memory leak by actually always freeing the per-stream
subtitle decoders (which are a hack to make ordered chapters behave
better).
If the --ytdl-format option is not used, force the "best" format. Do
this because youtube-dl is going to change its default format to one
that will trigger the (partially broken) DASH support in our own code.
Fixes#1867.
vo_opengl (or gl_hwdec_vdpau.c to be specific) calls
mp_vdpau_mixer_render() with video_rect=NULL, which means to use the
full surface. This is incorrect if the surface is actually cropped, as
it can happen with h264. In this case, it was rendering the parts
outside of the image.
Fix it by making this case use the cropped size instead.
Alternative fix for PR #1863.
Loaded 100 of 406 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.