Commit fae953b6 authored by Jean-Paul Saman's avatar Jean-Paul Saman

modules/codec/avcodec: Add VAAPI X11 vout

Video output VAAPI-X11 (-V vaapi-x11) depends on --ffmpeg-hw to be enabled.
parent ffe7367b
......@@ -10,9 +10,11 @@ libavcodec_plugin_la_SOURCES = \
chroma.h \
chroma.c \
vaapi.c \
vaapi_x11.c \
dxva2.c \
copy.c \
copy.h \
va.c \
va.h \
$(NULL)
if ENABLE_SOUT
......@@ -54,4 +56,3 @@ EXTRA_LTLIBRARIES += \
# FIXME mux.c \
# FIXME scale.c \
# FIXME $(NULL)
......@@ -141,7 +141,6 @@ vlc_module_begin ()
add_integer( "ffmpeg-threads", 0, THREADS_TEXT, THREADS_LONGTEXT, true );
#endif
#ifdef ENABLE_SOUT
/* encoder submodule */
add_submodule ()
......@@ -219,6 +218,17 @@ vlc_module_begin ()
add_submodule ()
AVIO_MODULE
#endif
#if defined(HAVE_AVCODEC_VAAPI)
/* vaapi_x11 submodule */
add_submodule()
set_description (N_("VAAPI X11 video output"))
set_category (CAT_VIDEO)
set_subcategory (SUBCAT_VIDEO_VOUT)
set_capability ("vout display", 75)
set_callbacks (OpenVaapiX11, CloseVaapiX11)
add_shortcut ("vaapi-x11")
#endif
vlc_module_end ()
/*****************************************************************************
......
......@@ -52,6 +52,12 @@ int InitVideoDec( decoder_t *p_dec, AVCodecContext *p_context,
AVCodec *p_codec, int i_codec_id, const char *psz_namecodec );
void EndVideoDec( decoder_t *p_dec );
/* VAAPI X11 Video Output */
#ifdef HAVE_AVCODEC_VAAPI
int OpenVaapiX11 (vlc_object_t *);
void CloseVaapiX11 (vlc_object_t *);
#endif
/* Audio Decoder */
int InitAudioDec( decoder_t *p_dec, AVCodecContext *p_context,
AVCodec *p_codec, int i_codec_id, const char *psz_namecodec );
......
......@@ -44,6 +44,12 @@
#endif
#include "avcodec.h"
#ifdef HAVE_AVCODEC_VAAPI
# include <vlc_xlib.h>
# include <libavcodec/vaapi.h>
# include <va/va.h>
# include <va/va_x11.h>
#endif
#include "va.h"
#include "copy.h"
......
/*****************************************************************************
* va.c: Video Acceleration API for avcodec
*****************************************************************************
* Copyright (C) 2011, M2X BV
* $Id$
*
* Authors: Jean-Paul Saman
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <vlc_common.h>
#include <vlc_fourcc.h>
#include <assert.h>
#ifdef HAVE_LIBAVCODEC_AVCODEC_H
# include <libavcodec/avcodec.h>
#else
# include <avcodec.h>
#endif
#include "avcodec.h"
#ifdef HAVE_AVCODEC_VAAPI
# include <vlc_xlib.h>
# include <libavcodec/vaapi.h>
# include <va/va.h>
# include <va/va_x11.h>
#endif
#include "va.h"
#ifdef HAVE_AVCODEC_VAAPI
/* Global VAAPI connection state */
static vlc_va_conn_t vlc_va_conn = { 0, 0, 0, 0 };
static vlc_va_conn_t *vlc_va_get_conn( void )
{
return (vlc_va_conn_t *) &vlc_va_conn;
}
int vlc_va_Initialize( vlc_va_conn_t *conn, const char *display_name )
{
static bool b_va_inited = false;
assert(conn == NULL);
/* connect global to caller */
conn = vlc_va_get_conn();
if (b_va_inited)
return VLC_SUCCESS;
/* Create a VA display */
conn->p_display_x11 = XOpenDisplay(display_name);
if( !conn->p_display_x11 )
goto error;
conn->p_display = vaGetDisplay(conn->p_display_x11);
if( !conn->p_display )
goto error;
if( vaInitialize(conn->p_display, &conn->i_version_major, &conn->i_version_minor) )
goto error;
b_va_inited = true;
return VLC_SUCCESS;
error:
return VLC_EGENERIC;
}
#endif
......@@ -61,5 +61,18 @@ static inline void vlc_va_Delete(vlc_va_t *va)
vlc_va_t *vlc_va_NewVaapi(vlc_object_t *obj, int codec_id);
vlc_va_t *vlc_va_NewDxva2(vlc_object_t *log, int codec_id);
#ifdef HAVE_AVCODEC_VAAPI
typedef struct vlc_va_conn_t vlc_va_conn_t;
struct vlc_va_conn_t
{
Display *p_display_x11;
VADisplay p_display;
int i_version_major;
int i_version_minor;
};
int vlc_va_Initialize(vlc_va_conn_t *conn, const char *display_name);
#endif
#endif
......@@ -36,18 +36,17 @@
#endif
#include "avcodec.h"
#ifdef HAVE_AVCODEC_VAAPI
# include <vlc_xlib.h>
# include <libavcodec/vaapi.h>
# include <va/va.h>
# include <va/va_x11.h>
#endif
#include "va.h"
#include "copy.h"
#ifdef HAVE_AVCODEC_VAAPI
#include <vlc_xlib.h>
#include <libavcodec/vaapi.h>
#include <X11/Xlib.h>
#include <va/va_x11.h>
typedef struct
{
VASurfaceID i_id;
......@@ -61,18 +60,13 @@ typedef struct
vlc_va_t va;
/* */
Display *p_display_x11;
VADisplay p_display;
vlc_va_conn_t *conn;
VAConfigID i_config_id;
VAContextID i_context_id;
struct vaapi_context hw_ctx;
/* */
int i_version_major;
int i_version_minor;
/* */
int i_surface_count;
unsigned int i_surface_order;
......@@ -133,29 +127,21 @@ static int Open( vlc_va_vaapi_t *p_va, int i_codec_id )
p_va->image.image_id = VA_INVALID_ID;
/* Create a VA display */
p_va->p_display_x11 = XOpenDisplay(NULL);
if( !p_va->p_display_x11 )
goto error;
p_va->p_display = vaGetDisplay( p_va->p_display_x11 );
if( !p_va->p_display )
goto error;
if( vaInitialize( p_va->p_display, &p_va->i_version_major, &p_va->i_version_minor ) )
if( vlc_va_Initialize( p_va->conn, NULL ) != VLC_SUCCESS )
goto error;
/* Create a VA configuration */
VAConfigAttrib attrib;
memset( &attrib, 0, sizeof(attrib) );
attrib.type = VAConfigAttribRTFormat;
if( vaGetConfigAttributes( p_va->p_display,
if( vaGetConfigAttributes( p_va->conn->p_display,
i_profile, VAEntrypointVLD, &attrib, 1 ) )
goto error;
/* Not sure what to do if not, I don't have a way to test */
if( (attrib.value & VA_RT_FORMAT_YUV420) == 0 )
goto error;
if( vaCreateConfig( p_va->p_display,
if( vaCreateConfig( p_va->conn->p_display,
i_profile, VAEntrypointVLD, &attrib, 1, &p_va->i_config_id ) )
{
p_va->i_config_id = VA_INVALID_ID;
......@@ -165,7 +151,7 @@ static int Open( vlc_va_vaapi_t *p_va, int i_codec_id )
p_va->i_surface_count = i_surface_count;
if( asprintf( &p_va->va.description, "VA API version %d.%d",
p_va->i_version_major, p_va->i_version_minor ) < 0 )
p_va->conn->i_version_major, p_va->conn->i_version_minor ) < 0 )
p_va->va.description = NULL;
return VLC_SUCCESS;
......@@ -179,18 +165,18 @@ static void DestroySurfaces( vlc_va_vaapi_t *p_va )
if( p_va->image.image_id != VA_INVALID_ID )
{
CopyCleanCache( &p_va->image_cache );
vaDestroyImage( p_va->p_display, p_va->image.image_id );
vaDestroyImage( p_va->conn->p_display, p_va->image.image_id );
}
if( p_va->i_context_id != VA_INVALID_ID )
vaDestroyContext( p_va->p_display, p_va->i_context_id );
vaDestroyContext( p_va->conn->p_display, p_va->i_context_id );
for( int i = 0; i < p_va->i_surface_count && p_va->p_surface; i++ )
{
vlc_va_surface_t *p_surface = &p_va->p_surface[i];
if( p_surface->i_id != VA_INVALID_SURFACE )
vaDestroySurfaces( p_va->p_display, &p_surface->i_id, 1 );
vaDestroySurfaces( p_va->conn->p_display, &p_surface->i_id, 1 );
}
free( p_va->p_surface );
......@@ -215,7 +201,7 @@ static int CreateSurfaces( vlc_va_vaapi_t *p_va, void **pp_hw_ctx, vlc_fourcc_t
/* Create surfaces */
VASurfaceID pi_surface_id[p_va->i_surface_count];
if( vaCreateSurfaces( p_va->p_display, i_width, i_height, VA_RT_FORMAT_YUV420,
if( vaCreateSurfaces( p_va->conn->p_display, i_width, i_height, VA_RT_FORMAT_YUV420,
p_va->i_surface_count, pi_surface_id ) )
{
for( int i = 0; i < p_va->i_surface_count; i++ )
......@@ -233,7 +219,7 @@ static int CreateSurfaces( vlc_va_vaapi_t *p_va, void **pp_hw_ctx, vlc_fourcc_t
}
/* Create a context */
if( vaCreateContext( p_va->p_display, p_va->i_config_id,
if( vaCreateContext( p_va->conn->p_display, p_va->i_config_id,
i_width, i_height, VA_PROGRESSIVE,
pi_surface_id, p_va->i_surface_count, &p_va->i_context_id ) )
{
......@@ -242,12 +228,12 @@ static int CreateSurfaces( vlc_va_vaapi_t *p_va, void **pp_hw_ctx, vlc_fourcc_t
}
/* Find and create a supported image chroma */
int i_fmt_count = vaMaxNumImageFormats( p_va->p_display );
int i_fmt_count = vaMaxNumImageFormats( p_va->conn->p_display );
VAImageFormat *p_fmt = calloc( i_fmt_count, sizeof(*p_fmt) );
if( !p_fmt )
goto error;
if( vaQueryImageFormats( p_va->p_display, p_fmt, &i_fmt_count ) )
if( vaQueryImageFormats( p_va->conn->p_display, p_fmt, &i_fmt_count ) )
{
free( p_fmt );
goto error;
......@@ -261,17 +247,17 @@ static int CreateSurfaces( vlc_va_vaapi_t *p_va, void **pp_hw_ctx, vlc_fourcc_t
p_fmt[i].fourcc == VA_FOURCC( 'I', '4', '2', '0' ) ||
p_fmt[i].fourcc == VA_FOURCC( 'N', 'V', '1', '2' ) )
{
if( vaCreateImage( p_va->p_display, &p_fmt[i], i_width, i_height, &p_va->image ) )
if( vaCreateImage( p_va->conn->p_display, &p_fmt[i], i_width, i_height, &p_va->image ) )
{
p_va->image.image_id = VA_INVALID_ID;
continue;
}
/* Validate that vaGetImage works with this format */
if( vaGetImage( p_va->p_display, pi_surface_id[0],
if( vaGetImage( p_va->conn->p_display, pi_surface_id[0],
0, 0, i_width, i_height,
p_va->image.image_id) )
{
vaDestroyImage( p_va->p_display, p_va->image.image_id );
vaDestroyImage( p_va->conn->p_display, p_va->image.image_id );
p_va->image.image_id = VA_INVALID_ID;
continue;
}
......@@ -292,7 +278,7 @@ static int CreateSurfaces( vlc_va_vaapi_t *p_va, void **pp_hw_ctx, vlc_fourcc_t
*pp_hw_ctx = &p_va->hw_ctx;
memset( &p_va->hw_ctx, 0, sizeof(p_va->hw_ctx) );
p_va->hw_ctx.display = p_va->p_display;
p_va->hw_ctx.display = p_va->conn->p_display;
p_va->hw_ctx.config_id = p_va->i_config_id;
p_va->hw_ctx.context_id = p_va->i_context_id;
......@@ -340,9 +326,9 @@ static int Extract( vlc_va_t *p_external, picture_t *p_picture, AVFrame *p_ff )
VASurfaceID i_surface_id = (VASurfaceID)(uintptr_t)p_ff->data[3];
#if VA_CHECK_VERSION(0,31,0)
if( vaSyncSurface( p_va->p_display, i_surface_id ) )
if( vaSyncSurface( p_va->conn->p_display, i_surface_id ) )
#else
if( vaSyncSurface( p_va->p_display, p_va->i_context_id, i_surface_id ) )
if( vaSyncSurface( p_va->conn->p_display, p_va->i_context_id, i_surface_id ) )
#endif
return VLC_EGENERIC;
......@@ -350,13 +336,13 @@ static int Extract( vlc_va_t *p_external, picture_t *p_picture, AVFrame *p_ff )
* my setup.
*/
if( vaGetImage( p_va->p_display, i_surface_id,
if( vaGetImage( p_va->conn->p_display, i_surface_id,
0, 0, p_va->i_surface_width, p_va->i_surface_height,
p_va->image.image_id) )
return VLC_EGENERIC;
void *p_base;
if( vaMapBuffer( p_va->p_display, p_va->image.buf, &p_base ) )
if( vaMapBuffer( p_va->conn->p_display, p_va->image.buf, &p_base ) )
return VLC_EGENERIC;
const uint32_t i_fourcc = p_va->image.format.fourcc;
......@@ -395,7 +381,7 @@ static int Extract( vlc_va_t *p_external, picture_t *p_picture, AVFrame *p_ff )
&p_va->image_cache );
}
if( vaUnmapBuffer( p_va->p_display, p_va->image.buf ) )
if( vaUnmapBuffer( p_va->conn->p_display, p_va->image.buf ) )
return VLC_EGENERIC;
return VLC_SUCCESS;
......@@ -458,11 +444,11 @@ static void Close( vlc_va_vaapi_t *p_va )
DestroySurfaces( p_va );
if( p_va->i_config_id != VA_INVALID_ID )
vaDestroyConfig( p_va->p_display, p_va->i_config_id );
if( p_va->p_display )
vaTerminate( p_va->p_display );
if( p_va->p_display_x11 )
XCloseDisplay( p_va->p_display_x11 );
vaDestroyConfig( p_va->conn->p_display, p_va->i_config_id );
if( p_va->conn->p_display )
vaTerminate( p_va->conn->p_display );
if( p_va->conn->p_display_x11 )
XCloseDisplay( p_va->conn->p_display_x11 );
}
static void Delete( vlc_va_t *p_external )
{
......
/**
* @file vaapi_x11.c
* @brief VA API using X11 video output module for VLC media player
*/
/*****************************************************************************
* Copyright © 2011, M2X BV
* Author: Jean-Paul Saman
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
****************************************************************************/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdlib.h>
#include <assert.h>
#include <vlc_common.h>
#include <vlc_plugin.h>
#include <vlc_vout_display.h>
#include <vlc_picture_pool.h>
#ifdef HAVE_AVCODEC_VAAPI
#ifdef HAVE_LIBAVCODEC_AVCODEC_H
# include <libavcodec/avcodec.h>
#else
# include <avcodec.h>
#endif
#include "avcodec.h"
#include <vlc_xlib.h>
#include <libavcodec/vaapi.h>
#include <va/va.h>
#include <va/va_x11.h>
#include "va.h"
#include <X11/Xutil.h>
/* It must be large enough to absorb the server display jitter but it is
* useless to used a too large value.
*/
#define MAX_PICTURES (3)
typedef struct vlc_vaapi_x11_window_t
{
int screen;
Visual *visual;
Window root;
Window window;
} vlc_vaapi_x11_window_t;
struct vout_display_sys_t
{
vlc_va_conn_t *conn;
vout_window_t *embed; /* VLC window (when windowed) */
vlc_vaapi_x11_window_t x11;
bool visible; /* whether to draw */
picture_pool_t *pool; /* picture pool */
};
static picture_pool_t *Pool (vout_display_t *, unsigned);
static void PictureDisplay (vout_display_t *, picture_t *, subpicture_t *);
static int Control (vout_display_t *, int, va_list);
static void Manage (vout_display_t *);
/* X11 Window */
static int CreateWindow(vout_display_t *vd)
{
vout_display_sys_t *sys = (vout_display_sys_t *) vd->sys;
sys->x11.screen = DefaultScreen(sys->conn->p_display_x11);
sys->x11.visual = DefaultVisual(sys->conn->p_display_x11, sys->x11.screen);
sys->x11.root = RootWindow(sys->conn->p_display_x11, sys->x11.screen);
XWindowAttributes attr;
XGetWindowAttributes(sys->conn->p_display_x11, sys->x11.root, &attr);
int32_t depth = attr.depth;
switch(attr.depth)
{
case 8:
if (vd->fmt.i_bits_per_pixel != 8)
vd->fmt.i_bits_per_pixel = 8;
vd->fmt.i_chroma = VLC_CODEC_RGB8;
break;
case 15:
if (vd->fmt.i_bits_per_pixel != 15)
vd->fmt.i_bits_per_pixel = 15;
vd->fmt.i_chroma = VLC_CODEC_RGB15;
break;
case 16:
if (vd->fmt.i_bits_per_pixel != 16)
vd->fmt.i_bits_per_pixel = 16;
vd->fmt.i_chroma = VLC_CODEC_RGB16;
break;
case 24:
if (vd->fmt.i_bits_per_pixel == 32)
vd->fmt.i_chroma = VLC_CODEC_RGB32;
else if (vd->fmt.i_bits_per_pixel == 24)
vd->fmt.i_chroma = VLC_CODEC_RGB24;
else
{
vd->fmt.i_bits_per_pixel = 24;
vd->fmt.i_chroma = VLC_CODEC_RGB24;
}
break;
case 32:
if (vd->fmt.i_bits_per_pixel != 32)
vd->fmt.i_bits_per_pixel = 32;
vd->fmt.i_chroma = VLC_CODEC_RGB32;
break;
default:
if (vd->fmt.i_bits_per_pixel != 24)
vd->fmt.i_bits_per_pixel = 24;
vd->fmt.i_chroma = VLC_CODEC_RGB24;
depth = 24;
break;
}
XVisualInfo vi;
XVisualInfo *vi_info = &vi;
XMatchVisualInfo(sys->conn->p_display_x11, sys->x11.screen, depth, TrueColor, vi_info);
XSetWindowAttributes xswa;
uint32_t xswa_mask;
xswa_mask = CWBorderPixel | CWBackPixel;
xswa.border_pixel = BlackPixel(sys->conn->p_display_x11, sys->x11.screen);
xswa.background_pixel = WhitePixel(sys->conn->p_display_x11, sys->x11.screen);
sys->x11.window = XCreateWindow(sys->conn->p_display_x11, sys->x11.root,
0, 0, /*wnd_cfg.x, wnd_cfg.y,*/
1080, 720, /*wnd_cfg.width, wnd_cfg.height,*/
0, depth,
InputOutput, vi_info->visual, xswa_mask, &xswa);
if (sys->x11.window == None)
return VLC_EGENERIC;
int map = XMapWindow(sys->conn->p_display_x11, sys->x11.window);
if (map == BadWindow)
return VLC_EGENERIC;
return VLC_SUCCESS;
}
static void DestroyWindow(vout_display_t *vd)
{
vout_display_sys_t *sys = (vout_display_sys_t *) vd->sys;
XFree(sys->x11.visual); /* ?? */
if (sys->x11.window)
{
XUnmapWindow(sys->conn->p_display_x11, sys->x11.window);
//x11_wait_event(sys->conn->p_display_x11, sys->x11.window, UnmapNotify);
XDestroyWindow(sys->conn->p_display_x11, sys->x11.window);
sys->x11.window = None;
}
}
static vout_window_t *MakeWindow (vout_display_t *vd)
{
vout_window_cfg_t wnd_cfg;
memset (&wnd_cfg, 0, sizeof (wnd_cfg));
wnd_cfg.type = VOUT_WINDOW_TYPE_XID;
wnd_cfg.x = var_InheritInteger (vd, "video-x");
wnd_cfg.y = var_InheritInteger (vd, "video-y");
wnd_cfg.width = vd->cfg->display.width;
wnd_cfg.height = vd->cfg->display.height;
vout_window_t *wnd = vout_display_NewWindow (vd, &wnd_cfg);
if (wnd == NULL)
msg_Err (vd, "parent window not available");
return wnd;
}
/**
* Probe the X server.
*/
int OpenVaapiX11 (vlc_object_t *obj)
{
vout_display_t *vd = (vout_display_t *) obj;
vout_display_sys_t *sys = malloc(sizeof(*sys));
if (unlikely(sys == NULL))
return VLC_ENOMEM;
vd->sys = sys;
sys->visible = false;
sys->embed = MakeWindow(vd);
if (unlikely(sys->embed == NULL))
goto error;
/* Create a VA display */
if( vlc_va_Initialize( sys->conn, sys->embed->display.x11 ) != VLC_SUCCESS )
goto error;
if (CreateWindow(vd) != VLC_SUCCESS)
goto error;
msg_Dbg(vd, "using VAAPI X11 window");
/* */
vout_display_info_t info = vd->info;
info.has_pictures_invalid = false;
info.has_event_thread = false;
/* Setup vout_display_t once everything is fine */
vd->info = info;
vd->pool = NULL; //Pool;
vd->prepare = NULL; //PictureRender;
vd->display = PictureDisplay;
vd->control = Control;
vd->manage = NULL; //Manage;
/* */
bool is_fullscreen = vd->cfg->is_fullscreen;
if (is_fullscreen && vout_window_SetFullScreen (sys->embed, true))
is_fullscreen = false;
vout_display_SendEventFullscreen (vd, is_fullscreen);
vout_display_SendEventDisplaySize (vd, vd->cfg->display.width, vd->cfg->display.height, is_fullscreen);
return VLC_SUCCESS;
error:
CloseVaapiX11(obj);
return VLC_EGENERIC;
}
void CloseVaapiX11 (vlc_object_t *obj)
{
vout_display_t *vd = (vout_display_t *) obj;
vout_display_sys_t *sys = (vout_display_sys_t *) vd->sys;
DestroyWindow(vd);
if (sys->conn->p_display_x11)
{
XFlush(sys->conn->p_display_x11);
XSync(sys->conn->p_display_x11, False);
XCloseDisplay(sys->conn->p_display_x11);
sys->conn->p_display_x11 = NULL;
}
if (sys->embed)
vout_display_DeleteWindow (vd, sys->embed);
free(vd->sys);
}
static int Control (vout_display_t *vd, int query, va_list ap)
{
vout_display_sys_t *sys = vd->sys;
switch (query)
{
case VOUT_DISPLAY_CHANGE_FULLSCREEN:
{
const vout_display_cfg_t *c = va_arg (ap, const vout_display_cfg_t *);
return vout_window_SetFullScreen (sys->embed, c->is_fullscreen);
}
case VOUT_DISPLAY_CHANGE_DISPLAY_SIZE:
{
const vout_display_cfg_t *p_cfg =
(const vout_display_cfg_t*)va_arg (ap, const vout_display_cfg_t *);
const bool is_forced = (bool)va_arg (ap, int);
if (is_forced
&& vout_window_SetSize (sys->embed,
p_cfg->display.width,
p_cfg->display.height))
return VLC_EGENERIC;
vout_display_place_t place;
vout_display_PlacePicture (&place, &vd->source, p_cfg, false);
if (place.width != vd->fmt.i_visible_width ||
place.height != vd->fmt.i_visible_height)
{
vout_display_SendEventPicturesInvalid (vd);
return VLC_SUCCESS;
}
#if 0 /* FIXME */
/* Move the picture within the window */
const uint32_t values[] = { place.x, place.y };
xcb_configure_window (sys->conn, sys->window,
XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y,
values);
#endif
return VLC_SUCCESS;
}
case VOUT_DISPLAY_CHANGE_WINDOW_STATE:
{
unsigned state = va_arg (ap, unsigned);
return vout_window_SetState (sys->embed, state);
}
case VOUT_DISPLAY_CHANGE_ZOOM:
case VOUT_DISPLAY_CHANGE_DISPLAY_FILLED:
case VOUT_DISPLAY_CHANGE_SOURCE_ASPECT:
case VOUT_DISPLAY_CHANGE_SOURCE_CROP:
/* I am not sure it is always necessary, but it is way simpler ... */
vout_display_SendEventPicturesInvalid (vd);
return VLC_SUCCESS;
case VOUT_DISPLAY_RESET_PICTURES:
{
#if 0
ResetPictures (vd);
#endif
vout_display_place_t place;
vout_display_PlacePicture (&place, &vd->source, vd->cfg, false);
vd->fmt.i_width = vd->source.i_width * place.width / vd->source.i_visible_width;
vd->fmt.i_height = vd->source.i_height * place.height / vd->source.i_visible_height;
vd->fmt.i_visible_width = place.width;
vd->fmt.i_visible_height = place.height;
vd->fmt.i_x_offset = vd->source.i_x_offset * place.width / vd->source.i_visible_width;
vd->fmt.i_y_offset = vd->source.i_y_offset * place.height / vd->source.i_visible_height;
return VLC_SUCCESS;
}
#if 0 /* FIXME */
/* Hide the mouse. It will be send when
* vout_display_t::info.b_hide_mouse is false */
case VOUT_DISPLAY_HIDE_MOUSE:
xcb_change_window_attributes (sys->conn, sys->embed->handle.xid,
XCB_CW_CURSOR, &(uint32_t){ sys->cursor });
return VLC_SUCCESS;
#endif
default:
msg_Err (vd, "Unknown request in XCB vout display");
return VLC_EGENERIC;
}
}
static void Manage (vout_display_t *vd)
{
VLC_UNUSED(vd);
#if 0
vout_display_sys_t *sys = vd->sys;
xcb_connection_t *conn = XGetXCBConnection (sys->display);
ManageEvent (vd, conn, &sys->visible);
#endif
}
static void PictureDisplay (vout_display_t *vd, picture_t *pic, subpicture_t *subpicture)
{
vout_display_sys_t *sys = vd->sys;
VLC_UNUSED(subpicture);
VLC_UNUSED(sys);
#if 0
if (subpicture)
{
/* FIXME: blend subpicture into VAAPI structure */
}
vout_display_place_t place;
vout_display_PlacePicture (&place, &vd->source, vd->cfg, false);
unsigned int flags = VA_FRAME_PICTURE;
if (!pic->b_progressive)
flags = pic->b_top_field_first ? VA_TOP_FIELD : VA_BOTTOM_FIELD;
VASurfaceID i_surface_id = (VASurfaceID)(uintptr_t)pic->p_sys;
#if VA_CHECK_VERSION(0,31,0)
if (vaSyncSurface(sys->display, i_surface_id))
#else
unsigned int i_context_id = /* FIXME: get context id */;
if (vaSyncSurface(sys->display, i_context_id, i_surface_id))
#endif
goto out;
VAStatus status = vaPutSurface(sys->display,
i_surface_id,
sys->x11.window,
vd->source.i_y_offset, vd->source.i_x_offset,
vd->fmt.i_visible_width, vd->fmt.i_visible_height,
place->x, place->y, place.width, place.height,
NULL, 0, /* client supplied destination clip list, cliplist count */
flags);
if (status != VA_STATUS_SUCCESS)
msg_Err(vd, "failed displaying picture");
out:
#endif
picture_Release(pic);
}
/**
* Return a direct buffer
*/
static picture_pool_t *Pool (vout_display_t *vd, unsigned requested_count)
{
vout_display_sys_t *sys = vd->sys;
(void)requested_count;
VLC_UNUSED(sys);
#if 0
if (sys->pool)
return sys->pool;
/* FIXME: allocate picture and output surfaces */
sys->pool = picture_pool_New (count, pic_array);
if (!sys->pool)
{
/* FIXME: Release allocated pictures */
return NULL;
}
XFlush(sys->conn->p_display_x11);
#endif
return sys->pool;
}
#endif /* HAVE_AVCODEC_VAAPI */
......@@ -51,6 +51,12 @@
#endif
#include "avcodec.h"
#ifdef HAVE_AVCODEC_VAAPI
# include <vlc_xlib.h>
# include <va/va.h>
#endif
#include "va.h"
#if defined(HAVE_AVCODEC_VAAPI) || defined(HAVE_AVCODEC_DXVA2)
# define HAVE_AVCODEC_VA
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment