[vlc-devel] commit: XCB: allocate UV planes, fallback to HW scaling + SW chroma ( Rémi Denis-Courmont )
git version control
git at videolan.org
Sun Apr 26 16:40:15 CEST 2009
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sun Apr 26 17:24:15 2009 +0300| [dc0001ab8ffbcc26085600d6c8024c72963e56fd] | committer: Rémi Denis-Courmont
XCB: allocate UV planes, fallback to HW scaling + SW chroma
XVideo is now usable for YUV!
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=dc0001ab8ffbcc26085600d6c8024c72963e56fd
---
modules/video_output/xcb/xvideo.c | 165 ++++++++++++++++++++++---------------
1 files changed, 99 insertions(+), 66 deletions(-)
diff --git a/modules/video_output/xcb/xvideo.c b/modules/video_output/xcb/xvideo.c
index 6d908b0..4ec03e2 100644
--- a/modules/video_output/xcb/xvideo.c
+++ b/modules/video_output/xcb/xvideo.c
@@ -230,30 +230,6 @@ static void Close (vlc_object_t *obj)
free (p_sys);
}
-static int QueryBestSize (vout_thread_t *vout,
- unsigned *restrict width, unsigned *restrict height)
-{
- vout_sys_t *p_sys = vout->p_sys;
- xcb_xv_query_best_size_reply_t *r;
- xcb_xv_query_best_size_cookie_t ck;
-
- ck = xcb_xv_query_best_size (p_sys->conn, p_sys->port,
- vout->fmt_in.i_visible_width,
- vout->fmt_in.i_visible_height,
- *width, *height, false);
- r = xcb_xv_query_best_size_reply (p_sys->conn, ck, NULL);
- if (r == NULL)
- return VLC_EGENERIC;
-
- msg_Dbg (vout, "best size: %ux%u -> %ux%u", *width, *height,
- r->actual_width, r->actual_height);
- *width = r->actual_width;
- *height = r->actual_height;
- free (r);
- return VLC_SUCCESS;
-}
-
-
static vlc_fourcc_t ParseFormat (vout_thread_t *vout,
const xcb_xv_image_format_info_t *restrict f)
{
@@ -353,13 +329,50 @@ static vlc_fourcc_t ParseFormat (vout_thread_t *vout,
}
+static const xcb_xv_image_format_info_t *
+FindFormat (vout_thread_t *vout, vlc_fourcc_t chroma, xcb_xv_port_t port,
+ const xcb_xv_list_image_formats_reply_t *list,
+ xcb_xv_query_image_attributes_reply_t **restrict pa)
+{
+ xcb_connection_t *conn = vout->p_sys->conn;
+ const xcb_xv_image_format_info_t *f, *end;
+
+ f = xcb_xv_list_image_formats_format (list);
+ end = f + xcb_xv_list_image_formats_format_length (list);
+ for (; f < end; f++)
+ {
+ if (chroma != ParseFormat (vout, f))
+ continue;
+
+ 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,
+ vout->fmt_in.i_width, vout->fmt_in.i_height), NULL);
+ if (i == NULL)
+ continue;
+
+ if (i->width != vout->fmt_in.i_width
+ || i->height != vout->fmt_in.i_height)
+ {
+ msg_Warn (vout, "incompatible size %ux%u -> %"PRIu32"x%"PRIu32,
+ vout->fmt_in.i_width, vout->fmt_in.i_height,
+ i->width, i->height);
+ free (i);
+ continue;
+ }
+ *pa = i;
+ return f;
+ }
+ return NULL;
+}
+
/**
* Allocate drawable window and picture buffers.
*/
static int Init (vout_thread_t *vout)
{
vout_sys_t *p_sys = vout->p_sys;
- unsigned x, y, width, height;
+ xcb_xv_query_image_attributes_reply_t *att;
/* FIXME: check max image size */
xcb_xv_adaptor_info_iterator_t it;
@@ -379,48 +392,88 @@ static int Init (vout_thread_t *vout)
if (r == NULL)
continue;
- const xcb_xv_image_format_info_t *f, *end;
- f = xcb_xv_list_image_formats_format (r);
- end = f + xcb_xv_list_image_formats_format_length (r);
- for (; f < end; f++)
- {
- vlc_fourcc_t chroma = ParseFormat (vout, f);
- if (!chroma)
- continue;
+ const xcb_xv_image_format_info_t *fmt;
- if (chroma == vout->fmt_in.i_chroma)
+ /* Video chroma in preference order */
+ const vlc_fourcc_t chromas[] = {
+ vout->fmt_in.i_chroma,
+ VLC_FOURCC ('Y', 'U', 'Y', '2'),
+ VLC_FOURCC ('R', 'V', '2', '4'),
+ VLC_FOURCC ('R', 'V', '1', '5'),
+ };
+ for (size_t i = 0; i < sizeof (chromas) / sizeof (chromas[0]); i++)
+ {
+ vlc_fourcc_t chroma = chromas[i];
+ fmt = FindFormat (vout, chroma, a->base_id, r, &att);
+ if (fmt != NULL)
{
vout->output.i_chroma = chroma;
- p_sys->id = f->id;
- break;
+ goto found_format;
}
- /* TODO: RGB masks */
}
-
free (r);
- /* TODO: grab port */
+ continue;
- msg_Dbg (vout, "using image format 0x%"PRIx32, p_sys->id);
+ found_format:
+ /* TODO: grab port */
p_sys->port = a->base_id;
msg_Dbg (vout, "using port %"PRIu32, p_sys->port);
- break;
+
+ p_sys->id = fmt->id;
+ msg_Dbg (vout, "using image format 0x%"PRIx32, p_sys->id);
+ if (fmt->type == XCB_XV_IMAGE_FORMAT_INFO_TYPE_RGB)
+ {
+ vout->fmt_out.i_rmask = vout->output.i_rmask = fmt->red_mask;
+ vout->fmt_out.i_gmask = vout->output.i_gmask = fmt->green_mask;
+ vout->fmt_out.i_bmask = vout->output.i_bmask = fmt->blue_mask;
+ }
+ free (r);
+ goto found_adaptor;
}
+ msg_Err (vout, "no available XVideo adaptor");
+ return VLC_EGENERIC; /* no usable adaptor */
- /* TODO: fallback to RV24 or I420 */
- if (!vout->output.i_chroma)
- return VLC_EGENERIC; /* no usable adaptor */
+ /* Allocate picture buffers */
+ const uint32_t *offsets;
+found_adaptor:
+ offsets = xcb_xv_query_image_attributes_offsets (att);
+
+ I_OUTPUTPICTURES = 0;
+ for (size_t index = 0; I_OUTPUTPICTURES < 2; index++)
+ {
+ picture_t *pic = vout->p_picture + index;
+
+ if (index > sizeof (vout->p_picture) / sizeof (pic))
+ break;
+ if (pic->i_status != FREE_PICTURE)
+ continue;
+
+ vout_InitPicture (vout, pic, vout->output.i_chroma,
+ att->width, att->height,
+ vout->fmt_in.i_aspect);
+ if (PictureAlloc (vout, pic, att->data_size,
+ p_sys->shm ? p_sys->conn : NULL))
+ break;
+ /* Allocate further planes as specified by XVideo */
+ /* We assume that offsets[0] is zero */
+ for (int i = 1; i < pic->i_planes; i++)
+ pic->p[i].p_pixels = pic->p->p_pixels + offsets[i];
+ PP_OUTPUTPICTURE[I_OUTPUTPICTURES++] = pic;
+ }
+ free (att);
+
+ unsigned x, y, width, height;
if (GetWindowSize (p_sys->embed, p_sys->conn, &width, &height))
return VLC_EGENERIC;
vout_PlacePicture (vout, width, height, &x, &y, &width, &height);
- if (QueryBestSize (vout, &width, &height))
- return VLC_EGENERIC;
const uint32_t values[] = { x, y, width, height, };
xcb_configure_window (p_sys->conn, p_sys->window,
XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y |
XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT,
values);
+ xcb_flush (p_sys->conn);
p_sys->height = height;
p_sys->width = width;
@@ -438,26 +491,6 @@ static int Init (vout_thread_t *vout)
vout->output.i_aspect = vout->fmt_out.i_aspect =
width * VOUT_ASPECT_FACTOR / height;
- /* Allocate picture buffers */
- I_OUTPUTPICTURES = 0;
- for (size_t index = 0; I_OUTPUTPICTURES < 2; index++)
- {
- picture_t *pic = vout->p_picture + index;
-
- if (index > sizeof (vout->p_picture) / sizeof (pic))
- break;
- if (pic->i_status != FREE_PICTURE)
- continue;
-
- vout_InitPicture (vout, pic, vout->output.i_chroma,
- vout->output.i_width, vout->output.i_height,
- vout->output.i_aspect);
- if (PictureAlloc (vout, pic, pic->p->i_pitch * pic->p->i_lines,
- p_sys->shm ? p_sys->conn : NULL))
- break;
- PP_OUTPUTPICTURE[I_OUTPUTPICTURES++] = pic;
- }
- xcb_flush (p_sys->conn);
return VLC_SUCCESS;
}
More information about the vlc-devel
mailing list