summaryrefslogtreecommitdiffstats
path: root/player
Commit message (Collapse)AuthorAgeFilesLines
* filter: minor cosmetic naming issuewm42020-03-082-2/+2
| | | | | Just putting some more lipstick on the pig, maybe it looks a bit nicer now.
* command: add libass-version propertywm42020-03-081-0/+15
| | | | A bit of a mess with that ifdeffery, but fuck it.
* player: rearrange libav* library checkwm42020-03-081-12/+2
| | | | No need to be nice. Also hopefully breaks idiotic distro patches.
* player: move on_unload hook after frame step pausingwm42020-03-071-2/+2
| | | | | | | Really minor detail that doesn't really matter. If frame stepping pauses playback on end (why does this special case even exist), it should probably be done after on_unload, because all works is supposed to be finished at that point.
* client API: always reset new_property_events fieldswm42020-03-071-1/+2
| | | | | | This was not reset in the num_properties==0 case. This didn't really matter, but for debugging it's slightly nicer to see new_property_events reset once the client thread is done with it.
* js: osd-overlay update: return the command result (match 7a76b577)Avi Halachmi (:avih)2020-03-071-2/+1
| | | | Currently only useful for the new 'compute_bounds' command key.
* js: osd-overlay update: support arbitrary key namesAvi Halachmi (:avih)2020-03-071-9/+11
| | | | | | | | | | | | | | | | | | | | Until now the 'update' method used mp.command_native with a hardcoded list of key names. Change it to use whatever keys the user set to this object, so that we can remain oblivious to new keys which 'osd-overlay' may support. This is how the lua code did it from the begining. We didn't, and now we pay the price. Note: could be implemented either as we have now (clone `this` excluding the methods) or by moving the methods up the prototype chain (i.e. class methods) so they don't get enumerated and use `this` as the command object itself. However, in the latter approach we'll have to save the values which we change (name, res_x, res_y) and restore them after the command, so it's simpler to just clone `this`.
* client API: provide ways to finish property changes on file changeswm42020-03-072-5/+56
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When the current file changes (or rather, when starting/finishing playback of a playlist entry), clients tend to have the problem that it's hard to tell whether a property change notification (via mpv_observe_property() and mechanisms layered on top of it) is from the previous or new playlist entry. The previous commit probably helps, but all the asynchronity is still a bit unhelpful. Try to make this better by adding new hooks, that are run before/after playback init/deinit. This is similar to the existing hooks, except they're outside of "initialized" playback, which excludes that you might accidentally get an overlap between the current and the previous/next playlist entry. That still doesn't seem quite enough, since normally, property change notifications come after the hook event. So basically a client would have to explicitly "drain" the event queue within the hook, and make the hook continue only after that is done. Knowing when property notifications are done is another asynchronous nightmare (how exactly it works keeps changing within client.c, and an API user probably can't tell anymore when all pending properties are truly done). So introduce another guarantee: properties that were changed before the hook happens will be returned before the hook event is returned. That means the client will have received all pending property notifications from the previous playlist entry (or whatever) before the hook is entered. As another minor complication, we shouldn't just keep the hook pending until _all_ property notifications are done, since the client's hook could produce new ones. (Or just consider things like the demuxer thread hammering the client with cache update events, while the "on_preloaded" hook is run.) So there is some extra untested, fragile logic in client.c to handle this (the waiting_for_hook flag). This probably works, but was barely tested. Not sure if this helps anyone, but I think it's fine for my own purposes. (I really hated this aspect of the API whenever I used it myself.)
* client API: avoid returning stale value on property notificationswm42020-03-061-4/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | This could happen if a property was flagged as changed, then updated, then flagged again, but gen_property_change_event() was called before the value was updated a second time. Then the function simply returned the old value, and would later trigger a new change event again. This was considered acceptable before, since property notifications are asynchronous anyway (so they may always be "outdated", it just mattered whether the most recent value was eventually delivered). But consider ordering with events. It seems desirable that specific important events (e.g. MPV_EVENT_START_FILE) should not be followed by property updates that happened before it, because that would make application logic really a mess, and property notification near-useless in certain cases. Avoid this by never returning a value if it was marked changed, but not updated yet. Unfortunately, this could lead to clients never receiving a value (or receiving it with a high random delay), if they're too slow to read it (or the property simply updates too often). Note that this is done for _all_ property notifications, not just returned events. Hopefully not a problem in practice. If it turns out to be one, this mechanism could be restricted to actually returned events, for which this really matters.
* command: remove legacy hook APIwm42020-03-063-63/+10
| | | | | Hopefully nothing uses this. (I know one exception, but, well, what can I do.)
* command: extend osd-overlay command with bounds reportingwm42020-03-062-1/+18
| | | | | | | | | | | | | | | | | | | | This is more or less a minimal hack to make _some_ text measurement functionality available to scripts. Since libass does not support such a thing, this simply uses the bounding box of the rendered text. This is far from ideal. Problems include: - using a bitmap bounding box - additional memory waste and/or flushing caches - dependency on window size - odd small deviations with different window sizes (run osd-test.lua and resize the window after each timer update; the bounding boxes aren't adjusted in an overly useful way) - inability to query the size _after_ actual rendering But I guess it's a start. Since I'm aware that it's crap, add a threat to the manpage that this may be changed/removed again. For now, I'm interested whether anyone will have use for it in its current form, as it's an often requested feature.
* player: force update of cache properties even on inactive demuxer cachewm42020-03-052-1/+7
| | | | | | | | | | | | | | | | | | | | | | | | | When the demuxer cache read until the end of the stream, and was finished and completely inactive, the cache properties were not updated anymore via MP_EVENT_CACHE_UPDATE. Unfortunately, many cache properties depend on the current playback position, such as cache-duration or fw-bytes. This is especially visible on the OSC. If everything was cached, seeking around didn't update the displayed forward cache duration. That means checking demuxer_reader_state.idle is not enough. You also need to check whether the current playback position changed. Fix this by explicitly using the current playback position, and update the properties if it changed "enough". "Enough" is 1 second of media time in this example, which may or may not be appropriate. In general, this could probably be done better. There are many other triggers that change the cache state and that are not covered. For now I'm content with getting rid of the obvious problems. I think the OSC problem in particular was caused by changing it from polling to using property change notifications.
* player: reduce impact of blocking filterswm42020-03-051-0/+1
| | | | | | | | | | | | | | | | | | | | Some filters may block the playloop for a longer time. For example, if a decoder fails to decode anything and somehow just discards packets, the filter graph would run (in a blocking manner) until all packets are read, which could take a longer time if the demuxer thread is fast enough. Make it exit every 100ms. That should at least give the user a chance to stop playback. Filtering could run on a different thread, but I don't see much value in doing that in the general case. It would just waste a thread. Although being able to use mp_filter_graph_interrupt() would be slightly nicer than such a timeout mechanism. Decoding in particular can actually use a separate thread (--vd-queue-enable), but again, this is not enabled by default, because it just wastes a thread. Like the previous f_decoder_wrapper commit, this is probably a sin.
* options: make decoder options local to decoder wrapperwm42020-03-013-20/+3
| | | | | | | | | | | | | | | Instead of having f_decoder_wrapper create its own copy of the entire mpv option tree, create a struct local to that file and move all used options to there. movie_aspect is used by the "video-aspect" deprecated property code. I think it's probably better not to remove the property yet, but fortunately it's easy to work around without needing special handling for this option or so. correct_pts is used to prevent use of hr-seek in playloop.c. Ignore that, if you use --no-correct-pts you're asking for trouble anyway. This is the only behavior change.
* player: add optional separate video decoding threadwm42020-02-291-1/+11
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | See manpage additions. This has been a topic in MPlayer/mplayer2/mpv since forever. But since libavcodec multi-threaded decoding was added, I've always considered this pointless. libavcodec requires you to "preload" it with packets, and then you can pretty much avoid blocking on it, if decoding is fast enough. But in some cases, a decoupled decoder thread _might_ help. Users have for example come up with cases where decoding video in a separate process and piping it as raw video to mpv helped. (Or my memory is false, and it was about vapoursynth filtering, who knows.) So let's just see whether this helps with anything. Note that this would have been _much_ easier if libavcodec had an asynchronous (or rather, non-blocking) API. It could probably have easily gained that with a small change to its multi-threading code and a small extension to its API, but I guess not. Unfortunately, this uglifies f_decoder_wrapper quite a lot. Part of this is due to annoying corner cases like legacy frame dropping and hardware decoder state. These could probably be prettified later on. There is also a change in playloop.c: this is because there is a need to coordinate playback resets between demuxer thread, decoder thread, and playback logic. I think this SEEK_BLOCK idea worked out reasonably well. There are still a number of problems. For example, if the demuxer cache is full, the decoder thread will simply block hard until the output queue is full, which interferes with seeking. Could also be improved later. Hardware decoding will probably die in a fire, because it will run out of surfaces quickly. We could reduce the queue to size 1... maybe later. We could update the queue options at runtime easily, but currently I'm not going to bother. I could only have put the lavc wrapper itself on a separate thread. But there is some annoying interaction with EDL and backward playback shit, and also you would have had to loop demuxer packets through the playloop, so this sounded less annoying. The food my mother made for us today was delicious. Because audio uses the same code, also for audio (even if completely pointless). Fixes: #6926
* f_decoder_wrapper: replace most public fields with setters/getterswm42020-02-295-19/+26
| | | | | | | | | | | | | | | | | | | I may (optionally) move decoding to a separate thread in a future change. It's a bit attractive to move the entire decoder wrapper to there, so if the demuxer has a new packet, it doesn't have to wake up the main thread, and can directly wake up the decoder. (Although that's bullshit, since there's a queue in between, and libavcodec's multi-threaded decoding plays cross-threads ping pong with packets anyway. On the other hand, the main thread would still have to shuffle the packets around, so whatever, just seems like better design.) As preparation, there shouldn't be any mutable state exposed by the wrapper. But there's still a large number of corner-caseish crap, so just use setters/getters for them. This recorder thing will inherently not work, so it'll have to be disabled if threads are used. This is a bit painful, but probably still the right thing. Like speculatively pulling teeth.
* player: remove delayed audio seek thingwm42020-02-293-51/+0
| | | | | | | | | | | | | | | | | | | | | | | | This was a hack that attempted to line up external audio tracks with video. The problem is that if you do a keyframe seek backwards, video will usually seek much farther back than audio (due to much higher keyframe aka seek point distances). The hack somehow made seeking a 2 step process. This existed in 4 different forms in the history of this code base, and it was always very cumbersome. We mostly needed this for ytdl_hook (I think?), which uses the 4th form, which is nicely confined to demux_timeline and is unrelated to the "external" audio tracks in the high level player. Since this is (probably) not really widely needed anymore, get rid of it. Better do this now, than when somehow rewriting all the seeking code (which might happen in this decade or the next or so) and when it wouldn't be easily revertable anymore in case we find we "really" need it unlike expected. There is no issue if hr-seeks are used. Also, you can still use edl files to "bundle" multiple streams as if it was a single stream (this is what ytdl_hook does now).
* osc: use default hr-seek when dragging progress bar to seekwm42020-02-281-2/+5
| | | | | | | The "seekbarkeyframes" option is now interpreted such if it's true, the player default is used. Too lazy to make this a choice option or whatever; the Lua option parser doesn't have support for that anyway. Someone who cares can adjust this.
* player: dumb seeking related stuff, make audio hr-seek defaultwm42020-02-286-47/+67
| | | | | | | | | | | | | | | | | | | | | | | | | | Try to deal with various corner cases. But when I fix one thing, another thing breaks. (And it's 50/50 whether I find the breakage immediately or a few months later.) So results may vary. The default for--hr-seek is changed to "default" (not creative enough to find a better name). In this mode, audio seeking is exact if there is no video, or if the video has only a single frame. This change is actually pretty dumb, since audio frames are usually small enough that exact seeking does not really add much. But it gets rid of some weird special cases. Internally, the most important change is that is_coverart and is_sparse handling is merged. is_sparse was originally just a special case for weird .ts streams that have the corresponding low-level flag set. The idea is that they're pretty similar anyway, so this would reduce the number of corner cases. But I'm not sure if this doesn't break the original intended use case for it (I don't have a sample anyway). This changes last-frame handling, and respects the duration of the last frame only if audio is disabled. This is mostly "coincidental" due to the need to make seeking past EOF trigger player exit, and is caused by setting STATUS_EOF early. On the other hand, this might have been this way before (see removed chunk close to it).
* player: attempt to fix playback end on hr-seeking past EOF againwm42020-02-281-3/+6
| | | | | | | | | | This tries to fix #7206 (hr-seeking past EOF does not stop playback) again. Commit 57fbc9cd76f7 should have fixed this, but trying it again (using that git revision), it often did not work. Whatever the fuck. So add another dumb special case that will break within weeks. Note that the check in handle_eof() had no effect, since execute_queued_seek() is called later, which cancels EOF in the same case.
* player: set playback_pts in hr-seek past EOF casewm42020-02-285-7/+11
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Hr-seek past the last frame instantly enters EOF, which means handle_playback_time() will not set playback_pts to the video PTS (as all video frames are skipped), which leads to the playback time being taken from the last seek target. This results in confusing behavior, especially since the seek time will be clipped to the file duration for display, but not for further relative seeks. Obviously, the time should be set to the last video frame, so use the last video frame as fallback if both audio and video have ended. Also, since the same problem exists with audio-only playback, add a fallback for audio PTS too. We don't know which was the "last" fragment of media played (to decide whether to use the audio or video PTS as the fallback), but it doesn't matter since the maximum works. This could lead to some undesired effects. In particular the audio PTS is basically a bad guess, and is for example not clipped against --end. (But the ridiculous way audio syncing and clamping currently works, I'm not going to touch that shit unless I rewrite it completely.) The cover art case is slightly broken: using --keep-open with keyframe seeks will result in 0 as playback PTS (the video PTS). OK, who cares, it got late. Also casually get rid of last_vo_pts, since that barely made any sense at all. Fixes: #7487
* player: remove stale last frame referenceswm42020-02-281-2/+5
| | | | | | | | | | | | | | | | | The seeking logic saves the last video frame it has seen (for example for being able to seek to the last frame, or backstepping). Unfortunately, the frame was fed back to the filtering pipeline in situations when it shouldn't have. Then it's an out of order frame, because it really saves the last _discarded_ frame. For example, seeking to the end of a file with --keep-open, shift+up, shift+down => invalid video pts warning due to saved_frame being fed back. Explicitly discard saved_frame when it's obviously not needed anymore. The removed accesses to "r" are strictly speaking unrelated (just const-propagating them).
* command: remove unintended newlinewm42020-02-271-1/+1
| | | | This just made it print a blank line.
* scripting: fix racy crash if loading .run files failswm42020-02-251-0/+3
| | | | | | | | | args->client was deallocated if the FDs were closed and nothing referenced it (IPC socket codes detected the closed sockets and asynchronously killed the mpv_handle in args->client). The problem was that args->log depended on it, and was also destroyed. Fix this by duplicating the mp_log.
* ta: remove two pointless wrapperswm42020-02-232-2/+2
|
* client API: fix race condition on client exitwm42020-02-231-1/+1
| | | | | | | | | | | | | | | | | | | | | | | The relatively recently added property update code has a race condition when clients exit. It still tried to access mpv_handle during and after it was destroyed. The reason is that it unlocks the lock for the mpv_handle list (while mpv_handle is locked), but nothing in mp_destroy_client() cares about this case. The latter function locks mpv_handle only before/while it makes sure all of its activity is coming to an end, such as asynchronous requests, and property updates that are in progress. It did not include the case when mp_client_send_property_changes() was still calling send_client_property_changes() with mpv_handle locked. Fix this by checking the mpv_handle.destroying field. This field can be set only when mpv_handle is locked. While we're checking the lock, the mpv_handle list is still locked, so at worst we might be at the point before mp_destroy_client() locks the list again and finally destroys the mpv_handle. This is a hard to reproduce race condition which I spotted only once in valgrind by chance, so the fix is unconfirmed.
* ytdl_hook: fix URL extraction for manifestssfan52020-02-231-4/+4
|
* ytdl_hook: prefer "format" over "format_note" field for track titleswm42020-02-211-1/+1
| | | | | Much more verbose, but on the other hand format_note is useless for the alphabetic site with fragmented DASH streams.
* ytdl_hook: use "format" as fallback for "format_note" for stream titleswm42020-02-211-1/+1
| | | | | "format_note" normally contains a semi-informative description of the format. But some extractors, confusingly, have it in the "format" field.
* ytdl_hook: fix audio codec with some extractorswm42020-02-211-5/+11
| | | | | E.g. soundcloud. While it still worked, not having the audio codec was pretty annoying.
* ytdl_hook: fix Lua escapeswm42020-02-211-3/+3
| | | | | | This was obviously nonsense. In Lua 5.1 this appeared to work correctly, but it really turned "\." into "." (making the pattern accept any character). The proper way is using "%" for escaping.
* ytdl_hook, edl: add fps, samplerate codec parameterswm42020-02-211-2/+9
| | | | Well, didn't help much in the case I was interested it.
* ytdl_hook: make codec mapping more declarativewm42020-02-211-12/+9
|
* ytdl_hook: remove some old playlist redirection hackwm42020-02-211-6/+0
| | | | Should not be needed anymore. In fact, it's probably dangerous.
* ytdl_hook: enable default selection via --ytdl-format with all_formatswm42020-02-211-1/+25
| | | | | | | | | In all_formats mode, we've ignored what --ytdl-format did so far, since we've converted the full format list, instead of just the formats selected by youtube-dl. But we can easily restore --ytdl-format behavior: just mark the selected tracks as default tracks.
* ytdl_hook: add length parameter to delay-loaded tracks only oncewm42020-02-211-3/+3
| | | | | This was done for each media type, so muxed tracks had it twice, which logged a dumb warning. Move it out of the per-media type loop.
* ytdl_hook: remove bitrate estimation from file sizewm42020-02-211-4/+0
| | | | | I think this is unnecessary, and at worst done by youtube-dl itself (didn't check).
* ytdl_hook: use tbr for all tracks if vbr/abr not availablewm42020-02-211-0/+9
| | | | | | | | | | | | | | | | | | vbr and abr are the video and audio bitrates. Sometimes there is a weird mix of any of them available, but in these cases, it's not good to fall back to tbr if a specific track has no vbr/abr. For example, the alphabetic site provides tbr only for the muxed fallback stream, but using tbr would make the primitive mpv hls_bitrate selection pick the compatibility stream for audio, because it appears to have a higher bitrate than the other audio-only streams (because the bitrate includes video). So we must not use tbr in this case. On the other hand, formats coming from youtube-dl HLS master playlist use will only have tbr set. So as a heuristic, use the tbr only if it's the only bitrate available in any track entry.
* ytdl_hook: replace skip_muxed with force_all_formats optionwm42020-02-211-26/+10
| | | | | | | | | | | | | I don't think the skip_muxed option was overlay useful. While it was nice to filter out the low quality muxed versions (as it happens on the alphabetic site, I suspect it's compatibility stuff), it's not really necessary, and just makes for another tricky and rarely used configuration option. (This was different before muxed tracks were also delay-loaded, and including the muxed versions slowed down loading.) Add the force_all_formats option instead, which handles the HLS case. Set it to true because they are also delay-loaded now, and don't slow down startup as much.
* ytdl_hook: delay-load interleaved fileswm42020-02-211-23/+36
| | | | | | (Or if it's about HLS, just "muxed"/multiplexed streams.) This only affects all_formats=yes,skip_muxed=no modes.
* ytdl_hook: signal duration in all_formats modewm42020-02-201-1/+6
| | | | | | If all streams were delay loaded, there was actually no duration present at all in the EDL metadata. So the length was considered unknown by the player frontend.
* ytdl_hook: attempt to filter out muxed streams if all_formats is usedwm42020-02-201-74/+147
| | | | | | | | | | | | | See manpage additions. We would have to extend delay_open to support multiple sub-tracks (for audio and video), and we'd still don't know (?) whether it might contain more than one stream each (thinking of HLS master streams). And if it's a true interleaved file (such as a "normal" mp4 file provided as fallback for more primitive players), we'd either have to signal such "bundled" tracks, or waste bandwidth. This restructures a lot. The if/else tree in add_single_video for format selection was a bit annoying, so it's split into separate if blocks, where it checks each time whether a URL was determined yet.
* ytdl_hook: remove forgotten debug messagewm42020-02-201-1/+0
| | | | It even has a typo.
* ytdl_hook: use bitrate fields for bitrate metadata instead of file sizeswm42020-02-201-1/+8
| | | | If available.
* ytdl_hook: try to skip interleaved streams with all_formatswm42020-02-201-2/+11
| | | | | | | | | | | | | | | | | If a "format" has both audio and video codec set, it might contain both audio and video. all_format assumes that each format is just a quality variant containing a single track. This seems to happen with sites that provide a HLS master URL. youtube-dl tends to "butcher" it, and the result isn't very ideal. I guess HLS "renditions" simply don't