[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:30:25 CEST 2018
---
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
More information about the vlc-devel
mailing list