Commit Graph

222 Commits

Author SHA1 Message Date
wm4 7caecc53b0 player: fix crash if no video decoder can be initialized
Caused by the recent refactoring for complex filters.
2016-02-10 00:07:01 +01:00
wm4 b7f6dfc19a player: force refresh seek when changing audio filters
Unfortunately I see no better solution.

The refresh seek is skipped if the amount of buffered audio is not
overly huge.

Unfortunately softvol af_volume insertion still can cause this issue,
because it's outside of the normal dynamic filter chain changing code.

Move the video refresh call to reinit_video_filters() to make it more
uniform along with the audio code.
2016-02-09 22:19:01 +01:00
wm4 ffb1d7807e player: remove some further current_track dependencies
Now it's used for initialization only for audio and video.
2016-02-05 23:41:44 +01:00
wm4 c0de087ba1 player: add complex filter graph support
See --lavfi-complex option.

This is still quite rough. There's no support for dynamic configuration
of any kind. There are probably corner cases where playback might freeze
or burn 100% CPU (due to dataflow problems when interaction with
libavfilter).

Future possible plans might include:
- freely switch tracks by providing some sort of default track graph
  label
- automatically enabling audio visualization
- automatically mix audio or stack video when multiple tracks are
  selected at once (similar to how multiple sub tracks can be selected)
2016-02-05 23:19:56 +01:00
wm4 8af70561a4 player: move audio and video decoder init to separate functions
Preparation.
2016-02-05 23:17:27 +01:00
wm4 5c8378b71a player: use different variable to indicate coverart
Slightly better.
2016-02-01 22:14:32 +01:00
wm4 ab318aeea8 audio/video: merge decoder return values
Will be helpful for the coming filter support. I planned on merging
audio/video decoding, but this will have to wait a bit longer, so only
remove the duplicate status codes.
2016-02-01 22:03:04 +01:00
wm4 526d578bee player: refactor: some more minor decoder/output decoupling
These changes don't make too much sense without context, but are
preparation for later. Then the audio_src/video_src fields will be
actually be NULL under circumstances.
2016-01-29 22:46:28 +01:00
wm4 340deb4e6e player: fix initial audio sync in certain cases
Regression caused by commit 3b95dd47. Also see commit 4c25b000. We can
either use video_next_pts and add "delay", or we just use video_pts. Any
other combination breaks. The reason why the assumption that delay==0 at
this point was wrong exactly because after displaying the first video
frame (usually done before audio resync) a new frame might be "added"
immediately, resulting in a new video_next_pts and "delay", which will
still amount to video_pts.

Fixes #2770. (The reason why display-sync was blamed in this issue is
because enabling display-sync in the options forces a prefetch by 2
instead of 1 frames for seeks/playback restart, which triggers the
issue, even if display-sync is not actually enabled. In this case,
display-sync is never enabled because the frames have a unusually high
frame duration. This is also what exposed the initial desync issue.)
2016-01-29 22:43:59 +01:00
wm4 dea42f77db video: fix coverart switching
If cover art is re-enabled during playback, the covert art picture
(which has pts==0) will be discarded. Add another corner case to
the list.
2016-01-27 21:10:11 +01:00
wm4 502763fcc7 video: slightly improve video stream switching
Resync newly switched video streams to the current playback position.
(Normal seeks will reset playback_pts to NOPTS.)
2016-01-26 14:06:41 +01:00
wm4 75d29b1457 video: limit maximum number of VO frames correctly
Otherwise, vo_frame.frames can be unintentionally overflown, leading to
undefined behavior in corner cases.
2016-01-24 18:09:14 +01:00
wm4 657dd4b807 video: don't wait for last video frame in the normal case
Even though the timing logic is correct, it tends to mess with looping
videos and such in unappreciated ways.

It also has to be admitted that most file formats seem not to properly
define the duration of the last video frame (or libavformat does not
export it in a useful way), so whether or not we should use the demuxer
reported framerate for the last frame is questionable. (Still, why would
you essentially just discard the last frame?)

The timing logic is kept, but disabled for video with "normal" FPS
values. In particular, we want to keep it for displaying images, which
implicitly set the frame duration to 1 second by reporting 1 FPS. It's
also good for slide shows with mf://.

Fixes #2745.
2016-01-22 00:25:44 +01:00
wm4 536efe6faf player: fix some oversights in video refactoring
vo_chain_uninit() isn't supposed to care much about the decoder
(although decoders and outputs still go strictly together, so there is
not much of an actual difference now).

Also unset track.d_video correctly.

