mirror of https://github.com/mpv-player/mpv
208 lines
9.6 KiB
Plaintext
208 lines
9.6 KiB
Plaintext
NOTE: DOCS/OUTDATED-tech/* may contain more detailed information, but most of it
|
|
is possibly or definitely outdated. This file intends to give a big
|
|
picture of how mplayer/mpv is structured.
|
|
|
|
core/mplayer.c:
|
|
This contains the main play loop, anything related to mplayer and playback
|
|
related initializations. It also contains the main function. Generally, it
|
|
accesses all other subsystems, initializes them, and pushes data between
|
|
them during playback.
|
|
|
|
The structure is as follows (as of commit e13c05366557cb):
|
|
* main():
|
|
* basic initializations (e.g. init_libav() and more)
|
|
* pre-parse command line (verbosity level, config file locations)
|
|
* load config files (parse_cfgfiles())
|
|
* parse command line, add files from the command line to playlist
|
|
(m_config_parse_mp_command_line())
|
|
* check help options etc. (call handle_help_options()), possibly exit
|
|
* call play_files() function that works down the playlist:
|
|
* run idle loop (idle_loop()), until there are files in the
|
|
playlist or an exit command was given (slave mode only)
|
|
* actually load and play a file in play_current_file():
|
|
* run all the dozens of functions to load the file and
|
|
initialize playback
|
|
* run a small loop that does normal playback, until the file is
|
|
done or a slave command terminates playback
|
|
(on each iteration, run_playloop() is called, which is rather
|
|
big and complicated - it decodes some audio and video on
|
|
each frame, waits for input, etc.)
|
|
* uninitialize playback
|
|
* determine next entry on the playlist to play
|
|
* loop, or exit if no next file or quit is requested
|
|
(see enum stop_play_reason)
|
|
* call exit_player_with_rc()
|
|
|
|
Things worth saying about the playback core:
|
|
- the currently played tracks are in sh_video and sh_audio
|
|
- the timeline stuff is used only with MKV ordered chapters (and some other
|
|
minor features: cue, edl)
|
|
- most state is in MPContext (mp_core.h), which is not available to the
|
|
subsystems
|
|
- the other subsystems rarely call back into the frontend, and the frontend
|
|
polls them instead (probably a good thing)
|
|
|
|
I like to call mplayer.c (and some other files) the "frontend".
|
|
|
|
talloc.h & talloc.c:
|
|
Hierarchical memory manager copied from Samba. It's like a malloc() with
|
|
more features. Most importantly, each talloc allocation can have a parent,
|
|
and if the parent is free'd, all children will be free'd as well. The
|
|
parent is an arbitrary talloc allocation. It's either set by the allocation
|
|
call by passing a talloc parent, usually as first argument to the allocation
|
|
function. It can also be set or reset later by other calls (at least
|
|
talloc_steal()). A talloc allocation that is used as parent is often called
|
|
a talloc context.
|
|
|
|
Lots of code still uses malloc() proper, and you should be careful what
|
|
type of allocation you're dealing with when returning or free'ing an
|
|
allocation. (Needless to say, talloc_free() and free() are completely
|
|
different things.)
|
|
|
|
The copy in mplayer has been modified to abort on OOM conditions. An
|
|
allocation call will never return NULL.
|
|
|
|
One very useful feature of talloc is fast tracking of memory leaks. ("Fast"
|
|
as in it doesn't require valgrind.) You can enable it by passing the option
|
|
--leak-report as first parameter, or better, setting the
|
|
MPV_LEAK_REPORT environment variable to "1":
|
|
export MPV_LEAK_REPORT=1
|
|
This will list all unfree'd allocations on exit.
|
|
|
|
Documentation can be found here:
|
|
http://git.samba.org/?p=samba.git;a=blob;f=lib/talloc/talloc.h;hb=HEAD
|
|
|
|
core/mp_core.h:
|
|
Data structures for mplayer.c and command.c. They are usually not accessed
|
|
by other parts of mplayer for the sake of modularization.
|
|
|
|
Note that there are lots of global variables floating around everywhere
|
|
else. This is an ongoing transition, and eventually there should be no
|
|
global variables anymore.
|
|
|
|
options.h contains the global option struct MPOpts, and its default values
|
|
are in defaultopts.c for some reason.
|
|
|
|
core/input/input.c:
|
|
This translates keyboard input comming from libvo and other sources (such
|
|
as remote control devices like Apple IR or slave mode commands) to the
|
|
key bindings listed in the user's (or the builtin) input.conf and turns
|
|
them into items of type struct mp_cmd. These commands are queued, and read
|
|
by mplayer.c. They get pushed with run_command() to command.c.
|
|
|
|
Note that keyboard input and slave mode input are essentially the same
|
|
things. Just looking at input.conf should make this clear. (The other
|
|
direction of slave mode communication, mplayer to application, consists of
|
|
random mp_msg() calls all over the code in all parts of the player.)
|
|
|
|
core/command.c:
|
|
This contains the implementation for slave commands and properties.
|
|
Properties are essentially dynamic variables changed by certain commands.
|
|
This is basically responsible for all user commands, like initiating
|
|
seeking, switching tracks, etc. It calls into mplayer.c, where most of the
|
|
work is done, but also into other parts of mplayer.
|
|
|
|
core/mp_msg.h:
|
|
All terminal output should go though mp_msg().
|
|
|
|
stream/*:
|
|
File input is implemented here. stream.h/.c provides a simple stream based
|
|
interface (like reading a number of bytes at a given offset). mplayer can
|
|
also play from http streams and such, which is implemented here.
|
|
|
|
E.g. if mplayer sees "http://something" on the command line, it will pick
|
|
stream_http.c based on the prefix, and pass the rest of the filename to it.
|
|
|
|
Some stream inputs are quite special: stream_dvd.c turns DVDs into mpeg
|
|
streams (DVDs are actually a bunch of vob files etc. on a filesystem),
|
|
stream_tv.c provides TV input including channel switching.
|
|
|
|
Some stream inputs are just there to invoke special demuxers, like
|
|
stream_mf.c. (Basically to make the prefix "mf://" do something special.)
|
|
|
|
cache2.c is a horrible little thing which provides a caching wrapper around
|
|
stream implementations, needed for smooth network playback.
|
|
|
|
demux/:
|
|
Demuxers split data streams into audio/video/sub streams, which in turn
|
|
yield packets. Packets (see demux_packet.h) are mostly byte chunks tagged
|
|
with a playback time (PTS). These packets are passed to the decoders.
|
|
|
|
Most demuxers have been removed from this fork, and the only important and
|
|
"actual" demuxers left are demux_mkv.c and demux_lavf.c (uses libavformat).
|
|
There are some pseudo demuxers like demux_cue.c, which exist only to invoke
|
|
other frontend code (tl_cue.c in this case).
|
|
|
|
The main interface is in demux.h. A demuxer provides a list of available
|
|
streams. Also, for each type of stream (video/audio/sub) there is a
|
|
demux_stream. This contains the current packet stream coming from the
|
|
demuxer as a linked list of demux_packets.
|
|
|
|
video/:
|
|
This contains several things related to audio/video encoding, as well as
|
|
video filters.
|
|
|
|
mp_image.h and img_format.h define how mplayer stores video frames
|
|
internally.
|
|
|
|
video/decode/:
|
|
vd_*.c are video decoders. (There's only vd_ffmpeg.c left.) dec_video.c/vd.c
|
|
handle most of connecting the frontend with the actual decoder.
|
|
|
|
video/filter/:
|
|
vf_*.c and vf.c form the video filter chain. They are fed by the video
|
|
decoder, and output the filtered images to the VOs though vf_vo.c. By
|
|
default, no video filters (except vf_vo) are used.
|
|
|
|
video/out/:
|
|
Video output. They also create GUI windows and handle user input. In most
|
|
cases, the windowing code is shared among VOs, like x11_common.c for X11 and
|
|
w32_common.c for Windows. The VOs stand between frontend and windowing code.
|
|
vo_opengl can pick a windowing system at runtime, e.g. the same binary can
|
|
provide both X11 and Cocoa support on OSX.
|
|
|
|
VOs can be reconfigured at runtime. A config() call can change the video
|
|
resolution and format, without destroying the window.
|
|
|
|
vo_vdpau and vo_opengl should be taken as reference.
|
|
|
|
audio/:
|
|
format.h/format.c define the audio formats.
|
|
|
|
audio/decode/:
|
|
ad_*.c and dec_audio.c/ad.c handle audio decoding.
|
|
|
|
audio/filter/:
|
|
Audio filter chain.
|
|
|
|
audio/out/:
|
|
Audio outputs.
|
|
|
|
Unlike VOs, AOs can't be reconfigured on a format change. Without
|
|
--gapless-audio, even playing a new file will close and re-open the audio
|
|
device.
|
|
|
|
Note that mplayer synchronizes the video to the audio. That's the reason
|
|
why buggy audio drivers can have a bad influence on playback quality.
|
|
|
|
sub/:
|
|
A big mess. Contains subtitle rendering (parts of it), OSD rendering,
|
|
subtitle loading.
|
|
|
|
There are about 3 types of subtitles: image subs, ASS subs, text subs. Also,
|
|
there are 3 rendering methods: image subs, libass, internal subtitle
|
|
renderer. Also, subtitles can come from demuxers or external files. All the
|
|
possible combinations create weird special cases, e.g. taking a text
|
|
subtitle event from the demuxer and converting it to ass for display is
|
|
different from loading a text subtitle and converting it to ass.
|
|
|
|
core/timeline/:
|
|
A timeline is the abstraction used by mplayer.c to combine several files
|
|
into one seemingly linear video. It's mainly used for ordered chapters
|
|
playback. The high level code to find and load other files containing the
|
|
segments for playing an ordered chapters file is in tl_matroska.c.
|
|
|
|
etc/:
|
|
The file input.conf is actually integrated into the mpv binary by the
|
|
build system. It contains the default keybindings.
|