mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-25 00:28:21 +00:00
assrender: Use the window size from downstream
This allows rendering the overlay at a resolution matching the video resolution. https://bugzilla.gnome.org/show_bug.cgi?id=753824
This commit is contained in:
parent
f021d32bef
commit
ecdc7bb37d
2 changed files with 53 additions and 5 deletions
|
@ -780,6 +780,24 @@ gst_ass_render_can_handle_caps (GstCaps * incaps)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_ass_render_update_render_size (GstAssRender * render)
|
||||||
|
{
|
||||||
|
gdouble video_aspect = (gdouble) render->info.width /
|
||||||
|
(gdouble) render->info.height;
|
||||||
|
gdouble window_aspect = (gdouble) render->window_width /
|
||||||
|
(gdouble) render->window_height;
|
||||||
|
|
||||||
|
/* render at the window size, with the video aspect ratio */
|
||||||
|
if (video_aspect >= window_aspect) {
|
||||||
|
render->ass_frame_width = render->window_width;
|
||||||
|
render->ass_frame_height = render->window_width / video_aspect;
|
||||||
|
} else {
|
||||||
|
render->ass_frame_width = render->window_height * video_aspect;
|
||||||
|
render->ass_frame_height = render->window_height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_ass_render_negotiate (GstAssRender * render, GstCaps * caps)
|
gst_ass_render_negotiate (GstAssRender * render, GstCaps * caps)
|
||||||
{
|
{
|
||||||
|
@ -788,6 +806,7 @@ gst_ass_render_negotiate (GstAssRender * render, GstCaps * caps)
|
||||||
gboolean alloc_has_meta = FALSE;
|
gboolean alloc_has_meta = FALSE;
|
||||||
gboolean attach = FALSE;
|
gboolean attach = FALSE;
|
||||||
gboolean ret = TRUE;
|
gboolean ret = TRUE;
|
||||||
|
guint width, height;
|
||||||
GstCapsFeatures *f;
|
GstCapsFeatures *f;
|
||||||
GstCaps *overlay_caps;
|
GstCaps *overlay_caps;
|
||||||
GstQuery *query;
|
GstQuery *query;
|
||||||
|
@ -815,6 +834,10 @@ gst_ass_render_negotiate (GstAssRender * render, GstCaps * caps)
|
||||||
GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION);
|
GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Initialize dimensions */
|
||||||
|
width = render->info.width;
|
||||||
|
height = render->info.height;
|
||||||
|
|
||||||
if (upstream_has_meta) {
|
if (upstream_has_meta) {
|
||||||
overlay_caps = gst_caps_ref (caps);
|
overlay_caps = gst_caps_ref (caps);
|
||||||
} else {
|
} else {
|
||||||
|
@ -862,9 +885,27 @@ gst_ass_render_negotiate (GstAssRender * render, GstCaps * caps)
|
||||||
|
|
||||||
GST_DEBUG ("sink alloc has overlay meta %d", alloc_has_meta);
|
GST_DEBUG ("sink alloc has overlay meta %d", alloc_has_meta);
|
||||||
|
|
||||||
|
if (alloc_has_meta) {
|
||||||
|
const GstStructure *params;
|
||||||
|
|
||||||
|
gst_query_parse_nth_allocation_meta (query, alloc_index, ¶ms);
|
||||||
|
if (params) {
|
||||||
|
if (gst_structure_get (params, "width", G_TYPE_UINT, &width,
|
||||||
|
"height", G_TYPE_UINT, &height, NULL)) {
|
||||||
|
GST_DEBUG ("received window size: %dx%d", width, height);
|
||||||
|
g_assert (width != 0 && height != 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
gst_query_unref (query);
|
gst_query_unref (query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Update render size if needed */
|
||||||
|
render->window_width = width;
|
||||||
|
render->window_height = height;
|
||||||
|
gst_ass_render_update_render_size (render);
|
||||||
|
|
||||||
/* For backward compatbility, we will prefer bliting if downstream
|
/* For backward compatbility, we will prefer bliting if downstream
|
||||||
* allocation does not support the meta. In other case we will prefer
|
* allocation does not support the meta. In other case we will prefer
|
||||||
* attaching, and will fail the negotiation in the unlikely case we are
|
* attaching, and will fail the negotiation in the unlikely case we are
|
||||||
|
@ -900,7 +941,7 @@ gst_ass_render_negotiate (GstAssRender * render, GstCaps * caps)
|
||||||
} else {
|
} else {
|
||||||
g_mutex_lock (&render->ass_mutex);
|
g_mutex_lock (&render->ass_mutex);
|
||||||
ass_set_frame_size (render->ass_renderer,
|
ass_set_frame_size (render->ass_renderer,
|
||||||
render->info.width, render->info.height);
|
render->ass_frame_width, render->ass_frame_height);
|
||||||
ass_set_storage_size (render->ass_renderer,
|
ass_set_storage_size (render->ass_renderer,
|
||||||
render->info.width, render->info.height);
|
render->info.width, render->info.height);
|
||||||
ass_set_pixel_aspect (render->ass_renderer,
|
ass_set_pixel_aspect (render->ass_renderer,
|
||||||
|
@ -1054,6 +1095,7 @@ gst_ass_render_composite_overlay (GstAssRender * render, ASS_Image * images)
|
||||||
gint max_x, max_y;
|
gint max_x, max_y;
|
||||||
gint width, height;
|
gint width, height;
|
||||||
gint stride;
|
gint stride;
|
||||||
|
gdouble hscale, vscale;
|
||||||
gpointer data;
|
gpointer data;
|
||||||
|
|
||||||
min_x = G_MAXINT;
|
min_x = G_MAXINT;
|
||||||
|
@ -1073,8 +1115,8 @@ gst_ass_render_composite_overlay (GstAssRender * render, ASS_Image * images)
|
||||||
max_y = image->dst_y + image->h;
|
max_y = image->dst_y + image->h;
|
||||||
}
|
}
|
||||||
|
|
||||||
width = MIN (max_x - min_x, render->info.width);
|
width = MIN (max_x - min_x, render->ass_frame_width);
|
||||||
height = MIN (max_y - min_y, render->info.height);
|
height = MIN (max_y - min_y, render->ass_frame_height);
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (render, "render overlay rectangle %dx%d%+d%+d",
|
GST_DEBUG_OBJECT (render, "render overlay rectangle %dx%d%+d%+d",
|
||||||
width, height, min_x, min_y);
|
width, height, min_x, min_y);
|
||||||
|
@ -1098,8 +1140,12 @@ gst_ass_render_composite_overlay (GstAssRender * render, ASS_Image * images)
|
||||||
-min_x, -min_y);
|
-min_x, -min_y);
|
||||||
gst_video_meta_unmap (vmeta, 0, &map);
|
gst_video_meta_unmap (vmeta, 0, &map);
|
||||||
|
|
||||||
rectangle = gst_video_overlay_rectangle_new_raw (buffer, min_x, min_y,
|
hscale = (gdouble) render->info.width / (gdouble) render->ass_frame_width;
|
||||||
width, height, GST_VIDEO_OVERLAY_FORMAT_FLAG_PREMULTIPLIED_ALPHA);
|
vscale = (gdouble) render->info.height / (gdouble) render->ass_frame_height;
|
||||||
|
|
||||||
|
rectangle = gst_video_overlay_rectangle_new_raw (buffer,
|
||||||
|
hscale * min_x, vscale * min_y, hscale * width, vscale * height,
|
||||||
|
GST_VIDEO_OVERLAY_FORMAT_FLAG_PREMULTIPLIED_ALPHA);
|
||||||
|
|
||||||
gst_buffer_unref (buffer);
|
gst_buffer_unref (buffer);
|
||||||
|
|
||||||
|
|
|
@ -76,12 +76,14 @@ struct _GstAssRender
|
||||||
ASS_Library *ass_library;
|
ASS_Library *ass_library;
|
||||||
ASS_Renderer *ass_renderer;
|
ASS_Renderer *ass_renderer;
|
||||||
ASS_Track *ass_track;
|
ASS_Track *ass_track;
|
||||||
|
gint ass_frame_width, ass_frame_height;
|
||||||
|
|
||||||
gboolean renderer_init_ok, track_init_ok;
|
gboolean renderer_init_ok, track_init_ok;
|
||||||
gboolean need_process;
|
gboolean need_process;
|
||||||
|
|
||||||
/* overlay stuff */
|
/* overlay stuff */
|
||||||
GstVideoOverlayComposition *composition;
|
GstVideoOverlayComposition *composition;
|
||||||
|
guint window_width, window_height;
|
||||||
gboolean attach_compo_to_buffer;
|
gboolean attach_compo_to_buffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue