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 { ...@@ -225,12 +225,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;
...@@ -276,13 +272,15 @@ typedef struct ...@@ -276,13 +272,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;
} }
/* */ /* */
...@@ -486,11 +484,11 @@ static void Close(vlc_va_t *external) ...@@ -486,11 +484,11 @@ 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_New(vlc_object_t *log, int pixfmt, int codec_id, int vlc_va_New(vlc_va_t *log, int pixfmt, int codec_id,
const es_format_t *fmt) const es_format_t *fmt)
{ {
if( pixfmt != PIX_FMT_DXVA2_VLD ) if( pixfmt != PIX_FMT_DXVA2_VLD )
...@@ -500,8 +498,9 @@ vlc_va_t *vlc_va_New(vlc_object_t *log, int pixfmt, int codec_id, ...@@ -500,8 +498,9 @@ vlc_va_t *vlc_va_New(vlc_object_t *log, int pixfmt, int codec_id,
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;
(void) fmt; (void) fmt;
...@@ -542,17 +541,17 @@ vlc_va_t *vlc_va_New(vlc_object_t *log, int pixfmt, int codec_id, ...@@ -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 */ /* 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->release = Release;
va->va.extract = Extract; external->extract = Extract;
va->va.close = Close; external->close = Close;
return &va->va; return VLC_SUCCESS;
error: error:
Close(&va->va); Close(va);
return NULL; return VLC_EGENERIC;
} }
/* */ /* */
......
...@@ -25,7 +25,12 @@ ...@@ -25,7 +25,12 @@
#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;
int (*setup)(vlc_va_t *, void **hw, vlc_fourcc_t *output, 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) ...@@ -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) 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_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 #endif
...@@ -50,13 +50,8 @@ typedef struct ...@@ -50,13 +50,8 @@ typedef struct
} vlc_va_surface_t; } vlc_va_surface_t;
typedef struct struct vlc_va_sys_t
{ {
vlc_va_t va;
vlc_object_t *log;
/* */
Display *p_display_x11; Display *p_display_x11;
VADisplay p_display; VADisplay p_display;
...@@ -81,16 +76,15 @@ typedef struct ...@@ -81,16 +76,15 @@ typedef struct
VAImage image; VAImage image;
copy_cache_t image_cache; 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; VAProfile i_profile, *p_profiles_list;
bool b_supported_profile = false; bool b_supported_profile = false;
int i_profiles_nb = 0; int i_profiles_nb = 0;
...@@ -133,20 +127,20 @@ static int Open( vlc_va_vaapi_t *p_va, int i_codec_id ) ...@@ -133,20 +127,20 @@ static int Open( vlc_va_vaapi_t *p_va, int i_codec_id )
p_va->p_display_x11 = XOpenDisplay(NULL); p_va->p_display_x11 = XOpenDisplay(NULL);
if( !p_va->p_display_x11 ) 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; goto error;
} }
p_va->p_display = vaGetDisplay( p_va->p_display_x11 ); p_va->p_display = vaGetDisplay( p_va->p_display_x11 );
if( !p_va->p_display ) 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; goto error;
} }
if( vaInitialize( p_va->p_display, &p_va->i_version_major, &p_va->i_version_minor ) ) 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; goto error;
} }
...@@ -171,7 +165,7 @@ static int Open( vlc_va_vaapi_t *p_va, int i_codec_id ) ...@@ -171,7 +165,7 @@ static int Open( vlc_va_vaapi_t *p_va, int i_codec_id )
free( p_profiles_list ); free( p_profiles_list );
if ( !b_supported_profile ) 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; goto error;
} }
...@@ -195,17 +189,18 @@ static int Open( vlc_va_vaapi_t *p_va, int i_codec_id ) ...@@ -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; 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->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; return VLC_SUCCESS;
error: error:
return VLC_EGENERIC; 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 ) if( p_va->image.image_id != VA_INVALID_ID )
{ {
...@@ -232,7 +227,7 @@ static void DestroySurfaces( vlc_va_vaapi_t *p_va ) ...@@ -232,7 +227,7 @@ static void DestroySurfaces( vlc_va_vaapi_t *p_va )
p_va->i_surface_width = 0; p_va->i_surface_width = 0;
p_va->i_surface_height = 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 ) int i_width, int i_height )
{ {
assert( i_width > 0 && i_height > 0 ); assert( i_width > 0 && i_height > 0 );
...@@ -341,7 +336,7 @@ error: ...@@ -341,7 +336,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 )
...@@ -363,7 +358,7 @@ static int Setup( vlc_va_t *p_external, void **pp_hw_ctx, vlc_fourcc_t *pi_chrom ...@@ -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 ) 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;
...@@ -433,7 +428,7 @@ static int Extract( vlc_va_t *p_external, picture_t *p_picture, AVFrame *p_ff ) ...@@ -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 ) 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_old;
int i; int i;
...@@ -470,7 +465,7 @@ static int Get( vlc_va_t *p_external, AVFrame *p_ff ) ...@@ -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 ) 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]; 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 ) ...@@ -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 ) if( p_va->i_surface_width || p_va->i_surface_height )
DestroySurfaces( p_va ); DestroySurfaces( p_va );
...@@ -497,44 +492,37 @@ static void Close( vlc_va_vaapi_t *p_va ) ...@@ -497,44 +492,37 @@ 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 );
} }
/* */ /* */
vlc_va_t *vlc_va_New( vlc_object_t *obj, int pixfmt, int i_codec_id, int vlc_va_New( vlc_va_t *p_va, int pixfmt, int i_codec_id,
const es_format_t *fmt ) const es_format_t *fmt )
{ {
/* Only VLD supported */ /* Only VLD supported */
if( pixfmt != PIX_FMT_VAAPI_VLD ) 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" ); msg_Warn( p_va, "Ignoring VA API" );
return NULL; 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; (void) fmt;
if( Open( p_va, i_codec_id ) ) int err = Open( p_va, i_codec_id );
{ if( err )
free( p_va ); return err;
return NULL;
}
/* */ /* */
p_va->va.setup = Setup; p_va->setup = Setup;
p_va->va.get = Get; p_va->get = Get;
p_va->va.release = Release; p_va->release = Release;
p_va->va.extract = Extract; p_va->extract = Extract;
p_va->va.close = Delete; p_va->close = Delete;
return &p_va->va; return VLC_SUCCESS;
} }
...@@ -37,9 +37,8 @@ ...@@ -37,9 +37,8 @@
#include <libavcodec/vda.h> #include <libavcodec/vda.h>
#include <VideoDecodeAcceleration/VDADecoder.h> #include <VideoDecodeAcceleration/VDADecoder.h>
typedef struct struct vlc_va_sys_t
{ {
vlc_va_t va;
struct vda_context hw_ctx; struct vda_context hw_ctx;
const uint8_t *p_extradata; const uint8_t *p_extradata;
...@@ -51,11 +50,13 @@ typedef struct ...@@ -51,11 +50,13 @@ typedef struct
vlc_object_t *p_log; 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,7 +241,7 @@ static void Close( vlc_va_t *p_external ) ...@@ -240,7 +241,7 @@ static void Close( vlc_va_t *p_external )
free( p_va ); free( p_va );
} }
vlc_va_t *vlc_va_New( vlc_object_t *p_log, int pixfmt, int i_codec_id, int vlc_va_New( vlc_va_t *external, int pixfmt, int i_codec_id,
const es_format_t *fmt ) const es_format_t *fmt )
{ {
if( pixfmt != PIX_FMT_VDA_VLD || i_codec_id != CODEC_ID_H264 ) if( pixfmt != PIX_FMT_VDA_VLD || i_codec_id != CODEC_ID_H264 )
...@@ -256,15 +257,17 @@ vlc_va_t *vlc_va_New( vlc_object_t *p_log, int pixfmt, int i_codec_id, ...@@ -256,15 +257,17 @@ vlc_va_t *vlc_va_New( vlc_object_t *p_log, int pixfmt, int i_codec_id,
if( !p_va ) if( !p_va )
return NULL; return NULL;
p_va->p_log = p_log; p_va->p_log = VLC_OBJECT(external);
p_va->p_extradata = fmt->p_extra; p_va->p_extradata = fmt->p_extra;
p_va->i_extradata = fmt->i_extra; p_va->i_extradata = fmt->i_extra;
p_va->va.setup = Setup; external->sys = p_va;
p_va->va.get = Get; external->description = (char *)"VDA";
p_va->va.release = Release; external->setup = Setup;
p_va->va.extract = Extract; external->get = Get;
p_va->va.close = Close; 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, ...@@ -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], msg_Dbg( p_dec, "Available decoder output format %d (%s)", pi_fmt[i],
name ? name : "unknown" ); 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 ); vlc_va_t *p_va = vlc_object_create( p_dec, sizeof( *p_va ) );
if( p_va == NULL ) 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" ); msg_Dbg( p_dec, "acceleration not available" );
continue; 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