Commit 856803c7 authored by Jean-Paul Saman's avatar Jean-Paul Saman

avcodec: make vlc_va_t a VLC object

(cherry picked from commit 93fd69f494343adb8871501729801c49c7651130)

Conflicts:
	modules/codec/avcodec/dxva2.c
	modules/codec/avcodec/va.h
	modules/codec/avcodec/vaapi.c
	modules/codec/avcodec/vda.c
	modules/codec/avcodec/video.c
parent 9d510ebe
...@@ -233,12 +233,8 @@ typedef struct { ...@@ -233,12 +233,8 @@ typedef struct {
} vlc_va_surface_t; } vlc_va_surface_t;
#define VA_DXVA2_MAX_SURFACE_COUNT (64) #define VA_DXVA2_MAX_SURFACE_COUNT (64)
typedef struct struct vlc_va_sys_t
{ {
/* */
vlc_va_t va;
/* */
vlc_object_t *log; vlc_object_t *log;
int codec_id; int codec_id;
int width; int width;
...@@ -284,13 +280,15 @@ typedef struct ...@@ -284,13 +280,15 @@ typedef struct
vlc_va_surface_t surface[VA_DXVA2_MAX_SURFACE_COUNT]; vlc_va_surface_t surface[VA_DXVA2_MAX_SURFACE_COUNT];
LPDIRECT3DSURFACE9 hw_surface[VA_DXVA2_MAX_SURFACE_COUNT]; LPDIRECT3DSURFACE9 hw_surface[VA_DXVA2_MAX_SURFACE_COUNT];
} vlc_va_dxva2_t; };
typedef struct vlc_va_sys_t vlc_va_dxva2_t;
/* */ /* */
static vlc_va_dxva2_t *vlc_va_dxva2_Get(void *external) static vlc_va_dxva2_t *vlc_va_dxva2_Get(vlc_va_t *external)
{ {
assert(external == (void*)(&((vlc_va_dxva2_t*)external)->va)); vlc_va_dxva2_t *va = external->sys;
return external; assert(VLC_OBJECT(external) == va->log);
return va;
} }
/* */ /* */
...@@ -494,68 +492,76 @@ static void Close(vlc_va_t *external) ...@@ -494,68 +492,76 @@ static void Close(vlc_va_t *external)
if (va->hd3d9_dll) if (va->hd3d9_dll)
FreeLibrary(va->hd3d9_dll); FreeLibrary(va->hd3d9_dll);
free(va->va.description); free(external->description);
free(va); free(va);
} }
vlc_va_t *vlc_va_NewDxva2(vlc_object_t *log, int codec_id) int vlc_va_New(vlc_va_t *p_external, int pixfmt, int codec_id,
const es_format_t *fmt)
{ {
/* Only one VLD supported */
if (pixfmt != PIX_FMT_DXVA2_VLD)
return VLC_EGENERIC;
vlc_va_dxva2_t *va = calloc(1, sizeof(*va)); vlc_va_dxva2_t *va = calloc(1, sizeof(*va));
if (!va) if (!va)
return NULL; return NULL;
external->sys = va;
/* */ /* */
va->log = log; va->log = VLC_OBJECT(external);
va->codec_id = codec_id; va->codec_id = codec_id;
/* Load dll*/ /* Load dll*/
va->hd3d9_dll = LoadLibrary(TEXT("D3D9.DLL")); va->hd3d9_dll = LoadLibrary(TEXT("D3D9.DLL"));
if (!va->hd3d9_dll) { if (!va->hd3d9_dll) {
msg_Warn(va->log, "cannot load d3d9.dll"); msg_Warn(p_external, "cannot load d3d9.dll");
goto error; goto error;
} }
va->hdxva2_dll = LoadLibrary(TEXT("DXVA2.DLL")); va->hdxva2_dll = LoadLibrary(TEXT("DXVA2.DLL"));
if (!va->hdxva2_dll) { if (!va->hdxva2_dll) {
msg_Warn(va->log, "cannot load dxva2.dll"); msg_Warn(p_external, "cannot load dxva2.dll");
goto error; goto error;
} }
msg_Dbg(va->log, "DLLs loaded"); msg_Dbg(p_external, "DLLs loaded");
/* */ /* */
if (D3dCreateDevice(va)) { if (D3dCreateDevice(va)) {
msg_Err(va->log, "Failed to create Direct3D device"); msg_Err(p_external, "Failed to create Direct3D device");
goto error; goto error;
} }
msg_Dbg(va->log, "D3dCreateDevice succeed"); msg_Dbg(va->log, "D3dCreateDevice succeed");
if (D3dCreateDeviceManager(va)) { if (D3dCreateDeviceManager(va)) {
msg_Err(va->log, "D3dCreateDeviceManager failed"); msg_Err(p_external, "D3dCreateDeviceManager failed");
goto error; goto error;
} }
if (DxCreateVideoService(va)) { if (DxCreateVideoService(va)) {
msg_Err(va->log, "DxCreateVideoService failed"); msg_Err(p_external, "DxCreateVideoService failed");
goto error; goto error;
} }
/* */ /* */
if (DxFindVideoServiceConversion(va, &va->input, &va->render)) { if (DxFindVideoServiceConversion(va, &va->input, &va->render)) {
msg_Err(va->log, "DxFindVideoServiceConversion failed"); msg_Err(p_external, "DxFindVideoServiceConversion failed");
goto error; goto error;
} }
/* TODO print the hardware name/vendor for debugging purposes */ /* TODO print the hardware name/vendor for debugging purposes */
va->va.description = DxDescribe(va); external->description = DxDescribe(va);
va->va.setup = Setup; external->setup = Setup;
va->va.get = Get; external->get = Get;
va->va.release = Release; external->put = NULL;
va->va.extract = Extract; external->release = Release;
va->va.close = Close; external->extract = Extract;
return &va->va; external->display = NULL;
external->query = NULL;
external->close = Close;
return VLC_SUCCESS;
error: error:
Close(&va->va); Close(va);
return NULL; return VLC_EGENERIC;
} }
/* */ /* */
......
...@@ -25,11 +25,14 @@ ...@@ -25,11 +25,14 @@
#define _VLC_VA_H 1 #define _VLC_VA_H 1
typedef struct vlc_va_t vlc_va_t; typedef struct vlc_va_t vlc_va_t;
typedef struct vlc_va_sys_t vlc_va_sys_t;
struct vlc_va_t { struct vlc_va_t {
VLC_COMMON_MEMBERS
vlc_va_sys_t *sys;
char *description; char *description;
bool direct_rendering; bool direct_rendering;
vlc_object_t *obj;
int (*setup)(vlc_va_t *, void **hw, vlc_fourcc_t *output, int (*setup)(vlc_va_t *, void **hw, vlc_fourcc_t *output,
int width, int height); int width, int height);
...@@ -74,9 +77,9 @@ static inline int vlc_va_Display(vlc_va_t *va, picture_t *dst) ...@@ -74,9 +77,9 @@ static inline int vlc_va_Display(vlc_va_t *va, picture_t *dst)
static inline void vlc_va_Delete(vlc_va_t *va) static inline void vlc_va_Delete(vlc_va_t *va)
{ {
va->close(va); va->close(va);
vlc_object_release(va);
} }
vlc_va_t *vlc_va_NewVaapi(vlc_object_t *obj, int codec_id); int vlc_va_New(vlc_va_t *, int pix, int codec, const es_format_t *);
vlc_va_t *vlc_va_NewDxva2(vlc_object_t *log, int codec_id);
#endif #endif
...@@ -49,13 +49,10 @@ ...@@ -49,13 +49,10 @@
#include "vaapi.h" #include "vaapi.h"
#include "copy.h" #include "copy.h"
typedef struct struct vlc_va_sys_t
{ {
vlc_va_t va;
/* */ /* */
vlc_va_conn_t *conn; vlc_va_conn_t *conn;
VAConfigID i_config_id; VAConfigID i_config_id;
struct vaapi_context hw_ctx; struct vaapi_context hw_ctx;
...@@ -68,10 +65,9 @@ typedef struct ...@@ -68,10 +65,9 @@ typedef struct
VAImage image; VAImage image;
copy_cache_t image_cache; copy_cache_t image_cache;
};
} vlc_va_vaapi_t; static void Close( vlc_va_t *p_va );
static void Close( vlc_va_vaapi_t *p_va );
static unsigned int vaFallbackFourCC[] = static unsigned int vaFallbackFourCC[] =
{ {
...@@ -80,12 +76,6 @@ static unsigned int vaFallbackFourCC[] = ...@@ -80,12 +76,6 @@ static unsigned int vaFallbackFourCC[] =
VA_FOURCC( 'N', 'V', '1', '2' ) VA_FOURCC( 'N', 'V', '1', '2' )
}; };
/* */
static vlc_va_vaapi_t *vlc_va_vaapi_Get( void *p_va )
{
return p_va;
}
/* */ /* */
static bool HasProfile( VAProfile profile, VAProfile *list, const int list_size ) static bool HasProfile( VAProfile profile, VAProfile *list, const int list_size )
{ {
...@@ -186,12 +176,15 @@ static int CalculateSurfaceCount( const int i_codec_id ) ...@@ -186,12 +176,15 @@ static int CalculateSurfaceCount( const int i_codec_id )
} }
/* */ /* */
static int Open( vlc_va_vaapi_t *p_va, int i_codec_id ) static int Open( vlc_va_t *p_external, int i_codec_id )
{ {
int i_profile; int i_profile;
vlc_va_sys_t *p_va = calloc(1, sizeof(*p_va));
if (unlikeyly(p_va == NULL))
return VLC_ENOMEM;
/* */ /* */
memset( p_va, 0, sizeof(*p_va) );
p_va->i_config_id = VA_INVALID_ID; p_va->i_config_id = VA_INVALID_ID;
p_va->image.image_id = VA_INVALID_ID; p_va->image.image_id = VA_INVALID_ID;
...@@ -235,16 +228,19 @@ static int Open( vlc_va_vaapi_t *p_va, int i_codec_id ) ...@@ -235,16 +228,19 @@ static int Open( vlc_va_vaapi_t *p_va, int i_codec_id )
p_va->va.description = NULL; p_va->va.description = NULL;
p_va->conn->unlock(); p_va->conn->unlock();
p_external->sys = p_va;
return VLC_SUCCESS; return VLC_SUCCESS;
unlock: unlock:
p_va->conn->unlock(); p_va->conn->unlock();
error: error:
Close(p_va); Close(p_external);
free(p_va);
return VLC_EGENERIC; return VLC_EGENERIC;
} }
static void DestroyDecodingContext( vlc_va_vaapi_t *p_va ) static void DestroyDecodingContext( vlc_va_sys_t *p_va )
{ {
p_va->conn->lock(); p_va->conn->lock();
if( p_va->image.image_id != VA_INVALID_ID ) if( p_va->image.image_id != VA_INVALID_ID )
...@@ -270,7 +266,7 @@ static void DestroyDecodingContext( vlc_va_vaapi_t *p_va ) ...@@ -270,7 +266,7 @@ static void DestroyDecodingContext( vlc_va_vaapi_t *p_va )
p_va->conn->unlock(); p_va->conn->unlock();
} }
static int CreateDecodingContext( vlc_va_vaapi_t *p_va, void **pp_hw_ctx, vlc_fourcc_t *pi_chroma, static int CreateDecodingContext( vlc_va_sys_t *p_va, void **pp_hw_ctx, vlc_fourcc_t *pi_chroma,
int i_width, int i_height ) int i_width, int i_height )
{ {
assert( i_width > 0 && i_height > 0 ); assert( i_width > 0 && i_height > 0 );
...@@ -383,7 +379,7 @@ error: ...@@ -383,7 +379,7 @@ error:
static int Setup( vlc_va_t *p_external, void **pp_hw_ctx, vlc_fourcc_t *pi_chroma, static int Setup( vlc_va_t *p_external, void **pp_hw_ctx, vlc_fourcc_t *pi_chroma,
int i_width, int i_height ) int i_width, int i_height )
{ {
vlc_va_vaapi_t *p_va = vlc_va_vaapi_Get(p_external); vlc_va_sys_t *p_va = p_external->sys;
if( p_va->i_surface_width == i_width && if( p_va->i_surface_width == i_width &&
p_va->i_surface_height == i_height ) p_va->i_surface_height == i_height )
...@@ -405,7 +401,7 @@ static int Setup( vlc_va_t *p_external, void **pp_hw_ctx, vlc_fourcc_t *pi_chrom ...@@ -405,7 +401,7 @@ static int Setup( vlc_va_t *p_external, void **pp_hw_ctx, vlc_fourcc_t *pi_chrom
} }
static int Extract( vlc_va_t *p_external, picture_t *p_picture, AVFrame *p_ff ) static int Extract( vlc_va_t *p_external, picture_t *p_picture, AVFrame *p_ff )
{ {
vlc_va_vaapi_t *p_va = vlc_va_vaapi_Get(p_external); vlc_va_sys_t *p_va = p_external->sys;
if( !p_va->image_cache.buffer ) if( !p_va->image_cache.buffer )
return VLC_EGENERIC; return VLC_EGENERIC;
...@@ -494,7 +490,7 @@ error: ...@@ -494,7 +490,7 @@ error:
static void Put(vlc_va_t *p_external, AVFrame *p_ff, picture_t *p_picture ) static void Put(vlc_va_t *p_external, AVFrame *p_ff, picture_t *p_picture )
{ {
vlc_va_vaapi_t *p_va = vlc_va_vaapi_Get(p_external); vlc_va_sys_t *p_va = p_external->sys;
p_va->conn->lock(); p_va->conn->lock();
...@@ -519,7 +515,7 @@ static void Put(vlc_va_t *p_external, AVFrame *p_ff, picture_t *p_picture ) ...@@ -519,7 +515,7 @@ static void Put(vlc_va_t *p_external, AVFrame *p_ff, picture_t *p_picture )
static int DisplayPicture( vlc_va_t *p_external, picture_t *p_picture ) static int DisplayPicture( vlc_va_t *p_external, picture_t *p_picture )
{ {
vlc_va_vaapi_t *p_va = vlc_va_vaapi_Get(p_external); vlc_va_sys_t *p_va = p_external->sys;
p_va->conn->lock(); p_va->conn->lock();
...@@ -546,14 +542,14 @@ error: ...@@ -546,14 +542,14 @@ error:
static int Get( vlc_va_t *p_external, AVFrame *p_ff ) static int Get( vlc_va_t *p_external, AVFrame *p_ff )
{ {
vlc_va_vaapi_t *p_va = vlc_va_vaapi_Get(p_external); vlc_va_sys_t *p_va = p_external->sys;
p_va->conn->lock(); p_va->conn->lock();
vlc_va_surface_t *p_surface = vlc_va_conn_GetSurface(p_va->conn); vlc_va_surface_t *p_surface = vlc_va_conn_GetSurface(p_va->conn);
if (!p_surface) if (!p_surface)
{ {
msg_Warn(p_external->obj, "No free surface found."); msg_Warn(p_external, "No free surface found.");
p_va->conn->unlock(); p_va->conn->unlock();
return VLC_EGENERIC; return VLC_EGENERIC;
} }
...@@ -576,7 +572,7 @@ static int Get( vlc_va_t *p_external, AVFrame *p_ff ) ...@@ -576,7 +572,7 @@ static int Get( vlc_va_t *p_external, AVFrame *p_ff )
static void Release( vlc_va_t *p_external, AVFrame *p_ff ) static void Release( vlc_va_t *p_external, AVFrame *p_ff )
{ {
vlc_va_vaapi_t *p_va = vlc_va_vaapi_Get(p_external); vlc_va_sys_t *p_va = p_external->sys;
p_va->conn->lock(); p_va->conn->lock();
VASurfaceID i_surface_id = (VASurfaceID)(uintptr_t)p_ff->data[3]; VASurfaceID i_surface_id = (VASurfaceID)(uintptr_t)p_ff->data[3];
...@@ -584,7 +580,7 @@ static void Release( vlc_va_t *p_external, AVFrame *p_ff ) ...@@ -584,7 +580,7 @@ static void Release( vlc_va_t *p_external, AVFrame *p_ff )
p_va->conn->unlock(); p_va->conn->unlock();
} }
static void Close( vlc_va_vaapi_t *p_va ) static void Close( vlc_va_sys_t *p_va )
{ {
if( p_va->i_surface_width || p_va->i_surface_height ) if( p_va->i_surface_width || p_va->i_surface_height )
DestroyDecodingContext( p_va ); DestroyDecodingContext( p_va );
...@@ -602,15 +598,15 @@ static void Close( vlc_va_vaapi_t *p_va ) ...@@ -602,15 +598,15 @@ static void Close( vlc_va_vaapi_t *p_va )
static void Delete( vlc_va_t *p_external ) static void Delete( vlc_va_t *p_external )
{ {
vlc_va_vaapi_t *p_va = vlc_va_vaapi_Get(p_external); vlc_va_sys_t *p_va = p_external->sys;
Close( p_va ); Close( p_va );
free( p_va->va.description ); free( p_external->description );
free( p_va ); free( p_va );
} }
static bool QuerySurfaceReady( vlc_va_t *p_external, picture_t *pic ) static bool QuerySurfaceReady( vlc_va_t *p_external, picture_t *pic )
{ {
vlc_va_vaapi_t *p_va = vlc_va_vaapi_Get(p_external); vlc_va_sys_t *p_va = p_external->p_sys;
assert(pic); assert(pic);
assert(pic->p_sys); assert(pic->p_sys);
...@@ -636,31 +632,35 @@ static bool QuerySurfaceReady( vlc_va_t *p_external, picture_t *pic ) ...@@ -636,31 +632,35 @@ static bool QuerySurfaceReady( vlc_va_t *p_external, picture_t *pic )
} }
/* */ /* */
vlc_va_t *vlc_va_NewVaapi( vlc_object_t *obj, int i_codec_id ) int vlc_va_New( vlc_va_t *p_va, int pixfmt, int i_codec_id,
const es_format_t *fmt )
{ {
if( !vlc_xlib_init( obj ) ) /* Only VLD supported */
return NULL; if( pixfmt != PIX_FMT_VAAPI_VLD )
return VLC_EGENERIC;
vlc_va_vaapi_t *p_va = calloc( 1, sizeof(*p_va) );
if( !p_va )
return NULL;
if( Open( p_va, i_codec_id ) ) if( !vlc_xlib_init( VLC_OBJECT(p_va) ) )
{ {
free( p_va ); msg_Warn( p_va, "Ignoring VA API" );
return NULL; return VLC_EGENERIC;
} }
(void) fmt;
int err = Open( p_va, i_codec_id );
if( err )
return err;
/* */ /* */
p_va->va.direct_rendering = p_va->conn->b_direct_rendering; p_va->direct_rendering = p_va->conn->b_direct_rendering;
p_va->va.obj = obj; p_va->setup = Setup;
p_va->va.setup = Setup; p_va->get = Get;
p_va->va.get = Get; p_va->put = Put;
p_va->va.put = Put; p_va->release = Release;
p_va->va.release = Release; p_va->extract = Extract;
p_va->va.extract = Extract; p_va->display = DisplayPicture;
p_va->va.display = DisplayPicture; p_va->query = QuerySurfaceReady;
p_va->va.query = QuerySurfaceReady; p_va->close = Delete;
p_va->va.close = Delete; return VLC_SUCCESS;
return &p_va->va;
} }
...@@ -1168,32 +1168,15 @@ static enum PixelFormat ffmpeg_GetFormat( AVCodecContext *p_context, ...@@ -1168,32 +1168,15 @@ static enum PixelFormat ffmpeg_GetFormat( AVCodecContext *p_context,
msg_Dbg( p_dec, "Available decoder output format %d (%s)", pi_fmt[i], msg_Dbg( p_dec, "Available decoder output format %d (%s)", pi_fmt[i],
name ? name : "unknown" ); name ? name : "unknown" );
/* Only VLD supported */ vlc_va_t *p_va = vlc_object_create( p_dec, sizeof( *p_va ) );
if( pi_fmt[i] == PIX_FMT_VAAPI_VLD ) if( unlikely(p_va == NULL) )
{
if( !var_InheritBool( p_dec, "xlib" ) )
{
msg_Warn( p_dec, "Ignoring VA API" );
continue;
}
#ifdef HAVE_AVCODEC_VAAPI
msg_Dbg( p_dec, "Trying VA API" );
p_sys->p_va = vlc_va_NewVaapi( VLC_OBJECT(p_dec), p_sys->i_codec_id );
if( !p_sys->p_va )
msg_Warn( p_dec, "Failed to open VA API" );
#else
continue; continue;
#endif if( vlc_va_New( p_va, pi_fmt[i], p_sys->i_codec_id, &p_dec->fmt_in ) )
}
#ifdef HAVE_AVCODEC_DXVA2
if( pi_fmt[i] == PIX_FMT_DXVA2_VLD )
{ {
msg_Dbg( p_dec, "Trying DXVA2" ); vlc_object_release( p_va );
p_sys->p_va = vlc_va_NewDxva2( VLC_OBJECT(p_dec), p_sys->i_codec_id ); msg_Dbg( p_dec, "acceleration not available" );
if( !p_sys->p_va ) continue;
msg_Warn( p_dec, "Failed to open DXVA2" );
} }
#endif
if( p_sys->p_va && if( p_sys->p_va &&
p_context->width > 0 && p_context->height > 0 ) p_context->width > 0 && p_context->height > 0 )
......
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