Compare commits

..
26 Commits
Author SHA1 Message Date
wm4 d276f753f7 Release 0.3.3 2014-01-15 21:03:02 +01:00
Grzegorz Blach c06000eef8 Detect Lua on FreeBSD 2014-01-15 20:57:17 +01:00
wm4 1bc1cd2305 player: avoid stalling when starting a network stream
Starting a network stream could stall by executing uncacheable stream
control requests (STREAM_CTRL_GET_LANG and STREAM_CTRL_GET_DVD_INFO).
Being uncacheable means the player has to wait until the cache is done
reading the current block of data. These requests can't be cached
because they're too complicated, so the only way to avoid them is
special casing the DVD and Bluray streams (which are the only things
which need these requests), and not doing them in other cases.

(This is kind of inelegant, but so is the rest of the DVD/BD code.)
2014-01-15 20:57:09 +01:00
wm4 a735a2abd7 demux_mkv: improve robustness by explicitly checking for level 1 elements
Matroska makes it pretty hard to resync correctly on broken files:
random data returns "valid" EBML IDs with a high probability, and when
trying to skip them it's likely that you skip a random amount of data
(instead of considering the element length invalid).

Improve upon this by skipping known level 1 elements only. Consider
everything else invalid and call the resync code. This might result in
annoying behavior when Matroska adds new level 1 elements, although it
won't be particularly harmful. Matroska doesn't really allow us to do
better (even mkvtoolnix explicitly checks for known level 1 elements).

Since we now don't always want to combine EBML element skipping and
resyncing, remove ebml_read_skip_or_resync_cluster(), and make
ebml_read_skip() more tolerant against skipping broken elements.

Also, don't resync when reading sub-elements, and instead do resyncing
when reading them results in an error.
2014-01-15 20:56:16 +01:00
wm4 112c1abe31 demux_mkv: avoid skipping too much data in corrupted files
Until now, corrupted files were detected if the size of an element (that
should be skipped) was larger than the remaining file. This still could
skip larger regions of the file itself if the broken size happened to be
within the file.

Change it so that it's never allowed to skip outside the parent's
element.
2014-01-15 20:56:13 +01:00
wm4 362b35b631 manpage: document --term-osd=force
Apparently this was forgotten when it was first added, or maybe it's an
arrifact from the rst conversion.

Conflicts:
	DOCS/man/en/options.rst
2014-01-15 20:54:32 +01:00
wm4 49cf0af294 player: don't block terminal OSD while seeking
Seeking usually show the status on OSD. In terminal OSD mode, no status
is shown, because there is already a separate status line.
Unfortunately, the mechanism for showing the status was still active,
which forced showing no message while the code for showing seek status
was active.
2014-01-15 20:53:44 +01:00
wm4 1b26874710 player: mention subtitles in av_desync_help_text
Insane .ass subtitle scripts can cause severe slowdown (depending on the
speed of the machine, or the insanity of the script), so mention how to
test without subtitles. This is mainly to make the user aware that
subtitle rendering can be a problem. For longwinded explanation, there
isn't enough space.
2014-01-15 20:53:41 +01:00
Stefano Pigozzi 8fe636da7a cocoa: fix window placement on secondary screens
For a long time the cocoa backend set the xinerama_x/y and used dx/dy from the
VO instance. This somewhat worked with some workarounds but wasn't really
what was supposed to be happening. Moreover 27e4360, which touched this
workaround introduced a regression.

New code doesn't set the xinerama_x/y values so that dx/dy are offsets in the
current screen (not a virtual screen composed of all the screens). The screen
reference detected during VOCTRL_UPDATE_SCREENINFO is also passed down to the
window initialization code.

Fixes #472
2014-01-15 20:53:19 +01:00
Stefano Pigozzi 812f149585 cocoa: refactor init window positioning code 2014-01-15 20:53:14 +01:00
wm4 635424c8f0 demux_lavf: add hack for MicroDVD for assuming frame based timing
MicroDVD files _can_ contain real timestamps instead of frame timestamps
if they declare a FPS. But this seems to be rare, so ignore that if the
FPS happens to match with the libavformat microdvd parser's default FPS.

