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 {
} vlc_va_surface_t;
#define VA_DXVA2_MAX_SURFACE_COUNT (64)
typedef struct
struct vlc_va_sys_t
{
/* */
vlc_va_t va;
/* */
vlc_object_t *log;
int codec_id;
int width;
......@@ -284,13 +280,15 @@ typedef struct
vlc_va_surface_t 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));
return external;
vlc_va_dxva2_t *va = external->sys;
assert(VLC_OBJECT(external) == va->log);
return va;
}
/* */
......@@ -494,68 +492,76 @@ static void Close(vlc_va_t *external)
if (va->hd3d9_dll)
FreeLibrary(va->hd3d9_dll);
free(va->va.description);
free(external->description);
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));
if (!va)
return NULL;
external->sys = va;
/* */
va->log = log;
va->log = VLC_OBJECT(external);
va->codec_id = codec_id;
/* Load dll*/
va->hd3d9_dll = LoadLibrary(TEXT("D3D9.DLL"));
if (!va->hd3d9_dll) {
msg_Warn(va->log, "cannot load d3d9.dll");
msg_Warn(p_external, "cannot load d3d9.dll");
goto error;
}
va->hdxva2_dll = LoadLibrary(TEXT("DXVA2.DLL"));
if (!va->hdxva2_dll) {
msg_Warn(va->log, "cannot load dxva2.dll");
msg_Warn(p_external, "cannot load dxva2.dll");
goto error;
}
msg_Dbg(va->log, "DLLs loaded");
msg_Dbg(p_external, "DLLs loaded");
/* */
if (D3dCreateDevice(va)) {
msg_Err(va->log, "Failed to create Direct3D device");
msg_Err(p_external, "Failed to create Direct3D device");
goto error;
}
msg_Dbg(va->log, "D3dCreateDevice succeed");
if (D3dCreateDeviceManager(va)) {
msg_Err(va->log, "D3dCreateDeviceManager failed");
msg_Err(p_external, "D3dCreateDeviceManager failed");
goto error;
}
if (DxCreateVideoService(va)) {
msg_Err(va->log, "DxCreateVideoService failed");
msg_Err(p_external, "DxCreateVideoService failed");
goto error;
}
/* */
if (DxFindVideoServiceConversion(va, &va->input, &va->render)) {
msg_Err(va->log, "DxFindVideoServiceConversion failed");
msg_Err(p_external, "DxFindVideoServiceConversion failed");
goto error;
}
/* TODO print the hardware name/vendor for debugging purposes */
va->va.description = DxDescribe(va);
va->va.setup = Setup;
va->va.get = Get;
va->va.release = Release;
va->va.extract = Extract;
va->va.close = Close;
return &va->va;
external->description = DxDescribe(va);
external->setup = Setup;
external->get = Get;
external->put = NULL;
external->release = Release;
external->extract = Extract;
external->display = NULL;
external->query = NULL;
external->close = Close;
return VLC_SUCCESS;
error:
Close(&va->va);
return NULL;
Close(va);
return VLC_EGENERIC;
}
/* */
......
......@@ -25,11 +25,14 @@
#define _VLC_VA_H 1
typedef struct vlc_va_t vlc_va_t;
typedef struct vlc_va_sys_t vlc_va_sys_t;
struct vlc_va_t {
VLC_COMMON_MEMBERS
vlc_va_sys_t *sys;
char *description;
bool direct_rendering;
vlc_object_t *obj;
int (*setup)(vlc_va_t *, void **hw, vlc_fourcc_t *output,
int width, int height);
......@@ -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)
{
va->close(va);
vlc_object_release(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);
int vlc_va_New(vlc_va_t *, int pix, int codec, const es_format_t *);
#endif
......@@ -49,13 +49,10 @@
#include "vaapi.h"
#include "copy.h"
typedef struct
struct vlc_va_sys_t
{
vlc_va_t va;
/* */
vlc_va_conn_t *conn;
VAConfigID i_config_id;
struct vaapi_context hw_ctx;
......@@ -68,10 +65,9 @@ typedef struct
VAImage image;
copy_cache_t image_cache;
};
} vlc_va_vaapi_t;
static void Close( vlc_va_vaapi_t *p_va );
static void Close( vlc_va_t *p_va );
static unsigned int vaFallbackFourCC[] =
{
......@@ -80,12 +76,6 @@ static unsigned int vaFallbackFourCC[] =
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 )
{
......@@ -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;
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->image.image_id = VA_INVALID_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->conn->unlock();
p_external->sys = p_va;
return VLC_SUCCESS;
unlock:
p_va->conn->unlock();
error:
Close(p_va);
Close(p_external);
free(p_va);
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();
if( p_va->image.image_id != VA_INVALID_ID )
......@@ -270,7 +266,7 @@ static void DestroyDecodingContext( vlc_va_vaapi_t *p_va )
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 )
{
assert( i_width > 0 && i_height > 0 );
......@@ -383,7 +379,7 @@ error:
static int Setup( vlc_va_t *p_external, void **pp_hw_ctx, vlc_fourcc_t *pi_chroma,
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 &&
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
}
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 )
return VLC_EGENERIC;
......@@ -494,7 +490,7 @@ error:
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();
......@@ -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 )
{
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();
......@@ -546,14 +542,14 @@ error:
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();
vlc_va_surface_t *p_surface = vlc_va_conn_GetSurface(p_va->conn);
if (!p_surface)
{
msg_Warn(p_external->obj, "No free surface found.");
msg_Warn(p_external, "No free surface found.");
p_va->conn->unlock();
return VLC_EGENERIC;
}
......@@ -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 )
{
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();
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 )
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 )
DestroyDecodingContext( p_va );
......@@ -602,15 +598,15 @@ static void Close( vlc_va_vaapi_t *p_va )
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 );
free( p_va->va.description );
free( p_external->description );
free( p_va );
}
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->p_sys);
......@@ -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 ) )
return NULL;
vlc_va_vaapi_t *p_va = calloc( 1, sizeof(*p_va) );
if( !p_va )
return NULL;
/* Only VLD supported */
if( pixfmt != PIX_FMT_VAAPI_VLD )
return VLC_EGENERIC;
if( Open( p_va, i_codec_id ) )
if( !vlc_xlib_init( VLC_OBJECT(p_va) ) )
{
free( p_va );
return NULL;
msg_Warn( p_va, "Ignoring VA API" );
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->va.obj = obj;
p_va->va.setup = Setup;
p_va->va.get = Get;
p_va->va.put = Put;
p_va->va.release = Release;
p_va->va.extract = Extract;
p_va->va.display = DisplayPicture;
p_va->va.query = QuerySurfaceReady;
p_va->va.close = Delete;
return &p_va->va;
p_va->direct_rendering = p_va->conn->b_direct_rendering;
p_va->setup = Setup;
p_va->get = Get;
p_va->put = Put;
p_va->release = Release;
p_va->extract = Extract;
p_va->display = DisplayPicture;
p_va->query = QuerySurfaceReady;
p_va->close = Delete;
return VLC_SUCCESS;
}
......@@ -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],
name ? name : "unknown" );
/* Only VLD supported */
if( pi_fmt[i] == PIX_FMT_VAAPI_VLD )
{
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
vlc_va_t *p_va = vlc_object_create( p_dec, sizeof( *p_va ) );
if( unlikely(p_va == NULL) )
continue;
#endif
}
#ifdef HAVE_AVCODEC_DXVA2
if( pi_fmt[i] == PIX_FMT_DXVA2_VLD )
if( vlc_va_New( p_va, pi_fmt[i], p_sys->i_codec_id, &p_dec->fmt_in ) )
{
msg_Dbg( p_dec, "Trying DXVA2" );
p_sys->p_va = vlc_va_NewDxva2( VLC_OBJECT(p_dec), p_sys->i_codec_id );
if( !p_sys->p_va )
msg_Warn( p_dec, "Failed to open DXVA2" );
vlc_object_release( p_va );
msg_Dbg( p_dec, "acceleration not available" );
continue;
}
#endif
if( p_sys->p_va &&
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