Remove a stale declaration from dec_video.h as well.
2016-01-22 00:25:44 +01:00
wm4 7bb9203f7f player: refactor: eliminate MPContext.d_audio 2016-01-22 00:25:44 +01:00
wm4 fef8b7984b audio: refactor: work towards unentangling audio decoding and filtering
Similar to the video path. dec_audio.c now handles decoding only. It
also looks very similar to dec_video.c, and actually contains some of
the rewritten code from it. (A further goal might be unifying the
decoders, I guess.)

High potential for regressions.
2016-01-22 00:25:44 +01:00
wm4 4195a345a5 player: refactor: eliminate MPContext.d_video
Eventually we want the VO be driven by a A->V filter, so a decoder
doesn't even have to exist. Some features definitely require a decoder
though (like reporting the decoder in use, hardware decoding, etc.), so
for each thing which accessed d_video, it has to be redecided if and how
it can access decoder state.

At least the "framedrop" property slightly changes semantics: you can
now always set this property, even if no video is active.

Some untested changes in this commit, but our bio-based distributed
test suite has to take care of this.
2016-01-17 18:38:07 +01:00
wm4 056901b2be video: refactor: disentangle decoding/filtering some more
This moves some code related to decoding from video.c to dec_video.c,
and also removes some accesses to dec_video.c from the filtering code.

dec_video.ch is starting to make sense, and simply returns video frames
from a demuxer stream. The API exposed is also somewhat intended to be
easily changeable to move decoding to a separate thread, if we ever want
this (due to libavcodec already being threaded, I don't see much of a
reason, but it might still be helpful).
2016-01-16 22:08:39 +01:00
wm4 2d4e8b623d video: refactor: slightly disentangle video filtering 2016-01-15 22:54:08 +01:00
wm4 9a88b118b4 video: decouple filtering/decoding slightly more
Lots of noise to remove the vfilter/vo fields from dec_video.

From now on, video filtering and output will still be done together,
summarized under struct vo_chain.

There is the question where exactly the vf_chain should go in such a
decoupled architecture. The end goal is being able to place a "complex"
filter between video decoders and output (which will culminate in
natural integration of A->V filters for natural integration of
libavfilter audio visualizations). The vf_chain is still useful for
"final" processing, such as format conversions and deinterlacing. Also,
there's only 1 VO and 1 --vf option. So having 1 vf_chain for a VO seems
ideal, since otherwise there would be no natural way to handle all these
existing options and mechanisms.

There is still some work required to truly decouple decoding.
2016-01-14 00:18:48 +01:00
wm4 5722f93a74 video: refactor: shuffle code around
struct dec_video should have nothing to do with video filters or
outputs, and this huge chunk of code was somehow stuck directly in
dec_video.c.
2016-01-14 00:18:36 +01:00
wm4 bf13bd0d47 video: refactor: handle video format fixups closer to decoder
Instead of handling this on filter chain reinit, do it directly after
the decoder. This makes the code less entangled. In particular, this
gets rid of the really weird "override params" concept in the video
filter code.

The last_format/fixed_formats have some redundance with decoder_output,
but unfortunately the latter has a slightly different use.
2016-01-14 00:18:31 +01:00
wm4 e420464ba6 player: simplify backstepping
Basically reimplement it. The old implementation was quite stupid, and
was probably done this way because video filtering and output used to be
way less decoupled. Now we can reimplement it in a very simple way: when
backstepping, seek to current time, but keep the last frame that was
supposed to be discarded when reaching the target time. When the seek
finishes, prepend the saved frame to the video frame queue.

A disadvantage is that the new implementation fails to skip over
timeline boundaries (ordered chapters etc.), but this never worked
properly anyway. It's possible that this will be fixed some time in the
future.
2016-01-12 23:49:00 +01:00
wm4 6fc0fe4426 player: handle hrseek framedrop correctly
This was non-sense and checked the option instead of the actual flag.
Possibly could lead to incorrect hr-seeks.
2016-01-12 23:48:28 +01:00
wm4 671df54e4d demux: merge sh_video/sh_audio/sh_sub
This is mainly a refactor. I'm hoping it will make some things easier
in the future due to cleanly separating codec metadata and stream
metadata.

Also, declare that the "codec" field can not be NULL anymore. demux.c
will set it to "" if it's NULL when added. This gets rid of a corner
case everything had to handle, but which rarely happened.
2016-01-12 23:48:19 +01:00
Dmitrij D. Czarkoff ea442fa047 mpv_talloc.h: rename from talloc.h
This change helps avoiding conflict with talloc.h from libtalloc.
2016-01-11 21:05:55 +01:00
wm4 bd5a02d080 player: detect audio PTS jumps, make video PTS heuristic less aggressive
This is another attempt at making files with sparse video frames work
better.

