Commit Graph

86 Commits

Author SHA1 Message Date
wm4 975e98b3fe player: print anamorphic size only if video is anamorphic
Has been annoying me since forever.
2014-11-02 17:34:02 +01:00
wm4 dab6cbca16 player: update meaning of drop_frame_cnt
Rename the variable, update comments, and update the documentation of
the property which returns its value.
2014-11-01 01:07:21 +01:00
wm4 0e97808fc5 player: show AV-desync message in all framedrop modes
This was shown only if decoder-framedropping was enabled, and only if at
least 50 frames were dropped by it. Since drop_frame_cnt used to mean
"number of late frames", this code made sense, but this is not the case
anymore: drop_frame_cnt can be even 0, all while video gets hopelessly
behind audio.

One problem with this is that short desync spikes (which usually can
probably dealt with) will also cause this message to be shown. If it
gets triggered too often, the code will need to be adjusted.
2014-11-01 01:06:22 +01:00
wm4 65db3291b3 client API: better error reporting
Give somewhat more information on playback failure.
2014-10-28 20:30:12 +01:00
wm4 f4ad398b28 video: send MPV_EVENT_VIDEO_RECONFIG on uninit
This event basically means "something about video changed", and uninit
is certainly an important change.
2014-10-24 15:34:28 +02:00
wm4 c9234d769d player: fix exiting if both audio and video fail initializing
The player was supposed to exit playback if both video and audio failed
to initialize (or if one of the streams was not selected when the other
stream failed). This didn't work; for one this check was missing from
one of the failure paths. And more importantly, both checked the
current_track array incorrectly.

Fix these issues, and move the failure handling code into a common
function.

CC: @mpv-player/stable
2014-10-23 18:31:43 +02:00
wm4 596231bc97 player: fix --frames
This could produce an extra frame, because reaching the maximum merely
signals the playloop to exit, without strictly enforcing the limit.

Fixes #1181.

CC: @mpv-player/stable
2014-10-14 13:29:38 +02:00
wm4 299bf5c017 player: signal EOF when using --frames 2014-10-10 15:14:11 +02:00
wm4 bc6b8caa6d video: try harder to decode cover art picture only once
For cover art, we pretend that the video stream is infinite, but also
stop decoding once we have an image on the VO (this seems advantageous
for the case when strange filters are inserted or the VO image gets
lost). Since a while ago, the video chain started decoding 2 images
though ("Non-monotonic video pts: 0.000000 <= 0.000000"), which is
annoying and wasteful.

Improve this by handling a certain corner case at initialization, which
will decode a second image while the first one is still stuck in the
filter chain. Also, just in case there are filters which buffer a lot,
also force EOF filtering (which means we tell the filters to flush
buffered frames).

CC: @mpv-player/stable
2014-10-09 17:57:17 +02:00
wm4 9d5d031b6d player: remove central uninit_player() function and flags mess
Each subsystem (or similar thing) had an INITIALIZED_ flag assigned. The
main use of this was that you could pass a bitmask of these flags to
uninit_player(). Except in some situations where you wanted to
uninitialize nearly everything, this wasn't really useful. Moreover, it
was quite annoying that subsystems had most of the code in a specific
file, but the uninit code in loadfile.c (because that's where
uninit_player() was implemented).

Simplify all this. Remove the flags; e.g. instead of testing for the
INITIALIZED_AO flag, test whether mpctx->ao is set. Move uninit code
to separate functions, e.g. uninit_audio_out().
2014-10-03 23:05:09 +02:00
wm4 f62f984404 player: don't print audio/video init failure message twice
The messages "Audio: no audio" and "Video: no video" could be printed
twice each if initializing them failed. Prevent his silliness.

CC: @mpv-player/stable
2014-10-02 03:12:45 +02:00
wm4 cdb25d5a21 video: change automatic rotation and 3D filter insertion
We inserted these filters with fixed parameters, which was ok. But this
also didn't change image parameters for the filters down the filter
chain and the VO. For example, if rotation by 90° was requested by the
file, we would insert a filter and rotate the video, but the VO would
still receive image parameters that direct rotation by 90°.

This wasn't a problem, but it could become one.

Fix this by letting the filters automatically pick up the image params.
The image params are reset on application. (We could probably also
always try to apply and reset image params in a filter, instead of
having special "auto" parameters. This would probably work, and video.c
would insert a "rotate=0" filter. But I'm afraid this would be confusing
and the current solution is cosmetically slightly nicer.)