This might actually break files that declare 23.976 FPS, but the video
file is not 23.976 FPS, but the chance that this happens is probably
very low, and the commit fixes the more common breakage with 25 FPS
video.
2014-01-15 20:51:50 +01:00
wm4 2319918721 sub: fix frame based subtitle timestamp handling
Subtitle formats with frame based timing require using the video FPS to
compute proper subtitle timestamps. But it looks like the calculation to
do that was inversed.
2014-01-15 20:51:47 +01:00
Alexander Preisinger 9fabf85a44 wayland: properly empty output list 2014-01-15 20:51:39 +01:00
Alexander Preisinger 54fd5d0979 wayland/shm: don't crash if initialization failed 2014-01-15 20:51:37 +01:00
wm4 d141d281ca wayland: fix crash when initialization fails
On X11, if no wayland compositor is running, wl_list_init() will never
be called. This will cause destroy_display() to segfault when trying to
iterate over the list.
2014-01-15 20:51:32 +01:00
Alexander Preisinger ebc3d74b04 wayland/shm: tone down warnings
Those warnings are printed far too often and actually aren't usefull at all.
2014-01-15 20:51:19 +01:00
Alexander Preisinger a63fab8921 wayland: fix memory leaks
There are still some leaks from wayland-cursor stuff, but there is no way to
free the memory as user of the cursor library.

Conflicts:
	video/out/wayland_common.c
2014-01-15 20:50:52 +01:00
wm4 4ee8d8d3f9 player: fix setting smaller timeout on Windows systems
On Windows, we don't have proper input event wakeup handling, so we
need to lower the playloop timeout in order to react fast to input.

Closes #387.
2014-01-15 20:50:02 +01:00
Alexander Preisinger 574a2484c1 wayland: cleanup registry_handle_global
The wl_registry object is already passed as a parameter. No need to create
a temporary variable.
2014-01-15 20:49:57 +01:00
Alexander Preisinger f5b92bee5e wayland: remove set_user_data from seat_listener
The user_data is passed on add_listener and can later be changed with
set_user_data. But because we don't want to change it later and because it is
the same object remove the set_user_data call.

