summaryrefslogtreecommitdiffstats
path: root/player/loadfile.c
Commit message (Collapse)AuthorAgeFilesLines
* player: remove duplicated track option setter codewm42020-04-151-7/+5
| | | | Well whatever.
* player: slightly improve use of secondary track selection limitswm42020-04-151-11/+9
| | | | | | Apparently, this was a bit of a mess, which caused the bug fixed by commit ec7f2388af2df. Try to improve this, and only use track selection entries that exist.
* player: don't segfault when unloading tracksNiklas Haas2020-04-151-0/+2
| | | | | | | | | e1e714ccc introduced a regression here when unloading a track (e.g. on VO/AO initilization error), due to no corresponding option existing for video/audio tracks with orders above 0, but the loop in `mp_deselect_track` being hard-coded to clear tracks up to NUM_PTRACKS. Introduce the simplest possible hackaround.
* player: do not fall back to a default track with explicit selectionswm42020-04-131-0/+2
| | | | | | | | | | | | | | | | | | Consider e.g. --aid=2 with a file that has only 1 track. Then it would fall back to selecting track 1. Stop doing this. If no matching track is found, this will not select any track now. Note that the fingerprint stuff (track_layout_hash in the source) prevents softens the impact of this change. Without the fingerprint, playing a dual-audio file with the second track selected, and then a single-audio file, would play the second file without audio. But the fingerprint resets it due to differences in the track list. Try to exhaustively document this and tricky interactions between the other features. What a damn mess, I think it's simply cursed. Of course it's still my fault. See: #7608
* player: mess with track selection details againwm42020-04-131-12/+30
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Some time ago, properties and options were mostly unified. However, the track selection properties/options semantics are incompatible to this change. I'm still trying to handle the fallout. There are two things that are in the way: 1. Track properties somehow return the runtime selection, not the option value (all while properties are supposed to be aliases to options with the same name). 2. The user's track options are not supposed to be changed without interaction. If a track is auto-selected, the property should return its ID, but the option value should remain at "auto". Only if the user actually writes to the property the option should change. E.g. playing e.g. an audio-only file and then a normal video file not play the video file with --vid=no just because the audio file had no video track. In addition to each of them being in conflict with the property/option unification, attempt to fix one of them breaks the other one. Today, we're trying to fix parts of this and avoiding an unfortunate case where you can get a conflicting option/property value, and where trying to select a track does nothing if the track to select has the same ID as the option value. This breaks 2. from above in certain situations. See manpage additions. See: #7608
* player, stats: more silly debug stuffwm42020-04-101-2/+1
| | | | | In addition to stats.c being gross, I don't think master branch code should be littered with debug code. But it's a helpful abomination.
* player: do not deinitialize AO on track switchingwm42020-04-091-1/+2
| | | | | | | | This should make it behave roughly like when switching from a file to the next (clearing audio buffers, keeping AO, but closing AO if the audio format seems to have changed and gapless mode is "weak"). Not necessarily useful, but harmless and may help with #7579 (untested).
* stats: some more performance graphswm42020-04-091-0/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | Add an infrastructure for collecting performance-related data, use it in some places. Add rendering of them to stats.lua. There were two main goals: minimal impact on the normal code and normal playback. So all these stats_* function calls either happen only during initialization, or return immediately if no stats collection is going on. That's why it does this lazily adding of stats entries etc. (a first iteration made each stats entry an API thing, instead of just a single stats_ctx, but I thought that was getting too intrusive in the "normal" code, even if everything gets worse inside of stats.c). You could get most of this information from various profilers (including the extremely primitive --dump-stats thing in mpv), but this makes it easier to see the most important information at once (at least in theory), partially because we know best about the context of various things. Not very happy with this. It's all pretty primitive and dumb. At this point I just wanted to get over with it, without necessarily having to revisit it later, but with having my stupid statistics. Somehow the code feels terrible. There are a lot of meh decisions in there that could be better or worse (but mostly could be better), and it just sucks but it's also trivial and uninteresting and does the job. I guess I hate programming. It's so tedious and the result is always shit. Anyway, enjoy.
* client API: report IDs of inserted playlist entries on loading playlistwm42020-03-271-6/+9
| | | | | | May or may not help when dealing with playlist loading in scripts. It's supposed to help with the mean fact that loading a recursive playlist will essentially edit the playlist behind the API user's back.
* client API: add a playlist entry unique IDwm42020-03-211-2/+8
| | | | | | This should make dealing with some async. things easier. It's intentionally not a globally unique ID.
* player: add potentially forgotten property change triggerwm42020-03-211-0/+1
| | | | | | Unfortunately, merely changing the playlist current position affects the flags returned by the "playlist" property, so the entirely thing needs to be marked as changed. Seems to be a design mistake.
* player: add a number of new playlist contol commands/propertieswm42020-03-211-2/+2
| | | | | | | | | | | | | | | | | | | | | | | Should give a good deal more explicit control and insight over the player state. Some feel a bit pointless, and/or expose internal weirdness. However, it's not like the existing weirdness didn't exist before, or can be made go away. (In part, the weirdness is because certain in-between states are visible. Hiding them would make things simpler, but less flexible.) Maybe this actually gives users a better idea how the API _should_ look like, too. On a side note, this tries to really guarantee that mpctx->playing is set between playback start/end. For that, the loadfile.c changes assume that mpctx->playing is set (guaranteed by code above the change), and that playing->filename is set (probably could never be false; was broken before and actually would have crashed if that could ever happen; in any case, also add an assert to playlist.c for this). playlist_entry_to_index() now tolerates playlist_entrys that are not part of the playlist. This is also needed for mpctx->playing.
* player: playlist-pos now use -1 for "no entry selected"wm42020-03-211-1/+1
| | | | | | | | | | | | | | | | | | | | | It's odd that this state is observable, but is made implicit by making the property unavailable. It's also odd that an API user cannot directly put the player into such a state. Just allow reading/writing -1 (or in fact, any out of bounds index) for this case. I'm also refraining from using OPT_CHOICE for the "no selection" case, because although that would be cleaner in theory, it would cause only problems to API users due to the more complex property type (worse is better). One reason for not restricting the integer range on the input property anymore is that if there are no playlist elements, the range would contain only 1 integer, which cannot be represented anymore since the recent m_option change. This was actually broken with 1 element playlists before (and still is, with the constricted type for OSD and the add/cycle commands). Doesn't matter too much.
* player: fix subtle idle mode differences on early program startwm42020-03-211-6/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | If the user manages to run a "loadfile x append" command before the loop in mp_play_files() is entered, then the player could start playing these. This isn't expected, because appending files to the playlist in idle mode does not normally start playback. It could happen because there is a short time window where commands are processed before the loop is entered (such as running the command when a script is loaded). The idle mode semantics are pretty weird: if files were provided in advance (on the command line), then these should be played immediately. But if idle mode was already entered, and something is appended to the playlist using "append", i.e. without explicitly triggering playback, then it should remain in idle mode. Try to follow this by redefining PT_STOP to strictly mean idle mode. Remove the playlist->current check from idle_loop(), since only the stop_play field counts now (cf. what mp_set_playlist_entry() does). This actually introduces the possibility that playlist->current, and with it playlist-pos, are set to something, even though playback is not active or being started. Previously, this was only possible during state transitions, such as when changing playlist entries. Very annoyingly, this means the current way MPV_EVENT_IDLE was sent doesn't work anymore. Logically, idle mode can be "active" even if idle_loop() was not entered yet (between the time after mp_initialize() and before the loop in mp_play_files()). Instead of worrying about this, redo the "idle-active" property, and deprecate the event. See: #7543
* player: actually report an exit error if encoding mode fails on closingwm42020-03-211-1/+1
| | | | | | | | | | | The code that determines the process exit code ignores all stop_play values other than PT_QUIT. Generally, PT_ERROR is meaningless outside of play_current_file(), and is mostly equivalent to PT_NEXT_ENTRY. Do something that makes it report a non-0 exit code, and indicates in the terminal exit message that something went wrong. Untested.
* filter: minor cosmetic naming issuewm42020-03-081-1/+1
| | | | | Just putting some more lipstick on the pig, maybe it looks a bit nicer now.
* 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: provide ways to finish property changes on file changeswm42020-03-071-2/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.)
* 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.
* player: remove delayed audio seek thingwm42020-02-291-6/+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).
* player: set playback_pts in hr-seek past EOF casewm42020-02-281-1/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | 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: change bitrate in track listing back to kilobitswm42020-02-201-1/+1
| | | | Because the --hls-bitrate option takes the same unit.
* player: print manifest per-stream bitrate information to terminalwm42020-02-191-0/+2
| | | | | Aka hls-bitrate. In turn, remove the demux_lavf.c hack, which made the track title use this.
* playlist: change from linked list to an arraywm42019-12-281-12/+10
| | | | | | | | | | | | | | | | | | | Although a linked list was ideal at first, there are cases where it sucks, and became increasingly awkward (with the mpv command API preferring integer indexes to access the list). In future, we probably want to add more playlist-related functionality, so better change it to an array now. An array isn't always ideal either. Since playlist entries are still separate objects (because in some cases you need a stable "iterator" to it), but you still need to efficiently get the next/previous playlist entry, there's a pl_index field, that needs to be maintained. E.g. adding an entry at the start of the playlist => update the pl_index field for all other entries. Well, it's not really worth to do something more complicated to avoid these things. This commit is probably buggy as shit. It's not like I bothered to test everything. That's _your_ role.
* stream, demux: redo origin policy thingwm42019-12-201-11/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | mpv has a very weak and very annoying policy that determines whether a playlist should be used or not. For example, if you play a remote playlist, you usually don't want it to be able to read local filesystem entries. (Although for a media player the impact is small I guess.) It's weak and annoying as in that it does not prevent certain cases which could be interpreted as bad in some cases, such as allowing playlists on the local filesystem to reference remote URLs. It probably barely makes sense, but we just want to exclude some other "definitely not a good idea" things, all while playlists generally just work, so whatever. The policy is: - from the command line anything is played - local playlists can reference anything except "unsafe" streams ("unsafe" means special stream inputs like libavfilter graphs) - remote playlists can reference only remote URLs - things like "memory://" and archives are "transparent" to this This commit does... something. It replaces the weird stream flags with a slightly clearer "origin" value, which is now consequently passed down and used everywhere. It fixes some deviations from the described policy. I wanted to force archives to reference only content within them, but this would probably have been more complicated (or required different abstractions), and I'm too lazy to figure it out, so archives are now "transparent" (playlists within archives behave the same outside). There may be a lot of bugs in this. This is unfortunately a very noisy commit because: - every stream open call now needs to pass the origin - so does every demuxer open call (=> params param. gets mandatory) - most stream were changed to provide the "origin" value - the origin value needed to be passed along in a lot of places - I was too lazy to split the commit Fixes: #7274
* player: loadfile overrides previous stop commandwm42019-12-061-1/+1
| | | | | | | | | | | | | | | | Both the "stop" and "loadfile" commands are asynchronous. "stop" starts terminating playback, which used to be done in the same playloop iteration, but now it may take longer, so a "loadfile" command can be received while this is going on. (Possible that it used to work if the second command was issued at least in the next playloop iteration.) Make the "loadfile" override the "stop" mode, so the next file will be played, instead of quitting or going into idle mode. Unlike the referenced bug report claims, this has nothing to do with IPC. Fixes: #7225
* player: change m_config to use new option handling mechanismswm42019-11-291-5/+16
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Instead of making m_config a special-case, it more or less uses the underlying m_config_cache/m_config_shadow APIs properly. This makes the player core a (relatively) equivalent user of the core option API. In particular, this means that other threads can change core options with m_config_cache_write_opt() calls (before this commit, this merely led to diverging option values). An important change is that before this commit, mpctx->opts contained the "master copy" of all option data. Now it's just another copy of the option data, and the shadow copy is considered the master. This is why whenever mpctx->opts is written, the change needs to be copied to the master (thus why this commits add a bunch of m_config_notify... calls). If another thread (e.g. a VO) changes an option, async_change_cb is now invoked, which funnels the change notification through the player's layers. The new self_notification parameter on mp_option_change_callback is so that m_config_notify... doesn't trigger recursion, and it's used in cases where the change was already "processed". It's still needed to trigger libmpv property updates. (I considered using an extra m_config_cache for that, but it'd only cause problems with no advantages.) I think the recent changes actually forgot to send libmpv property updates in some cases. This should fix this anyway. In some cases, property updates are reworked, and the potential for bugs should be lower (probably). The primary point of this change is to allow external updates, for example by a VO writing the fullscreen option if the window state is changed by the window manager (rather than mpv changing it). This is not used yet, but the following commits will.
* player: remove mechanisms for better logging with repl.luawm42019-11-181-0/+3
| | | | | | | | | | | | | | | | | | | | | | As preparation for making repl.lua part of the core (maybe), add some mechanisms which are supposed to improve its behavior. Add a silent mode. Calling mpv_request_log_messages() with the log level name prefixed with "silent:" will disable logging from the API user's perspective. But it will keep the log buffer, and record new messages, without returning them to the user. If logging is enabled again by requesting the same log level without "silent:" prefix, the buffered log messages are returned to the user at once. This is not documented, because it's far too messy and special as that I'd want anyone to rely on this behavior, but it will be perfectly fine for an internal script. Another thing is that we record early startup messages. The goal is to make the repl.lua script show option and config parsing file errors. This works only with the special "terminal-default" log level. In addition, reduce the "terminal-default" capacity to only 100 log messages. If this is going to be enabled by default, it shouldn't use too much resources.
* options: remove M_SETOPT_RUNTIMEwm42019-11-101-1/+1
| | | | | | | Used to contain flags for "save" setting of options at runtime. Now there is nothing special needed anymore and it's 0. So drop it completely, and remove anything that distinguishes between runtime and initialization time.
* player: avoid duplicate track auto selectionStephan Hilb2019-10-181-1/+14
| | | | | | | | | Since a track may not be selected twice, it makes sense e.g. for secondary subtitles to select the next best match and avoid the duplicate selection. This allows for example `--slang=en,ja --secondary-sid=auto` to select 'en' as primary and 'ja' as secondary without needing to know the actual sid for 'ja'.
* player: don't load external files when reading from stdinckath2019-10-061-1/+1
|
* loadfile: make prefetching actually workwm42019-09-291-1/+3
| | | | | | | | | | | | | | | | Looks like this didn't actually work. Prefetching will do nothing if there isn't a thread to "drive" it, and the demuxer thread needs to be explicitly enabled. (I guess I did the worst possible job in verifying whether this actually worked when I implemented it. On the other hand, the user didn't confirm back whether it worked, so who cares.) Like in the previous commit, bad factoring makes everything worse. It duplicates logic and implementation of enable_demux_thread(), since the opener thread cannot access the mpctx->opts field freely. But it's deep night, so fuck it. Fixes: c1f1a0845e03885e Fixes: #6753
* loadfile: don't always accidentally always prefetchingwm42019-09-291-11/+15
| | | | | | | | | | | | | | demux_start_prefetch() was called unconditionally in two cases. This is completely wrong. I'm not sure what part of my brain died off that something this obviously wrong went in. The prefetch case is a bit more complicated. It's a different thread, so you can't access just access mpctx->opts there. So add an explicit field for this, which is the simplest way to get this done. (Even if it's bad factoring.) Fixes: c1f1a0845e03885eebe63 Fixes: 556e204a112ee286972e5
* recorder: don't use a magic index for mp_recorder_get_sink()wm42019-09-291-1/+1
| | | | | | | | | | | | | | | | | | | Although this was sort of elegant, it just seems to complicate things slightly. Originally, the API meant that you cache mp_recorder_sink yourself (which would avoid the mess of passing an index around), but that too seems slightly roundabout. In a later change, I want to change the set of streams passed to mp_recorder_create(), and then I'd have to keep track of the index for each stream, which would suck. With this commit, I can just pass the unambiguous sh_stream to it, and it will be guaranteed to match the correct stream. The disadvantages are barely worth discussing. It's a new linear search per packet, but usually only 2 to 4 streams are active at a time. Also, in theory a user could want to write 2 streams using the same sh_stream (same metadata, just writing different packets or so), but in practice this is never done.
* player: use track title if exists instead of filenamethewisenerd2019-09-211-1/+5
|
* loadfile: restore playlist prefetchingwm42019-09-201-4/+11
| | | | | | | | | | | | | | | | | | | | | | | With the stream cache gone, this function had almost no use anymore (other than opening the stream). Improve this by triggering demuxer cache readahead. This enables all streams. At this point we can't know yet what streams the user's options would select (at least not without great additional effort). Generally this is what you want, and the stream cache would have read the same amount of data. In addition, this will work much better for files that e.g. need to seek to the end when opening (typically mp4, and mkv files produced by newer mkvmerge versions). Remove the deselection call from add_stream_track(). This should be fine, as streams normally start out as deselected anyway. In the prefetch case, some code in play_current_file() actually deselects it. Streams that appear during demuxing are disabled by default, so this doesn't break this logic either. Fixes: #6753
* demux, command: add a third stream recording mechanismwm42019-09-191-0/+2
| | | |