Unfortunately, the vf_stereo3d.c change turned out a big mess, but once
the "internal" filter is fully replaced with libavfilter, most of this
can be radically simplified.
2014-09-27 18:31:59 +02:00
wm4 d23ffd243f player: rate-limit OSD text update
There's no need to update OSD messages and the terminal status if nobody
is going to see it. Since the player doesn't block on video display
anymore, this update happens to often and probably burns slightly more
CPU than necessary. (OSD redrawing is handled separately, so it's just
mostly useless text processing and such.)

Change it so that it's updated only on every video frame or all 50ms
(whatever comes first).

For VO OSD, we could in theory try to lock to the OSD redraw heuristic
or the display refresh rate, but that's more complicated and doesn't
work for the terminal status.
2014-09-25 21:32:56 +02:00
wm4 f605b03f63 video: filter new frames at a better time (2)
We generally want 2 things:
1. minimal wakeups for decoding each frame
2. minimal number of frames decoded on continuous seeking

Commit 35810cb8 changed this a bit, and fixed 1. But it broke 2., and
now it decodes 2 frames instead of 1 when you keep seeking (arrow key
held down or such). This made seeking appear slower.

Fix this by making the logic more explicit. In particular, call the
filters only if we actually try to get a new frame.

When playing with --no-audio and all other distractions disabled (like
OSC), it still wakes up 2 times per frame - but the second time is
merely because the VO didn't accept the new frame yet.
2014-09-22 18:06:59 +02:00
wm4 771583c285 video: actually count decoder-dropped frames
Normally, feeding a packet to the decoder should always return a frame
_if_ we received a frame before. So while we can't know exactly whether
a frame was dropped, at least the normal case is easily detectable.

This means we display something closer to the actual framedrop count,
instead of a bad guess.
2014-09-20 00:45:39 +02:00
wm4 4047e7e6cb video: improve decoder-based framedropping mode
This is the "old" framedropping mode (derived from MPlayer). At least in
the mplayer2/mpv source base, it stopped working properly years ago (or
maybe it never worked properly). For one, it depends on the video
framerate, which assume constant framerate. Another problem was that it
could lead to freezing video display: video could get so much behind
that it couldn't recover from framedrop.

Make some small changes to improve this.

Don't use the current audio position to check how much we are behind.
Instead, use the last known A/V difference. last_av_difference is
updated only when a video frame is scheduled for display. This means we
can keep stop dropping once we're done catching up, even if video is
technically still behind. What helps us here that this forces a video
frame to be displayed after a while. Likewise, we reset the
dropped_frames count only when scheduling a new frame for display as
well.