This might be a copy&paste leftover from the initial draft for the wayland
backend.
2014-01-15 20:49:55 +01:00
Alexander Preisinger ca3d7144db wayland: use static consistently
Declare everything that is only needed inside wayland_common.c as static.
2014-01-15 20:49:52 +01:00
wm4 86e7c3defb terminal: don't initialize termcap etc. if stdout is not a terminal
Otherwise, it seems one of the term* libraries will write escape
sequences to stdout, for whatever reason.
2014-01-15 20:49:42 +01:00
Alexander Preisinger 0fe1385d80 wayland: fix fullscreen & resizing for good
I added enough logic to never set ontop or fullscreen twitce.
This commit keeps also the size of the video if multiple videos are played.
If the ratio differs the width will be kept at the same size and only the
height changes.
2014-01-15 20:49:32 +01:00
wm4 f4e9371d0f manpage: mention how to get a list of codecs for use with --hwdec-codecs 2014-01-15 20:49:26 +01:00
wm4 909185d49e wayland: silence annoying libwayland-client message
libwayland-client contains the following code [1]:

	runtime_dir = getenv("XDG_RUNTIME_DIR");
	if (!runtime_dir) {
		fprintf(stderr,
			"error: XDG_RUNTIME_DIR not set in the environment.\n");

This means this message will unconditionally and unavoidably be printed
if XDG_RUNTIME_DIR is not set. Since mpv is a terminal program, and we
want to avoid unnecessary output, work it around by not attempting to
use wayland if this environment variable is not set.

[1] http://cgit.freedesktop.org/wayland/wayland/tree/src/wayland-client.c#n636
    (cd0dccd01e16fa404e03974d30ded3aebdb1c4bc)
2014-01-15 20:49:22 +01:00
wm4 c18c324c6f wayland: fix some memory leaks on initialization failure
This commonly happens when initializing vo_opengl on a X11-only system.

Unfortunately, most wl_*_destroy() functions appear not to accept NULL
pointers, making partial deinitialization a pain: you have to add your
own NULL checks everywhere to avoid crashes.

xkb.context is uninitialized separately, because you can initialize it
just fine, even if the rest of input initialization fails.
2014-01-15 20:49:19 +01:00
20 changed files with 183 additions and 101 deletions

No files matched your search

+6 -1
View File
@@ -1142,6 +1142,9 @@ OPTIONS
Allow hardware decoding for a given list of codecs only. The special value
``all`` always allows all codecs.
You can get the list of allowed codecs with ``mpv --vd=help``. Remove the
prefix, e.g. instead of ``lavc:h264`` use ``h264``.
By default this is set to ``h264,vc1,wmv3``.
This is usually only needed with broken GPUs, where a codec is reported
@@ -2366,7 +2369,7 @@ OPTIONS
Some ``--sws`` options are tunable. The description of the ``scale``
video filter has further information.
``--term-osd, --no-term-osd``
``--term-osd, --no-term-osd``, ``--term-osd=force``
Display OSD messages on the console when no video output is available.
Enabled by default.
@@ -2375,6 +2378,8 @@ OPTIONS
console. The escape sequence should move the pointer to the beginning of
the line used for the OSD and clear it (default: ``^[[A\r^[[K``).
``force`` enables terminal OSD even if a video window is created.
``--title=<string>``
Set the window title. Properties are expanded on playback start.
(See `Property Expansion`_.)
+1 -1
View File
@@ -1 +1 @@
0.3.2
0.3.3
+6
View File
@@ -458,6 +458,12 @@ static void handle_stream(demuxer_t *demuxer, int i)
memcpy(sh_sub->extradata, codec->extradata, codec->extradata_size);
sh_sub->extradata_len = codec->extradata_size;
}
// Hack for MicroDVD: if time_base matches the ffmpeg microdvd reader's
// default FPS (23.976), assume the MicroDVD file did not declare a
// FPS, and the MicroDVD file uses frame based timing.
if (codec->time_base.num == 125 && codec->time_base.den == 2997)
sh_sub->frame_based = true;
break;
}
case AVMEDIA_TYPE_ATTACHMENT: {
+18 -9
View File
@@ -723,7 +723,7 @@ static int demux_mkv_read_cues(demuxer_t *demuxer)
stream_t *s = demuxer->stream;
if (opts->index_mode == 0 || opts->index_mode == 2) {
ebml_read_skip(s, NULL);
ebml_read_skip(demuxer->log, -1, s);
return 0;
}
@@ -1128,7 +1128,7 @@ static int read_header_element(struct demuxer *demuxer, uint32_t id,
res = 2;
}
if (!at_filepos && id != EBML_ID_INVALID)
ebml_read_skip(s, NULL);
ebml_read_skip(demuxer->log, -1, s);
return res;
}
@@ -2270,7 +2270,7 @@ static void index_block(demuxer_t *demuxer, struct block_info *block)
}
}
static int read_block(demuxer_t *demuxer, struct block_info *block)
static int read_block(demuxer_t *demuxer, int64_t end, struct block_info *block)
{
mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv;
stream_t *s = demuxer->stream;
@@ -2281,7 +2281,7 @@ static int read_block(demuxer_t *demuxer, struct block_info *block)
free_block(block);
length = ebml_read_length(s, NULL);
if (length > 500000000)
if (length > 500000000 || stream_tell(s) + length > (uint64_t)end)
goto exit;
block->alloc = malloc(length + AV_LZO_INPUT_PADDING);
if (!block->alloc)
@@ -2442,7 +2442,7 @@ static int read_block_group(demuxer_t *demuxer, int64_t end,
break;
case MATROSKA_ID_BLOCK:
if (read_block(demuxer, block) < 0)
if (read_block(demuxer, end, block) < 0)
goto error;
break;
@@ -2454,11 +2454,12 @@ static int read_block_group(demuxer_t *demuxer, int64_t end,
block->keyframe = false;
break;
case MATROSKA_ID_CLUSTER:
case EBML_ID_INVALID:
goto error;
default:
if (ebml_read_skip_or_resync_cluster(demuxer->log, s, NULL) != 0)
if (ebml_read_skip(demuxer->log, end, s) != 0)
goto error;
break;
}
@@ -2491,6 +2492,8 @@ static int read_next_block(demuxer_t *demuxer, struct block_info *block)
case MATROSKA_ID_BLOCKGROUP: {
int64_t end = ebml_read_length(s, NULL);
end += stream_tell(s);
if (end > mkv_d->cluster_end)
goto find_next_cluster;
int res = read_block_group(demuxer, end, block);
if (res < 0)
goto find_next_cluster;
@@ -2501,7 +2504,7 @@ static int read_next_block(demuxer_t *demuxer, struct block_info *block)
case MATROSKA_ID_SIMPLEBLOCK: {
*block = (struct block_info){ .simple = true };
int res = read_block(demuxer, block);
int res = read_block(demuxer, mkv_d->cluster_end, block);
if (res < 0)
goto find_next_cluster;
if (res > 0)
@@ -2517,7 +2520,7 @@ static int read_next_block(demuxer_t *demuxer, struct block_info *block)
goto find_next_cluster;
default: ;
if (ebml_read_skip_or_resync_cluster(demuxer->log, s, NULL) != 0)
if (ebml_read_skip(demuxer->log, mkv_d->cluster_end, s) != 0)
goto find_next_cluster;
break;
}
@@ -2532,7 +2535,13 @@ static int read_next_block(demuxer_t *demuxer, struct block_info *block)
break;
if (s->eof)
return -1;
ebml_read_skip_or_resync_cluster(demuxer->log, s, NULL);
// For the sake of robustness, consider even unknown level 1
// elements the same as unknown/broken IDs.
if (!ebml_is_mkv_level1_id(id) ||
ebml_read_skip(demuxer->log, -1, s) != 0)
{
ebml_resync_cluster(demuxer->log, s);
}
}
next_cluster:
mkv_d->cluster_end = ebml_read_length(s, NULL);
+36 -36
View File
@@ -41,6 +41,26 @@
#define SIZE_MAX ((size_t)-1)
#endif
// Whether the id is a known Matroska level 1 element (allowed as element on
// global file level, after the level 0 MATROSKA_ID_SEGMENT).
// This (intentionally) doesn't include "global" elements.
bool ebml_is_mkv_level1_id(uint32_t id)
{
switch (id) {
case MATROSKA_ID_SEEKHEAD:
case MATROSKA_ID_INFO:
case MATROSKA_ID_CLUSTER:
case MATROSKA_ID_TRACKS:
case MATROSKA_ID_CUES:
case MATROSKA_ID_ATTACHMENTS:
case MATROSKA_ID_CHAPTERS:
case MATROSKA_ID_TAGS:
return true;
default:
return false;
}
}
/*
* Read: the element content data ID.
* Return: the ID.
@@ -252,21 +272,32 @@ char *ebml_read_utf8(stream_t *s, uint64_t *length)
/*
* Skip the current element.
* end: the end of the parent element or -1 (for robust error handling)
*/
int ebml_read_skip(stream_t *s, uint64_t *length)
int ebml_read_skip(struct mp_log *log, int64_t end, stream_t *s)
{
uint64_t len;
int l;
int64_t pos = stream_tell(s);
len = ebml_read_length(s, &l);
if (len == EBML_UINT_INVALID)
return 1;
if (length)
*length = len + l;
goto invalid;
stream_skip(s, len);
int64_t pos2 = stream_tell(s);
if (len >= INT64_MAX - pos2 || (end > 0 && pos2 + len > end))
goto invalid;
if (!stream_skip(s, len))
goto invalid;
return 0;
invalid:
mp_err(log, "Invalid EBML length at position %"PRId64"\n", pos);
stream_seek(s, pos);
return 1;
}
/*
@@ -291,37 +322,6 @@ int ebml_resync_cluster(struct mp_log *log, stream_t *s)
return -1;
}
/*
* Skip the current element, or on error, call ebml_resync_cluster().
*/
int ebml_read_skip_or_resync_cluster(struct mp_log *log, stream_t *s,
uint64_t *length)
{
uint64_t len;
int l;
len = ebml_read_length(s, &l);
if (len == EBML_UINT_INVALID)
goto resync;
if (length)
*length = len + l;
int64_t pos = stream_tell(s);
// When reading corrupted elements, len will often be a random high number,
// and stream_skip() will fail when skipping past EOF.
if (!stream_skip(s, len)) {
stream_seek(s, pos);
goto resync;
}
return 0;
resync:
return ebml_resync_cluster(log, s) < 0 ? -1 : 1;
}
/*
* Read the next element, but only the header. The contents
* are supposed to be sub-elements which can be read separately.
+2 -3
View File
@@ -92,6 +92,7 @@ struct ebml_parse_ctx {
#define EBML_FLOAT_INVALID -1000000000.0
bool ebml_is_mkv_level1_id(uint32_t id);
uint32_t ebml_read_id (stream_t *s, int *length);
uint64_t ebml_read_vlen_uint (bstr *buffer);
int64_t ebml_read_vlen_int (bstr *buffer);
@@ -101,9 +102,7 @@ int64_t ebml_read_int (stream_t *s, uint64_t *length);
double ebml_read_float (stream_t *s, uint64_t *length);
char *ebml_read_ascii (stream_t *s, uint64_t *length);
char *ebml_read_utf8 (stream_t *s, uint64_t *length);
int ebml_read_skip (stream_t *s, uint64_t *length);
int ebml_read_skip_or_resync_cluster(struct mp_log *log, stream_t *s,
uint64_t *length);
int ebml_read_skip(struct mp_log *log, int64_t end, stream_t *s);
int ebml_resync_cluster(struct mp_log *log, stream_t *s);
uint32_t ebml_read_master (stream_t *s, uint64_t *length);
+6 -2
View File
@@ -47,6 +47,8 @@
#include "input/keycodes.h"
#include "terminal.h"
static int use_terminal;
#if HAVE_TERMIOS
static volatile struct termios tio_orig;
static volatile int tio_orig_set;
@@ -454,7 +456,7 @@ static volatile int getch2_enabled = 0;
static void do_activate_getch2(void)
{
if (getch2_active)
if (getch2_active || !use_terminal)
return;
#if HAVE_TERMINFO || HAVE_TERMCAP
@@ -612,6 +614,8 @@ void terminal_setup_stdin_cmd_input(struct input_ctx *ictx)
int terminal_init(void)
{
load_termcap(NULL);
use_terminal = isatty(1);
if (use_terminal)
load_termcap(NULL);
return 0;
}
+7 -2
View File
@@ -443,13 +443,16 @@ static struct track *add_stream_track(struct MPContext *mpctx,
track->preloaded = !!stream->sub->track;
// Needed for DVD and Blu-ray.
if (!track->lang) {
struct stream *st = track->demuxer->stream;
if (!track->lang && (st->uncached_type == STREAMTYPE_BLURAY ||
st->uncached_type == STREAMTYPE_DVD))
{
struct stream_lang_req req = {
.type = track->type,
.id = map_id_from_demuxer(track->demuxer, track->type,
track->demuxer_id)
};
stream_control(track->demuxer->stream, STREAM_CTRL_GET_LANG, &req);
stream_control(st, STREAM_CTRL_GET_LANG, &req);
if (req.name[0])
track->lang = talloc_strdup(track, req.name);
}
@@ -472,6 +475,8 @@ static void add_dvd_tracks(struct MPContext *mpctx)
struct demuxer *demuxer = mpctx->demuxer;
struct stream *stream = demuxer->stream;
struct stream_dvd_info_req info;
if (stream->uncached_type != STREAMTYPE_DVD)
return;
if (stream_control(stream, STREAM_CTRL_GET_DVD_INFO, &info) > 0) {
for (int n = 0; n < info.num_subs; n++) {
struct track *track = talloc_ptrtype(NULL, track);
+6 -3
View File
@@ -435,9 +435,12 @@ static void add_seek_osd_messages(struct MPContext *mpctx)
set_osd_bar_chapters(mpctx, OSD_BAR_SEEK);
}
if (mpctx->add_osd_seek_info & OSD_SEEK_INFO_TEXT) {
mp_osd_msg_t *msg = add_osd_msg(mpctx, OSD_MSG_TEXT, 1,
mpctx->opts->osd_duration);
msg->show_position = true;
// Never in term-osd mode
if (mpctx->video_out && mpctx->opts->term_osd != 1) {
mp_osd_msg_t *msg = add_osd_msg(mpctx, OSD_MSG_TEXT, 1,
mpctx->opts->osd_duration);
msg->show_position = true;
}
}
if (mpctx->add_osd_seek_info & OSD_SEEK_INFO_CHAPTER_TEXT) {
char *chapter = chapter_display_name(mpctx, get_current_chapter(mpctx));
+3 -3
View File
@@ -71,8 +71,8 @@ static const char av_desync_help_text[] =
" This is due to vsync limiting the framerate.\n"
"- Playing from a slow network source.\n"
" Download the file instead.\n"
"- Try to find out whether audio or video is causing this by experimenting\n"
" with --no-video and --no-audio.\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 swiched audio or video tracks, try seeking to force synchronization.\n"
"If none of this helps you, file a bug report.\n\n";
@@ -924,7 +924,7 @@ static double get_wakeup_period(struct MPContext *mpctx)
*/
double sleeptime = WAKEUP_PERIOD;
#ifndef HAVE_POSIX_SELECT
#if !HAVE_POSIX_SELECT
// No proper file descriptor event handling; keep waking up to poll input
sleeptime = MPMIN(sleeptime, 0.02);
#endif
+1
View File
@@ -35,6 +35,7 @@ enum streamtype {
STREAMTYPE_RADIO,
STREAMTYPE_DVB,
STREAMTYPE_DVD,
STREAMTYPE_BLURAY,
STREAMTYPE_PVR,
STREAMTYPE_TV,
STREAMTYPE_MF,
+1
View File
@@ -390,6 +390,7 @@ err_no_info:
b->current_angle = angle;
b->current_title = title;
s->type = STREAMTYPE_BLURAY;
s->end_pos = title_size;
s->sector_size = BLURAY_SECTOR_SIZE;
s->flags = MP_STREAM_SEEK;
+1 -1
View File
@@ -420,7 +420,7 @@ bool sub_read_all_packets(struct dec_sub *sub, struct sh_stream *sh)
// 23.976 FPS is used as default timebase for frame based formats
if (sub->video_fps && sh->sub->frame_based)
sub_speed *= sub->video_fps / 23.976;
sub_speed *= 23.976 / sub->video_fps;
if (opts->sub_fps && sub->video_fps)
sub_speed *= opts->sub_fps / sub->video_fps;
+3 -5
View File
@@ -221,8 +221,6 @@ static void vo_cocoa_update_screen_info(struct vo *vo)
aspect_save_screenres(vo, r.size.width, r.size.height);
opts->screenwidth = r.size.width;
opts->screenheight = r.size.height;
vo->xinerama_x = r.origin.x;
vo->xinerama_y = r.origin.y;
}
static void resize_window(struct vo *vo)
@@ -262,7 +260,7 @@ static void create_window(struct vo *vo, uint32_t d_width, uint32_t d_height,
struct vo_cocoa_state *s = vo->cocoa;
struct mp_vo_opts *opts = vo->opts;
const NSRect contentRect = NSMakeRect(0, 0, d_width, d_height);
const NSRect contentRect = NSMakeRect(vo->dx, vo->dy, d_width, d_height);
int window_mask = 0;
if (opts->border) {
@@ -276,7 +274,8 @@ static void create_window(struct vo *vo, uint32_t d_width, uint32_t d_height,
[[MpvVideoWindow alloc] initWithContentRect:contentRect
styleMask:window_mask
backing:NSBackingStoreBuffered
defer:NO];
defer:NO
screen:s->current_screen];
s->view = [[[MpvVideoView alloc] initWithFrame:contentRect] autorelease];
[s->view setWantsBestResolutionOpenGLSurface:YES];
@@ -299,7 +298,6 @@ static void create_window(struct vo *vo, uint32_t d_width, uint32_t d_height,
[s->window setDelegate:s->window];
[s->window makeMainWindow];
[s->window setFrameOrigin:NSMakePoint(vo->dx, vo->dy)];
[s->window makeKeyAndOrderFront:nil];
[NSApp activateIgnoringOtherApps:YES];
+3 -2
View File
@@ -188,11 +188,12 @@ static void releaseGlContext_wayland(MPGLContext *ctx)
struct vo_wayland_state *wl = ctx->vo->wayland;
gl->Finish();
eglReleaseThread();
wl_egl_window_destroy(wl->egl_context.egl_window);
eglDestroySurface(wl->egl_context.egl.dpy, wl->egl_context.egl_surface);
eglMakeCurrent(wl->egl_context.egl.dpy, NULL, NULL, EGL_NO_CONTEXT);
eglDestroyContext(wl->egl_context.egl.dpy, wl->egl_context.egl.ctx);
eglTerminate(wl->egl_context.egl.dpy);
eglReleaseThread();
wl_egl_window_destroy(wl->egl_context.egl_window);
wl->egl_context.egl.ctx = NULL;
}
+9 -5
View File
@@ -539,7 +539,7 @@ static void draw_image(struct vo *vo, mp_image_t *mpi)
struct buffer *buf = buffer_get_back(p);
if (!buf) {
MP_WARN(p->wl, "can't draw, back buffer is busy\n");
MP_VERBOSE(p->wl, "can't draw, back buffer is busy\n");
return;
}
@@ -570,7 +570,7 @@ static void flip_page(struct vo *vo)
buffer_swap(p);
if (!p->redraw_callback) {
MP_INFO(p->wl, "restart frame callback\n");
MP_DBG(p->wl, "restart frame callback\n");
frame_handle_redraw(p, NULL, 0);
}
}
@@ -639,6 +639,9 @@ static int reconfig(struct vo *vo, struct mp_image_params *fmt, int flags)
vo_wayland_config(vo, vo->dwidth, vo->dheight, flags);
if (p->wl->window.events & VO_EVENT_RESIZE)
resize(p);
return 0;
}
@@ -648,6 +651,9 @@ static void uninit(struct vo *vo)
for (int i = 0; i < MAX_BUFFERS; ++i)
destroy_shm_buffer(&p->buffers[i]);
if (p->redraw_callback)
wl_callback_destroy(p->redraw_callback);
talloc_free(p->original_image);
vo_wayland_uninit(vo);
@@ -657,10 +663,8 @@ static int preinit(struct vo *vo)
{
struct priv *p = vo->priv;
if (!vo_wayland_init(vo)) {
MP_ERR(p->wl, "could not initalise backend\n");
if (!vo_wayland_init(vo))
return -1;
}
p->vo = vo;
p->wl = vo->wayland;
+67 -26
View File
@@ -144,7 +144,7 @@ static void display_handle_delete_id(void *data,
MP_DBG(wl, "Object %u deleted\n", id);
}
const struct wl_display_listener display_listener = {
static const struct wl_display_listener display_listener = {
display_handle_error,
display_handle_delete_id
};
@@ -171,7 +171,7 @@ static void ssurface_handle_popup_done(void *data,
{
}
const struct wl_shell_surface_listener shell_surface_listener = {
static const struct wl_shell_surface_listener shell_surface_listener = {
ssurface_handle_ping,
ssurface_handle_configure,
ssurface_handle_popup_done
@@ -220,7 +220,7 @@ static void output_handle_mode(void *data,
output->flags = flags;
}
const struct wl_output_listener output_listener = {
static const struct wl_output_listener output_listener = {
output_handle_geometry,
output_handle_mode
};
@@ -329,7 +329,7 @@ static void keyboard_handle_modifiers(void *data,
0, 0, group);
}
const struct wl_keyboard_listener keyboard_listener = {
static const struct wl_keyboard_listener keyboard_listener = {
keyboard_handle_keymap,
keyboard_handle_enter,
keyboard_handle_leave,
@@ -443,7 +443,6 @@ static void seat_handle_capabilities(void *data,
if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !wl->input.keyboard) {
wl->input.keyboard = wl_seat_get_keyboard(seat);
wl_keyboard_set_user_data(wl->input.keyboard, wl);
wl_keyboard_add_listener(wl->input.keyboard, &keyboard_listener, wl);
}
else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && wl->input.keyboard) {
@@ -452,7 +451,6 @@ static void seat_handle_capabilities(void *data,
}
if ((caps & WL_SEAT_CAPABILITY_POINTER) && !wl->input.pointer) {
wl->input.pointer = wl_seat_get_pointer(seat);
wl_pointer_set_user_data(wl->input.pointer, wl);
wl_pointer_add_listener(wl->input.pointer, &pointer_listener, wl);
}
else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && wl->input.pointer) {
@@ -466,13 +464,12 @@ static const struct wl_seat_listener seat_listener = {
};
static void registry_handle_global (void *data,
struct wl_registry *registry,
struct wl_registry *reg,
uint32_t id,
const char *interface,
uint32_t version)
{
struct vo_wayland_state *wl = data;
struct wl_registry *reg = wl->display.registry;
if (strcmp(interface, "wl_compositor") == 0) {
@@ -578,6 +575,8 @@ static void shedule_resize(struct vo_wayland_state *wl,
int32_t x, y;
float temp_aspect = width / (float) MPMAX(height, 1);
MP_DBG(wl, "shedule resize: %dx%d\n", width, height);
if (width < minimum_size)
width = minimum_size;
@@ -632,6 +631,9 @@ static void shedule_resize(struct vo_wayland_state *wl,
static bool create_display (struct vo_wayland_state *wl)
{
if (wl->vo->probing && !getenv("XDG_RUNTIME_DIR"))
return false;
wl->display.display = wl_display_connect(NULL);
if (!wl->display.display) {
@@ -644,7 +646,6 @@ static bool create_display (struct vo_wayland_state *wl)
wl_display_add_listener(wl->display.display, &display_listener, wl);
wl_list_init(&wl->display.output_list);
wl->display.registry = wl_display_get_registry(wl->display.display);
wl_registry_add_listener(wl->display.registry, &registry_listener, wl);
@@ -657,15 +658,33 @@ static bool create_display (struct vo_wayland_state *wl)
static void destroy_display (struct vo_wayland_state *wl)
{
struct vo_wayland_output *output = NULL;
struct vo_wayland_output *tmp = NULL;
wl_list_for_each_safe(output, tmp, &wl->display.output_list, link) {
if (output && output->output) {
wl_output_destroy(output->output);
output->output = NULL;
wl_list_remove(&output->link);
}
}
if (wl->display.shm)
wl_shm_destroy(wl->display.shm);
if (wl->display.shell)
wl_shell_destroy(wl->display.shell);
if (wl->display.compositor)
wl_compositor_destroy(wl->display.compositor);
wl_registry_destroy(wl->display.registry);
wl_display_flush(wl->display.display);
wl_display_disconnect(wl->display.display);
if (wl->display.registry)
wl_registry_destroy(wl->display.registry);
if (wl->display.display) {
wl_display_flush(wl->display.display);
wl_display_disconnect(wl->display.display);
}
}
static bool create_window (struct vo_wayland_state *wl)
@@ -690,8 +709,11 @@ static bool create_window (struct vo_wayland_state *wl)
static void destroy_window (struct vo_wayland_state *wl)
{
wl_shell_surface_destroy(wl->window.shell_surface);
wl_surface_destroy(wl->window.surface);
if (wl->window.shell_surface)
wl_shell_surface_destroy(wl->window.shell_surface);
if (wl->window.surface)
wl_surface_destroy(wl->window.surface);
}
static bool create_cursor (struct vo_wayland_state *wl)
@@ -740,9 +762,11 @@ static void destroy_input (struct vo_wayland_state *wl)
wl_keyboard_destroy(wl->input.keyboard);
xkb_map_unref(wl->input.xkb.keymap);
xkb_state_unref(wl->input.xkb.state);
xkb_context_unref(wl->input.xkb.context);
}
if (wl->input.xkb.context)
xkb_context_unref(wl->input.xkb.context);
if (wl->input.pointer)
wl_pointer_destroy(wl->input.pointer);
@@ -760,11 +784,14 @@ int vo_wayland_init (struct vo *vo)
wl->vo = vo;
wl->log = mp_log_new(wl, vo->log, "wayland");
wl_list_init(&wl->display.output_list);
if (!create_input(wl)
|| !create_display(wl)
|| !create_window(wl)
|| !create_cursor(wl))
{
vo_wayland_uninit(vo);
return false;
}
@@ -786,13 +813,11 @@ void vo_wayland_uninit (struct vo *vo)
static void vo_wayland_ontop (struct vo *vo)
{
MP_DBG(vo->wayland, "going ontop\n");
vo->opts->ontop = 0;
vo->opts->fullscreen = 1;
/* use the already existing code to leave fullscreen mode and go into
* toplevel mode */
vo_wayland_fullscreen(vo);
struct vo_wayland_state *wl = vo->wayland;
MP_DBG(wl, "going ontop\n");
vo->opts->ontop = 1;
wl_shell_surface_set_toplevel(wl->window.shell_surface);
shedule_resize(wl, 0, wl->window.width, wl->window.height);
}
static void vo_wayland_border (struct vo *vo)
@@ -918,6 +943,9 @@ static void vo_wayland_update_screeninfo (struct vo *vo)
}
}
wl->window.fs_width = opts->screenwidth;
wl->window.fs_height = opts->screenheight;
aspect_save_screenres(vo, opts->screenwidth, opts->screenheight);
}
@@ -979,13 +1007,26 @@ bool vo_wayland_config (struct vo *vo, uint32_t d_width,
{
struct vo_wayland_state *wl = vo->wayland;
wl->window.width = d_width;
wl->window.height = d_height;
wl->window.p_width = d_width;
wl->window.p_height = d_height;
wl->window.aspect = wl->window.width / (float) MPMAX(wl->window.height, 1);
wl->window.aspect = d_width / (float) MPMAX(d_height, 1);
vo_wayland_fullscreen(vo);
if (!(flags & VOFLAG_HIDDEN)) {
if (!wl->window.is_init) {
wl->window.width = d_width;
wl->window.height = d_height;
}
if (vo->opts->fullscreen) {
if (wl->window.is_fullscreen)
shedule_resize(wl, 0, wl->window.fs_width, wl->window.fs_height);
else
vo_wayland_fullscreen(vo);
}
else
vo_wayland_ontop(vo);
wl->window.is_init = true;
}
return true;
}
+4 -1
View File
@@ -80,7 +80,7 @@ struct vo_wayland_state {
} display;
struct {
int32_t width;
int32_t width; // current size of the window
int32_t height;
int32_t p_width; // previous sizes for leaving fullscreen
int32_t p_height;
@@ -90,7 +90,10 @@ struct vo_wayland_state {
int32_t sh_y;
float aspect;
bool is_init; // true if the window has a valid size
bool is_fullscreen; // don't keep aspect ratio in fullscreen mode
int32_t fs_width; // fullscreen sizes
int32_t fs_height;
struct wl_surface *surface;
int32_t mouse_x; // mouse position inside the surface
+2
View File
@@ -52,10 +52,12 @@ def check_lua(ctx, dependency_identifier):
lua_versions = [
( '51', 'lua >= 5.1.0 lua < 5.2.0'),
( '51deb', 'lua5.1 >= 5.1.0'), # debian
( '51fbsd', 'lua-5.1 >= 5.1.0'), # FreeBSD
( 'luajit', 'luajit >= 2.0.0' ),
# assume all our dependencies (libquvi in particular) link with 5.1
( '52', 'lua >= 5.2.0' ),
( '52deb', 'lua5.2 >= 5.2.0'), # debian
( '52fbsd', 'lua-5.2 >= 5.2.0'), # FreeBSD
]
if ctx.options.LUA_VER:
+1 -1
View File
@@ -766,7 +766,7 @@ def options(opt):
group.add_option('--lua',
type = 'string',
dest = 'LUA_VER',
help = "select Lua package which should be autodetected. Choices: 51 51deb 52 52deb luajit")
help = "select Lua package which should be autodetected. Choices: 51 51deb 51fbsd 52 52deb 52fbsd luajit")
@conf
def is_debug_build(ctx):