[vlc-devel] [PATCH] vmem: lock/unlock pictures from pool callback

Rémi Denis-Courmont remi at remlab.net
Tue Jul 12 10:19:10 CEST 2016


Le 2016-07-12 09:59, Thomas Guillem a écrit :
> Pictures are now locked just before decoding, and unlocked before the 
> picture
> is displayed. This is the behavior expected by users and by the
> libvlc_video_lock_cb/libvlc_video_unlock_cb documentation.

I don't think that this is generally feasible without memory copying 
inside vmem, as the picture buffers might have other references. 
Specifically, I don't think the patch makes the code do what this 
comment implies.

> Furthermore, lock callbacks can now fail (planes[0] is checked before
> continuing).
> ---
>  modules/video_output/vmem.c | 73
> +++++++++++++++++++++++++++++----------------
>  1 file changed, 48 insertions(+), 25 deletions(-)
>
> diff --git a/modules/video_output/vmem.c 
> b/modules/video_output/vmem.c
> index 64aefa1..fa05360 100644
> --- a/modules/video_output/vmem.c
> +++ b/modules/video_output/vmem.c
> @@ -83,6 +83,9 @@ vlc_module_end()
>
> 
> *****************************************************************************/
>  struct picture_sys_t {
>      void *id;
> +    void *opaque;
> +    void *(*lock)(void *sys, void **plane);
> +    void (*unlock)(void *sys, void *id, void *const *plane);
>  };
>
>  /* NOTE: the callback prototypes must match those of LibVLC */
> @@ -107,20 +110,6 @@ static picture_pool_t *Pool  (vout_display_t *,
> unsigned);
>  static void           Display(vout_display_t *, picture_t *,
> subpicture_t *);
>  static int            Control(vout_display_t *, int, va_list);
>
> -static void Unlock(void *data, picture_t *pic)
> -{
> -    vout_display_sys_t *sys = data;
> -    picture_sys_t *picsys = pic->p_sys;
> -    void *planes[PICTURE_PLANE_MAX];
> -
> -    assert(!picture_IsReferenced(pic));
> -
> -    for (int i = 0; i < pic->i_planes; i++)
> -        planes[i] = pic->p[i].p_pixels;
> -
> -    sys->unlock(sys->opaque, picsys->id, planes);
> -}
> -
>
> 
> /*****************************************************************************
>   * Open: allocates video thread
>
> 
> *****************************************************************************
> @@ -252,14 +241,39 @@ static void Close(vlc_object_t *object)
>          sys->cleanup(sys->opaque);
>
>      if (sys->pool)
> -    {
> -        if (sys->unlock != NULL)
> -            picture_pool_Enum(sys->pool, Unlock, sys);
>          picture_pool_Release(sys->pool);
> -    }
>      free(sys);
>  }
>
> +static int PoolLockPicture(picture_t *pic)
> +{
> +    picture_sys_t *picsys = pic->p_sys;
> +    void *planes[PICTURE_PLANE_MAX] = {};
> +
> +    picsys->id = picsys->lock(picsys->opaque, planes);
> +    if (planes[0] == NULL)
> +        return -1;
> +
> +    for (int i = 0; i < pic->i_planes; i++)
> +        pic->p[i].p_pixels = planes[i];
> +    return 0;
> +
> +}
> +
> +static void PoolUnlockPicture(picture_t *pic)
> +{
> +    picture_sys_t *picsys = pic->p_sys;
> +
> +    if (picsys->unlock != NULL)
> +    {
> +        void *planes[PICTURE_PLANE_MAX] = {};
> +        for (int i = 0; i < pic->i_planes; i++)
> +            planes[i] = pic->p[i].p_pixels;
> +
> +        picsys->unlock(picsys->opaque, picsys->id, planes);
> +    }
> +}
> +
>  static picture_pool_t *Pool(vout_display_t *vd, unsigned count)
>  {
>      vout_display_sys_t *sys = vd->sys;
> @@ -280,14 +294,14 @@ static picture_pool_t *Pool(vout_display_t *vd,
> unsigned count)
>              break;
>          }
>          picsys->id = NULL;
> +        picsys->opaque = sys->opaque;
> +        picsys->lock = sys->lock;
> +        picsys->unlock = sys->unlock;
>
>          picture_resource_t rsc = { .p_sys = picsys };
> -        void *planes[PICTURE_PLANE_MAX];
> -
> -        picsys->id = sys->lock(sys->opaque, planes);
>
>          for (unsigned i = 0; i < PICTURE_PLANE_MAX; i++) {
> -            rsc.p[i].p_pixels = planes[i];
> +            rsc.p[i].p_pixels = NULL;
>              rsc.p[i].i_lines  = sys->lines[i];
>              rsc.p[i].i_pitch  = sys->pitches[i];
>          }
> @@ -301,7 +315,13 @@ static picture_pool_t *Pool(vout_display_t *vd,
> unsigned count)
>      }
>
>      /* */
> -    sys->pool = picture_pool_New(count, pictures);
> +    picture_pool_configuration_t pool_cfg = {
> +        .picture_count = count,
> +        .picture = pictures,
> +        .lock = PoolLockPicture,
> +        .unlock = PoolUnlockPicture,
> +    };
> +    sys->pool = picture_pool_NewExtended(&pool_cfg);
>      if (!sys->pool) {
>          for (unsigned i = 0; i < count; i++)
>              picture_Release(pictures[i]);
> @@ -314,10 +334,13 @@ static void Display(vout_display_t *vd,
> picture_t *pic, subpicture_t *subpic)
>  {
>      vout_display_sys_t *sys = vd->sys;
>
> +    /* Unlock the picture buffer before the picture is displayed */
> +    void *id = pic->p_sys->id;
> +    picture_Release(pic);
> +
>      if (sys->display != NULL)
> -        sys->display(sys->opaque, pic->p_sys->id);
> +        sys->display(sys->opaque, id);
>
> -    picture_Release(pic);
>      VLC_UNUSED(subpic);
>  }

-- 
Rémi Denis-Courmont
http://www.remlab.net/


More information about the vlc-devel mailing list