[vlc-devel] [PATCH 9/9] video_output: allow the vout to select which picture it wants to display
Steve Lhomme
robux4 at ycbcr.xyz
Sat Oct 27 08:46:35 CEST 2018
Optionally pass a second picture per prepare/display for real stereo display.
For frame sequential the display may need both pictures at once, or only one
of them. And the video_output doesn't know about it, only the display knows
which mode it's currently using, so we need to ask it what it wants and pass
it that way.
---
src/video_output/display.c | 40 ++++++++++++++++++++
src/video_output/video_output.c | 64 +++++++++++++++++++++++++++-----
src/video_output/vout_internal.h | 2 +
src/video_output/vout_wrapper.h | 3 ++
4 files changed, 100 insertions(+), 9 deletions(-)
diff --git a/src/video_output/display.c b/src/video_output/display.c
index f347700643..2ba19b6ebf 100644
--- a/src/video_output/display.c
+++ b/src/video_output/display.c
@@ -749,6 +749,46 @@ bool vout_ManageDisplay(vout_display_t *vd, bool allow_reset_pictures)
return false;
}
+void vout_SelectMultiviewPictures(vout_display_t *vd, picture_t *eyes[2])
+{
+ vout_display_owner_sys_t *osys = vd->owner.sys;
+ vlc_stereoscopic_mode_t stereo_mode = osys->stereo_mode;
+
+ if (stereo_mode == VIDEO_STEREO_OUTPUT_AUTO)
+ stereo_mode = VIDEO_STEREO_OUTPUT_LEFT_ONLY;
+
+ switch ( stereo_mode )
+ {
+ case VIDEO_STEREO_OUTPUT_ORIGINAL:
+ /* unmodified source */
+ break;
+ case VIDEO_STEREO_OUTPUT_LEFT_ONLY:
+ if ( eyes[0]->format.multiview_mode == MULTIVIEW_STEREO_FRAME ) {
+ if (!eyes[0]->format.b_multiview_left_eye)
+ {
+ eyes[0] = NULL;
+ }
+ eyes[1] = NULL;
+ } else {
+ assert( eyes[1] == NULL );
+ }
+ break;
+ case VIDEO_STEREO_OUTPUT_RIGHT_ONLY:
+ if ( eyes[0]->format.multiview_mode == MULTIVIEW_STEREO_FRAME ) {
+ if (eyes[0]->format.b_multiview_left_eye)
+ {
+ eyes[0] = NULL;
+ }
+ eyes[1] = NULL;
+ } else {
+ assert( eyes[1] == NULL );
+ }
+ break;
+ case VIDEO_STEREO_OUTPUT_AUTO:
+ vlc_assert_unreachable();
+ }
+}
+
bool vout_AreDisplayPicturesInvalid(vout_display_t *vd)
{
vout_display_owner_sys_t *osys = vd->owner.sys;
diff --git a/src/video_output/video_output.c b/src/video_output/video_output.c
index 0336de353f..ad3b59dd45 100644
--- a/src/video_output/video_output.c
+++ b/src/video_output/video_output.c
@@ -1196,21 +1196,56 @@ static int ThreadDisplayRenderPicture(vout_thread_t *vout, bool is_forced)
/* Render the direct buffer */
vout_UpdateDisplaySourceProperties(vd, &todisplay->format);
- todisplay = vout_FilterDisplay(vd, todisplay);
- if (todisplay == NULL) {
+ picture_t *eyes[2] = { todisplay, NULL };
+ if ( todisplay->format.multiview_mode == MULTIVIEW_STEREO_FRAME )
+ {
+ /* only display pictures by pair of Left/Right eye */
+ if ( todisplay->format.b_multiview_left_eye ==
+ !todisplay->format.b_multiview_right_eye_first )
+ {
+ /* keep the first eye picture until the next one arrived */
+ if (sys->stereo_pic)
+ picture_Release(sys->stereo_pic);
+ sys->stereo_pic = picture_Hold(todisplay);
+ }
+ else if (todisplay != sys->stereo_pic)
+ eyes[1] = sys->stereo_pic;
+ }
+
+ vout_SelectMultiviewPictures(vd, eyes);
+ if (eyes[0] == NULL)
+ {
+ if (subpic != NULL)
+ subpicture_Delete(subpic);
+ picture_Release(todisplay);
+ return VLC_SUCCESS;
+ }
+
+ eyes[0] = vout_FilterDisplay(vd, eyes[0]);
+ if (eyes[0] == NULL) {
if (subpic != NULL)
subpicture_Delete(subpic);
return VLC_EGENERIC;
}
+ if (eyes[1] != NULL) {
+ eyes[1] = vout_FilterDisplay(vd, eyes[1]);
+ if (eyes[1] == NULL) {
+ picture_Release(eyes[0]);
+ if (subpic != NULL)
+ subpicture_Delete(subpic);
+ return VLC_EGENERIC;
+ }
+ }
if ( subpic &&
!sys->display.use_dr && !do_dr_spu && !do_early_spu && sys->spu_blend)
{
- picture_BlendSubpicture(todisplay, sys->spu_blend, subpic);
-
+ picture_BlendSubpicture(eyes[0], sys->spu_blend, subpic);
+ if (eyes[1])
+ picture_BlendSubpicture(eyes[1], sys->spu_blend, subpic);
}
- vout_display_Prepare(vd, todisplay,
- sys->display.use_dr || do_dr_spu ? subpic : NULL, todisplay->date);
+ vout_display_Prepare(vd, eyes[0],
+ sys->display.use_dr || do_dr_spu ? subpic : NULL, eyes[0]->date);
vout_chrono_Stop(&sys->render);
#if 0
@@ -1224,16 +1259,17 @@ static int ThreadDisplayRenderPicture(vout_thread_t *vout, bool is_forced)
/* Wait the real date (for rendering jitter) */
#if 0
- vlc_tick_t delay = todisplay->date - vlc_tick_now();
+ vlc_tick_t delay = eyes[0]->date - vlc_tick_now();
if (delay < 1000)
msg_Warn(vout, "picture is late (%lld ms)", delay / 1000);
#endif
if (!is_forced)
- vlc_tick_wait(todisplay->date);
+ vlc_tick_wait(eyes[0]->date);
/* Display the direct buffer returned by vout_RenderPicture */
sys->displayed.date = vlc_tick_now();
- vout_display_Display(vd, todisplay);
+ vout_display_Display(vd, eyes[0]);
+ eyes[0]->p_next = NULL;
if (subpic)
subpicture_Delete(subpic);
@@ -1371,6 +1407,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);
}
@@ -1525,6 +1566,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 b189f4a8ef..fe541064ff 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 */
};
/**
diff --git a/src/video_output/vout_wrapper.h b/src/video_output/vout_wrapper.h
index c5dbb3a20c..7ce2f1363e 100644
--- a/src/video_output/vout_wrapper.h
+++ b/src/video_output/vout_wrapper.h
@@ -83,6 +83,9 @@ picture_t * vout_FilterDisplay(vout_display_t *, picture_t *);
void vout_FilterFlush(vout_display_t *);
bool vout_AreDisplayPicturesInvalid(vout_display_t *);
+
+void vout_SelectMultiviewPictures(vout_display_t *, picture_t *eyes[2]);
+
bool vout_ManageDisplay(vout_display_t *, bool allow_reset_pictures);
void vout_SetDisplaySize(vout_display_t *, unsigned width, unsigned height);
--
2.17.0
More information about the vlc-devel
mailing list