Compare commits
73
Commits
git-release
...
v0.7.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1783e8cade | ||
|
|
c7d6b21789 | ||
|
|
8d4e6498c3 | ||
|
|
9984f4fffd | ||
|
|
75a62c7a64 | ||
|
|
73eaadf6c3 | ||
|
|
292f6f1904 | ||
|
|
5a2947c9d0 | ||
|
|
fdea35a71b | ||
|
|
8f6eb196cd | ||
|
|
3b6e063599 | ||
|
|
015218f8c8 | ||
|
|
00d1d6d807 | ||
|
|
49c3cbfb4e | ||
|
|
925becfb15 | ||
|
|
2cebc52065 | ||
|
|
34e504bf93 | ||
|
|
f0649ce841 | ||
|
|
65af6a55b7 | ||
|
|
1326d3f0b8 | ||
|
|
b062b54626 | ||
|
|
9bee56cc67 | ||
|
|
9fb0180eb2 | ||
|
|
4f8af1a518 | ||
|
|
62b6048468 | ||
|
|
b6363c8100 | ||
|
|
db4cec8a6c | ||
|
|
4de6f4f616 | ||
|
|
7c53bb4bb1 | ||
|
|
115709e3c1 | ||
|
|
1e8dbf8212 | ||
|
|
1bfaab13ca | ||
|
|
083235d91f | ||
|
|
bc4e115b30 | ||
|
|
807763c85e | ||
|
|
69fa6c4b73 | ||
|
|
3141381c2e | ||
|
|
8f847437a9 | ||
|
|
487fcea6f4 | ||
|
|
63a31db0a3 | ||
|
|
575edecccb | ||
|
|
14adda8f6b | ||
|
|
7cacff6d61 | ||
|
|
4ced125239 | ||
|
|
ac94c81134 | ||
|
|
9501050ddc | ||
|
|
c688880f9e | ||
|
|
47ec404a52 | ||
|
|
18b15a436f | ||
|
|
6583ad6970 | ||
|
|
863701391c | ||
|
|
3803c14279 | ||
|
|
39126c3828 | ||
|
|
b9cfc3622c | ||
|
|
1b0bf6507e | ||
|
|
7ca6aa4ad0 | ||
|
|
b82a98722a | ||
|
|
3d6d7012ff | ||
|
|
3051ff9f25 | ||
|
|
9bf66294f8 | ||
|
|
577378b827 | ||
|
|
1679222e18 | ||
|
|
74270cd1db | ||
|
|
718bf3b39e | ||
|
|
5ecb381d78 | ||
|
|
17f1332955 | ||
|
|
f4a1dfdffb | ||
|
|
d3972125a1 | ||
|
|
71f504a43d | ||
|
|
bc1370041d | ||
|
|
4f74869cd8 | ||
|
|
8d8b36df1b | ||
|
|
2da6c95208 |
No files matched your search
@@ -25,6 +25,7 @@ API changes
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
|
--- mpv 0.7.0 is released ---
|
||||||
1.10 - deprecate/disable everything directly related to script_dispatch
|
1.10 - deprecate/disable everything directly related to script_dispatch
|
||||||
(most likely affects nobody)
|
(most likely affects nobody)
|
||||||
1.9 - add enum mpv_end_file_reason for mpv_event_end_file.reason
|
1.9 - add enum mpv_end_file_reason for mpv_event_end_file.reason
|
||||||
|
|||||||
@@ -113,8 +113,8 @@ Miscellaneous
|
|||||||
* Matroska edition switching at runtime.
|
* Matroska edition switching at runtime.
|
||||||
* Support for playing URLs of popular streaming sites directly.
|
* Support for playing URLs of popular streaming sites directly.
|
||||||
(e.g. ``mpv https://www.youtube.com/watch?v=...``).
|
(e.g. ``mpv https://www.youtube.com/watch?v=...``).
|
||||||
Requires a recent version of ``youtube-dl`` to be installed, and
|
Requires a recent version of ``youtube-dl`` to be installed. Can be
|
||||||
``ytdl=yes`` in the mpv config file.
|
disabled with ``ytdl=no`` in the mpv config file.
|
||||||
* Support for precise scrolling which scales the parameter of commands. If the
|
* Support for precise scrolling which scales the parameter of commands. If the
|
||||||
input doesn't support precise scrolling the scale factor stays 1.
|
input doesn't support precise scrolling the scale factor stays 1.
|
||||||
* Allow changing/adjusting video filters at runtime. (This is also used to make
|
* Allow changing/adjusting video filters at runtime. (This is also used to make
|
||||||
|
|||||||
+1
-1
@@ -573,7 +573,7 @@ strictly part of the guaranteed API.
|
|||||||
Runs an external process and waits until it exits. Returns process status
|
Runs an external process and waits until it exits. Returns process status
|
||||||
and the captured output.
|
and the captured output.
|
||||||
|
|
||||||
The paramater ``t`` is a table. The function reads the following entries:
|
The parameter ``t`` is a table. The function reads the following entries:
|
||||||
|
|
||||||
``args``
|
``args``
|
||||||
Array of strings. The first array entry is the executable. This
|
Array of strings. The first array entry is the executable. This
|
||||||
|
|||||||
@@ -426,20 +426,20 @@ Program Behavior
|
|||||||
Enable the youtube-dl hook-script. It will look at the input URL, and will
|
Enable the youtube-dl hook-script. It will look at the input URL, and will
|
||||||
play the video located on the website. This works with many streaming sites,
|
play the video located on the website. This works with many streaming sites,
|
||||||
not just the one the scripts are named after. This requires a recent version
|
not just the one the scripts are named after. This requires a recent version
|
||||||
of youtube-dl to be installed on the system.
|
of youtube-dl to be installed on the system. (Enabled by default.)
|
||||||
|
|
||||||
If the script can't do anything with an URL, it will do nothing.
|
If the script can't do anything with an URL, it will do nothing.
|
||||||
|
|
||||||
Currently disabled by default, because youtube-dl's generic extractor can
|
|
||||||
get stuck on some URL, preventing playback.
|
|
||||||
|
|
||||||
(Note: this is the replacement for the now removed libquvi support.)
|
(Note: this is the replacement for the now removed libquvi support.)
|
||||||
|
|
||||||
``--ytdl-format=<best|worst|mp4|webm|...>``
|
``--ytdl-format=<best|worst|mp4|webm|...>``
|
||||||
Video format/quality that is directly passed to youtube-dl. The possible
|
Video format/quality that is directly passed to youtube-dl. The possible
|
||||||
values are specific to the website and the video, for a given url the
|
values are specific to the website and the video, for a given url the
|
||||||
available formats can be found with the command
|
available formats can be found with the command
|
||||||
``youtube-dl --list-formats URL``.
|
``youtube-dl --list-formats URL``. See youtube-dl's documentation for
|
||||||
|
available aliases. To use experimental DASH support for youtube, use
|
||||||
|
``bestvideo+bestaudio``.
|
||||||
|
(Default: ``best``)
|
||||||
|
|
||||||
Video
|
Video
|
||||||
-----
|
-----
|
||||||
@@ -577,7 +577,7 @@ Video
|
|||||||
Disable scaling of the video. If the window is larger than the video,
|
Disable scaling of the video. If the window is larger than the video,
|
||||||
black bars are added. Otherwise, the video is cropped. The video still
|
black bars are added. Otherwise, the video is cropped. The video still
|
||||||
can be influenced by the other ``--video-...`` options. (If the
|
can be influenced by the other ``--video-...`` options. (If the
|
||||||
``--video-zoom`` option is set to a value other than ``1``, scaling is
|
``--video-zoom`` option is set to a value other than ``0``, scaling is
|
||||||
enabled, but the video isn't automatically scaled to the window size.)
|
enabled, but the video isn't automatically scaled to the window size.)
|
||||||
|
|
||||||
The video and monitor aspects aspect will be ignored. Aspect correction
|
The video and monitor aspects aspect will be ignored. Aspect correction
|
||||||
|
|||||||
+135
@@ -0,0 +1,135 @@
|
|||||||
|
Release 0.7.2
|
||||||
|
=============
|
||||||
|
|
||||||
|
Changes
|
||||||
|
-------
|
||||||
|
|
||||||
|
- Give precedence to the DVD menu navigation keyboard bindings so that user
|
||||||
|
defined LEFT/RIGHT/... bindings don't break DVD menu navigation.
|
||||||
|
- Try to fallback to the "default" device if the selected device is busy in the
|
||||||
|
alsa AO.
|
||||||
|
- Don't create Dock icon for audio only files on OS X.
|
||||||
|
- Save screenshots to desktop when using the app bundle on OS X.
|
||||||
|
- Restore ab-loop settings with playback resume.
|
||||||
|
- Bump required youtube-dl version to 2014.11.26 and enable the ytdl_hook Lua
|
||||||
|
script by default (now playing videos from YouTube and the like will work
|
||||||
|
out of the box without any configuration change needed).
|
||||||
|
|
||||||
|
Bug fixes
|
||||||
|
---------
|
||||||
|
|
||||||
|
- Don't signal an error if --stream-dump is used.
|
||||||
|
- Fix removing key bindings from Lua scripts.
|
||||||
|
- Reject channel descriptions with too many channels in the coreaudio AO.
|
||||||
|
- Don't async redraw when waiting for VO redraw on OS X (this fixes the very
|
||||||
|
annoying glitch where the black bars disappear for a single frame when going
|
||||||
|
fullscreen).
|
||||||
|
- Fix mono playback with the also AO.
|
||||||
|
- Don't crash if framebuffers are not available in the opengl VO.
|
||||||
|
|
||||||
|
New features
|
||||||
|
------------
|
||||||
|
|
||||||
|
- Try to handle multi-arc videos in the ytdl_hook Lua script.
|
||||||
|
|
||||||
|
This listing is not complete. There are many more bug fixes and changes. The
|
||||||
|
complete change log can be viewed by running ``git log 47ec404..c7d6b21`` in
|
||||||
|
the git repository.
|
||||||
|
|
||||||
|
Release 0.7.1
|
||||||
|
=============
|
||||||
|
|
||||||
|
Changes
|
||||||
|
-------
|
||||||
|
|
||||||
|
- Don't show the volume neutral marker on the OSD if softvol is disabled.
|
||||||
|
- Don't select a subtitle track when executing the sub_add input command in
|
||||||
|
"auto" mode.
|
||||||
|
|
||||||
|
Bug fixes
|
||||||
|
---------
|
||||||
|
|
||||||
|
- Fix busy loop when seeking while paused (this fixes a problem with pulseaudio
|
||||||
|
that caused mpv and the pulseaudio daemon to use 100% CPU).
|
||||||
|
- Fix Lua function utils.subprocess() in Windows versions older than Vista.
|
||||||
|
- Avoid creating a window bigger than the screen on Windows.
|
||||||
|
- Don't ignore the last line in m3u playlists.
|
||||||
|
- Don't crash if a codec could not be opened.
|
||||||
|
- Dynamically allocate audio channel map entries (this should fix a crash in
|
||||||
|
the alsa and coreaudio AOs with audio devices that support more than 20
|
||||||
|
channel maps).
|
||||||
|
- Ignore the "srgb" option in the opengl VO if hardware decoding is enabled.
|
||||||
|
- Linearize non-RGB sRGB files correctly (eg. JPEG).
|
||||||
|
- Fix opening reference URLs (.file/id=) on OS X.
|
||||||
|
|
||||||
|
This listing is not complete. There are many more bug fixes and changes. The
|
||||||
|
complete change log can be viewed by running ``git log 8d8b36d..6583ad6`` in
|
||||||
|
the git repository.
|
||||||
|
|
||||||
|
Release 0.7.0
|
||||||
|
=============
|
||||||
|
|
||||||
|
Changes
|
||||||
|
-------
|
||||||
|
|
||||||
|
- Buffer partial log messages in the client API (the client API will now only
|
||||||
|
pass full log messages to clients).
|
||||||
|
- Remove ncurses/terminfo/termcap support (it was disabled by default and
|
||||||
|
replaced by new code since v0.6.0).
|
||||||
|
- Enable cdda:// support by default again (it was disabled since v0.6.0).
|
||||||
|
- Cascade-load input.conf (if there are several input.confs in the set of valid
|
||||||
|
config paths, load them all).
|
||||||
|
- Draw the OSD twice in 3D mode (this fixes subtitles display in 3D mode).
|
||||||
|
- Make wasapi the default AO on Windows again since many of its problems have
|
||||||
|
been solved.
|
||||||
|
- Use "site-functions" subdir to install the zsh completion script instead of
|
||||||
|
the Debian-specific "vendor-completions" (also provide the --zshdir waf
|
||||||
|
configure option for changing this value).
|
||||||
|
- Improve synchronization between the Cocoa GUI and the player (this fixes some
|
||||||
|
long standing deadlock issues on Mac OS X).
|
||||||
|
- Remove --fs-missioncontrol option (only relevant to Mac OS X).
|
||||||
|
|
||||||
|
New features
|
||||||
|
------------
|
||||||
|
|
||||||
|
- Enable pitch correction by default when playing at higher speeds (this can be
|
||||||
|
controlled with the --audio-pitch-correction option).
|
||||||
|
- Open stream and demuxer asynchronously (this should avoid having the player
|
||||||
|
get blocked on network streams).
|
||||||
|
- Add cache-buffering-state property for querying the cache fill status until
|
||||||
|
the player unpauses.
|
||||||
|
- Add support for listing and selecting the audio device (note that it is not
|
||||||
|
implemented for all AOs, see the --audio-device option for more information).
|
||||||
|
- Add support for a JSON-based IPC mechanism (note that this is not currently
|
||||||
|
supported on Windows, see the JSON IPC section in the manpage for more
|
||||||
|
information).
|
||||||
|
- Add Lua utility function for starting processes (see utils.subprocess() in the
|
||||||
|
manpage).
|
||||||
|
- Add Lua utility function for parsing JSON (see utils.parse_json() in the
|
||||||
|
manpage).
|
||||||
|
- Add field-dominance property (see --field-dominance option).
|
||||||
|
- Add video-rotate property (see --video-rotate option).
|
||||||
|
- Add playback-abort property for querying whether playback is stopped or is to
|
||||||
|
be stopped.
|
||||||
|
- Add cursor-autohide property (see --cursor-autohide option).
|
||||||
|
- Add vo-configured property for querying whether a window is created.
|
||||||
|
- Add support for dxva2 hardware acceleration on Windows.
|
||||||
|
- Drop libquvi support (this has been replaced by a built-in Lua script that
|
||||||
|
invokes the youtube-dl tool, which needs to be installed, see the --ytdl
|
||||||
|
option).
|
||||||
|
- Add support for loading chapters from an external file (see the
|
||||||
|
--chapters-file option).
|
||||||
|
- Add window-minimized property for querying whether the window is minimized
|
||||||
|
(works for X11 only).
|
||||||
|
- Make it possible to configure the OSC seekbar style (see the "seekbarstyle"
|
||||||
|
OSC option).
|
||||||
|
- Add support for libmpv on Mac OS X (it used to be broken, now it's fully
|
||||||
|
functional and also provides support for embedding the mpv window inside a
|
||||||
|
Cocoa/Qt application).
|
||||||
|
- Try to use the audio channel map reported by ALSA in the alsa AO.
|
||||||
|
- Add option to disable text OSD rendering completely (useful for working around
|
||||||
|
certain fontconfig issues, see the --use-text-osd option).
|
||||||
|
|
||||||
|
This listing is not complete. There are many more bug fixes and changes. The
|
||||||
|
complete change log can be viewed by running ``git log 7759c18..9479daa`` in
|
||||||
|
the git repository.
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
screenshot-template=~/Desktop/shot%n
|
||||||
+12
-5
@@ -81,14 +81,21 @@ void mp_chmap_sel_add_alsa_def(struct mp_chmap_sel *s)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ARRAY_LEN(x) (sizeof(x) / sizeof((x)[0]))
|
|
||||||
|
|
||||||
// Add a channel map that should be allowed.
|
// Add a channel map that should be allowed.
|
||||||
void mp_chmap_sel_add_map(struct mp_chmap_sel *s, const struct mp_chmap *map)
|
void mp_chmap_sel_add_map(struct mp_chmap_sel *s, const struct mp_chmap *map)
|
||||||
{
|
{
|
||||||
assert(s->num_chmaps < ARRAY_LEN(s->chmaps));
|
if (!mp_chmap_is_valid(map))
|
||||||
if (mp_chmap_is_valid(map))
|
return;
|
||||||
s->chmaps[s->num_chmaps++] = *map;
|
if (!s->chmaps)
|
||||||
|
s->chmaps = s->chmaps_storage;
|
||||||
|
if (s->num_chmaps == MP_ARRAY_SIZE(s->chmaps_storage)) {
|
||||||
|
if (!s->tmp)
|
||||||
|
return;
|
||||||
|
s->chmaps = talloc_memdup(s->tmp, s->chmaps, sizeof(s->chmaps_storage));
|
||||||
|
}
|
||||||
|
if (s->chmaps != s->chmaps_storage)
|
||||||
|
MP_TARRAY_GROW(s->tmp, s->chmaps, s->num_chmaps);
|
||||||
|
s->chmaps[s->num_chmaps++] = *map;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow all waveext formats in default order.
|
// Allow all waveext formats in default order.
|
||||||
|
|||||||
+5
-1
@@ -26,8 +26,12 @@ struct mp_chmap_sel {
|
|||||||
// should be considered opaque
|
// should be considered opaque
|
||||||
bool allow_any, allow_waveext;
|
bool allow_any, allow_waveext;
|
||||||
bool speakers[MP_SPEAKER_ID_COUNT];
|
bool speakers[MP_SPEAKER_ID_COUNT];
|
||||||
struct mp_chmap chmaps[20];
|
struct mp_chmap *chmaps;
|
||||||
int num_chmaps;
|
int num_chmaps;
|
||||||
|
|
||||||
|
struct mp_chmap chmaps_storage[20];
|
||||||
|
|
||||||
|
void *tmp; // set to any talloc context to allow more chmaps entries
|
||||||
};
|
};
|
||||||
|
|
||||||
void mp_chmap_sel_add_any(struct mp_chmap_sel *s);
|
void mp_chmap_sel_add_any(struct mp_chmap_sel *s);
|
||||||
|
|||||||
@@ -280,8 +280,13 @@ static inline void update_ch(af_hrtf_t *s, short *in, const int k)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* We need to update the bass compensation delay line, too. */
|
/* We need to update the bass compensation delay line, too. */
|
||||||
s->ba_l[k] = in[0] + in[4] + in[2];
|
// TODO: should this use lf/cf/rf etc. instead?
|
||||||
s->ba_r[k] = in[4] + in[1] + in[3];
|
s->ba_l[k] = in[0];
|
||||||
|
s->ba_r[k] = in[1];
|
||||||
|
if (s->decode_mode == HRTF_MIX_51) {
|
||||||
|
s->ba_l[k] += in[4] + in[2];
|
||||||
|
s->ba_r[k] += in[4] + in[3];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clear_coeff(af_hrtf_t *s, float *c)
|
static void clear_coeff(af_hrtf_t *s, float *c)
|
||||||
|
|||||||
+2
-2
@@ -36,7 +36,7 @@ struct mixer {
|
|||||||
struct ao *ao;
|
struct ao *ao;
|
||||||
struct af_stream *af;
|
struct af_stream *af;
|
||||||
// Static, dependent on ao/softvol settings
|
// Static, dependent on ao/softvol settings
|
||||||
bool softvol; // use AO (true) or af_volume (false)
|
bool softvol; // use AO (false) or af_volume (true)
|
||||||
bool ao_softvol; // AO has private or per-app volume
|
bool ao_softvol; // AO has private or per-app volume
|
||||||
bool emulate_mute; // if true, emulate mute with volume=0
|
bool emulate_mute; // if true, emulate mute with volume=0
|
||||||
// Last known values (possibly out of sync with reality)
|
// Last known values (possibly out of sync with reality)
|
||||||
@@ -72,7 +72,7 @@ bool mixer_audio_initialized(struct mixer *mixer)
|
|||||||
float mixer_getneutralvolume(struct mixer *mixer)
|
float mixer_getneutralvolume(struct mixer *mixer)
|
||||||
{
|
{
|
||||||
// gain == 1
|
// gain == 1
|
||||||
return 1.0 / mixer->opts->softvol_max * 100.0 * 100.0;
|
return mixer->softvol ? 1.0 / mixer->opts->softvol_max * 100.0 * 100.0 : 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void checkvolume(struct mixer *mixer)
|
static void checkvolume(struct mixer *mixer)
|
||||||
|
|||||||
+10
-2
@@ -279,7 +279,7 @@ static int find_alsa_channel(int mp_channel)
|
|||||||
static bool query_chmaps(struct ao *ao, struct mp_chmap *chmap)
|
static bool query_chmaps(struct ao *ao, struct mp_chmap *chmap)
|
||||||
{
|
{
|
||||||
struct priv *p = ao->priv;
|
struct priv *p = ao->priv;
|
||||||
struct mp_chmap_sel chmap_sel = {0};
|
struct mp_chmap_sel chmap_sel = {.tmp = p};
|
||||||
|
|
||||||
snd_pcm_chmap_query_t **maps = snd_pcm_query_chmaps(p->alsa);
|
snd_pcm_chmap_query_t **maps = snd_pcm_query_chmaps(p->alsa);
|
||||||
if (!maps)
|
if (!maps)
|
||||||
@@ -461,17 +461,22 @@ static int init(struct ao *ao)
|
|||||||
if (strcmp(device, "default") != 0)
|
if (strcmp(device, "default") != 0)
|
||||||
device = talloc_asprintf(ao, "plug:%s", device);
|
device = talloc_asprintf(ao, "plug:%s", device);
|
||||||
}
|
}
|
||||||
|
const char *old_dev = device;
|
||||||
if (ao->device)
|
if (ao->device)
|
||||||
device = ao->device;
|
device = ao->device;
|
||||||
if (p->cfg_device && p->cfg_device[0])
|
if (p->cfg_device && p->cfg_device[0])
|
||||||
device = p->cfg_device;
|
device = p->cfg_device;
|
||||||
|
bool user_set_device = device != old_dev; // not strcmp()
|
||||||
|
|
||||||
MP_VERBOSE(ao, "using device: %s\n", device);
|
MP_VERBOSE(ao, "using device: %s\n", device);
|
||||||
MP_VERBOSE(ao, "using ALSA version: %s\n", snd_asoundlib_version());
|
MP_VERBOSE(ao, "using ALSA version: %s\n", snd_asoundlib_version());
|
||||||
|
|
||||||
err = try_open_device(ao, device, p->cfg_block ? 0 : SND_PCM_NONBLOCK);
|
err = try_open_device(ao, device, p->cfg_block ? 0 : SND_PCM_NONBLOCK);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
if (err != -EBUSY && !p->cfg_block) {
|
if (err == -EBUSY && !user_set_device && strcmp(device, "default") != 0) {
|
||||||
|
MP_WARN(ao, "Device '%s' busy, retrying default.\n", device);
|
||||||
|
err = try_open_device(ao, "default", 0);
|
||||||
|
} else if (err != -EBUSY && !p->cfg_block) {
|
||||||
MP_WARN(ao, "Open in nonblock-mode "
|
MP_WARN(ao, "Open in nonblock-mode "
|
||||||
"failed, trying to open in block-mode.\n");
|
"failed, trying to open in block-mode.\n");
|
||||||
err = try_open_device(ao, device, 0);
|
err = try_open_device(ao, device, 0);
|
||||||
@@ -630,6 +635,9 @@ static int init(struct ao *ao)
|
|||||||
MP_WARN(ao, "Got unknown channel map from ALSA.\n");
|
MP_WARN(ao, "Got unknown channel map from ALSA.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ao->channels.num == 1)
|
||||||
|
ao->channels.speaker[0] = MP_SP(FC);
|
||||||
|
|
||||||
free(alsa_chmap);
|
free(alsa_chmap);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+27
-13
@@ -185,7 +185,7 @@ static bool init_chmap(struct ao *ao)
|
|||||||
&layouts, &n_layouts);
|
&layouts, &n_layouts);
|
||||||
CHECK_CA_ERROR("could not get audio device prefered layouts");
|
CHECK_CA_ERROR("could not get audio device prefered layouts");
|
||||||
|
|
||||||
struct mp_chmap_sel chmap_sel = {0};
|
struct mp_chmap_sel chmap_sel = {.tmp = p};
|
||||||
for (int i = 0; i < n_layouts; i++) {
|
for (int i = 0; i < n_layouts; i++) {
|
||||||
struct mp_chmap chmap = {0};
|
struct mp_chmap chmap = {0};
|
||||||
if (ca_layout_to_mp_chmap(ao, &layouts[i], &chmap))
|
if (ca_layout_to_mp_chmap(ao, &layouts[i], &chmap))
|
||||||
@@ -354,22 +354,28 @@ static void ca_log_layout(struct ao *ao, AudioChannelLayout *layout)
|
|||||||
|
|
||||||
AudioChannelDescription *descs = layout->mChannelDescriptions;
|
AudioChannelDescription *descs = layout->mChannelDescriptions;
|
||||||
|
|
||||||
MP_VERBOSE(ao, "layout: tag: <%d>, bitmap: <%d>, "
|
MP_VERBOSE(ao, "layout: tag: <%u>, bitmap: <%u>, "
|
||||||
"descriptions <%d>\n",
|
"descriptions <%u>\n",
|
||||||
layout->mChannelLayoutTag,
|
(unsigned) layout->mChannelLayoutTag,
|
||||||
layout->mChannelBitmap,
|
(unsigned) layout->mChannelBitmap,
|
||||||
layout->mNumberChannelDescriptions);
|
(unsigned) layout->mNumberChannelDescriptions);
|
||||||
|
|
||||||
for (int i = 0; i < layout->mNumberChannelDescriptions; i++) {
|
for (int i = 0; i < layout->mNumberChannelDescriptions; i++) {
|
||||||
AudioChannelDescription d = descs[i];
|
AudioChannelDescription d = descs[i];
|
||||||
MP_VERBOSE(ao, " - description %d: label <%d, %d>, flags: <%u>, "
|
MP_VERBOSE(ao, " - description %d: label <%u, %u>, "
|
||||||
"coords: <%f, %f, %f>\n", i,
|
" flags: <%u>, coords: <%f, %f, %f>\n", i,
|
||||||
d.mChannelLabel,
|
(unsigned) d.mChannelLabel,
|
||||||
ca_label_to_mp_speaker_id(d.mChannelLabel),
|
(unsigned) ca_label_to_mp_speaker_id(d.mChannelLabel),
|
||||||
d.mChannelFlags,
|
(unsigned) d.mChannelFlags,
|
||||||
d.mCoordinates[0],
|
d.mCoordinates[0],
|
||||||
d.mCoordinates[1],
|
d.mCoordinates[1],
|
||||||
d.mCoordinates[2]);
|
d.mCoordinates[2]);
|
||||||
|
|
||||||
|
if (i >= 32) {
|
||||||
|
MP_VERBOSE(ao, " detected more than 32 channel descriptions, "
|
||||||
|
"skipping output");
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -410,14 +416,22 @@ bool ca_layout_to_mp_chmap(struct ao *ao, AudioChannelLayout *layout,
|
|||||||
// to the waveextensible definition: this is the kind of
|
// to the waveextensible definition: this is the kind of
|
||||||
// descriptions we process here.
|
// descriptions we process here.
|
||||||
|
|
||||||
|
if (layout->mNumberChannelDescriptions > MP_NUM_CHANNELS) {
|
||||||
|
MP_VERBOSE(ao, "layout has too many descriptions (%u, max: %d)\n",
|
||||||
|
(unsigned) layout->mNumberChannelDescriptions,
|
||||||
|
MP_NUM_CHANNELS);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
for (int n = 0; n < layout->mNumberChannelDescriptions; n++) {
|
for (int n = 0; n < layout->mNumberChannelDescriptions; n++) {
|
||||||
AudioChannelLabel label = layout->mChannelDescriptions[n].mChannelLabel;
|
AudioChannelLabel label = layout->mChannelDescriptions[n].mChannelLabel;
|
||||||
uint8_t speaker = ca_label_to_mp_speaker_id(label);
|
uint8_t speaker = ca_label_to_mp_speaker_id(label);
|
||||||
if (label == kAudioChannelLabel_Unknown)
|
if (label == kAudioChannelLabel_Unknown)
|
||||||
continue;
|
continue;
|
||||||
if (speaker < 0) {
|
if (speaker < 0) {
|
||||||
MP_VERBOSE(ao, "channel label=%d unusable to build channel "
|
MP_VERBOSE(ao, "channel label=%u unusable to build channel "
|
||||||
"bitmap, skipping layout\n", label);
|
"bitmap, skipping layout\n", (unsigned) label);
|
||||||
|
goto coreaudio_error;
|
||||||
} else {
|
} else {
|
||||||
chmap->speaker[n] = speaker;
|
chmap->speaker[n] = speaker;
|
||||||
chmap->num = n + 1;
|
chmap->num = n + 1;
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ OSStatus ca_get_ary(AudioObjectID id, ca_scope scope, ca_sel selector,
|
|||||||
err = AudioObjectGetPropertyDataSize(id, &p_addr, 0, NULL, &p_size);
|
err = AudioObjectGetPropertyDataSize(id, &p_addr, 0, NULL, &p_size);
|
||||||
CHECK_CA_ERROR_SILENT_L(coreaudio_error);
|
CHECK_CA_ERROR_SILENT_L(coreaudio_error);
|
||||||
|
|
||||||
*data = talloc_size(NULL, p_size);
|
*data = talloc_zero_size(NULL, p_size);
|
||||||
*elements = p_size / element_size;
|
*elements = p_size / element_size;
|
||||||
|
|
||||||
err = ca_get(id, scope, selector, p_size, *data);
|
err = ca_get(id, scope, selector, p_size, *data);
|
||||||
@@ -87,7 +87,7 @@ OSStatus ca_get_str(AudioObjectID id, ca_scope scope, ca_sel selector,
|
|||||||
CFStringGetMaximumSizeForEncoding(
|
CFStringGetMaximumSizeForEncoding(
|
||||||
CFStringGetLength(string), CA_CFSTR_ENCODING) + 1;
|
CFStringGetLength(string), CA_CFSTR_ENCODING) + 1;
|
||||||
|
|
||||||
*data = talloc_size(NULL, size);
|
*data = talloc_zero_size(NULL, size);
|
||||||
CFStringGetCString(string, *data, size, CA_CFSTR_ENCODING);
|
CFStringGetCString(string, *data, size, CA_CFSTR_ENCODING);
|
||||||
CFRelease(string);
|
CFRelease(string);
|
||||||
coreaudio_error:
|
coreaudio_error:
|
||||||
|
|||||||
@@ -286,6 +286,8 @@ static int lavf_check_file(demuxer_t *demuxer, enum demux_check check)
|
|||||||
.buf_size = 0,
|
.buf_size = 0,
|
||||||
.buf = av_mallocz(PROBE_BUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE),
|
.buf = av_mallocz(PROBE_BUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE),
|
||||||
};
|
};
|
||||||
|
if (!avpd.buf)
|
||||||
|
return -1;
|
||||||
|
|
||||||
bool final_probe = false;
|
bool final_probe = false;
|
||||||
do {
|
do {
|
||||||
@@ -679,6 +681,8 @@ static int demux_open_lavf(demuxer_t *demuxer, enum demux_check check)
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
avfc = avformat_alloc_context();
|
avfc = avformat_alloc_context();
|
||||||
|
if (!avfc)
|
||||||
|
return -1;
|
||||||
|
|
||||||
if (lavfdopts->cryptokey)
|
if (lavfdopts->cryptokey)
|
||||||
parse_cryptokey(avfc, lavfdopts->cryptokey);
|
parse_cryptokey(avfc, lavfdopts->cryptokey);
|
||||||
|
|||||||
+12
-6
@@ -345,6 +345,10 @@ static int demux_mkv_read_info(demuxer_t *demuxer)
|
|||||||
if (info.n_timecode_scale) {
|
if (info.n_timecode_scale) {
|
||||||
mkv_d->tc_scale = info.timecode_scale;
|
mkv_d->tc_scale = info.timecode_scale;
|
||||||
MP_VERBOSE(demuxer, "| + timecode scale: %" PRIu64 "\n", mkv_d->tc_scale);
|
MP_VERBOSE(demuxer, "| + timecode scale: %" PRIu64 "\n", mkv_d->tc_scale);
|
||||||
|
if (mkv_d->tc_scale < 1 || mkv_d->tc_scale > INT_MAX) {
|
||||||
|
res = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (info.n_duration) {
|
if (info.n_duration) {
|
||||||
mkv_d->duration = info.duration * mkv_d->tc_scale / 1e9;
|
mkv_d->duration = info.duration * mkv_d->tc_scale / 1e9;
|
||||||
@@ -1414,20 +1418,22 @@ static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track)
|
|||||||
sh_a->bitrate = 16000 * 8;
|
sh_a->bitrate = 16000 * 8;
|
||||||
sh_a->block_align = 1024;
|
sh_a->block_align = 1024;
|
||||||
|
|
||||||
if (!strcmp(track->codec_id, MKV_A_AAC) && track->private_data) {
|
if (!strcmp(track->codec_id, MKV_A_AAC)) {
|
||||||
if (!extradata_len) {
|
if (track->private_data && !extradata_len) {
|
||||||
extradata = track->private_data;
|
extradata = track->private_data;
|
||||||
extradata_len = track->private_size;
|
extradata_len = track->private_size;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Recreate the 'private data' */
|
/* Recreate the 'private data' */
|
||||||
/* which faad2 uses in its initialization */
|
|
||||||
srate_idx = aac_get_sample_rate_index(track->a_sfreq);
|
srate_idx = aac_get_sample_rate_index(track->a_sfreq);
|
||||||
if (!strncmp(&track->codec_id[12], "MAIN", 4))
|
const char *tail = "";
|
||||||
|
if (strlen(track->codec_id) >= 12)
|
||||||
|
tail = &track->codec_id[12];
|
||||||
|
if (!strncmp(tail, "MAIN", 4))
|
||||||
profile = 0;
|
profile = 0;
|
||||||
else if (!strncmp(&track->codec_id[12], "LC", 2))
|
else if (!strncmp(tail, "LC", 2))
|
||||||
profile = 1;
|
profile = 1;
|
||||||
else if (!strncmp(&track->codec_id[12], "SSR", 3))
|
else if (!strncmp(tail, "SSR", 3))
|
||||||
profile = 2;
|
profile = 2;
|
||||||
else
|
else
|
||||||
profile = 3;
|
profile = 3;
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ static int parse_m3u(struct pl_parser *p)
|
|||||||
return -1;
|
return -1;
|
||||||
if (p->probing)
|
if (p->probing)
|
||||||
return 0;
|
return 0;
|
||||||
while (!pl_eof(p)) {
|
while (line.len || !pl_eof(p)) {
|
||||||
if (line.len > 0 && !bstr_startswith0(line, "#"))
|
if (line.len > 0 && !bstr_startswith0(line, "#"))
|
||||||
pl_add(p, line);
|
pl_add(p, line);
|
||||||
line = bstr_strip(pl_get_line(p));
|
line = bstr_strip(pl_get_line(p));
|
||||||
@@ -110,7 +110,7 @@ static int parse_ref_init(struct pl_parser *p)
|
|||||||
"application/vnd.ms.wms-hdr.asfv1", NULL};
|
"application/vnd.ms.wms-hdr.asfv1", NULL};
|
||||||
bstr burl = bstr0(p->s->url);
|
bstr burl = bstr0(p->s->url);
|
||||||
if (bstr_eatstart0(&burl, "http://") && check_mimetype(p->s, mmsh_types)) {
|
if (bstr_eatstart0(&burl, "http://") && check_mimetype(p->s, mmsh_types)) {
|
||||||
MP_INFO(p, "Redirectiong to mmsh://\n");
|
MP_INFO(p, "Redirecting to mmsh://\n");
|
||||||
playlist_add_file(p->pl, talloc_asprintf(p, "mmsh://%.*s", BSTR_P(burl)));
|
playlist_add_file(p->pl, talloc_asprintf(p, "mmsh://%.*s", BSTR_P(burl)));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-3
@@ -445,6 +445,8 @@ static struct cmd_bind *find_any_bind_for_key(struct input_ctx *ictx,
|
|||||||
}
|
}
|
||||||
if (s->flags & MP_INPUT_EXCLUSIVE)
|
if (s->flags & MP_INPUT_EXCLUSIVE)
|
||||||
break;
|
break;
|
||||||
|
if (best_bind && (s->flags & MP_INPUT_ON_TOP))
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return best_bind;
|
return best_bind;
|
||||||
@@ -1019,14 +1021,15 @@ void mp_input_define_section(struct input_ctx *ictx, char *name, char *location,
|
|||||||
if (!name || !name[0])
|
if (!name || !name[0])
|
||||||
return; // parse_config() changes semantics with restrict_section==empty
|
return; // parse_config() changes semantics with restrict_section==empty
|
||||||
input_lock(ictx);
|
input_lock(ictx);
|
||||||
|
// Delete:
|
||||||
|
struct cmd_bind_section *bs = get_bind_section(ictx, bstr0(name));
|
||||||
|
remove_binds(bs, builtin);
|
||||||
if (contents) {
|
if (contents) {
|
||||||
|
// Redefine:
|
||||||
parse_config(ictx, builtin, bstr0(contents), location, name);
|
parse_config(ictx, builtin, bstr0(contents), location, name);
|
||||||
} else {
|
} else {
|
||||||
// Disable:
|
// Disable:
|
||||||
mp_input_disable_section(ictx, name);
|
mp_input_disable_section(ictx, name);
|
||||||
// Delete:
|
|
||||||
struct cmd_bind_section *bs = get_bind_section(ictx, bstr0(name));
|
|
||||||
remove_binds(bs, builtin);
|
|
||||||
}
|
}
|
||||||
input_unlock(ictx);
|
input_unlock(ictx);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,6 +45,16 @@ static void read_pipe_thread(struct mp_input_src *src, void *param)
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we're reading from stdin, unset it. All I/O on synchronous handles is
|
||||||
|
// serialized, so stupid DLLs that call GetFileType on stdin can hang the
|
||||||
|
// process if they do it while we're reading from it. At least, the
|
||||||
|
// VirtualBox OpenGL ICD is affected by this, but only on Windows XP.
|
||||||
|
// GetFileType works differently in later versions of Windows. See:
|
||||||
|
// https://support.microsoft.com/kb/2009703
|
||||||
|
// http://blogs.msdn.com/b/oldnewthing/archive/2011/12/02/10243553.aspx
|
||||||
|
if ((void*)_get_osfhandle(fd) == GetStdHandle(STD_INPUT_HANDLE))
|
||||||
|
SetStdHandle(STD_INPUT_HANDLE, NULL);
|
||||||
|
|
||||||
waio = waio_alloc((void *)_get_osfhandle(fd), 0, NULL, NULL);
|
waio = waio_alloc((void *)_get_osfhandle(fd), 0, NULL, NULL);
|
||||||
if (!waio) {
|
if (!waio) {
|
||||||
MP_ERR(src, "Can't initialize win32 file reader.\n");
|
MP_ERR(src, "Can't initialize win32 file reader.\n");
|
||||||
|
|||||||
+2
-2
@@ -2146,7 +2146,7 @@ static int parse_chmap(struct mp_log *log, const m_option_t *opt,
|
|||||||
|
|
||||||
const m_option_type_t m_option_type_chmap = {
|
const m_option_type_t m_option_type_chmap = {
|
||||||
.name = "Audio channels or channel map",
|
.name = "Audio channels or channel map",
|
||||||
.size = sizeof(struct mp_chmap *),
|
.size = sizeof(struct mp_chmap),
|
||||||
.parse = parse_chmap,
|
.parse = parse_chmap,
|
||||||
.copy = copy_opt,
|
.copy = copy_opt,
|
||||||
};
|
};
|
||||||
@@ -2620,7 +2620,7 @@ static int parse_obj_settings(struct mp_log *log, struct bstr opt,
|
|||||||
if (m_obj_list_find(&desc, list, str)) {
|
if (m_obj_list_find(&desc, list, str)) {
|
||||||
if (desc.replaced_name)
|
if (desc.replaced_name)
|
||||||
mp_warn(log, "Driver '%s' has been replaced with '%s'!\n",
|
mp_warn(log, "Driver '%s' has been replaced with '%s'!\n",
|
||||||
desc.name, desc.replaced_name);
|
desc.replaced_name, desc.name);
|
||||||
} else {
|
} else {
|
||||||
if (!list->allow_unknown_entries) {
|
if (!list->allow_unknown_entries) {
|
||||||
mp_err(log, "Option %.*s: %.*s doesn't exist.\n",
|
mp_err(log, "Option %.*s: %.*s doesn't exist.\n",
|
||||||
|
|||||||
+1
-1
@@ -614,7 +614,7 @@ const struct MPOpts mp_default_opts = {
|
|||||||
.use_text_osd = 1,
|
.use_text_osd = 1,
|
||||||
#if HAVE_LUA
|
#if HAVE_LUA
|
||||||
.lua_load_osc = 1,
|
.lua_load_osc = 1,
|
||||||
.lua_load_ytdl = 0,
|
.lua_load_ytdl = 1,
|
||||||
.lua_ytdl_format = NULL,
|
.lua_ytdl_format = NULL,
|
||||||
#endif
|
#endif
|
||||||
.auto_load_scripts = 1,
|
.auto_load_scripts = 1,
|
||||||
|
|||||||
@@ -233,6 +233,8 @@ Application *mpv_shared_app(void)
|
|||||||
options:NSAnchoredSearch
|
options:NSAnchoredSearch
|
||||||
range:NSMakeRange(0, [MPV_PROTOCOL length])];
|
range:NSMakeRange(0, [MPV_PROTOCOL length])];
|
||||||
|
|
||||||
|
url = [url stringByRemovingPercentEncoding];
|
||||||
|
|
||||||
self.files = @[url];
|
self.files = @[url];
|
||||||
|
|
||||||
if (self.willStopOnOpenEvent) {
|
if (self.willStopOnOpenEvent) {
|
||||||
@@ -329,7 +331,10 @@ void init_cocoa_application(void)
|
|||||||
NSApp = mpv_shared_app();
|
NSApp = mpv_shared_app();
|
||||||
[NSApp setDelegate:NSApp];
|
[NSApp setDelegate:NSApp];
|
||||||
[NSApp initialize_menu];
|
[NSApp initialize_menu];
|
||||||
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
|
|
||||||
|
// Will be set to Regular from cocoa_common during UI creation so that we
|
||||||
|
// don't create an icon when playing audio only files.
|
||||||
|
[NSApp setActivationPolicy:NSApplicationActivationPolicyAccessory];
|
||||||
|
|
||||||
atexit_b(^{
|
atexit_b(^{
|
||||||
// Because activation policy has just been set to behave like a real
|
// Because activation policy has just been set to behave like a real
|
||||||
@@ -439,21 +444,6 @@ static bool bundle_started_from_finder(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char macosx_icon[] =
|
|
||||||
#include "osdep/macosx_icon.inc"
|
|
||||||
;
|
|
||||||
|
|
||||||
static void set_application_icon(NSApplication *app)
|
|
||||||
{
|
|
||||||
NSData *icon_data = [NSData dataWithBytesNoCopy:(void *)macosx_icon
|
|
||||||
length:sizeof(macosx_icon)
|
|
||||||
freeWhenDone:NO];
|
|
||||||
NSImage *icon = [[NSImage alloc] initWithData:icon_data];
|
|
||||||
[app setApplicationIconImage:icon];
|
|
||||||
[icon release];
|
|
||||||
[icon_data release];
|
|
||||||
}
|
|
||||||
|
|
||||||
void macosx_finder_args_preinit(int *argc, char ***argv)
|
void macosx_finder_args_preinit(int *argc, char ***argv)
|
||||||
{
|
{
|
||||||
Application *app = mpv_shared_app();
|
Application *app = mpv_shared_app();
|
||||||
@@ -475,7 +465,6 @@ void macosx_finder_args_preinit(int *argc, char ***argv)
|
|||||||
*argc = cocoa_argc;
|
*argc = cocoa_argc;
|
||||||
*argv = cocoa_argv;
|
*argv = cocoa_argv;
|
||||||
} else {
|
} else {
|
||||||
set_application_icon(app);
|
|
||||||
for (int i = 0; i < *argc; i++ ) {
|
for (int i = 0; i < *argc; i++ ) {
|
||||||
NSString *arg = [NSString stringWithUTF8String:(*argv)[i]];
|
NSString *arg = [NSString stringWithUTF8String:(*argv)[i]];
|
||||||
[app.argumentsList addObject:arg];
|
[app.argumentsList addObject:arg];
|
||||||
|
|||||||
@@ -440,8 +440,10 @@ void cocoa_set_input_context(struct input_ctx *input_context)
|
|||||||
size_t num_files = [files count];
|
size_t num_files = [files count];
|
||||||
char **files_utf8 = talloc_array(NULL, char*, num_files);
|
char **files_utf8 = talloc_array(NULL, char*, num_files);
|
||||||
[files enumerateObjectsUsingBlock:^(id obj, NSUInteger i, BOOL *_){
|
[files enumerateObjectsUsingBlock:^(id obj, NSUInteger i, BOOL *_){
|
||||||
char *filename = (char *)[obj UTF8String];
|
NSURL *url = [NSURL URLWithString:obj];
|
||||||
size_t bytes = [obj lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
|
NSString *path = [url path];
|
||||||
|
char *filename = (char *)[path UTF8String];
|
||||||
|
size_t bytes = [path lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
|
||||||
files_utf8[i] = talloc_memdup(files_utf8, filename, bytes + 1);
|
files_utf8[i] = talloc_memdup(files_utf8, filename, bytes + 1);
|
||||||
}];
|
}];
|
||||||
mp_event_drop_files(_inputContext, num_files, files_utf8);
|
mp_event_drop_files(_inputContext, num_files, files_utf8);
|
||||||
|
|||||||
@@ -111,9 +111,8 @@ static int create_overlapped_pipe(HANDLE *read, HANDLE *write)
|
|||||||
// overlapped pipes, so instead, use a named pipe with a unique name
|
// overlapped pipes, so instead, use a named pipe with a unique name
|
||||||
*read = CreateNamedPipeW(buf, PIPE_ACCESS_INBOUND |
|
*read = CreateNamedPipeW(buf, PIPE_ACCESS_INBOUND |
|
||||||
FILE_FLAG_FIRST_PIPE_INSTANCE | FILE_FLAG_OVERLAPPED,
|
FILE_FLAG_FIRST_PIPE_INSTANCE | FILE_FLAG_OVERLAPPED,
|
||||||
PIPE_TYPE_BYTE | PIPE_WAIT | PIPE_REJECT_REMOTE_CLIENTS,
|
PIPE_TYPE_BYTE | PIPE_WAIT, 1, 0, 4096, 0, NULL);
|
||||||
1, 0, 4096, 0, NULL);
|
if (*read == INVALID_HANDLE_VALUE)
|
||||||
if (!*read)
|
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
// Open the write end of the pipe as a synchronous handle
|
// Open the write end of the pipe as a synchronous handle
|
||||||
|
|||||||
@@ -515,7 +515,6 @@ static void do_fill_audio_out_buffers(struct MPContext *mpctx, double endpts)
|
|||||||
// later. Retrying is needed to get the correct sync PTS.
|
// later. Retrying is needed to get the correct sync PTS.
|
||||||
if (mpctx->audio_status >= STATUS_DRAINING && status == AD_OK) {
|
if (mpctx->audio_status >= STATUS_DRAINING && status == AD_OK) {
|
||||||
mpctx->audio_status = STATUS_SYNCING;
|
mpctx->audio_status = STATUS_SYNCING;
|
||||||
mpctx->sleeptime = 0;
|
|
||||||
return; // retry on next iteration
|
return; // retry on next iteration
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-2
@@ -4350,7 +4350,9 @@ int run_command(MPContext *mpctx, mp_cmd_t *cmd)
|
|||||||
struct track *sub = mp_add_subtitles(mpctx, cmd->args[0].v.s);
|
struct track *sub = mp_add_subtitles(mpctx, cmd->args[0].v.s);
|
||||||
if (!sub)
|
if (!sub)
|
||||||
return -1;
|
return -1;
|
||||||
if (cmd->args[1].v.i != 1) {
|
if (cmd->args[1].v.i == 1) {
|
||||||
|
sub->no_default = true;
|
||||||
|
} else {
|
||||||
mp_switch_track(mpctx, sub->type, sub);
|
mp_switch_track(mpctx, sub->type, sub);
|
||||||
mp_mark_user_track_selection(mpctx, 0, sub->type);
|
mp_mark_user_track_selection(mpctx, 0, sub->type);
|
||||||
}
|
}
|
||||||
@@ -4492,7 +4494,7 @@ int run_command(MPContext *mpctx, mp_cmd_t *cmd)
|
|||||||
char *sep = strchr(name, '/');
|
char *sep = strchr(name, '/');
|
||||||
char *target = NULL;
|
char *target = NULL;
|
||||||
char space[MAX_CLIENT_NAME];
|
char space[MAX_CLIENT_NAME];
|
||||||
if (name) {
|
if (sep) {
|
||||||
snprintf(space, sizeof(space), "%.*s", (int)(sep - name), name);
|
snprintf(space, sizeof(space), "%.*s", (int)(sep - name), name);
|
||||||
target = space;
|
target = space;
|
||||||
name = sep + 1;
|
name = sep + 1;
|
||||||
|
|||||||
@@ -243,6 +243,8 @@ static const char *const backup_properties[] = {
|
|||||||
"options/ass-use-margins",
|
"options/ass-use-margins",
|
||||||
"options/ass-vsfilter-aspect-compat",
|
"options/ass-vsfilter-aspect-compat",
|
||||||
"options/ass-style-override",
|
"options/ass-style-override",
|
||||||
|
"options/ab-loop-a",
|
||||||
|
"options/ab-loop-b",
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+2
-3
@@ -125,9 +125,8 @@ void mp_nav_init(struct MPContext *mpctx)
|
|||||||
|
|
||||||
MP_VERBOSE(mpctx->nav_state, "enabling\n");
|
MP_VERBOSE(mpctx->nav_state, "enabling\n");
|
||||||
|
|
||||||
mp_input_enable_section(mpctx->input, "discnav", 0);
|
mp_input_enable_section(mpctx->input, "discnav",
|
||||||
mp_input_set_section_mouse_area(mpctx->input, "discnav-menu",
|
MP_INPUT_ALLOW_VO_DRAGGING | MP_INPUT_ALLOW_HIDE_CURSOR);
|
||||||
INT_MIN, INT_MIN, INT_MAX, INT_MAX);
|
|
||||||
|
|
||||||
update_state(mpctx);
|
update_state(mpctx);
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-5
@@ -300,14 +300,17 @@ double timeline_set_from_time(struct MPContext *mpctx, double pts, bool *need_re
|
|||||||
{
|
{
|
||||||
if (pts < 0)
|
if (pts < 0)
|
||||||
pts = 0;
|
pts = 0;
|
||||||
|
|
||||||
|
int new = mpctx->num_timeline_parts - 1;
|
||||||
for (int i = 0; i < mpctx->num_timeline_parts; i++) {
|
for (int i = 0; i < mpctx->num_timeline_parts; i++) {
|
||||||
struct timeline_part *p = mpctx->timeline + i;
|
if (pts < mpctx->timeline[i + 1].start) {
|
||||||
if (pts < (p + 1)->start) {
|
new = i;
|
||||||
*need_reset = timeline_set_part(mpctx, i, false);
|
break;
|
||||||
return pts - p->start + p->source_start;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return MP_NOPTS_VALUE;
|
|
||||||
|
*need_reset = timeline_set_part(mpctx, new, false);
|
||||||
|
return pts - mpctx->timeline[new].start + mpctx->timeline[new].source_start;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int find_new_tid(struct MPContext *mpctx, enum stream_type t)
|
static int find_new_tid(struct MPContext *mpctx, enum stream_type t)
|
||||||
@@ -964,6 +967,7 @@ static void play_current_file(struct MPContext *mpctx)
|
|||||||
|
|
||||||
if (opts->stream_dump && opts->stream_dump[0]) {
|
if (opts->stream_dump && opts->stream_dump[0]) {
|
||||||
stream_dump(mpctx);
|
stream_dump(mpctx);
|
||||||
|
mpctx->error_playing = 1;
|
||||||
goto terminate_playback;
|
goto terminate_playback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1043,7 +1043,7 @@ static int script_input_enable_section(lua_State *L)
|
|||||||
} else if (bstr_equals0(val, "exclusive")) {
|
} else if (bstr_equals0(val, "exclusive")) {
|
||||||
flags |= MP_INPUT_EXCLUSIVE;
|
flags |= MP_INPUT_EXCLUSIVE;
|
||||||
} else {
|
} else {
|
||||||
luaL_error(L, "invalid flag: '%.*s'", BSTR_P(val));
|
luaL_error(L, "invalid flag");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mp_input_enable_section(mpctx->input, section, flags);
|
mp_input_enable_section(mpctx->input, section, flags);
|
||||||
|
|||||||
+16
-3
@@ -1853,9 +1853,13 @@ function tick()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function do_enable_keybindings()
|
||||||
|
mp.enable_key_bindings("showhide", "allow-vo-dragging|allow-hide-cursor")
|
||||||
|
end
|
||||||
|
|
||||||
function enable_osc(enable)
|
function enable_osc(enable)
|
||||||
if enable then
|
if enable then
|
||||||
mp.enable_key_bindings("showhide")
|
do_enable_keybindings()
|
||||||
show_osc()
|
show_osc()
|
||||||
else
|
else
|
||||||
hide_osc()
|
hide_osc()
|
||||||
@@ -1876,12 +1880,21 @@ mp.observe_property("fullscreen", "bool", function(name, val) state.fullscreen =
|
|||||||
mp.observe_property("pause", "bool", pause_state)
|
mp.observe_property("pause", "bool", pause_state)
|
||||||
mp.observe_property("cache-idle", "bool", cache_state)
|
mp.observe_property("cache-idle", "bool", cache_state)
|
||||||
|
|
||||||
|
mp.observe_property("disc-menu-active", "bool", function(name, val)
|
||||||
|
if val == true then
|
||||||
|
hide_osc()
|
||||||
|
mp.disable_key_bindings("showhide")
|
||||||
|
else
|
||||||
|
do_enable_keybindings()
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
-- mouse show/hide bindings
|
-- mouse show/hide bindings
|
||||||
mp.set_key_bindings({
|
mp.set_key_bindings({
|
||||||
{"mouse_move", function(e) process_event("mouse_move", nil) end},
|
{"mouse_move", function(e) process_event("mouse_move", nil) end},
|
||||||
{"mouse_leave", mouse_leave},
|
{"mouse_leave", mouse_leave},
|
||||||
}, "showhide")
|
}, "showhide", "force")
|
||||||
mp.enable_key_bindings("showhide", "allow-vo-dragging|allow-hide-cursor")
|
do_enable_keybindings()
|
||||||
|
|
||||||
--mouse input bindings
|
--mouse input bindings
|
||||||
mp.set_key_bindings({
|
mp.set_key_bindings({
|
||||||
|
|||||||
+42
-15
@@ -3,7 +3,7 @@ local msg = require 'mp.msg'
|
|||||||
|
|
||||||
local ytdl = {
|
local ytdl = {
|
||||||
path = "youtube-dl",
|
path = "youtube-dl",
|
||||||
minver = "2014.11.09",
|
minver = "2014.11.26",
|
||||||
vercheck = nil,
|
vercheck = nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,30 +97,57 @@ mp.add_hook("on_load", 10, function ()
|
|||||||
elseif not (json["_type"] == nil) and (json["_type"] == "playlist") then
|
elseif not (json["_type"] == nil) and (json["_type"] == "playlist") then
|
||||||
-- a playlist
|
-- a playlist
|
||||||
|
|
||||||
local playlist = "#EXTM3U\n"
|
-- some funky guessing to detect multi-arc videos
|
||||||
for i, entry in pairs(json.entries) do
|
if not (json.entries[1]["webpage_url"] == nil)
|
||||||
local site = entry.url
|
and (json.entries[1]["webpage_url"] == json["webpage_url"]) then
|
||||||
|
msg.verbose("multi-arc video detected, building EDL")
|
||||||
|
|
||||||
-- some extractors will still return the full info for
|
|
||||||
-- all clips in the playlist and the URL will point
|
local playlist = "edl://"
|
||||||
-- directly to the file in that case, which we don't
|
for i, entry in pairs(json.entries) do
|
||||||
-- want so get the webpage URL instead, which is what
|
|
||||||
-- we want
|
playlist = playlist .. entry.url .. ";"
|
||||||
if not (entry["webpage_url"] == nil) then
|
|
||||||
site = entry["webpage_url"]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
playlist = playlist .. "ytdl://" .. site .. "\n"
|
msg.debug("EDL: " .. playlist)
|
||||||
end
|
|
||||||
|
|
||||||
mp.set_property("stream-open-filename", "memory://" .. playlist)
|
|
||||||
|
mp.set_property("stream-open-filename", playlist)
|
||||||
|
if not (json.title == nil) then
|
||||||
|
mp.set_property("file-local-options/media-title", json.title)
|
||||||
|
end
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
local playlist = "#EXTM3U\n"
|
||||||
|
for i, entry in pairs(json.entries) do
|
||||||
|
local site = entry.url
|
||||||
|
|
||||||
|
-- some extractors will still return the full info for
|
||||||
|
-- all clips in the playlist and the URL will point
|
||||||
|
-- directly to the file in that case, which we don't
|
||||||
|
-- want so get the webpage URL instead, which is what
|
||||||
|
-- we want
|
||||||
|
if not (entry["webpage_url"] == nil) then
|
||||||
|
site = entry["webpage_url"]
|
||||||
|
end
|
||||||
|
|
||||||
|
playlist = playlist .. "ytdl://" .. site .. "\n"
|
||||||
|
end
|
||||||
|
|
||||||
|
mp.set_property("stream-open-filename", "memory://" .. playlist)
|
||||||
|
end
|
||||||
|
|
||||||
else -- probably a video
|
else -- probably a video
|
||||||
local streamurl = ""
|
local streamurl = ""
|
||||||
|
|
||||||
-- DASH?
|
-- DASH?
|
||||||
if not (json["requested_formats"] == nil) then
|
if not (json["requested_formats"] == nil) then
|
||||||
msg.info("NOTE: Using DASH, expect inaccurate duration.")
|
msg.info("Using DASH, expect inaccurate duration.")
|
||||||
|
if not (json.duration == nil) then
|
||||||
|
msg.info("actual duration: " .. mp.format_time(json.duration))
|
||||||
|
end
|
||||||
|
|
||||||
-- video url
|
-- video url
|
||||||
streamurl = json["requested_formats"][1].url
|
streamurl = json["requested_formats"][1].url
|
||||||
|
|
||||||
|
|||||||
+3
-12
@@ -214,16 +214,6 @@ static int mp_seek(MPContext *mpctx, struct seek_params seek,
|
|||||||
bool need_reset = false;
|
bool need_reset = false;
|
||||||
demuxer_amount = timeline_set_from_time(mpctx, seek.amount,
|
demuxer_amount = timeline_set_from_time(mpctx, seek.amount,
|
||||||
&need_reset);
|
&need_reset);
|
||||||
if (demuxer_amount == MP_NOPTS_VALUE) {
|
|
||||||
assert(!need_reset);
|
|
||||||
mpctx->stop_play = AT_END_OF_FILE;
|
|
||||||
// When seeking outside of the file, but not when ending last segment.
|
|
||||||
if (!timeline_fallthrough) {
|
|
||||||
clear_audio_output_buffers(mpctx);
|
|
||||||
reset_playback_state(mpctx);
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (need_reset) {
|
if (need_reset) {
|
||||||
reinit_video_chain(mpctx);
|
reinit_video_chain(mpctx);
|
||||||
reinit_audio_chain(mpctx);
|
reinit_audio_chain(mpctx);
|
||||||
@@ -961,10 +951,11 @@ void run_playloop(struct MPContext *mpctx)
|
|||||||
mpctx->audio_status == STATUS_EOF &&
|
mpctx->audio_status == STATUS_EOF &&
|
||||||
mpctx->video_status == STATUS_EOF)
|
mpctx->video_status == STATUS_EOF)
|
||||||
{
|
{
|
||||||
if (end_is_new_segment) {
|
int new_part = mpctx->timeline_part + 1;
|
||||||
|
if (end_is_new_segment && new_part < mpctx->num_timeline_parts) {
|
||||||
mp_seek(mpctx, (struct seek_params){
|
mp_seek(mpctx, (struct seek_params){
|
||||||
.type = MPSEEK_ABSOLUTE,
|
.type = MPSEEK_ABSOLUTE,
|
||||||
.amount = mpctx->timeline[mpctx->timeline_part+1].start
|
.amount = mpctx->timeline[new_part].start
|
||||||
}, true);
|
}, true);
|
||||||
} else
|
} else
|
||||||
mpctx->stop_play = AT_END_OF_FILE;
|
mpctx->stop_play = AT_END_OF_FILE;
|
||||||
|
|||||||
+3
-4
@@ -127,8 +127,8 @@ void uninit_sub_renderer(struct MPContext *mpctx)
|
|||||||
static void init_sub_renderer(struct MPContext *mpctx) {}
|
static void init_sub_renderer(struct MPContext *mpctx) {}
|
||||||
void uninit_sub_renderer(struct MPContext *mpctx) {}
|
void uninit_sub_renderer(struct MPContext *mpctx) {}
|
||||||
|
|
||||||
void mp_ass_configure(ASS_Renderer *priv, struct MPOpts *opts,
|
void mp_ass_configure_fonts(struct ass_renderer *a, struct MPOpts *b,
|
||||||
struct mp_osd_res *dim) {}
|
struct mpv_global *c, struct mp_log *d) {}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -227,10 +227,9 @@ static void update_subtitle(struct MPContext *mpctx, int order)
|
|||||||
struct track *track = mpctx->current_track[order][STREAM_SUB];
|
struct track *track = mpctx->current_track[order][STREAM_SUB];
|
||||||
struct dec_sub *dec_sub = mpctx->d_sub[order];
|
struct dec_sub *dec_sub = mpctx->d_sub[order];
|
||||||
|
|
||||||
if (!track)
|
if (!track || !dec_sub)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
assert(dec_sub);
|
|
||||||
int obj = order ? OSDTYPE_SUB2 : OSDTYPE_SUB;
|
int obj = order ? OSDTYPE_SUB2 : OSDTYPE_SUB;
|
||||||
|
|
||||||
if (mpctx->d_video) {
|
if (mpctx->d_video) {
|
||||||
|
|||||||
@@ -243,11 +243,6 @@ static int control(stream_t *stream, int cmd, void *arg)
|
|||||||
{
|
{
|
||||||
cdda_priv *p = stream->priv;
|
cdda_priv *p = stream->priv;
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case STREAM_CTRL_GET_NUM_TITLES:
|
|
||||||
{
|
|
||||||
*(unsigned int *)arg = p->cd->tracks;
|
|
||||||
return STREAM_OK;
|
|
||||||
}
|
|
||||||
case STREAM_CTRL_GET_NUM_CHAPTERS:
|
case STREAM_CTRL_GET_NUM_CHAPTERS:
|
||||||
{
|
{
|
||||||
int start_track = get_track_by_sector(p, p->start_sector);
|
int start_track = get_track_by_sector(p, p->start_sector);
|
||||||
|
|||||||
@@ -67,6 +67,13 @@ enum mp_csp_prim {
|
|||||||
MP_CSP_PRIM_COUNT
|
MP_CSP_PRIM_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum mp_csp_trc {
|
||||||
|
MP_CSP_TRC_NONE,
|
||||||
|
MP_CSP_TRC_BT_2020_APPROX,
|
||||||
|
MP_CSP_TRC_BT_2020_EXACT,
|
||||||
|
MP_CSP_TRC_SRGB
|
||||||
|
};
|
||||||
|
|
||||||
// Any enum mp_csp_prim value is a valid index (except MP_CSP_PRIM_COUNT)
|
// Any enum mp_csp_prim value is a valid index (except MP_CSP_PRIM_COUNT)
|
||||||
extern const char *const mp_csp_prim_names[MP_CSP_PRIM_COUNT];
|
extern const char *const mp_csp_prim_names[MP_CSP_PRIM_COUNT];
|
||||||
|
|
||||||
|
|||||||
+15
-10
@@ -353,6 +353,8 @@ static void init_avctx(struct dec_video *vd, const char *decoder,
|
|||||||
ctx->hwdec_fmt = 0;
|
ctx->hwdec_fmt = 0;
|
||||||
ctx->avctx = avcodec_alloc_context3(lavc_codec);
|
ctx->avctx = avcodec_alloc_context3(lavc_codec);
|
||||||
AVCodecContext *avctx = ctx->avctx;
|
AVCodecContext *avctx = ctx->avctx;
|
||||||
|
if (!ctx->avctx)
|
||||||
|
goto error;
|
||||||
avctx->bit_rate = 0;
|
avctx->bit_rate = 0;
|
||||||
avctx->opaque = vd;
|
avctx->opaque = vd;
|
||||||
avctx->codec_type = AVMEDIA_TYPE_VIDEO;
|
avctx->codec_type = AVMEDIA_TYPE_VIDEO;
|
||||||
@@ -360,15 +362,15 @@ static void init_avctx(struct dec_video *vd, const char *decoder,
|
|||||||
|
|
||||||
avctx->refcounted_frames = 1;
|
avctx->refcounted_frames = 1;
|
||||||
ctx->pic = av_frame_alloc();
|
ctx->pic = av_frame_alloc();
|
||||||
|
if (!ctx->pic)
|
||||||
|
goto error;
|
||||||
|
|
||||||
if (ctx->hwdec) {
|
if (ctx->hwdec) {
|
||||||
avctx->thread_count = 1;
|
avctx->thread_count = 1;
|
||||||
avctx->get_format = get_format_hwdec;
|
avctx->get_format = get_format_hwdec;
|
||||||
avctx->get_buffer2 = get_buffer2_hwdec;
|
avctx->get_buffer2 = get_buffer2_hwdec;
|
||||||
if (ctx->hwdec->init(ctx) < 0) {
|
if (ctx->hwdec->init(ctx) < 0)
|
||||||
uninit_avctx(vd);
|
goto error;
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
mp_set_avcodec_threads(avctx, lavc_param->threads);
|
mp_set_avcodec_threads(avctx, lavc_param->threads);
|
||||||
}
|
}
|
||||||
@@ -418,11 +420,14 @@ static void init_avctx(struct dec_video *vd, const char *decoder,
|
|||||||
mp_copy_lav_codec_headers(avctx, sh->lav_headers);
|
mp_copy_lav_codec_headers(avctx, sh->lav_headers);
|
||||||
|
|
||||||
/* open it */
|
/* open it */
|
||||||
if (avcodec_open2(avctx, lavc_codec, NULL) < 0) {
|
if (avcodec_open2(avctx, lavc_codec, NULL) < 0)
|
||||||
MP_ERR(vd, "Could not open codec.\n");
|
goto error;
|
||||||
uninit_avctx(vd);
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
error:
|
||||||
|
MP_ERR(vd, "Could not open codec.\n");
|
||||||
|
uninit_avctx(vd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void uninit_avctx(struct dec_video *vd)
|
static void uninit_avctx(struct dec_video *vd)
|
||||||
@@ -430,7 +435,7 @@ static void uninit_avctx(struct dec_video *vd)
|
|||||||
vd_ffmpeg_ctx *ctx = vd->priv;
|
vd_ffmpeg_ctx *ctx = vd->priv;
|
||||||
AVCodecContext *avctx = ctx->avctx;
|
AVCodecContext *avctx = ctx->avctx;
|
||||||
|
|
||||||
if (avctx)
|
if (avctx && avctx->codec)
|
||||||
avcodec_flush_buffers(avctx);
|
avcodec_flush_buffers(avctx);
|
||||||
|
|
||||||
if (ctx->hwdec && ctx->hwdec->uninit)
|
if (ctx->hwdec && ctx->hwdec->uninit)
|
||||||
|
|||||||
@@ -734,6 +734,8 @@ struct AVFrame *mp_image_to_av_frame_and_unref(struct mp_image *img)
|
|||||||
void *ptr = new_ref->planes[n];
|
void *ptr = new_ref->planes[n];
|
||||||
size_t size = new_ref->stride[n] * new_ref->h;
|
size_t size = new_ref->stride[n] * new_ref->h;
|
||||||
frame->buf[n] = av_buffer_create(ptr, size, free_img, dummy_ref, flags);
|
frame->buf[n] = av_buffer_create(ptr, size, free_img, dummy_ref, flags);
|
||||||
|
if (!frame->buf[n])
|
||||||
|
abort();
|
||||||
}
|
}
|
||||||
talloc_free(new_ref);
|
talloc_free(new_ref);
|
||||||
return frame;
|
return frame;
|
||||||
|
|||||||
@@ -144,6 +144,22 @@ static void disable_power_management(struct vo *vo)
|
|||||||
&s->power_mgmt_assertion);
|
&s->power_mgmt_assertion);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char macosx_icon[] =
|
||||||
|
#include "osdep/macosx_icon.inc"
|
||||||
|
;
|
||||||
|
|
||||||
|
static void set_application_icon(NSApplication *app)
|
||||||
|
{
|
||||||
|
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||||
|
NSData *icon_data = [NSData dataWithBytesNoCopy:(void *)macosx_icon
|
||||||
|
length:sizeof(macosx_icon)
|
||||||
|
freeWhenDone:NO];
|
||||||
|
NSImage *icon = [[NSImage alloc] initWithData:icon_data];
|
||||||
|
[app setApplicationIconImage:icon];
|
||||||
|
[icon release];
|
||||||
|
[pool release];
|
||||||
|
}
|
||||||
|
|
||||||
int vo_cocoa_init(struct vo *vo)
|
int vo_cocoa_init(struct vo *vo)
|
||||||
{
|
{
|
||||||
struct vo_cocoa_state *s = talloc_zero(vo, struct vo_cocoa_state);
|
struct vo_cocoa_state *s = talloc_zero(vo, struct vo_cocoa_state);
|
||||||
@@ -195,7 +211,10 @@ void vo_cocoa_uninit(struct vo *vo)
|
|||||||
[s->gl_ctx release];
|
[s->gl_ctx release];
|
||||||
[s->view removeFromSuperview];
|
[s->view removeFromSuperview];
|
||||||
[s->view release];
|
[s->view release];
|
||||||
if (s->window) [s->window release];
|
if (s->window) {
|
||||||
|
[s->window release];
|
||||||
|
[NSApp setActivationPolicy:NSApplicationActivationPolicyAccessory];
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -453,6 +472,9 @@ int vo_cocoa_config_window(struct vo *vo, uint32_t flags, void *gl_ctx)
|
|||||||
// reconfiguration code.
|
// reconfiguration code.
|
||||||
s->pending_events |= VO_EVENT_RESIZE;
|
s->pending_events |= VO_EVENT_RESIZE;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
|
||||||
|
set_application_icon(NSApp);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -731,7 +753,9 @@ void *vo_cocoa_cgl_pixel_format(struct vo *vo)
|
|||||||
@synthesize vout = _video_output;
|
@synthesize vout = _video_output;
|
||||||
|
|
||||||
- (void)performAsyncResize:(NSSize)size {
|
- (void)performAsyncResize:(NSSize)size {
|
||||||
vo_cocoa_resize_redraw(self.vout, size.width, size.height);
|
struct vo_cocoa_state *s = self.vout->cocoa;
|
||||||
|
if (!s->waiting_frame)
|
||||||
|
vo_cocoa_resize_redraw(self.vout, size.width, size.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)keyboardEnabled {
|
- (BOOL)keyboardEnabled {
|
||||||
|
|||||||
@@ -91,7 +91,8 @@ void mp_compute_weights(struct filter_kernel *filter, double f, float *out_w)
|
|||||||
double sum = 0;
|
double sum = 0;
|
||||||
for (int n = 0; n < filter->size; n++) {
|
for (int n = 0; n < filter->size; n++) {
|
||||||
double x = f - (n - filter->size / 2 + 1);
|
double x = f - (n - filter->size / 2 + 1);
|
||||||
double w = filter->weight(filter, fabs(x) / filter->inv_scale);
|
double c = fabs(x) / filter->inv_scale;
|
||||||
|
double w = c <= filter->radius ? filter->weight(filter, c) : 0;
|
||||||
out_w[n] = w;
|
out_w[n] = w;
|
||||||
sum += w;
|
sum += w;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -141,6 +141,11 @@ static bool is_software_gl(GL *gl)
|
|||||||
strcmp(renderer, "Mesa X11") == 0;
|
strcmp(renderer, "Mesa X11") == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void GLAPIENTRY dummy_glBindFramebuffer(GLenum target, GLuint framebuffer)
|
||||||
|
{
|
||||||
|
assert(framebuffer == 0);
|
||||||
|
}
|
||||||
|
|
||||||
#define FN_OFFS(name) offsetof(GL, name)
|
#define FN_OFFS(name) offsetof(GL, name)
|
||||||
|
|
||||||
#define DEF_FN(name) {FN_OFFS(name), {"gl" # name}}
|
#define DEF_FN(name) {FN_OFFS(name), {"gl" # name}}
|
||||||
@@ -618,6 +623,10 @@ void mpgl_load_functions(GL *gl, void *(*getProcAddress)(const GLubyte *),
|
|||||||
|
|
||||||
mp_verbose(log, "Detected OpenGL features:");
|
mp_verbose(log, "Detected OpenGL features:");
|
||||||
list_features(gl->mpgl_caps, log, MSGL_V, false);
|
list_features(gl->mpgl_caps, log, MSGL_V, false);
|
||||||
|
|
||||||
|
// Provided for simpler handling if no framebuffer support is available.
|
||||||
|
if (!gl->BindFramebuffer)
|
||||||
|
gl->BindFramebuffer = &dummy_glBindFramebuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+26
-7
@@ -901,10 +901,25 @@ static void compile_shaders(struct gl_video *p)
|
|||||||
bool use_conv_gamma = p->conv_gamma != 1.0;
|
bool use_conv_gamma = p->conv_gamma != 1.0;
|
||||||
bool use_const_luma = p->image_params.colorspace == MP_CSP_BT_2020_C;
|
bool use_const_luma = p->image_params.colorspace == MP_CSP_BT_2020_C;
|
||||||
|
|
||||||
|
enum mp_csp_trc gamma_fun = MP_CSP_TRC_NONE;
|
||||||
|
|
||||||
// Linear light scaling is only enabled when either color correction
|
// Linear light scaling is only enabled when either color correction
|
||||||
// option (3dlut or srgb) is enabled, otherwise scaling is done in the
|
// option (3dlut or srgb) is enabled, otherwise scaling is done in the
|
||||||
// source space. We also need to linearize for constant luminance systems.
|
// source space. We also need to linearize for constant luminance systems.
|
||||||
bool convert_to_linear_gamma = !p->is_linear_rgb && use_cms || use_const_luma;
|
if ((!p->is_linear_rgb && use_cms) || use_const_luma) {
|
||||||
|
// We just use the color level range to distinguish between PC
|
||||||
|
// content like images, which are most likely sRGB, and TV content
|
||||||
|
// like movies, which are most likely BT.2020
|
||||||
|
if (p->image_params.colorlevels == MP_CSP_LEVELS_PC && !p->hwdec_active) {
|
||||||
|
// FIXME: I don't know if hwdec sets the color levels to PC or not,
|
||||||
|
// but let's avoid the bug just in case.
|
||||||
|
gamma_fun = MP_CSP_TRC_SRGB;
|
||||||
|
} else if (p->opts.approx_gamma) {
|
||||||
|
gamma_fun = MP_CSP_TRC_BT_2020_APPROX;
|
||||||
|
} else {
|
||||||
|
gamma_fun = MP_CSP_TRC_BT_2020_EXACT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Figure out the right color spaces we need to convert, if any
|
// Figure out the right color spaces we need to convert, if any
|
||||||
enum mp_csp_prim prim_src = p->image_params.primaries, prim_dest;
|
enum mp_csp_prim prim_src = p->image_params.primaries, prim_dest;
|
||||||
@@ -943,9 +958,11 @@ static void compile_shaders(struct gl_video *p)
|
|||||||
|
|
||||||
char *header_osd = talloc_strdup(tmp, header);
|
char *header_osd = talloc_strdup(tmp, header);
|
||||||
shader_def_opt(&header_osd, "USE_OSD_LINEAR_CONV_APPROX",
|
shader_def_opt(&header_osd, "USE_OSD_LINEAR_CONV_APPROX",
|
||||||
use_cms && p->opts.approx_gamma);
|
use_cms && gamma_fun == MP_CSP_TRC_BT_2020_APPROX);
|
||||||
shader_def_opt(&header_osd, "USE_OSD_LINEAR_CONV_BT2020",
|
shader_def_opt(&header_osd, "USE_OSD_LINEAR_CONV_BT2020",
|
||||||
use_cms && !p->opts.approx_gamma);
|
use_cms && gamma_fun == MP_CSP_TRC_BT_2020_EXACT);
|
||||||
|
shader_def_opt(&header_osd, "USE_OSD_LINEAR_CONV_SRGB",
|
||||||
|
use_cms && gamma_fun == MP_CSP_TRC_SRGB);
|
||||||
shader_def_opt(&header_osd, "USE_OSD_CMS_MATRIX", use_cms_matrix);
|
shader_def_opt(&header_osd, "USE_OSD_CMS_MATRIX", use_cms_matrix);
|
||||||
shader_def_opt(&header_osd, "USE_OSD_3DLUT", p->use_lut_3d);
|
shader_def_opt(&header_osd, "USE_OSD_3DLUT", p->use_lut_3d);
|
||||||
// 3DLUT overrides SRGB
|
// 3DLUT overrides SRGB
|
||||||
@@ -980,9 +997,11 @@ static void compile_shaders(struct gl_video *p)
|
|||||||
shader_def_opt(&header_conv, "USE_CONV_GAMMA", use_conv_gamma);
|
shader_def_opt(&header_conv, "USE_CONV_GAMMA", use_conv_gamma);
|
||||||
shader_def_opt(&header_conv, "USE_CONST_LUMA", use_const_luma);
|
shader_def_opt(&header_conv, "USE_CONST_LUMA", use_const_luma);
|
||||||
shader_def_opt(&header_conv, "USE_LINEAR_LIGHT_APPROX",
|
shader_def_opt(&header_conv, "USE_LINEAR_LIGHT_APPROX",
|
||||||
convert_to_linear_gamma && p->opts.approx_gamma);
|
gamma_fun == MP_CSP_TRC_BT_2020_APPROX);
|
||||||
shader_def_opt(&header_conv, "USE_LINEAR_LIGHT_BT2020",
|
shader_def_opt(&header_conv, "USE_LINEAR_LIGHT_BT2020",
|
||||||
convert_to_linear_gamma && !p->opts.approx_gamma);
|
gamma_fun == MP_CSP_TRC_BT_2020_EXACT);
|
||||||
|
shader_def_opt(&header_conv, "USE_LINEAR_LIGHT_SRGB",
|
||||||
|
gamma_fun == MP_CSP_TRC_SRGB);
|
||||||
if (p->opts.alpha_mode > 0 && p->has_alpha && p->plane_count > 3)
|
if (p->opts.alpha_mode > 0 && p->has_alpha && p->plane_count > 3)
|
||||||
shader_def(&header_conv, "USE_ALPHA_PLANE", "3");
|
shader_def(&header_conv, "USE_ALPHA_PLANE", "3");
|
||||||
if (p->opts.alpha_mode == 2 && p->has_alpha)
|
if (p->opts.alpha_mode == 2 && p->has_alpha)
|
||||||
@@ -1018,7 +1037,7 @@ static void compile_shaders(struct gl_video *p)
|
|||||||
|
|
||||||
// Don't sample from input video textures before converting the input to
|
// Don't sample from input video textures before converting the input to
|
||||||
// linear light.
|
// linear light.
|
||||||
if (use_input_gamma || use_conv_gamma)
|
if (use_input_gamma || use_conv_gamma || gamma_fun != MP_CSP_TRC_NONE)
|
||||||
use_indirect = true;
|
use_indirect = true;
|
||||||
|
|
||||||
// It doesn't make sense to scale the chroma with cscale in the 1. scale
|
// It doesn't make sense to scale the chroma with cscale in the 1. scale
|
||||||
@@ -1409,7 +1428,7 @@ static void init_video(struct gl_video *p, const struct mp_image_params *params)
|
|||||||
p->image_dh = params->d_h;
|
p->image_dh = params->d_h;
|
||||||
p->image_params = *params;
|
p->image_params = *params;
|
||||||
|
|
||||||
if (p->is_rgb && (p->opts.srgb || p->use_lut_3d)) {
|
if (p->is_rgb && (p->opts.srgb || p->use_lut_3d) && !p->hwdec_active) {
|
||||||
// If we're opening an RGB source like a png file or similar,
|
// If we're opening an RGB source like a png file or similar,
|
||||||
// we just sample it using GL_SRGB which treats it as an sRGB source
|
// we just sample it using GL_SRGB which treats it as an sRGB source
|
||||||
// and pretend it's linear as far as CMS is concerned
|
// and pretend it's linear as far as CMS is concerned
|
||||||
|
|||||||
@@ -43,6 +43,12 @@
|
|||||||
|
|
||||||
// Earlier GLSL doesn't support mix() with bvec
|
// Earlier GLSL doesn't support mix() with bvec
|
||||||
#if __VERSION__ >= 130
|
#if __VERSION__ >= 130
|
||||||
|
vec3 srgb_expand(vec3 v)
|
||||||
|
{
|
||||||
|
return mix(v / 12.92, pow((v + vec3(0.055))/1.055, vec3(2.4)),
|
||||||
|
lessThanEqual(vec3(0.04045), v));
|
||||||
|
}
|
||||||
|
|
||||||
vec3 srgb_compand(vec3 v)
|
vec3 srgb_compand(vec3 v)
|
||||||
{
|
{
|
||||||
return mix(v * 12.92, 1.055 * pow(v, vec3(1.0/2.4)) - 0.055,
|
return mix(v * 12.92, 1.055 * pow(v, vec3(1.0/2.4)) - 0.055,
|
||||||
@@ -98,6 +104,9 @@ void main() {
|
|||||||
#ifdef USE_OSD_LINEAR_CONV_BT2020
|
#ifdef USE_OSD_LINEAR_CONV_BT2020
|
||||||
color.rgb = bt2020_expand(color.rgb);
|
color.rgb = bt2020_expand(color.rgb);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef USE_OSD_LINEAR_CONV_SRGB
|
||||||
|
color.rgb = srgb_expand(color.rgb);
|
||||||
|
#endif
|
||||||
#ifdef USE_OSD_CMS_MATRIX
|
#ifdef USE_OSD_CMS_MATRIX
|
||||||
// Convert to the right target gamut first (to BT.709 for sRGB,
|
// Convert to the right target gamut first (to BT.709 for sRGB,
|
||||||
// and to BT.2020 for 3DLUT). Normal clamping here as perceptually
|
// and to BT.2020 for 3DLUT). Normal clamping here as perceptually
|
||||||
@@ -419,8 +428,9 @@ void main() {
|
|||||||
lessThanEqual(color.br, vec2(0))) + color.gg;
|
lessThanEqual(color.br, vec2(0))) + color.gg;
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_COLORMATRIX
|
#ifdef USE_COLORMATRIX
|
||||||
// Clamp down here to avoid clipping CbCr details before CONST_LUMA
|
// CONST_LUMA involves numbers outside the [0,1] range so we make sure
|
||||||
// has a chance to convert them.
|
// to clip here, after the (possible) USE_CONST_LUMA calculations are done,
|
||||||
|
// instead of immediately after the colormatrix conversion.
|
||||||
color = clamp(color, 0, 1);
|
color = clamp(color, 0, 1);
|
||||||
#endif
|
#endif
|
||||||
// If we are scaling in linear light (SRGB or 3DLUT option enabled), we
|
// If we are scaling in linear light (SRGB or 3DLUT option enabled), we
|
||||||
@@ -438,6 +448,13 @@ void main() {
|
|||||||
// ... and actual BT.2020 (two-part function)
|
// ... and actual BT.2020 (two-part function)
|
||||||
color = bt2020_expand(color);
|
color = bt2020_expand(color);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef USE_LINEAR_LIGHT_SRGB
|
||||||
|
// This is not needed for most sRGB content since we can use GL_SRGB to
|
||||||
|
// directly sample RGB texture in linear light, but for things which are
|
||||||
|
// also sRGB but in a different format (such as JPEG's YUV), we need
|
||||||
|
// to convert to linear light manually.
|
||||||
|
color = srgb_expand(color);
|
||||||
|
#endif
|
||||||
#ifdef USE_CONST_LUMA
|
#ifdef USE_CONST_LUMA
|
||||||
// Calculate the green channel from the expanded RYcB
|
// Calculate the green channel from the expanded RYcB
|
||||||
// The BT.2020 specification says Yc = 0.2627*R + 0.6780*G + 0.0593*B
|
// The BT.2020 specification says Yc = 0.2627*R + 0.6780*G + 0.0593*B
|
||||||
|
|||||||
+13
-5
@@ -152,7 +152,7 @@ static int find_depth_from_visuals(struct vo *vo, Visual ** visual_return)
|
|||||||
return bestvisual_depth;
|
return bestvisual_depth;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void getMyXImage(struct priv *p, int foo)
|
static bool getMyXImage(struct priv *p, int foo)
|
||||||
{
|
{
|
||||||
struct vo *vo = p->vo;
|
struct vo *vo = p->vo;
|
||||||
#if HAVE_SHM && HAVE_XEXT
|
#if HAVE_SHM && HAVE_XEXT
|
||||||
@@ -212,6 +212,10 @@ shmemerror:
|
|||||||
p->myximage[foo] =
|
p->myximage[foo] =
|
||||||
XCreateImage(vo->x11->display, p->vinfo.visual, p->depth, ZPixmap,
|
XCreateImage(vo->x11->display, p->vinfo.visual, p->depth, ZPixmap,
|
||||||
0, NULL, p->image_width, p->image_height, 8, 0);
|
0, NULL, p->image_width, p->image_height, 8, 0);
|
||||||
|
if (!p->myximage[foo]) {
|
||||||
|
MP_WARN(vo, "could not allocate image");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
size_t sz = p->myximage[foo]->bytes_per_line * p->image_height + 32;
|
size_t sz = p->myximage[foo]->bytes_per_line * p->image_height + 32;
|
||||||
p->ImageDataOrig[foo] = calloc(1, sz);
|
p->ImageDataOrig[foo] = calloc(1, sz);
|
||||||
p->myximage[foo]->data = p->ImageDataOrig[foo] + 16
|
p->myximage[foo]->data = p->ImageDataOrig[foo] + 16
|
||||||
@@ -220,6 +224,7 @@ shmemerror:
|
|||||||
#if HAVE_SHM && HAVE_XEXT
|
#if HAVE_SHM && HAVE_XEXT
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void freeMyXImage(struct priv *p, int foo)
|
static void freeMyXImage(struct priv *p, int foo)
|
||||||
@@ -342,8 +347,10 @@ static bool resize(struct vo *vo)
|
|||||||
p->image_height = p->dst_h;
|
p->image_height = p->dst_h;
|
||||||
|
|
||||||
p->num_buffers = 2;
|
p->num_buffers = 2;
|
||||||
for (int i = 0; i < p->num_buffers; i++)
|
for (int i = 0; i < p->num_buffers; i++) {
|
||||||
getMyXImage(p, i);
|
if (!getMyXImage(p, i))
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
const struct fmt2Xfmtentry_s *fmte = fmt2Xfmt;
|
const struct fmt2Xfmtentry_s *fmte = fmt2Xfmt;
|
||||||
while (fmte->mpfmt) {
|
while (fmte->mpfmt) {
|
||||||
@@ -615,7 +622,8 @@ static int control(struct vo *vo, uint32_t request, void *data)
|
|||||||
case VOCTRL_GET_PANSCAN:
|
case VOCTRL_GET_PANSCAN:
|
||||||
return VO_TRUE;
|
return VO_TRUE;
|
||||||
case VOCTRL_SET_PANSCAN:
|
case VOCTRL_SET_PANSCAN:
|
||||||
resize(vo);
|
if (vo->config_ok)
|
||||||
|
resize(vo);
|
||||||
return VO_TRUE;
|
return VO_TRUE;
|
||||||
case VOCTRL_REDRAW_FRAME:
|
case VOCTRL_REDRAW_FRAME:
|
||||||
draw_image(vo, p->original_image);
|
draw_image(vo, p->original_image);
|
||||||
@@ -629,7 +637,7 @@ static int control(struct vo *vo, uint32_t request, void *data)
|
|||||||
|
|
||||||
int events = 0;
|
int events = 0;
|
||||||
int r = vo_x11_control(vo, &events, request, data);
|
int r = vo_x11_control(vo, &events, request, data);
|
||||||
if (events & (VO_EVENT_EXPOSE | VO_EVENT_RESIZE))
|
if (vo->config_ok && (events & (VO_EVENT_EXPOSE | VO_EVENT_RESIZE)))
|
||||||
resize(vo);
|
resize(vo);
|
||||||
vo_event(vo, events);
|
vo_event(vo, events);
|
||||||
return r;
|
return r;
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <windowsx.h>
|
#include <windowsx.h>
|
||||||
|
#include <initguid.h>
|
||||||
#include <ole2.h>
|
#include <ole2.h>
|
||||||
|
|
||||||
#include "options/options.h"
|
#include "options/options.h"
|
||||||
@@ -904,8 +905,8 @@ static int reinit_window_state(struct vo_w32_state *w32)
|
|||||||
// Center the final window
|
// Center the final window
|
||||||
n_w = r.right - r.left;
|
n_w = r.right - r.left;
|
||||||
n_h = r.bottom - r.top;
|
n_h = r.bottom - r.top;
|
||||||
r.left = screen_w / 2 - n_w / 2;
|
r.left = w32->screenrc.x0 + screen_w / 2 - n_w / 2;
|
||||||
r.top = screen_h / 2 - n_h / 2;
|
r.top = w32->screenrc.y0 + screen_h / 2 - n_h / 2;
|
||||||
r.right = r.left + n_w;
|
r.right = r.left + n_w;
|
||||||
r.bottom = r.top + n_h;
|
r.bottom = r.top + n_h;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,14 +31,14 @@ def __add_generic_flags__(ctx):
|
|||||||
def __add_gcc_flags__(ctx):
|
def __add_gcc_flags__(ctx):
|
||||||
ctx.env.CFLAGS += ["-Wall", "-Wundef", "-Wmissing-prototypes", "-Wshadow",
|
ctx.env.CFLAGS += ["-Wall", "-Wundef", "-Wmissing-prototypes", "-Wshadow",
|
||||||
"-Wno-switch", "-Wno-parentheses", "-Wpointer-arith",
|
"-Wno-switch", "-Wno-parentheses", "-Wpointer-arith",
|
||||||
"-Wredundant-decls", "-Wno-pointer-sign",
|
"-Wredundant-decls", "-Wno-pointer-sign"]
|
||||||
"-Werror=implicit-function-declaration",
|
__test_and_add_flags__(ctx, ["-Werror=implicit-function-declaration",
|
||||||
"-Wno-error=deprecated-declarations",
|
"-Wno-error=deprecated-declarations",
|
||||||
"-Wno-error=unused-function" ]
|
"-Wno-error=unused-function",
|
||||||
__test_and_add_flags__(ctx, ["-Wempty-body"])
|
"-Wempty-body",
|
||||||
__test_and_add_flags__(ctx, ["-Wdisabled-optimization"])
|
"-Wdisabled-optimization",
|
||||||
__test_and_add_flags__(ctx, ["-Wstrict-prototypes"])
|
"-Wstrict-prototypes",
|
||||||
__test_and_add_flags__(ctx, ["-Wno-format-zero-length"])
|
"-Wno-format-zero-length"])
|
||||||
|
|
||||||
def __add_clang_flags__(ctx):
|
def __add_clang_flags__(ctx):
|
||||||
ctx.env.CFLAGS += ["-Wno-logical-op-parentheses", "-fcolor-diagnostics",
|
ctx.env.CFLAGS += ["-Wno-logical-op-parentheses", "-fcolor-diagnostics",
|
||||||
|
|||||||
@@ -539,7 +539,7 @@ audio_output_features = [
|
|||||||
}, {
|
}, {
|
||||||
'name': '--alsa',
|
'name': '--alsa',
|
||||||
'desc': 'ALSA audio output',
|
'desc': 'ALSA audio output',
|
||||||
'func': check_pkg_config('alsa'),
|
'func': check_pkg_config('alsa >= 1.0.18'),
|
||||||
}, {
|
}, {
|
||||||
'name': '--coreaudio',
|
'name': '--coreaudio',
|
||||||
'desc': 'CoreAudio audio output',
|
'desc': 'CoreAudio audio output',
|
||||||
@@ -825,14 +825,14 @@ def options(opt):
|
|||||||
|
|
||||||
opt.parse_features('build and install options', build_options)
|
opt.parse_features('build and install options', build_options)
|
||||||
optional_features = main_dependencies + libav_dependencies
|
optional_features = main_dependencies + libav_dependencies
|
||||||
opt.parse_features('optional feaures', optional_features)
|
opt.parse_features('optional features', optional_features)
|
||||||
opt.parse_features('audio outputs', audio_output_features)
|
opt.parse_features('audio outputs', audio_output_features)
|
||||||
opt.parse_features('video outputs', video_output_features)
|
opt.parse_features('video outputs', video_output_features)
|
||||||
opt.parse_features('hwaccels', hwaccel_features)
|
opt.parse_features('hwaccels', hwaccel_features)
|
||||||
opt.parse_features('tv features', radio_and_tv_features)
|
opt.parse_features('tv features', radio_and_tv_features)
|
||||||
opt.parse_features('standalone app', standalone_features)
|
opt.parse_features('standalone app', standalone_features)
|
||||||
|
|
||||||
group = opt.get_option_group("optional feaures")
|
group = opt.get_option_group("optional features")
|
||||||
group.add_option('--lua',
|
group.add_option('--lua',
|
||||||
type = 'string',
|
type = 'string',
|
||||||
dest = 'LUA_VER',
|
dest = 'LUA_VER',
|
||||||
|
|||||||
Reference in new issue
Block a user