Steve Lhomme pushed to branch master at VideoLAN / VLC


Commits:
149ec7c4 by Steve Lhomme at 2024-03-22T11:40:44+00:00
direct3d11: turn if on scaling zoom into asserts

The core cannot give us a null scaling.

- - - - -
88a96744 by Steve Lhomme at 2024-03-22T11:40:44+00:00
direct3d9: handle subpicture region scaling

- - - - -
47ef6c88 by Steve Lhomme at 2024-03-22T11:40:44+00:00
opengl: handle subpicture region scaling

- - - - -
3434d904 by Steve Lhomme at 2024-03-22T11:40:44+00:00
mmal/vout: fix extend of region rendering

They are only shown in the display area, regardless of the picture cropping.

- - - - -
b91f768c by Steve Lhomme at 2024-03-22T11:40:44+00:00
mmal/vout: handle subpicture region scaling

- - - - -
488a671c by Steve Lhomme at 2024-03-22T11:40:44+00:00
xcb/render: crop the region picture before rendering it

This is how the main picture is handled as well

- - - - -
7c37a081 by Steve Lhomme at 2024-03-22T11:40:44+00:00
xcb/render: use a factor to scale horizontally/vertically

- - - - -
eaaf8cfc by Steve Lhomme at 2024-03-22T11:40:44+00:00
xcb/render: handle subpicture region scaling

- - - - -
7908d46e by Steve Lhomme at 2024-03-22T11:40:44+00:00
libplacebo: handle subpicture region scaling

- - - - -
918e7fc1 by Steve Lhomme at 2024-03-22T11:40:44+00:00
android/display: handle subpicture region scaling

- - - - -
f6845137 by Steve Lhomme at 2024-03-22T11:40:44+00:00
VLCSampleBufferDisplay: handle subpicture region scaling

- - - - -
f9434a95 by Steve Lhomme at 2024-03-22T11:40:44+00:00
vout_subpictures: set the part of the region picture to display in the picture

The picture format already has a way to set cropping values in the picture.
We just need a clone of the picture to change the metadata.

- - - - -
073cba39 by Steve Lhomme at 2024-03-22T11:40:44+00:00
subpicture: use the cropped picture format when blending

The local blend_fmt was just exactly the same.

- - - - -
7b5664c0 by Steve Lhomme at 2024-03-22T11:40:44+00:00
vout_subpictures: handle zoomed placement in the core

The zooming factor is applied once in the core, no need to make the display 
module compute it.

- - - - -
d8a0130e by Steve Lhomme at 2024-03-22T11:40:44+00:00
vout: reset the display info before each opening

A display module may set a value but not be used in the end.

- - - - -
17bc969d by Steve Lhomme at 2024-03-22T11:40:44+00:00
vlc_spu: assume display module that can render subpicture regions can scale it

We already require these display modules to be able to place and scale/stretch 
the video picture.

- - - - -
afbc933c by Steve Lhomme at 2024-03-22T11:40:44+00:00
vout_subpictures: simplify spu region scaling boolean

At this stage all regions are picture-based (ie not text regions). We don't 
need to check it anymore.
Even if someday display modules can render text regions on their own, they can 
surely do the scaling too.

- - - - -
36f6d1c5 by Steve Lhomme at 2024-03-22T11:40:44+00:00
vout_subpictures: handle region scaled placement in SpuRenderRegion()

We can avoid some scaling rounding if it's not applied.

- - - - -


19 changed files:

- include/vlc_spu.h
- include/vlc_subpicture.h
- include/vlc_vout_display.h
- modules/hw/mmal/mmal_picture.c
- modules/hw/mmal/mmal_picture.h
- modules/hw/mmal/vout.c
- modules/stream_out/transcode/video.c
- modules/video_output/android/display.c
- modules/video_output/apple/VLCSampleBufferDisplay.m
- modules/video_output/libplacebo/display.c
- modules/video_output/opengl/sub_renderer.c
- modules/video_output/win32/direct3d11.cpp
- modules/video_output/win32/direct3d9.c
- modules/video_output/xcb/render.c
- src/misc/subpicture.c
- src/video_output/display.c
- src/video_output/video_output.c
- src/video_output/vout_subpictures.c
- test/modules/video_output/opengl/sub_renderer.c


Changes:

=====================================
include/vlc_spu.h
=====================================
@@ -75,14 +75,13 @@ VLC_API void spu_PutSubpicture( spu_t *, subpicture_t * );
  * \param system_now the reference current time
  * \param pts the timestamp of the rendered frame
  * \param ignore_osd whether we display the OSD or not
- * \param external_scale whether scaling picture is done by the client or this 
function
  *
  * The returned value if non NULL must be released by subpicture_Delete().
  */
 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,
                                    vlc_tick_t system_now, vlc_tick_t pts,
