summaryrefslogtreecommitdiffstats
path: root/player
Commit message (Collapse)AuthorAgeFilesLines
* client API: kill async commands on terminationwm42018-05-243-14/+46
| | | | | | | | | | | This affects async commands started by client API, commands with async capability run in a sync way by client API (think mpv_command_node() with "subprocess"), and detached async work. Since scripts might want to do some cleanup work (that might involve launching processes, don't ask), we don't unconditionally kill everything on exit, but apply an arbitrary timeout of 2 seconds until async commands are aborted.
* lua: expose mpv_abort_async_command()wm42018-05-242-3/+26
| | | | Also somewhat cleans up mp.command_native_async() error handling.
* command: make "subprocess" explicitly abortablewm42018-05-241-5/+7
| | | | Now mpv_abort_async_command() can be used to stop the process.
* command: add a way to abort asynchronous commandswm42018-05-248-9/+131
| | | | | | | | | | | | Many asynchronous commands are potentially long running operations, such as loading something from network or running a foreign process. Obviously it shouldn't just be possible for them to freeze the player if they don't terminate as expected. Also, there will be situations where you want to explicitly stop some of those operations explicitly. So add an infrastructure for this. Commands have to support this explicitly. The next commit uses this to actually add support to a command.
* player: rename "lock" to "abort_lock"wm42018-05-243-12/+12
| | | | | | If a struct as large as MPContext contains a field named "lock", it creates the impression that it is the primary lock for MPContext. This is wrong, the lock just protects a single field.
* lua: reimplement mp.subprocess_detached() by invoking the "run" commandwm42018-05-242-30/+4
| | | | | | | | The "run" command is old. I'm not sure why the separate Lua implementation was added. But maybe it as because the "run" command used to be limited to a small number of arguments. This limit has been removed a while ago. In any case, the old implementation is not needed anymore.
* lua: reimplement mp.subprocess() by invoking the new subprocess commandwm42018-05-243-79/+24
| | | | | | | We keep mp.subprocess() with roughly the same semantics for compatibility with scripts (including the internal ytdl script). Seems to work with rhe ytdl wrapper. Not tested further.
* command: add a subprocess commandwm42018-05-241-0/+96
| | | | | | | This supports named arguments. It benefits from the infrastructure of async commands. The plan is to reimplement Lua's utils.subprocess() on top of it.
* video: trust container FPS early on if possiblewm42018-05-241-1/+2
| | | | | If the container FPS is correct, this can help getting ideal mix factors for vo_gpu interpolation mode. Otherwise, it doesn't matter.
* input: add a define for the number of mouse buttons and use itwm42018-05-241-1/+1
| | | | (Why the fuck are there up to 20 mouse buttons?)
* lua: expose async commandswm42018-05-242-0/+40
| | | | Might be useful for some.
* screenshot: report success to callerwm42018-05-241-3/+7
| | | | Matters only to API callers, but still nice to have.
* client API: merge status_reply() helper with only remaining callerwm42018-05-241-12/+5
| | | | | All other callers had to be changed, so there's no point in keeping this helper function around. It's just another unnecessary indirection.
* client API: add returning of data from async commandswm42018-05-241-5/+10
| | | | This was not done sooner out of laziness.
* screenshot: change async behavior to be in line with new semanticswm42018-05-243-115/+75
| | | | | | | | | | | | | | | | | | | | | | Basically reimplement the async behavior on top of the async command code. With this, all screenshot commands are async, and the "async" prefix basically does nothing. The prefix now behaves exactly like with other commands that use spawn_thread. This also means using the prefix in the preset input.conf is pointless (without effect) and misleading, so remove that. The each_frame mode was actually particularly painful in making this change, since the player wants to block for it when writing a screenshot, and generally doesn't fit into the new infrastructure. It was still relatively easy to reimplement by copying the original command and then repeating it on each frame. The waiting is reentrant now, so move the call in video.c to a "safer" spot. One way to observe how the new semantics interact with everything is using the mpv repl script and sending a screenshot command through it. Without async flag, the script will freeze while writing the screenshot (while playback continues), while with async flag it continues.
* command: move screenshot command stubs to screenshot.cwm42018-05-243-67/+66
| | | | | | | | | | Commands are not a monolithic giant switch() statement anymore, but individual functions. There's no reason to have the command handlers themselves in command.c, with a weird under-defined API in between. (In the future, I'd like to split up command.c further, and when I do that, scrrenshot.c will probably gets its own mp_cmd_def[] array, and define the commands locally instead of exporting the raw handlers.)
* player: make all external file loading actions asyncwm42018-05-243-22/+91
| | | | | Still missing: not freezing when removing a track (i.e. closing demuxer) with the sub-remove/audio-remove/rescan-external-files commands.
* player: make abort during loading faster if ytdl_hook is usedwm42018-05-241-0/+7
| | | | | | | | | | | | | | | | Basically, the ytdl_hook script will not terminate the script, even if you change to a new playlist entry. This happens because ytdl_hook keeps the player core in an early loading stage, and the forceful playback abort is done only in the ermination code. This does not handle the "stop" and "quit" commands, which can still take longer than expected, but on the other hand have some weird special handling (see below). I'm not doing this out of laziness. Playback stopping will have to be somewhat redone anyway. Basically we want to give everything a chance to terminate, and if it doesn't work, we want to stop loading or playback forcefully after a small timeout. We also want to remove the mess with input.c's special handling of "quit" and some other commands (see abort_playback_cb stuff).
* player: don't even start loading external tracks when aborting loadingwm42018-05-241-1/+1
| | | | | | It seems the ytdl script like to continue loading external tracks even if loading was aborted. Trying to do so will still quickly fail, but not without a load of log noise. So check and error out early.
* command: make sub-add and audio-add commands asyncwm42018-05-243-7/+21
| | | | | | | | | | Pretty trivial, since commands can be async now, and the common code even provides convenience like running commands on a worker thread. The only ugly thing is that mp_add_external_file() needs an extra flag for locking. This is because there's still some code which calls this synchronously from the main thread, and unlocking the core makes no sense there.
* command: add infrastructure for async commandswm42018-05-247-44/+271
| | | | | | | | | | | | | | | | | | | | | | | | | | | This enables two types of command behavior: 1. Plain async behavior, like "loadfile" not completing until the file is fully loaded. 2. Running parts of the command on worker threads, e.g. for I/O, such as "sub-add" doing network accesses on a thread while the core continues. Both have no implementation yet, and most new code is actually inactive. The plan is to implement a number of useful cases in the following commits. The most tricky part is handling internal keybindings (input.conf) and the multi-command feature (concatenating commands with ";"). It requires a bunch of roundabout code to make it do the expected thing in combination with async commands. There is the question how commands should be handled that come in at a higher rate than what can be handled by the core. Currently, it will simply queue up input.conf commands as long as memory lasts. The client API is limited by the size of the reply queue per client. For commands which require a worker thread, the thread pool is limited to 30 threads, and then will queue up work in memory. The number is completely arbitrary.
* thread_pool: make it slightly less dumbwm42018-05-241-1/+1
| | | | | | | | | | | | The existing thread pool code is the most primitive thread pool possible. That's fine, but one annoying thing was that it used a static number of threads. Make it dynamic, so we don't need to "waste" idle threads. This tries to add threads as needed. If threads are idle for some time, destroy them again until a minimum number of threads is reached. Also change the license to ISC.
* client: merge can_terminate() functionwm42018-05-241-15/+12
| | | | | | | | | | | This has some tricky interactions. In particular, it requires the core to be locked due to reading outstanding_async, which is documented on the only caller only. It's probably better to merge it with its only caller. The new code should be strictly equivalent, other than the fact that it doesn't temporarily unlock+lock when entering the loop for the first time (which doesn't matter here).
* command: handle list commands like normal commandswm42018-05-241-7/+11
| | | | Pretty annoying.
* demux, player: fix playback of sparse video streams (w/ still images)Aman Gupta2018-05-243-3/+26
| | | | | | | | | | | | | | | Fixes several issues playing back mpegts with video streams marked as having "still images". For example, see this video which has frames only every 6s: https://s3.amazonaws.com/tmm1/music-choice.ts Changes include: - start playback right away, without waiting for first video frame - do not consider the sparse video stream in demuxer underrun detection - do not require multiple video frames for the VO - use audio as the master stream for demuxer metadata events - use audio stream for playback time Signed-off-by: Aman Gupta <aman@tmm1.net>
* stats: show sample format of audio tracksfan52018-05-171-0/+1
|
* ytdl_hook: try to set video track first if availableRicardo Constantino2018-05-031-4/+4
| | | | | | | Fixes `--ytdl-format="dash-fastly_skyfire-video-363357330+dash-fastly_skyfire_sep-audio-363357330" https://vimeo.com/108650530` This happened because the video track also had audio available and after adding it expecting an audio-only track, there were no more tracks with video.
* player: add more logging around buffering stateAman Gupta2018-05-031-2/+7
|
* command: fix condition for failure when parsing cycle-value paramswm42018-05-031-1/+1
| | | | | | Could make it behave differently (and leak memory) in certain cases. Basically, m_option_parse() randomly returns 0 or 1, but most time 1, with the difference due to legacy reasons that don't matter anymore.
* command: simplify option property initwm42018-05-031-22/+13
| | | | | | | The "if (prop.name)" check is redundant, because an assert above it implies that it never can be NULL. Deduplicate some code for initializing the "prop" variable.
* input: merge cmd_list.c with cmd.cwm42018-05-031-1/+1
| | | | | | It doesn't really make sense to keep a separate cmd_list.c file, which does _not_ contain a command list, but only a few minor helper functions.
* command: split big command handler switch into separate functionswm42018-05-032-775/+1014
| | | | | | | | | | | | | | | | | | | This gets rid of run_command() and its big switch statement, which was an idiotically big function of almost 1000 lines. The switch is replaced with a callback per command, and each command is now implemented in its own function. Command IDs are not needed anymore, so the mp_command_type enum disappears. There should be no functional changes, but since this refactors 64 commands, regressions are possible. The handler() parameter is void*, because in theory the input code is supposed to be independent of the player core code. For example, you should be able to reuse the command parser code for some other part of mpv. In practice, the variable containing command list is defined in the player core anyway, so you could say this doesn't work. But I'm still trying to hold onto this idea, so I went with void*.
* input: remove some explicit uses of command IDswm42018-05-031-11/+17
| | | | | | | | | | The plan is to remove the command ID enum. This will happen by replacing the big switch statement in command.c with dispatching to per-command callbacks. As preparation, remove uses of the command IDs outside of the actual dispatching mechanism. Also remove some instances of checking cmd->def for NULL. We now require this always to be set.
* input: move command list to command.cwm42018-05-031-0/+216
| | | | Preparation for more changes.
* build: make encoding mode non-optionalwm42018-05-035-25/+5
| | | | Makes it easier to not break the build by confusing the ifdeffery.
* encode: get rid of the output packet queuewm42018-05-032-0/+7
| | | | | | | | | | | | Until recently, ao_lavc and vo_lavc started encoding whenever the core happened to send them data. Since audio and video are not initialized at the same time, and the muxer was not necessarily opened when the first encoder started to produce data, the resulting packets were put into a queue. As soon as the muxer was opened, the queue was flushed. Change this to make the core wait with sending data until all encoders are initialized. This has the advantage that we don't need to queue up the packets.
* video: actually wait for last frame being rendered on EOFwm42018-05-031-1/+5
| | | | | | | | | | | | | | | | | | | The video timing code could just decide that EOF was reached before it was displayed. This is not really a problem for normal playback (if you use something like --keep-open it'd show the last frame anyway, otherwise it'd at best flash it on screen before destroying the window). But in encode mode, it really matters, and makes the difference between having one frame more or less in the output file. Fix this by waiting for the VO before starting the real EOF. vo_is_ready_for_frame() is normally used to determine when the VO frame queue has enough space to send a new frame. Since the VO frame queue is currently at most 1 frame, it being signaled means the remaining frame was consumed and thus sent to the VO driver. If it returns false, it will wake up the playloop as soon as the state changes. I also considered using vo_still_displaying(), but it's not reliable, because it checks the realtime of the frame end display time.
* command: change cycle-value command behaviorwm42018-04-291-73/+88
| | | | | | | | | | | | | | | | | | | | Instead of using an internal counter to keep track of the value that was set last, attempt to find the current value of the property/option in the value list, and then set the next value in the list. There are some potential problems. If a property refuses to accept a specific value, the cycle-values command will fail, and start from the same position again. It can't know that it's supposed to skip the next value. The same can happen to properties which behave "strangely", such as the "aspect" property, which will return the current aspect if you write "-1" to it. As a consequence, cycle-values can appear to get "stuck". I still think the new behavior is what users expect more, and which is generally more useful. We won't restore the ability to get the old behavior, unless we decide to revert this commit entirely. Fixes #5772, and hopefully other complaints.
* command: make track properties cycle through no/auto if uninitializedwm42018-04-291-9/+18
| | | | | | | | | | | | | If playback has not been initialized yet (decoders not initialized etc.), or if in idle mode, let the track properties cycle through "no" and "auto". This should be slightly more helpful than making it simply exit. Depending on the stage of loading, more could be done. For example, if youtube-dl loads additional subtitle files, it can happen that these get added before the main file, and this could be cycled through to an extent. This is probably too clever, and also sort of dangerous (unintended interactions with messy in-loading state), so don't do it.
* command: fix coding stylewm42018-04-291-5/+6
| | | | Add {...}, change if(!a) to if(a) and swap its if/else body.
* player: don't wait for last video frame in encode modewm42018-04-291-0/+3
| | | | | This code makes the player wait using real time, which makes sense for normal playback, but not encode mode.
* encode: rewrite half of itwm42018-04-293-13/+19
| | | | | | | | | | | | | The main change is that we wait with opening the muxer ("writing headers") until we have data from all streams. This fixes race conditions at init due to broken assumptions in the old code. This also changes a lot of other stuff. I found and fixed a few API violations (often things for which better mechanisms were invented, and the old ones are not valid anymore). I try to get away from the public mutex and shared fields in encode_lavc_context. For now it's still needed for some timestamp-related fields, but most are gone. It also removes some bad code duplication between audio and video paths.
* vo: add vo_reconfig2()wm42018-04-291-1/+1
| | | | | | 1. I want to get away from mp_image_params (maybe). 2. For encoding mode, it's convenient to get the nominal_fps, which is a mp_image field, and not in mp_image_params.
* encode: some more cleanupswm42018-04-291-1/+0
|
* video: remove internal stereo_out flagwm42018-04-291-3/+1
| | | | | | Also rename stereo3d to stereo_in. The only real change is that the vo_gpu OSD code now uses the actual stereo 3D mode, instead of the --video-steroe-mode value. (Why does this vo_gpu code even exist?)
* client API: preparations for allowing render API to use DR etc.wm42018-04-292-6/+28
| | | | | | | | | | | | | | | | | | | | | | | | | | | | DR (letting the decoder allocate texture memory) requires running the allocation on the render thread. This is rather hard with the render API, because the user controls this thread and when it's entered. It was not possible until now. This commit adds a bunch of infrastructure to make this possible. We add a new optional mode (MPV_RENDER_PARAM_ADVANCED_CONTROL) which basically lets the user's render thread and libmpv agree how this should be done. Misuse would lead to deadlocks. To make this less likely, strictly document thread safety/locking issues. In particular, document which libmpv functions can be called without issues. (The rest has to be assumed unsafe.) The worst issue is destruction of the render context while video is still active. To avoid certain unintended recursive locks (i.e. deadlocks, unless we'd make the locks recursive), make the update callback lock separate. Make "killing" the video chain asynchronous, so we can do extra work while video is being destroyed. Because losing wakeups is a big deal, setting the update callback now triggers a wakeup. (It would have been better if the wakeup callback were a parameter to mpv_render_context_create(), but too late.) This commit does not add DR yet; the following commit does this.
* audio: fix EOF handling if there was no data at allwm42018-04-201-0/+7
| | | | | | It stopped and did nothing, instead of terminating (or just letting video play, if there was any video). Regression due to recent filter changes.
* player: remove in_dispatch fieldwm42018-04-182-9/+5
| | | | (Not sure if worth the trouble, but it does seem less awkward.)
* scripting: change when/how player waits for scripts being loadedwm42018-04-182-20/+15
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Fundamentally, scripts are loaded asynchronously, but as a feature, there was code to wait until a script is loaded (for a certain arbitrary definition of "loaded"). This was done in scripting.c with the wait_loaded() function. This called mp_idle(), and since there are commands to load/unload scripts, it meant the player core loop could be entered recursively. I think this is a major complication and has some problems. For example, if you had a script that does 'os.execute("sleep inf")', then every time you ran a command to load an instance of the script would add a new stack frame of mp_idle(). This would lead to some sort of reentrancy horror that is hard to debug. Also misc/dispatch.c contains a somewhat tricky mess to support such recursive invocations. There were also some bugs due to this and due to unforeseen interactions with other messes. This scripting stuff was the only thing making use of that reentrancy, and future commands that have "logical" waiting for something should be implemented differently. So get rid of it. Change the code to wait only in the player initialization phase: the only place where it really has to wait is before playback is started, because scripts might want to set options or hooks that interact with playback initialization. Unloading of builtin scripts (can happen with e.g. "set osc no") is left asynchronous; the unloading wasn't too robust anyway, and this change won't make a difference if someone is trying to break it intentionally. Note that this is not in mp_initialize(), because mpv_initialize() uses this by locking the core, which would have the same problem. In the future, commands which logically wait should use different mechanisms. Originally I thought the current approach (that is removed with this commit) should be used, but it's too much of a mess and can't even be used in some cases. Examples are: - "loadfile" should be made blocking (needs to run the normal player code and manually unblock the thread issuing the command) - "add-sub" should not freeze the player until the URL is opened (needs to run opening on a separate thread) Possibly the current scripting behavior could be restored once new mechanisms exist, and if it turns out that anyone needs it. With this commit there should be no further instances of recursive playloop invocations (other than the case in the following commit), since all mp_idle()/mp_wait_events() calls are done strictly from the main thread (and not commands/properties or libmpv client API that "lock" the main thread).
* demux, player: mark dependent tracksAman Gupta2018-04-172-1/+2
| | | | | | | ffmpeg marks audio tracks which are not meant to be played standalone as DEPENDENT. these are typically used in DVB broadcasts for audio descriptions, and are meant to be mixed into the main audio track during playback.
* client API: make sure to send IDLE event after mpv_initialize()wm42018-04-161-0/+1
| | | | | | | | | | | This was slightly broken: since mp_initialize() did not necessarily interrupt core_thread() (which is waiting for initialization), it did not enter mp_play_files(), which would have sent an IDLE event. I suppose that in some cases (like with mpv-android), the initial IDLE event was never actually sent, because the first wakeup of the core thread happens with the "loadfile" command, which will disallow the core thread an IDLE event.
* client API: fix potential sporadic freezes on terminationwm42018-04-161-4/+4
| | | | | | | | | | | | | | | Although this was never observed to be happening, it seems definitely possible: we first tell the main thread to exit, and then we ask the main thread to do some work for us (with mp_dispatch_run()). Obviously this is racy, and the main thread could exit without doing this, which would block mp_dispatch_run() forever. Fix this by changing the order of operation, so that it makes sense. We could also just store the pthread_t of the main thread in some variable, but the fact that pthread_create() might set the pthread_t argument _after_ starting the thread makes this a bit messy (at least it doesn't seem to be guaranteed on a superficial look at the manpage).
*