Commit 93fd69f4 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

avcodec: make vlc_va_t a VLC object

parent 1962cd30
......@@ -225,12 +225,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;
......@@ -276,13 +272,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;
}
/* */
......@@ -486,12 +484,12 @@ 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_New(vlc_object_t *log, int pixfmt, int codec_id,
const es_format_t *fmt)
int vlc_va_New(vlc_va_t *log, int pixfmt, int codec_id,
const es_format_t *fmt)
{
if( pixfmt != PIX_FMT_DXVA2_VLD )
return NULL;
......@@ -500,8 +498,9 @@ vlc_va_t *vlc_va_New(vlc_object_t *log, int pixfmt, int codec_id,
if (!va)
return NULL;
external->sys = va;
/* */
va->log = log;
va->log = VLC_OBJECT(external);
va->codec_id = codec_id;
(void) fmt;
......@@ -542,17 +541,17 @@ vlc_va_t *vlc_va_New(vlc_object_t *log, int pixfmt, int codec_id,
}
/* 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->release = Release;
external->extract = Extract;
external->close = Close;
return VLC_SUCCESS;
error:
Close(&va->va);
return NULL;
Close(va);
return VLC_EGENERIC;
}
/* */
......
......@@ -25,7 +25,12 @@
#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;
int (*setup)(vlc_va_t *, void **hw, vlc_fourcc_t *output,
......@@ -56,8 +61,9 @@ static inline int vlc_va_Extract(vlc_va_t *va, picture_t *dst, AVFrame *src)
static inline void vlc_va_Delete(vlc_va_t *va)
{
va->close(va);
vlc_object_release(va);
}
vlc_va_t *vlc_va_New(vlc_object_t *, int pix, int codec, const es_format_t *);
int vlc_va_New(vlc_va_t *, int pix, int codec, const es_format_t *);
#endif
......@@ -50,13 +50,8 @@ typedef struct
} vlc_va_surface_t;
typedef struct
struct vlc_va_sys_t
{
vlc_va_t va;
vlc_object_t *log;
/* */
Display *p_display_x11;
VADisplay p_display;
......@@ -81,16 +76,15 @@ typedef struct
VAImage image;
copy_cache_t image_cache;
} vlc_va_vaapi_t;
static vlc_va_vaapi_t *vlc_va_vaapi_Get( void *p_va )
{
return p_va;
}
};
/* */
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 )
{
vlc_va_sys_t *p_va = calloc( 1, sizeof(*p_va) );
if ( unlikely(p_va == NULL) )
return VLC_ENOMEM;
VAProfile i_profile, *p_profiles_list;
bool b_supported_profile = false;
int i_profiles_nb = 0;
......@@ -133,20 +127,20 @@ static int Open( vlc_va_vaapi_t *p_va, int i_codec_id )
p_va->p_display_x11 = XOpenDisplay(NULL);
if( !p_va->p_display_x11 )
{
msg_Err( p_va->log, "Could not connect to X server" );
msg_Err( p_external, "Could not connect to X server" );
goto error;
}
p_va->p_display = vaGetDisplay( p_va->p_display_x11 );
if( !p_va->p_display )
{
msg_Err( p_va->log, "Could not get a VAAPI device" );
msg_Err( p_external, "Could not get a VAAPI device" );
goto error;
}
if( vaInitialize( p_va->p_display, &p_va->i_version_major, &p_va->i_version_minor ) )
{
msg_Err( p_va->log, "Failed to initialize the VAAPI device" );
msg_Err( p_external, "Failed to initialize the VAAPI device" );
goto error;
}
......@@ -171,7 +165,7 @@ static int Open( vlc_va_vaapi_t *p_va, int i_codec_id )
free( p_profiles_list );
if ( !b_supported_profile )
{
msg_Dbg( p_va->log, "Codec and profile not supported by the hardware" );
msg_Dbg( p_external, "Codec and profile not supported by the hardware" );
goto error;
}
......@@ -195,17 +189,18 @@ 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",
if( asprintf( &p_external->description, "VA API version %d.%d",
p_va->i_version_major, p_va->i_version_minor ) < 0 )
p_va->va.description = NULL;
p_external->description = NULL;
p_external->sys = p_va;
return VLC_SUCCESS;
error:
return VLC_EGENERIC;
}
static void DestroySurfaces( vlc_va_vaapi_t *p_va )
static void DestroySurfaces( vlc_va_sys_t *p_va )
{
if( p_va->image.image_id != VA_INVALID_ID )
{
......@@ -232,7 +227,7 @@ static void DestroySurfaces( vlc_va_vaapi_t *p_va )
p_va->i_surface_width = 0;
p_va->i_surface_height = 0;
}
static int CreateSurfaces( vlc_va_vaapi_t *p_va, void **pp_hw_ctx, vlc_fourcc_t *pi_chroma,
static int CreateSurfaces( 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 );
......@@ -341,7 +336,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 )
......@@ -363,7 +358,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;
......@@ -433,7 +428,7 @@ static int Extract( vlc_va_t *p_external, picture_t *p_picture, 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;
int i_old;
int i;
......@@ -470,7 +465,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;
VASurfaceID i_surface_id = (VASurfaceID)(uintptr_t)p_ff->data[3];
......@@ -483,7 +478,7 @@ static void Release( vlc_va_t *p_external, AVFrame *p_ff )
}
}
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 )
DestroySurfaces( p_va );
......@@ -497,44 +492,37 @@ 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 );
}
/* */
vlc_va_t *vlc_va_New( vlc_object_t *obj, int pixfmt, int i_codec_id,
const es_format_t *fmt )
int vlc_va_New( vlc_va_t *p_va, int pixfmt, int i_codec_id,
const es_format_t *fmt )
{
/* Only VLD supported */
if( pixfmt != PIX_FMT_VAAPI_VLD )
return NULL;
return VLC_EGENERIC;
if( !vlc_xlib_init( obj ) )
if( !vlc_xlib_init( VLC_OBJECT(p_va) ) )
{
msg_Warn( obj, "Ignoring VA API" );
return NULL;
msg_Warn( p_va, "Ignoring VA API" );
return VLC_EGENERIC;
}
vlc_va_vaapi_t *p_va = calloc( 1, sizeof(*p_va) );
if( !p_va )
return NULL;
p_va->log = obj;
(void) fmt;
if( Open( p_va, i_codec_id ) )
{
free( p_va );
return NULL;
}
int err = Open( p_va, i_codec_id );
if( err )
return err;
/* */
p_va->va.setup = Setup;
p_va->va.get = Get;
p_va->va.release = Release;
p_va->va.extract = Extract;
p_va->va.close = Delete;
return &p_va->va;
p_va->setup = Setup;
p_va->get = Get;
p_va->release = Release;
p_va->extract = Extract;
p_va->close = Delete;
return VLC_SUCCESS;
}
......@@ -37,9 +37,8 @@
#include <libavcodec/vda.h>
#include <VideoDecodeAcceleration/VDADecoder.h>
typedef struct
struct vlc_va_sys_t
{
vlc_va_t va;
struct vda_context hw_ctx;
const uint8_t *p_extradata;
......@@ -51,11 +50,13 @@ typedef struct
vlc_object_t *p_log;
} vlc_va_vda_t;
};
static vlc_va_vda_t *vlc_va_vda_Get( void *p_va )
typedef struct vlc_va_sys_t vlc_va_vda_t;
static vlc_va_vda_t *vlc_va_vda_Get( vlc_va_t *p_va )
{
return p_va;
return p_va->sys;
}
/*****************************************************************************
......@@ -240,8 +241,8 @@ static void Close( vlc_va_t *p_external )
free( p_va );
}
vlc_va_t *vlc_va_New( vlc_object_t *p_log, int pixfmt, int i_codec_id,
const es_format_t *fmt )
int vlc_va_New( vlc_va_t *external, int pixfmt, int i_codec_id,
const es_format_t *fmt )
{
if( pixfmt != PIX_FMT_VDA_VLD || i_codec_id != CODEC_ID_H264 )
return NULL;
......@@ -256,15 +257,17 @@ vlc_va_t *vlc_va_New( vlc_object_t *p_log, int pixfmt, int i_codec_id,
if( !p_va )
return NULL;
p_va->p_log = p_log;
p_va->p_log = VLC_OBJECT(external);
p_va->p_extradata = fmt->p_extra;
p_va->i_extradata = fmt->i_extra;
p_va->va.setup = Setup;
p_va->va.get = Get;
p_va->va.release = Release;
p_va->va.extract = Extract;
p_va->va.close = Close;
external->sys = p_va;
external->description = (char *)"VDA";
external->setup = Setup;
external->get = Get;
external->release = Release;
external->extract = Extract;
external->close = Close;
return &p_va->va;
return VLC_SUCCESS;
}
......@@ -1144,9 +1144,12 @@ static enum PixelFormat ffmpeg_GetFormat( AVCodecContext *p_context,
msg_Dbg( p_dec, "Available decoder output format %d (%s)", pi_fmt[i],
name ? name : "unknown" );
vlc_va_t *p_va = vlc_va_New( VLC_OBJECT(p_dec), pi_fmt[i], p_sys->i_codec_id, &p_dec->fmt_in );
if( p_va == NULL )
vlc_va_t *p_va = vlc_object_create( p_dec, sizeof( *p_va ) );
if( unlikely(p_va == NULL) )
continue;
if( vlc_va_New( p_va, pi_fmt[i], p_sys->i_codec_id, &p_dec->fmt_in ) )
{
vlc_object_release( p_va );
msg_Dbg( p_dec, "acceleration not available" );
continue;
}
......
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