Steve Lhomme pushed to branch master at VideoLAN / VLC


Commits:
c7f0adde by Steve Lhomme at 2024-03-28T14:54:23+00:00
display: add an option to display SPUs in black bars

To do that we need the video to fill the entire window.

- - - - -
d39c000d by Steve Lhomme at 2024-03-28T14:54:23+00:00
vout_subpictures: only pass the width/height of the output area

The subpicture doesn't need to know more.

- - - - -
d423ca07 by Steve Lhomme at 2024-03-28T14:54:23+00:00
video_output: pass the display size to subpicture rendering for blending 
displays

We already pass the position of the video in the display. So we have both 
information all the time.
Plus the format SAR was already using the display SAR.

- - - - -
349e7c09 by Steve Lhomme at 2024-03-28T14:54:23+00:00
vout_subpictures: show subtitles in black bars

This is disabling the subtitle area "stacking" as it forces the source
subtitle subpicture to be absolute. But absolute subpictures have absolute
coordinates inside the (unscaled) video. They are not meant to be shown
outside of the video area.

- - - - -


9 changed files:

- include/vlc_spu.h
- include/vlc_vout_display.h
- lib/media_player.c
- modules/stream_out/transcode/video.c
- modules/video_output/splitter.c
- src/libvlc-module.c
- src/video_output/video_output.c
- src/video_output/vout_intf.c
- src/video_output/vout_subpictures.c


Changes:

=====================================
include/vlc_spu.h
=====================================
@@ -83,6 +83,7 @@ VLC_API void spu_PutSubpicture( spu_t *, subpicture_t * );
  */
 VLC_API struct vlc_render_subpicture * spu_Render( spu_t *spu, const 
vlc_fourcc_t *p_chroma_list,
                                    const video_format_t *p_fmt_dst, const 
video_format_t *p_fmt_src,
+                                   bool spu_in_full_window,
                                    const struct vout_display_place_t 
*video_position,
                                    vlc_tick_t system_now, vlc_tick_t pts,
                                    bool ignore_osd );


=====================================
include/vlc_vout_display.h
=====================================
@@ -99,6 +99,7 @@ struct vout_display_placement {
     vlc_video_align_t align; /**< Alignment within the window */
     enum vlc_video_fitting fitting; /**< Scaling/fitting mode */
     vlc_rational_t zoom; /**< Zoom ratio (if fitting is disabled) */
+    bool full_fill; /**< whether the rendering will take the whole display */
 };
 
 /**


=====================================
lib/media_player.c
=====================================
@@ -703,6 +703,7 @@ libvlc_media_player_new( libvlc_instance_t *instance )
     var_Create (mp, "sub-filter", VLC_VAR_STRING | VLC_VAR_DOINHERIT);
 
     var_Create (mp, "osd", VLC_VAR_BOOL); // off
+    var_Create (mp, "spu-fill", VLC_VAR_BOOL | VLC_VAR_DOINHERIT);
 
     doinherit = module_exists("marq") ? VLC_VAR_DOINHERIT : 0;
     var_Create(mp, "marq-marquee", VLC_VAR_STRING);


=====================================
modules/stream_out/transcode/video.c
=====================================
@@ -468,7 +468,7 @@ static picture_t * RenderSubpictures( sout_stream_id_sys_t 
*id, picture_t *p_pic
     fmt.i_sar_den = fmt.i_sar_num = 1;
 
     vlc_render_subpicture *p_subpic = spu_Render( id->p_spu, NULL, &fmt,
-                                         &outfmt, NULL, vlc_tick_now(), 
p_pic->date,
+                                         &outfmt, false, NULL, vlc_tick_now(), 
p_pic->date,
                                          false );
 
     /* Overlay subpicture */


=====================================
modules/video_output/splitter.c
=====================================
@@ -287,6 +287,7 @@ static int vlc_vidsplit_Open(vout_display_t *vd,
                 .align = { 0, 0 } /* TODO */,
                 .fitting = VLC_VIDEO_FIT_SMALLER,
                 .zoom = { 1, 1 },
+                .full_fill = true,
             },
         };
         const char *modname = output->psz_module;


=====================================
src/libvlc-module.c
=====================================
@@ -787,6 +787,10 @@ static const char* const ppsz_restore_playback_desc[] = {
 #define SPU_LONGTEXT N_( \
     "You can completely disable the sub-picture processing.")
 
