"XVideo hardware adaptor to use. By default, VLC will " \
"use the first functional adaptor.")
-#define SHM_TEXT N_("Use shared memory")
-#define SHM_LONGTEXT N_( \
- "Use shared memory to communicate between VLC and the X server.")
+#define FORMAT_TEXT N_("XVideo format id")
+#define FORMAT_LONGTEXT N_( \
+ "XVideo image format id to use. By default, VLC will " \
+ "try to use the best match for the video being played.")
static int Open (vlc_object_t *);
static void Close (vlc_object_t *);
set_description (N_("XVideo output (XCB)"))
set_category (CAT_VIDEO)
set_subcategory (SUBCAT_VIDEO_VOUT)
- set_capability ("vout display", 155)
+ set_capability ("vout display", 200)
set_callbacks (Open, Close)
- add_integer ("xvideo-adaptor", -1, NULL,
+ add_integer ("xvideo-adaptor", -1,
ADAPTOR_TEXT, ADAPTOR_LONGTEXT, true)
- add_bool ("x11-shm", true, NULL, SHM_TEXT, SHM_LONGTEXT, true)
- add_deprecated_alias ("xvideo-shm")
+ add_integer ("xvideo-format-id", 0,
+ FORMAT_TEXT, FORMAT_LONGTEXT, true)
+ add_obsolete_bool ("xvideo-shm") /* removed in 1.2.0 */
add_shortcut ("xcb-xv", "xv", "xvideo", "xid")
vlc_module_end ()
};
static picture_pool_t *Pool (vout_display_t *, unsigned);
-static void Display (vout_display_t *, picture_t *);
+static void Display (vout_display_t *, picture_t *, subpicture_t *subpicture);
static int Control (vout_display_t *, int, va_list);
static void Manage (vout_display_t *);
return ok;
}
-static vlc_fourcc_t ParseFormat (vout_display_t *vd,
+static vlc_fourcc_t ParseFormat (vlc_object_t *obj,
const xcb_xv_image_format_info_t *restrict f)
{
if (f->byte_order != ORDER && f->bpp != 8)
switch (f->num_planes)
{
case 1:
- switch (f->bpp)
+ switch (popcount (f->red_mask | f->green_mask | f->blue_mask))
{
- case 32:
- if (f->depth == 24)
- return VLC_CODEC_RGB32;
- if (f->depth == 32)
- return 0; /* ARGB -> VLC cannot do that currently */
- break;
case 24:
- if (f->depth == 24)
+ if (f->bpp == 32 && f->depth == 32)
+ return VLC_CODEC_RGBA;
+ if (f->bpp == 32 && f->depth == 24)
+ return VLC_CODEC_RGB32;
+ if (f->bpp == 24 && f->depth == 24)
return VLC_CODEC_RGB24;
break;
case 16:
- if (f->depth == 16)
+ if (f->bpp == 16 && f->depth == 16)
return VLC_CODEC_RGB16;
- if (f->depth == 15)
+ break;
+ case 15:
+ if (f->bpp == 16 && f->depth == 16)
+ return VLC_CODEC_RGBT;
+ if (f->bpp == 16 && f->depth == 15)
return VLC_CODEC_RGB15;
break;
+ case 12:
+ if (f->bpp == 16 && f->depth == 16)
+ return VLC_CODEC_RGBA16;
+ if (f->bpp == 16 && f->depth == 12)
+ return VLC_CODEC_RGB12;
case 8:
- if (f->depth == 8)
+ if (f->bpp == 8 && f->depth == 8)
return VLC_CODEC_RGB8;
break;
}
break;
}
- msg_Err (vd, "unknown XVideo RGB format %"PRIx32" (%.4s)",
+ msg_Err (obj, "unknown XVideo RGB format %"PRIx32" (%.4s)",
f->id, f->guid);
- msg_Dbg (vd, " %"PRIu8" planes, %"PRIu8" bits/pixel, "
+ msg_Dbg (obj, " %"PRIu8" planes, %"PRIu8" bits/pixel, "
"depth %"PRIu8, f->num_planes, f->bpp, f->depth);
break;
break;
}
bad:
- msg_Err (vd, "unknown XVideo YUV format %"PRIx32" (%.4s)", f->id,
+ msg_Err (obj, "unknown XVideo YUV format %"PRIx32" (%.4s)", f->id,
f->guid);
- msg_Dbg (vd, " %"PRIu8" planes, %"PRIu32" bits/pixel, "
+ msg_Dbg (obj, " %"PRIu8" planes, %"PRIu32" bits/pixel, "
"%"PRIu32"/%"PRIu32"/%"PRIu32" bits/sample", f->num_planes,
f->bpp, f->y_sample_bits, f->u_sample_bits, f->v_sample_bits);
- msg_Dbg (vd, " period: %"PRIu32"/%"PRIu32"/%"PRIu32"x"
+ msg_Dbg (obj, " period: %"PRIu32"/%"PRIu32"/%"PRIu32"x"
"%"PRIu32"/%"PRIu32"/%"PRIu32,
f->vhorz_y_period, f->vhorz_u_period, f->vhorz_v_period,
f->vvert_y_period, f->vvert_u_period, f->vvert_v_period);
- msg_Warn (vd, " order: %.32s", f->vcomp_order);
+ msg_Warn (obj, " order: %.32s", f->vcomp_order);
break;
}
return 0;
xcb_connection_t *conn = vd->sys->conn;
const xcb_xv_image_format_info_t *f, *end;
-#ifndef XCB_XV_OLD
f = xcb_xv_list_image_formats_format (list);
-#else
- f = (xcb_xv_image_format_info_t *) (list + 1);
-#endif
end = f + xcb_xv_list_image_formats_format_length (list);
for (; f < end; f++)
{
- if (chroma != ParseFormat (vd, f))
+ if (chroma != ParseFormat (VLC_OBJECT(vd), f))
continue;
/* VLC pads scanline to 16 pixels internally */
- unsigned width = (fmt->i_width + 15) & ~15;
- unsigned height = (fmt->i_height + 15) & ~15;
+ unsigned width = fmt->i_width;
+ unsigned height = fmt->i_height;
xcb_xv_query_image_attributes_reply_t *i;
i = xcb_xv_query_image_attributes_reply (conn,
xcb_xv_query_image_attributes (conn, port, f->id,
static int Open (vlc_object_t *obj)
{
vout_display_t *vd = (vout_display_t *)obj;
- vout_display_sys_t *p_sys = malloc (sizeof (*p_sys));
+ vout_display_sys_t *p_sys;
if (!var_InheritBool (obj, "overlay"))
return VLC_EGENERIC;
+ p_sys = malloc (sizeof (*p_sys));
if (p_sys == NULL)
return VLC_ENOMEM;
continue;
}
- if (!(a->type & XCB_XV_TYPE_IMAGE_MASK))
+ if (!(a->type & XCB_XV_TYPE_INPUT_MASK)
+ || !(a->type & XCB_XV_TYPE_IMAGE_MASK))
continue;
xcb_xv_list_image_formats_reply_t *r =
else
chromas = chromas_default;
- vlc_fourcc_t chroma;
- for (size_t i = 0; chromas[i]; i++)
+ int forced_format_id = var_CreateGetInteger (obj, "xvideo-format-id");
+ vlc_fourcc_t chroma = forced_format_id;
+ xfmt = FindFormat (vd, chroma, &fmt, a->base_id, r, &p_sys->att);
+ for (size_t i = 0; !xfmt && chromas[i]; i++)
{
chroma = chromas[i];
}
xfmt = FindFormat (vd, chroma, &fmt, a->base_id, r, &p_sys->att);
- if (xfmt != NULL)
- {
- p_sys->id = xfmt->id;
- p_sys->swap_uv = vlc_fourcc_AreUVPlanesSwapped (fmt.i_chroma,
- chroma);
- if (!p_sys->swap_uv)
- fmt.i_chroma = chroma;
- if (xfmt->type == XCB_XV_IMAGE_FORMAT_INFO_TYPE_RGB)
- {
- fmt.i_rmask = xfmt->red_mask;
- fmt.i_gmask = xfmt->green_mask;
- fmt.i_bmask = xfmt->blue_mask;
- }
- break;
- }
}
- free (r);
if (xfmt == NULL) /* No acceptable image formats */
+ {
+ free (r);
continue;
+ }
+
+ p_sys->id = xfmt->id;
+ p_sys->swap_uv = vlc_fourcc_AreUVPlanesSwapped (fmt.i_chroma, chroma);
+ if (!p_sys->swap_uv)
+ fmt.i_chroma = chroma;
+ if (xfmt->type == XCB_XV_IMAGE_FORMAT_INFO_TYPE_RGB)
+ {
+ fmt.i_rmask = xfmt->red_mask;
+ fmt.i_gmask = xfmt->green_mask;
+ fmt.i_bmask = xfmt->blue_mask;
+ }
+ free (r);
/* Grab a port */
for (unsigned i = 0; i < a->num_ports; i++)
msg_Err (vd, "no available XVideo adaptor");
goto error;
}
- else
+ /* Compute video (window) placement within the parent window */
{
xcb_map_window (conn, p_sys->window);
xcb_create_gc (conn, p_sys->gc, p_sys->window, 0, NULL);
msg_Dbg (vd, "using X11 graphic context 0x%08"PRIx32, p_sys->gc);
+ /* Disable color keying if applicable */
+ {
+ xcb_intern_atom_reply_t *r =
+ xcb_intern_atom_reply (conn,
+ xcb_intern_atom (conn, 1, 21, "XV_AUTOPAINT_COLORKEY"), NULL);
+ if (r != NULL && r->atom != 0)
+ xcb_xv_set_port_attribute(conn, p_sys->port, r->atom, 1);
+ }
+
/* Create cursor */
p_sys->cursor = CreateBlankCursor (conn, screen);
- CheckSHM (obj, conn, &p_sys->shm);
+ p_sys->shm = CheckSHM (obj, conn);
/* */
vout_display_info_t info = vd->info;
/**
* Sends an image to the X server.
*/
-static void Display (vout_display_t *vd, picture_t *pic)
+static void Display (vout_display_t *vd, picture_t *pic, subpicture_t *subpicture)
{
vout_display_sys_t *p_sys = vd->sys;
xcb_shm_seg_t segment = pic->p_sys->segment;
}
out:
picture_Release (pic);
+ (void)subpicture;
}
static int Control (vout_display_t *vd, int query, va_list ap)
case VOUT_DISPLAY_HIDE_MOUSE:
xcb_change_window_attributes (p_sys->conn, p_sys->embed->handle.xid,
XCB_CW_CURSOR, &(uint32_t){ p_sys->cursor });
+ xcb_flush (p_sys->conn);
return VLC_SUCCESS;
case VOUT_DISPLAY_RESET_PICTURES:
assert(0);