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:
Arnaud Vrac 2015-08-19 17:18:31 +02:00 committed by Sebastian Dröge
parent f021d32bef
commit ecdc7bb37d
2 changed files with 53 additions and 5 deletions

View file

@ -780,6 +780,24 @@ gst_ass_render_can_handle_caps (GstCaps * incaps)
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
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 attach = FALSE;
gboolean ret = TRUE;
guint width, height;
GstCapsFeatures *f;
GstCaps *overlay_caps;
GstQuery *query;
@ -815,6 +834,10 @@ gst_ass_render_negotiate (GstAssRender * render, GstCaps * caps)
GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION);
}
/* Initialize dimensions */
width = render->info.width;
height = render->info.height;
if (upstream_has_meta) {
overlay_caps = gst_caps_ref (caps);
} else {
@ -862,9 +885,27 @@ gst_ass_render_negotiate (GstAssRender * render, GstCaps * caps)
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, &params);
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);
}
/* 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
* allocation does not support the meta. In other case we will prefer
* 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 {
g_mutex_lock (&render->ass_mutex);
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,
render->info.width, render->info.height);
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 width, height;
gint stride;
gdouble hscale, vscale;
gpointer data;
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;
}
width = MIN (max_x - min_x, render->info.width);
height = MIN (max_y - min_y, render->info.height);
width = MIN (max_x - min_x, render->ass_frame_width);
height = MIN (max_y - min_y, render->ass_frame_height);
GST_DEBUG_OBJECT (render, "render overlay rectangle %dx%d%+d%+d",
width, height, min_x, min_y);
@ -1098,8 +1140,12 @@ gst_ass_render_composite_overlay (GstAssRender * render, ASS_Image * images)
-min_x, -min_y);
gst_video_meta_unmap (vmeta, 0, &map);
rectangle = gst_video_overlay_rectangle_new_raw (buffer, min_x, min_y,
width, height, GST_VIDEO_OVERLAY_FORMAT_FLAG_PREMULTIPLIED_ALPHA);
hscale = (gdouble) render->info.width / (gdouble) render->ass_frame_width;
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);

View file

@ -76,12 +76,14 @@ struct _GstAssRender
ASS_Library *ass_library;
ASS_Renderer *ass_renderer;
ASS_Track *ass_track;
gint ass_frame_width, ass_frame_height;
gboolean renderer_init_ok, track_init_ok;
gboolean need_process;
/* overlay stuff */
GstVideoOverlayComposition *composition;
guint window_width, window_height;
gboolean attach_compo_to_buffer;
};