The problem is that you generally can't know whether a jump in video
timestamps is just a (very) long video frame, or a timestamp reset. Due
to the existence of files with sparse video frames (new frame only every
few seconds or longer), every heuristic will be arbitrary (in general,
at least).

But we can use the fact that if video is continuous, audio should also
be continuous. Audio discontinuities can be easily detected, and if that
happens, reset some of the playback state.

The way the playback state is reset is rather radical (resets decoders
as well), but it's just better not to cause too much obscure stuff to
happen here. If the A/V sync code were to be rewritten, it should
probably strictly use PTS values (not this strange time_frame/delay
stuff), which would make it much easier to detect such situations and
to react to them.
2016-01-09 20:39:28 +01:00
wm4 b7e179f6d3 video: fix debug message
Should not be a warning, and the message text was also very useless.
2016-01-06 19:48:55 +01:00
wm4 2059ba2c40 video: do not disable hr-seek framedrop too early
This didn't make too much sense, and just made seeking slower. Strictly
suggest the decoder to drop a frame if its PTS is before the seek
target.
2015-12-30 15:51:47 +01:00
wm4 b47bf06f97 sub: change how subtitles are read
Slightly change how it is decided when a new packet should be read.
Switch to demux_read_packet_async(), and let the player "wait properly"
until required subtitle packets arrive, instead of blocking everything.
Move distinguishing the cases of passive and active reading into the
demuxer, where it belongs.
2015-12-29 01:35:52 +01:00
wm4 0a0bb9059f video: switch from using display aspect to sample aspect
MPlayer traditionally always used the display aspect ratio, e.g. 16:9,
while FFmpeg uses the sample (aka pixel) aspect ratio.

Both have a bunch of advantages and disadvantages. Actually, it seems
using sample aspect ratio is generally nicer. The main reason for the
change is making mpv closer to how FFmpeg works in order to make life
easier. It's also nice that everything uses integer fractions instead
of floats now (except --video-aspect option/property).

Note that there is at least 1 user-visible change: vf_dsize now does
not set the display size, only the display aspect ratio. This is
because the image_params d_w/d_h fields did not just set the display
aspect, but also the size (except in encoding mode).
2015-12-19 20:45:36 +01:00
wm4 c46106d633 player: remove redundant check
Found by Coverity.
2015-12-05 23:53:48 +01:00
wm4 832cb56f2d player: don't make display-sync panic on timestamp discontinuities 2015-12-04 17:07:50 +01:00
wm4 68c6da69f7 player: resync audio only on larger timestamp discontinuities
Helps with files that have occasional broken timestamps. For larger
discontinuities, e.g. caused by actual timestamp resets, we still want
to realign audio.

(I guess in general, this should be removed and replaced by a more
general resync-on-desync logic, but not now.)
2015-12-04 16:55:55 +01:00
wm4 318e9801f2 vo_opengl: fix interpolation with display-sync
At least I hope so.

Deriving the duration from the pts was not really correct. It doesn't
include speed adjustments, and becomes completely wrong of the user e.g.
changes the playback speed by a huge amount. Pass through the accurate
duration value by adding a new vo_frame field.

The value for vsync_offset was not correct either. We don't need the
error for the next frame, but the error for the current one. This wasn't
noticed because it makes no difference in symmetric cases, like 24 fps
on 60 Hz.

I'm still not entirely confident in the correctness of this, but it sure
is an improvement.

