vlc | branch: master | Steve Lhomme <[email protected]> | Tue Jun 6 18:23:03 2017 +0200| [1479c1b23261e5f217e0cbc270c5b7c8b72e7f1f] | committer: Jean-Baptiste Kempf
directx_va: rework the picture picking algorithm Just rely on an available atomic value to find a usable picture or wait for the vout to release some pictures. Similar to the algorithm found in avcodec/VDPAU. Signed-off-by: Jean-Baptiste Kempf <[email protected]> > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=1479c1b23261e5f217e0cbc270c5b7c8b72e7f1f --- modules/codec/avcodec/directx_va.c | 58 ++++++++++++++++---------------------- modules/codec/avcodec/directx_va.h | 2 -- 2 files changed, 25 insertions(+), 35 deletions(-) diff --git a/modules/codec/avcodec/directx_va.c b/modules/codec/avcodec/directx_va.c index 68b4613a0d..a90e3155cf 100644 --- a/modules/codec/avcodec/directx_va.c +++ b/modules/codec/avcodec/directx_va.c @@ -356,7 +356,6 @@ int directx_va_Setup(vlc_va_t *va, directx_sys_t *dx_sys, AVCodecContext *avctx) return VLC_ENOMEM; } atomic_init(&surface->refcount, 1); - surface->order = 0; surface->p_lock = &dx_sys->surface_lock; surface->p_pic = dx_sys->pf_alloc_surface_pic(va, &fmt, i); dx_sys->surface[i] = surface; @@ -389,57 +388,50 @@ void DestroyVideoDecoder(vlc_va_t *va, directx_sys_t *dx_sys) dx_sys->surface_count = 0; } -/* FIXME it is nearly common with VAAPI */ +static vlc_va_surface_t *GetSurface(directx_sys_t *dx_sys) +{ + for (int i = 0; i < dx_sys->surface_count; i++) { + vlc_va_surface_t *surface = dx_sys->surface[i]; + uintptr_t expected = 1; + + if (atomic_compare_exchange_strong(&surface->refcount, &expected, 2)) + { + /* TODO do a copy to allow releasing locally and keep forward alive atomic_fetch_sub(&surface->refs, 1);*/ + surface->decoderSurface = dx_sys->hw_surface[i]; + return surface; + } + } + return NULL; +} + vlc_va_surface_t *directx_va_Get(vlc_va_t *va, directx_sys_t *dx_sys) { /* Check the device */ if (dx_sys->pf_check_device(va)!=VLC_SUCCESS) return NULL; - vlc_mutex_lock( &dx_sys->surface_lock ); - - /* Grab the oldest unused surface, in case none are, use the oldest used one - * XXX using the used one is a workaround in case a problem happens with libavcodec */ - int i, old = -1, old_used = -1; + unsigned tries = (CLOCK_FREQ + VOUT_OUTMEM_SLEEP) / VOUT_OUTMEM_SLEEP; + vlc_va_surface_t *field; - for (i = 0; i < dx_sys->surface_count; i++) { - vlc_va_surface_t *surface = dx_sys->surface[i]; - if (((old == -1 || surface->order < dx_sys->surface[old]->order)) && atomic_load(&surface->refcount)) - old = i; - if (old_used == -1 || surface->order < dx_sys->surface[old_used]->order) - old_used = i; - } - if (old >= 0) - i = old; - else if (old_used >= 0) + while ((field = GetSurface(dx_sys)) == NULL) { - msg_Warn(va, "couldn't find a free decoding buffer, using index %d", old_used); - i = old_used; + if (--tries == 0) + return NULL; + /* Pool empty. Wait for some time as in src/input/decoder.c. + * XXX: Both this and the core should use a semaphore or a CV. */ + msleep(VOUT_OUTMEM_SLEEP); } - - vlc_va_surface_t *surface = dx_sys->surface[i]; - - atomic_store(&surface->refcount,1); - surface->order = ++dx_sys->surface_order; - surface->decoderSurface = dx_sys->hw_surface[i]; - - vlc_mutex_unlock( &dx_sys->surface_lock ); - - return surface; + return field; } void directx_va_AddRef(vlc_va_surface_t *surface) { - vlc_mutex_lock( surface->p_lock ); atomic_fetch_add(&surface->refcount, 1); - vlc_mutex_unlock( surface->p_lock ); } void directx_va_Release(vlc_va_surface_t *surface) { - vlc_mutex_lock( surface->p_lock ); atomic_fetch_sub(&surface->refcount, 1); - vlc_mutex_unlock( surface->p_lock ); } void directx_va_Close(vlc_va_t *va, directx_sys_t *dx_sys) diff --git a/modules/codec/avcodec/directx_va.h b/modules/codec/avcodec/directx_va.h index 157306e64b..299127e977 100644 --- a/modules/codec/avcodec/directx_va.h +++ b/modules/codec/avcodec/directx_va.h @@ -45,7 +45,6 @@ /* */ typedef struct { atomic_uintptr_t refcount; - unsigned int order; vlc_mutex_t *p_lock; picture_t *p_pic; D3D_DecoderSurface *decoderSurface; @@ -80,7 +79,6 @@ typedef struct /* */ int surface_count; - int surface_order; int surface_width; int surface_height; _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
