Compare commits

...
73 Commits
Author SHA1 Message Date
Diogo Franco (Kovensky) 4db470e08a Release 0.8.3 2015-03-17 10:50:21 +09:00
Diogo Franco (Kovensky) cf3819ece9 Update RELEASE_NOTES 2015-03-17 10:49:57 +09:00
wm4 575b631d67 video: don't drop anamorphic scaling if it's too minor
This played e.g. a 1264x722 file as 1264x720. There was some code which
dropped the aspect ratio if the video (in original resolution) wasn't
scaled by more than 4 pixels. Commit 5f3c3f8c introduced this (although
I'm not really sure what the code replaced by it did).

Just remove this "feature".

(cherry picked from commit d96fad04be)
2015-03-17 10:49:56 +09:00
wm4 4c1b45b5ab command: don't drop audio buffers when switching filters
This partially reverts commit ae7228c6. I guess the old behavior was
slightly more popular.

Fixes #1693 (probably).

(cherry picked from commit 699fc0e51e)
2015-03-17 10:49:56 +09:00
wm4 8932d90ec6 demux_lavf: fix rejection of image2 demuxer
This was probably broken for some time in git master, and the later
commit which happened to fix it was not picked.

Fixes #1689.
2015-03-16 11:58:24 +01:00
Diogo Franco (Kovensky) fc4da23c64 Update RELEASE_NOTES 2015-03-16 17:26:05 +09:00
Martin Herkt 017c2808e4 bootstrap: add waf mirror
(cherry picked from commit 958dbca3ef)
2015-03-16 17:08:16 +09:00
wm4 c5a8fc793c audio: fix off by one error in channel map selection code
The consequence was that some AOs (like ao_jack) could not output 8
channels.

Fixes #1688.

(cherry picked from commit c4f4b09014)
2015-03-16 17:08:01 +09:00
Martin Herkt 3dcd3476c6 man: fix PDF build
(cherry picked from commit add4c9ee03)
2015-03-16 17:07:47 +09:00
Stefano Pigozzi ad119460d7 cocoa: signal VO_EVENT_WIN_STATE on fps change
Fixes #1686

(cherry picked from commit efe0fb75bc)
2015-03-15 21:33:38 +09:00
James Ross-Gowan e865543be2 w32_common: don't hide cursor when the menu is open
Previously, mpv would hide the cursor when the autohide timer expired,
even if the window menu was open. This made it difficult to use the menu
with the mouse.

When handling VOCTRL_SET_CURSOR_VISIBILITY, instead of determining
whether to call SetCursor by checking if the cursor is in the client
area, call it based on the parameters to the last WM_SETCURSOR message.
When the window enters "menu mode," it gets a WM_SETCURSOR message with
HIWORD(lParam) set to 0 to indicate that the cursor shouldn't be set.

(cherry picked from commit acbac01a73)
2015-03-15 20:09:00 +09:00
wm4 e84a00651a vo: update FPS only on state changes
I'm not comfortable with VOCTRL_GET_DISPLAY_FPS being called every
frame.

This requires the VO to set VO_EVENT_WIN_STATE if the FPS could have
changed. At least the X11 backend does this.

(cherry picked from commit 209f8225ed)
2015-03-15 20:08:00 +09:00
wm4 b17ccd1c43 demux_mkv: make matroska.pl script output deterministic
Work around the randomized Perl hashtables by sorting the elements.

Fixes #1673.

(cherry picked from commit 7e9c441d41)
2015-03-15 20:07:14 +09:00
wm4 62d922e4f0 command: allow changing some VO options even if VO wasn't created yet
Instead of refusing to set properties like "fullscreen" if no VO was
created, always allow it. So if no VO is created, setting the property
merely changes the options (and will be applied once the VO is created).
This is consistent with similar behavior changes to some other
properties.

Improves the behavior reported in #1676.

Also, we shouldn't check the config_ok variable - the VO should do this.

(cherry picked from commit e9841630ad)
2015-03-15 20:07:06 +09:00
wm4 eaa5393c4a player: fix crash when taking screenshots in idle mode
mpctx->filename is obviously not set if no file is playing.

When this code was written, it probably couldn't happen, because the
normal screenshot path fails much earlier in idle mode. But you can
still take screenshots in "full window" mode, and recently the
screenshot code was changed to use the "full window" mode if the normal
path does not work.

(cherry picked from commit ca474d22c9)
2015-03-15 20:06:50 +09:00
wm4 50b74bf407 x11: ignore mouse enter/leave events due to pointer grab
If you click on a window that doesn't have a focus, a LeaveNotify
followed by a EnterNotify event can be generated. The former will have
mode set to NotifyGrab, the latter to NotifyUngrab. This will make the
player think the mouse left the window, even though this is not the
case. Ignore these and only react to those with mode set to
NotifyNormal.

Probably fixes #1672, and some other strange issues on some WMs.

(cherry picked from commit 30860f7b10)
2015-03-15 20:06:28 +09:00
Stefano Pigozzi 414cdc9da6 build: disable tests by default
Having them autodetect is a bad idea since it would link cmocka in the main
mpv binary (which users don't want).

(cherry picked from commit ca0b33e9b1)
2015-03-11 12:49:40 +09:00
wm4 1c4bdfaf9c vo: hide opengl-cb in --vo=help
Avoids stupid questions.

(cherry picked from commit c7790b4526)
2015-03-11 12:49:40 +09:00
wm4 76809e5ef7 vo_opengl_cb: clear last video frame on uninit()
mpv_opengl_cb_render() is supposed to clear the screen with the
background color if there's no video... I think.

It didn't do this, because although uninit() requested gl_video_config()
to be called, this didn't happen, because this function checks whether
the VO is set - and it's unsert after uninit() releases the lock.

Also call the user wakeup callback in this situation, so the user
actually redraws immediately.

(cherry picked from commit eff265c140)
2015-03-11 12:49:40 +09:00
wm4 efc72daea9 client API: clarify mpv_opengl_cb_render() viewport parameter
Basically, the idea behind the vp parameter is broken - I guess the
intention was to enable rendering to a specific subrectangle of the
target framebuffer, but there's nothing to specify the actual target
rectangle (the VO will still clear e.g. the borders between video and
framebuffer borders).

We're not going to keep the current semantics either with the upcoming
rework of vo_opengl, so declare this for broken. Maybe we can introduce
a function later which does this properly.

(cherry picked from commit 90adf2904e)
2015-03-11 12:49:40 +09:00
wm4 b414d9a9a7 stream: use relaxed atomic loads for checking playback aborts
Seems appropriate, and will probably avoid performance surprises with
scary architectures which don't have trivial implementations for atomic
loads. (Consider that demux_mkv calls this very often now, and
libavformat demuxers and streams did this for a while now.)

(cherry picked from commit b9307b7175)
2015-03-11 12:49:40 +09:00
wm4 2b737f8bfc demux_mkv: never warn when trying to resync on EOF
If this happens, the file is actually broken, but the assumption is
simply that the file was truncated, and printing a warning would be
strange.

(cherry picked from commit 112d9aeda1)
2015-03-11 12:49:40 +09:00
wm4 9e99a0c8b9 demux_mkv: check for playback aborts
Check async abort notification. libavformat already do something
equivalent.

Before this commit, the demuxer could enter resync mode (and print silly
warning messages) when the stream stopped returning data because of an
abort.

(cherry picked from commit 39fa05d374)
2015-03-11 12:49:40 +09:00
James Ross-Gowan e22ecb1585 w32_common: remove redundant is_maximized function
This already exists as IsMaximized in the Windows API.

(cherry picked from commit 5f0eda7b94)
2015-03-11 12:49:40 +09:00
wm4 6358e9be5c x11: fix VOCTRL_GET_WIN_STATE
Do not rely on the pointed-to argument to be initialized; VOCTRLs are
supposed to completely overwrite them on success (or not to touch them
on failure).

The currently only caller of VOCTRL_GET_WIN_STATE initializes the value
before calling this, so this is merely about correctness and didn't lead
to any actual bugs.

(cherry picked from commit b7f242dfcf)
2015-03-11 12:49:40 +09:00
Kevin Mitchell d57a48c64e stream/smb: mark as network stream for --cache=auto
This causes the cache to be enabled with --cache=auto. It was not done
previously because the small cache size 320k actually led to worse
performance. However, with the current default cache size of 25000kb,
caching notably improves performance.

(cherry picked from commit 3efbc1a9a3)
2015-03-11 12:49:40 +09:00
Niklas Haas 22691f2e6a manpage: document swapinterval default
(cherry picked from commit 6983430c35)
2015-03-11 12:49:39 +09:00
Filip Milivojevic 623a259eee vf_vavpp: fix deinterlacing
Add filter parameters to VAAPI deinterlacing filter to actually process
bottom fields instead of deinterlacing top field twice.

Signed-off-by: wm4 <wm4@nowhere>
(cherry picked from commit 5c3a6ca96e)
2015-03-11 12:49:39 +09:00
wm4 fa81e835bc DOCS: minor update to coding style
(cherry picked from commit 6f507d14c1)
2015-03-11 12:49:39 +09:00
Stefano Pigozzi 46cc45223c cocoa: fix autohide in fullscreen
(cherry picked from commit 8ec9bce2d3)
2015-03-11 12:49:39 +09:00
Stefano Pigozzi 0e160123fd cocoa: fix mouse hiding with launchpad and dock folders
Some UI elements in OS X – like Launchpad and Dock folders – are implemented
using borderless windows in background demonized applications.
When we use these elements, mpv doesn't stop to be the active application, but
the mpv window leaves keyWindow state while we use the OS controls.

This commit just keeps track of window state to update the cursor visibility
accordingly.

Fixes #513

(cherry picked from commit ce239f1577)
2015-03-11 12:49:39 +09:00
torque 710979e0e8 cocoa: clamp mouse position to window.
Prevents out-of-window coordinates being reported for mouse coordinates.
Previously they could be out-of-window coordinates on init or on resize.

(cherry picked from commit 39537f6474)
2015-03-11 12:49:39 +09:00
torque 18d3c2ab85 cocoa: update mouse coordinates when window is initialized.
Make MpvEventsView -signalMousePosition a public method so it can be
called without a compiler warning. Previously, the mouse position would
be reported as (0,0) until the cursor was moved.

(cherry picked from commit bce753060e)
2015-03-11 12:49:39 +09:00
Martin Herkt f84ca3a516 vo_opengl/x11: fix automatic ICC profile loading
mpv would attempt to load ICC profiles several times during VO init
even if no window is displayed. This potentially causes it to load
a profile for a different screen than it is going to be displayed
on, thereby invalidating the profile cache and rebuilding the LUT
every single time.
It would not unload a previously loaded profile when the video
window is moved to a display without an installed profile.

Fix these issues and tweak the log messages a little.

(cherry picked from commit 1bab7f69ae)
2015-03-11 12:49:39 +09:00
Stefano Pigozzi 324a40d2e1 cocoa: remove possible use after free
(cherry picked from commit 5cddd4ccca)
2015-03-11 12:49:33 +09:00
Stefano Pigozzi 83e98d3ada cocoa: fix some crashes caused by async uninit
Always keep around our private state and destroy it when we are really done in
the async uninit callback.

Fixes #1657

(cherry picked from commit c66b51dab0)
2015-03-11 12:39:56 +09:00
wm4 a424fe1296 demux_mkv: actually skip elements out of reach
This is missing from the previous commit. Not that harmful, but also
slightly un-nice since even a failed seek will reset the cache.

(cherry picked from commit f0ab1f2048)
2015-03-11 12:34:26 +09:00
wm4 e09803ae6b demux_mkv: fix issues with unseekable streams
A user reported a webm stream that couldn't be played. The issue was
that this stream 1. was on an unseekable HTTP connection, and 2. had a
SeekHead element (wtf?). The code reading the SeekHead marked the
element as unreadable too early: although you can't seek in the stream,
reading the header elements after the SeekHead read them anyway. Marking
them as unreadable only after the normal header reading fixes this.

(The way the failing stream was setup was pretty retarded: inserting
these SeekHead elements makes absolutely no sense for a stream that
cannot be seeked.)

Fixes #1656.

(cherry picked from commit 12dcc5eaac)
2015-03-11 12:34:02 +09:00
torque 80669188d6 Lua: add unpack shim for Lua 5.2/5.3 compatibility.
The global unpack function got moved to table.unpack in Lua 5.2, and
it's only available as the global if 5.2 is built with compatibility
enabled (the default). Lua 5.3 does not build with 5.1 compatibility by
default.

Fixes #1648.

(cherry picked from commit 4ff29f33b0)
2015-03-11 12:33:53 +09:00
wm4 1a3a3aba63 player: allow changing playback speed in early audio init stages
If the audio decoder was created, but no audio filter chain created yet
(still trying to decode a first audio frame), setting the "speed"
property could explode. It tried to recreate the filter chain, even
though no format was set yet.

This is inconvenient and should not happen.

(cherry picked from commit 720d4a5a1a)
2015-03-11 12:33:22 +09:00
wm4 0b141eaa82 DOCS/compile-window.md: add Lua package to MXE instructions
The MSYS2 ones already mention Lua.

(cherry picked from commit 3fe61ada84)
2015-03-11 12:33:00 +09:00
wm4 cac071dc23 build: make vdpau and dxva2 checks nicer
Using check_statement() with an empty statement just to check for the
header is quite a hack. Fix check_headers() (so it takes a "use"
parameter), and use it for the checks instead.

(cherry picked from commit dfa562b5db)
2015-03-11 12:32:51 +09:00
ChrisK2 c77f076ae4 DOCS, options: fix example
(cherry picked from commit e9ff136dd3)
2015-03-11 12:32:03 +09:00
wm4 f4393eaa6c build: check whether hwaccels are enabled in FFmpeg
FFmpeg can be compiled with them disabled, and then it won't provide the
public headers specific to these APIs, causing mpv compilation failure.

(cherry picked from commit baa354c64c)
2015-03-11 12:31:53 +09:00
wm4 bbd6501bd3 vd_lavc: let --hwdec=auto select "vaapi-copy"
Instead of "vaapi", simply by changing the probe order.

"vaapi" uses the GLX GL interop, which has causing us more problems than
it solved.

Unfortunately this leads also to copying if "--hwdec=auto --vo=vaapi" is
used, even though GLX is not involved in this case - but I don't care
enough to make the probe logic cleverer just for this. You can still get
the zero-copy path with --hwdec=vaapi.

(cherry picked from commit 27b5492a82)
2015-03-11 12:31:40 +09:00
wm4 dc29a21b5c vd_lavc: request 1 more threads than CPU cores
This duplicates the logic which FFmpeg's libavcodec uses. The effects
are unknown, though it's somewhat clear that a single thread doesn't
necessarily saturate a single CPU.

(Eventually we should just let FFmpeg auto-init the thread count, but
for now I prefer it this way, so e.g. verbose mode will print the
thread count.)

(cherry picked from commit 9657e5a2ca)
2015-03-11 12:31:16 +09:00
wm4 4d87844508 vo_vaapi: fix video equalizer (second try)
The vaapi equalizer have a custom range, and can have a smaller range
than mpv's normalized video equalizer values. The result is that a vaapi
equalizer value can map to multiple mpv values, so changing a mpv value
by 1 can get "stuck". Fix by remember the mpv value, and returning it if
it still corresponds to the vaapi value.

Really fixes #1647.

(Why am I even bothering with this irredeemable crap?)

(cherry picked from commit fc571e0adb)
2015-03-11 12:30:50 +09:00
wm4 cced4bf4d6 vo_vaapi: round equalizer values
Probably fixes #1647 (if it's correct at all). I couldn't reproduce with
the vdpau libva driver, but a driver can use different ranges.

(cherry picked from commit 4e3f8ccb9d)
2015-03-11 12:30:50 +09:00
wm4 5734cd7063 README: fix typos
(cherry picked from commit 6d4a758295)
2015-03-05 10:48:31 +09:00
wm4 52324a494c ad_spdif: remove per-packet message
It was annoying and didn't ever help with anything.

(cherry picked from commit 55f69605fb)
2015-03-05 10:48:25 +09:00
wm4 7ee8237e66 cache: assume file size from EOF position
If we're caching a stream with unknown size, and we reach EOF, then
consider the EOF position the file size. Typically makes sense when
reading from a pipe or a http connection that did not send a size.

(cherry picked from commit 3cd394995f)
2015-03-05 10:47:36 +09:00
wm4 6fc0b4e24b README: add some better links
Also write something about MPlayer, since this is a frequently asked
question.

(cherry picked from commit 771cb34932)
2015-03-05 10:47:24 +09:00
wm4 3d3b1b8bba win32: fix some more -Wparentheses warnings
Stupid compiler.

For decode_surrogate_pair(), I changed the order of evaluation; it
shouldn't matter, but this order is more readable in my opinion.

(cherry picked from commit 85bf102f54)
2015-03-05 10:47:14 +09:00
Stefano Pigozzi 21a90cc49c cocoa: silence -Wlogical-op-parentheses
(cherry picked from commit 3c3f9a8042)
2015-03-05 10:47:03 +09:00
wm4 83119f05c4 build: fix warnings with --disable-libass
This crap seems to break every other fullmoon.

(cherry picked from commit 0bbf36b796)
2015-03-05 10:46:49 +09:00
wm4 081ddd26b4 stream_cdda: fix parameter passing
All cdda options (except --cdrom-drive) were ignored, because the priv
struct (with the options set) was just replaced. Oops.

(cherry picked from commit 1ba24d2585)
2015-03-04 13:08:25 +09:00
wm4 78349cc188 player: refine rar:// playlist-safety handling
It was possible to make the player play local files by putting rar://
links into remote playlists, and some other potentially unsafe things.

Redo the handling of it. Now the rar-redirector (the thing in
demux_playlist.c) sets disable_safety, which makes the player open any
playlist entries returned. This is fine, because it redirects to the
same file anyway (just with different selection/interpretation of the
contents). On the other hand, rar:// itself is now considered fully
unsafe, which means that it is ignored if found in normal playlists.

(cherry picked from commit a4b6bf8c41)
2015-03-03 16:08:43 +09:00
wm4 931f614257 msg: use relaxed atomics for log level test
This should be sufficient.

If stdatomic.h is not available, we make no difference.

(cherry picked from commit 01b87e509c)
2015-03-03 16:08:24 +09:00
wm4 e682d82527 vf_scale: libswscale is being stupid
This time (there are a lot of times), libswscale randomly ignores
brightness/saturation/contrast settings.

Looking at MPlayer code, it appears the return value of
sws_setColorspaceDetails() signals if changing these settings is
supported at all.

(Nevermind that supporting this feature has almost 0 value, and
obviously eats maintenance time.)

(cherry picked from commit 08199a64d2)
2015-03-03 16:07:04 +09:00
torque 76fd4b4e33 Lua: add mp.get_screen_margins().
When used with mp.get_screen_size(), mp.get_screen_margins() allows a
Lua script to determine what portion of the mpv window actually has the
video in it.

(cherry picked from commit 1bbf1eb3ce)
2015-03-03 16:06:46 +09:00
Oliver Freyermuth 623b0a77e1 stream_dvb: Always define NO_STREAM_ID_FILTER if missing.
It is also used for initialization in channel-list setup.
Should fix compilation on FreeBSD, and is more correct
since it is used unconditionally.
Reverts 6445648 .

(cherry picked from commit 40c9e79068)
2015-03-03 16:05:24 +09:00
Stefano Pigozzi c6c4c3ea9c cocoa: remove the setNextKeyView hack
Just use makeFirstResponder on the mpv events view from client code
if you need the built in keyboard events (this is easier for dealing with view
nesting).

(cherry picked from commit 03a69bac95)
2015-03-03 16:05:24 +09:00
Stefano Pigozzi 8e5a854374 examples/cocoabasic: allow to send stop command
(cherry picked from commit 721e430cd2)
2015-03-03 16:05:24 +09:00
zymos 90a0add131 manpage: fix typo
Signed-off-by: wm4 <wm4@nowhere>
(cherry picked from commit b742384162)
2015-03-03 16:05:24 +09:00
wm4 443fd456a1 vo_opengl: delete 16 bit test texture
Essentially a leak, but not that bad since it's small and allocated only
once.

(cherry picked from commit 73c5c3df53)
2015-03-03 16:02:22 +09:00
wm4 910da3af6a vo_opengl: fix some comments
(cherry picked from commit e7b7a5a476)
2015-03-03 16:02:16 +09:00
wm4 517f15dc49 stream: remove stream filter concept
Unused since the previous commit. (Apparently it was a stupid idea.)

(cherry picked from commit fbf76da913)
2015-03-03 16:02:07 +09:00
wm4 62cf557b5f stream_rar: treat rar files as playlists
Refactors an older hack, which for some reason used a more complicated
way. This generates the playlist representing the contents of the rar
file in demux_playlist.c. The pseudo-demuxer could easily be separate
from the the playlist parsers (and in fact there's almost no shared
code), but I don't think this obscure feature deserves a separate file.

Sample files created with:

    rar a -v20000k -m0 files.rar file1.mkv file1.mkv

(cherry picked from commit 5824eb7107)
2015-03-03 16:02:02 +09:00
wm4 95e1952377 build: improve DVB check
A use of NO_STREAM_ID_FILTER was added to the DVB code recently. While I
have no idea what it's needed for, it makes mpv fail to compile on
FreeBSD 10.1. Add it to the dvb configure check.

(cherry picked from commit 64456488b3)
2015-03-03 16:01:37 +09:00
Niklas Haas 90126b9f88 manpage: update wording on speed
The way I interpreted it, it seemed like this was not default behavior
and could be enabled with --audio-pitch-correction - it should be made
clearer that this is actually *the default behavior*.

(cherry picked from commit 0f99b302f5)
2015-03-03 16:00:38 +09:00
wm4 01223a3e0f player: adjust A/V desync message
Broken drivers are an issue rather often. Maybe this gives the user an
idea that this could be the reason. (We can't dump much more info on a
80x24 terminal.)

(cherry picked from commit a5f3083ae7)
2015-03-03 15:58:57 +09:00
wm4 76b0291bf2 vo_opengl: test FBOs only if they're going to be used
Change test_fbo() so that it checks the FBO lazily, and restructure
check_gl_features() to invoke it only if we know that a FBO will be
needed for a certain enabled feature.

This can avoid strange error messages when using --vo=opengl and the
FBO format does not work. It's also less confusing when reading the
verbose log (users might think that the FBO is actually used, etc.).

(cherry picked from commit 280c826379)
2015-03-03 15:58:43 +09:00
wm4 3fc0c18997 vo_xv: don't attempt to clear window before mapped
This can happen with the "no-colorkey" suboption. Then the code in
xv_draw_colorkey() can be run before vo_x11_config_vo_window(), when
vo_gc is not allocated yet.

Fixes #1629.

(cherry picked from commit a2e0cd7f25)
2015-03-03 15:58:28 +09:00
66 changed files with 508 additions and 350 deletions

No files matched your search

+33 -15
View File
@@ -33,6 +33,7 @@ static inline void check_error(int status)
mpv_handle *mpv;
dispatch_queue_t queue;
NSWindow *w;
NSView *wrapper;
}
@end
@@ -55,11 +56,19 @@ static void wakeup(void *);
[self->w makeMainWindow];
[self->w makeKeyAndOrderFront:nil];
NSRect frame = [[self->w contentView] bounds];
self->wrapper = [[NSView alloc] initWithFrame:frame];
[self->wrapper setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable];
[[self->w contentView] addSubview:self->wrapper];
[self->wrapper release];
NSMenu *m = [[NSMenu alloc] initWithTitle:@"AMainMenu"];
NSMenuItem *item = [m addItemWithTitle:@"Apple" action:nil keyEquivalent:@""];
NSMenu *sm = [[NSMenu alloc] initWithTitle:@"Apple"];
[m setSubmenu:sm forItem:item];
[sm addItemWithTitle: @"Shutdown mpv" action:@selector(shutdown) keyEquivalent:@"s"];
[sm addItemWithTitle: @"mpv_command('stop')" action:@selector(mpv_stop) keyEquivalent:@""];
[sm addItemWithTitle: @"mpv_command('quit')" action:@selector(mpv_quit) keyEquivalent:@""];
[sm addItemWithTitle: @"quit" action:@selector(terminate:) keyEquivalent:@"q"];
[NSApp setMenu:m];
[NSApp activateIgnoringOtherApps:YES];
}
@@ -93,7 +102,7 @@ static void wakeup(void *);
exit(1);
}
int64_t wid = (intptr_t) [self->w contentView];
int64_t wid = (intptr_t) self->wrapper;
check_error(mpv_set_option(mpv, "wid", MPV_FORMAT_INT64, &wid));
// Maybe set some options here, like default key bindings.
@@ -122,24 +131,28 @@ static void wakeup(void *);
- (void) handleEvent:(mpv_event *)event
{
switch (event->event_id) {
case MPV_EVENT_SHUTDOWN:
// Clean up and shut down.
mpv_terminate_destroy(mpv);
case MPV_EVENT_SHUTDOWN: {
mpv_detach_destroy(mpv);
mpv = NULL;
dispatch_async(dispatch_get_main_queue(), ^{
[[NSApplication sharedApplication] terminate:nil];
});
printf("event: shutdown\n");
break;
}
case MPV_EVENT_LOG_MESSAGE: {
struct mpv_event_log_message *msg = (struct mpv_event_log_message *)event->data;
printf("[%s] %s: %s", msg->prefix, msg->level, msg->text);
}
case MPV_EVENT_VIDEO_RECONFIG:
case MPV_EVENT_VIDEO_RECONFIG: {
dispatch_async(dispatch_get_main_queue(), ^{
[self->w selectNextKeyView:nil];
NSArray *subviews = [self->wrapper subviews];
if ([subviews count] > 0) {
// mpv's events view
NSView *eview = [self->wrapper subviews][0];
[self->w makeFirstResponder:eview];
}
});
}
default:
printf("event: %s\n", mpv_event_name(event->event_id));
@@ -166,13 +179,18 @@ static void wakeup(void *context) {
// Ostensibly, mpv's window would be hooked up to this.
- (BOOL) windowShouldClose:(id)sender
{
[self shutdown];
if (self->w)
[self->w release];
return YES;
return NO;
}
- (void) shutdown
- (void) mpv_stop
{
if (mpv) {
const char *args[] = {"stop", NULL};
mpv_command(mpv, args);
}
}
- (void) mpv_quit
{
if (mpv) {
const char *args[] = {"quit", NULL};
+2 -2
View File
@@ -66,9 +66,9 @@ echo "MXE_TARGETS := i686-w64-mingw32.static" >> settings.mk
# echo "MXE_TARGETS := x86_64-w64-mingw32.static" >> settings.mk
# Build required packages. The following provide a minimum required to build
# mpv.
# a reasonable mpv binary (though not an absolute minimum).
make gcc ffmpeg libass jpeg pthreads
make gcc ffmpeg libass jpeg pthreads lua
# Add MXE binaries to $PATH
export PATH=/opt/mxe/usr/bin/:$PATH
+2
View File
@@ -118,6 +118,8 @@ mpv uses C99 with K&R formatting, with some exceptions.
very_long_condition_b)
{
code();
} else {
...
}
```
- Remove any trailing whitespace.
+4 -3
View File
@@ -565,9 +565,10 @@ Available filters are:
Scale tempo in sync with speed (default).
pitch
Reverses effect of filter. Scales pitch without altering tempo.
Add ``[ multiply speed 0.9438743126816935`` and
``] multiply speed 1.059463094352953`` to your ``input.conf``
to step by musical semi-tones.
Add this to your ``input.conf`` to step by musical semi-tones::
[ multiply speed 0.9438743126816935
] multiply speed 1.059463094352953
.. warning::
+1 -1
View File
@@ -495,7 +495,7 @@ Example implementation::
optionB = -0.5,
optionC = true,
}
options.read_options(options, "myscript")
read_options(options, "myscript")
print(option.optionA)
+1 -1
View File
@@ -517,7 +517,7 @@ listed.
- Cache state, e.g. ``Cache: 2s+134KB``. Visible if the stream cache is enabled.
The first value shows the amount of video buffered in the demuxer in seconds,
the second value shows *additional* data buffered in the stream cache in
kilobytes. (``demuxer-cache-duration`` and ``cached-used`` properties.)
kilobytes. (``demuxer-cache-duration`` and ``cache-used`` properties.)
PROTOCOLS
+3 -2
View File
@@ -104,8 +104,9 @@ Playback Control
``--speed=<0.01-100>``
Slow down or speed up playback by the factor given as parameter.
If ``--audio-pitch-correction`` is used, playing with a speed higher than
normal automatically inserts the ``scaletempo`` audio filter.
If ``--audio-pitch-correction`` (on by default) is used, playing with a
speed higher than normal automatically inserts the ``scaletempo`` audio
filter.
``--loop=<N|inf|force|no>``
Loops playback ``N`` times. A value of ``1`` plays it one time (default),
+2 -1
View File
@@ -419,7 +419,8 @@ Available video output drivers are:
``swapinterval=<n>``
Interval in displayed frames between two buffer swaps.
1 is equivalent to enable VSYNC, 0 to disable VSYNC.
1 is equivalent to enable VSYNC, 0 to disable VSYNC. Defaults to 1 if
not specified.
``cscale=<filter>``
As ``scale``, but for interpolating chroma information. If the image
+31 -3
View File
@@ -7,8 +7,13 @@ Overview
**mpv** is a media player based on MPlayer and mplayer2. It supports a wide
variety of video file formats, audio and video codecs, and subtitle types.
If you are wondering what's different from mplayer2 and MPlayer you can read
more about the [changes][changes].
Releases can be found on the [release list][releases].
Downloads
---------
For semi-official builds and third-party packages please see
[mpv.io](http://mpv.io/installation/).
Compilation
-----------
@@ -124,6 +129,28 @@ For small changes you can just send us pull requests through GitHub. For bigger
changes come and talk to us on IRC before you start working on them. It will
make code review easier for both parties later on.
Relation to MPlayer and mplayer2
--------------------------------
mpv is based on mplayer2, which in turn is based on the original MPlayer
(also called mplayer, mplayer-svn, mplayer1). Many changes have been made, a
large part of which is incompatible or completely changes how the player
behaves. Although there are still many similarities to its ancestors, mpv
should generally be treated as a completely different program.
mpv was forked because we wanted to modernize MPlayer. This includes
removing cruft (including features which stopped making sense 10 years ago),
and of course adding modern features. Such huge and intrusive changes made it
infeasible to work directly with MPlayer, which is mostly focused on
preservation, so a fork had to be made. (Actually, mpv is based on mplayer2,
which already started this process of removing cruft.)
In general, mpv should be considered a completely new program, rather than a
MPlayer drop-in replacement.
If you are wondering what's different from mplayer2 and MPlayer, an incomplete
list of changes is located [here][mplayer-changes].
Contact
-------
@@ -139,7 +166,7 @@ mailing lists are mostly unused.
To contact the `mpv` team in private write to `mpv-team@googlegroups.com`. Use
only if discretion is required.
[changes]: https://github.com/mpv-player/mpv/blob/master/DOCS/man/changes.rst
[releases]: https://github.com/mpv-player/mpv/releases
[mpv-build]: https://github.com/mpv-player/mpv-build
[homebrew-mpv]: https://github.com/mpv-player/homebrew-mpv
[issue-tracker]: https://github.com/mpv-player/mpv/issues
@@ -148,3 +175,4 @@ only if discretion is required.
[ffmpeg_vs_libav]: https://github.com/mpv-player/mpv/wiki/FFmpeg-versus-Libav
[release-policy]: https://github.com/mpv-player/mpv/blob/master/DOCS/release-policy.md
[windows_compilation]: https://github.com/mpv-player/mpv/blob/master/DOCS/compile-windows.md
[mplayer-changes]: https://github.com/mpv-player/mpv/blob/master/DOCS/mplayer-changes.rst
+30
View File
@@ -1,3 +1,33 @@
Release 0.8.3
=============
Changes
-------
- Documentation fixes and updates.
- (Client API) Clarify `mpv_opengl_cb_render`'s viewport parameter behavior.
Bug fixes
---------
- (X11) Fix crash on `vo_xv:no-colorkey` with the Overlay adapter. (bug #1629)
- Make the video equalizer work correctly on some VAAPI drivers. (bug #1647)
- Prevent OSD from disappearing when clicking on mozplugger. (bug #1672)
- The new DVB-S2 support code, using S2API, now builds on FreeBSD.
- Fix decoding of seekable matroska from unseekable network stream. (bug #1656)
- (OSX) Fix crashing when closing a VO's window (usually at exit). (bug #1657)
- (OSX) Unhide the mouse cursor when over the Dock or Launchpad. (bug #513)
- (OSX) Fix mouse cursor autohiding when the player is fullscreen.
- `vf_vavpp` (VAAPI postprocessing) now deinterlaces video correctly.
- `smb://` streams now use the stream cache (used to be inefficient).
- (Windows) Do not hide the mouse cursor when it is hovering the window menu.
- Fix 8-channel output on `ao_jack`. (bug #1688)
- Fix `--mf-fps` parameter on JPEG files. (bug #1689)
- Fix anamorphic scaling being ignored if it was very minor.
This listing is not complete. A complete changelog can be seen by running
`git log v0.8.2..v0.8.3` in the git repository.
Release 0.8.2
=============
+1 -1
View File
@@ -64,7 +64,7 @@ sub generate_c_header {
# Output a counter variable for each element
# (presence/absence for scalars, item count for arrays)
for my $subel (values %{$el->{subelements}}) {
for my $subel (sort values %{$el->{subelements}}) {
print " int n_$subel->{fieldname};\n"
}
print "};\n";
+1 -1
View File
@@ -1 +1 @@
0.8.2
0.8.3
+2 -2
View File
@@ -74,7 +74,7 @@ void mp_chmap_sel_add_waveext(struct mp_chmap_sel *s)
// Classic ALSA-based MPlayer layouts.
void mp_chmap_sel_add_alsa_def(struct mp_chmap_sel *s)
{
for (int n = 0; n < MP_NUM_CHANNELS; n++) {
for (int n = 1; n <= MP_NUM_CHANNELS; n++) {
struct mp_chmap t;
mp_chmap_from_channels_alsa(&t, n);
if (t.num)
@@ -102,7 +102,7 @@ void mp_chmap_sel_add_map(struct mp_chmap_sel *s, const struct mp_chmap *map)
// Allow all waveext formats in default order.
void mp_chmap_sel_add_waveext_def(struct mp_chmap_sel *s)
{
for (int n = 1; n < MP_NUM_CHANNELS; n++) {
for (int n = 1; n <= MP_NUM_CHANNELS; n++) {
struct mp_chmap map;
mp_chmap_from_channels(&map, n);
mp_chmap_sel_add_map(s, &map);
-1
View File
@@ -200,7 +200,6 @@ static int decode_packet(struct dec_audio *da, struct mp_audio **out)
AVPacket pkt;
mp_set_av_packet(&pkt, mpkt, NULL);
pkt.pts = pkt.dts = 0;
MP_VERBOSE(da, "spdif packet, size=%d\n", pkt.size);
if (mpkt->pts != MP_NOPTS_VALUE) {
da->pts = mpkt->pts;
da->pts_offset = 0;
+18 -5
View File
@@ -6,7 +6,8 @@ from __future__ import print_function
import os, sys, stat, hashlib, subprocess
WAFRELEASE = "waf-1.8.4"
WAFURL = "http://ftp.waf.io/pub/release/" + WAFRELEASE
WAFURLS = ["http://ftp.waf.io/pub/release/" + WAFRELEASE,
"http://www.freehackers.org/~tnagy/release/" + WAFRELEASE]
SHA256HASH = "f02035fa5d8814f33f19b2b20d43822ddef6bb39b955ca196c2a247a1f9ffaa8"
if os.path.exists("waf"):
@@ -16,12 +17,24 @@ if os.path.exists("waf"):
sys.exit(0)
try:
from urllib.request import urlopen
from urllib.request import urlopen, URLError
except:
from urllib2 import urlopen
from urllib2 import urlopen, URLError
print("Downloading %s..." % WAFURL)
waf = urlopen(WAFURL).read()
waf = None
for WAFURL in WAFURLS:
try:
print("Downloading {}...".format(WAFURL))
waf = urlopen(WAFURL).read()
break
except URLError:
print("Download failed.")
if not waf:
print("Could not download {}.".format(WAFRELEASE))
sys.exit(1)
if SHA256HASH == hashlib.sha256(waf).hexdigest():
with open("waf", "wb") as wf:
+2
View File
@@ -135,6 +135,8 @@ void mp_set_avcodec_threads(struct mp_log *l, AVCodecContext *avctx, int threads
threads = 1;
} else {
mp_verbose(l, "Detected %d logical cores.\n", threads);
if (threads > 1)
threads += 1; // extra thread for better load balancing
}
// Apparently some libavcodec versions have or had trouble with more
// than 16 threads, and/or print a warning when using > 16.
+4 -1
View File
@@ -136,8 +136,11 @@ bool mp_msg_test(struct mp_log *log, int lev)
struct mp_log_root *root = log->root;
if (!root || root->mute)
return false;
if (atomic_load(&log->reload_counter) != atomic_load(&root->reload_counter))
if (atomic_load_explicit(&log->reload_counter, memory_order_relaxed) !=
atomic_load_explicit(&root->reload_counter, memory_order_relaxed))
{
update_loglevel(log);
}
return lev <= log->level;
}
+2
View File
@@ -62,6 +62,8 @@ struct playlist {
// current_was_replaced is set to true.
struct playlist_entry *current;
bool current_was_replaced;
bool disable_safety;
};
void playlist_entry_add_param(struct playlist_entry *e, bstr name, bstr value);
+6 -1
View File
@@ -888,7 +888,7 @@ static struct demuxer *open_given_type(struct mpv_global *global,
stream_seek(stream, 0);
// Peek this much data to avoid that stream_read() run by some demuxers
// or stream filters will flush previous peeked data.
// will flush previous peeked data.
stream_peek(stream, STREAM_BUFFER_SIZE);
int ret = demuxer->desc->open(in->d_thread, check);
@@ -1378,6 +1378,11 @@ void demux_unpause(demuxer_t *demuxer)
pthread_mutex_unlock(&in->lock);
}
bool demux_cancel_test(struct demuxer *demuxer)
{
return mp_cancel_test(demuxer->stream->cancel);
}
struct demux_chapter *demux_copy_chapter_data(struct demux_chapter *c, int num)
{
struct demux_chapter *new = talloc_array(NULL, struct demux_chapter, num);
+2
View File
@@ -251,6 +251,8 @@ void demux_start_thread(struct demuxer *demuxer);
void demux_stop_thread(struct demuxer *demuxer);
void demux_set_wakeup_cb(struct demuxer *demuxer, void (*cb)(void *ctx), void *ctx);
bool demux_cancel_test(struct demuxer *demuxer);
void demux_flush(struct demuxer *demuxer);
int demux_seek(struct demuxer *demuxer, double rel_seek_secs, int flags);
+1
View File
@@ -134,6 +134,7 @@ static const struct format_hack format_hacks[] = {
BLACKLIST("bin"),
// Image demuxers, disabled in favor of demux_mf (for now):
BLACKLIST("image"),
BLACKLIST("image2"),
BLACKLIST("image2pipe"),
BLACKLIST("bmp_pipe"), BLACKLIST("dpx_pipe"), BLACKLIST("exr_pipe"),
BLACKLIST("j2k_pipe"), BLACKLIST("png_pipe"), BLACKLIST("tiff_pipe"),
+19 -14
View File
@@ -1036,9 +1036,6 @@ static int demux_mkv_read_seekhead(demuxer_t *demuxer)
struct ebml_seek_head seekhead = {0};
struct ebml_parse_ctx parse_ctx = {demuxer->log};
int64_t end = 0;
stream_control(s, STREAM_CTRL_GET_SIZE, &end);
MP_VERBOSE(demuxer, "/---- [ parsing seek head ] ---------\n");
if (ebml_read_element(s, &parse_ctx, &seekhead, &ebml_seek_head_desc) < 0) {
res = -1;
@@ -1053,16 +1050,7 @@ static int demux_mkv_read_seekhead(demuxer_t *demuxer)
uint64_t pos = seek->seek_position + mkv_d->segment_start;
MP_DBG(demuxer, "Element 0x%x at %"PRIu64".\n",
(unsigned)seek->seek_id, pos);
struct header_elem *elem = get_header_element(demuxer, seek->seek_id, pos);
// Warn against incomplete files.
if (elem && pos >= end) {
elem->parsed = true; // don't bother
if (!mkv_d->eof_warning) {
MP_WARN(demuxer, "SeekHead position beyond "
"end of file - incomplete file?\n");
mkv_d->eof_warning = true;
}
}
get_header_element(demuxer, seek->seek_id, pos);
}
out:
MP_VERBOSE(demuxer, "\\---- [ parsing seek head ] ---------\n");
@@ -1810,12 +1798,27 @@ static int demux_mkv_open(demuxer_t *demuxer, enum demux_check check)
return -1;
}
int64_t end = 0;
stream_control(s, STREAM_CTRL_GET_SIZE, &end);
// Read headers that come after the first cluster (i.e. require seeking).
// Note: reading might increase ->num_headers.
// Likewise, ->headers might be reallocated.
for (int n = 0; n < mkv_d->num_headers; n++) {
struct header_elem *elem = &mkv_d->headers[n];
if (elem->id == MATROSKA_ID_CUES && !elem->parsed) {
if (elem->parsed)
continue;
// Warn against incomplete files and skip headers outside of range.
if (elem->pos >= end) {
elem->parsed = true; // don't bother if file is incomplete
if (!mkv_d->eof_warning) {
MP_WARN(demuxer, "SeekHead position beyond "
"end of file - incomplete file?\n");
mkv_d->eof_warning = true;
}
continue;
}
if (elem->id == MATROSKA_ID_CUES) {
// Read cues when they are needed, to avoid seeking on opening.
MP_VERBOSE(demuxer, "Deferring reading cues.\n");
continue;
@@ -2519,6 +2522,8 @@ static int read_next_block(demuxer_t *demuxer, struct block_info *block)
break;
if (s->eof)
return -1;
if (demux_cancel_test(demuxer))
return -1;
if (id == EBML_ID_EBML && stream_tell(s) >= mkv_d->segment_end) {
// Appended segment - don't use its clusters, consider this EOF.
stream_seek(s, stream_tell(s) - 4);
+26
View File
@@ -23,6 +23,7 @@
#include "common/playlist.h"
#include "options/path.h"
#include "stream/stream.h"
#include "stream/rar.h"
#include "demux.h"
#define PROBE_SIZE (8 * 1024)
@@ -188,6 +189,30 @@ static int parse_pls(struct pl_parser *p)
return 0;
}
static int parse_rar(struct pl_parser *p)
{
if (RarProbe(p->s))
return -1;
if (p->probing)
return 0;
int count;
rar_file_t **files;
if (RarParse(p->s, &count, &files))
return -1;
p->pl->disable_safety = true; // make it load rar://
char *prefix = mp_url_escape(p, p->real_stream->url, "~|");
for (int n = 0; n < count; n++) {
// stream_rar.c does the real work
playlist_add_file(p->pl,
talloc_asprintf(p, "rar://%s|%s", prefix, files[n]->name));
RarFileDelete(files[n]);
}
talloc_free(files);
return 0;
}
static int parse_txt(struct pl_parser *p)
{
if (!p->force)
@@ -220,6 +245,7 @@ static const struct pl_format formats[] = {
{"mov", parse_mov_rtsptext},
{"pls", parse_pls,
MIME_TYPES("audio/x-scpls")},
{"rar", parse_rar},
{"txt", parse_txt},
};
+4 -2
View File
@@ -228,8 +228,10 @@ int ebml_resync_cluster(struct mp_log *log, stream_t *s)
{
int64_t pos = stream_tell(s);
uint32_t last_4_bytes = 0;
mp_err(log, "Corrupt file detected. "
"Trying to resync starting from position %"PRId64"...\n", pos);
if (!s->eof) {
mp_err(log, "Corrupt file detected. "
"Trying to resync starting from position %"PRId64"...\n", pos);
}
while (!s->eof) {
// Assumes MATROSKA_ID_CLUSTER is 4 bytes, with no 0 bytes.
if (last_4_bytes == MATROSKA_ID_CLUSTER) {
+4 -1
View File
@@ -186,11 +186,14 @@ int mpv_opengl_cb_init_gl(mpv_opengl_cb_context *ctx, const char *exts,
* postprocessing, it will always bind and unbind FBOs itself. If
* you want mpv to render on the main framebuffer, pass 0.
* @param vp Viewport to render on. The renderer will essentially call:
* glViewport(vp[0], vp[1], vp[2], vp[3]);
* glViewport(0, 0, vp[2], vp[3]);
* before rendering. The height (vp[3]) can be negative to flip the
* image - the renderer will flip it before setting the viewport
* (typically you want to flip the image if you are rendering
* directly to the main framebuffer).
* vp[0] and vp[1] should be set to 0.
* The viewport width and height imply the target FBO or framebuffer's
* size. It will always render to the full size of it.
* @return the number of left frames in the internal queue to be rendered
*/
int mpv_opengl_cb_render(mpv_opengl_cb_context *ctx, int fbo, int vp[4]);
+2 -2
View File
@@ -240,7 +240,7 @@ char *mp_path_join(void *talloc_ctx, struct bstr p1, struct bstr p2)
return bstrdup0(talloc_ctx, p1);
#if HAVE_DOS_PATHS
if (p2.len >= 2 && p2.start[1] == ':'
if ((p2.len >= 2 && p2.start[1] == ':')
|| p2.start[0] == '\\' || p2.start[0] == '/')
#else
if (p2.start[0] == '/')
@@ -251,7 +251,7 @@ char *mp_path_join(void *talloc_ctx, struct bstr p1, struct bstr p2)
int endchar1 = p1.start[p1.len - 1];
#if HAVE_DOS_PATHS
have_separator = endchar1 == '/' || endchar1 == '\\'
|| p1.len == 2 && endchar1 == ':'; // "X:" only
|| (p1.len == 2 && endchar1 == ':'); // "X:" only
#else
have_separator = endchar1 == '/';
#endif
+5
View File
@@ -41,6 +41,11 @@ typedef struct { volatile unsigned long long v; } atomic_ullong;
#define ATOMIC_VAR_INIT(x) \
{.v = (x)}
#define memory_order_relaxed 1
#define memory_order_seq_cst 2
#define atomic_load_explicit(p, e) atomic_load(p)
#if HAVE_ATOMIC_BUILTINS
#define atomic_load(p) \
+1 -1
View File
@@ -376,7 +376,7 @@ void cocoa_set_input_context(struct input_ctx *input_context)
if (cocoaModifiers & NSControlKeyMask)
mask |= MP_KEY_MODIFIER_CTRL;
if (LeftAltPressed(cocoaModifiers) ||
RightAltPressed(cocoaModifiers) && ![self useAltGr])
(RightAltPressed(cocoaModifiers) && ![self useAltGr]))
mask |= MP_KEY_MODIFIER_ALT;
if (cocoaModifiers & NSCommandKeyMask)
mask |= MP_KEY_MODIFIER_META;
+1 -1
View File
@@ -133,7 +133,7 @@ void set_playback_speed(struct MPContext *mpctx, double new_speed)
opts->playback_speed = new_speed;
if (!mpctx->d_audio)
if (!mpctx->d_audio || mpctx->d_audio->afilter->initialized < 1)
return;
recreate_audio_filters(mpctx);
+4 -5
View File
@@ -2297,15 +2297,15 @@ static int panscan_property_helper(void *ctx, struct m_property *prop,
static int mp_property_vo_flag(struct m_property *prop, int action, void *arg,
int vo_ctrl, int *vo_var, MPContext *mpctx)
{
if (!mpctx->video_out)
return M_PROPERTY_UNAVAILABLE;
if (action == M_PROPERTY_SET) {
int desired = !!*(int *) arg;
if (*vo_var == desired)
return M_PROPERTY_OK;
if (mpctx->video_out->config_ok)
if (mpctx->video_out) {
vo_control(mpctx->video_out, vo_ctrl, 0);
} else {
*vo_var = desired;
}
return *vo_var == desired ? M_PROPERTY_OK : M_PROPERTY_ERROR;
}
return mp_property_generic_option(mpctx, prop, action, arg);
@@ -3808,7 +3808,6 @@ static bool reinit_filters(MPContext *mpctx, enum stream_type mediatype)
case STREAM_VIDEO:
return reinit_video_filters(mpctx) >= 0;
case STREAM_AUDIO:
clear_audio_output_buffers(mpctx);
return reinit_audio_filters(mpctx) >= 0;
}
return false;
+6 -3
View File
@@ -1118,10 +1118,13 @@ goto_reopen_demuxer: ;
load_timeline(mpctx);
if (mpctx->demuxer->playlist) {
int entry_stream_flags =
(mpctx->demuxer->stream->safe_origin ? 0 : STREAM_SAFE_ONLY) |
(mpctx->demuxer->stream->is_network ? STREAM_NETWORK_ONLY : 0);
struct playlist *pl = mpctx->demuxer->playlist;
int entry_stream_flags = 0;
if (!pl->disable_safety) {
entry_stream_flags = STREAM_SAFE_ONLY;
if (mpctx->demuxer->stream->is_network)
entry_stream_flags |= STREAM_NETWORK_ONLY;
}
for (struct playlist_entry *e = pl->first; e; e = e->next)
e->stream_flags |= entry_stream_flags;
transfer_playlist(mpctx, pl);
+12
View File
@@ -971,6 +971,17 @@ static int script_get_screen_size(lua_State *L)
return 3;
}
static int script_get_screen_margins(lua_State *L)
{
struct MPContext *mpctx = get_mpctx(L);
struct mp_osd_res vo_res = osd_get_vo_res(mpctx->osd, OSDTYPE_EXTERNAL);
lua_pushnumber(L, vo_res.ml);
lua_pushnumber(L, vo_res.mt);
lua_pushnumber(L, vo_res.mr);
lua_pushnumber(L, vo_res.mb);
return 4;
}
static int script_get_mouse_pos(lua_State *L)
{
struct MPContext *mpctx = get_mpctx(L);
@@ -1280,6 +1291,7 @@ static const struct fn_entry main_fns[] = {
FN_ENTRY(set_osd_ass),
FN_ENTRY(get_osd_resolution),
FN_ENTRY(get_screen_size),
FN_ENTRY(get_screen_margins),
FN_ENTRY(get_mouse_pos),
FN_ENTRY(get_time),
FN_ENTRY(input_define_section),
+2
View File
@@ -1,3 +1,5 @@
-- Compatibility shim for lua 5.2/5.3
unpack = unpack or table.unpack
-- these are used internally by lua.c
mp.UNKNOWN_TYPE.info = "this value is inserted if the C type is not supported"
+2
View File
@@ -167,6 +167,8 @@ static char *create_fname(struct MPContext *mpctx, char *template,
}
case 'f':
case 'F': {
if (!mpctx->filename)
goto error_exit;
char *video_file = mp_basename(mpctx->filename);
if (video_file) {
char *name = video_file;
+2 -2
View File
@@ -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_fonts(struct ass_renderer *a, struct MPOpts *b,
struct mpv_global *c, struct mp_log *d) {}
static void mp_ass_configure_fonts(struct ass_renderer *a, struct osd_style_opts *b,
struct mpv_global *c, struct mp_log *d) {}
#endif
+3 -3
View File
@@ -70,11 +70,11 @@ static const char av_desync_help_text[] =
"- Slow video output.\n"
" Try a different --vo driver (--vo=help for a list). Make sure framedrop\n"
" is not disabled, or experiment with different values for --framedrop.\n"
"- Playing from a slow network source.\n"
" Download the file instead.\n"
" Make sure you have proper drivers for your GPU installed. If mpv\n"
" autoselects 'VO: [x11]', it's a sure sign your drivers are messed up.\n"
"- Playing from a slow network source. Download the file instead.\n"
"- Try to find out whether audio/video/subs are causing this by experimenting\n"
" with --no-video, --no-audio, or --no-sub.\n"
"- If you switched audio or video tracks, try seeking to force synchronization.\n"
"If none of this helps you, file a bug report.\n\n";
void update_fps(struct MPContext *mpctx)
+8 -2
View File
@@ -102,6 +102,9 @@ struct priv {
int64_t reads; // number of actual read attempts performed
int64_t read_filepos; // client read position (mirrors cache->pos)
int64_t eof_pos;
int control; // requested STREAM_CTRL_... or CACHE_CTRL_...
void *control_arg; // temporary for executing STREAM_CTRLs
int control_res;
@@ -277,8 +280,10 @@ done:
s->eof = len <= 0;
s->idle = s->eof;
s->reads++;
if (s->eof)
if (s->eof) {
s->eof_pos = stream_tell(s->stream);
MP_TRACE(s, "EOF reached.\n");
}
pthread_cond_signal(&s->wakeup);
@@ -352,7 +357,7 @@ static void update_cached_controls(struct priv *s)
talloc_free(s->stream_metadata);
s->stream_metadata = talloc_steal(s, tags);
}
s->stream_size = -1;
s->stream_size = s->eof_pos;
if (stream_control(s->stream, STREAM_CTRL_GET_SIZE, &i64) == STREAM_OK)
s->stream_size = i64;
s->has_avseek = stream_control(s->stream, STREAM_CTRL_HAS_AVSEEK, NULL) > 0;
@@ -610,6 +615,7 @@ int stream_cache_init(stream_t *cache, stream_t *stream,
struct priv *s = talloc_zero(NULL, struct priv);
s->log = cache->log;
s->eof_pos = -1;
cache_drop_contents(s);
+1 -1
View File
@@ -37,12 +37,12 @@
#ifndef DTV_STREAM_ID
#define DTV_STREAM_ID DTV_ISDBS_TS_ID
#endif
#endif
// This is only defined, for convenience, since API 5.8.
#ifndef NO_STREAM_ID_FILTER
#define NO_STREAM_ID_FILTER (~0U)
#endif
#endif
#if (DVB_API_VERSION == 3 && DVB_API_VERSION_MINOR >= 1) || DVB_API_VERSION == 5
#define DVB_ATSC 1
+2 -4
View File
@@ -385,8 +385,7 @@ int RarParse(struct stream *s, int *count, rar_file_t ***file)
if (!volume_mrl)
goto done;
vol = stream_create(volume_mrl, STREAM_READ | STREAM_NO_FILTERS,
s->cancel, s->global);
vol = stream_create(volume_mrl, STREAM_READ, s->cancel, s->global);
if (!vol)
goto done;
@@ -421,8 +420,7 @@ int RarSeek(rar_file_t *file, uint64_t position)
if (strcmp(old_chunk->mrl, file->current_chunk->mrl)) {
if (file->s)
free_stream(file->s);
file->s = stream_create(file->current_chunk->mrl,
STREAM_READ | STREAM_NO_FILTERS,
file->s = stream_create(file->current_chunk->mrl, STREAM_READ,
file->cancel, file->global);
}
return file->s ? stream_seek(file->s, offset) : 0;
+14 -39
View File
@@ -74,8 +74,7 @@ extern const stream_info_t stream_info_dvdnav;
extern const stream_info_t stream_info_bdmv_dir;
extern const stream_info_t stream_info_bluray;
extern const stream_info_t stream_info_bdnav;
extern const stream_info_t stream_info_rar_filter;
extern const stream_info_t stream_info_rar_entry;
extern const stream_info_t stream_info_rar;
extern const stream_info_t stream_info_edl;
static const stream_info_t *const stream_list[] = {
@@ -115,8 +114,7 @@ static const stream_info_t *const stream_list[] = {
&stream_info_null,
&stream_info_mf,
&stream_info_edl,
&stream_info_rar_filter,
&stream_info_rar_entry,
&stream_info_rar,
&stream_info_file,
NULL
};
@@ -256,32 +254,25 @@ static const char *match_proto(const char *url, const char *proto)
return NULL;
}
static int open_internal(const stream_info_t *sinfo, struct stream *underlying,
const char *url, int flags, struct mp_cancel *c,
struct mpv_global *global, struct stream **ret)
static int open_internal(const stream_info_t *sinfo, const char *url, int flags,
struct mp_cancel *c, struct mpv_global *global,
struct stream **ret)
{
if (sinfo->stream_filter != !!underlying)
return STREAM_NO_MATCH;
if (sinfo->stream_filter && (flags & STREAM_NO_FILTERS))
return STREAM_NO_MATCH;
if (!sinfo->is_safe && (flags & STREAM_SAFE_ONLY))
return STREAM_UNSAFE;
if (!sinfo->is_network && (flags & STREAM_NETWORK_ONLY))
return STREAM_UNSAFE;
const char *path = NULL;
// Stream filters use the original URL, with no protocol matching at all.
if (!sinfo->stream_filter) {
for (int n = 0; sinfo->protocols && sinfo->protocols[n]; n++) {
path = match_proto(url, sinfo->protocols[n]);
if (path)
break;
}
if (!path)
return STREAM_NO_MATCH;
for (int n = 0; sinfo->protocols && sinfo->protocols[n]; n++) {
path = match_proto(url, sinfo->protocols[n]);
if (path)
break;
}
if (!path)
return STREAM_NO_MATCH;
stream_t *s = new_stream();
s->log = mp_log_new(s, global->log, sinfo->name);
s->info = sinfo;
@@ -290,7 +281,6 @@ static int open_internal(const stream_info_t *sinfo, struct stream *underlying,
s->global = global;
s->url = talloc_strdup(s, url);
s->path = talloc_strdup(s, path);
s->source = underlying;
s->allow_caching = true;
s->is_network = sinfo->is_network;
s->mode = flags & (STREAM_READ | STREAM_WRITE);
@@ -357,7 +347,7 @@ struct stream *stream_create(const char *url, int flags,
// Open stream proper
bool unsafe = false;
for (int i = 0; stream_list[i]; i++) {
int r = open_internal(stream_list[i], NULL, url, flags, c, global, &s);
int r = open_internal(stream_list[i], url, flags, c, global, &s);
if (r == STREAM_OK)
break;
if (r == STREAM_NO_MATCH || r == STREAM_UNSUPPORTED)
@@ -386,19 +376,6 @@ struct stream *stream_create(const char *url, int flags,
goto done;
}
// Open stream filters
for (;;) {
struct stream *new = NULL;
for (int i = 0; stream_list[i]; i++) {
int r = open_internal(stream_list[i], s, s->url, flags, c, global, &new);
if (r == STREAM_OK)
break;
}
if (!new)
break;
s = new;
}
done:
talloc_free(log);
return s;
@@ -730,7 +707,6 @@ void free_stream(stream_t *s)
if (s->close)
s->close(s);
free_stream(s->uncached_stream);
free_stream(s->source);
talloc_free(s);
}
@@ -759,7 +735,6 @@ static stream_t *open_cache(stream_t *orig, const char *name)
cache->mime_type = talloc_strdup(cache, orig->mime_type);
cache->demuxer = talloc_strdup(cache, orig->demuxer);
cache->lavf_type = talloc_strdup(cache, orig->lavf_type);
cache->safe_origin = orig->safe_origin;
cache->streaming = orig->streaming,
cache->is_network = orig->is_network;
cache->opts = orig->opts;
@@ -1012,7 +987,7 @@ void mp_cancel_reset(struct mp_cancel *c)
// For convenience, c==NULL is allowed.
bool mp_cancel_test(struct mp_cancel *c)
{
return c ? atomic_load(&c->triggered) : false;
return c ? atomic_load_explicit(&c->triggered, memory_order_relaxed) : false;
}
// Wait until the even is signaled. If the timeout (in seconds) expires, return
-4
View File
@@ -54,7 +54,6 @@ enum streamtype {
#define STREAM_WRITE 1
// flags for stream_open_ext (this includes STREAM_READ and STREAM_WRITE)
#define STREAM_NO_FILTERS 2
#define STREAM_SAFE_ONLY 4
#define STREAM_NETWORK_ONLY 8
@@ -157,7 +156,6 @@ typedef struct stream_info_st {
void *(*get_defaults)(struct stream *st);
const struct m_option *options;
const char *const *url_options;
bool stream_filter;
bool can_write; // correctly checks for READ/WRITE modes
bool is_safe; // opening is no security issue, even with remote provided URLs
bool is_network; // used to restrict remote playlist entries to remote URLs
@@ -196,7 +194,6 @@ typedef struct stream {
bool streaming : 1; // known to be a network stream if true
bool seekable : 1; // presence of general byte seeking support
bool fast_skip : 1; // consider stream fast enough to fw-seek by skipping
bool safe_origin : 1; // used for playlists that can be opened safely
bool is_network : 1; // original stream_info_t.is_network flag
bool allow_caching : 1; // stream cache makes sense
struct mp_log *log;
@@ -209,7 +206,6 @@ typedef struct stream {
char *capture_filename;
struct stream *uncached_stream; // underlying stream for cache wrapper
struct stream *source;
// Includes additional padding in case sizes get rounded up by sector size.
unsigned char buffer[];
-2
View File
@@ -227,7 +227,6 @@ static void close_cdda(stream_t *s)
cdda_priv *p = (cdda_priv *)s->priv;
paranoia_free(p->cdp);
cdda_close(p->cd);
free(p);
}
static int get_track_by_sector(cdda_priv *p, unsigned int sector)
@@ -313,7 +312,6 @@ static int open_cdda(stream_t *st)
return STREAM_ERROR;
}
priv = calloc(1,sizeof(cdda_priv));
priv->cd = cdd;
if (p->toc_bias)
+5 -74
View File
@@ -43,11 +43,10 @@ This works as follows:
- stream_open() with file01.rar
- is opened as normal file (stream_file.c or others) first
- stream_info_rar_filter stream filter applies
- leads to rar_filter_open()
- the rar code in demux_playlist.c detects it
- if multi-part, opens file02.rar, file03.rar, etc. as actual streams
(recursive opening is prevented with the STREAM_NO_FILTERS flag)
- read accesses return a m3u playlist with entries like:
- it returns a playlist like this to the player:
rar://bla01.rar|subfile.mkv
(one such entry for each file contained in the rar)
- stream_open() with the playlist entry, e.g. rar://bla01.rar|subfile.mkv
@@ -99,7 +98,7 @@ static int rar_entry_open(stream_t *stream)
*name++ = '\0';
mp_url_unescape_inplace(base);
struct stream *rar = stream_create(base, STREAM_READ | STREAM_NO_FILTERS,
struct stream *rar = stream_create(base, STREAM_READ | STREAM_SAFE_ONLY,
stream->cancel, stream->global);
if (!rar)
return STREAM_ERROR;
@@ -143,76 +142,8 @@ static int rar_entry_open(stream_t *stream)
return STREAM_OK;
}
static int rar_filter_fill_buffer(stream_t *s, char *buffer, int max_len)
{
struct stream *m = s->priv;
return stream_read_partial(m, buffer, max_len);
}
static int rar_filter_seek(stream_t *s, int64_t newpos)
{
struct stream *m = s->priv;
return stream_seek(m, newpos);
}
static void rar_filter_close(stream_t *s)
{
struct stream *m = s->priv;
free_stream(m);
}
static int rar_filter_control(stream_t *s, int cmd, void *arg)
{
struct stream *m = s->priv;
return stream_control(m, cmd, arg);
}
static int rar_filter_open(stream_t *stream)
{
struct stream *rar = stream->source;
if (!rar)
return STREAM_UNSUPPORTED;
int count;
rar_file_t **files;
if (!rar || RarProbe(rar) || RarParse(rar, &count, &files))
return STREAM_UNSUPPORTED;
void *tmp = talloc_new(NULL);
// Create a playlist containing all entries of the .rar file. The URLs
// link to rar_entry_open().
char *prefix = mp_url_escape(tmp, stream->url, "~|");
char *pl = talloc_strdup(tmp, "#EXTM3U\n");
for (int n = 0; n < count; n++) {
pl = talloc_asprintf_append_buffer(pl, "rar://%s|%s\n",
prefix, files[n]->name);
RarFileDelete(files[n]);
}
talloc_free(files);
struct stream *m = open_memory_stream(pl, strlen(pl));
stream->priv = m;
stream->fill_buffer = rar_filter_fill_buffer;
stream->seek = rar_filter_seek;
stream->seekable = true;
stream->close = rar_filter_close;
stream->control = rar_filter_control;
stream->safe_origin = true;
talloc_free(tmp);
return STREAM_OK;
}
const stream_info_t stream_info_rar_entry = {
.name = "rar_entry",
const stream_info_t stream_info_rar = {
.name = "rar",
.open = rar_entry_open,
.protocols = (const char*const[]){ "rar", NULL },
};
const stream_info_t stream_info_rar_filter = {
.name = "rar_filter",
.open = rar_filter_open,
.stream_filter = true,
};
+1
View File
@@ -133,6 +133,7 @@ static int open_f (stream_t *stream)
stream->close = close_f;
stream->control = control;
stream->read_chunk = 128 * 1024;
stream->streaming = true;
return STREAM_OK;
}
+1 -8
View File
@@ -402,6 +402,7 @@ int video_reconfig_filters(struct dec_video *d_video,
if (sh->aspect > 0)
vf_set_dar(&p.d_w, &p.d_h, p.w, p.h, sh->aspect);
} else {
MP_VERBOSE(d_video, "Using bitstream aspect ratio.\n");
// Even if the aspect switches back, don't use container aspect again.
d_video->initial_decoder_aspect = -1;
}
@@ -410,14 +411,6 @@ int video_reconfig_filters(struct dec_video *d_video,
if (force_aspect >= 0.0)
vf_set_dar(&p.d_w, &p.d_h, p.w, p.h, force_aspect);
if (abs(p.d_w - p.w) >= 4 || abs(p.d_h - p.h) >= 4) {
MP_VERBOSE(d_video, "Aspect ratio is %.2f:1 - "
"scaling to correct movie aspect.\n", sh->aspect);
} else {
p.d_w = p.w;
p.d_h = p.h;
}
// Apply user overrides
if (opts->requested_colorspace != MP_CSP_AUTO)
p.colorspace = opts->requested_colorspace;
+1 -1
View File
@@ -130,8 +130,8 @@ static const struct vd_lavc_hwdec *const hwdec_list[] = {
&mp_vd_lavc_vda,
#endif
#if HAVE_VAAPI_HWACCEL
&mp_vd_lavc_vaapi,
&mp_vd_lavc_vaapi_copy,
&mp_vd_lavc_vaapi,
#endif
#if HAVE_DXVA2_HWACCEL
&mp_vd_lavc_dxva2_copy,
+8
View File
@@ -163,6 +163,14 @@ static struct mp_image *render(struct vf_instance *vf, struct mp_image *in,
status = vaMapBuffer(p->display, buffer, (void**)&param);
if (!check_error(vf, status, "vaMapBuffer()"))
break;
VAProcFilterParameterBufferDeinterlacing *filter_params;
status = vaMapBuffer(p->display, *(p->pipe.filters), (void**)&filter_params);
if (!check_error(vf, status, "vaMapBuffer()"))
break;
filter_params->flags = flags & VA_TOP_FIELD ? 0 : VA_DEINTERLACING_BOTTOM_FIELD;
vaUnmapBuffer(p->display, *(p->pipe.filters));
param->surface = in_id;
param->surface_region = NULL;
param->output_region = NULL;
+1
View File
@@ -23,4 +23,5 @@
- (void)setFullScreen:(BOOL)willBeFullscreen;
- (void)clear;
- (BOOL)canHideCursor;
- (void)signalMousePosition;
@end
+4 -2
View File
@@ -28,7 +28,6 @@
@property(nonatomic, assign) BOOL clearing;
@property(nonatomic, assign) BOOL hasMouseDown;
@property(nonatomic, retain) NSTrackingArea *tracker;
- (void)signalMousePosition;
- (BOOL)hasDock:(NSScreen*)screen;
- (BOOL)hasMenubar:(NSScreen*)screen;
- (int)mpvButtonNumber:(NSEvent*)event;
@@ -167,7 +166,8 @@
- (BOOL)canHideCursor
{
return !self.hasMouseDown && [self containsMouseLocation];
return !self.hasMouseDown && [self containsMouseLocation]
&& [[self window] isKeyWindow];
}
- (void)mouseEntered:(NSEvent *)event
@@ -207,6 +207,8 @@
- (void)signalMousePosition
{
NSPoint p = [self convertPointToPixels:[self mouseLocation]];
p.x = MIN(MAX(p.x, 0), self.bounds.size.width-1);
p.y = MIN(MAX(p.y, 0), self.bounds.size.height-1);
[self.adapter signalMouseMovement:p];
}
+2 -1
View File
@@ -18,7 +18,7 @@
#import <Cocoa/Cocoa.h>
#include "video/out/vo.h"
@interface MpvCocoaAdapter : NSObject
@interface MpvCocoaAdapter : NSObject<NSWindowDelegate>
- (void)setNeedsResize;
- (void)signalMouseMovement:(NSPoint)point;
- (void)putKeyEvent:(NSEvent*)event;
@@ -28,6 +28,7 @@
- (void)handleFilesArray:(NSArray *)files;
- (void)didChangeWindowedScreenProfile:(NSScreen *)screen;
- (void)performAsyncResize:(NSSize)size;
- (void)didChangeMousePosition;
- (BOOL)isInFullScreenMode;
- (BOOL)keyboardEnabled;
+10
View File
@@ -61,6 +61,16 @@
[self.adapter didChangeWindowedScreenProfile:[self screen]];
}
- (void)windowDidResignKey:(NSNotification *)notification
{
[self.adapter windowDidResignKey:notification];
}
- (void)windowDidBecomeKey:(NSNotification *)notification
{
[self.adapter windowDidBecomeKey:notification];
}
- (BOOL)canBecomeMainWindow { return YES; }
- (BOOL)canBecomeKeyWindow { return YES; }
- (BOOL)windowShouldClose:(id)sender
+48 -37
View File
@@ -52,12 +52,13 @@
#define cocoa_unlock(s) pthread_mutex_unlock(&s->mutex)
static void vo_cocoa_fullscreen(struct vo *vo);
static void cocoa_rm_fs_screen_profile_observer(struct vo *vo);
static void cocoa_rm_fs_screen_profile_observer(struct vo_cocoa_state *s);
struct vo_cocoa_state {
NSWindow *window;
NSView *view;
MpvVideoView *video;
MpvCocoaAdapter *adapter;
NSOpenGLContext *gl_ctx;
NSScreen *current_screen;
@@ -87,9 +88,8 @@ struct vo_cocoa_state {
void (*resize_redraw)(struct vo *vo, int w, int h);
};
static void with_cocoa_lock(struct vo *vo, void(^block)(void))
static void with_cocoa_lock(struct vo_cocoa_state *s, void(^block)(void))
{
struct vo_cocoa_state *s = vo->cocoa;
cocoa_lock(s);
block();
cocoa_unlock(s);
@@ -97,8 +97,9 @@ static void with_cocoa_lock(struct vo *vo, void(^block)(void))
static void with_cocoa_lock_on_main_thread(struct vo *vo, void(^block)(void))
{
struct vo_cocoa_state *s = vo->cocoa;
dispatch_async(dispatch_get_main_queue(), ^{
with_cocoa_lock(vo, block);
with_cocoa_lock(s, block);
});
}
@@ -111,17 +112,15 @@ static void queue_new_video_size(struct vo *vo, int w, int h)
}
}
static void enable_power_management(struct vo *vo)
static void enable_power_management(struct vo_cocoa_state *s)
{
struct vo_cocoa_state *s = vo->cocoa;
if (!s->power_mgmt_assertion) return;
IOPMAssertionRelease(s->power_mgmt_assertion);
s->power_mgmt_assertion = kIOPMNullAssertionID;
}
static void disable_power_management(struct vo *vo)
static void disable_power_management(struct vo_cocoa_state *s)
{
struct vo_cocoa_state *s = vo->cocoa;
if (s->power_mgmt_assertion) return;
IOPMAssertionCreateWithName(
kIOPMAssertionTypePreventUserIdleDisplaySleep,
@@ -148,7 +147,7 @@ static void set_application_icon(NSApplication *app)
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(NULL, struct vo_cocoa_state);
*s = (struct vo_cocoa_state){
.waiting_frame = false,
.power_mgmt_assertion = kIOPMNullAssertionID,
@@ -190,16 +189,10 @@ void vo_cocoa_register_resize_callback(struct vo *vo,
void vo_cocoa_uninit(struct vo *vo)
{
struct vo_cocoa_state *s = vo->cocoa;
NSView *ev = s->view;
// keep the event view around for later in order to call -clear
if (!s->embedded) {
[ev retain];
}
with_cocoa_lock_on_main_thread(vo, ^{
enable_power_management(vo);
cocoa_rm_fs_screen_profile_observer(vo);
enable_power_management(s);
cocoa_rm_fs_screen_profile_observer(s);
[s->gl_ctx release];
@@ -208,21 +201,15 @@ void vo_cocoa_uninit(struct vo *vo)
[s->video removeFromSuperview];
[s->view removeFromSuperview];
[(MpvEventsView *)s->view clear];
[s->view release];
// if using --wid + libmpv there's no window to release
if (s->window)
[s->window release];
});
// don't use the mutex, because at that point it could have been destroyed
// and no one is accessing the events view anyway
if (!s->embedded) {
dispatch_async(dispatch_get_main_queue(), ^{
[(MpvEventsView *)ev clear];
[ev release];
});
}
talloc_free(s);
});
}
static int get_screen_handle(struct vo *vo, int identifier, NSWindow *window,
@@ -279,6 +266,8 @@ static void vo_cocoa_update_screen_fps(struct vo *vo)
s->screen_fps = (t.timeScale / (double) t.timeValue);
CVDisplayLinkRelease(link);
}
s->pending_events |= VO_EVENT_WIN_STATE;
}
static void vo_cocoa_update_screen_info(struct vo *vo, struct mp_rect *out_rc)
@@ -379,10 +368,9 @@ static void create_ui(struct vo *vo, struct mp_rect *win, int geo_flags)
view.adapter = adapter;
s->view = view;
[parent addSubview:s->view];
// insert ourselves as the next key view so that clients can give key
// focus to the mpv view by calling -[NSWindow selectNextKeyView:]
[parent setNextKeyView:s->view];
// update the cursor position now that the view has been added.
[view signalMousePosition];
s->adapter = adapter;
#if HAVE_COCOA_APPLICATION
cocoa_register_menu_item_action(MPM_H_SIZE, @selector(halfSize));
@@ -427,9 +415,8 @@ static int cocoa_set_window_title(struct vo *vo, const char *title)
return VO_TRUE;
}
static void cocoa_rm_fs_screen_profile_observer(struct vo *vo)
static void cocoa_rm_fs_screen_profile_observer(struct vo_cocoa_state *s)
{
struct vo_cocoa_state *s = vo->cocoa;
[[NSNotificationCenter defaultCenter]
removeObserver:s->fs_icc_changed_ns_observer];
}
@@ -439,7 +426,7 @@ static void cocoa_add_fs_screen_profile_observer(struct vo *vo)
struct vo_cocoa_state *s = vo->cocoa;
if (s->fs_icc_changed_ns_observer)
cocoa_rm_fs_screen_profile_observer(vo);
cocoa_rm_fs_screen_profile_observer(s);
if (vo->opts->fsscreen_id < 0)
return;
@@ -501,7 +488,7 @@ int vo_cocoa_config_window(struct vo *vo, uint32_t flags, void *gl_ctx)
}
// trigger a resize -> don't set vo->dwidth and vo->dheight directly
// since this block is executed asynchrolously to the video
// since this block is executed asynchronously to the video
// reconfiguration code.
s->pending_events |= VO_EVENT_RESIZE;
});
@@ -612,6 +599,13 @@ static void vo_cocoa_fullscreen(struct vo *vo)
draw_changes_after_next_frame(vo);
[(MpvEventsView *)s->view setFullScreen:opts->fullscreen];
if ([s->view window] != s->window) {
// cocoa implements fullscreen views by moving the view to a fullscreen
// window. Set that window delegate to the cocoa adapter to trigger
// calls to -windowDidResignKey: and -windowDidBecomeKey:
[[s->view window] setDelegate:s->adapter];
}
s->pending_events |= VO_EVENT_ICC_PROFILE_CHANGED;
s->pending_events |= VO_EVENT_RESIZE;
}
@@ -645,7 +639,7 @@ int vo_cocoa_control(struct vo *vo, int *events, int request, void *arg)
return vo_cocoa_ontop(vo);
case VOCTRL_GET_UNFS_WINDOW_SIZE: {
int *s = arg;
with_cocoa_lock(vo, ^{
with_cocoa_lock(vo->cocoa, ^{
NSSize size = [vo->cocoa->view frame].size;
s[0] = size.width;
s[1] = size.height;
@@ -667,10 +661,10 @@ int vo_cocoa_control(struct vo *vo, int *events, int request, void *arg)
case VOCTRL_UPDATE_WINDOW_TITLE:
return cocoa_set_window_title(vo, (const char *) arg);
case VOCTRL_RESTORE_SCREENSAVER:
enable_power_management(vo);
enable_power_management(vo->cocoa);
return VO_TRUE;
case VOCTRL_KILL_SCREENSAVER:
disable_power_management(vo);
disable_power_management(vo->cocoa);
return VO_TRUE;
case VOCTRL_GET_ICC_PROFILE:
vo_cocoa_control_get_icc_profile(vo, arg);
@@ -769,4 +763,21 @@ int vo_cocoa_control(struct vo *vo, int *events, int request, void *arg)
struct vo_cocoa_state *s = self.vout->cocoa;
s->pending_events |= VO_EVENT_ICC_PROFILE_CHANGED;
}
- (void)didChangeMousePosition
{
struct vo_cocoa_state *s = self.vout->cocoa;
[(MpvEventsView *)s->view signalMousePosition];
}
- (void)windowDidResignKey:(NSNotification *)notification
{
[self didChangeMousePosition];
}
- (void)windowDidBecomeKey:(NSNotification *)notification
{
[self didChangeMousePosition];
}
@end
+32 -33
View File
@@ -467,9 +467,9 @@ void gl_video_set_debug(struct gl_video *p, bool enable)
}
// Draw a textured quad.
// x0, y0, x1, y1 = destination coordinates of the quad
// tx0, ty0, tx1, ty1 = source texture coordinates (usually in pixels)
// texture_w, texture_h = size of the texture, or an inverse factor
// x0, y0, x1, y1 = destination coordinates of the quad in pixels
// tx0, ty0, tx1, ty1 = source texture coordinates in pixels
// tex_w, tex_h = size of the texture in pixels
// flags = bits 0-1: rotate, bits 2: flip vertically
static void draw_quad(struct gl_video *p,
float x0, float y0, float x1, float y1,
@@ -2086,20 +2086,26 @@ void gl_video_upload_image(struct gl_video *p, struct mp_image *mpi)
gl->BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
}
static bool test_fbo(struct gl_video *p, GLenum format)
static bool test_fbo(struct gl_video *p, bool *success)
{
if (!*success)
return false;
GL *gl = p->gl;
bool success = false;
*success = false;
MP_VERBOSE(p, "Testing user-set FBO format (0x%x)\n",
(unsigned)p->opts.fbo_format);
struct fbotex fbo = {0};
if (fbotex_init(&fbo, p->gl, p->log, 16, 16, p->gl_target, GL_LINEAR, format))
if (fbotex_init(&fbo, p->gl, p->log, 16, 16, p->gl_target, GL_LINEAR,
p->opts.fbo_format))
{
gl->BindFramebuffer(GL_FRAMEBUFFER, fbo.fbo);
gl->BindFramebuffer(GL_FRAMEBUFFER, 0);
success = true;
*success = true;
}
fbotex_uninit(&fbo);
glCheckError(gl, p->log, "FBO test");
return success;
return *success;
}
// Disable features that are not supported with the current OpenGL version.
@@ -2116,33 +2122,25 @@ static void check_gl_features(struct gl_video *p)
char *disabled[10];
int n_disabled = 0;
if (have_fbo) {
MP_VERBOSE(p, "Testing user-set FBO format (0x%x)\n",
(unsigned)p->opts.fbo_format);
have_fbo = test_fbo(p, p->opts.fbo_format);
}
// Normally, we want to disable them by default if FBOs are unavailable,
// because they will be slow (not critically slow, but still slower).
// Without FP textures, we must always disable them.
// I don't know if luminance alpha float textures exist, so disregard them.
if (!have_float_tex || !have_arrays || !have_fbo || !have_1d_tex) {
for (int n = 0; n < 2; n++) {
const struct filter_kernel *kernel = mp_find_filter_kernel(p->opts.scalers[n]);
if (kernel) {
char *reason = "";
if (!have_fbo)
reason = "scaler (FBO)";
if (!have_float_tex)
reason = "scaler (float tex.)";
if (!have_arrays)
reason = "scaler (no GLSL support)";
if (!have_1d_tex && kernel->polar)
reason = "scaler (1D tex.)";
if (*reason) {
p->opts.scalers[n] = "bilinear";
disabled[n_disabled++] = reason;
}
for (int n = 0; n < 2; n++) {
const struct filter_kernel *kernel = mp_find_filter_kernel(p->opts.scalers[n]);
if (kernel) {
char *reason = NULL;
if (!test_fbo(p, &have_fbo))
reason = "scaler (FBO)";
if (!have_float_tex)
reason = "scaler (float tex.)";
if (!have_arrays)
reason = "scaler (no GLSL support)";
if (!have_1d_tex && kernel->polar)
reason = "scaler (1D tex.)";
if (reason) {
p->opts.scalers[n] = "bilinear";
disabled[n_disabled++] = reason;
}
}
}
@@ -2167,12 +2165,12 @@ static void check_gl_features(struct gl_video *p)
p->opts.srgb = false;
disabled[n_disabled++] = "sRGB output (GLSL version)";
}
if (!have_fbo && use_cms) {
if (use_cms && !test_fbo(p, &have_fbo)) {
p->opts.srgb = false;
p->use_lut_3d = false;
disabled[n_disabled++] = "color management (FBO)";
}
if (!have_fbo && p->opts.smoothmotion) {
if (p->opts.smoothmotion && !test_fbo(p, &have_fbo)) {
p->opts.smoothmotion = false;
disabled[n_disabled++] = "smoothmotion (FBO)";
}
@@ -2232,6 +2230,7 @@ static int init_gl(struct gl_video *p)
MP_VERBOSE(p, "16 bit texture depth: %d.\n", (int)param);
p->texture_16bit_depth = param;
}
gl->DeleteTextures(1, &tex);
}
debug_check_gl(p, "after init_gl");
+33 -13
View File
@@ -129,7 +129,8 @@ struct vo_internal {
bool paused;
bool vsync_timed; // the VO redraws itself as fast as possible
// at every vsync
int queued_events;
int queued_events; // event mask for the user
int internal_events; // event mask for us
int64_t flip_queue_offset; // queue flip events at most this much in advance
@@ -145,8 +146,9 @@ struct vo_internal {
int64_t frame_pts; // realtime of intended display
int64_t frame_duration; // realtime frame duration (for framedrop)
// --- The following fields can be accessed from the VO thread only
int64_t vsync_interval;
// --- The following fields can be accessed from the VO thread only
int64_t vsync_interval_approx;
int64_t last_flip;
char *window_title;
@@ -166,7 +168,7 @@ static bool get_desc(struct m_obj_desc *dst, int index)
.priv_size = vo->priv_size,
.priv_defaults = vo->priv_defaults,
.options = vo->options,
.hidden = vo->encode,
.hidden = vo->encode || !strcmp(vo->name, "opengl-cb"),
.p = vo,
};
return true;
@@ -230,6 +232,7 @@ static struct vo *vo_create(bool probing, struct mpv_global *global,
talloc_steal(vo, log);
*vo->in = (struct vo_internal) {
.dispatch = mp_dispatch_create(vo),
.internal_events = VO_EVENT_WIN_STATE,
};
mp_make_wakeup_pipe(vo->in->wakeup_pipe);
mp_dispatch_set_wakeup_fn(vo->in->dispatch, dispatch_wakeup_cb, vo);
@@ -302,16 +305,27 @@ void vo_destroy(struct vo *vo)
// to be called from VO thread only
static void update_display_fps(struct vo *vo)
{
double display_fps = 1000.0; // assume infinite if unset
if (vo->global->opts->frame_drop_fps > 0) {
display_fps = vo->global->opts->frame_drop_fps;
} else {
vo->driver->control(vo, VOCTRL_GET_DISPLAY_FPS, &display_fps);
struct vo_internal *in = vo->in;
pthread_mutex_lock(&in->lock);
if (in->internal_events & VO_EVENT_WIN_STATE) {
in->internal_events &= ~(unsigned)VO_EVENT_WIN_STATE;
pthread_mutex_unlock(&in->lock);
double display_fps = 1000.0; // assume infinite if unset
if (vo->global->opts->frame_drop_fps > 0) {
display_fps = vo->global->opts->frame_drop_fps;
} else {
vo->driver->control(vo, VOCTRL_GET_DISPLAY_FPS, &display_fps);
}
int64_t n_interval = MPMAX((int64_t)(1e6 / display_fps), 1);
pthread_mutex_lock(&in->lock);
if (vo->in->vsync_interval != n_interval)
MP_VERBOSE(vo, "Assuming %f FPS for framedrop.\n", display_fps);
vo->in->vsync_interval = n_interval;
}
int64_t n_interval = MPMAX((int64_t)(1e6 / display_fps), 1);
if (vo->in->vsync_interval != n_interval)
MP_VERBOSE(vo, "Assuming %f FPS for framedrop.\n", display_fps);
vo->in->vsync_interval = n_interval;
pthread_mutex_unlock(&in->lock);
}
static void check_vo_caps(struct vo *vo)
@@ -533,6 +547,7 @@ void vo_wait_frame(struct vo *vo)
pthread_mutex_unlock(&in->lock);
}
// needs lock
static int64_t prev_sync(struct vo *vo, int64_t ts)
{
struct vo_internal *in = vo->in;
@@ -895,7 +910,11 @@ void vo_set_flip_queue_params(struct vo *vo, int64_t offset_us, bool vsync_timed
int64_t vo_get_vsync_interval(struct vo *vo)
{
return vo->in->vsync_interval;
struct vo_internal *in = vo->in;
pthread_mutex_lock(&in->lock);
int64_t res = vo->in->vsync_interval;
pthread_mutex_unlock(&in->lock);
return res;
}
// Set specific event flags, and wakeup the playback core if needed.
@@ -907,6 +926,7 @@ void vo_event(struct vo *vo, int event)
if ((in->queued_events & event & VO_EVENTS_USER) != (event & VO_EVENTS_USER))
mp_input_wakeup(vo->input_ctx);
in->queued_events |= event;
in->internal_events |= event;
pthread_mutex_unlock(&in->lock);
}
+1 -1
View File
@@ -36,7 +36,7 @@
#define VO_EVENT_RESIZE 2
// The ICC profile needs to be reloaded
#define VO_EVENT_ICC_PROFILE_CHANGED 4
// Some other window state changed
// Some other window state changed (position, window state, fps)
#define VO_EVENT_WIN_STATE 8
// Set of events the player core may be interested in.
+1 -1
View File
@@ -940,7 +940,7 @@ render_osd:
// Return the high byte of the value that represents white in chroma (U/V)
static int get_chroma_clear_val(int bit_depth)
{
return 1 << (bit_depth - 1 & 7);
return 1 << ((bit_depth - 1) & 7);
}
// this macro is supposed to work on all formats supported by 3D rendering, and
+8 -6
View File
@@ -254,15 +254,17 @@ static bool get_and_update_icc_profile(struct gl_priv *p, int *events)
{
if (p->icc_opts->profile_auto) {
MP_VERBOSE(p, "Querying ICC profile...\n");
bstr icc;
bstr icc = bstr0(NULL);
int r = p->glctx->vo_control(p->vo, events, VOCTRL_GET_ICC_PROFILE, &icc);
if (r == VO_TRUE) {
if (r != VO_NOTAVAIL) {
if (r == VO_FALSE) {
MP_WARN(p, "Could not retrieve an ICC profile.\n");
} else if (r == VO_NOTIMPL) {
MP_ERR(p, "icc-profile-auto not implemented on this platform.\n");
}
gl_lcms_set_memory_profile(p->cms, &icc);
} else if (r == VO_NOTIMPL) {
MP_ERR(p, "icc-profile-auto not implemented on this platform.\n");
} else {
MP_ERR(p, "Could not retrieve an ICC profile.\n");
}
}
+9 -8
View File
@@ -306,20 +306,20 @@ int mpv_opengl_cb_render(struct mpv_opengl_cb_context *ctx, int fbo, int vp[4])
gl_video_resize(ctx->renderer, &wnd, &src, &dst, &osd, !ctx->flip);
}
if (vo) {
struct vo_priv *p = vo->priv;
if (ctx->reconfigured)
gl_video_config(ctx->renderer, &ctx->img_params);
if (ctx->reconfigured || ctx->update_new_opts) {
struct vo_priv *opts = p->ctx->new_opts ? p->ctx->new_opts : p;
if (ctx->reconfigured)
gl_video_config(ctx->renderer, &ctx->img_params);
if (ctx->update_new_opts) {
struct vo_priv *p = vo ? vo->priv : NULL;
struct vo_priv *opts = ctx->new_opts ? ctx->new_opts : p;
if (opts) {
gl_video_set_options(ctx->renderer, opts->renderer_opts);
ctx->gl->debug_context = opts->use_gl_debug;
gl_video_set_debug(ctx->renderer, opts->use_gl_debug);
frame_queue_shrink(ctx, opts->frame_queue_size);
}
ctx->reconfigured = false;
ctx->update_new_opts = false;
}
ctx->reconfigured = false;
ctx->update_new_opts = false;
struct mp_csp_equalizer *eq = gl_video_eq_ptr(ctx->renderer);
if (ctx->eq_changed) {
@@ -507,6 +507,7 @@ static void uninit(struct vo *vo)
p->ctx->img_params = (struct mp_image_params){0};
p->ctx->reconfigured = true;
p->ctx->active = NULL;
update(p);
pthread_mutex_unlock(&p->ctx->lock);
}
+41 -14
View File
@@ -23,6 +23,7 @@
#include <assert.h>
#include <stdarg.h>
#include <limits.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
@@ -100,6 +101,7 @@ struct priv {
unsigned int *va_subpic_flags;
int va_num_subpic_formats;
VADisplayAttribute *va_display_attrs;
int *mp_display_attr;
int va_num_display_attrs;
};
@@ -446,46 +448,70 @@ static int get_displayattribtype(const char *name)
return -1;
}
static VADisplayAttribute *get_display_attribute(struct priv *p,
const char *name)
static int get_display_attribute(struct priv *p, const char *name)
{
int type = get_displayattribtype(name);
for (int n = 0; n < p->va_num_display_attrs; n++) {
VADisplayAttribute *attr = &p->va_display_attrs[n];
if (attr->type == type)
return attr;
return n;
}
return NULL;
return -1;
}
static int mp_eq_to_va(VADisplayAttribute * const attr, int mpvalue)
{
/* normalize to attribute value range */
int r = attr->max_value - attr->min_value;
if (r == 0)
return INT_MIN; // assume INT_MIN is outside allowed min/max range
return ((mpvalue + 100) * r + 100) / 200 + attr->min_value;
}
static int get_equalizer(struct priv *p, const char *name, int *value)
{
VADisplayAttribute * const attr = get_display_attribute(p, name);
int index = get_display_attribute(p, name);
if (index < 0)
return VO_NOTIMPL;
if (!attr || !(attr->flags & VA_DISPLAY_ATTRIB_GETTABLE))
VADisplayAttribute *attr = &p->va_display_attrs[index];
if (!(attr->flags & VA_DISPLAY_ATTRIB_GETTABLE))
return VO_NOTIMPL;
/* normalize to -100 .. 100 range */
int r = attr->max_value - attr->min_value;
if (r == 0)
return VO_NOTIMPL;
*value = ((attr->value - attr->min_value) * 200) / r - 100;
*value = ((attr->value - attr->min_value) * 200 + r / 2) / r - 100;
if (mp_eq_to_va(attr, p->mp_display_attr[index]) == attr->value)
*value = p->mp_display_attr[index];
return VO_TRUE;
}
static int set_equalizer(struct priv *p, const char *name, int value)
{
VADisplayAttribute * const attr = get_display_attribute(p, name);
VAStatus status;
if (!attr || !(attr->flags & VA_DISPLAY_ATTRIB_SETTABLE))
int index = get_display_attribute(p, name);
if (index < 0)
return VO_NOTIMPL;
/* normalize to attribute value range */
int r = attr->max_value - attr->min_value;
if (r == 0)
VADisplayAttribute *attr = &p->va_display_attrs[index];
if (!(attr->flags & VA_DISPLAY_ATTRIB_SETTABLE))
return VO_NOTIMPL;
attr->value = ((value + 100) * r) / 200 + attr->min_value;
int r = mp_eq_to_va(attr, value);
if (r == INT_MIN)
return VO_NOTIMPL;
attr->value = r;
p->mp_display_attr[index] = value;
MP_VERBOSE(p, "Changing '%s' (range [%d, %d]) to %d\n", name,
attr->max_value, attr->min_value, attr->value);
va_lock(p->mpvaapi);
status = vaSetDisplayAttributes(p->display, attr, 1);
@@ -642,6 +668,7 @@ static int preinit(struct vo *vo)
&p->va_num_display_attrs);
if (!CHECK_VA_STATUS(p, "vaQueryDisplayAttributes()"))
p->va_num_display_attrs = 0;
p->mp_display_attr = talloc_zero_array(vo, int, p->va_num_display_attrs);
}
return 0;
+2
View File
@@ -382,6 +382,8 @@ static void xv_draw_colorkey(struct vo *vo, const struct mp_rect *rc)
if (ctx->xv_ck_info.method == CK_METHOD_MANUALFILL ||
ctx->xv_ck_info.method == CK_METHOD_BACKGROUND)
{
if (!x11->vo_gc)
return;
//less tearing than XClearWindow()
XSetForeground(x11->display, x11->vo_gc, ctx->xv_colorkey);
XFillRectangle(x11->display, x11->window, x11->vo_gc, rc->x0, rc->y0,
+10 -17
View File
@@ -98,6 +98,9 @@ struct vo_w32_state {
int mouse_x;
int mouse_y;
// Should SetCursor be called when handling VOCTRL_SET_CURSOR_VISIBILITY?
bool can_set_cursor;
// UTF-16 decoding state for WM_CHAR and VK_PACKET
int high_surrogate;
@@ -312,16 +315,9 @@ static void subtract_window_borders(HWND hwnd, RECT *rc)
rc->bottom -= b.bottom;
}
static bool is_maximized(struct vo_w32_state *w32)
{
WINDOWPLACEMENT wp = { .length = sizeof(WINDOWPLACEMENT) };
GetWindowPlacement(w32->window, &wp);
return wp.showCmd == SW_SHOWMAXIMIZED;
}
static LRESULT borderless_nchittest(struct vo_w32_state *w32, int x, int y)
{
if (is_maximized(w32))
if (IsMaximized(w32->window))
return HTCLIENT;
POINT mouse = { x, y };
@@ -403,7 +399,7 @@ static int mod_state(struct vo_w32_state *w32)
static int decode_surrogate_pair(wchar_t lead, wchar_t trail)
{
return 0x10000 + ((lead & 0x3ff) << 10) | (trail & 0x3ff);
return 0x10000 + (((lead & 0x3ff) << 10) | (trail & 0x3ff));
}
static int decode_utf16(struct vo_w32_state *w32, wchar_t c)
@@ -686,7 +682,10 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
mp_input_put_key(w32->input_ctx, MP_INPUT_RELEASE_ALL);
break;
case WM_SETCURSOR:
if (LOWORD(lParam) == HTCLIENT && !w32->cursor_visible) {
// The cursor should only be hidden if the mouse is in the client area
// and if the window isn't in menu mode (HIWORD(lParam) is non-zero)
w32->can_set_cursor = LOWORD(lParam) == HTCLIENT && HIWORD(lParam);
if (w32->can_set_cursor && !w32->cursor_visible) {
SetCursor(NULL);
return TRUE;
}
@@ -1206,12 +1205,6 @@ fail:
return 0;
}
static bool vo_w32_is_cursor_in_client(struct vo_w32_state *w32)
{
DWORD pos = GetMessagePos();
return SendMessage(w32->window, WM_NCHITTEST, 0, pos) == HTCLIENT;
}
static int gui_thread_control(struct vo_w32_state *w32, int request, void *arg)
{
switch (request) {
@@ -1257,7 +1250,7 @@ static int gui_thread_control(struct vo_w32_state *w32, int request, void *arg)
case VOCTRL_SET_CURSOR_VISIBILITY:
w32->cursor_visible = *(bool *)arg;
if (vo_w32_is_cursor_in_client(w32)) {
if (w32->can_set_cursor && w32->tracking) {
if (w32->cursor_visible)
SetCursor(LoadCursor(NULL, IDC_ARROW));
else
+6
View File
@@ -931,6 +931,8 @@ int vo_x11_check_events(struct vo *vo)
x11->win_drag_button1_down = false;
break;
case LeaveNotify:
if (Event.xcrossing.mode != NotifyNormal)
break;
x11->win_drag_button1_down = false;
mp_input_put_key(vo->input_ctx, MP_KEY_MOUSE_LEAVE);
break;
@@ -1672,6 +1674,7 @@ int vo_x11_control(struct vo *vo, int *events, int request, void *arg)
case VOCTRL_GET_WIN_STATE: {
if (!x11->pseudo_mapped)
return VO_FALSE;
*(int *)arg = 0;
int num_elems;
long *elems = x11_get_property(x11, x11->window, XA(x11, _NET_WM_STATE),
XA_ATOM, 32, &num_elems);
@@ -1700,6 +1703,8 @@ int vo_x11_control(struct vo *vo, int *events, int request, void *arg)
return VO_TRUE;
}
case VOCTRL_GET_ICC_PROFILE: {
if (!x11->pseudo_mapped)
return VO_NOTAVAIL;
int screen = 0; // xinerama screen number
for (int n = 0; n < x11->num_displays; n++) {
struct xrandr_display *disp = &x11->displays[n];
@@ -1714,6 +1719,7 @@ int vo_x11_control(struct vo *vo, int *events, int request, void *arg)
mp_snprintf_cat(prop, sizeof(prop), "_%d", screen);
x11->icc_profile_property = XAs(x11, prop);
int len;
MP_VERBOSE(x11, "Retrieving ICC profile for display: %d\n", screen);
void *icc = x11_get_property(x11, x11->rootwin, x11->icc_profile_property,
XA_CARDINAL, 8, &len);
if (!icc)
+9 -3
View File
@@ -238,9 +238,11 @@ int mp_sws_reinit(struct mp_sws_context *ctx)
// This can fail even with normal operation, e.g. if a conversion path
// simply does not support these settings.
sws_setColorspaceDetails(ctx->sws, sws_getCoefficients(s_csp), s_range,
sws_getCoefficients(d_csp), d_range,
ctx->brightness, ctx->contrast, ctx->saturation);
int r =
sws_setColorspaceDetails(ctx->sws, sws_getCoefficients(s_csp), s_range,
sws_getCoefficients(d_csp), d_range,
ctx->brightness, ctx->contrast, ctx->saturation);
ctx->supports_csp = r >= 0;
if (sws_init_context(ctx->sws, ctx->src_filter, ctx->dst_filter) < 0)
return -1;
@@ -294,6 +296,8 @@ int mp_image_sw_blur_scale(struct mp_image *dst, struct mp_image *src,
int mp_sws_get_vf_equalizer(struct mp_sws_context *sws, struct vf_seteq *eq)
{
if (!sws->supports_csp)
return 0;
if (!strcmp(eq->item, "brightness"))
eq->value = ((sws->brightness * 100) + (1 << 15)) >> 16;
else if (!strcmp(eq->item, "contrast"))
@@ -307,6 +311,8 @@ int mp_sws_get_vf_equalizer(struct mp_sws_context *sws, struct vf_seteq *eq)
int mp_sws_set_vf_equalizer(struct mp_sws_context *sws, struct vf_seteq *eq)
{
if (!sws->supports_csp)
return 0;
if (!strcmp(eq->item, "brightness"))
sws->brightness = ((eq->value << 16) + 50) / 100;
else if (!strcmp(eq->item, "contrast"))
+1
View File
@@ -44,6 +44,7 @@ struct mp_sws_context {
// Cached context (if any)
struct SwsContext *sws;
bool supports_csp;
// Contains parameters for which sws is valid
struct mp_sws_context *cached;
+2 -2
View File
@@ -109,7 +109,7 @@ def check_pkg_config(*args, **kw_ext):
return result
return fn
def check_headers(*headers):
def check_headers(*headers, **kw_ext):
def undef_others(ctx, headers, found):
not_found_hs = set(headers) - set([found])
for not_found_h in not_found_hs:
@@ -119,7 +119,7 @@ def check_headers(*headers):
def fn(ctx, dependency_identifier):
for header in headers:
defaults = {'header_name': header, 'features': 'c cprogram'}
options = __merge_options__(dependency_identifier, defaults)
options = __merge_options__(dependency_identifier, defaults, kw_ext)
if ctx.check(**options):
undef_others(ctx, headers, header)
defkey = DependencyInflector(dependency_identifier).define_key()
+6 -3
View File
@@ -84,6 +84,7 @@ build_options = [
'name': '--test',
'desc': 'test suite (using cmocka)',
'func': check_pkg_config('cmocka >= 0.4.1'),
'default': 'disable',
}, {
'name': '--clang-database',
'desc': 'generate a clang compilation database',
@@ -691,7 +692,7 @@ hwaccel_features = [
'name': '--vaapi-hwaccel',
'desc': 'libavcodec VAAPI hwaccel',
'deps': [ 'vaapi' ],
'func': check_true,
'func': check_headers('libavcodec/vaapi.h', use='libav'),
} , {
'name': '--vda-hwaccel',
'desc': 'libavcodec VDA hwaccel',
@@ -710,12 +711,14 @@ hwaccel_features = [
'name': '--vdpau-hwaccel',
'desc': 'libavcodec VDPAU hwaccel',
'deps': [ 'vdpau' ],
'func': check_true,
'func': check_statement('libavcodec/vdpau.h',
'av_vdpau_alloc_context()',
use='libav'),
}, {
'name': '--dxva2-hwaccel',
'desc': 'libavcodec DXVA2 hwaccel',
'deps': [ 'gdi' ],
'func': check_true,
'func': check_headers('libavcodec/dxva2.h', use='libav'),
}
]