/*****************************************************************************
* vaapi.c: VAAPI helpers for the libavcodec decoder
*****************************************************************************
- * Copyright (C) 2009 Laurent Aimar
- * $Id$
+ * Copyright (C) 2009-2010 Laurent Aimar
+ * Copyright (C) 2012-2014 RĂ©mi Denis-Courmont
*
* Authors: Laurent Aimar <fenrir_AT_ videolan _DOT_ org>
*
#include <vlc_common.h>
#include <vlc_plugin.h>
#include <vlc_fourcc.h>
-#include <vlc_xlib.h>
+#ifdef VLC_VA_BACKEND_XLIB
+# include <vlc_xlib.h>
+# include <va/va_x11.h>
+#endif
+#ifdef VLC_VA_BACKEND_DRM
+# include <sys/types.h>
+# include <sys/stat.h>
+# include <fcntl.h>
+# include <vlc_fs.h>
+# include <va/va_drm.h>
+#endif
#include <libavcodec/avcodec.h>
#include <libavcodec/vaapi.h>
-#include <X11/Xlib.h>
-#include <va/va_x11.h>
#include "avcodec.h"
#include "va.h"
static void Delete( vlc_va_t * );
vlc_module_begin ()
- set_description( N_("Video Acceleration (VA) API") )
+#if defined (VLC_VA_BACKEND_XLIB)
+ set_description( N_("VA-API video decoder via X11") )
+#elif defined (VLC_VA_BACKEND_DRM)
+ set_description( N_("VA-API video decoder via DRM") )
+#endif
set_capability( "hw decoder", 0 )
set_category( CAT_INPUT )
set_subcategory( SUBCAT_INPUT_VCODEC )
set_callbacks( Create, Delete )
+ add_shortcut( "vaapi" )
vlc_module_end ()
typedef struct
struct vlc_va_sys_t
{
- Display *p_display_x11;
+#ifdef VLC_VA_BACKEND_XLIB
+ Display *p_display_x11;
+#endif
+#ifdef VLC_VA_BACKEND_DRM
+ int drm_fd;
+#endif
VADisplay p_display;
VAConfigID i_config_id;
struct vaapi_context hw_ctx;
- /* */
- int i_version_major;
- int i_version_minor;
-
/* */
vlc_mutex_t lock;
int i_surface_count;
};
/* */
-static int Open( vlc_va_t *va, int i_codec_id )
+static int Open( vlc_va_t *va, int i_codec_id, int i_thread_count )
{
vlc_va_sys_t *sys = calloc( 1, sizeof(*sys) );
if ( unlikely(sys == NULL) )
case AV_CODEC_ID_MPEG1VIDEO:
case AV_CODEC_ID_MPEG2VIDEO:
i_profile = VAProfileMPEG2Main;
- i_surface_count = 2+1;
+ i_surface_count = 2 + 2;
break;
case AV_CODEC_ID_MPEG4:
i_profile = VAProfileMPEG4AdvancedSimple;
break;
case AV_CODEC_ID_H264:
i_profile = VAProfileH264High;
- i_surface_count = 16+1;
- break;
+ i_surface_count = 16 + i_thread_count + 2;
+ break;;
default:
+ free( sys );
return VLC_EGENERIC;
}
sys->image.image_id = VA_INVALID_ID;
/* Create a VA display */
+#ifdef VLC_VA_BACKEND_XLIB
sys->p_display_x11 = XOpenDisplay(NULL);
if( !sys->p_display_x11 )
{
}
sys->p_display = vaGetDisplay( sys->p_display_x11 );
+#endif
+#ifdef VLC_VA_BACKEND_DRM
+ sys->drm_fd = vlc_open("/dev/dri/card0", O_RDWR);
+ if( sys->drm_fd == -1 )
+ {
+ msg_Err( va, "Could not access rendering device: %m" );
+ goto error;
+ }
+
+ sys->p_display = vaGetDisplayDRM( sys->drm_fd );
+#endif
if( !sys->p_display )
{
msg_Err( va, "Could not get a VAAPI device" );
goto error;
}
- if( vaInitialize( sys->p_display, &sys->i_version_major, &sys->i_version_minor ) )
+ int major, minor;
+
+ if( vaInitialize( sys->p_display, &major, &minor ) )
{
msg_Err( va, "Failed to initialize the VAAPI device" );
goto error;
vlc_mutex_init(&sys->lock);
- if( asprintf( &va->description, "VA API version %d.%d",
- sys->i_version_major, sys->i_version_minor ) < 0 )
- va->description = NULL;
-
va->sys = sys;
+ va->description = vaQueryVendorString( sys->p_display );
return VLC_SUCCESS;
error:
-#warning Leaks!
+ if( sys->p_display != NULL )
+ vaTerminate( sys->p_display );
+#ifdef VLC_VA_BACKEND_XLIB
+ if( sys->p_display_x11 != NULL )
+ XCloseDisplay( sys->p_display_x11 );
+#endif
+#ifdef VLC_VA_BACKEND_DRM
+ if( sys->drm_fd != -1 )
+ close( sys->drm_fd );
+#endif
+ free( sys );
return VLC_EGENERIC;
}
if( sys->i_config_id != VA_INVALID_ID )
vaDestroyConfig( sys->p_display, sys->i_config_id );
- if( sys->p_display )
- vaTerminate( sys->p_display );
- if( sys->p_display_x11 )
- XCloseDisplay( sys->p_display_x11 );
+ vaTerminate( sys->p_display );
+#ifdef VLC_VA_BACKEND_XLIB
+ XCloseDisplay( sys->p_display_x11 );
+#endif
+#ifdef VLC_VA_BACKEND_DRM
+ close( sys->drm_fd );
+#endif
}
static void Delete( vlc_va_t *va )
{
vlc_va_sys_t *sys = va->sys;
Close( sys );
- free( va->description );
free( sys );
}
static int Create( vlc_va_t *p_va, AVCodecContext *ctx,
const es_format_t *fmt )
{
+#ifdef VLC_VA_BACKEND_XLIB
if( !vlc_xlib_init( VLC_OBJECT(p_va) ) )
{
msg_Warn( p_va, "Ignoring VA API" );
return VLC_EGENERIC;
}
+#endif
(void) fmt;
- int err = Open( p_va, ctx->codec_id );
+ int err = Open( p_va, ctx->codec_id, ctx->thread_count );
if( err )
return err;