mpv/DOCS/tech-overview.txt

218 lines
10 KiB
Plaintext
Raw Normal View History

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/:
2013-06-04 22:28:15 +00:00
Contains subtitle rendering, OSD rendering, and parts of subtitle loading.
sub.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).
Subtitles are loaded either via libass (for .ass), subreader.c (the old
MPlayer subtitle loader code), or libavformat demuxers. The subtitles are
then passed to dec_sub.c and the subtitle decoders in sd_*.c. All text
subtitles are rendered by sd_ass.c. If text subtitles are not in the ASS
format, subtitle converters are inserted, for example sd_srt.c, which is
used to convert SRT->ASS. sd_srt.c is also used as general converter for
text->ASS (to prevent interpretation of text as ASS tags).
subreader.c should eventually go away. It should be replaced by either
libavformat's demuxers, or by mpv native demuxers for more common formats
like SRT. See commit message of commit 92ae48d what needs to be done to
replace subreader.c completely and why.
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/:
core: redo how codecs are mapped, remove codecs.conf Use codec names instead of FourCCs to identify codecs. Rewrite how codecs are selected and initialized. Now each decoder exports a list of decoders (and the codec it supports) via add_decoders(). The order matters, and the first decoder for a given decoder is preferred over the other decoders. E.g. all ad_mpg123 decoders are preferred over ad_lavc, because it comes first in the mpcodecs_ad_drivers array. Likewise, decoders within ad_lavc that are enumerated first by libavcodec (using av_codec_next()) are preferred. (This is actually critical to select h264 software decoding by default instead of vdpau. libavcodec and ffmpeg/avconv use the same method to select decoders by default, so we hope this is sane.) The codec names follow libavcodec's codec names as defined by AVCodecDescriptor.name (see libavcodec/codec_desc.c). Some decoders have names different from the canonical codec name. The AVCodecDescriptor API is relatively new, so we need a compatibility layer for older libavcodec versions for codec names that are referenced internally, and which are different from the decoder name. (Add a configure check for that, because checking versions is getting way too messy.) demux/codec_tags.c is generated from the former codecs.conf (minus "special" decoders like vdpau, and excluding the mappings that are the same as the mappings libavformat's exported RIFF tables). It contains all the mappings from FourCCs to codec name. This is needed for demux_mkv, demux_mpg, demux_avi and demux_asf. demux_lavf will set the codec as determined by libavformat, while the other demuxers have to do this on their own, using the mp_set_audio/video_codec_from_tag() functions. Note that the sh_audio/video->format members don't uniquely identify the codec anymore, and sh->codec takes over this role. Replace the --ac/--vc/--afm/--vfm with new --vd/--ad options, which provide cover the functionality of the removed switched. Note: there's no CODECS_FLAG_FLIP flag anymore. This means some obscure container/video combinations (e.g. the sample Film_200_zygo_pro.mov) are played flipped. ffplay/avplay doesn't handle this properly either, so we don't care and blame ffmeg/libav instead.
2013-02-09 14:15:19 +00:00
The file input.conf is actually integrated into the mpv binary by the
build system. It contains the default keybindings.