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

Thomas Guillem thomas at gllm.fr
Tue Jul 12 10:47:03 CEST 2016



On Tue, Jul 12, 2016, at 10:19, Rémi Denis-Courmont wrote:
> 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.

Ok, I see. There is no way to be sure that the buffer will be unlocked
when I release the picture from the Display callback since the picture
can be hold by something else.

One way to fix it is to remove the warning comment:
 * \warning A picture buffer is unlocked after the picture is decoded,
 * but before the picture is displayed.

Since we can't know when a picture will be unlocked, but we are sure it
will be unlocked before it's locked again.

> 
> > 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/
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel


More information about the vlc-devel mailing list