summaryrefslogtreecommitdiffstats
path: root/player
Commit message (Collapse)AuthorAgeFilesLines
* ytdl_hook.lua: improve check for sub language before inserting all-subsUmar Javed2021-11-151-1/+1
| | | | | | | youtube-dl and yt-dlp both support --sub-langs and --srt-lang in addition to --sub-lang for defining languages of subtitles. This hook only checked for sub-lang in --ytdl-raw-options and inserted --all-subs in its absence.
* options: const annotate all m_opt_choice_alternatives accessorsEmil Velikov2021-11-151-1/+1
| | | | | | | Constant data, most accessors are good but some were missing the explicit notation. Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
* options: const annotate m_obj_list accessorsEmil Velikov2021-11-151-1/+1
| | | | | | | Nearly all the code base correctly references the data as constant. But a couple of instances - fix those. Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
* osdep: rename MP_UNREACHABLENiklas Haas2021-11-031-1/+1
| | | | | It was pointed out on IRC that the name is misleading, since the actual semantics of the macro is to assert first.
* osdep: add MP_UNREACHABLENiklas Haas2021-11-031-1/+1
| | | | | | | | | This seems to work on gcc, clang and mingw as-is, but I made it conditional on __GNUC__ just in case, even though I can't figure out which compilers we care about that don't export this define. Also replace all instances of assert(0) in the code by MP_UNREACHABLE(), which is a strict improvement.
* js: ~~/init.js: use mp.find_config_fileAvi Halachmi (:avih)2021-11-011-9/+5
| | | | | | | | | | | | The problem with the previous code - which used mp.get_user_path, is that it returns a path even with --no-config, and even if the file doesn't exist. This is why we tested the "config" property, and also used mp.utils.file_info to check that the file exists. mp.find_config_file doesn't return a path with no-cofig and doesn't return a path if the file doesn't exists. It's simpler and better.
* console.lua: define remaining emacs keybindingsGuido Cella2021-11-011-3/+33
|
* lua: makenode: prevent lua stack corruptionAvi Halachmi (:avih)2021-10-201-1/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Normally there was no issue, but when the code converted a deeply nested table into an mpv node - it didn't ensure the stack has room. Lua doesn't check stack overflow when invoking lua_push* functions, and leaves this responsibility to the (c) user via lua_checkstack. Normally that's not an issue because when a lua (or autofree) function is called, it's guaranteed at least LUA_MINSTACK (20) pushes. However, pushnode and makenode are recursive, and each iteration can add few values at the stack (which are popped when the recursion unwinds), so checkstack must be used on (recursive) entry. pushnode already checked the stack, makenode did not. This commit checks the stack at makenode as well. The value of 6 (stack places to reserve) is with some room to spare, and in pratice each iteration needs 2-3 at most (pushnode also leaves room). Example which could previously corrupt the stack: utils.format_json({d1={d2={<8 more times>}}} This uses makenode to convert the lua table into an mpv node which the json writer uses as input, and if the depth is 10 or more then corruption could occur. mp.command_native is also affected, as well as any other mp/utils command which takes a lua table as input. While at it, fix the error string which pushnode used (luaL_checkstack uses the provided string with "Stack overflow (%s)", so the user message only needs to be additional info).
* lua: autofree infrastructure: x2 fasterAvi Halachmi (:avih)2021-10-191-17/+47
| | | | | | | | | | | | | | | | | | | | | The speedup is due to moving big part of the autofree runtime overhead (new lua c closure) to happen once on init at af_pushcclosure, instead of on every call. This also allows supporting upvalues trivially, even if mpv doesn't use it currently, and is more consistent with lua APIs. While x2 infrastructure speedup is meaningful - and similar between lua 5.1/5.2/jit, in practice it's a much smaller improvement because the autofree overhead is typically small compared to the "real" work (the actual functionality, and talloc+free which is needed anyway). So with this commit, fast functions improve more in percentage. E.g. utils.parse_json("0") is relatively fast and is now about 25% faster, while a slower call like mp.command_native("ignore") is now about 10% faster than before. If we had mp.noop() which does nothing (but still "needs" alloc/free) - it would now be about 50% faster. Overall, it's a mild performance improvements, the API is now more consistent with lua, and without increasing code size or complexity.
* js: custom-init: use ~~/init.js instead of ~~/.init.js (dot)Avi Halachmi (:avih)2021-10-191-6/+10
| | | | | | | | | | | | | | | | | | | | mpv doesn't have other dot files in its config dir, and it also shouldn't be "invisible". The new name ~~/init.js now replaces ~~/.init.js While mpv usually deprecates things before outright removing them, in this case the old (dot) name is replaced without deprecation: - It's a bad idea to execute hidden scripts, even if at a config dir, and we don't want to do that for the next release cycle too. - We warn if the old (dot) name exists and the new name doesn't, which should be reasonably visible for affected users. - It's likely niche enough to not cause too much pain. If for some reason both names are needed, e.g. when using also an old mpv versions, then the old name could be symlinked to the new one, or simply have one line: `require("~~/init")` to load the new name, while a new mpv version will load (only) the new name without warning.
* command: with lavfi-complex, make current-tracks return the first oneGuido Cella2021-10-151-0/+10
| | | | | | | | | | | | | | | | | | | This behavior is more convenient and allows profile conditions like: [video] profile-cond=get('current-tracks/video/image') == false [image] profile-cond=get('current-tracks/video/image') Otherwise, these profiles have to be manually applied and restored in a script. The note about discouraging the use of current-tracks in scripts is removed, because it makes people avoid using this convenient property. It was added in 720bcd79d03 without leaving an explanation of why you shouldn't use it, and the only reason seems to be that it doesn't work with lavfi-complex, but this commit changes that.
* player: add track-list/N/image sub-propertyGuido Cella2021-10-143-0/+3
| | | | | | | | | | | | | | | | | | | | | | This exposes whether a video track is detected as an image, which is useful for profile conditions, property expansion and lavfi-complex. The lavf demuxer sets image to true when the existing check detects an image. When the lavf demuxer fails, the mf one guesses if the file is an image by its extension, so sh->image is set to true when the mf demuxer succeds and there's only one file. The mkv demuxer just sets image to true for any attached picture. The timeline demuxer just copies the value of image from source to destination. This sets image to true for attached pictures, standalone images and images added with !new_stream in EDL playlists, but it is imperfect since you could concatenate multiple images in an EDL playlist (which should be done with the mf demuxer anyway). This is good enough anyway since the comment of the modified function already says it is "Imperfect and arbitrary".
* js: custom init: ignore ~~/.init.js with --no-configAvi Halachmi (:avih)2021-10-121-1/+4
| | | | | | The custom init script should be considered a configuration file, and as such it should be ignored when the user wants vanilla mpv - and now it is ignored with --no-config.
* osc.lua: avoid infinite ticks loop on idleAvi Halachmi (:avih)2021-10-031-1/+11
| | | | | | | | | | | | | | | Before this commit, animation-end was handled at render(), however, it's not called on idle, which resulted in state.anitype ~= nil, with nothing to reset it during idle, which caused in an infinite tick() loop (starts on first mouse move). Now tick resets the animation on idle, and also, as a safety measure, if we're past 1s after the animation deadline. The safety measure is because the osc states are complex, and it's easier to detect a "we really shouldn't be animating now" at tick() itself rather than detecting the exact states where animation should be reset. Generally, the safety mmeasure is not needed.
* osc.lua: unify animation reset function (no-op)Avi Halachmi (:avih)2021-10-031-6/+8
|
* Revert "player: add track-list/N/image sub-property"Jan Ekström2021-10-023-3/+0
| | | | | | | | Unfortunately, this functionality in large part based on a struct member that was made private in FFmpeg/FFmpeg@7489f632815c98ad58c3db71d1a5239b5dae266c in May. Unfortunately, this was not noticed during review. This reverts commit 0862664ac952d21fef531a8923a58ae575268fc5.
* player: add track-list/N/image sub-propertyGuido Cella2021-10-023-0/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This exposes whether a video track is detected as an image. This is useful for profile conditions, property expansion and lavfi-complex, and is more accurate than any detection even Lua scripts can perform, since they can't differentiate between images and videos without container-fps and audio and with duration 1 (which is the duration set by the mf demuxer with the default --mf-fps=1). The lavf demuxer image check is moved to where the number of frames is available for comparison, and is modified to check the number of frames and duration instead of the video codec. This doesn't misdetect videos in a codec commonly used for images (e.g. mjpeg) as images, and can detect images in a codec commonly used for videos (e.g. 1-frame gifs). pix files are also now detected as images, while before they weren't since the condition was checking if the AVInputFormat name ends with _pipe, and alias_pix doesn't. Both nb_frames and codec_info_nb_frames are checked because nb_frames is 0 for some video codecs (hevc, av1, vc1, mpeg1video, vp9 if forcing --demuxer=lavf), and codec_info_nb_frames is 1 for others (mpeg, mpeg4, wmv3). The duration is checked as well because for some uncommon codecs and containers found in FFMpeg's FATE suite, libavformat returns nb_frames = 0 and codec_info_nb_frames = 1. For some of them it even returns duration = 0, so they are blacklisted in order to never be considered images. The extra codecs that would have to be blacklisted without checking the duration are AV_CODEC_ID_4XM, AV_CODEC_ID_BINKVIDEO, AV_CODEC_ID_DSICINVIDEO, AV_CODEC_ID_ESCAPE130, AV_CODEC_ID_MMVIDEO, AV_CODEC_ID_NUV, AV_CODEC_ID_RL2, AV_CODEC_ID_SMACKVIDEO and AV_CODEC_ID_XAN_WC3, while the containers are film-cpk, ivf and ogg. The lower limit for duration is 10 because that's the duration of 1-frame gifs. Streams with codec_info_nb_frames 0 are not considered images because vp9 and av1 have nb_frames = 0 and codec_info_nb_frames = 0, and we can't rely on just the duration to detect them because they could be livestreams without an initial duration, and actually even if we could for these codecs libavformat returns huge negative durations like -9223372036854775808. Some more images in the FATE suite that are really frames cut from a video in an uncommon codec and container, like cine/bayer_gbrg8.cine, could be detected by allowing codec_info_nb_frames = 0, but then any present and future video codec with nb_frames = 0 and codec_info_nb_frames = 0 would need to be added to the blacklist. Some even have duration > 10, so to detect these images the duration check would have to be removed, and all the previously mentioned extra codecs and containers would have to be added added to the blacklists, which means that images that use them (if they exist anywhere) will never be detected. These FATE images aren't detected as such by mediainfo either anyway, nor can a Lua script reliably detect them as images since they have container-fps and duration > 0 and != 1, and you probably will never see files like them anywhere else. For attached pictures the lavf demuxer always set image to true, which is necessary because they have duration > 10. There is a minor change in behavior for which audio with attached pictures now has mf-fps as container-fps instead of unavailable, but this makes it consistent with external cover art, which was already being assigned mf-fps. When the lavf demuxer fails, the mf one guesses if the file is an image by its extension, so sh->image is set to true when the mf demuxer succeds and there's only one file. Even if you add a video's file type to --mf-type and open it with the mf protocol, only the first frame is used, so setting image to true is still accurate. When converting an image to the extensions listed in demux/demux_mf.c, tga and pam files are currently the only ones detected by the mf demuxer rather than lavf. Actually they are detected with the image2 format, but it is blacklisted; see d0fee0ac33a. The mkv demuxer just sets image to true for any attached picture. The timeline demuxer just copies the value of image from source to destination. This sets image to true for attached pictures, standalone images and images added with !new_stream in EDL playlists, but it is imperfect since you could concatenate multiple images in an EDL playlist (which should be done with the mf demuxer anyway). This is good enough anyway since the comment of the modified function already says it is "Imperfect and arbitrary".
* js: custom init (~~/.init.js): fail loudly on errorsAvi Halachmi (:avih)2021-09-301-3/+3
| | | | | | | | | | | | Previously, loading ~~/.init.js was inside a try block, in order to quietly ignore errors if the file doesn't exist. However, that also prevented any real errors from showing up even when the file does exist, and the script continued as if everything is OK, while in fact the custom init script didn't complete correctly. Now we first check if the file exists, and then load it without try/catch, so that any error shows up normally (and abort the script).
* ytdl_hook.lua: search for yt-dlp by defaultGuido Cella2021-09-251-18/+48
| | | | | | | | | | | Because youtube-dl is inactive and the yt-dlp fork is becoming more popular, make mpv use yt-dlp without any extra configuration. yt-dlp is ordered before youtube-dl because it's more obscure, so users who have yt-dlp installed are more likely to want to use it rather than youtube-dl. Fixes #9208.
* command: cycle: respect the prefix "repeatable"Avi Halachmi (:avih)2021-08-191-1/+3
| | | | | | | | | | | | | | | | | The "cycle" command _declaration_ enables repeatability by default, however, the command handler applies additional logic to augment it, based on the property which is being cycled - using some guesswork. Specifically, properties with discrete values are not repeatable (like sub or osd-level), while continuous properties are repeatable (like volume). Previously, the "repeatable" prefix could not override this additional logic. This commit changes the behavior so that the logic affects only the default repeatability (still based on the property like before), however, the "repeatable" prefix is now allowed to override it.
* stats.lua: typo lavfi-complexStefan de Konink2021-08-151-2/+2
| | | | Fix typo lavi-complex to lavfi-complex.
* sub: show subs without duration on vid changeGuido Cella2021-08-131-1/+1
| | | | | | | | | | | | | | | | | When changing video track with subtitles with unknown duration, they aren't shown until you seek, cycle sub back and forth, or apply a video filter. This is caused by reinit_video_chain_src() calling reset_subtitle_state() -> sub/sd_ass.c:reset() -> ass_flush_events() when ctx->duration_unknown is true. The ass_flush_events() call was added in a714f8e so subs with unknown duration wouldn't multiply on seek, i.e. when reset_subtitle_state() is called from reset_playback_state(). So keep calling it from there, and in reinit_video_chain_src() use just term_osd_set_subs(mpctx, NULL) instead to clear any subtitles printed to the terminal. The reset_subtitle_state() call was added in c1ac97b to "reset the state correctly when switching between video/no-video", but with it removed I no longer notice any issue doing that.
* sub: align ytdl-hook secondary subs to the topGuido Cella2021-08-111-2/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 29e15e6248 prefixed youtube-dl's subs url with an edl prefix to not download them until they're selected, which is useful when there are many sub languages. But this prefix broke the alignment of secondary subs, which would overlap the primary subs instead of always being placed at the top. This can be tested with --sub-file='edl://!no_clip;!delay_open,media_type=sub;secondary_sub.srt' When a sub is added, sub.c:reinit_sub() is called. This calls in init_subdec() -> dec_sub.c:sub_create() -> init_decoder() -> sd_ass:init(). Then reinit_sub() calls sub_control(track->d_sub, SD_CTRL_SET_TOP, &(bool){!!order}) which sets sd_ass_priv.on_top = true for secondary subs. But for EDL subs the real sub is initialized again when in dec_sub.c:sub_read_packets() is_new_segment() returns true and update_segment() is called, or when sub_get_bitmaps() calls update_segment(). update_segment() then calls init_decoder(), which calls sd_ass:init(), so sd_ass_priv is reinitialized, and its on_top property is left false. This commit sets it to true again. For URLs that need to be downloaded it seems that the update_segment() call that reinitializes sd_ass_priv is always the one in sub_read_packets(), but with local subs sub_get_bitmaps() is usually called earlier (though there shouldn't be a reason to use the EDL URL for local subs), so I added the order parameter to sub_create(), rather than adding it to all of update_segment(), sub_read_packets() and sub_get_bitmaps(). Also removes the cast to bool in the other sub_control call, since sub/sd_ass.c:control already casts arg to bool when cmd is SD_CTRL_SET_TOP.
* lua: read_options: quote values at error messagesAvi Halachmi (:avih)2021-08-101-3/+3
| | | | | | | This makes it easier to understand the error in cases of incorrect syntax or formatting at .conf files. (js already has this quoting). Fixes #9105
* command: check for monitor par in window-scaleDudemanguy2021-08-091-0/+6
| | | | | | | | When performing the scaling calculations, the window scale properties do not bother checking for potential monitor par. The vo keeps track of this via vo->monitor_par. Simply multiply/divide the video's width or height depending on the value of monitor_par. We also clamp the values to avoid the values running away to infinity in extreme cases.
* command: check for rotation in window-scaleDudemanguy2021-08-091-0/+3
| | | | | | | | | | | | | | | The vo currently handles rotations in 90 degree steps and some VOs set this via VO_CAP_ROTATE90. When the rotation exactly hits either 90 or 270 degrees, this causes the values of dwidth and dheight to perfectly swap like one would expect. However, the mp_image_params_get_dsize function call in both of the window scale functions do not take this special case into account. So the width/height values returned will be incorrectly flipped in the 90 and 270 degree cases if the vo driver does implement VO_CAP_ROTATE90 (like vo=gpu). Fortunately, the mp_image_params struct keeps track of the rotation for us. So all we need to do is check if the image is rotated at 90 or 270 degrees and check that the current vo driver supports VO_CAP_ROTATE90. If so, then swap vid_w and vid_h to their true, correct values.
* command: merge window-scale code togetherDudemanguy2021-08-091-13/+3
| | | | | | | Based on a small patch originally written by @avih. Instead of duplicating the window-scale logic in update_window_scale, just call the mp_property_current_window_scale function with the M_PROPERTY_SET action and a NULL property.
* command: make current-window-scale writeable, 2nd attemptDudemanguy2021-08-071-0/+9
| | | | | | | | | | | | | | | | | | | | | | The window-scale property mirrors the respective option (not the effective scale derived from the current window size), and as such setting its value to the same value it had before has no effect. Specifically - the window will not resize. This is consistent as far as property-option bridge behavior goes, but we do end up with an issue that we can't set an arbitrary scale and expect the window to always resize accordingly. We do also have a current-window-scale property which does reflect the actual window size, however, it's been read-only till now. This commit makes current-window-scale RW so that it's now always possible to set an arbitrary scale and expect the window to resize accordingly (without affecting window-scale - like manual resize). Also, mention window-scale no-effect-if-not-changed at the docs. Based on code by @Dudemanguy from commit 873ae0d, with same effect.
* Revert "command: make current-window-scale writeable"Avi Halachmi (:avih)2021-08-071-34/+25
| | | | | | | | | | | This reverts commit 873ae0de2af3bb84a11e5e57f6e3a8942b2263c2. The next commit will restore this functionality, with the following differences from the reverted commit: - Smaller and simpler code change. - On bad scale: use "Invalid value" (compared to "no such property"). - Doesn't combine the docs for window-scale and current-window-scale. - Doesn't remove the docs for window-scale behavior prior to 0.31.0.
* stats.lua: page 4 (keys): group current-window-scale under windowGuido Cella2021-08-061-1/+1
| | | | | This groups "set current-window-scale ..." under the "window" group instead of "current" in the list of keybindings.
* command: make current-window-scale writeableDudemanguy2021-08-051-25/+34
| | | | | | | | | | | | | | | | | | | | | | | | | | Somewhat confusingly, mpv has both a window-scale option and a current-window-scale property. The documentation lists window-scale under properties (and it is technically is one), but at its core it is actually an option which means it behaves subtly different. Options in mpv are runtime-configurable, but they only change anything if the value of the option itself changes. window-scale is an option and not meant to keep track of the actual scale of the window (intended behavior introduced by d07b7f0). This causes window-scale to do nothing in certain cases (ex: the window is manually resized and window-scale is set to 1.00 again). This is logical and consistent with the behavior of the rest of the mpv options, but it also makes it a poor candidate for setting the mpv window scale dynamically. As a remedy, we can just make current-window-scale writeable instead. current-window-scale is intended to always report the actual scale of the window and keep track of any window size changes made by the user. By making this property also writeable, it allows the user to have more intuitive behavior (i.e. setting current-window-scale to 1.00 always sets the window to a scale of 1). Additionally, the default input.conf is changed to use current-window-scale instead of window-scale. The window-scale documentation under property list is removed since it is already documented under options and users should probably set the current-window-scale property instead in most cases.
* stats.lua: page 4 (keys): better alignment of non-ascii keysAvi Halachmi (:avih)2021-07-311-2/+16
| | | | | | | | | | | | | | | | | | | | | | | Previously we assumed the key-name string occupies strlen(name) cells, now we count codepoints instead. This improves alignment of non-english key names. Still not perfect because we don't know if the key name is single or double width, but wcwidth not available to scripts, notoriously unreliable (depends on locale, correct and updated tables, etc), and also not always available (Windows). Still, better than nothing, and we err by at most one cell - vs up to three before this commit (4 bytes keyname codepoint). In the future we could do the alignment using libass tags, however, this both complicates the ass-output generation, and also not available when we output for the terminal, so for now only count codepoints. Also, if the key name was in a right-to-left language, then previously the name/command were swapped visually. Now we inject a left-to-right marker before the name to ensure direction. This works also when harfbuzz is disabled for libass (--sub-ass-shaper=simple).
* player: eac3 to the whitelist of audio extensionsDudemanguy2021-07-301-1/+1
| | | | ffmpeg plays these just fine. Fixes #9065.
* stats.lua: page 4 (keys): detect single-quotesAvi Halachmi (:avih)2021-07-301-2/+2
|
* options: audio-display determines cover priorityGuido Cella2021-07-291-2/+6
| | | | | | | | | | | | Let audio-display determine whether embedded images or external cover art tracks should be selected when both are present. Attached pictures are given priority by default as requested in #8539. Also updates references to attached pictures in the log and manpage to refer to cover art as well. Closes #8539.
* command: handle changes to image-display-durationGuido Cella2021-07-251-0/+5
| | | | | | | | | | When changing image-display-duration at runtime, make the new value take effect immediately, rather than from the next playlist-position change. This allows toggling the slideshow mode while viewing images (without hacks like executing playlist-play-index current afterwards). All the conditions are just to be safe since even if you set time_frame while playing a video, it's immediately overwritten by the next value.
* stats.lua: fix ass-escape while persistent_overlay=yesAvi Halachmi (:avih)2021-07-251-14/+27
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | mpv has two methods to display output from text input: - show-text (scripting: mp.osd_message) has ass disabled by default (escaped), and the property osd-ass-cc can control escaping. - osd-overlay (scripting: mp.set_osd_ass or mp.create_osd_overlay) has ass enabled (unescaped), and osd-ass-cc is NOT supported. By default, stats.lua uses mp.osd_message which does support escaping. That's persistent_overlay=no. When using persistent_overlay=yes then mp.set_osd_ass is used. Due to this, the no_ASS(..) function - which is supposed to escape ass, simply returned its input unmodified when persistent_overlay is enabled. This is not a new issue, and the filters on page 1 use no_ASS() to no avail in persistent mode, however, this content (filter name and value strings) rarely actually needs escaping, and users didn't notice. However, the new page 4 (keys) does break visibly when no_ASS doesn't work, because it tries to escape arbitrary key-names and command strings, and at the very least the key '{' is bound by default, which is displayed incorrectly if escaping doesn't work. Fix this by rolling our own escaping when using mp.set_osd_ass, similar to how the mpv code does it for mp.osd_message (substrings replacements). However, this means that the set_ASS(..) function can no longer behave correctly because escaping requires going through the whole content string rather than only inserting a marker. Luckily, other than at no_ASS, set_ASS was only used at one place (text_style), which is only called from two places: - generate_graph() only needs to restore styles - not to enable ass. - add_header() is only used at the begining of page output, and uses set_ASS to enable ass initially when using mp.osd_message. So remove the set_ASS function, and instead enable ass directly at print_page using osd-ass-cc when mp.osd_message is used. Fixes #9022
* js: fix tiny leaks if js_try throws(!)Avi Halachmi (:avih)