Commit 30cb3147 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

avcodec: pass VA picture from the decoder to the hardware plugin

parent 27dc2eab
...@@ -380,8 +380,7 @@ ok: ...@@ -380,8 +380,7 @@ ok:
return VLC_SUCCESS; return VLC_SUCCESS;
} }
static int Extract(vlc_va_t *va, picture_t *picture, void *opaque, static int Extract(vlc_va_t *va, picture_t *picture, uint8_t *data)
uint8_t *data)
{ {
vlc_va_sys_t *sys = va->sys; vlc_va_sys_t *sys = va->sys;
LPDIRECT3DSURFACE9 d3d = (LPDIRECT3DSURFACE9)(uintptr_t)data; LPDIRECT3DSURFACE9 d3d = (LPDIRECT3DSURFACE9)(uintptr_t)data;
...@@ -440,12 +439,11 @@ static int Extract(vlc_va_t *va, picture_t *picture, void *opaque, ...@@ -440,12 +439,11 @@ static int Extract(vlc_va_t *va, picture_t *picture, void *opaque,
/* */ /* */
IDirect3DSurface9_UnlockRect(d3d); IDirect3DSurface9_UnlockRect(d3d);
(void) opaque;
return VLC_SUCCESS; return VLC_SUCCESS;
} }
/* FIXME it is nearly common with VAAPI */ /* FIXME it is nearly common with VAAPI */
static int Get(vlc_va_t *va, void **opaque, uint8_t **data) static int Get(vlc_va_t *va, picture_t *pic, uint8_t **data)
{ {
vlc_va_sys_t *sys = va->sys; vlc_va_sys_t *sys = va->sys;
...@@ -479,15 +477,17 @@ static int Get(vlc_va_t *va, void **opaque, uint8_t **data) ...@@ -479,15 +477,17 @@ static int Get(vlc_va_t *va, void **opaque, uint8_t **data)
surface->refcount = 1; surface->refcount = 1;
surface->order = sys->surface_order++; surface->order = sys->surface_order++;
*data = (void *)surface->d3d; *data = (void *)surface->d3d;
*opaque = surface; pic->context = surface;
return VLC_SUCCESS; return VLC_SUCCESS;
} }
static void Release(void *opaque, uint8_t *data) static void Release(void *opaque, uint8_t *data)
{ {
vlc_va_surface_t *surface = opaque; picture_t *pic = opaque;
vlc_va_surface_t *surface = pic->context;
surface->refcount--; surface->refcount--;
pic->context = NULL;
(void) data; (void) data;
} }
......
...@@ -38,9 +38,9 @@ struct vlc_va_t { ...@@ -38,9 +38,9 @@ struct vlc_va_t {
int pix_fmt; int pix_fmt;
int (*setup)(vlc_va_t *, AVCodecContext *, vlc_fourcc_t *output); int (*setup)(vlc_va_t *, AVCodecContext *, vlc_fourcc_t *output);
int (*get)(vlc_va_t *, void **opaque, uint8_t **data); int (*get)(vlc_va_t *, picture_t *pic, uint8_t **data);
void (*release)(void *opaque, uint8_t *surface); void (*release)(void *pic, uint8_t *surface);
int (*extract)(vlc_va_t *, picture_t *dst, void *opaque, uint8_t *data); int (*extract)(vlc_va_t *, picture_t *pic, uint8_t *data);
}; };
/** /**
...@@ -68,7 +68,7 @@ static inline int vlc_va_Setup(vlc_va_t *va, AVCodecContext *avctx, ...@@ -68,7 +68,7 @@ static inline int vlc_va_Setup(vlc_va_t *va, AVCodecContext *avctx,
* The surface will be used as output for the hardware decoder, and possibly * The surface will be used as output for the hardware decoder, and possibly
* also as a reference frame to decode other surfaces. * also as a reference frame to decode other surfaces.
* *
* @param opaque pointer to storage space for surface internal data [OUT] * @param pic pointer to VLC picture being allocated [IN/OUT]
* @param data pointer to the AVFrame data[0] and data[3] pointers [OUT] * @param data pointer to the AVFrame data[0] and data[3] pointers [OUT]
* *
* @note This function needs not be reentrant. However it may be called * @note This function needs not be reentrant. However it may be called
...@@ -77,25 +77,25 @@ static inline int vlc_va_Setup(vlc_va_t *va, AVCodecContext *avctx, ...@@ -77,25 +77,25 @@ static inline int vlc_va_Setup(vlc_va_t *va, AVCodecContext *avctx,
* *
* @return VLC_SUCCESS on success, otherwise an error code. * @return VLC_SUCCESS on success, otherwise an error code.
*/ */
static inline int vlc_va_Get(vlc_va_t *va, void **opaque, uint8_t **data) static inline int vlc_va_Get(vlc_va_t *va, picture_t *pic, uint8_t **data)
{ {
return va->get(va, opaque, data); return va->get(va, pic, data);
} }
/** /**
* Releases a hardware surface from a libavcodec frame. * Releases a hardware surface from a libavcodec frame.
* The surface has been previously allocated with vlc_va_Get(). * The surface has been previously allocated with vlc_va_Get().
* *
* @param opaque opaque data pointer of the AVFrame set by vlc_va_Get() * @param pic VLC picture being released [IN/OUT]
* @param data data[0] pointer of the AVFrame set by vlc_va_Get() * @param data data[0] pointer of the AVFrame set by vlc_va_Get()
* *
* @note This function needs not be reentrant. However it may be called * @note This function needs not be reentrant. However it may be called
* concurrently with vlc_va_Get() and/or vlc_va_Extract() from other threads * concurrently with vlc_va_Get() and/or vlc_va_Extract() from other threads
* and other frames. * and other frames.
*/ */
static inline void vlc_va_Release(vlc_va_t *va, void *opaque, uint8_t *data) static inline void vlc_va_Release(vlc_va_t *va, picture_t *pic, uint8_t *data)
{ {
va->release(opaque, data); va->release(pic, data);
} }
/** /**
...@@ -108,10 +108,9 @@ static inline void vlc_va_Release(vlc_va_t *va, void *opaque, uint8_t *data) ...@@ -108,10 +108,9 @@ static inline void vlc_va_Release(vlc_va_t *va, void *opaque, uint8_t *data)
* @note This function needs not be reentrant, but it may run concurrently with * @note This function needs not be reentrant, but it may run concurrently with
* vlc_va_Get() or vlc_va_Release() in other threads (with distinct frames). * vlc_va_Get() or vlc_va_Release() in other threads (with distinct frames).
*/ */
static inline int vlc_va_Extract(vlc_va_t *va, picture_t *dst, void *opaque, static inline int vlc_va_Extract(vlc_va_t *va, picture_t *pic, uint8_t *data)
uint8_t *data)
{ {
return va->extract(va, dst, opaque, data); return va->extract(va, pic, data);
} }
/** /**
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include <vlc_common.h> #include <vlc_common.h>
#include <vlc_plugin.h> #include <vlc_plugin.h>
#include <vlc_fourcc.h> #include <vlc_fourcc.h>
#include <vlc_picture.h>
#ifdef VLC_VA_BACKEND_XLIB #ifdef VLC_VA_BACKEND_XLIB
# include <vlc_xlib.h> # include <vlc_xlib.h>
...@@ -272,8 +273,7 @@ error: ...@@ -272,8 +273,7 @@ error:
return VLC_EGENERIC; return VLC_EGENERIC;
} }
static int Extract( vlc_va_t *va, picture_t *p_picture, void *opaque, static int Extract( vlc_va_t *va, picture_t *p_picture, uint8_t *data )
uint8_t *data )
{ {
vlc_va_sys_t *sys = va->sys; vlc_va_sys_t *sys = va->sys;
VASurfaceID i_surface_id = (VASurfaceID)(uintptr_t)data; VASurfaceID i_surface_id = (VASurfaceID)(uintptr_t)data;
...@@ -346,11 +346,10 @@ static int Extract( vlc_va_t *va, picture_t *p_picture, void *opaque, ...@@ -346,11 +346,10 @@ static int Extract( vlc_va_t *va, picture_t *p_picture, void *opaque,
vaDestroyImage( sys->p_display, sys->image.image_id ); vaDestroyImage( sys->p_display, sys->image.image_id );
sys->image.image_id = VA_INVALID_ID; sys->image.image_id = VA_INVALID_ID;
} }
(void) opaque;
return VLC_SUCCESS; return VLC_SUCCESS;
} }
static int Get( vlc_va_t *va, void **opaque, uint8_t **data ) static int Get( vlc_va_t *va, picture_t *pic, uint8_t **data )
{ {
vlc_va_sys_t *sys = va->sys; vlc_va_sys_t *sys = va->sys;
int i_old; int i_old;
...@@ -377,18 +376,21 @@ static int Get( vlc_va_t *va, void **opaque, uint8_t **data ) ...@@ -377,18 +376,21 @@ static int Get( vlc_va_t *va, void **opaque, uint8_t **data )
p_surface->i_refcount = 1; p_surface->i_refcount = 1;
p_surface->i_order = sys->i_surface_order++; p_surface->i_order = sys->i_surface_order++;
pic->context = p_surface;
*data = (void *)(uintptr_t)p_surface->i_id; *data = (void *)(uintptr_t)p_surface->i_id;
*opaque = p_surface;
return VLC_SUCCESS; return VLC_SUCCESS;
} }
static void Release( void *opaque, uint8_t *data ) static void Release( void *opaque, uint8_t *data )
{ {
vlc_va_surface_t *p_surface = opaque; picture_t *pic = opaque;
vlc_va_surface_t *p_surface = pic->context;
vlc_mutex_lock( p_surface->p_lock ); vlc_mutex_lock( p_surface->p_lock );
p_surface->i_refcount--; p_surface->i_refcount--;
vlc_mutex_unlock( p_surface->p_lock ); vlc_mutex_unlock( p_surface->p_lock );
pic->context = NULL;
(void) data; (void) data;
} }
......
...@@ -47,8 +47,8 @@ ...@@ -47,8 +47,8 @@
static int Open( vlc_va_t *, AVCodecContext *, const es_format_t * ); static int Open( vlc_va_t *, AVCodecContext *, const es_format_t * );
static void Close( vlc_va_t * , AVCodecContext *); static void Close( vlc_va_t * , AVCodecContext *);
static int Setup( vlc_va_t *, AVCodecContext *, vlc_fourcc_t *); static int Setup( vlc_va_t *, AVCodecContext *, vlc_fourcc_t *);
static int Get( vlc_va_t *, void **, uint8_t ** ); static int Get( vlc_va_t *, picture_t *, uint8_t ** );
static int Extract( vlc_va_t *, picture_t *, void *, uint8_t * ); static int Extract( vlc_va_t *, picture_t *, uint8_t * );
static void Release( void *, uint8_t * ); static void Release( void *, uint8_t * );
static void vda_Copy422YpCbCr8( picture_t *p_pic, static void vda_Copy422YpCbCr8( picture_t *p_pic,
...@@ -256,17 +256,16 @@ static void vda_Copy420YpCbCr8Planar( picture_t *p_pic, ...@@ -256,17 +256,16 @@ static void vda_Copy420YpCbCr8Planar( picture_t *p_pic,
CVPixelBufferUnlockBaseAddress( buffer, 0 ); CVPixelBufferUnlockBaseAddress( buffer, 0 );
} }
static int Get( vlc_va_t *va, void **opaque, uint8_t **data ) static int Get( vlc_va_t *va, picture_t *pic, uint8_t **data )
{ {
VLC_UNUSED( va ); VLC_UNUSED( va );
(void) pic;
*data = (uint8_t *)1; // dummy *data = (uint8_t *)1; // dummy
(void) opaque;
return VLC_SUCCESS; return VLC_SUCCESS;
} }
static int Extract( vlc_va_t *va, picture_t *p_picture, void *opaque, static int Extract( vlc_va_t *va, picture_t *p_picture, uint8_t *data )
uint8_t *data )
{ {
vlc_va_vda_t *p_vda = vlc_va_vda_Get( va ); vlc_va_vda_t *p_vda = vlc_va_vda_Get( va );
CVPixelBufferRef cv_buffer = ( CVPixelBufferRef )data; CVPixelBufferRef cv_buffer = ( CVPixelBufferRef )data;
...@@ -297,7 +296,6 @@ static int Extract( vlc_va_t *va, picture_t *p_picture, void *opaque, ...@@ -297,7 +296,6 @@ static int Extract( vlc_va_t *va, picture_t *p_picture, void *opaque,
} }
else else
vda_Copy422YpCbCr8( p_picture, cv_buffer ); vda_Copy422YpCbCr8( p_picture, cv_buffer );
(void) opaque;
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -357,16 +355,15 @@ static int Setup( vlc_va_t *va, AVCodecContext *avctx, vlc_fourcc_t *p_chroma ) ...@@ -357,16 +355,15 @@ static int Setup( vlc_va_t *va, AVCodecContext *avctx, vlc_fourcc_t *p_chroma )
} }
// Never called // Never called
static int Get( vlc_va_t *va, void **opaque, uint8_t **data ) static int Get( vlc_va_t *va, picture_t *p_picture, uint8_t **data )
{ {
VLC_UNUSED( va ); VLC_UNUSED( va );
(void) p_picture;
(void) data; (void) data;
(void) opaque;
return VLC_SUCCESS; return VLC_SUCCESS;
} }
static int Extract( vlc_va_t *va, picture_t *p_picture, void *opaque, static int Extract( vlc_va_t *va, picture_t *p_picture, uint8_t *data )
uint8_t *data )
{ {
CVPixelBufferRef cv_buffer = (CVPixelBufferRef)data; CVPixelBufferRef cv_buffer = (CVPixelBufferRef)data;
...@@ -383,7 +380,6 @@ static int Extract( vlc_va_t *va, picture_t *p_picture, void *opaque, ...@@ -383,7 +380,6 @@ static int Extract( vlc_va_t *va, picture_t *p_picture, void *opaque,
vda_Copy422YpCbCr8( p_picture, cv_buffer ); vda_Copy422YpCbCr8( p_picture, cv_buffer );
(void) opaque;
return VLC_SUCCESS; return VLC_SUCCESS;
} }
......
...@@ -88,7 +88,6 @@ typedef struct ...@@ -88,7 +88,6 @@ typedef struct
{ {
vlc_va_t *va; vlc_va_t *va;
picture_t *pic; picture_t *pic;
void *opaque;
} lavc_va_picture_t; } lavc_va_picture_t;
#ifdef HAVE_AVCODEC_MT #ifdef HAVE_AVCODEC_MT
...@@ -813,8 +812,7 @@ static picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block ) ...@@ -813,8 +812,7 @@ static picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
lavc_va_picture_t *vapic = p_sys->p_ff_pic->opaque; lavc_va_picture_t *vapic = p_sys->p_ff_pic->opaque;
p_pic = vapic->pic; p_pic = vapic->pic;
vlc_va_Extract( p_sys->p_va, p_pic, vapic->opaque, vlc_va_Extract( p_sys->p_va, p_pic, p_sys->p_ff_pic->data[3] );
p_sys->p_ff_pic->data[3] );
picture_Hold( p_pic ); picture_Hold( p_pic );
} }
else else
...@@ -965,7 +963,7 @@ static void lavc_va_ReleaseFrame(void *opaque, uint8_t *data) ...@@ -965,7 +963,7 @@ static void lavc_va_ReleaseFrame(void *opaque, uint8_t *data)
{ {
lavc_va_picture_t *vapic = opaque; lavc_va_picture_t *vapic = opaque;
vlc_va_Release(vapic->va, vapic->opaque, data); vlc_va_Release(vapic->va, vapic->pic, data);
picture_Release(vapic->pic); picture_Release(vapic->pic);
free(vapic); free(vapic);
} }
...@@ -990,7 +988,7 @@ static int lavc_va_GetFrame(struct AVCodecContext *ctx, AVFrame *frame, ...@@ -990,7 +988,7 @@ static int lavc_va_GetFrame(struct AVCodecContext *ctx, AVFrame *frame,
vapic->va = va; vapic->va = va;
vapic->pic = pic; vapic->pic = pic;
if (vlc_va_Get(va, &vapic->opaque, &frame->data[0])) if (vlc_va_Get(va, pic, &frame->data[0]))
{ {
msg_Err(dec, "hardware acceleration picture allocation failed"); msg_Err(dec, "hardware acceleration picture allocation failed");
picture_Release(pic); picture_Release(pic);
......
...@@ -127,7 +127,7 @@ static vlc_vdp_video_field_t *GetSurface(vlc_va_t *va) ...@@ -127,7 +127,7 @@ static vlc_vdp_video_field_t *GetSurface(vlc_va_t *va)
return CreateSurface(va); return CreateSurface(va);
} }
static int Lock(vlc_va_t *va, void **opaque, uint8_t **data) static int Lock(vlc_va_t *va, picture_t *pic, uint8_t **data)
{ {
vlc_vdp_video_field_t *field; vlc_vdp_video_field_t *field;
unsigned tries = (CLOCK_FREQ + VOUT_OUTMEM_SLEEP) / VOUT_OUTMEM_SLEEP; unsigned tries = (CLOCK_FREQ + VOUT_OUTMEM_SLEEP) / VOUT_OUTMEM_SLEEP;
...@@ -141,31 +141,19 @@ static int Lock(vlc_va_t *va, void **opaque, uint8_t **data) ...@@ -141,31 +141,19 @@ static int Lock(vlc_va_t *va, void **opaque, uint8_t **data)
msleep(VOUT_OUTMEM_SLEEP); msleep(VOUT_OUTMEM_SLEEP);
} }
*opaque = field; pic->context = field;
*data = (void *)(uintptr_t)field->frame->surface; *data = (void *)(uintptr_t)field->frame->surface;
return VLC_SUCCESS; return VLC_SUCCESS;
} }
static void Unlock(void *opaque, uint8_t *data) static void Unlock(void *opaque, uint8_t *data)
{ {
vlc_vdp_video_field_t *field = opaque; (void) opaque; (void) data;
DestroySurface(field);
(void) data;
} }
static int Copy(vlc_va_t *va, picture_t *pic, void *opaque, uint8_t *data) static int Copy(vlc_va_t *va, picture_t *pic, uint8_t *data)
{ {
vlc_vdp_video_field_t *field = opaque; (void) va; (void) pic; (void) data;
assert(field != NULL);
field = vlc_vdp_video_copy(field);
if (unlikely(field == NULL))
return VLC_ENOMEM;
assert(pic->context == NULL);
pic->context = field;
(void) va; (void) data;
return VLC_SUCCESS; return VLC_SUCCESS;
} }
......
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