summaryrefslogtreecommitdiffstats
path: root/player
Commit message (Collapse)AuthorAgeFilesLines
* 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).
* audio: don't recreate AO if a filter changes the output formatwm42018-04-151-1/+28
| | | | | | | | | | | | | | | | | | | | | | | Until recently, the AO was reinitialized strictly only on decoder format changes. But the commit for simplifying audio format negotiation removed this. Now the AO is recreated for any format change. This is sort of annoying if you change playback speed. The insertion/removal of af_scaletempo can change the sample format. For example, the acompressor filter will convert output to double, so toggling scaletempo will force the format back to float. This recreates the AO under the --gapless-audio=weak default. This likely affects a lot of other filters too. Work this around by allowing sample format changes, and keeping the current AO format in these cases. This is probably not a big problem. Most audio APIs force the output format to float anyway. This means you actually have to worry about what the default gapless mode does to your audio. If you start with a file that uses 8 bit per sample, and then continue playing a 24 bit FLAC, it will be converted down to 8 bit per sample. (Assuming they are played in a way that uses the gapless logic.)
* ytdl_hook: don't log error when loading is abortedwm42018-04-151-2/+6
|
* js: use new hooks API (match f60826c3)Avi Halachmi (:avih)2018-04-072-10/+50
|
* js: dump(..): fix incorrect <VISITED> with array argumentAvi Halachmi (:avih)2018-04-071-1/+1
| | | | | | | | | | | | | | | | | | | | | When dump's argument is an array, it was displaying <VISITED> for all the array's object elements (objects, arrays, etc), regardless if they're actually visited or not. The reason is that we try to stringify twice: once normally which may throw (on cycles), and a second time while excluding visited items which is indicated by binding the replacer to an empty array - in which we hold the visited items, where the replacer tests if its 'this' is an array or not and acts accordingly. However, its "this" may also be an array even if we don't bind it to one, because its "normal" this is the main stringified object, so the test of Array.isArray(this) is true when the top object is an array, and the object items are indeed are in it - so the replacer considers them visited. Fix by binding to null on the first attempt such that "this" is an array only when we want it to test for visited items and not when the argument itself is an array.
* js: implement mp.register_idleAvi Halachmi (:avih)2018-04-071-2/+37
| | | | | | | | | | Due to earlier misinterpretation of the Lua docs as if mp.register_idle registers a one-shot callback, the JS docs suggested to use setTimeout. But the behavior and Lua docs are such that it's a repeating callback which fires just before the script thread goes to sleep. Implement it for JS too.
* js: implement mp.options.read_optionsAvi Halachmi (:avih)2018-04-071-0/+52
|
* config: replace config dir lua-settings/ with dir script-opts/Avi Halachmi (:avih)2018-04-071-1/+9
| | | | lua-settings/ is still supported, with deprecation warning.
* player: fix hook processing consistency and code duplication issueswm42018-03-263-45/+20
| | | | | | | | | | | | | | | | | | | | | | | | There was a "generic" function to run a hook and to wait for its completion, yet there were two duplicated functions doing the same anyway. Replace them with a single function. They differed in how stop_play was handled, but it was broken anyway. stop_play is set when playback is stopped due to quitting or changing the playlist entry - but we still can't stop hook processing, because that would mean asynchronously doing something else while the user hook code is still busy and might still have the expectation that running the hook stops everything else. So not waiting until the hook ends properly is against the whole hook idea. That this was done inconsistently is even worse. (Though it could be argued that when quitting the player, everything should just be stopped violently. But I still think that's up to the hook handler.) process_hooks() does not return anything, since hook processing doesn't really have a result (it's all about blocking and letting some other code synchronously do something). Just let the caller check whether loading was aborted in the meantime. Also change the potentially misleading name of mp_hook_run().
* client API: add a first class hook API, and deprecate old APIwm42018-03-268-67/+154
| | | | | | | | | | | | | | | As it turns out, there are multiple libmpv users who saw a need to use the hook API. The API is kind of shitty and was never meant to be actually public (it was mostly a hack for the ytdl script). Introduce a proper API and deprecate the old one. The old one will probably continue to work for a few releases, but will be removed eventually. There are some slight changes to the old API, but if a user followed the manual properly, it won't break. Mostly untested. Appears to work with ytdl_hook.
* command: remove an old compatibility hackwm42018-03-261-48/+1
| | | | | Was removed 3 releases ago and was spamming warning messages that it'll be dropped, so it's fine to remove it now.
* command: remove duplication of property set error message handlingwm42018-03-261-59/+36
| | | | | | | | Move all of this stuff to a common function. This makes the error messages less specific, but I don't think anyone will miss it. The OSD flag handling is annoying, but it's nothing that should be changed with this commit.
* command: move property multiply code to m_property.cwm42018-03-261-26/+3
| | | | | | | I think this will help with reducing code d