Some inspiration was taken from earlier work by xnor (see issue #620),
although the implementation turned out quite different.

This still uses the demuxer-reported (possibly broken) FPS value. It
also doesn't account for filters changing FPS. We can't do much about
this, because without decoding _and_ filtering, we just can't know how
long a frame is. In theory, you could derive that from the raw packet
timestamps and the filter chain contents, but actually doing this is
too involved. Fortunately, the main thing the FPS affects is actually
the displayed framedrop count.
2014-09-20 00:45:11 +02:00
wm4 70f4721574 player: reset last_av_difference if not applicable
Don't let stale values linger around.

Also fix a slightly related case in audio.c.
2014-09-20 00:44:37 +02:00
wm4 5c8549ac68 video: separate calling decoder/filter
Rename video_decode_and_filter to video_filter, and add a new
video_decode_and_filter function. This function now calls the decoder.
This is done so that we can check filters a second time after decoding,
which avoids a useless playloop iteration.

(This and the previous commits are really just microoptimizations, which
simply reduce the number of times the playloop has to recheck
everything.)
2014-09-18 19:35:23 +02:00
wm4 e37ad620aa video: check whether there are enough frames after filtering
Move the check to a function. Run the check a second time after
decoding/filtering. This second check is strictly speaking redundant
(which is why it wasn't done until now), but it avoids a useless
playloop iteration.
2014-09-18 19:34:56 +02:00
wm4 35810cb8b4 video: filter new frames at a better time
Move this code below the code that "shifts" the newly filtered frame.
This allows us to skip a useless playloop iteration later, because
obviously we need to filter a new frame after the previous frame has
been "shifted", and not before that.
2014-09-18 19:32:25 +02:00
wm4 8599c959fe video: initial Matroska 3D support
This inserts an automatic conversion filter if a Matroska file is marked
as 3D (StereoMode element). The basic idea is similar to video rotation
and colorspace handling: the 3D mode is added as a property to the video
params. Depending on this property, a video filter can be inserted.

As of this commit, extending mp_image_params is actually completely
unnecessary - but the idea is that it will make it easier to integrate
with VOs supporting stereo 3D mogrification. Although vo_opengl does
support some stereo rendering, it didn't support the mode my sample file
used, so I'll leave that part for later.

Not that most mappings from Matroska mode to vf_stereo3d mode are
probably wrong, and some are missing.

Assuming that Matroska modes, and vf_stereo3d in modes, and out modes
are all the same might be an oversimplification - we'll see.

See issue #1045.
2014-08-30 23:24:46 +02:00
wm4 f104ef1282 player: minor changes
This shouldn't change anything functionally.

Change the A/V desync message. --framedrop is enabled by default now, so
the text must be changed a little. I've never heard of audio outputs
messing up A/V sync recently, so remove that part.

Remove the unused ao_pts field.

Reorder 2 A/V sync related expressions so that they look the same.
2014-08-25 21:39:24 +02:00
wm4 39b42814e0 player: restore silent seeking
Commit 846257da introduced an accidental feature: if you kept seeking
(so playback never really resumes), the audio would never be played.
This was nice, but commit 4c25b000 accidentally removed it again (due
to the video_next_pts being earlier available than it used to be, so
audio could be played before the player executed the next queued seek).

Implicitly reintroduce the old behavior again by not decoding a second
video frame immediately. Usually, the second frame is used to compute
the frame duration needed to for accurate framedropping, but since the
first frame after a seek is never dropped, we don't need this.

Now the video code will queue the new frame to the VO immediately, and
since fill_audio_out_buffers() is called in the playloop before
write_video() and execute_queued_seek(), it never gets the chance to
enter STATUS_READY, and seeks will be silent.

This also has a nice side-effect: since the second frame is not decoded
and filtered, seeking becomes slightly faster (back to the same level
as with framedrop disabled).

It seems this still sometimes plays a period of audio when keeping a
seek key down. In my tests, this appeared to happen because the seek
finished before the next key repeat was sent.
2014-08-23 12:02:40 +02:00
wm4 4c25b000b5 player: fix recent speed change regression
Commit 5afc025c broke this. The reason is that mpctx->delay is updated
when a new video frame is added. This value is also needed to resync
audio, but it will be for the wrong PTS. They must be consistent with
each other, and if they aren't, initial sync will be off by N video
frames, which results at least in worse user experience.

This can be reproduced by for example heavily switching between normal
and 2x speed, or similar.

Fix by readding the video_next_pts field (keeping its use minimal,
instead of reverting the commit that removed it).
2014-08-22 15:36:48 +02:00
wm4 e9e73f8d03 video: refactor queue handling
This simplifies the code, and fixes an odd bug: the second-last frame
was displayed for a very short duration if framedrop was enabled. The
reason was that basically the time difference between second-last and
last frame were skipped, because at this point EOF was already
signaled. Also see commit b0959488 for a similar issue in the
same code.

This removes the messiness of the next_frame 2-frame queue, and
strictly runs the "new frame" code when a frame is moved to the first
position of the queue, instead of somehow messing with return codes.

This also merges update_video() into video_output_image().
2014-08-22 14:22:06 +02:00
wm4 5afc025cc9 video: get rid of video_next_pts field
Not really needed anymore. Code should be mostly equivalent.

Also get rid of some other now-unused or outdated things.
2014-08-22 14:22:06 +02:00
wm4 7b3a889c92 video: move some code around
No functional changes. init_vo() is now needed a bit further down, and
moving it keeps definition and use close. adjust_sync() will be used by
a function further up in one of the following commits.
2014-08-22 14:22:06 +02:00
wm4 bc90f71d35 video: minor simplification
This is mostly equivalent, but simpler, and reduces some duplication.
2014-08-22 14:22:06 +02:00
wm4 7758c15e95 video: don't assume query_format is thread-safe
Although it's probably safe for most VOs, there's no guarantee.
2014-08-20 21:35:45 +02:00
wm4 543ba6c114 video: add VO framedropping mode
This mostly uses the same idea as with vo_vdpau.c, but much simplified.

On X11, it tries to get the display framerate with XF86VM, and limits
the frequency of new video frames against it. Note that this is an old
extension, and is confirmed not to work correctly with multi-monitor
setups. But we're using it because it was already around (it is also
used by vo_vdpau).

This attempts to predict the next vsync event by using the time of the
last frame and the display FPS. Even if that goes completely wrong,
the results are still relatively good.

On other systems, or if the X11 code doesn't return a display FPS, a
framerate of 1000 is assumed. This is infinite for all practical
purposes, and means that only frames which are definitely too late are
dropped. This probably has worse results, but is still useful.

"--framedrop=yes" is basically replaced with "--framedrop=decoder". The
old framedropping mode is kept around, and should perhaps be improved.
Dropping on the decoder level is still useful if decoding itself is too
slow.
2014-08-15 23:33:33 +02:00
wm4 3eaa407c6f video: reduce non-sense messages when playing coverart
Don't print PTS warnings by skipping the normal video path.
2014-08-13 22:01:10 +02:00
wm4 b0959488d1 video: don't run new frame processing on every iteration
This ran adjust_sync() on every playloop iteration, instead of every
newly decoded frame. It seems this was idempotent in the common case,
but the code was originally designed to be run once only, so restore
that.
2014-08-13 22:01:10 +02:00
wm4 4a325a8592 video: move some more code around
No functional changes.
2014-08-13 22:01:09 +02:00
wm4 48bd1294eb video: move some code around 2014-08-13 21:53:47 +02:00
wm4 311ce60b16 video: exit early when nothing to do
These cases were probably confusing. Exit early, which makes it much
clearer what's going on. Should not change anything functionally.
2014-08-13 21:51:26 +02:00
wm4 d4e0fc76bb video: minor simplification of the old framedrop code
No changes in functionality, other than being slightly more correct at
stream EOF.
2014-08-13 21:50:23 +02:00
wm4 5ed7bc6321 video: fix and simplify video format changes and last frame display
The previous commit broke these things, and fixing them is separate in
this commit in order to reduce the volume of changes.

Move the image queue from the VO to the playback core. The image queue
is a remnant of the old way how vdpau was implemented, and increasingly
became more and more an artifact. In the end, it did only one thing:
computing the duration of the current frame. This was done by taking the
PTS difference between the current and the future frame. We keep this,
but by moving it out of the VO, we don't have to special-case format
changes anymore. This simplifies the code a lot.

Since we need the queue to compute the duration only, a queue size
larger than 2 makes no sense, and we can hardcode that.

Also change how the last frame is handled. The last frame is a bit of a
problem, because video timing works by showing one frame after another,
which makes it a special case. Make the VO provide a function to notify
us when the frame is done, instead. The frame duration is used for that.

This is not perfect. For example, changing playback speed during the
last frame doesn't update the end time. Pausing will not stop the clock
that times the last frame. But I don't think this matters for such a
corner case.
2014-08-12 23:24:08 +02:00
wm4 df58e82237 video: move display and timing to a separate thread
The VO is run inside its own thread. It also does most of video timing.
The playloop hands the image data and a realtime timestamp to the VO,
and the VO does the rest.

In particular, this allows the playloop to do other things, instead of
blocking for video redraw. But if anything accesses the VO during video
timing, it will block.

This also fixes vo_sdl.c event handling; but that is only a side-effect,
since reimplementing the broken way would require more effort.

Also drop --softsleep. In theory, this option helps if the kernel's
sleeping mechanism is too inaccurate for video timing. In practice, I
haven't ever encountered a situation where it helps, and it just burns
CPU cycles. On the other hand it's probably actively harmful, because
it prevents the libavcodec decoder threads from doing real work.

Side note:

Originally, I intended that multiple frames can be queued to the VO. But
this is not done, due to problems with OSD and other certain features.
OSD in particular is simply designed in a way that it can be neither
timed nor copied, so you do have to render it into the video frame
before you can draw the next frame. (Subtitles have no such restriction.
sd_lavc was even updated to fix this.) It seems the right solution to
queuing multiple VO frames is rendering on VO-backed framebuffers, like
vo_vdpau.c does. This requires VO driver support, and is out of scope
of this commit.

As consequence, the VO has a queue size of 1. The existing video queue
is just needed to compute frame duration, and will be moved out in the
next commit.
2014-08-12 23:24:08 +02:00
wm4 b8f025a58a video: don't keep multiple pointers to hwdec info struct
This makes a certain corner case simpler at a later point.
2014-08-11 23:09:39 +02:00
wm4 37357e2265 video: fix dangling pointer issue
The function video_decode_and_filter(), called between initializing the
local vf variable and using it, can actually destroy and recreate the
filter. Thus, the vf variable turns into a dangling pointer if that
happens.

Could be observed with: --hwdec=vda --deinterlace=yes --vf=yadif

(Also happens with vdpau/vaapi.)
2014-08-11 15:37:13 +02:00
wm4 8dfe0c73c9 video: remove "hard" framedrop mode
Completely useless, and could accidentally be enabled by cycling
framedrop modes. Just get rid of it.

But still allow triggering the old code with --vd-lavc-framedrop, in
case someone asks for it. If nobody does, this new option will be
removed eventually.
2014-08-09 00:35:35 +02:00
wm4 886ac09699 audio: fix encoding mode
If this code is not skipped, encoding (or dumping with --ao=pcm) will
attempt to adjust video timing to audio. Since another commit (0cce8fe6)
already avoids writing audio ahead, this didn't slow down encoding to
realtime, but it was still significantly slower.

This change should actually remove all extra sleeping.
2014-08-07 18:07:43 +02:00
wm4 b38ac38aec client API: trigger MPV_EVENT_VIDEO_RECONFIG on vf recreation
Until now, it was done only on VO reconfig, but this easily can miss
some events, in case the VO output format doesn't change.
2014-08-06 20:30:47 +02:00
wm4 0f5aed9c62 player: some further playloop cleanups
Handle --term-playing-msg at a better place.

Move MPV_EVENT_TICK hack into a separate function. Also add some words
to the client API that you shouldn't use it. (But better leave breaking
it for later.)

