Timeline handling converted the pts values from demuxed subtitles to
timeline scale. Change the code to do most subtitle handling in
original subtitle source pts, and instead convert current playback
timeline pts to those units when deciding which subtitle to show.
The main functionality changes are that now demuxed subtitles which
overlap chapter boundaries are handled correctly (at least for libass
subtitles), and external subtitles are assumed to use same pts scale
as current source (this needs improvements later).
Before, a video subtitle that had a duration continuing past the end
of the chapter would continue to be shown for the original duration,
even if the chapter ended and playback switched to a position in the
source where the subtitle shouldn't exist. Now, the subtitle will
correctly end.
Before, external subtitle files were interpreted as specifying pts
values in timeline scale. Now, they're interpreted as specifying pts
values in source file time scale, for _every_ source file. This is
probably more likely to be what the user wants for the "main" source
file in case there is one, but almost certainly not quite right for
multiple source files where the same subs could be shown over
different scenes. If the user wants them to match some main source
file, it's probably still better to have incorrect extra subs for
video from some files than to have every subtitle appearing at the
wrong time. The new code makes it easier to change the interpretation
of the subtitle times, and some configurability should be added in
the future.
Remove the old EDL implementation that was activated with the --edl
option. It is mostly redundant and inferior compared to the newer
demux_edl support, though currently there's no support for using the
same EDL files with the new implementation and the mute functionality
of the old implementation is not supported. The main reason to remove
the old implementation at this point is that the mute functionality
would conflict with following audio volume handling changes, and
working on the old code would be a wasted effort in the long run as at
some point it would be removed anyway.
The --edlout functionality is kept for now, even though after this
commit there is no code that could directly read its output.
Since the recent OSD redraw changes, every GUI expose event causes the
message "===== PAUSE =====" to be printed on console. This was a bit
annoying, so change it so that it is only printed once when going into
paused mode. It's also printed again if the cache status changes (when
playing URLs), or when the status line is printed during pause mode (when
you seek while paused).
This also removes some minor code duplication.
Add a VO command (VOCTRL_SCREENSHOT) which requests a screenshot
directly from the VO. If VO support is available, screenshots will be
taken instantly (no more 1 or 2 frames delay). Taking screenshots when
hardware decoding is in use will also work (vdpau). Additionally, the
screenshots will now use the same colorspace as the video display.
Change the central MPContext to be allocated with talloc so that it
can be used as a talloc parent context.
This commit does not yet implement the functionality for any VO (added
in subsequent commits).
The old screenshot video filter is not needed anymore if VO support is
present, and in that case will not be used even if it is present in
the filter chain. If VO support is not available then the filter is
used like before. Note that the filter still has some of the old
problems, such as delaying the screenshot by at least 1 frame.
Information about individual chapters was printed during demuxer
opening phase, and total chapter count (ID_CHAPTERS) was printed
according to mpctx->demuxer->num_chapters. When playing a file with
ordered chapters, this meant that chapter information about every
source file was printed individually (even though only the chapters
from the first file would be used for playback) and the total chapter
count could be wrong. Remove the printing of chapter information from
the demuxer layer and print the chapter information and count actually
used for playback in core print_file_properties().
Also somewhat simplify the internal chapters API and remove possible
inconsistencies.
Something like the OSD menu functionality could be useful. However the
current implementation has several problems and would require a
relatively large amount of work to get into good shape. As far as I
know there are few users of the existing functionality. Nobody is
working on the existing code and keeping it compiling at all while
changing other code would require extra work. So delete the menu code
and some related code elsewhere that's used by nothing else.
Seeking while paused could result in the current audio pts being
reported incorrectly due to relevant variables not being reinitialized
after the seek until more audio was played. When playing audio-only
files, this meant that current overall playback position could be
reported incorrectly which in turn could break further seeks. Improve
things on two levels: First, store the seek target position and use
that as the current playback position for audio-only files until
things can be reinitialized. Second, try to reinitialize audio
decoding enough to know its current pts even while paused. Also avoid
printing the actual huge negative value of MP_NOPTS_VALUE on the
status line when pts could not be determined.
Move sub_filenames() and related code from subreader.c to new file
find_subfiles.c. This function is used to find subtitle files that
should be loaded for the current video; this functionality is not
specific to the particular kind of text subtitle handling implemented
in subreader.c.
Also reindent and prettify the moved code a bit.
Make the outside interface of audio output handling similar to the
video output one. An AO object is first created, and then methods
called with ao_[methodname](ao, args...). However internally libao2/
still holds all data in globals, and trying to create multiple
simultaneous AO instances won't work.
The timeline code previously added to support Matroska ordered
chapters allows constructing a playback timeline from segments picked
from multiple source files. Add support for a new EDL format to make
this machinery available for use with file formats other than Matroska
and in a manner easier to use than creating files with ordered
chapters.
Unlike the old -edl option which specifies an additional file with
edits to apply to the video file given as the main argument, the new
EDL format is used by giving only the EDL file as the file to play;
that file then contains the filename(s) to use as source files where
actual video segments come from. Filename paths in the EDL file are
ignored. Currently the source files are only searched for in the
directory of the EDL file; support for a search path option will
likely be added in the future.
Format of the EDL files
The first line in the file must be "mplayer EDL file, version 2".
The rest of the lines belong to one of these classes:
1) lines specifying source files
2) empty lines
3) lines specifying timeline segments.
Lines beginning with '<' specify source files. These lines first
contain an identifier used to refer to the source file later, then the
filename separated by whitespace. The identifier must start with a
letter. Filenames that start or end with whitespace or contain
newlines are not supported.
On other lines '#' characters delimit comments. Lines that contain
only whitespace after comments have been removed are ignored.
Timeline segments must appear in the file in chronological order. Each
segment has the following information associated with it:
- duration
- output start time
- output end time (= output start time + duration)
- source id (specifies the file the content of the segment comes from)
- source start time (timestamp in the source file)
- source end time (= source start time + duration)
The output timestamps must form a continuous timeline from 0 to the
end of the last segment, such that each new segment starts from the
time the previous one ends at. Source files and times may change
arbitrarily between segments.
The general format for lines specifying timeline segments is
[output time info] source_id [source time info]
source_id must be an identifier defined on a '<' line. Both the time
info parts consists of zero or more of the following elements:
1) timestamp
2) -timestamp
3) +duration
4) *
5) -*
, where "timestamp" and "duration" are decimal numbers (computations
are done with nanosecond precision). Whitespace around "+" and "-" is
optional. 1) and 2) specify start and end time of the segment on
output or source side. 3) specifies duration; the semantics are the
same whether this appears on output or source side. 4) and 5) are
ignored on the output side (they're always implicitly assumed). On the
source side 4) specifies that the segment starts where the previous
segment _using this source_ ended; if there was no previous segment
time 0 is used. 5) specifies that the segment ends where the next
segment using this source starts.
Redundant information may be omitted. It will be filled in using the
following rules:
- output start for first segment is 0
- two of [output start, output end, duration] imply third
- two of [source start, source end, duration] imply third
- output start = output end of previous segment
- output end = output start of next segment
- if "*", source start = source end of earlier segment
- if "-*", source end = source start of a later segment
As a special rule, a last zero-duration segment without a source
specification may appear. This will produce no corresponding segment
in the resulting timeline, but can be used as syntax to specify the
end time of the timeline (with effect equal to adding -time on the
previous line).
Examples:
----- begin -----
mplayer EDL file, version 2
< id1 filename
0 id1 123
100 id1 456
200 id1 789
300
----- end -----
All segments come from the source file "filename". First segment
(output time 0-100) comes from time 123-223, second 456-556, third
789-889.
----- begin -----
mplayer EDL file, version 2
< f filename
f 60-120
f 600-660
f 30- 90
----- end -----
Play first seconds 60-120 from the file, then 600-660, then 30-90.
----- begin -----
mplayer EDL file, version 2
< id1 filename1
< id2 filename2
+10 id1 *
+10 id2 *
+10 id1 *
+10 id2 *
+10 id1 *
+10 id2 *
----- end -----
This plays time 0-10 from filename1, then 0-10 from filename1, then
10-20 from filename1, then 10-20 from filename2, then 20-30 from
filename1, then 20-30 from filename2.
----- begin -----
mplayer EDL file, version 2
< t1 filename1
< t2 filename2
t1 * +2 # segment 1
+2 t2 100 # segment 2
t1 * # segment 3
t2 *-* # segment 4
t1 3 -* # segment 5
+0.111111 t2 102.5 # segment 6
7.37 t1 5 +1 # segment 7
----- end -----
This rather pathological example illustrates the rules for filling in
implied data. All the values can be determined by recursively applying
the rules given above, and the full end result is this:
+2 0-2 t1 0-2 # segment 1
+2 2-4 t2 100-102 # segment 2
+0.758889 4-4.758889 t1 2-2.758889 # segment 3
+0.5 4.4758889-5.258889 t2 102-102.5 # segment 4
+2 5.258889-7.258889 t1 3-5 # segment 5
+0.111111 7.258889-7.37 t2 102.5-102.611111 # segment 6
+1 7.37-8.37 t1 5-6 # segment 7
Add new file timeline/tl_matroska.c. Move the code that parses
ordered chapter information from Matroska files and creates the
timeline structure based on that to the new file.
Initialize the format parameter given to open_stream() in the moved
code. The previous uninitialized value shouldn't have caused any
visible effects.
Rendering of ASS subtitles tries to be bug compatible with VSFilter
and stretches fonts when the video is anamorphic (some scripts try to
compensate for this VSFilter behavior, so trying to render them
"correctly" would give the wrong result). However this behavior is not
appropriate for subtitles we converted to ASS format ourselves for
libass rendering, as they certainly don't have VSFilter bug
workarounds. Change the code to use different behavior for "native"
ASS tracks and converted ones. It's questionable whether the
VSFilter-compatible behavior is appropriate for external .ass files
either, as there could be anamorphic and non-anamorphic versions of
the same video and the bug-compatible behavior can only be correct for
one alternative at most. However it's probably better to keep it as a
default at least, so that extracting a muxed subtitle track and using
that does not give behavior different from the original muxed one.
The aspect ratio setting is per ASS_Renderer, and changing it resets
libass caches. For that reason this commit adds separate renderer
instances to use for the "correct" and "VSFilter bug compatible"
cases.
Add a framework for subtitle decoder modules that work more like
audio/video decoders do, and change libass rendering of demuxed
subtitles to use the new framework.
The old subtitle code is messy, with details specific to handling
particular subtitle types spread over high-level code. This should
make it easier to clean things up and fix some bugs/limitations.
The contents of mpcommon.c were quite arbitrary; the most common
reason to place some functions in this file had been "MEncoder happens
to need similar code as MPlayer and we want to share some parts, but
we have no clue whatsoever how to organize things in a sensible way,
so we'll just dump those parts we want to share in mpcommon.c". As a
result of containing an essentially random subset of top-level player
functionality the mpcommon.h header required access to central structs
and was unsuitable for inclusion in lower-level code, but was
nonetheless included there for the mplayer_version symbol.
Move almost all contents from mpcommon.c to mplayer.c. mplayer.c is
already big and should perhaps be split further, but keeping a few
random functions in mpcommon.c would not be an improvement.
* hr-seek:
input: add default keybindings Shift+[arrow] for small exact seeks
input: support bindings with modifier keys for X input
core: audio: make ogg missing audio timing workaround more complex
core: add support for precise non-keyframe-limited seeks
core: add struct for queued seek info
commands: add generic option -> property wrapper
options: add "choice" option type, use for -pts-association-mode
core: remove looping in update_video(), modify command handling a bit
core: seek: use accurate seek mode with audio-only files
core: avoid using sh_video->pts as "current pts"
libvo: register X11 connection fd in input event system
core: timing: add special handling of long frame intervals
core: move central play loop to a separate function
Conflicts:
DOCS/tech/slave.txt
Add support for seeking to an arbitrary non-keyframe position by
decoding video starting from the previous keyframe. Whether to use
this functionality when seeking is controlled by the new option
-hr-seek and a new third argument to the "seek" command. The default
is to use it for absolute seeks (like chapter seeks) but not for
relative ones. Because there's currently no support for cutting
encoded audio some desync is expected if encoded audio passthrough is
used. Currently precise seeks always go to the first frame with
timestamp equal to or greater than the target position; there's no
support for "matching or earlier" backwards seeks at frame level.
To prepare for the addition of exact seek support, add a struct for
queued seek state and a helper function to update its state. It would
have been cumbersome to update additional state (showing whether the
seek is forced to be exact or non-exact) manually at every point that
handles seeks.
Let higher-level code call update_video() again instead of looping
inside it until there's a frame ready to show. Change the conditions
for running user commands somewhat. Overall effect shouldn't be that
big. Now other commands can be executed after a seek before a video
frame is decoded; in this case the seek target time may be used as the
"current position".
build_afilter_chain is not safe to use directly, thus make it
static and instead use reinit_audio_chain which should have
better error handling.
Fixes a crash with -af hrtf and changing speed, audio will
still stop playing though.
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@32648 b3059339-0415-0410-9bf9-f77b7e298cf2
Add a new field "video_pts" to mpctx. It records the time of the last
frame flipped visible on VO. Change various code which used
sh_video->pts to use either the new field or get_current_time(mpctx).
Add code to enforce matching pts with video when (re)starting the
audio stream, by either cutting away the first samples or inserting
silence at the beginning. New option -noinitial-audio-sync can be used
to disable this and return to old behavior.
Move functions to query current playback position, percentage position
and total video length from from the demuxer layer to top level. The
functions need access to playback state that doesn't belong on the
demuxing level. Make the new functions more capable and simplify some
code that can now rely on them. This fixes some errors in displayed in
OSD and slave mode information when using timeline (ordered chapters).
Change numbering so that demuxers can "asynchronously" add subtitles
during playback.
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@31678 b3059339-0415-0410-9bf9-f77b7e298cf2
Fix calculation of global_sub_size.
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@31711 b3059339-0415-0410-9bf9-f77b7e298cf2
Update global_sub_pos if we auto-selected a subtitle.
This avoid strange behaviour with subtitle selection in that
case, because the subtitle selection code thinks no subtitle
was displayed while we actually did display one.
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@31863 b3059339-0415-0410-9bf9-f77b7e298cf2
Move function to avoid a forward declaration.
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@31864 b3059339-0415-0410-9bf9-f77b7e298cf2
Fix subtitle selection: make selecting -sid 0 work again by replacing the
M_PROPERTY_STEP_UP hack by M_PROPERTY_SET and set the global sub pos also
when we do not yet have a subtitle stream but do know the number of subs
from out-of-band as e.g. for DVD.
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@31882 b3059339-0415-0410-9bf9-f77b7e298cf2
100l, re-add vobsub_get_id_by_index call accidentally removed in
r31678.
Patch by ubitux [ubitux gmail com].
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@31985 b3059339-0415-0410-9bf9-f77b7e298cf2
Due to inexact seeks, chapter seek commands may result in a playback
position that's inside the previous chapter. This causes problems when
the user does repeated next-chapter/previous-chapter seeks, because
the code will use the wrong base for calculating 'next' or
'previous'. Improve the behavior by adding a heuristic that keeps
track of what chapter the user last wanted to seek to and adjusts the
"current chapter" value based on that.
The _t namespace is reserved for POSIX; the typedef is pointless obfuscation.
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@30560 b3059339-0415-0410-9bf9-f77b7e298cf2
exit_player() was declared with differing parameter types in mplayer.c and
mplayer.h. Make the declaration in the .h file match the one in the .c file
and adjust all usages of exit_player() throughout the codebase. Also move
the exit_player() declaration into mp_core.h next to exit_player_with_rc().
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@30558 b3059339-0415-0410-9bf9-f77b7e298cf2
process the sleep before playing the frame seeked to and can be annoying
when the user tries to escape a series of "stuck" frames with a huge duration.
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@30217 b3059339-0415-0410-9bf9-f77b7e298cf2
Add interfaces to allow VO drivers to add or remove frames from the
video stream and to alter timestamps. Currently this functionality
only works with in correct-pts mode. Use the new functionality in
vo_vdpau to properly support frame-adding deinterlace modes.
Frames added by the VDPAU deinterlacing code are now properly timed.
Before every second frame was always shown immediately (probably next
monitor refresh) after the previous one, even if you were watching
things in slow motion, and framestepping didn't stop at them at all.
When seeking the deinterlace algorithm is no longer fed a mix of
frames from old and new positions.
As a side effect of the changes a problem with resize events was also
fixed. Resizing calls video_to_output_surface() to render the frame at
the new resolution, but before this function also changed the list of
history frames, so resizing could give an image different from the
original one, and also corrupt next frames due to them seeing the
wrong history. Now the function has no such side effects. There are
more resize-related problems though that will be fixed in a later
commit.
The deint_mpi[] list of reserved frames is increased from 2 to 3
entries for reasons related to the above. Having 2 entries is enough
when you initially get a new frame in draw_image() because then you'll
have those two entries plus the new one for a total of 3 (the code
relied on the oldest mpi implicitly staying reserved for the duration
of the call even after usage count was decreased). However if you want
to be able to reproduce the rendering outside draw_image(), relying on
the explicitly reserved list only, then it needs to store 3 entries.
The GUI is badly designed and too closely coupled to the internal
details of other code. The GUI code is in bad shape and unmaintained
for years. There is no indication that anyone would maintain it in the
future either. Even if someone did volunteer to implement a better
integrated GUI having the current code in the tree probably wouldn't
help much. So get rid of it.
Add basic support for Matroska ordered chapters. The switching between
segments is implemented as a general edit timeline that could also be
used for other purposes.
Some things still need improvement. In particular the current code
does not try to do any proper mapping between audio/video/subtitle
streams of different files and there should be options for better
control of how MPlayer searches other files for the required content.
Clean up the code and make the behavior more consistent. Before
bits of the OSD information were triggered in different places, and
various property commands that affect playback position only showed
the seek bar while the main seek command also triggered showing the
percentage in OSD text. Now only the seek and chapter commands trigger
all information and others nothing (which is consistent with most
property behavior).
Notable functionality changes:
* Timing change between any two frames is now accurately limited to
1/10 of their nominal distance. Previous code did not always use the
correct duration.
* The status line now keeps showing the same A-V sync value from one
video frame change to the next. Previously it kept recalculating
the value using a new audio position but the same video position
when the status line was updated between video frames. This
incorrectly showed the video losing sync with audio.
* The status line now displays actual measured A-V difference in
autosync mode too. The previous code displayed values that
completely ignored real timing in autosync mode, showing 0 A-V
difference even when video was significantly behind audio due to
inadequate decoding speed. The new behavior can make the shown A-V
values appear more unstable if the audio out has unreliable delay
measurements (the most likely reason to use autosync), but this is a
display change rather than a timing quality change.
* Autosync mode now tries to adjust timing by the amount of time
vo_flip() calls take, so the calls start earlier and finish at the
time the frame should be shown. Previously non-autosync mode
adjusted for this but autosync did not.
* The warning about the system being too slow to decode the video in
realtime is now displayed in autosync mode too.
When OSD contents change while paused, try to change the OSD drawn in
the currently visible frame. If such OSD updates are not supported
then advance by one frame and draw the OSD normally. Add some support
for OSD redrawing to vo xv.
The new xv code makes a copy of the original frame contents before
drawing the OSD if MPlayer is already paused when the frame is drawn.
If such a copy of the current frame exists then the frame contents can
be restored and a different OSD drawn on top of the same frame.
Add separate pause_player() / unpause_player functions(), move some
pausing-related state into explicit variables and make commands while
paused not unpause. Not everything works properly while paused yet (no
screen updates etc).
The mpctx->eof field was used to also store other reasons to stop
playing the current file besides EOF, and the code didn't properly
distinguish those from EOF. Rename the field to "stop_play" and clean
up some of the code accessing it. Properly separating EOF from other
reasons allows handling file switching better.
Before this commit buffered audio was always drained before moving to
the next file (the only exception when it was NOT drained when
stopping a file was when quitting the player completely). This added
an extra delay when manually moving to the next file as you had to
wait for the currently buffered audio to finish playing before the
next file would start. After this commit audio is only drained if the
file reaches EOF normally; otherwise audio is cut and the next file
starts immediately.