Also, remove the MP_STATS() calls - they're not really useful to debug
anything anymore.
2015-11-28 15:45:49 +01:00
wm4 ea1caa474a player: fix commit 50bb209a
Well, this was stupid.
2015-11-28 02:24:03 +01:00
wm4 7023c383b2 vo: change vo_frame field units
This was just converting back and forth between int64_t/microseconds and
double/seconds. Remove this stupidity. The pts/duration fields are still
in microseconds, but they have no meaning in the display-sync case (also
drop printing the pts field from opengl/video.c - it's always 0).
2015-11-27 22:04:44 +01:00
wm4 50bb209a80 player: always disable display-sync on desyncs
Instead of periodically trying to enable it again. There are two cases
that can happen:

1. A random discontinuity messed everything up,
2. Things are just broken and will desync all the time

Until now, it tried to deal with case 1 - but maybe this is really rare,
and we don't really need to care about it. On the other hand, case 2 is
kind of hard to diagnose if the user doesn't use the terminal.

Seeking will reenable display-sync, so you can fix playback if case 1
happens, but still get predictable behavior in case 2.
2015-11-27 14:40:52 +01:00
wm4 b250c19a38 player: make display-vdrop mode do what the manpage claims
Don't change video speed in this mode, which is closer to the claim on
the manpage that it's close to the behavior of the "audio" mode.
2015-11-26 18:53:32 +01:00
wm4 5bc9b273b3 player: log some more display-sync information 2015-11-25 22:07:47 +01:00
wm4 85450d06a1 player: use demuxer ts offset to simplify timeline ts handling
Use the demux_set_ts_offset() added in the previous commit to base each
timeline segment to use timestamps according to its relative position
within the overall timeline. As a consequence we don't need to care
about these timestamps anymore, and everything becomes simpler.

(Another minor but delicious nugget of sanity.)
2015-11-16 23:17:33 +01:00
wm4 a790009a63 player: account for minor VO underruns
If the player sends a frame with duration==0 to the VO, it can trivially
underrun. Don't panic, but keep the correct time.

Also, returning the absolute time from vo_get_next_frame_start_time()
just to turn it into a float with relative time was silly. Rename it and
make it return what the caller needs.
2015-11-14 21:49:48 +01:00
wm4 9f43778eb2 player: fix audio drift computation at different playback speeds
This computed nonsense if the user set a playback speed other than 1
(in addition to the display-sync speed change).
2015-11-14 21:42:25 +01:00
wm4 0f3dedebb4 player: stricter framedrop threshold
80ms allowable desync was a bit too much. It'd allow for a range of
160ms, which everyone can notice. It might also be a bother to apply
compensation resampling speed for that long.
2015-11-13 22:53:38 +01:00
wm4 70d46a9fb8 player: try to compensate actual audio drift
We always let audio slowly desync until a threshold is reached, and then
pushed it back by applying a maximum compensation speed. Refine what
comes afterwards: instead of playing with the nominal video speed, use
the actual required audio speed for keeping sync as measured by the A/V
difference. (The "actual" speed is the ideal speed with A/V differences
added.)

Although this works in theory, it's somewhat questionable how much this
works in practice. The ideal time value is actually not exact, but is
the time at which the frame is scheduled (could be compensated by using
the time_left calculations in handle_display_sync_frame()). It doesn't
account for speed changes or catastrophic discontinuities. It uses only
10 past frames.
2015-11-13 22:51:39 +01:00
wm4 c362c3d7ae player: change display-sync audio speed only if needed
As long as it's within the desync tolerance, do not change the audio
speed at all for resampling. This reduces speed changes which might be
caused by jittering timestamps and similar cases.

(While in theory you could just not care and change speed every single
frame, I'm afraid that such changes could possibly cause audio
artifacts. So better just avoid it in the first place.)
2015-11-13 22:50:58 +01:00
wm4 07b8abbd62 player: remove display_sync_disable_counter
We can implement it differently and drop a tiny bit of state.
2015-11-13 22:49:50 +01:00
wm4 d5981924fe command: add vsync-ratio property
This is very "illustrative", unlike the video-speed-correction
property, and thus useful. It can also be used to observe scheduling
errors, which are not detected by the core. (These happen due to
rounding errors; possibly not evne our fault, but coming from
files with rounded timestamps and so on.)
2015-11-13 22:48:32 +01:00
wm4 62b386c2fd player: compute required display-sync speed change differently
Instead of looking at the current frame duration for the intended
speedup, look at all past frames, and find a good average speed. This
ties in with not wanting to average _all_ frame durations, which
doesn't make sense in VFR situations.

This is currently done in the most naive way possible, but already sort
of works for VFR which switches between frame durations that are
integer multiples of a base rate. Certainly more improvements could
be made, such as trying to adjust directly on FPS changes, instead of
averaging everything, but for now this is not needed at all.
2015-11-13 22:47:14 +01:00
wm4 fad254562b player: smooth out frame durations by averaging them
Helps somewhat with muxer-rounded timestamps.

There is some danger that this introduces a timestamp drift. But since
they are averaged values (unlike as when using an incorrect container
framerate hint), any potential drift shouldn't be too brutal, or
compensate itself soon. So I won't bother yet with comparing the results
with the real timestamp, unless we run into actual problems.

Of course we still prefer potentially real timestamps over the
approximated ones. But unless the timestamps match the container FPS,
we can't know whether they are (no, checking whether the they have
microsecond components would be cheating). Perhaps in future, we could
let the demuxer export the timebase - if the timebase is not 1000 (or
divisible by it), we know that millisecond-rounded timestamps won't
happen.
2015-11-13 22:46:55 +01:00