Commit 7f9d09bb authored by Jean-Paul Saman's avatar Jean-Paul Saman

codec/avcodec/va*.{c.h}: Implement picture pool

Implement picture pool for VAAPI-X11 vout.
parent ab1b18d4
......@@ -86,17 +86,21 @@ error:
void vlc_va_Terminate( vlc_va_conn_t *conn )
{
assert(conn);
conn->i_ref_count--;
if (conn->i_ref_count <= 0)
{
if( conn->p_display )
vaTerminate( conn->p_display );
if( conn->p_display_x11 )
XCloseDisplay( conn->p_display_x11 );
conn->p_display = 0;
conn->p_display_x11 = NULL;
}
if (conn->i_ref_count > 0)
return;
if( conn->p_display )
vaTerminate( conn->p_display );
if( conn->p_display_x11 )
XCloseDisplay( conn->p_display_x11 );
/* Reset values */
conn->p_display = 0;
conn->p_display_x11 = NULL;
conn->i_version_major = conn->i_version_minor = 0;
conn->i_ref_count = 0;
conn = NULL;
}
#endif
......@@ -33,6 +33,7 @@ struct vlc_va_t {
int (*get)(vlc_va_t *, AVFrame *frame);
void (*release)(vlc_va_t *, AVFrame *frame);
int (*extract)(vlc_va_t *, picture_t *dst, AVFrame *src);
int (*display)(vlc_va_t *, picture_t *dst, AVFrame *src);
void (*close)(vlc_va_t *);
};
......@@ -53,6 +54,10 @@ static inline int vlc_va_Extract(vlc_va_t *va, picture_t *dst, AVFrame *src)
{
return va->extract(va, dst, src);
}
static inline int vlc_va_Display(vlc_va_t *va, picture_t *dst, AVFrame *src)
{
return va->display(va, dst, src);
}
static inline void vlc_va_Delete(vlc_va_t *va)
{
va->close(va);
......@@ -74,6 +79,11 @@ struct vlc_va_conn_t
int vlc_va_Initialize(vlc_va_conn_t *conn, const char *display_name);
void vlc_va_Terminate(vlc_va_conn_t *conn);
struct picture_sys_t
{
VASurfaceID i_surface_id;
};
#endif
#endif
......
......@@ -27,6 +27,7 @@
#include <vlc_common.h>
#include <vlc_fourcc.h>
#include <vlc_picture.h>
#include <assert.h>
#ifdef HAVE_LIBAVCODEC_AVCODEC_H
......@@ -386,6 +387,31 @@ static int Extract( vlc_va_t *p_external, picture_t *p_picture, AVFrame *p_ff )
return VLC_SUCCESS;
}
static int DisplayPicture( vlc_va_t *p_external, picture_t *p_picture, AVFrame *p_ff )
{
vlc_va_vaapi_t *p_va = vlc_va_vaapi_Get(p_external);
if( !p_va->image_cache.buffer )
return VLC_EGENERIC;
VASurfaceID i_surface_id = (VASurfaceID)(uintptr_t)p_ff->data[3];
#if VA_CHECK_VERSION(0,31,0)
if( vaSyncSurface( p_va->conn->p_display, i_surface_id ) )
#else
if( vaSyncSurface( p_va->conn->p_display, p_va->i_context_id, i_surface_id ) )
#endif
return VLC_EGENERIC;
if (!p_picture->p_sys)
return VLC_ENOMEM;
assert( sizeof(p_picture->p_sys) == sizeof(picture_sys_t) );
p_picture->p_sys->i_surface_id = i_surface_id;
return VLC_SUCCESS;
}
static int Get( vlc_va_t *p_external, AVFrame *p_ff )
{
vlc_va_vaapi_t *p_va = vlc_va_vaapi_Get(p_external);
......@@ -477,6 +503,7 @@ vlc_va_t *vlc_va_NewVaapi( vlc_object_t *obj, int i_codec_id )
p_va->va.get = Get;
p_va->va.release = Release;
p_va->va.extract = Extract;
p_va->va.display = DisplayPicture;
p_va->va.close = Delete;
return &p_va->va;
}
......
......@@ -30,6 +30,7 @@
#include <vlc_common.h>
#include <vlc_plugin.h>
#include <vlc_picture.h>
#include <vlc_vout_display.h>
#include <vlc_picture_pool.h>
......@@ -145,8 +146,8 @@ static int CreateWindow(vout_display_t *vd)
xswa.background_pixel = WhitePixel(sys->conn->p_display_x11, sys->x11.screen);
sys->x11.window = XCreateWindow(sys->conn->p_display_x11, sys->x11.root,
0, 0, /*wnd_cfg.x, wnd_cfg.y,*/
1080, 720, /*wnd_cfg.width, wnd_cfg.height,*/
vd->source.i_y_offset, vd->source.i_x_offset,
vd->cfg->display.width, vd->cfg->display.height,
0, depth,
InputOutput, vi_info->visual, xswa_mask, &xswa);
if (sys->x11.window == None)
......@@ -203,9 +204,9 @@ int OpenVaapiX11 (vlc_object_t *obj)
vd->sys = sys;
sys->conn = NULL;
sys->visible = false;
sys->embed = MakeWindow(vd);
if (unlikely(sys->embed == NULL))
goto error;
......@@ -216,7 +217,8 @@ int OpenVaapiX11 (vlc_object_t *obj)
if (CreateWindow(vd) != VLC_SUCCESS)
goto error;
msg_Dbg(vd, "using VAAPI X11 window");
msg_Dbg(vd, "using VAAPI X11 window (version %d.%d)",
sys->conn->i_version_major, sys->conn->i_version_minor);
/* */
vout_display_info_t info = vd->info;
......@@ -226,7 +228,7 @@ int OpenVaapiX11 (vlc_object_t *obj)
/* Setup vout_display_t once everything is fine */
vd->info = info;
vd->pool = NULL; //Pool;
vd->pool = Pool;
vd->prepare = NULL; //PictureRender;
vd->display = PictureDisplay;
vd->control = Control;
......@@ -251,16 +253,26 @@ void CloseVaapiX11 (vlc_object_t *obj)
vout_display_t *vd = (vout_display_t *) obj;
vout_display_sys_t *sys = (vout_display_sys_t *) vd->sys;
DestroyWindow(vd);
if (sys->conn->p_display_x11)
if (sys->conn)
{
XFlush(sys->conn->p_display_x11);
XSync(sys->conn->p_display_x11, False);
DestroyWindow(vd);
if (sys->conn->p_display_x11)
{
XFlush(sys->conn->p_display_x11);
XSync(sys->conn->p_display_x11, False);
}
}
if (sys->embed)
vout_display_DeleteWindow (vd, sys->embed);
vlc_va_Terminate(sys->conn);
if (sys->conn)
vlc_va_Terminate(sys->conn);
if (sys->pool)
{
picture_pool_Delete(sys->pool);
sys->pool = NULL;
}
free(vd->sys);
}
......@@ -322,9 +334,9 @@ static int Control (vout_display_t *vd, int query, va_list ap)
case VOUT_DISPLAY_RESET_PICTURES:
{
#if 0
ResetPictures (vd);
#endif
picture_pool_Delete (sys->pool);
sys->pool = NULL;
vout_display_place_t place;
vout_display_PlacePicture (&place, &vd->source, vd->cfg, false);
......@@ -367,13 +379,13 @@ static void PictureDisplay (vout_display_t *vd, picture_t *pic, subpicture_t *su
{
vout_display_sys_t *sys = vd->sys;
VLC_UNUSED(subpicture);
VLC_UNUSED(sys);
#if 0
if (subpicture)
{
/* FIXME: blend subpicture into VAAPI structure */
}
#endif
vout_display_place_t place;
vout_display_PlacePicture (&place, &vd->source, vd->cfg, false);
......@@ -381,54 +393,91 @@ static void PictureDisplay (vout_display_t *vd, picture_t *pic, subpicture_t *su
if (!pic->b_progressive)
flags = pic->b_top_field_first ? VA_TOP_FIELD : VA_BOTTOM_FIELD;
VASurfaceID i_surface_id = (VASurfaceID)(uintptr_t)pic->p_sys;
#if VA_CHECK_VERSION(0,31,0)
if (vaSyncSurface(sys->display, i_surface_id))
#else
unsigned int i_context_id = /* FIXME: get context id */;
if (vaSyncSurface(sys->display, i_context_id, i_surface_id))
#endif
goto out;
VASurfaceID i_surface_id = pic->p_sys->i_surface_id;
VAStatus status = vaPutSurface(sys->display,
VAStatus status = vaPutSurface(sys->conn->p_display,
i_surface_id,
sys->x11.window,
vd->source.i_y_offset, vd->source.i_x_offset,
vd->fmt.i_visible_width, vd->fmt.i_visible_height,
place->x, place->y, place.width, place.height,
place.x, place.y, place.width, place.height,
NULL, 0, /* client supplied destination clip list, cliplist count */
flags);
if (status != VA_STATUS_SUCCESS)
msg_Err(vd, "failed displaying picture");
out:
#endif
picture_Release(pic);
}
static void vlc_va_PictureRelease(picture_t *pic)
{
assert(pic);
assert(sizeof(pic->p_sys) == sizeof(picture_sys_t));
if( --pic->i_refcount > 0 )
return;
free(pic->p_sys);
picture_Delete(pic);
}
/**
* Return a direct buffer
*/
static picture_pool_t *Pool (vout_display_t *vd, unsigned requested_count)
{
vout_display_sys_t *sys = vd->sys;
(void)requested_count;
VLC_UNUSED(sys);
#if 0
VLC_UNUSED(requested_count);
if (sys->pool)
return sys->pool;
/* FIXME: allocate picture and output surfaces */
#if 0
vout_display_place_t place;
vout_display_PlacePicture (&place, &vd->source, vd->cfg, false);
sys->pool = picture_pool_New (count, pic_array);
if (!sys->pool)
const uint32_t values[] = { place.x, place.y, place.width, place.height };
xcb_configure_window (sys->conn, sys->window,
XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y |
XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT,
values);
#endif
picture_t *pic_array[MAX_PICTURES];
unsigned int count;
for (count = 0; count < MAX_PICTURES; count++)
{
/* FIXME: Release allocated pictures */
return NULL;
pic_array[count] = picture_NewFromFormat(&vd->fmt);
if (!pic_array[count])
break;
picture_sys_t *sys = (picture_sys_t *) calloc(1, sizeof(picture_sys_t));
if (!sys)
{
picture_Release(pic_array[count]);
break;
}
pic_array[count]->p_sys = sys;
pic_array[count]->pf_release = vlc_va_PictureRelease;
}
if (count == 0)
return NULL;
sys->pool = picture_pool_New (count, pic_array);
if (!sys->pool)
goto error;
XFlush(sys->conn->p_display_x11);
#endif
return sys->pool;
error:
/* Cleanup on error */
for (int i = 0; i < MAX_PICTURES; i++)
{
picture_t *pic = pic_array[i];
if (pic)
picture_Release(pic);
}
return NULL;
}
#endif /* HAVE_AVCODEC_VAAPI */
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