[vlc-devel] [RFC] video_output: handle a second picture to display for Frame Sequential 3D sources

Steve Lhomme robux4 at ycbcr.xyz
Tue Aug 21 15:35:17 CEST 2018


Only vout that can actually display stereo pictures need to take care of 
the second picture (opt-in). So for now only the D3D11 module will 
implement these callbacks.

This is the same algorithm used so far in the D3D11 module to keep the 
secondary (or primary) eye picture.


On 21/08/2018 15:30, Steve Lhomme wrote:
> ---
>   include/vlc_vout_display.h       |  4 +++
>   include/vlc_vout_wrapper.h       | 11 ++++++--
>   src/video_output/display.c       |  4 +--
>   src/video_output/video_output.c  | 47 +++++++++++++++++++++++++++++---
>   src/video_output/vout_internal.h |  2 ++
>   5 files changed, 60 insertions(+), 8 deletions(-)
>
> diff --git a/include/vlc_vout_display.h b/include/vlc_vout_display.h
> index 025cae13f1..f66578f960 100644
> --- a/include/vlc_vout_display.h
> +++ b/include/vlc_vout_display.h
> @@ -277,6 +277,8 @@ struct vout_display_t {
>        */
>       void       (*prepare)(vout_display_t *, picture_t *, subpicture_t *,
>                             vlc_tick_t date);
> +    void       (*prepare_stereo)(vout_display_t *, picture_t *, picture_t *,
> +                                 subpicture_t *, vlc_tick_t date);
>   
>       /* Display a picture and an optional subpicture (mandatory).
>        *
> @@ -289,6 +291,8 @@ struct vout_display_t {
>        * subpicture, so you must release them as soon as possible.
>        */
>       void       (*display)(vout_display_t *, picture_t *, subpicture_t *);
> +    void       (*display_stereo)(vout_display_t *, picture_t *, picture_t *,
> +                                 subpicture_t *);
>   
>       /* Control on the module (mandatory) */
>       int        (*control)(vout_display_t *, int, va_list);
> diff --git a/include/vlc_vout_wrapper.h b/include/vlc_vout_wrapper.h
> index e0a6ab0d1f..2ee69597f9 100644
> --- a/include/vlc_vout_wrapper.h
> +++ b/include/vlc_vout_wrapper.h
> @@ -41,10 +41,13 @@ static inline picture_pool_t *vout_display_Pool(vout_display_t *vd, unsigned cou
>    */
>   static inline void vout_display_Prepare(vout_display_t *vd,
>                                           picture_t *picture,
> +                                        picture_t *second_eye,
>                                           subpicture_t *subpicture,
>                                           vlc_tick_t date)
>   {
> -    if (vd->prepare)
> +    if (second_eye && vd->prepare_stereo)
> +        vd->prepare_stereo(vd, picture, second_eye, subpicture, date);
> +    else if (vd->prepare)
>           vd->prepare(vd, picture, subpicture, date);
>   }
>   
> @@ -53,9 +56,13 @@ static inline void vout_display_Prepare(vout_display_t *vd,
>    */
>   static inline void vout_display_Display(vout_display_t *vd,
>                                           picture_t *picture,
> +                                        picture_t *second_eye,
>                                           subpicture_t *subpicture)
>   {
> -    vd->display(vd, picture, subpicture);
> +    if (second_eye && vd->display_stereo)
> +        vd->display_stereo(vd, picture, second_eye, subpicture);
> +    else
> +        vd->display(vd, picture,  subpicture);
>   }
>   
>   /**
> diff --git a/src/video_output/display.c b/src/video_output/display.c
> index 1d2e039111..1fafb87d4d 100644
> --- a/src/video_output/display.c
> +++ b/src/video_output/display.c
> @@ -1205,7 +1205,7 @@ static void SplitterPrepare(vout_display_t *vd,
>       for (int i = 0; i < sys->count; i++) {
>           sys->picture[i] = vout_FilterDisplay(sys->display[i], sys->picture[i]);
>           if (sys->picture[i])
> -            vout_display_Prepare(sys->display[i], sys->picture[i], NULL, date);
> +            vout_display_Prepare(sys->display[i], sys->picture[i], NULL, NULL, date);
>       }
>   }
>   static void SplitterDisplay(vout_display_t *vd,
> @@ -1217,7 +1217,7 @@ static void SplitterDisplay(vout_display_t *vd,
>       assert(!subpicture);
>       for (int i = 0; i < sys->count; i++) {
>           if (sys->picture[i])
> -            vout_display_Display(sys->display[i], sys->picture[i], NULL);
> +            vout_display_Display(sys->display[i], sys->picture[i], NULL, NULL);
>       }
>       picture_Release(picture);
>   }
> diff --git a/src/video_output/video_output.c b/src/video_output/video_output.c
> index 4561c39e81..84e4df15c1 100644
> --- a/src/video_output/video_output.c
> +++ b/src/video_output/video_output.c
> @@ -1123,6 +1123,7 @@ static int ThreadDisplayRenderPicture(vout_thread_t *vout, bool is_forced)
>        */
>       bool is_direct = vout->p->decoder_pool == vout->p->display_pool;
>       picture_t *todisplay = filtered;
> +    picture_t *todisplay_right = NULL;
>       picture_t *snap_pic = todisplay;
>       if (do_early_spu && subpic) {
>           if (vout->p->spu_blend) {
> @@ -1185,6 +1186,22 @@ static int ThreadDisplayRenderPicture(vout_thread_t *vout, bool is_forced)
>               picture_Release(snap_pic);
>       }
>   
> +    if (todisplay->format.multiview_mode == MULTIVIEW_STEREO_FRAME)
> +    {
> +        /* special handling of multiframe videos */
> +        if (todisplay->format.b_multiview_right_eye_first == !todisplay->format.b_multiview_left_eye)
> +        {
> +            /* keep this picture for later */
> +            if (sys->stereo_pic)
> +                picture_Release(sys->stereo_pic);
> +            sys->stereo_pic = todisplay;
> +            return VLC_SUCCESS;
> +        }
> +
> +        /* we have both pictures */
> +        todisplay_right = picture_Hold(sys->stereo_pic);
> +    }
> +
>       /* Render the direct buffer */
>       vout_UpdateDisplaySourceProperties(vd, &todisplay->format);
>   
> @@ -1194,13 +1211,25 @@ static int ThreadDisplayRenderPicture(vout_thread_t *vout, bool is_forced)
>               subpicture_Delete(subpic);
>           return VLC_EGENERIC;
>       }
> +    if (todisplay_right != NULL) {
> +        todisplay_right = vout_FilterDisplay(vd, todisplay_right);
> +        if (todisplay_right == NULL) {
> +            picture_Release(todisplay);
> +            if (subpic != NULL)
> +                subpicture_Delete(subpic);
> +            return VLC_EGENERIC;
> +        }
> +    }
>   
>       if (sys->display.use_dr) {
> -        vout_display_Prepare(vd, todisplay, subpic, todisplay->date);
> +        vout_display_Prepare(vd, todisplay, todisplay_right, subpic, todisplay->date);
>       } else {
> -        if (!do_dr_spu && !do_early_spu && vout->p->spu_blend && subpic)
> +        if (!do_dr_spu && !do_early_spu && vout->p->spu_blend && subpic) {
>               picture_BlendSubpicture(todisplay, vout->p->spu_blend, subpic);
> -        vout_display_Prepare(vd, todisplay, do_dr_spu ? subpic : NULL,
> +            if (todisplay_right)
> +                picture_BlendSubpicture(todisplay_right, vout->p->spu_blend, subpic);
> +        }
> +        vout_display_Prepare(vd, todisplay, todisplay_right, do_dr_spu ? subpic : NULL,
>                                todisplay->date);
>   
>           if (!do_dr_spu && subpic)
> @@ -1231,7 +1260,7 @@ static int ThreadDisplayRenderPicture(vout_thread_t *vout, bool is_forced)
>   
>       /* Display the direct buffer returned by vout_RenderPicture */
>       vout->p->displayed.date = vlc_tick_now();
> -    vout_display_Display(vd, todisplay, subpic);
> +    vout_display_Display(vd, todisplay, todisplay_right, subpic);
>   
>       vout_statistic_AddDisplayed(&vout->p->statistic, 1);
>   
> @@ -1366,6 +1395,11 @@ static void ThreadFlush(vout_thread_t *vout, bool below, vlc_tick_t date)
>           }
>       }
>   
> +    if (vout->p->stereo_pic) {
> +        picture_Release(vout->p->stereo_pic);
> +        vout->p->stereo_pic = NULL;
> +    }
> +
>       picture_fifo_Flush(vout->p->decoder_fifo, date, below);
>       vout_FilterFlush(vout->p->display.vd);
>   }
> @@ -1579,6 +1613,11 @@ static void ThreadStop(vout_thread_t *vout, vout_display_state_t *state)
>           vout_CloseWrapper(vout, state);
>       }
>   
> +    if (vout->p->stereo_pic) {
> +        picture_Release(vout->p->stereo_pic);
> +        vout->p->stereo_pic = NULL;
> +    }
> +
>       /* Destroy the video filters */
>       ThreadDelAllFilterCallbacks(vout);
>       filter_chain_Delete(vout->p->filter.chain_interactive);
> diff --git a/src/video_output/vout_internal.h b/src/video_output/vout_internal.h
> index 1ae5cb009d..59a57aed65 100644
> --- a/src/video_output/vout_internal.h
> +++ b/src/video_output/vout_internal.h
> @@ -148,6 +148,8 @@ struct vout_thread_sys_t
>       picture_pool_t  *decoder_pool;
>       picture_fifo_t  *decoder_fifo;
>       vout_chrono_t   render;           /**< picture render time estimator */
> +
> +    picture_t       *stereo_pic; /* frame sequential first eye in the sequence */
>   };
>   
>   /**
> -- 
> 2.17.0
>
> _______________________________________________
> 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