mirror of
https://github.com/mpv-player/mpv
synced 2024-12-25 08:12:17 +00:00
244 lines
11 KiB
Plaintext
244 lines
11 KiB
Plaintext
This file intends to give a big picture overview of how mpv is structured.
|
|
|
|
player/*.c:
|
|
Essentially makes up the player applications, including the main() function
|
|
and the playback loop.
|
|
|
|
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 (only if --idle it set)
|
|
* 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 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()
|
|
* run_playloop():
|
|
* calls fill_audio_out_buffers()
|
|
This checks whether new audio needs to be decoded, and pushes it
|
|
to the AO.
|
|
* calls write_video()
|
|
Decode new video, and push it to the VO.
|
|
* determines whether playback of the current file has ended
|
|
* determines when to start playback after seeks
|
|
* and calls a whole lot of other stuff
|
|
(Really, this function does everything.)
|
|
|
|
Things worth saying about the playback core:
|
|
- most state is in MPContext (core.h), which is not available to the
|
|
subsystems
|
|
- the currently played tracks are in mpctx->current_tracks, and decoder
|
|
state in track.d_video/d_audio/d_sub
|
|
- the other subsystems rarely call back into the frontend, and the frontend
|
|
polls them instead (probably a good thing)
|
|
- one exceptions are wakeup callbacks, which notify a "higher" component
|
|
of a changed situation in a subsystem
|
|
|
|
I like to call the player/*.c files the "frontend".
|
|
|
|
ta.h & ta.c:
|
|
Hierarchical memory manager inspired by talloc 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.
|
|
|
|
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 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
|
|
|
|
For some reason, we're still using API-compatible wrappers instead of TA
|
|
directly. The talloc wrapper has only a subset of the functionality, and
|
|
in particular the wrappers abort() on memory allocation failure.
|
|
|
|
Note: unlike tcmalloc, jemalloc, etc., talloc() is not actually a malloc
|
|
replacement. It works on top of system malloc and provides additional
|
|
features that are supposed to make memory management easier.
|
|
|
|
player/command.c:
|
|
This contains the implementation for client API 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 other player/*.c files,
|
|
where most of the work is done, but also calls other parts of mpv.
|
|
|
|
player/core.h:
|
|
Data structures and function prototypes for most of player/*.c. They are
|
|
usually not accessed by other parts of mpv for the sake of modularization.
|
|
|
|
player/client.c:
|
|
This implements the client API (libmpv/client.h). For the most part, this
|
|
just calls into other parts of the player. This also manages a ringbuffer
|
|
of events from player to clients.
|
|
|
|
options/options.h, options/options.c
|
|
options.h contains the global option struct MPOpts. The option declarations
|
|
(option names, types, and MPOpts offsets for the option parser) are in
|
|
options.c. Most default values for options and MPOpts are in
|
|
mp_default_opts at the end of options.c.
|
|
|
|
MPOpts is unfortunately quite monolithic, and virtually accessed by
|
|
everything.But some components (like video outputs and video filters) have
|
|
their own sub-option tables separate from MPOpts.
|
|
|
|
The actual option parser is spread over m_option.c, m_config.c, and
|
|
parse_commandline.c, and uses the option table in options.c.
|
|
|
|
input/input.c:
|
|
This translates keyboard input coming from VOs and other sources (such
|
|
as remote control devices like Apple IR or client API 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 playloop.c. They get pushed with run_command() to command.c.
|
|
|
|
Note that keyboard input and commands used by the client API are the same.
|
|
The client API only uses the command parser though, and has its own queue
|
|
of input commands somewhere else.
|
|
|
|
common/msg.h:
|
|
All terminal output must go through 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). mpv can
|
|
also play from http streams and such, which is implemented here.
|
|
|
|
E.g. if mpv sees "http://something" on the command line, it will pick
|
|
stream_lavf.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.)
|
|
|
|
demux/:
|
|
Demuxers split data streams into audio/video/sub streams, which in turn
|
|
are split in 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.
|
|
|
|
The main interface is in demux.h. The stream headers are in stheader.h.
|
|
There is a stream header for each audio/video/sub stream, and each of them
|
|
holds codec information about the stream and other information.
|
|
|
|
demux.c is a bit big, the main reason being that it contains the demuxer
|
|
cache, which is implemented as a list of packets. The cache is complex
|
|
because it support seeking, multiple ranges, prefetching, and so on.
|
|
|
|
video/:
|
|
This contains several things related to audio/video decoding, as well as
|
|
video filters.
|
|
|
|
mp_image.h and img_format.h define how mpv stores decoded video frames
|
|
internally.
|
|
|
|
video/decode/:
|
|
vd_*.c are video decoders. (There's only vd_lavc.c left.) dec_video.c
|
|
handles 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. vf_scale is automatically
|
|
inserted if the video output can't handle the video format used by the
|
|
decoder.
|
|
|
|
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_gpu 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 vo_reconfig() call can change the video
|
|
resolution and format, without destroying the window.
|
|
|
|
vo_gpu should be taken as reference.
|
|
|
|
audio/:
|
|
format.h/format.c define the uncompressed audio formats. (As well as some
|
|
compressed formats used for spdif.)
|
|
|
|
audio/decode/:
|
|
ad_*.c and dec_audio.c handle audio decoding. ad_lavc.c is the
|
|
decoder using ffmpeg. ad_spdif.c is not really a decoder, but is used for
|
|
compressed audio passthrough.
|
|
|
|
audio/filter/:
|
|
Audio filter chain. af_lavrresample is inserted if any form of conversion
|
|
between audio formats is needed.
|
|
|
|
audio/out/:
|
|
Audio outputs.
|
|
|
|
Unlike VOs, AOs can't be reconfigured on a format change. On audio format
|
|
changes, the AO will simply be closed and re-opened.
|
|
|
|
There are wrappers to support for two types of audio APIs: push.c and
|
|
pull.c. ao.c calls into one of these. They contain generic code to deal
|
|
with the data flow these APIs impose.
|
|
|
|
Note that mpv synchronizes the video to the audio. That's the reason
|
|
why buggy audio drivers can have a bad influence on playback quality.
|
|
|
|
sub/:
|
|
Contains subtitle and OSD rendering.
|
|
|
|
osd.c/.h is actually the OSD code. It queries dec_sub.c to retrieve
|
|
decoded/rendered subtitles. osd_libass.c is the actual implementation of
|
|
the OSD text renderer (which uses libass, and takes care of all the tricky
|
|
fontconfig/freetype API usage and text layouting).
|
|
|
|
The VOs call osd.c to render OSD and subtitle (via e.g. osd_draw()). osd.c
|
|
in turn asks dec_sub.c for subtitle overlay bitmaps, which relays the
|
|
request to one of the sd_*.c subtitle decoders/renderers.
|
|
|
|
Subtitle loading is in demux/. The MPlayer subreader.c is mostly gone - parts
|
|
of it survive in demux_subreader.c. It's used as last fallback, or to handle
|
|
some text subtitle types on Libav. It should go away eventually. Normally,
|
|
subtitles are loaded via demux_lavf.c.
|
|
|
|
The subtitles are passed to dec_sub.c and the subtitle decoders in sd_*.c
|
|
as they are demuxed. All text subtitles are rendered by sd_ass.c. If text
|
|
subtitles are not in the ASS format, the libavcodec subtitle converters are
|
|
used (lavc_conv.c).
|
|
|
|
Text subtitles can be preloaded, in which case they are read fully as soon
|
|
as the subtitle is selected. In this case, they are effectively stored in
|
|
sd_ass.c's internal state.
|
|
|
|
etc/:
|
|
The file input.conf is actually integrated into the mpv binary by the
|
|
build system. It contains the default keybindings.
|