If video output and VO don't support the same format, a conversion
filter needs to be insert. Since a VO can support multiple formats, and
the filter chain also can deal with multiple formats, you basically have
to pick from a huge matrix of possible conversions.
The old MPlayer code had a quite naive algorithm: it first checked
whether any conversion from the list of preferred conversions matched,
and if not, it was falling back on checking a hardcoded list of output
formats (more or less sorted by quality). This had some unintended side-
effects, like not using obvious "replacement" formats, selecting the
wrong colorspace, selecting a bit depth that is too high or too low, and
more.
Use avcodec_find_best_pix_fmt_of_list() provided by FFmpeg instead. This
function was made for this purpose, and should select the "best" format.
Libav provides a similar function, but with a different name - there is
a function with the same name in FFmpeg, but it has different semantics
(I'm not sure if Libav or FFmpeg fucked up here).
This also removes handling of VFCAP_CSP_SUPPORTED vs.
VFCAP_CSP_SUPPORTED_BY_HW, which has no meaning anymore, except possibly
for filter chains with multiple scale filters.
Fixes#1494.
In my opinion, libavformat should be doing this. But a patch handling a
very safe case rejected, so I suppose we have to do it manually. (This
patch was only escaping spaces, which can never work because they break
the basic syntax of the HTTP protocol.)
This commit attempts to do 2 things:
- Try to guess whether libavformat will use the URL for http. This is
not always trivial, because some protocols will recursively pass part
of the user URL to http in some way.
- Try to fix invalid URLs. We fix only the simplest case: only
characters that are never valid are escaped. This excludes invalid
escape codes, which happen with freestanding '%' characters.
Fixes#1495.
Sigh...
The C locale system is incredibly shitty, and if used, breaks basic
string functions. The locale can change the decimal mark from "." to
",", which affects conversion between floats and strings: snprintf() and
strtod() respect the locale decimal mark, and change behavior. (What's
even better, the behavior of these functions can change asynchronously,
if setlocale() is called after threads were started.)
So just check the locale in the client API, and refuse to work if it's
wrong. This also makes the lib print to stderr, which I consider the
lesser evil in this specific situation.
Handles mismatching libavfilter/libavdevice and libavcodec slightly
better.
libavfilter and libavdevice are optional, and thus are checked
separately and at a later point of the build. But if a user system has
at least 2 FFmpeg installations, and one of them lacks libavfilter or
libavdevice, the build script will pick up the libavfilter/libavdevice
package of the "other" FFmpeg installation. The moment waf picks these
up, all include paths will start pointing at the "wrong" FFmpeg, and the
FFmpeg API checks done earlier might be wrong too, leading to obscure
and hard to explain compilation failures.
Just moving the libavfilter/libavdevice checks before the FFmpeg API
checks somewhat deals with this issue. Certainly not a proper solution,
but since the change is harmless, and there is no proper solution, and
the change doesn't actually add anything new, why not.
This function is always available, which is reflected by the fact that
the configure check doesn't actually bother to check for its existence.
Instead, MinGW and Cygwin imply it. The check was probably "needed" when
the priority code was still in a separate source file.
Remove the check, and use _WIN32 for testing for the win32 API (in a
bunch of other places too).
In general, you need to check errno when using strtol(), but as far as I
know, strtol() won't reset errno on success. This has to be done
manually. The code could have failed sporadically if strtol() succeeded,
and errno was already set to one of the checked values.
(This strtol() still isn't fully error checked, but I don't know if it's
intentional, e.g. for parsing a numeric prefix only.)
Before this commit, ao_null was used as last fallback. This doesn't make
too much sense. Why would you decode audio just to discard it? Let audio
initialization fail instead. This also handles the weird but possible
corner-case that ao_null might fail initializing, in which case e.g.
ao_pcm could be autoselected. (This happened once, and had to be fixed
manually.)
This removes the slightly duplicated code for picking the required AO
driver if --audio-device forces one. Now --audio-device reuses the same
code as --ao for this.
As a consequence, ao_alloc_pb() and ao_create() can be merged into
ao_init(). Although the ao_init() argument list, which is already pretty
big, grows by one, it's better than having all these similar sounding
functions around.
Actually, I just wanted to do the change the following commit will do,
but I found this code was more of a mess than it had to be.
libdvdnav is garbage. Seeking by time is incredibly inexact, which is in
part due to the fact that it does not use the DVD seek tables. Instead,
it assumes CBR for certain ranges within the DVD, which makes especially
small seeks unreliable.
I have no good fix for this, other than hacking libdvdnav (I'd rather
prefer to remove mpv DVD support completely than doing this). So here's
a shitty hack that tries to workaround these problems. A basic
observation is that seeking in VLC seems to work quite well; however it
seems to be based on seeking by blocks (unless there is a subtle "trick"
I didn't see in the source code). mpv usually seeks by timestamps, so
this is not an option for us. However, we can pretend we are doing this
in the DVD layer.
The previous commit added a way to pass through relative seeks. This
commit uses the relative seek. STREAM_CTRL_SEEK_TO_TIME is backwards
compatible (there's still dvdread and bluray), so most code is about
extracing the relative seek information and turning it into a block
seek.
(Another way would have been using SEEK_FACTOR stuff, but that would
probably make for a less reliable way to handle this situation.)
Additionally, if a hr-seek is done, add an offset by 10 seconds. As long
as the error done by libdvdnav is not worse, this should help with hr-
seeks - although it makes them much slower.
Pass through the seek flags to the stream layer. The STREAM_CTRL
semantics become a bit awkward, but that's still the least awkward
part about optical disc media.
Make demux_disc.c request relative seeks. Now the player will use
relative seeks if the user sends relative seek commands, and the
demuxer announces it wants these by setting rel_seeks to true. This
change probably changes seek behavior for dvd, dvdnav, bluray, cdda,
and possibly makes seeking useless if the demuxer-cache is set to
a high value.
Will be used in the next commit. (Split to make reverting the next
commit easier.)
Before this, we merely printed a message to the terminal. Now the API
user can determine this properly. This might be important for API users
which somehow maintain complex state, which all has to be invalidated if
(state-changing) events are missing due to an overflow.
This also forces the client API user to empty the event queue, which is
good, because otherwise the event queue would reach the "filled up"
state immediately again due to further asynchronous events being added
to the queue.
Also add some minor improvements to mpv_wait_event() documentation, and
some other minor cosmetic changes.
We still need to send the VO a duration in these cases. Disabling
framedrop has logically absolutely nothing to do with these cases; it
was overlooked in commit 918b06c4.
So we always send the frame duration (or a guess for it), and check
whether framedropping is actually enabled in the VO code. (It would
be cleaner to send framedrop as a flag, but I don't care about that
right now.)
This complains within dvb_strtok_r() that savePtr is uninitialized.
There doesn't seem to be any code path where this can happen though, so
it's probably a false positive. Silence it anyway.
Broke operation with GLSL.
Since 1D texture usage was apparently (and mysteriously) good for speed,
it might be added back, but it's unknown how to do so in a clean way.
The "ontop" and "border" properties already used a common
mp_property_vo_flag() function, and the corresponding VOCTRLs used the
same conventions. "fullscreen" is pretty similar, but was handled
slightly similar. Change how VOCTRL_FULLSCREEN behaves, and use the same
helper function for "fullscreen" as the other flags.
Fixes#1472.
(Maybe these options should have been named --autofit-max and
--autofit-min, but since --autofit-larger already exists, use
--autofit-smaller for symmetry.)
Normally the player doesn't read from unselected streams, so this should
be a no-op. But unfortunately, some broken files can severely confuse
the player, and assign the same demuxer stream to multiple front-end
tracks. Then selecting one of the tracks would deselect the other track,
with the end result that the demuxer stream for the selected track is
deselected. This could happen with mkv files that use the same track
number (which is of course broken). timeline_set_part() sets the tracks
using demuxer_stream_by_demuxer_id(), using the broken non-unique IDs.
The observable effect was that the player never quit, because
demux_read_packet_async() told the caller to wait some longer for new
packets. Fix by returning EOF instead.
Fixes#1481.
This is for the ordered chapters case only. In theory this could have
resulted in initial audio, video or subs missing, although it didn't
happen in practice (because no streams were selected, thus the demuxer
thread didn't actually try to read anything). It's still better to make
this explicit.
Also, timeline_set_part() can be private to loadfile.c.
The last video frame is another case that has a separate code path,
although it's pretty similar to the one in commit 73e5aa87. Fix this
in a different way, which also takes care of the last frame case,
although without context the code becomes slightly more tricky.
As further cleanup, move the decision about framedropping itself to
the same place, so the check in vo.c becomes much simpler. The check
for the vo->driver->encode flag, which is remvoed completely, was
redundant too.
Fixes#1480.
If the program name isn't quoted and the .exe it refers to isn't found,
CreateProcess will add the program arguments to the program name and
continue searching, so for "program arg1 arg2", CreateProcess would try
"program.exe", "program arg1.exe", then "program arg1 arg2.exe". This
behaviour is weird and not really desirable, so prevent it by always
quoting the program name.
When quoting argv[0], escape sequences shouldn't be used. msvcrt, .NET
and CommandLineToArgvW all treat argv[0] literally and end it on the
trailing quote, without processing escape sequences.
The "\\" escape was rendered as "\" on the website. I'm hoping quoting
this in ``...`` will render it correctly.
Also add an example for show_text, which awkwardly does not require
escaping the "\".
If the video format changes (e.g. different frame size), a special code
path is entered to wait until the currently displayed frame is done.
Otherwise, the frame before the change would be destroyed by the
vo_reconfig() call.
This code path didn't respect --untimed; correct this.
Fixes#1475.
__STRICT_ANSI__ disables functions and definitions that aren't in ANSI
C. Unfortunately this includes j1(), which is used by the new
ewa_lanczos code. Cygwin's CFLAGS already unset __STRICT_ANSI__, but it
should be unset for both Cygwin and MinGW.
After finding out more about how video mastering is done in the real
world it dawned upon me why the "hack" we figured out in #534 looks so
much better.
Since mastering studios have historically been using only CRTs, the
practice adopted for backwards compatibility was to simulate CRT
responses even on modern digital monitors, a practice so ubiquitous that
the ITU-R formalized it in R-Rec BT.1886 to be precisely gamma 2.40.
As such, we finally have enough proof to get rid of the option
altogether and just always do that.
The value 1.961 is a rounded version of my experimentally obtained
approximation of the BT.709 curve, which resulted in a value of around
1.9610336. This is the closest average match to the source brightness
while preserving the nonlinear response of the BT.1886 ideal monitor.
For playback in dark environments, it's expected that the gamma shift
should be reproduced by a user controlled setting, up to a maximum of
1.224 (2.4/1.961) for a pitch black environment.
More information:
https://developer.apple.com/library/mac/technotes/tn2257/_index.html
This was forgotten when the option was implemented, and makes this
option work as advertised.
Fixes#1473 (though the default behavior is probably still stupid).
Adds about 7 lines of boilerplate per filter. This could be avoided by
providing a different entrypoint (something like af->filter_inplace),
which would basically mirror the old interface exactly for this kind of
filter. But I feel like it would just be a hack to support all those
old, useless filters better. (The ideal solution would be using a
language that can do closures to provide a compat. wrapper, but
whatever.)
af_bs2b has terribly repetitious code for setting up filter functions
for each format (most of them useless, in addition to bs2b being
useless), so I did something terrible with macros.
af_sinesuppress had commented code for float filtering (maybe it was
broken; it has been commented every since it was added in 2006). Remove
this code.
Just to make sure all filters get the correct format. Together wih the
check in af_add_output_frame(), this asserts that
af->prev->fmt_out == af->fmt_in
This also requires setting the "in" pseudo-filter (s->first) formats
correctly. Before this commit, the fmt_in/fmt_out fields weren't used
for this filter.
Support for taking screenshots when doing hardware decoding needs to be
added later.
This takes the last image queued to the VO, which is logically the image
the player thinks is on screen (so e.g. subtitles will match).
forget_frames() does not clear this, because seeking does not remove the
current image from the screen (until the next one is drawn).