Handle --frames and frame_step differently. Remove the mess from the
playloop, and do it after frame display. Give up on the weird semantics
for audio-only mode (they didn't make sense anyway), and adjust the
manpage accordingly.
2014-08-03 20:31:00 +02:00
wm4 de8e9ca9d2 video: fix attached picture mode
Playing audio files with embedded cover art broke due to some of the
recent changes. Treat video EOF properly, and don't burn the CPU.
Disable hrseek for video in attached picture mode, since the decoder
will always produce a new image, which makes hrseek never terminate.

Fixes #970.
2014-07-31 21:57:11 +02:00
wm4 1423bd0bfd player: move video display code out of the playloop
Basically move the code from playloop.c to video.c. The new function
write_video() now contains the code that was part of run_playloop().

There are no functional changes, except handling "new_frame_shown"
slightly differently. This is done so that we don't need new a new
MPContext field or a return value for write_video() to signal this
condition. Instead, it's handled indirectly.
2014-07-30 23:29:00 +02:00
wm4 8f2e9f1d61 player: split seek_reset()
This also reduces some code duplication with other parts of the code.

The changfe is mostly cosmetic, although there are also some subtle
changes in behavior. At least one change is that the big desync message
is now printed after every seek.
2014-07-30 23:29:00 +02:00
wm4 c38013bffb video: actually flush filter chain
Frames buffered in filters weren't flushed, so on EOF, the last frames
were dropped, depending on how much filters buffered. Oops.

Test case: "mpv something.jpg --vf=buffer"
2014-07-30 23:29:00 +02:00
wm4 862d7d8a1a player: fix desync when seeking and switching external tracks
If you for example use --audio-file, disable the external track, seek,
and enable the external track again, the playback position of the
external file was off, and you would get major A/V desync. This was
actually supposed to work, but broke at some time ago (probably commit
2b87415f). It didn't work, because it attempted to seek the stream if it
was already selected, which was always true due to
reselect_demux_streams() being called before that.

Fix by putting the initial selection and the seek together.
2014-07-29 17:55:28 +02:00
wm4 261506e36e audio: change playback restart and resyncing
This commit makes audio decoding non-blocking. If e.g. the network is
too slow the playloop will just go to sleep, instead of blocking until
enough data is available.

For video, this was already done with commit 7083f88c. For audio, it's
unfortunately much more complicated, because the audio decoder was used
in a blocking manner. Large changes are required to get around this.
The whole playback restart mechanism must be turned into a statemachine,
especially since it has close interactions with video restart. Lots of
video code is thus also changed.

(For the record, I don't think switching this code to threads would
make this conceptually easier: the code would still have to deal with
external input while blocked, so these in-between states do get visible
[and thus need to be handled] anyway. On the other hand, it certainly
should be possible to modularize this code a bit better.)

This will probably cause a bunch of regressions.
2014-07-28 21:20:37 +02:00