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
|
||||
(most likely affects nobody)
|
||||
1.9 - add enum mpv_end_file_reason for mpv_event_end_file.reason
|
||||
|
||||
@@ -113,8 +113,8 @@ Miscellaneous
|
||||
* Matroska edition switching at runtime.
|
||||
* Support for playing URLs of popular streaming sites directly.
|
||||
(e.g. ``mpv https://www.youtube.com/watch?v=...``).
|
||||
Requires a recent version of ``youtube-dl`` to be installed, and
|
||||
``ytdl=yes`` in the mpv config file.
|
||||
Requires a recent version of ``youtube-dl`` to be installed. Can be
|
||||
disabled with ``ytdl=no`` in the mpv config file.
|
||||
* Support for precise scrolling which scales the parameter of commands. If the
|
||||
input doesn't support precise scrolling the scale factor stays 1.
|
||||
* 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
|
||||
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``
|
||||
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
|
||||
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
|
||||
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.
|
||||
|
||||
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.)
|
||||
|
||||
``--ytdl-format=<best|worst|mp4|webm|...>``
|
||||
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
|
||||
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
|
||||
-----
|
||||
@@ -577,7 +577,7 @@ 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
|
||||
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.)
|
||||
|
||||
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.
|
||||
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))
|
||||
s->chmaps[s->num_chmaps++] = *map;
|
||||
if (!mp_chmap_is_valid(map))
|
||||
return;
|
||||
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.
|
||||
|
||||
+5
-1
@@ -26,8 +26,12 @@ struct mp_chmap_sel {
|
||||
// should be considered opaque
|
||||
bool allow_any, allow_waveext;
|
||||
bool speakers[MP_SPEAKER_ID_COUNT];
|
||||
struct mp_chmap chmaps[20];
|
||||
struct mp_chmap *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);
|
||||
|
||||
@@ -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. */
|
||||
s->ba_l[k] = in[0] + in[4] + in[2];
|
||||
s->ba_r[k] = in[4] + in[1] + in[3];
|
||||
// TODO: should this use lf/cf/rf etc. instead?
|
||||
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)
|
||||
|
||||
+2
-2
@@ -36,7 +36,7 @@ struct mixer {
|
||||
struct ao *ao;
|
||||
struct af_stream *af;
|
||||
// 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 emulate_mute; // if true, emulate mute with volume=0
|
||||
// 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)
|
||||
{
|
||||
// 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)
|
||||
|
||||
+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)
|
||||
{
|
||||
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);
|
||||
if (!maps)
|
||||
@@ -461,17 +461,22 @@ static int init(struct ao *ao)
|
||||
if (strcmp(device, "default") != 0)
|
||||
device = talloc_asprintf(ao, "plug:%s", device);
|
||||
}
|
||||
const char *old_dev = device;
|
||||
if (ao->device)
|
||||
device = ao->device;
|
||||
if (p->cfg_device && p->cfg_device[0])
|
||||
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 ALSA version: %s\n", snd_asoundlib_version());
|
||||
|
||||
err = try_open_device(ao, device, p->cfg_block ? 0 : SND_PCM_NONBLOCK);
|
||||
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 "
|
||||
"failed, trying to open in block-mode.\n");
|
||||
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");
|
||||
}
|
||||
|
||||
if (ao->channels.num == 1)
|
||||
ao->channels.speaker[0] = MP_SP(FC);
|
||||
|
||||
free(alsa_chmap);
|
||||
}
|
||||
#endif
|
||||
|
||||
+27
-13
@@ -185,7 +185,7 @@ static bool init_chmap(struct ao *ao)
|
||||
&layouts, &n_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++) {
|
||||
struct mp_chmap chmap = {0};
|
||||
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;
|
||||
|
||||
MP_VERBOSE(ao, "layout: tag: <%d>, bitmap: <%d>, "
|
||||
"descriptions <%d>\n",
|
||||
layout->mChannelLayoutTag,
|
||||
layout->mChannelBitmap,
|
||||
layout->mNumberChannelDescriptions);
|
||||
MP_VERBOSE(ao, "layout: tag: <%u>, bitmap: <%u>, "
|
||||
"descriptions <%u>\n",
|
||||
(unsigned) layout->mChannelLayoutTag,
|
||||
(unsigned) layout->mChannelBitmap,
|
||||
(unsigned) layout->mNumberChannelDescriptions);
|
||||
|
||||
for (int i = 0; i < layout->mNumberChannelDescriptions; i++) {
|
||||
AudioChannelDescription d = descs[i];
|
||||
MP_VERBOSE(ao, " - description %d: label <%d, %d>, flags: <%u>, "
|
||||
"coords: <%f, %f, %f>\n", i,
|
||||
d.mChannelLabel,
|
||||
ca_label_to_mp_speaker_id(d.mChannelLabel),
|
||||
d.mChannelFlags,
|
||||
MP_VERBOSE(ao, " - description %d: label <%u, %u>, "
|
||||
" flags: <%u>, coords: <%f, %f, %f>\n", i,
|
||||
(unsigned) d.mChannelLabel,
|
||||
(unsigned) ca_label_to_mp_speaker_id(d.mChannelLabel),
|
||||
(unsigned) d.mChannelFlags,
|
||||
d.mCoordinates[0],
|
||||
d.mCoordinates[1],
|
||||
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
|
||||
// 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++) {
|
||||
AudioChannelLabel label = layout->mChannelDescriptions[n].mChannelLabel;
|
||||
uint8_t speaker = ca_label_to_mp_speaker_id(label);
|
||||
if (label == kAudioChannelLabel_Unknown)
|
||||
continue;
|
||||
if (speaker < 0) {
|
||||
MP_VERBOSE(ao, "channel label=%d unusable to build channel "
|
||||
"bitmap, skipping layout\n", label);
|
||||
MP_VERBOSE(ao, "channel label=%u unusable to build channel "
|
||||
"bitmap, skipping layout\n", (unsigned) label);
|
||||
goto coreaudio_error;
|
||||
} else {
|
||||
chmap->speaker[n] = speaker;
|
||||
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);
|
||||
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;
|
||||
|
||||
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(
|
||||
CFStringGetLength(string), CA_CFSTR_ENCODING) + 1;
|
||||
|
||||
*data = talloc_size(NULL, size);
|
||||
*data = talloc_zero_size(NULL, size);
|
||||
CFStringGetCString(string, *data, size, CA_CFSTR_ENCODING);
|
||||
CFRelease(string);
|
||||
coreaudio_error:
|
||||
|
||||
@@ -286,6 +286,8 @@ static int lavf_check_file(demuxer_t *demuxer, enum demux_check check)
|
||||
.buf_size = 0,
|
||||
.buf = av_mallocz(PROBE_BUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE),
|
||||
};
|
||||
if (!avpd.buf)
|
||||
return -1;
|
||||
|
||||
bool final_probe = false;
|
||||
do {
|
||||
@@ -679,6 +681,8 @@ static int demux_open_lavf(demuxer_t *demuxer, enum demux_check check)
|
||||
return -1;
|
||||
|
||||
avfc = avformat_alloc_context();
|
||||
if (!avfc)
|
||||
return -1;
|
||||
|
||||
if (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) {
|
||||
mkv_d->tc_scale = info.timecode_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) {
|
||||
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->block_align = 1024;
|
||||
|
||||
if (!strcmp(track->codec_id, MKV_A_AAC) && track->private_data) {
|
||||
if (!extradata_len) {
|
||||
if (!strcmp(track->codec_id, MKV_A_AAC)) {
|
||||
if (track->private_data && !extradata_len) {
|
||||
extradata = track->private_data;
|
||||
extradata_len = track->private_size;
|
||||
}
|
||||
} else {
|
||||
/* Recreate the 'private data' */
|
||||
/* which faad2 uses in its initialization */
|
||||
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;
|
||||
else if (!strncmp(&track->codec_id[12], "LC", 2))
|
||||
else if (!strncmp(tail, "LC", 2))
|
||||
profile = 1;
|
||||
else if (!strncmp(&track->codec_id[12], "SSR", 3))
|
||||
else if (!strncmp(tail, "SSR", 3))
|
||||
profile = 2;
|
||||
else
|
||||
profile = 3;
|
||||
|
||||
@@ -86,7 +86,7 @@ static int parse_m3u(struct pl_parser *p)
|
||||
return -1;
|
||||
if (p->probing)
|
||||
return 0;
|
||||
while (!pl_eof(p)) {
|
||||
while (line.len || !pl_eof(p)) {
|
||||
if (line.len > 0 && !bstr_startswith0(line, "#"))
|
||||
pl_add(p, line);
|
||||
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};
|
||||
bstr burl = bstr0(p->s->url);
|
||||
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)));
|
||||
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)
|
||||
break;
|
||||
if (best_bind && (s->flags & MP_INPUT_ON_TOP))
|
||||
break;
|
||||
}
|
||||
|
||||
return best_bind;
|
||||
@@ -1019,14 +1021,15 @@ void mp_input_define_section(struct input_ctx *ictx, char *name, char *location,
|
||||
if (!name || !name[0])
|
||||
return; // parse_config() changes semantics with restrict_section==empty
|
||||
input_lock(ictx);
|
||||
// Delete:
|
||||
struct cmd_bind_section *bs = get_bind_section(ictx, bstr0(name));
|
||||
remove_binds(bs, builtin);
|
||||
if (contents) {
|
||||
// Redefine:
|
||||
parse_config(ictx, builtin, bstr0(contents), location, name);
|
||||
} else {
|
||||
// Disable:
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -45,6 +45,16 @@ static void read_pipe_thread(struct mp_input_src *src, void *param)
|
||||
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);
|
||||
if (!waio) {
|
||||
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 = {
|
||||
.name = "Audio channels or channel map",
|
||||
.size = sizeof(struct mp_chmap *),
|
||||
.size = sizeof(struct mp_chmap),
|
||||
.parse = parse_chmap,
|
||||
.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 (desc.replaced_name)
|
||||
mp_warn(log, "Driver '%s' has been replaced with '%s'!\n",
|
||||
desc.name, desc.replaced_name);
|
||||
desc.replaced_name, desc.name);
|
||||
} else {
|
||||
if (!list->allow_unknown_entries) {
|
||||
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,
|
||||
#if HAVE_LUA
|
||||
.lua_load_osc = 1,
|
||||
.lua_load_ytdl = 0,
|
||||
.lua_load_ytdl = 1,
|
||||
.lua_ytdl_format = NULL,
|
||||
#endif
|
||||
.auto_load_scripts = 1,
|
||||
|
||||
@@ -233,6 +233,8 @@ Application *mpv_shared_app(void)
|
||||
options:NSAnchoredSearch
|
||||
range:NSMakeRange(0, [MPV_PROTOCOL length])];
|
||||
|
||||
url = [url stringByRemovingPercentEncoding];
|
||||
|
||||
self.files = @[url];
|
||||
|
||||
if (self.willStopOnOpenEvent) {
|
||||
@@ -329,7 +331,10 @@ void init_cocoa_application(void)
|
||||
NSApp = mpv_shared_app();
|
||||
[NSApp setDelegate:NSApp];
|
||||
[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(^{
|
||||
// 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)
|
||||
{
|
||||
Application *app = mpv_shared_app();
|
||||
@@ -475,7 +465,6 @@ void macosx_finder_args_preinit(int *argc, char ***argv)
|
||||
*argc = cocoa_argc;
|
||||
*argv = cocoa_argv;
|
||||
} else {
|
||||
set_application_icon(app);
|
||||
for (int i = 0; i < *argc; i++ ) {
|
||||
NSString *arg = [NSString stringWithUTF8String:(*argv)[i]];
|
||||
[app.argumentsList addObject:arg];
|
||||
|
||||
@@ -440,8 +440,10 @@ void cocoa_set_input_context(struct input_ctx *input_context)
|
||||
size_t num_files = [files count];
|
||||
char **files_utf8 = talloc_array(NULL, char*, num_files);
|
||||
[files enumerateObjectsUsingBlock:^(id obj, NSUInteger i, BOOL *_){
|
||||
char *filename = (char *)[obj UTF8String];
|
||||
size_t bytes = [obj lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
|
||||
NSURL *url = [NSURL URLWithString:obj];
|
||||
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);
|
||||
}];
|
||||
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
|
||||
*read = CreateNamedPipeW(buf, PIPE_ACCESS_INBOUND |
|
||||
FILE_FLAG_FIRST_PIPE_INSTANCE | FILE_FLAG_OVERLAPPED,
|
||||
PIPE_TYPE_BYTE | PIPE_WAIT | PIPE_REJECT_REMOTE_CLIENTS,
|
||||
1, 0, 4096, 0, NULL);
|
||||
if (!*read)
|
||||
PIPE_TYPE_BYTE | PIPE_WAIT, 1, 0, 4096, 0, NULL);
|
||||
if (*read == INVALID_HANDLE_VALUE)
|
||||
goto error;
|
||||
|
||||
// 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.
|
||||
if (mpctx->audio_status >= STATUS_DRAINING && status == AD_OK) {
|
||||
mpctx->audio_status = STATUS_SYNCING;
|
||||
mpctx->sleeptime = 0;
|
||||
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);
|
||||
if (!sub)
|
||||
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_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 *target = NULL;
|
||||
char space[MAX_CLIENT_NAME];
|
||||
if (name) {
|
||||
if (sep) {
|
||||
snprintf(space, sizeof(space), "%.*s", (int)(sep - name), name);
|
||||
target = space;
|
||||
name = sep + 1;
|
||||
|
||||
@@ -243,6 +243,8 @@ static const char *const backup_properties[] = {
|
||||
"options/ass-use-margins",
|
||||
"options/ass-vsfilter-aspect-compat",
|
||||
"options/ass-style-override",
|
||||
"options/ab-loop-a",
|
||||
"options/ab-loop-b",
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
+2
-3
@@ -125,9 +125,8 @@ void mp_nav_init(struct MPContext *mpctx)
|
||||
|
||||
MP_VERBOSE(mpctx->nav_state, "enabling\n");
|
||||
|
||||
mp_input_enable_section(mpctx->input, "discnav", 0);
|
||||
mp_input_set_section_mouse_area(mpctx->input, "discnav-menu",
|
||||
INT_MIN, INT_MIN, INT_MAX, INT_MAX);
|
||||
mp_input_enable_section(mpctx->input, "discnav",
|
||||
MP_INPUT_ALLOW_VO_DRAGGING | MP_INPUT_ALLOW_HIDE_CURSOR);
|
||||
|
||||
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)
|
||||
pts = 0;
|
||||
|
||||
int new = mpctx->num_timeline_parts - 1;
|
||||
for (int i = 0; i < mpctx->num_timeline_parts; i++) {
|
||||
struct timeline_part *p = mpctx->timeline + i;
|
||||
if (pts < (p + 1)->start) {
|
||||
*need_reset = timeline_set_part(mpctx, i, false);
|
||||
return pts - p->start + p->source_start;
|
||||
if (pts < mpctx->timeline[i + 1].start) {
|
||||
new = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
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)
|
||||
@@ -964,6 +967,7 @@ static void play_current_file(struct MPContext *mpctx)
|
||||
|
||||
if (opts->stream_dump && opts->stream_dump[0]) {
|
||||
stream_dump(mpctx);
|
||||
mpctx->error_playing = 1;
|
||||
goto terminate_playback;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -1043,7 +1043,7 @@ static int script_input_enable_section(lua_State *L)
|
||||
} else if (bstr_equals0(val, "exclusive")) {
|
||||
flags |= MP_INPUT_EXCLUSIVE;
|
||||
} else {
|
||||
luaL_error(L, "invalid flag: '%.*s'", BSTR_P(val));
|
||||
luaL_error(L, "invalid flag");
|
||||
}
|
||||
}
|
||||
mp_input_enable_section(mpctx->input, section, flags);
|
||||
|
||||
+16
-3
@@ -1853,9 +1853,13 @@ function tick()
|
||||
end
|
||||
end
|
||||
|
||||
function do_enable_keybindings()
|
||||
mp.enable_key_bindings("showhide", "allow-vo-dragging|allow-hide-cursor")
|
||||
end
|
||||
|
||||
function enable_osc(enable)
|
||||
if enable then
|
||||
mp.enable_key_bindings("showhide")
|
||||
do_enable_keybindings()
|
||||
show_osc()
|
||||
else
|
||||
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("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
|
||||
mp.set_key_bindings({
|
||||
{"mouse_move", function(e) process_event("mouse_move", nil) end},
|
||||
{"mouse_leave", mouse_leave},
|
||||
}, "showhide")
|
||||
mp.enable_key_bindings("showhide", "allow-vo-dragging|allow-hide-cursor")
|
||||
}, "showhide", "force")
|
||||
do_enable_keybindings()
|
||||
|
||||
--mouse input bindings
|
||||
mp.set_key_bindings({
|
||||
|
||||
+42
-15
@@ -3,7 +3,7 @@ local msg = require 'mp.msg'
|
||||
|
||||
local ytdl = {
|
||||
path = "youtube-dl",
|
||||
minver = "2014.11.09",
|
||||
minver = "2014.11.26",
|
||||
vercheck = nil,
|
||||
}
|
||||
|
||||
@@ -97,30 +97,57 @@ mp.add_hook("on_load", 10, function ()
|
||||
elseif not (json["_type"] == nil) and (json["_type"] == "playlist") then
|
||||
-- a playlist
|
||||
|
||||
local playlist = "#EXTM3U\n"
|
||||
for i, entry in pairs(json.entries) do
|
||||
local site = entry.url
|
||||
-- some funky guessing to detect multi-arc videos
|
||||
if not (json.entries[1]["webpage_url"] == nil)
|
||||
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
|
||||
-- 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"]
|
||||
|
||||
local playlist = "edl://"
|
||||
for i, entry in pairs(json.entries) do
|
||||
|
||||
playlist = playlist .. entry.url .. ";"
|
||||
end
|
||||
|
||||
playlist = playlist .. "ytdl://" .. site .. "\n"
|
||||
end
|
||||
msg.debug("EDL: " .. playlist)
|
||||
|
||||
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
|
||||
local streamurl = ""
|
||||
|
||||
-- DASH?
|
||||
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
|
||||
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;
|
||||
demuxer_amount = timeline_set_from_time(mpctx, seek.amount,
|
||||
&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) {
|
||||
reinit_video_chain(mpctx);
|
||||
reinit_audio_chain(mpctx);
|
||||
@@ -961,10 +951,11 @@ void run_playloop(struct MPContext *mpctx)
|
||||
mpctx->audio_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){
|
||||
.type = MPSEEK_ABSOLUTE,
|
||||
.amount = mpctx->timeline[mpctx->timeline_part+1].start
|
||||
.amount = mpctx->timeline[new_part].start
|
||||
}, true);
|
||||
} else
|
||||
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) {}
|
||||
void uninit_sub_renderer(struct MPContext *mpctx) {}
|
||||
|
||||
void mp_ass_configure(ASS_Renderer *priv, struct MPOpts *opts,
|
||||
struct mp_osd_res *dim) {}
|
||||
void mp_ass_configure_fonts(struct ass_renderer *a, struct MPOpts *b,
|
||||
struct mpv_global *c, struct mp_log *d) {}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -227,10 +227,9 @@ static void update_subtitle(struct MPContext *mpctx, int order)
|
||||
struct track *track = mpctx->current_track[order][STREAM_SUB];
|
||||
struct dec_sub *dec_sub = mpctx->d_sub[order];
|
||||
|
||||
if (!track)
|
||||
if (!track || !dec_sub)
|
||||
return;
|
||||
|
||||
assert(dec_sub);
|
||||
int obj = order ? OSDTYPE_SUB2 : OSDTYPE_SUB;
|
||||
|
||||
if (mpctx->d_video) {
|
||||
|
||||
@@ -243,11 +243,6 @@ static int control(stream_t *stream, int cmd, void *arg)
|
||||
{
|
||||
cdda_priv *p = stream->priv;
|
||||
switch (cmd) {
|
||||
case STREAM_CTRL_GET_NUM_TITLES:
|
||||
{
|
||||
*(unsigned int *)arg = p->cd->tracks;
|
||||
return STREAM_OK;
|
||||
}
|
||||
case STREAM_CTRL_GET_NUM_CHAPTERS:
|
||||
{
|
||||
int start_track = get_track_by_sector(p, p->start_sector);
|
||||
|
||||
@@ -67,6 +67,13 @@ enum mp_csp_prim {
|
||||
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)
|
||||
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->avctx = avcodec_alloc_context3(lavc_codec);
|
||||
AVCodecContext *avctx = ctx->avctx;
|
||||
if (!ctx->avctx)
|
||||
goto error;
|
||||
avctx->bit_rate = 0;
|
||||
avctx->opaque = vd;
|
||||
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;
|
||||
ctx->pic = av_frame_alloc();
|
||||
if (!ctx->pic)
|
||||
goto error;
|
||||
|
||||
if (ctx->hwdec) {
|
||||
avctx->thread_count = 1;
|
||||
avctx->get_format = get_format_hwdec;
|
||||
avctx->get_buffer2 = get_buffer2_hwdec;
|
||||
if (ctx->hwdec->init(ctx) < 0) {
|
||||
uninit_avctx(vd);
|
||||
return;
|
||||
}
|
||||
if (ctx->hwdec->init(ctx) < 0)
|
||||
goto error;
|
||||
} else {
|
||||
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);
|
||||
|
||||
/* open it */
|
||||
if (avcodec_open2(avctx, lavc_codec, NULL) < 0) {
|
||||
MP_ERR(vd, "Could not open codec.\n");
|
||||
uninit_avctx(vd);
|
||||
return;
|
||||
}
|
||||
if (avcodec_open2(avctx, lavc_codec, NULL) < 0)
|
||||
goto error;
|
||||
|
||||
return;
|
||||
|
||||
error:
|
||||
MP_ERR(vd, "Could not open codec.\n");
|
||||
uninit_avctx(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;
|
||||
AVCodecContext *avctx = ctx->avctx;
|
||||
|
||||
if (avctx)
|
||||
if (avctx && avctx->codec)
|
||||
avcodec_flush_buffers(avctx);
|
||||
|
||||
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];
|
||||
size_t size = new_ref->stride[n] * new_ref->h;
|
||||
frame->buf[n] = av_buffer_create(ptr, size, free_img, dummy_ref, flags);
|
||||
if (!frame->buf[n])
|
||||
abort();
|
||||
}
|
||||
talloc_free(new_ref);
|
||||
return frame;
|
||||
|
||||
@@ -144,6 +144,22 @@ static void disable_power_management(struct vo *vo)
|
||||
&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)
|
||||
{
|
||||
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->view removeFromSuperview];
|
||||
[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.
|
||||
s->pending_events |= VO_EVENT_RESIZE;
|
||||
});
|
||||
|
||||
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
|
||||
set_application_icon(NSApp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -731,7 +753,9 @@ void *vo_cocoa_cgl_pixel_format(struct vo *vo)
|
||||
@synthesize vout = _video_output;
|
||||
|
||||
- (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 {
|
||||
|
||||
@@ -91,7 +91,8 @@ void mp_compute_weights(struct filter_kernel *filter, double f, float *out_w)
|
||||
double sum = 0;
|
||||
for (int n = 0; n < filter->size; n++) {
|
||||
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;
|
||||
sum += w;
|
||||
}
|
||||
|
||||
@@ -141,6 +141,11 @@ static bool is_software_gl(GL *gl)
|
||||
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 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:");
|
||||
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_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
|
||||
// option (3dlut or srgb) is enabled, otherwise scaling is done in the
|
||||
// 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
|
||||
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);
|
||||
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",
|
||||
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_3DLUT", p->use_lut_3d);
|
||||
// 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_CONST_LUMA", use_const_luma);
|
||||
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",
|
||||
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)
|
||||
shader_def(&header_conv, "USE_ALPHA_PLANE", "3");
|
||||
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
|
||||
// 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;
|
||||
|
||||
// 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_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,
|
||||
// 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
|
||||
|
||||
@@ -43,6 +43,12 @@
|
||||
|
||||
// Earlier GLSL doesn't support mix() with bvec
|
||||
#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)
|
||||
{
|
||||
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
|
||||
color.rgb = bt2020_expand(color.rgb);
|
||||
#endif
|
||||
#ifdef USE_OSD_LINEAR_CONV_SRGB
|
||||
color.rgb = srgb_expand(color.rgb);
|
||||
#endif
|
||||
#ifdef USE_OSD_CMS_MATRIX
|
||||
// Convert to the right target gamut first (to BT.709 for sRGB,
|
||||
// and to BT.2020 for 3DLUT). Normal clamping here as perceptually
|
||||
@@ -419,8 +428,9 @@ void main() {
|
||||
lessThanEqual(color.br, vec2(0))) + color.gg;
|
||||
#endif
|
||||
#ifdef USE_COLORMATRIX
|
||||
// Clamp down here to avoid clipping CbCr details before CONST_LUMA
|
||||
// has a chance to convert them.
|
||||
// CONST_LUMA involves numbers outside the [0,1] range so we make sure
|
||||
// to clip here, after the (possible) USE_CONST_LUMA calculations are done,
|
||||
// instead of immediately after the colormatrix conversion.
|
||||
color = clamp(color, 0, 1);
|
||||
#endif
|
||||
// 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)
|
||||
color = bt2020_expand(color);
|
||||
#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
|
||||
// Calculate the green channel from the expanded RYcB
|
||||
// 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;
|
||||
}
|
||||
|
||||
static void getMyXImage(struct priv *p, int foo)
|
||||
static bool getMyXImage(struct priv *p, int foo)
|
||||
{
|
||||
struct vo *vo = p->vo;
|
||||
#if HAVE_SHM && HAVE_XEXT
|
||||
@@ -212,6 +212,10 @@ shmemerror:
|
||||
p->myximage[foo] =
|
||||
XCreateImage(vo->x11->display, p->vinfo.visual, p->depth, ZPixmap,
|
||||
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;
|
||||
p->ImageDataOrig[foo] = calloc(1, sz);
|
||||
p->myximage[foo]->data = p->ImageDataOrig[foo] + 16
|
||||
@@ -220,6 +224,7 @@ shmemerror:
|
||||
#if HAVE_SHM && HAVE_XEXT
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
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->num_buffers = 2;
|
||||
for (int i = 0; i < p->num_buffers; i++)
|
||||
getMyXImage(p, i);
|
||||
for (int i = 0; i < p->num_buffers; i++) {
|
||||
if (!getMyXImage(p, i))
|
||||
return -1;
|
||||
}
|
||||
|
||||
const struct fmt2Xfmtentry_s *fmte = fmt2Xfmt;
|
||||
while (fmte->mpfmt) {
|
||||
@@ -615,7 +622,8 @@ static int control(struct vo *vo, uint32_t request, void *data)
|
||||
case VOCTRL_GET_PANSCAN:
|
||||
return VO_TRUE;
|
||||
case VOCTRL_SET_PANSCAN:
|
||||
resize(vo);
|
||||
if (vo->config_ok)
|
||||
resize(vo);
|
||||
return VO_TRUE;
|
||||
case VOCTRL_REDRAW_FRAME:
|
||||
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 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);
|
||||
vo_event(vo, events);
|
||||
return r;
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <assert.h>
|
||||
#include <windows.h>
|
||||
#include <windowsx.h>
|
||||
#include <initguid.h>
|
||||
#include <ole2.h>
|
||||
|
||||
#include "options/options.h"
|
||||
@@ -904,8 +905,8 @@ static int reinit_window_state(struct vo_w32_state *w32)
|
||||
// Center the final window
|
||||
n_w = r.right - r.left;
|
||||
n_h = r.bottom - r.top;
|
||||
r.left = screen_w / 2 - n_w / 2;
|
||||
r.top = screen_h / 2 - n_h / 2;
|
||||
r.left = w32->screenrc.x0 + screen_w / 2 - n_w / 2;
|
||||
r.top = w32->screenrc.y0 + screen_h / 2 - n_h / 2;
|
||||
r.right = r.left + n_w;
|
||||
r.bottom = r.top + n_h;
|
||||
}
|
||||
|
||||
@@ -31,14 +31,14 @@ def __add_generic_flags__(ctx):
|
||||
def __add_gcc_flags__(ctx):
|
||||
ctx.env.CFLAGS += ["-Wall", "-Wundef", "-Wmissing-prototypes", "-Wshadow",
|
||||
"-Wno-switch", "-Wno-parentheses", "-Wpointer-arith",
|
||||
"-Wredundant-decls", "-Wno-pointer-sign",
|
||||
"-Werror=implicit-function-declaration",
|
||||
"-Wno-error=deprecated-declarations",
|
||||
"-Wno-error=unused-function" ]
|
||||
__test_and_add_flags__(ctx, ["-Wempty-body"])
|
||||
__test_and_add_flags__(ctx, ["-Wdisabled-optimization"])
|
||||
__test_and_add_flags__(ctx, ["-Wstrict-prototypes"])
|
||||
__test_and_add_flags__(ctx, ["-Wno-format-zero-length"])
|
||||
"-Wredundant-decls", "-Wno-pointer-sign"]
|
||||
__test_and_add_flags__(ctx, ["-Werror=implicit-function-declaration",
|
||||
"-Wno-error=deprecated-declarations",
|
||||
"-Wno-error=unused-function",
|
||||
"-Wempty-body",
|
||||
"-Wdisabled-optimization",
|
||||
"-Wstrict-prototypes",
|
||||
"-Wno-format-zero-length"])
|
||||
|
||||
def __add_clang_flags__(ctx):
|
||||
ctx.env.CFLAGS += ["-Wno-logical-op-parentheses", "-fcolor-diagnostics",
|
||||
|
||||
@@ -539,7 +539,7 @@ audio_output_features = [
|
||||
}, {
|
||||
'name': '--alsa',
|
||||
'desc': 'ALSA audio output',
|
||||
'func': check_pkg_config('alsa'),
|
||||
'func': check_pkg_config('alsa >= 1.0.18'),
|
||||
}, {
|
||||
'name': '--coreaudio',
|
||||
'desc': 'CoreAudio audio output',
|
||||
@@ -825,14 +825,14 @@ def options(opt):
|
||||
|
||||
opt.parse_features('build and install options', build_options)
|
||||
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('video outputs', video_output_features)
|
||||
opt.parse_features('hwaccels', hwaccel_features)
|
||||
opt.parse_features('tv features', radio_and_tv_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',
|
||||
type = 'string',
|
||||
dest = 'LUA_VER',
|
||||
|
||||
Reference in new issue
Block a user