-                                   bool ignore_osd, bool external_scale );
+                                   bool ignore_osd );
 
 /**
  * It registers a new SPU channel.


=====================================
include/vlc_subpicture.h
=====================================
@@ -208,13 +208,8 @@ typedef struct subpicture_private_t subpicture_private_t;
 struct subpicture_region_rendered
 {
     picture_t       *p_picture;          /**< picture comprising this region */
-
-    unsigned             source_offset_x;
-    unsigned             source_offset_y;
     vout_display_place_t place;    // position of region, relative to alignment
     int             i_alpha;                               /**< transparency */
-    vlc_rational_t  zoom_h;
-    vlc_rational_t  zoom_v;
 };
 
 struct vlc_render_subpicture


=====================================
include/vlc_vout_display.h
=====================================
@@ -129,7 +129,6 @@ typedef struct vout_display_cfg {
  *
  */
 typedef struct {
-    bool can_scale_spu;                     /* Handles subpictures with a non 
default zoom factor */
     const vlc_fourcc_t *subpicture_chromas; /* List of supported chromas for 
subpicture rendering. */
 } vout_display_info_t;
 


=====================================
modules/hw/mmal/mmal_picture.c
=====================================
@@ -1036,6 +1036,7 @@ MMAL_BUFFER_HEADER_T * 
hw_mmal_vzc_buf_from_pic(vzc_pool_ctl_t * const pc,
                                                 picture_t * const pic,
                                                 const MMAL_RECT_T dst_pic_rect,
                                                 const int x_offset, const int 
y_offset,
+                                                const unsigned width, const 
unsigned height,
                                                 const unsigned int alpha,
                                                 const bool is_first)
 {
@@ -1134,8 +1135,8 @@ MMAL_BUFFER_HEADER_T * 
hw_mmal_vzc_buf_from_pic(vzc_pool_ctl_t * const pc,
         sb->orig_dest_rect = (MMAL_RECT_T){
             .x      = x_offset,
             .y      = y_offset,
-            .width  = fmt->i_visible_width,
-            .height = fmt->i_visible_height
+            .width  = width,
+            .height = height
         };
 
         if (needs_copy)


=====================================
modules/hw/mmal/mmal_picture.h
=====================================
@@ -126,6 +126,7 @@ typedef struct vzc_pool_ctl_s vzc_pool_ctl_t;
 MMAL_BUFFER_HEADER_T * hw_mmal_vzc_buf_from_pic(vzc_pool_ctl_t * const pc, 
picture_t * const pic,
                                                 const MMAL_RECT_T dst_pic_rect,
                                                 const int x_offset, const int 
y_offset,
+                                                const unsigned width, const 
unsigned height,
                                                 const unsigned int alpha, 
const bool is_first);
 
 void hw_mmal_vzc_pool_flush(vzc_pool_ctl_t * const pc);


=====================================
modules/hw/mmal/vout.c
=====================================
@@ -753,7 +753,10 @@ static int attach_subpics(vout_display_t * const vd, 
vout_display_sys_t * const
         if ((sys->subpic_bufs[n] = hw_mmal_vzc_buf_from_pic(sys->vzc,
             src,
             (MMAL_RECT_T){.width = vd->cfg->display.width, 
.height=vd->cfg->display.height},
-            r->place.x, r->place.y,
+            r->place.x,
+            r->place.y,
+            r->place.width,
+            r->place.height,
             r->i_alpha,
             n == 0)) == NULL)
         {
@@ -1254,7 +1257,7 @@ static int OpenMmalVout(vout_display_t *vd,
     fmtp->i_chroma = req_chroma(fmtp);
 
     vd->info = (vout_display_info_t){
-        .subpicture_chromas = hw_mmal_vzc_subpicture_chromas
+        .subpicture_chromas = hw_mmal_vzc_subpicture_chromas,
     };
 
     vd->ops = &ops;


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


=====================================
modules/video_output/android/display.c
=====================================
@@ -150,7 +150,8 @@ static bool subpicture_NeedDraw(vout_display_t *vd,
         vlc_vector_foreach(r, &subpicture->regions)
         {
             struct sub_region *cmp = &sub->regions.data[i++];
-            if (cmp->x != r->place.x || cmp->y != r->place.y
+            if (cmp->x != r->place.x
+             || cmp->y != r->place.y
              || cmp->width != r->place.width
              || cmp->height != r->place.height)
             {


=====================================
modules/video_output/apple/VLCSampleBufferDisplay.m
=====================================
@@ -407,15 +407,15 @@ static CGRect RegionBackingFrame(VLCSampleBufferDisplay* 
sys,
                                  const vlc_render_subpicture *subpicture,
                                  const struct subpicture_region_rendered *r)
 {
-    const float scale_w = (float)(sys->place.width)  / 
subpicture->i_original_picture_width;
-    const float scale_h = (float)(sys->place.height) / 
subpicture->i_original_picture_height;
+    const float scale_w = (float)(sys->place.width ) / 
(subpicture->i_original_picture_width );
+    const float scale_h = (float)(sys->place.height) / 
(subpicture->i_original_picture_height);
 
     // Invert y coords for CoreGraphics
-    const float y = subpicture->i_original_picture_height - r->place.height - 
r->place.y;
+    const float y = subpicture->i_original_picture_height - scale_h * 
(r->place.height + r->place.y);
 
     return CGRectMake(
         scale_w * r->place.x + sys->place.x,
-        scale_h * y + sys->place.y,
+        /*scale_h */ y + sys->place.y,
         scale_w * r->place.width,
         scale_h * r->place.height
     );
@@ -436,8 +436,8 @@ static void UpdateSubpictureRegions(vout_display_t *vd,
     vlc_vector_foreach(r, &subpicture->regions) {
         CFIndex length = r->p_picture->format.i_height * 
r->p_picture->p->i_pitch;
         const size_t pixels_offset =
-                r->source_offset_y * r->p_picture->p->i_pitch +
-                r->source_offset_x * r->p_picture->p->i_pixel_pitch;
+                r->p_picture->format.i_y_offset * r->p_picture->p->i_pitch +
+                r->p_picture->format.i_x_offset * 
r->p_picture->p->i_pixel_pitch;
 
         CFDataRef data = CFDataCreate(
             NULL,


=====================================
modules/video_output/libplacebo/display.c
=====================================
@@ -167,7 +167,6 @@ static int Open(vout_display_t *vd,
     };
 
     vd->info.subpicture_chromas = subfmts;
-
     vd->ops = &ops;
 
     UpdateParams(vd);
@@ -411,15 +410,13 @@ static void PictureRender(vout_display_t *vd, picture_t 
*pic,
 
             sys->overlay_parts[i] = (struct pl_overlay_part) {
                 .src = {
-                    .x0 = r->source_offset_x,
-                    .y0 = r->source_offset_y,
-                    .x1 = r->source_offset_x + r->place.width,
-                    .y1 = r->source_offset_y + r->place.height,
+                    .x1 = r->p_picture->format.i_visible_width,
+                    .y1 = r->p_picture->format.i_visible_height,
                 },
                 .dst = {
                     .x0 = place.x + r->place.x,
                     .y0 = place.y + r->place.y * ysign,
-                    .x1 = place.x + r->place.x + r->place.width,
+                    .x1 = place.x + (r->place.x + r->place.width ),
                     .y1 = place.y + (r->place.y + r->place.height) * ysign,
                 },
             };


=====================================
modules/video_output/opengl/sub_renderer.c
=====================================
@@ -280,8 +280,8 @@ vlc_gl_sub_renderer_Prepare(struct vlc_gl_sub_renderer *sr,
             }
 
             const size_t pixels_offset =
-                r->source_offset_y * r->p_picture->p->i_pitch +
-                r->source_offset_x * r->p_picture->p->i_pixel_pitch;
+                r->p_picture->format.i_y_offset * r->p_picture->p->i_pitch +
+                r->p_picture->format.i_x_offset * 
r->p_picture->p->i_pixel_pitch;
             if (!glr->texture)
             {
                 /* Could not recycle a previous texture, generate a new one. */


=====================================
modules/video_output/win32/direct3d11.cpp
=====================================
@@ -491,8 +491,6 @@ static int Open(vout_display_t *vd,
     vlc_window_SetTitle(vd->cfg->window, VOUT_TITLE " (Direct3D11 output)");
     msg_Dbg(vd, "Direct3D11 display adapter successfully initialized");
 
-    vd->info.can_scale_spu        = true;
-
     if (var_InheritBool(vd, "direct3d11-hw-blending") &&
         sys->regionQuad.generic.textureFormat != NULL)
     {
@@ -1567,10 +1565,10 @@ static int Direct3D11MapSubpicture(vout_display_t *vd, 
int *subpicture_region_co
         }
 
         RECT output;
-        output.left   = r->source_offset_x;
-        output.right  = r->source_offset_x + r->place.width;
-        output.top    = r->source_offset_y;
-        output.bottom = r->source_offset_y + r->place.height;
+        output.left   = r->p_picture->format.i_x_offset;
+        output.right  = r->p_picture->format.i_x_offset + 
r->p_picture->format.i_visible_width;
+        output.top    = r->p_picture->format.i_y_offset;
+        output.bottom = r->p_picture->format.i_y_offset + 
r->p_picture->format.i_visible_height;
 
         D3D11_UpdateQuadPosition(vd, sys->d3d_dev, quad, &output,
             video_format_GetTransform(ORIENT_NORMAL, 
sys->display.orientation));
@@ -1581,17 +1579,6 @@ static int Direct3D11MapSubpicture(vout_display_t *vd, 
int *subpicture_region_co
         spuViewport.right  = (FLOAT) (r->place.x + r->place.width)  * 
sys->area.place.width  / subpicture->i_original_picture_width;
         spuViewport.bottom = (FLOAT) (r->place.y + r->place.height) * 
sys->area.place.height / subpicture->i_original_picture_height;
 
-        if (r->zoom_h.num != 0 && r->zoom_h.den != 0)
-        {
-            spuViewport.left   = (FLOAT) spuViewport.left   * r->zoom_h.num / 
r->zoom_h.den;
-            spuViewport.right  = (FLOAT) spuViewport.right  * r->zoom_h.num / 
r->zoom_h.den;
-        }
-        if (r->zoom_v.num != 0 && r->zoom_v.den != 0)
-        {
-            spuViewport.top    = (FLOAT) spuViewport.top    * r->zoom_v.num / 
r->zoom_v.den;
-            spuViewport.bottom = (FLOAT) spuViewport.bottom * r->zoom_v.num / 
r->zoom_v.den;
-        }
-
         /* move the SPU inside the video area */
         spuViewport.left   += sys->area.place.x;
         spuViewport.right  += sys->area.place.x;


=====================================
modules/video_output/win32/direct3d9.c
=====================================
@@ -926,7 +926,7 @@ static void Direct3D9ImportSubpicture(vout_display_t *vd,
             uint8_t  *src_data   = r->p_picture->p->p_pixels;
             int       src_pitch  = r->p_picture->p->i_pitch;
 
-            if (d3dr->format == D3DFMT_A8B8G8R8) {
+            if (d3dr->format == D3DFMT_A8B8G8R8 /*|| d3dr->format == 
D3DFMT_A8R8G8B8*/) {
                 if (dst_pitch == r->p_picture->p->i_pitch) {
                     memcpy(dst_data, src_data, r->p_picture->format.i_height * 
dst_pitch);
                 } else {
@@ -954,14 +954,14 @@ static void Direct3D9ImportSubpicture(vout_display_t *vd,
         }
 
         /* Map the subpicture to sys->sys.sys.place */
-        const float scale_w = (float)(sys->area.place.width)  / 
subpicture->i_original_picture_width;
+        const float scale_w = (float)(sys->area.place.width ) / 
subpicture->i_original_picture_width;
         const float scale_h = (float)(sys->area.place.height) / 
subpicture->i_original_picture_height;
 
         RECT rect_in_display;
-        rect_in_display.left   =            scale_w * r->place.x,
-        rect_in_display.right  = rect_in_display.left + scale_w * 
r->place.width,
-        rect_in_display.top    =            scale_h * r->place.y,
-        rect_in_display.bottom = rect_in_display.top  + scale_h * 
r->place.height;
+        rect_in_display.left   = scale_w * r->place.x;
+        rect_in_display.right  = scale_w * (r->place.x + r->place.width);
+        rect_in_display.top    = scale_h * r->place.y;
+        rect_in_display.bottom = scale_h * (r->place.y + r->place.height);
 
         rect_in_display.left   += sys->area.place.x;
         rect_in_display.right  += sys->area.place.x;
@@ -975,10 +975,10 @@ static void Direct3D9ImportSubpicture(vout_display_t *vd,
         texture_rect.bottom = r->p_picture->format.i_height;
 
         RECT texture_visible_rect;
-        texture_visible_rect.left   = r->source_offset_x;
-        texture_visible_rect.right  = r->source_offset_x + r->place.width;
-        texture_visible_rect.top    = r->source_offset_y;
-        texture_visible_rect.bottom = r->source_offset_y + r->place.height;
+        texture_visible_rect.left   = r->p_picture->format.i_x_offset;
+        texture_visible_rect.right  = r->p_picture->format.i_x_offset + 
r->p_picture->format.i_visible_width;
+        texture_visible_rect.top    = r->p_picture->format.i_y_offset;
+        texture_visible_rect.bottom = r->p_picture->format.i_y_offset + 
r->p_picture->format.i_visible_height;
 
         Direct3D9SetupVertices(d3dr->vertex, &texture_rect, 
&texture_visible_rect,
                               &rect_in_display, r->i_alpha, ORIENT_NORMAL);


=====================================
modules/video_output/xcb/render.c
=====================================
@@ -52,6 +52,7 @@ typedef struct vout_display_sys_t {
         xcb_pixmap_t crop;
         xcb_pixmap_t scale;
         xcb_pixmap_t subpic;
+        xcb_pixmap_t subpic_crop;
         xcb_pixmap_t alpha;
         xcb_window_t dest;
     } drawable;
@@ -60,6 +61,7 @@ typedef struct vout_display_sys_t {
         xcb_render_picture_t crop;
         xcb_render_picture_t scale;
         xcb_render_picture_t subpic;
+        xcb_render_picture_t subpic_crop;
         xcb_render_picture_t alpha;
         xcb_render_picture_t dest;
     } picture;
@@ -118,14 +120,18 @@ static void RenderRegion(vout_display_t *vd, const 
vlc_render_subpicture *subpic
     xcb_connection_t *conn = sys->conn;
     const vout_display_place_t *place = &sys->place;
     picture_t *pic = reg->p_picture;
-    unsigned sw = pic->format.i_width;
-    unsigned sh = pic->format.i_height;
+    unsigned sw = reg->place.width;
+    unsigned sh = reg->place.height;
     xcb_rectangle_t rects[] = { { 0, 0, sw, sh }, };
 
-    xcb_create_pixmap(conn, 32, sys->drawable.subpic, sys->root, sw, sh);
+    xcb_create_pixmap(conn, 32, sys->drawable.subpic, sys->root, 
+        pic->format.i_width, pic->format.i_height);
+    xcb_create_pixmap(conn, 32, sys->drawable.subpic_crop, sys->root, sw, sh);
     xcb_create_pixmap(conn, 8, sys->drawable.alpha, sys->root, sw, sh);
     xcb_render_create_picture(conn, sys->picture.subpic, sys->drawable.subpic,
                               sys->format.argb, 0, NULL);
+    xcb_render_create_picture(conn, sys->picture.subpic_crop, 
sys->drawable.subpic_crop,
+                              sys->format.argb, 0, NULL);
     xcb_render_create_picture(conn, sys->picture.alpha, sys->drawable.alpha,
                               sys->format.alpha, 0, NULL);
 
@@ -135,9 +141,16 @@ static void RenderRegion(vout_display_t *vd, const 
vlc_render_subpicture *subpic
                   pic->p->i_lines, 0, 0, 0, 32,
                   pic->p->i_pitch * pic->p->i_lines, pic->p->p_pixels);
 
-    /* Copy alpha channel */
+    /* Crop the picture with pixel accuracy */
     xcb_render_composite(conn, XCB_RENDER_PICT_OP_SRC,
                          sys->picture.subpic, XCB_RENDER_PICTURE_NONE,
+                         sys->picture.subpic_crop,
+                         reg->p_picture->format.i_x_offset, 
reg->p_picture->format.i_y_offset, 0, 0,
+                         0, 0, reg->p_picture->format.i_visible_width, 
reg->p_picture->format.i_visible_height);
+
+    /* Copy alpha channel */
+    xcb_render_composite(conn, XCB_RENDER_PICT_OP_SRC,
+                         sys->picture.subpic_crop, XCB_RENDER_PICTURE_NONE,
                          sys->picture.alpha, 0, 0, 0, 0, 0, 0, sw, sh);
 
     /* Force alpha channel to maximum (add 100% and clip).
@@ -147,7 +160,7 @@ static void RenderRegion(vout_display_t *vd, const 
vlc_render_subpicture *subpic
     static const xcb_render_color_t alpha_one_color = { 0, 0, 0, 0xffff };
 
     xcb_render_fill_rectangles(conn, XCB_RENDER_PICT_OP_ADD,
-                               sys->picture.subpic, alpha_one_color,
+                               sys->picture.subpic_crop, alpha_one_color,
                                ARRAY_SIZE(rects), rects);
 
     /* Multiply by region and subpicture alpha factors */
@@ -156,31 +169,52 @@ static void RenderRegion(vout_display_t *vd, const 
vlc_render_subpicture *subpic
         0, 0, 0, lroundf(reg->i_alpha * alpha_fixed) };
 
     xcb_render_fill_rectangles(conn, XCB_RENDER_PICT_OP_IN_REVERSE,
-                               sys->picture.subpic, alpha_color,
+                               sys->picture.subpic_crop, alpha_color,
                                ARRAY_SIZE(rects), rects);
 
+    const float scale_w = (float)(place->width ) / 
(subpic->i_original_picture_width );
+    const float scale_h = (float)(place->height) / 
(subpic->i_original_picture_height);
     /* Mask in the original alpha channel then renver over the scaled pixmap.
      * Mask (pre)multiplies RGB channels and restores the alpha channel.
      */
-    int_fast16_t dx = place->x + reg->place.x * place->width
-                      / subpic->i_original_picture_width;
-    int_fast16_t dy = place->y + reg->place.y * place->height
-                      / subpic->i_original_picture_height;
-    uint_fast16_t dw = (reg->place.width) * place->width
-                       / subpic->i_original_picture_width;
-    uint_fast16_t dh = (reg->place.height) * place->height
-                       / subpic->i_original_picture_height;
+    int_fast16_t dx = place->x + reg->place.x * scale_w;
+    int_fast16_t dy = place->y + reg->place.y * scale_h;
+    uint_fast16_t dw = (reg->place.width)  * scale_w;
+    uint_fast16_t dh = (reg->place.height) * scale_h;
+
+    xcb_render_transform_t transform = {
+        0, 0, 0,
+        0, 0, 0,
+        /* Multiply z by width and height to compensate for x and y above */
+        0, 0, 10000,
+    };
+    transform.matrix11 = 10000 * reg->p_picture->format.i_visible_width  / 
reg->place.width;
+    transform.matrix22 = 10000 * reg->p_picture->format.i_visible_height / 
reg->place.height;
+
+    xcb_render_set_picture_transform(conn, sys->picture.subpic_crop, 
transform);
+    xcb_render_set_picture_transform(conn, sys->picture.alpha,       
transform);
+
+    if (likely(sys->filter != NULL))
+    {
+        xcb_render_set_picture_filter(conn, sys->picture.subpic_crop,
+                                      strlen(sys->filter), sys->filter,
+                                      0, NULL);
+        xcb_render_set_picture_filter(conn, sys->picture.alpha,
+                                      strlen(sys->filter), sys->filter,
+                                      0, NULL);
+    } 
 
     xcb_render_composite(conn, XCB_RENDER_PICT_OP_OVER,
-                         sys->picture.subpic, sys->picture.alpha,
+                         sys->picture.subpic_crop, sys->picture.alpha,
                          sys->picture.scale,
-                         reg->source_offset_x, reg->source_offset_y,
-                         reg->source_offset_x, reg->source_offset_y,
+                         0, 0, 0, 0,
                          dx, dy, dw, dh);
 
     xcb_render_free_picture(conn, sys->picture.alpha);
+    xcb_render_free_picture(conn, sys->picture.subpic_crop);
     xcb_render_free_picture(conn, sys->picture.subpic);
     xcb_free_pixmap(conn, sys->drawable.alpha);
+    xcb_free_pixmap(conn, sys->drawable.subpic_crop);
     xcb_free_pixmap(conn, sys->drawable.subpic);
 }
 
@@ -651,12 +685,14 @@ static int Open(vout_display_t *vd,
     sys->drawable.crop = xcb_generate_id(conn);
     sys->drawable.scale = xcb_generate_id(conn);
     sys->drawable.subpic = xcb_generate_id(conn);
+    sys->drawable.subpic_crop = xcb_generate_id(conn);
     sys->drawable.alpha = xcb_generate_id(conn);
     sys->drawable.dest = xcb_generate_id(conn);
     sys->picture.source = xcb_generate_id(conn);
     sys->picture.crop = xcb_generate_id(conn);
     sys->picture.scale = xcb_generate_id(conn);
     sys->picture.subpic = xcb_generate_id(conn);
+    sys->picture.subpic_crop = xcb_generate_id(conn);
     sys->picture.alpha = xcb_generate_id(conn);
     sys->picture.dest = xcb_generate_id(conn);
     sys->gc = xcb_generate_id(conn);


=====================================
src/misc/subpicture.c
=====================================
@@ -362,14 +362,8 @@ unsigned picture_BlendSubpicture(picture_t *dst,
     vlc_vector_foreach(r, &src->regions) {
         assert(r->p_picture);
 
-        video_format_t blend_fmt = r->p_picture->format;
-        blend_fmt.i_x_offset = r->source_offset_x;
-        blend_fmt.i_y_offset = r->source_offset_y;
-        blend_fmt.i_visible_width = r->place.width;
-        blend_fmt.i_visible_height = r->place.height;
-
         if (filter_ConfigureBlend(blend, dst->format.i_width,
-                                  dst->format.i_height,  &blend_fmt)
+                                  dst->format.i_height,  &r->p_picture->format)
          || filter_Blend(blend, dst, r->place.x, r->place.y, r->p_picture, 
r->i_alpha))
             msg_Err(blend, "blending %4.4s to %4.4s failed",
                     (char *)&blend->fmt_in.video.i_chroma,


=====================================
src/video_output/display.c
=====================================
@@ -775,6 +775,7 @@ vout_display_t *vout_display_New(vlc_object_t *parent,
 
         vlc_objres_clear(VLC_OBJECT(vd));
         video_format_Clean(&osys->display_fmt);
+        osys->display.info = (vout_display_info_t){};
     }
 
     msg_Dbg(vd, "no %s modules matched with name %s", "vout display", module);


=====================================
src/video_output/video_output.c
=====================================
@@ -1129,7 +1129,7 @@ static vlc_render_subpicture 
*RenderSPUs(vout_thread_sys_t *sys,
                       subpicture_chromas, spu_frame,
                       sys->display->source,
                       system_now, render_subtitle_date,
-                      ignore_osd, sys->display->info.can_scale_spu);
+                      ignore_osd);
 }
 
 static int PrerenderPicture(vout_thread_sys_t *sys, picture_t *filtered,


=====================================
src/video_output/vout_subpictures.c
=====================================
@@ -866,7 +866,7 @@ spu_SelectSubpictures(spu_t *spu, vlc_tick_t system_now,
 static struct subpicture_region_rendered *SpuRenderRegion(spu_t *spu,
                             spu_area_t *dst_area,
                             const spu_render_entry_t *entry, 
subpicture_region_t *region,
-                            const spu_scale_t scale_size,
+                            const spu_scale_t scale_size, bool apply_scale,
                             const vlc_fourcc_t *chroma_list,
                             const video_format_t *fmt,
                             const spu_area_t *subtitle_area, size_t 
subtitle_area_count,
@@ -876,6 +876,9 @@ static struct subpicture_region_rendered 
*SpuRenderRegion(spu_t *spu,
     subpicture_t *subpic = entry->subpic;
     spu_private_t *sys = spu->p;
 
+    if (scale_size.h == SCALE_UNIT && scale_size.w == SCALE_UNIT)
+        apply_scale = false;
+
     int x_offset;
     int y_offset;
 
@@ -899,7 +902,7 @@ static struct subpicture_region_rendered 
*SpuRenderRegion(spu_t *spu,
      * to ensure that overlap does not occur. */
     int y_margin = 0;
     if (!crop_requested && subpic->b_subtitle)
-        y_margin = spu_invscale_h(sys->margin, scale_size);
+        y_margin = apply_scale ? spu_invscale_h(sys->margin, scale_size) : 
sys->margin;
 
     /* Place the picture
      * We compute the position in the rendered size */
@@ -914,7 +917,7 @@ static struct subpicture_region_rendered 
*SpuRenderRegion(spu_t *spu,
     if (entry->channel_order == VLC_VOUT_ORDER_SECONDARY)
     {
         int secondary_margin =
-            spu_invscale_h(sys->secondary_margin, scale_size);
+            apply_scale ? spu_invscale_h(sys->secondary_margin, scale_size) : 
sys->secondary_margin;
         if (!subpic->b_absolute)
         {
             /* Move the secondary subtitles by the secondary margin before
@@ -935,7 +938,7 @@ static struct subpicture_region_rendered 
*SpuRenderRegion(spu_t *spu,
     *dst_area = spu_area_create(x_offset, y_offset,
                                 region->fmt.i_visible_width,
                                 region->fmt.i_visible_height,
-                                scale_size);
+                                apply_scale ? scale_size : spu_scale_unit());
 
     /* Handle overlapping subtitles when possible */
     if (subpic->b_subtitle && !subpic->b_absolute)
@@ -959,8 +962,8 @@ static struct subpicture_region_rendered 
*SpuRenderRegion(spu_t *spu,
     x_offset = spu_scale_w(restrained.x, restrained.scale);
     y_offset = spu_scale_h(restrained.y, restrained.scale);
 
-    const unsigned dst_width  = spu_scale_w(region->fmt.i_visible_width,  
scale_size);
-    const unsigned dst_height = spu_scale_h(region->fmt.i_visible_height, 
scale_size);
+    const unsigned dst_width  = apply_scale ? 
spu_scale_w(region->fmt.i_visible_width,  scale_size) : 
region->fmt.i_visible_width;
+    const unsigned dst_height = apply_scale ? 
spu_scale_h(region->fmt.i_visible_height, scale_size) : 
region->fmt.i_visible_height;
 
     if (unlikely(dst_width == 0 || dst_height == 0))
         return NULL;
@@ -1025,7 +1028,7 @@ static struct subpicture_region_rendered 
*SpuRenderRegion(spu_t *spu,
     }
 
     /* Scale from rendered size to destination size */
-    if (scale_size.w != SCALE_UNIT || scale_size.h != SCALE_UNIT || 
convert_chroma)
+    if ((apply_scale && (scale_size.w != SCALE_UNIT || scale_size.h != 
SCALE_UNIT)) || convert_chroma)
     {
         /* Destroy the cache if unusable */
         if (region->p_private) {
@@ -1131,10 +1134,10 @@ static struct subpicture_region_rendered 
*SpuRenderRegion(spu_t *spu,
     if (crop_requested) {
         int crop_x, crop_y, crop_width, crop_height;
         if(sys->force_crop){
-            crop_x     = spu_scale_w(sys->crop.x, scale_size);
-            crop_y     = spu_scale_h(sys->crop.y, scale_size);
-            crop_width = spu_scale_w(sys->crop.width,  scale_size);
-            crop_height= spu_scale_h(sys->crop.height, scale_size);
+            crop_x     = apply_scale ? spu_scale_w(sys->crop.x, scale_size) : 
sys->crop.x;
+            crop_y     = apply_scale ? spu_scale_h(sys->crop.y, scale_size) : 
sys->crop.y;
+            crop_width = apply_scale ? spu_scale_w(sys->crop.width,  
scale_size) : sys->crop.width;
+            crop_height= apply_scale ? spu_scale_h(sys->crop.height, 
scale_size) : sys->crop.height;
         }
         else
         {
@@ -1177,20 +1180,22 @@ static struct subpicture_region_rendered 
*SpuRenderRegion(spu_t *spu,
     struct subpicture_region_rendered *dst = calloc(1, sizeof(*dst));
     if (unlikely(dst == NULL))
         return NULL;
-    dst->p_picture = picture_Hold(region_picture);
+    dst->p_picture = picture_Clone(region_picture);
     if (unlikely(dst->p_picture == NULL))
     {
         free(dst);
         return NULL;
     }
-    dst->source_offset_x = region_fmt.i_x_offset;
-    dst->source_offset_y = region_fmt.i_y_offset;
+    assert(region_fmt.i_x_offset + region_fmt.i_visible_width  <= 
dst->p_picture->format.i_width);
+    assert(region_fmt.i_y_offset + region_fmt.i_visible_height <= 
dst->p_picture->format.i_height);
+    dst->p_picture->format.i_x_offset       = region_fmt.i_x_offset;
+    dst->p_picture->format.i_y_offset       = region_fmt.i_y_offset;
+    dst->p_picture->format.i_visible_width  = region_fmt.i_visible_width;
+    dst->p_picture->format.i_visible_height = region_fmt.i_visible_height;
     dst->place.x    = x_offset;
     dst->place.y    = y_offset;
     dst->place.width  = region_fmt.i_visible_width;
     dst->place.height = region_fmt.i_visible_height;
-    dst->zoom_h.den = dst->zoom_h.num = 1;
-    dst->zoom_v.den = dst->zoom_v.num = 1;
     int fade_alpha = 255;
     if (subpic->b_fade) {
         vlc_tick_t fade_start = subpic->i_start + 3 * (subpic->i_stop - 
subpic->i_start) / 4;
@@ -1200,6 +1205,17 @@ static struct subpicture_region_rendered 
*SpuRenderRegion(spu_t *spu,
                                 (subpic->i_stop - fade_start);
     }
     dst->i_alpha   = fade_alpha * subpic->i_alpha * region->i_alpha / (255 * 
255);
+
+    if (!apply_scale && scale_size.h != SCALE_UNIT)
+    {
+        dst->place.x      = spu_scale_w(dst->place.x,     scale_size);
+        dst->place.width  = spu_scale_w(dst->place.width, scale_size);
+    }
+    if (!apply_scale && scale_size.w != SCALE_UNIT)
+    {
+        dst->place.y      = spu_scale_h(dst->place.y,     scale_size);
+        dst->place.height = spu_scale_h(dst->place.height, scale_size);
+    }
     return dst;
 }
 
@@ -1331,12 +1347,9 @@ static vlc_render_subpicture *SpuRenderSubpictures(spu_t 
*spu,
             /* Check scale validity */
             assert(scale.w != 0 && scale.h != 0);
 
-            const bool do_external_scale = external_scale && 
!subpicture_region_IsText( region );
-            spu_scale_t virtual_scale = external_scale ? (spu_scale_t){ 
SCALE_UNIT, SCALE_UNIT } : scale;
-
             /* */
             output_last_ptr = SpuRenderRegion(spu, &area,
-                            entry, rendered_region, virtual_scale,
+                            entry, rendered_region, scale, !external_scale,
                             chroma_list, fmt_dst,
                             subtitle_area, subtitle_area_count,
                             subpic->b_subtitle ? render_subtitle_date : 
system_now);
@@ -1345,20 +1358,6 @@ static vlc_render_subpicture *SpuRenderSubpictures(spu_t 
*spu,
             if (unlikely(output_last_ptr == NULL))
                 continue;
 
-            if (do_external_scale)
-            {
-                if (scale.h != SCALE_UNIT)
-                {
-                    output_last_ptr->zoom_v.num = scale.h;
-                    output_last_ptr->zoom_v.den = SCALE_UNIT;
-                }
-                if (scale.w != SCALE_UNIT)
-                {
-                    output_last_ptr->zoom_h.num = scale.w;
-                    output_last_ptr->zoom_h.den = SCALE_UNIT;
-                }
-            }
-
             vlc_vector_push(&output->regions, output_last_ptr);
 
             if (subpic->b_subtitle) {
@@ -2040,10 +2039,10 @@ vlc_render_subpicture *spu_Render(spu_t *spu,
                          const video_format_t *fmt_src,
                          vlc_tick_t system_now,
                          vlc_tick_t render_subtitle_date,
-                         bool ignore_osd,
-                         bool external_scale)
+                         bool ignore_osd)
 {
     spu_private_t *sys = spu->p;
+    const bool external_scale = chroma_list != NULL;
 
     /* Update sub-source chain */
     vlc_mutex_lock(&sys->lock);


=====================================
test/modules/video_output/opengl/sub_renderer.c
=====================================
@@ -184,8 +184,6 @@ static void test_opengl_offscreen(
     p_region->place.width  = picture->format.i_visible_width;
     p_region->place.height = picture->format.i_visible_height;
     p_region->i_alpha = 255;
-    p_region->zoom_h.num = p_region->zoom_h.den = 1;
-    p_region->zoom_v.num = p_region->zoom_h.den = 1;
     vlc_vector_push( &subpicture->regions, p_region );
 
     ret = vlc_gl_sub_renderer_Prepare(sr, subpicture);



View it on GitLab: 
https://code.videolan.org/videolan/vlc/-/compare/dadd1bcccd715fad104643ac2e8efbca5d96cef2...36f6d1c59bf73038ae36ce56fa47a06cbf100fbd

-- 
View it on GitLab: 
https://code.videolan.org/videolan/vlc/-/compare/dadd1bcccd715fad104643ac2e8efbca5d96cef2...36f6d1c59bf73038ae36ce56fa47a06cbf100fbd
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