vlc/vlc-3.0 | branch: master | Thomas Guillem <tho...@gllm.fr> | Fri Mar 2 12:04:55 2018 +0100| [f313a295edf11ff49bd35f0c537c3039396c64e3] | committer: Thomas Guillem
video_output: blend subtitles with hw pics when taking a snaphost Fixes #19892 (cherry picked from commit 811677236dfeb3a3d4f010692ca03c6dadc981ca) Signed-off-by: Thomas Guillem <tho...@gllm.fr> > http://git.videolan.org/gitweb.cgi/vlc/vlc-3.0.git/?a=commit;h=f313a295edf11ff49bd35f0c537c3039396c64e3 --- src/video_output/video_output.c | 77 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 74 insertions(+), 3 deletions(-) diff --git a/src/video_output/video_output.c b/src/video_output/video_output.c index dfe2a3b3bc..ffddcb0903 100644 --- a/src/video_output/video_output.c +++ b/src/video_output/video_output.c @@ -910,6 +910,60 @@ static int ThreadDisplayPreparePicture(vout_thread_t *vout, bool reuse, bool fra return VLC_SUCCESS; } +static picture_t *ConvertRGB32AndBlendBufferNew(filter_t *filter) +{ + return picture_NewFromFormat(&filter->fmt_out.video); +} + +static picture_t *ConvertRGB32AndBlend(vout_thread_t *vout, picture_t *pic, + subpicture_t *subpic) +{ + /* This function will convert the pic to RGB32 and blend the subpic to it. + * The returned pic can't be used to display since the chroma will be + * different than the "vout display" one, but it can be used for snapshots. + * */ + + assert(vout->p->spu_blend); + + filter_owner_t owner = { + .video = { + .buffer_new = ConvertRGB32AndBlendBufferNew, + }, + }; + filter_chain_t *filterc = filter_chain_NewVideo(vout, false, &owner); + if (!filterc) + return NULL; + + es_format_t src = vout->p->spu_blend->fmt_out; + es_format_t dst = src; + dst.video.i_chroma = VLC_CODEC_RGB32; + video_format_FixRgb(&dst.video); + + if (filter_chain_AppendConverter(filterc, &src, &dst) != 0) + { + filter_chain_Delete(filterc); + return NULL; + } + + picture_Hold(pic); + pic = filter_chain_VideoFilter(filterc, pic); + filter_chain_Delete(filterc); + + if (pic) + { + filter_t *swblend = filter_NewBlend(VLC_OBJECT(vout), &dst.video); + if (swblend) + { + bool success = picture_BlendSubpicture(pic, swblend, subpic) > 0; + filter_DeleteBlend(swblend); + if (success) + return pic; + } + picture_Release(pic); + } + return NULL; +} + static int ThreadDisplayRenderPicture(vout_thread_t *vout, bool is_forced) { vout_thread_sys_t *sys = vout->p; @@ -1014,6 +1068,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 *snap_pic = todisplay; if (do_early_spu && subpic) { if (vout->p->spu_blend) { picture_t *blent = picture_pool_Get(vout->p->private_pool); @@ -1022,9 +1077,20 @@ static int ThreadDisplayRenderPicture(vout_thread_t *vout, bool is_forced) picture_Copy(blent, filtered); if (picture_BlendSubpicture(blent, vout->p->spu_blend, subpic)) { picture_Release(todisplay); - todisplay = blent; + snap_pic = todisplay = blent; } else + { + /* Blending failed, likely because the picture is opaque or + * read-only. Try to convert the opaque picture to a + * software RGB32 one before blending it. */ + if (do_snapshot) + { + picture_t *copy = ConvertRGB32AndBlend(vout, blent, subpic); + if (copy) + snap_pic = copy; + } picture_Release(blent); + } } } subpicture_Delete(subpic); @@ -1050,14 +1116,19 @@ static int ThreadDisplayRenderPicture(vout_thread_t *vout, bool is_forced) VideoFormatCopyCropAr(&direct->format, &todisplay->format); picture_Copy(direct, todisplay); picture_Release(todisplay); - todisplay = direct; + snap_pic = todisplay = direct; } /* * Take a snapshot if requested */ if (do_snapshot) - vout_snapshot_Set(&vout->p->snapshot, &vd->source, todisplay); + { + assert(snap_pic); + vout_snapshot_Set(&vout->p->snapshot, &vd->source, snap_pic); + if (snap_pic != todisplay) + picture_Release(snap_pic); + } /* Render the direct buffer */ vout_UpdateDisplaySourceProperties(vd, &todisplay->format); _______________________________________________ vlc-commits mailing list vlc-commits@videolan.org https://mailman.videolan.org/listinfo/vlc-commits