Incorrect SPU scaling when physical size != visible size
On a video with padding (physical size != visible size), SPU are wrongly scaled due to confusion between the visible and physical size. The issue also exists in VLC3.
For example, download Big Buck Bunny 720p (source):
-
i_visible_width
: 1280 -
i_visible_height
: 720 -
i_width
: 1280 -
i_height
: 738 (!= 720)
Create a SRT file with the same name in the same folder (Big_Buck_Bunny_720_10s_1MB.srt
):
1
00:00:06,000 --> 00:00:07,000
Here is a subtitle
2
00:00:08,000 --> 00:00:09,000
Big Buck Bunny
(The first subtitle is not before 6 seconds to avoid confusion with the video title SPU on start)
And some logs:
diff --git a/src/video_output/vout_subpictures.c b/src/video_output/vout_subpictures.c
index 312ccd3492..c0a285d682 100644
--- a/src/video_output/vout_subpictures.c
+++ b/src/video_output/vout_subpictures.c
@@ -967,6 +967,12 @@ static void SpuRenderRegion(spu_t *spu,
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);
+ fprintf(stderr, "scale w=%u/10000 h=%u/10000: %ux%u -> %ux%u\n",
+ scale_size.w, scale_size.h,
+ region->fmt.i_visible_width,
+ region->fmt.i_visible_height,
+ dst_width, dst_height);
+
/* Destroy the cache if unusable */
if (region->p_private) {
subpicture_region_private_t *private = region->p_private;
@@ -1038,6 +1044,11 @@ static void SpuRenderRegion(spu_t *spu,
scale->fmt_out.video.i_visible_height =
spu_scale_h(region->fmt.i_visible_height, scale_size);
+ fprintf(stderr, "swscale %ux%u -> %ux%u\n",
+ scale->fmt_in.video.i_visible_width,
+ scale->fmt_in.video.i_visible_height,
+ scale->fmt_out.video.i_visible_width,
+ scale->fmt_out.video.i_visible_height);
picture = scale->ops->filter_video(scale, picture);
assert(picture == NULL || !picture_HasChainedPics(picture)); // no chaining
if (!picture)
@@ -1209,6 +1220,8 @@ static subpicture_t *SpuRenderSubpictures(spu_t *spu,
const int i_original_width = subpic->i_original_picture_width;
const int i_original_height = subpic->i_original_picture_height;
+ fprintf(stderr, "original wxh = %ux%u\n", i_original_width, i_original_height);
+
/* Render all regions
* We always transform non absolute subtitle into absolute one on the
* first rendering to allow good subtitle overlap support.
@@ -1971,6 +1984,10 @@ subpicture_t *spu_Render(spu_t *spu,
spu_render_entry_t *entry = &subpicture_array[i];
subpicture_t *subpic = entry->subpic;
+ const int i_original_width = subpic->i_original_picture_width;
+ const int i_original_height = subpic->i_original_picture_height;
+ fprintf(stderr, "[subpic] %ux%u\n", i_original_width, i_original_height);
+
spu_PrerenderSync(sys, entry->subpic);
/* Update time to clock */
Here is the output:
[subpic] 1280x720
original wxh = 1280x720
[subpic] 1280x720
original wxh = 1280x720
… repeated many time (it's the video title SPU on start)
[subpic] 1280x738
original wxh = 1280x738
scale w=9756/10000 h=9756/10000: 390x41 -> 380x39
swscale 390x41 -> 380x39
[subpic] 1280x738
original wxh = 1280x738
scale w=9756/10000 h=9756/10000: 390x41 -> 380x39
… repeated many times
[subpic] 1280x738
original wxh = 1280x738
scale w=9756/10000 h=9756/10000: 363x51 -> 354x49
swscale 363x51 -> 354x49
[subpic] 1280x738
original wxh = 1280x738
scale w=9756/10000 h=9756/10000: 363x51 -> 354x49
… repeated many times
Edited by Romain Vimont