Until now, mp_msg output always went to the terminal. There was no way
to grab the stream of output messages. But this will be needed by
various future changes: Lua scripts, slave mode, client library...
This commit allows registering a ring buffer. A callback would be more
straight-forward, but since msg.c sits at the bottom of the lock
hierarchy (it's used by virtually everything), this would probably be a
nightmare. A ring buffer will be simpler and more predictable in the
long run.
We allocate new memory for each ringbuffer entry, which is probably a
bit expensive. We could try to be clever and somehow pack the data
directly into the buffer, but I felt like this wouldn't be worth the
complexity. You'd have to copy the data a bunch of times anyway. I'm
hoping that we can get away with using the ringbuffer mechanism for
low frequency important messages only (and not e.g. for high volume
debug messages), so the cost doesn't matter that much.
A ringbuffer has a simple, single log level. I considered allowing
--msglevel style per-prefix configuration for each ringbuffer, but
that would have been pretty complicated to implement, and wouldn't
have been that useful either.
This makes
mp_msg(x, y, "a\nb\n")
behave the same as
mp_msg(x, y, "a\n")
mp_msg(x, y, "b\n")
which is probably what one would expect. Before this commit, the "b"
line didn't have a prefix when using ths single mp_msg call.
The terminal OSD code includes the handling of the terminal status line,
showing player OSD messages on the terminal, and showing subtitles on
terminal (the latter two only if there is no video window, or if
terminal OSD is forced).
This didn't handle some corner cases correctly. For example, showing an
OSD message on the terminal always cleared the previous line, even if
the line was an important message (or even just the command prompt, if
most other messages were silenced).
Attempt to handle this correctly by keeping track of how many lines the
terminal OSD currently consists of. Since there could be race conditions
with other messages being printed, implement this in msg.c. Now msg.c
expects that MSGL_STATUS messages rewrite the status line, so the caller
is forced to use a single mp_msg() call to set the status line.
Instead of littering print_status() all over the place, update the
status only once per playloop iteration in update_osd_msg(). In audio-
only mode, the status line might now be a little bit off, but it's
perhaps ok.
Print the status line only if it has changed, or if another message was
printed. This might help with extremely slow terminals, although in
audio+video mode, it'll still be updated very often (A-V sync display
changes on every frame).
Instead of hardcoding the terminal sequences, use
terminfo/termcap to get the sequences. Remove the --term-osd-esc option,
which allowed to override the hardcoded escapes - it's useless now.
The fallback for terminals with no escape sequences for moving the
cursor and clearing a line is removed. This somewhat breaks status line
display on these terminals, including the MS Windows console: instead of
querying the terminal size and clearing the line manually by padding the
output with spaces, the line is simply not cleared. I don't expect this
to be a problem on UNIX, and on MS Windows we could emulate escape
sequences. Note that terminal OSD (other than the status line) was
broken anyway on these terminals.
In osd.c, the function get_term_width() is not used anymore, so remove
it. To remind us that the MS Windows console apparently adds a line
break when writint the last column, adjust screen_width in terminal-
win.c accordingly.
This code is shared between input.conf parser and option parser. Until
now, the performance didn't really matter. But I want to use this code
for JSON parsing too, and since JSON will have to be parsed a lot, it
should probably try to avoid realloc'ing too much.
This commit moves parsing of C-style escaped strings into a common
function, and allows using it in a way realloc can be completely
avoided, if the already allocated buffer is large enough.
I find this annoying. It's the reason common/version.c exists at all.
options.c did this for the user agent, which contains the version
number. Because not including version.h means you can't build the user
agent and use it in mp_default_opts anymore, do something rather awkward
in main.c to initialize the default user agent.
The TV code pretends to be part of stream/, but it's actually demuxer
code too. The audio_in code is shared between the TV code and
stream_radio.c, so stream_radio.c needs a small hack until stream.c is
converted.
This is pretty nasty, because FFmpeg/Libav is yet another library with a
global message callback. We do something with mutexes trying to get it
done, but of course we can't actually solve this problem. If more than
one library in a process use FFmpeg/Libav, only one of them will get log
messages.
Always pass around mp_log contexts in the option parser code. This of
course affects all users of this API as well.
In stream.c, pass a mp_null_log, because we can't do it properly yet.
This will be fixed later.
The mp_select_decoders() function doesn't have a log context (and I
don't want to give it one), so get rid of the mp_msg error message by
enhancing the semantics such that the syntax error is replaced by a new
feature. Now doing "--ad=something" will enable all decoders in the
"something" module, same as "--ad=something:*". Pretty useless, but gets
rid of the annoyance.
I don't know under which circumstances this can error (other than a
broken format string). It seems it won't return an error code on I/O
errors, so maybe broken format strings are the only case. Either way,
don't continue if an error is returned.
We have certain race conditions coming from doing multiple fprintf()
calls (setting up colors etc.). I'm not sure whether it would be worth
changing to code such that we do only one fprintf() call (and assume
this synchronizes access), but considering it would be hard to do
(Windows compatibility, ...), and that stdio uses per FILE locks anyway,
this is simpler and probably not less efficient. Also, there's no
problem handling the weird statusline special case this way.
Note that mp_msg_* calls which are silent won't acquire the lock, and
acquiring the lock happens on actual output only (which is slow and
serialized anyway).
Basically, reimplement --msglevel. Instead of making the new msg code
use the legacy code, make the legacy code use the reimplemented
functionality.
The handling of the deprecated --identify switch changes. It temporarily
stops working; this will be fixed in later commits.
The actual sub-options syntax (like --msglevel-vo=...) goes away, but I
bet nobody knew about this or used this anyway.
Instead of making msg.c an ifdef hell for unix vs. windows code, move
the code to separate functions defined in terminal-unix.c/terminal-
win.c.
Drop the code that selects random colors for --msgmodule prefixes.
This comes with a real change in behavior: now the signal handler is set
only when the terminal input code is active (e.g. not with
--no-consolecontrols), but this should be ok.
In my opinion, config.h inclusions should be kept to a minimum. MPlayer
code really liked including config.h everywhere, though, even in often
used header files. Try to reduce this.