[vlc-commits] [Git][videolan/vlc][master] 5 commits: vout_subpictures: pass the placed video to the SPU renderer
Steve Lhomme (@robUx4)
gitlab at videolan.org
Wed Mar 27 12:13:10 UTC 2024
Steve Lhomme pushed to branch master at VideoLAN / VLC
Commits:
07769165 by Steve Lhomme at 2024-03-27T11:43:23+00:00
vout_subpictures: pass the placed video to the SPU renderer
In case the absolute SPUs need shifting inside the video.
- - - - -
301cc264 by Steve Lhomme at 2024-03-27T11:43:23+00:00
vout_subpictures: place rendered regions in display coordinates
Only for display modules that render regions separately.
- - - - -
83f01e93 by Steve Lhomme at 2024-03-27T11:43:23+00:00
VLCSampleBufferDisplay: remove write-only sys->place
- - - - -
9c35043b by Steve Lhomme at 2024-03-27T11:43:23+00:00
android/display: remove write-only sub->place
- - - - -
26b590f1 by Steve Lhomme at 2024-03-27T11:43:23+00:00
direct3d9: clear the scene when the cached subpicture regions change
When they are displayed outside of the black bars they are not cleaned properly.
- - - - -
17 changed files:
- include/vlc_spu.h
- include/vlc_subpicture.h
- include/vlc_vout_display.h
- modules/stream_out/transcode/video.c
- modules/video_output/android/display.c
- modules/video_output/apple/VLCSampleBufferDisplay.m
- modules/video_output/caopengllayer.m
- modules/video_output/libplacebo/display.c
- modules/video_output/macosx.m
- modules/video_output/opengl/display.c
- modules/video_output/opengl/sub_renderer.c
- modules/video_output/win32/direct3d11.cpp
- modules/video_output/win32/direct3d9.c
- modules/video_output/win32/glwin32.c
- modules/video_output/xcb/render.c
- src/video_output/video_output.c
- src/video_output/vout_subpictures.c
Changes:
=====================================
include/vlc_spu.h
=====================================
@@ -32,6 +32,8 @@
extern "C" {
#endif
+struct vout_display_place_t;
+
/**
* \defgroup spu Sub-picture channels
* \ingroup video_output
@@ -72,6 +74,7 @@ VLC_API void spu_PutSubpicture( spu_t *, subpicture_t * );
* \param p_chroma_list is a list of supported chroma for the output (can be NULL)
* \param p_fmt_dst is the format of the picture on which the return subpicture will be rendered.
* \param p_fmt_src is the format of the original(source) video.
+ * \param video_position position of the video inside the display or NULL to fit in p_fmt_dst
* \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
@@ -80,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,
+ const struct vout_display_place_t *video_position,
vlc_tick_t system_now, vlc_tick_t pts,
bool ignore_osd );
=====================================
include/vlc_subpicture.h
=====================================
@@ -208,7 +208,7 @@ typedef struct subpicture_private_t subpicture_private_t;
struct subpicture_region_rendered
{
picture_t *p_picture; /**< picture comprising this region */
- vout_display_place_t place; // position of region, relative to alignment
+ vout_display_place_t place; /**< visible area in display coordinates */
int i_alpha; /**< transparency */
};
=====================================
include/vlc_vout_display.h
=====================================
@@ -497,7 +497,7 @@ void vout_display_GetDefaultDisplaySize(unsigned *width, unsigned *height,
*
* This structure stores the result of a vout_display_PlacePicture() call.
*/
-typedef struct {
+typedef struct vout_display_place_t {
int x; /*< Relative pixel offset from the display left edge */
int y; /*< Relative pixel offset from the display top edge */
unsigned width; /*< Picture pixel width */
=====================================
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, vlc_tick_now(), p_pic->date,
+ &outfmt, NULL, vlc_tick_now(), p_pic->date,
false );
/* Overlay subpicture */
=====================================
modules/video_output/android/display.c
=====================================
@@ -47,7 +47,6 @@ struct subpicture
struct vlc_gl_api api;
struct vlc_gl_interop *interop;
struct vlc_gl_sub_renderer *renderer;
- vout_display_place_t place;
bool place_changed;
bool is_dirty;
bool clear;
@@ -90,10 +89,6 @@ static int subpicture_Control(vout_display_t *vd, int query)
case VOUT_DISPLAY_CHANGE_DISPLAY_FILLED:
case VOUT_DISPLAY_CHANGE_ZOOM:
{
- struct vout_display_placement dp = vd->cfg->display;
-
- FlipVerticalAlign(&dp);
- vout_display_PlacePicture(&sub->place, vd->source, &dp);
sub->place_changed = true;
return VLC_SUCCESS;
}
@@ -201,8 +196,8 @@ static void subpicture_Prepare(vout_display_t *vd, const vlc_render_subpicture *
if (sub->place_changed)
{
- sub->api.vt.Viewport(sub->place.x, sub->place.y,
- sub->place.width, sub->place.height);
+ sub->api.vt.Viewport(0, 0,
+ vd->cfg->display.width, vd->cfg->display.height);
sub->place_changed = false;
}
@@ -318,11 +313,8 @@ static int subpicture_OpenDisplay(vout_display_t *vd)
goto disable_win;
/* Initialize and configure subpicture renderer/interop */
- struct vout_display_placement dp = vd->cfg->display;
- FlipVerticalAlign(&dp);
- vout_display_PlacePicture(&sub->place, vd->source, &dp);
sub->place_changed = true;
- vlc_gl_Resize(sub->gl, dp.width, dp.height);
+ vlc_gl_Resize(sub->gl, vd->cfg->display.width, vd->cfg->display.height);
if (vlc_gl_MakeCurrent(sub->gl))
goto delete_gl;
=====================================
modules/video_output/apple/VLCSampleBufferDisplay.m
=====================================
@@ -296,7 +296,6 @@ shouldInheritContentsScale:(CGFloat)newScale
@interface VLCSampleBufferDisplay: NSObject {
@public
- vout_display_place_t place;
filter_t *converter;
}
@property (nonatomic) id<VLCOpenGLVideoViewEmbedding> container;
@@ -403,15 +402,15 @@ static void RenderPicture(vout_display_t *vd, picture_t *pic, vlc_tick_t date) {
CFRelease(sampleBuffer);
}
-static CGRect RegionBackingFrame(VLCSampleBufferDisplay* sys,
+static CGRect RegionBackingFrame(unsigned display_height,
const struct subpicture_region_rendered *r)
{
// Invert y coords for CoreGraphics
- const float y = sys->place.height - r->place.height - r->place.y;
+ const int y = display_height - r->place.height - r->place.y;
return CGRectMake(
- r->place.x + sys->place.x,
- y + sys->place.y,
+ r->place.x,
+ y,
r->place.width,
r->place.height
);
@@ -451,7 +450,7 @@ static void UpdateSubpictureRegions(vout_display_t *vd,
region.subpicture = sys.subpicture;
region.image = image;
- region.backingFrame = RegionBackingFrame(sys, r);
+ region.backingFrame = RegionBackingFrame(vd->cfg->display.height, r);
[regions addObject:region];
CGDataProviderRelease(provider);
CFRelease(data);
@@ -498,7 +497,7 @@ static bool IsSubpictureDrawNeeded(vout_display_t *vd, const vlc_render_subpictu
VLCSampleBufferSubpictureRegion *region =
sys.subpicture.regions[i++];
- CGRect newRegion = RegionBackingFrame(sys, r);
+ CGRect newRegion = RegionBackingFrame(vd->cfg->display.height, r);
if ( !CGRectEqualToRect(region.backingFrame, newRegion) )
{
@@ -569,8 +568,6 @@ static void PrepareDisplay (vout_display_t *vd) {
spuView = nil;
}
- vout_display_PlacePicture(&sys->place, vd->source, &vd->cfg->display);
-
sys.displayView = displayView;
sys.spuView = spuView;
@synchronized(sys.displayLayer) {
@@ -606,11 +603,7 @@ static int Control (vout_display_t *vd, int query)
case VOUT_DISPLAY_CHANGE_ZOOM:
case VOUT_DISPLAY_CHANGE_SOURCE_ASPECT:
case VOUT_DISPLAY_CHANGE_SOURCE_CROP:
- {
- vout_display_PlacePicture(
- &sys->place, vd->source, &vd->cfg->display);
break;
- }
default:
msg_Err (vd, "Unhandled request %d", query);
return VLC_EGENERIC;
=====================================
modules/video_output/caopengllayer.m
=====================================
@@ -792,7 +792,7 @@ shouldInheritContentsScale:(CGFloat)newScale
// Ensure viewport and aspect ratio is correct
vout_display_opengl_Viewport(sys->vgl, sys->place.x, sys->place.y,
sys->place.width, sys->place.height);
- vout_display_opengl_SetOutputSize(sys->vgl, sys->place.width, sys->place.height);
+ vout_display_opengl_SetOutputSize(sys->vgl, sys->cfg.display.width, sys->cfg.display.height);
vout_display_opengl_Display(sys->vgl);
vlc_gl_ReleaseCurrent(sys->gl);
=====================================
modules/video_output/libplacebo/display.c
=====================================
@@ -414,10 +414,10 @@ static void PictureRender(vout_display_t *vd, picture_t *pic,
.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 ),
- .y1 = place.y + (r->place.y + r->place.height) * ysign,
+ .x0 = r->place.x,
+ .y0 = r->place.y * ysign,
+ .x1 = (r->place.x + r->place.width ),
+ .y1 = (r->place.y + r->place.height) * ysign,
},
};
i++;
@@ -429,13 +429,13 @@ static void PictureRender(vout_display_t *vd, picture_t *pic,
}
// If we don't cover the entire output, clear it first
- struct pl_rect2d full = {0, 0, frame.fbo->params.w, frame.fbo->params.h };
- struct pl_rect2d norm = {place.x, place.y, place.x + place.width, place.y + place.height };
- pl_rect2d_normalize(&norm);
- if (!pl_rect2d_eq(norm, full)) {
+ // struct pl_rect2d full = {0, 0, frame.fbo->params.w, frame.fbo->params.h };
+ // struct pl_rect2d norm = {place.x, place.y, place.x + place.width, place.y + place.height };
+ // pl_rect2d_normalize(&norm);
+ // if (!pl_rect2d_eq(norm, full)) {
// TODO: make background color configurable?
pl_tex_clear(gpu, frame.fbo, (float[4]){ 0.0, 0.0, 0.0, 0.0 });
- }
+ // }
switch (sys->lut_mode) {
case LUT_DECODING:
=====================================
modules/video_output/macosx.m
=====================================
@@ -565,7 +565,7 @@ static void OpenglSwap (vlc_gl_t *gl)
vout_display_opengl_Viewport(sys->vgl, sys->place.x, sys->place.y,
sys->place.width, sys->place.height);
- vout_display_opengl_SetOutputSize(sys->vgl, sys->place.width, sys->place.height);
+ vout_display_opengl_SetOutputSize(sys->vgl, sys->cfg.display.width, sys->cfg.display.height);
if (sys->has_first_frame)
vout_display_opengl_Display (sys->vgl);
=====================================
modules/video_output/opengl/display.c
=====================================
@@ -302,8 +302,8 @@ static void PictureRender (vout_display_t *vd, picture_t *pic,
sys->vt.Flush();
if (sys->place_changed)
{
- vout_display_opengl_SetOutputSize(sys->vgl, sys->place.width,
- sys->place.height);
+ vout_display_opengl_SetOutputSize(sys->vgl, vd->cfg->display.width,
+ vd->cfg->display.height);
vout_display_opengl_Viewport(sys->vgl, sys->place.x, sys->place.y,
sys->place.width, sys->place.height);
sys->place_changed = false;
=====================================
modules/video_output/opengl/sub_renderer.c
=====================================
@@ -350,6 +350,8 @@ vlc_gl_sub_renderer_Draw(struct vlc_gl_sub_renderer *sr)
vt->Enable(GL_BLEND);
vt->BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ vt->Viewport(0, 0, sr->output_width, sr->output_height);
+
/* We need two buffer objects for each region: for vertex and texture coordinates. */
if (2 * sr->region_count > sr->buffer_object_count) {
if (sr->buffer_object_count > 0)
=====================================
modules/video_output/win32/direct3d11.cpp
=====================================
@@ -1651,12 +1651,6 @@ static int Direct3D11MapSubpicture(vout_display_t *vd, int *subpicture_region_co
spuViewport.right = r->place.x + r->place.width;
spuViewport.bottom = r->place.y + r->place.height;
- /* move the SPU inside the video area */
- spuViewport.left += sys->area.place.x;
- spuViewport.right += sys->area.place.x;
- spuViewport.top += sys->area.place.y;
- spuViewport.bottom += sys->area.place.y;
-
quad->UpdateViewport( &spuViewport, sys->display.pixelFormat );
D3D11_UpdateQuadOpacity(vd, sys->d3d_dev, quad, r->i_alpha / 255.0f );
=====================================
modules/video_output/win32/direct3d9.c
=====================================
@@ -890,6 +890,7 @@ static void Direct3D9ImportSubpicture(vout_display_t *vd,
cache->height == r->p_picture->format.i_height) {
*d3dr = *cache;
memset(cache, 0, sizeof(*cache));
+ sys->clear_scene = true;
break;
}
}
@@ -960,11 +961,6 @@ static void Direct3D9ImportSubpicture(vout_display_t *vd,
rect_in_display.top = r->place.y;
rect_in_display.bottom = r->place.y + r->place.height;
- rect_in_display.left += sys->area.place.x;
- rect_in_display.right += sys->area.place.x;
- rect_in_display.top += sys->area.place.y;
- rect_in_display.bottom += sys->area.place.y;
-
RECT texture_rect;
texture_rect.left = 0;
texture_rect.right = r->p_picture->format.i_width;
@@ -1070,7 +1066,7 @@ static void Direct3D9RenderScene(vout_display_t *vd,
if (sys->startEndRenderingCb && !sys->startEndRenderingCb( sys->outside_opaque, true ))
return;
- if (sys->clear_scene) {
+ if (sys->clear_scene || sys->d3dregion_count != subpicture_count) {
/* Clear the backbuffer and the zbuffer */
hr = IDirect3DDevice9_Clear(d3ddev, 0, NULL, D3DCLEAR_TARGET,
D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
=====================================
modules/video_output/win32/glwin32.c
=====================================
@@ -256,11 +256,9 @@ static void Prepare(vout_display_t *vd, picture_t *picture,
vout_display_PlacePicture(&place, vd->source, &place_cfg);
- const int width = place.width;
- const int height = place.height;
- vlc_gl_Resize (sys->gl, width, height);
- vout_display_opengl_SetOutputSize(sys->vgl, width, height);
- vout_display_opengl_Viewport(sys->vgl, place.x, place.y, width, height);
+ vlc_gl_Resize (sys->gl, place.width, place.height);
+ vout_display_opengl_SetOutputSize(sys->vgl, vd->cfg->display.width, vd->cfg->display.height);
+ vout_display_opengl_Viewport(sys->vgl, place.x, place.y, place.width, place.height);
sys->area.place_changed = false;
}
vout_display_opengl_Prepare (sys->vgl, picture, subpicture);
=====================================
modules/video_output/xcb/render.c
=====================================
@@ -118,13 +118,12 @@ static void RenderRegion(vout_display_t *vd, const vlc_render_subpicture *subpic
{
vout_display_sys_t *sys = vd->sys;
xcb_connection_t *conn = sys->conn;
- const vout_display_place_t *place = &sys->place;
picture_t *pic = reg->p_picture;
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,
+ 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);
@@ -175,8 +174,8 @@ static void RenderRegion(vout_display_t *vd, const vlc_render_subpicture *subpic
/* 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;
- int_fast16_t dy = place->y + reg->place.y;
+ int_fast16_t dx = reg->place.x;
+ int_fast16_t dy = reg->place.y;
uint_fast16_t dw = reg->place.width;
uint_fast16_t dh = reg->place.height;
@@ -200,7 +199,7 @@ static void RenderRegion(vout_display_t *vd, const vlc_render_subpicture *subpic
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_crop, sys->picture.alpha,
=====================================
src/video_output/video_output.c
=====================================
@@ -1121,13 +1121,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,
+ 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,
+ sys->display->source, video_position,
system_now, render_subtitle_date,
ignore_osd);
}
@@ -1172,9 +1173,11 @@ static int PrerenderPicture(vout_thread_sys_t *sys, picture_t *filtered,
// otherwise it's done in the display chroma
const bool blending_before_converter = vd->source->orientation == ORIENT_NORMAL;
+ vout_display_place_t place;
+ const vout_display_place_t *video_place = NULL; // default to fit the video
video_format_t fmt_spu;
if (vd_does_blending) {
- vout_display_place_t place;
+ video_place = &place;
vout_display_PlacePicture(&place, vd->source, &vd->cfg->display);
fmt_spu = *vd->source;
@@ -1220,7 +1223,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);
+ do_snapshot, video_place);
if (subpic) {
picture_t *blent = picture_pool_Get(sys->private_pool);
if (blent) {
@@ -1270,7 +1273,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);
+ do_snapshot, video_place);
if (subpic)
{
picture_BlendSubpicture(todisplay, sys->spu_blend, subpic);
@@ -1282,7 +1285,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);
+ false, video_place);
else
*out_subpic = NULL;
=====================================
src/video_output/vout_subpictures.c
=====================================
@@ -37,6 +37,7 @@
#include <vlc_filter.h>
#include <vlc_spu.h>
#include <vlc_vector.h>
+#include <vlc_vout_display.h>
#include "../libvlc.h"
#include "vout_internal.h"
@@ -1243,6 +1244,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,
+ const vout_display_place_t *video_position,
vlc_tick_t system_now,
vlc_tick_t render_subtitle_date,
bool external_scale)
@@ -1337,10 +1339,13 @@ static vlc_render_subpicture *SpuRenderSubpictures(spu_t *spu,
* FIXME The current scaling ensure that the heights match, the width being
* cropped.
*/
- spu_scale_t scale = spu_scale_createq((uint64_t)fmt_dst->i_visible_height * fmt_dst->i_sar_den * region_sar.num,
- (uint64_t)i_original_height * fmt_dst->i_sar_num * region_sar.den,
- fmt_dst->i_visible_height,
- i_original_height);
+ // 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,
+ (uint64_t)i_original_height * fmt_dst->i_sar_num * region_sar.den,
+ video_position->height,
+ i_original_height);
/* Check scale validity */
assert(scale.w != 0 && scale.h != 0);
@@ -1356,6 +1361,10 @@ 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;
+
vlc_vector_push(&output->regions, output_last_ptr);
if (subpic->b_subtitle) {
@@ -2036,6 +2045,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,
+ const vout_display_place_t *video_position,
vlc_tick_t system_now,
vlc_tick_t render_subtitle_date,
bool ignore_osd)
@@ -2096,6 +2106,16 @@ vlc_render_subpicture *spu_Render(spu_t *spu,
chroma_list = vlc_fourcc_IsYUV(fmt_dst->i_chroma) ? chroma_list_default_yuv
: chroma_list_default_rgb;
+ vout_display_place_t place;
+ if (video_position == NULL)
+ {
+ video_position = &place;
+ place.x = 0;
+ place.y = 0;
+ place.width = fmt_dst->i_visible_width;
+ place.height = fmt_dst->i_visible_height;
+ }
+
/* wake up prerenderer, we have some video size and chroma */
spu_PrerenderWake(sys, fmt_dst, fmt_src, chroma_list);
@@ -2139,6 +2159,7 @@ vlc_render_subpicture *spu_Render(spu_t *spu,
chroma_list,
fmt_dst,
fmt_src,
+ video_position,
system_now,
render_subtitle_date,
external_scale);
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/21f9ba48a681ff7fd4e3c655785c5c5c05dad7dd...26b590f174b21b02ddd11b1313c507ad1cdebb47
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/21f9ba48a681ff7fd4e3c655785c5c5c05dad7dd...26b590f174b21b02ddd11b1313c507ad1cdebb47
You're receiving this email because of your account on code.videolan.org.
VideoLAN code repository instance
More information about the vlc-commits
mailing list