+#define SPU_FULL_TEXT N_("Display sub-pictures on full window")
+#define SPU_FULL_LONGTEXT N_( \
+    "It allows showing subtitles in black bars.")
+
 #define SECONDARY_SUB_POSITION_TEXT N_("Position of secondary subtitles")
 #define SECONDARY_SUB_POSITION_LONGTEXT N_( \
     "Place on video where to display secondary subtitles (default bottom 
center).")
@@ -1748,6 +1752,8 @@ vlc_module_begin ()
 
     add_bool( "spu", true, SPU_TEXT, SPU_LONGTEXT )
         change_safe ()
+    add_bool( "spu-fill", true, SPU_FULL_TEXT, SPU_FULL_LONGTEXT )
+        change_safe ()
     add_bool( "osd", true, OSD_TEXT, OSD_LONGTEXT )
     add_module("text-renderer", "text renderer", "any",
                TEXTRENDERER_TEXT, TEXTRENDERER_LONGTEXT)


=====================================
src/video_output/video_output.c
=====================================
@@ -682,6 +682,7 @@ static void VoutGetDisplayCfg(vout_thread_sys_t *p_vout, 
const video_format_t *f
     const int display_height = var_GetInteger(vout, "height");
     cfg->display.width   = display_width > 0  ? display_width  : 0;
     cfg->display.height  = display_height > 0 ? display_height : 0;
+    cfg->display.full_fill = var_GetBool(vout, "spu-fill");
     cfg->display.fitting = var_GetBool(vout, "autoscale")
         ? var_InheritFit(VLC_OBJECT(vout)) : VLC_VIDEO_FIT_NONE;
     unsigned msar_num, msar_den;
@@ -1121,14 +1122,14 @@ static vlc_render_subpicture 
*RenderSPUs(vout_thread_sys_t *sys,
                                 const vlc_fourcc_t *subpicture_chromas,
                                 const video_format_t *spu_frame,
                                 vlc_tick_t system_now, vlc_tick_t 
render_subtitle_date,
-                                bool ignore_osd,
+                                bool ignore_osd, bool spu_in_full_window,
                                 const vout_display_place_t *video_position)
 {
     if (unlikely(sys->spu == NULL))
         return NULL;
     return spu_Render(sys->spu,
                       subpicture_chromas, spu_frame,
-                      sys->display->source, video_position,
+                      sys->display->source, spu_in_full_window, video_position,
                       system_now, render_subtitle_date,
                       ignore_osd);
 }
@@ -1164,6 +1165,8 @@ static int PrerenderPicture(vout_thread_sys_t *sys, 
picture_t *filtered,
     const bool vd_does_blending = !do_snapshot &&
                                    vd->info.subpicture_chromas &&
                                    *vd->info.subpicture_chromas != 0;
+    const bool spu_in_full_window = vd->cfg->display.full_fill &&
+                                    vd_does_blending;
 
     //FIXME: Denying blending_before_converter if vd->source->orientation != 
ORIENT_NORMAL
     //will have the effect that snapshots miss the subpictures. We do this
@@ -1183,10 +1186,12 @@ static int PrerenderPicture(vout_thread_sys_t *sys, 
picture_t *filtered,
         fmt_spu = *vd->source;
         fmt_spu.i_sar_num = vd->cfg->display.sar.num;
         fmt_spu.i_sar_den = vd->cfg->display.sar.den;
+        fmt_spu.i_x_offset       = 0;
+        fmt_spu.i_y_offset       = 0;
         fmt_spu.i_width          =
-        fmt_spu.i_visible_width  = place.width;
+        fmt_spu.i_visible_width  = vd->cfg->display.width;
         fmt_spu.i_height         =
-        fmt_spu.i_visible_height = place.height;
+        fmt_spu.i_visible_height = vd->cfg->display.height;
     } else {
         if (blending_before_converter) {
             fmt_spu = *vd->source;
@@ -1223,7 +1228,7 @@ static int PrerenderPicture(vout_thread_sys_t *sys, 
picture_t *filtered,
     if (!vd_does_blending && blending_before_converter && sys->spu_blend) {
         vlc_render_subpicture *subpic = RenderSPUs(sys, NULL, &fmt_spu_rot,
                                           system_now, render_subtitle_date,
-                                          do_snapshot, video_place);
+                                          do_snapshot, spu_in_full_window, 
video_place);
         if (subpic) {
             picture_t *blent = picture_pool_Get(sys->private_pool);
             if (blent) {
@@ -1273,7 +1278,7 @@ static int PrerenderPicture(vout_thread_sys_t *sys, 
picture_t *filtered,
     {
         vlc_render_subpicture *subpic = RenderSPUs(sys, NULL, &fmt_spu_rot,
                                           system_now, render_subtitle_date,
-                                          do_snapshot, video_place);
+                                          do_snapshot, spu_in_full_window, 
video_place);
         if (subpic)
         {
             picture_BlendSubpicture(todisplay, sys->spu_blend, subpic);
@@ -1285,7 +1290,7 @@ static int PrerenderPicture(vout_thread_sys_t *sys, 
picture_t *filtered,
     if (vd_does_blending)
         *out_subpic = RenderSPUs(sys, vd->info.subpicture_chromas, 
&fmt_spu_rot,
                                  system_now, render_subtitle_date,
-                                 false, video_place);
+                                 false, spu_in_full_window, video_place);
     else
         *out_subpic = NULL;
 


=====================================
src/video_output/vout_intf.c
=====================================
@@ -298,6 +298,10 @@ void vout_CreateVars( vout_thread_t *p_vout )
     /* Viewpoint */
     var_Create( p_vout, "viewpoint", VLC_VAR_ADDRESS  );
     var_Create( p_vout, "viewpoint-changeable", VLC_VAR_BOOL );
+
+    /* SPU in full window */
+    var_Create( p_vout, "spu-fill", VLC_VAR_BOOL | VLC_VAR_DOINHERIT
+                | VLC_VAR_ISCOMMAND );
 }
 
 void vout_IntfInit( vout_thread_t *p_vout )


=====================================
src/video_output/vout_subpictures.c
=====================================
@@ -135,6 +135,8 @@ struct spu_private_t {
         subpicture_t   *p_processed;
         video_format_t  fmtsrc;
         video_format_t  fmtdst;
+        bool            spu_in_full_window;
+        vout_display_place_t video_position;
         vlc_fourcc_t    chroma_list[SPU_CHROMALIST_COUNT+1];
         bool            live;
     } prerender;
@@ -579,12 +581,13 @@ static void SpuAreaFixOverlap(spu_area_t *dst,
 }
 
 
-static void SpuAreaFitInside(spu_area_t *area, const spu_area_t *boundary)
+static void SpuAreaFitInside(spu_area_t *area, const unsigned boundary_width,
+                                               const unsigned boundary_height)
 {
     spu_area_t a = spu_area_scaled(*area);
     bool modified = false;
 
-    const int i_error_x = (a.x + a.width) - boundary->width;
+    const int i_error_x = (a.x + a.width) - boundary_width;
     if (i_error_x > 0)
     {
         a.x -= i_error_x;
@@ -596,7 +599,7 @@ static void SpuAreaFitInside(spu_area_t *area, const 
spu_area_t *boundary)
         modified = true;
     }
 
-    const int i_error_y = (a.y + a.height) - boundary->height;
+    const int i_error_y = (a.y + a.height) - boundary_height;
     if (i_error_y > 0)
     {
         a.y -= i_error_y;
@@ -952,7 +955,7 @@ static struct subpicture_region_rendered 
*SpuRenderRegion(spu_t *spu,
                             subpicture_region_t *region,
                             const spu_scale_t scale_size, bool apply_scale,
                             const vlc_fourcc_t *chroma_list,
-                            const video_format_t *fmt,
+                            const unsigned output_width, const unsigned 
output_height,
                             const spu_area_t *subtitle_area, size_t 
subtitle_area_count,
                             vlc_tick_t render_date)
 {
@@ -1036,10 +1039,7 @@ static struct subpicture_region_rendered 
*SpuRenderRegion(spu_t *spu,
     if (subpic->b_subtitle)
         restrained.y -= y_margin;
 
-    spu_area_t display = spu_area_create(0, 0, fmt->i_visible_width,
-                                         fmt->i_visible_height,
-                                         spu_scale_unit());
-    SpuAreaFitInside(&restrained, &display);
+    SpuAreaFitInside(&restrained, output_width, output_height);
 
     /* Fix the position for the current scale_size */
     x_offset = spu_scale_w(restrained.x, restrained.scale);
@@ -1317,6 +1317,23 @@ static void spu_UpdateOriginalSize(spu_t *spu, 
subpicture_t *subpic,
     }
 }
 
+static bool IsSubpicInVideo(const subpicture_t *subpic, bool 
spu_in_full_window)
+{
+    // no spu outside video allowed
+    if (!spu_in_full_window)
+        return true;
+
+    // absolute spu in video coordinates
+    if (subpic->b_absolute)
+        return true;
+
+    // only subtitle SPUs allowed outside video
+    if (!subpic->b_subtitle)
+        return true;
+
+    return false;
+}
+
 /**
  * This function renders all sub picture units in the list.
  */
@@ -1326,6 +1343,7 @@ static vlc_render_subpicture *SpuRenderSubpictures(spu_t 
*spu,
                                           const vlc_fourcc_t *chroma_list,
                                           const video_format_t *fmt_dst,
                                           const video_format_t *fmt_src,
+                                          bool spu_in_full_window,
                                           const vout_display_place_t 
*video_position,
                                           vlc_tick_t system_now,
                                           vlc_tick_t render_subtitle_date,
@@ -1380,6 +1398,16 @@ static vlc_render_subpicture *SpuRenderSubpictures(spu_t 
*spu,
 
         const unsigned i_original_width = subpic->i_original_picture_width;
         const unsigned i_original_height = subpic->i_original_picture_height;
+        const bool subpic_in_video = IsSubpicInVideo(subpic, 
spu_in_full_window);
+
+        unsigned output_width, output_height;
+        if (subpic_in_video) {
+            output_width  = video_position->width;
+            output_height = video_position->height;
+        } else {
+            output_width  = fmt_dst->i_visible_width;
+            output_height = fmt_dst->i_visible_height;
+        }
 
         /* Render all regions
          * We always transform non absolute subtitle into absolute one on the
@@ -1410,9 +1438,9 @@ static vlc_render_subpicture *SpuRenderSubpictures(spu_t 
*spu,
             };
             if (region_sar.num <= 0 || region_sar.den <= 0) {
 
-                const uint64_t i_sar_num = (uint64_t)fmt_dst->i_visible_width  
*
+                const uint64_t i_sar_num = (uint64_t)output_width  *
                                            fmt_dst->i_sar_num * 
i_original_height;
-                const uint64_t i_sar_den = (uint64_t)fmt_dst->i_visible_height 
*
+                const uint64_t i_sar_den = (uint64_t)output_height *
                                            fmt_dst->i_sar_den * 
i_original_width;
 
                 vlc_ureduce(&region_sar.num, &region_sar.den,
@@ -1426,9 +1454,9 @@ static vlc_render_subpicture *SpuRenderSubpictures(spu_t 
*spu,
             // position the rendered video, rather than the whole output format
             // expand the width using the SAR
             spu_scale_t scale;
-            scale = spu_scale_createq((uint64_t)video_position->height * 
fmt_dst->i_sar_den * region_sar.num,
+            scale = spu_scale_createq((uint64_t)output_height          * 
fmt_dst->i_sar_den * region_sar.num,
                                       (uint64_t)i_original_height      * 
fmt_dst->i_sar_num * region_sar.den,
-                                      video_position->height,
+                                      output_height,
                                       i_original_height);
 
             /* Check scale validity */
@@ -1448,7 +1476,7 @@ static vlc_render_subpicture *SpuRenderSubpictures(spu_t 
*spu,
             output_last_ptr = SpuRenderRegion(spu, &area,
                             &forced_subpic, entry->channel_order,
                             rendered_region, scale, !external_scale,
-                            chroma_list, fmt_dst,
+                            chroma_list, output_width, output_height,
                             subtitle_area, subtitle_area_count,
                             subpic->b_subtitle ? render_subtitle_date : 
system_now);
             if (rendered_region != region)
@@ -1456,9 +1484,11 @@ static vlc_render_subpicture *SpuRenderSubpictures(spu_t 
*spu,
             if (unlikely(output_last_ptr == NULL))
                 continue;
 
-            // place the region inside the video area
-            output_last_ptr->place.x += video_position->x;
-            output_last_ptr->place.y += video_position->y;
+            if (subpic_in_video) {
+                // place the region inside the video area
+                output_last_ptr->place.x += video_position->x;
+                output_last_ptr->place.y += video_position->y;
+            }
 
             vlc_vector_push(&output->regions, output_last_ptr);
 
@@ -1610,6 +1640,8 @@ static int SubSourceDelProxyCallbacks(filter_t *filter, 
void *opaque)
 static void spu_PrerenderWake(spu_private_t *sys,
                               const video_format_t *fmt_dst,
                               const video_format_t *fmt_src,
+                              bool spu_in_full_window,
+                              const vout_display_place_t *video_position,
                               const vlc_fourcc_t *chroma_list)
 {
     vlc_mutex_lock(&sys->prerender.lock);
@@ -1623,6 +1655,8 @@ static void spu_PrerenderWake(spu_private_t *sys,
         video_format_Clean(&sys->prerender.fmtsrc);
         video_format_Copy(&sys->prerender.fmtsrc, fmt_src);
     }
+    sys->prerender.spu_in_full_window = spu_in_full_window;
+    sys->prerender.video_position = *video_position;
 
     for(size_t i=0; i<SPU_CHROMALIST_COUNT; i++)
     {
@@ -1744,6 +1778,13 @@ static void * spu_PrerenderThread(void *priv)
         video_format_Copy(&fmtdst, &sys->prerender.fmtdst);
         video_format_Copy(&fmtsrc, &sys->prerender.fmtsrc);
 
+        if (IsSubpicInVideo(sys->prerender.p_processed, 
sys->prerender.spu_in_full_window))
+        {
+            fmtdst.i_width  = fmtdst.i_visible_width  = 
sys->prerender.video_position.width;
+            fmtdst.i_height = fmtdst.i_visible_height = 
sys->prerender.video_position.height;
+            fmtdst.i_sar_num = fmtdst.i_sar_den = 1;
+        }
+
         vlc_mutex_unlock(&sys->prerender.lock);
 
         spu_PrerenderText(spu, sys->prerender.p_processed,
@@ -2137,6 +2178,7 @@ vlc_render_subpicture *spu_Render(spu_t *spu,
                          const vlc_fourcc_t *chroma_list,
                          const video_format_t *fmt_dst,
                          const video_format_t *fmt_src,
+                         bool spu_in_full_window,
                          const vout_display_place_t *video_position,
                          vlc_tick_t system_now,
                          vlc_tick_t render_subtitle_date,
@@ -2209,7 +2251,7 @@ vlc_render_subpicture *spu_Render(spu_t *spu,
     }
 
     /* wake up prerenderer, we have some video size and chroma */
-    spu_PrerenderWake(sys, fmt_dst, fmt_src, chroma_list);
+    spu_PrerenderWake(sys, fmt_dst, fmt_src, spu_in_full_window, 
video_position, chroma_list);
 
     vlc_mutex_lock(&sys->lock);
 
@@ -2236,8 +2278,16 @@ vlc_render_subpicture *spu_Render(spu_t *spu,
         subpic->i_start = entry->start;
         subpic->i_stop = entry->stop;
 
+        video_format_t fmtdst = *fmt_dst;
+        if (IsSubpicInVideo(subpic, spu_in_full_window))
+        {
+            fmtdst.i_width  = fmtdst.i_visible_width  = video_position->width;
+            fmtdst.i_height = fmtdst.i_visible_height = video_position->height;
+            fmtdst.i_sar_num = fmtdst.i_sar_den = 1;
+        }
+
         subpicture_Update(subpic,
-                          fmt_src, fmt_dst,
+                          fmt_src, &fmtdst,
                           subpic->b_subtitle ? render_subtitle_date : 
system_now);
     }
 
@@ -2251,6 +2301,7 @@ vlc_render_subpicture *spu_Render(spu_t *spu,
                                                 chroma_list,
                                                 fmt_dst,
                                                 fmt_src,
+                                                spu_in_full_window,
                                                 video_position,
                                                 system_now,
                                                 render_subtitle_date,



View it on GitLab: 
https://code.videolan.org/videolan/vlc/-/compare/8b09d72394f3ec75b388aaaea4415331f535c4a4...349e7c09eeea8e947eb560d4890a784e1772aa22

-- 
View it on GitLab: 
https://code.videolan.org/videolan/vlc/-/compare/8b09d72394f3ec75b388aaaea4415331f535c4a4...349e7c09eeea8e947eb560d4890a784e1772aa22
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance
_______________________________________________
vlc-commits mailing list
vlc-commits@videolan.org
https://mailman.videolan.org/listinfo/vlc-commits

Reply via email to