mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-03-28 11:55:39 +00:00
Merge branch 'master' of ssh://uraeus@git.freedesktop.org/git/gstreamer/gst-plugins-bad
This commit is contained in:
commit
f5a00b5cb6
4 changed files with 117 additions and 41 deletions
|
@ -76,6 +76,7 @@ struct _FPSDisplaySinkPrivate
|
|||
GstElement *text_overlay;
|
||||
GstElement *video_sink;
|
||||
GstQuery *query;
|
||||
GstPad *ghost_pad;
|
||||
|
||||
/* statistics */
|
||||
guint64 frames_rendered, last_frames_rendered;
|
||||
|
@ -122,12 +123,14 @@ fps_display_sink_class_init (FPSDisplaySinkClass * klass)
|
|||
|
||||
g_object_class_install_property (gobject_klass, ARG_SYNC,
|
||||
g_param_spec_boolean ("sync",
|
||||
"Sync", "Sync on the clock", FALSE, G_PARAM_READWRITE));
|
||||
"Sync", "Sync on the clock", TRUE,
|
||||
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property (gobject_klass, ARG_TEXT_OVERLAY,
|
||||
g_param_spec_boolean ("text-overlay",
|
||||
"text-overlay",
|
||||
"Wether to use text-overlay", TRUE, G_PARAM_READWRITE));
|
||||
"Wether to use text-overlay", TRUE,
|
||||
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));
|
||||
|
||||
gstelement_klass->change_state = fps_display_sink_change_state;
|
||||
|
||||
|
@ -186,7 +189,7 @@ on_video_sink_data_flow (GstPad * pad, GstMiniObject * mini_obj,
|
|||
static void
|
||||
fps_display_sink_init (FPSDisplaySink * self, FPSDisplaySinkClass * g_class)
|
||||
{
|
||||
GstPad *sink_pad, *target_pad;
|
||||
GstPad *sink_pad;
|
||||
|
||||
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, FPS_TYPE_DISPLAY_SINK,
|
||||
FPSDisplaySinkPrivate);
|
||||
|
@ -197,39 +200,27 @@ fps_display_sink_init (FPSDisplaySink * self, FPSDisplaySinkClass * g_class)
|
|||
/* create child elements */
|
||||
self->priv->video_sink =
|
||||
gst_element_factory_make ("xvimagesink", "fps-display-video_sink");
|
||||
self->priv->text_overlay =
|
||||
gst_element_factory_make ("textoverlay", "fps-display-text-overlay");
|
||||
|
||||
if (!self->priv->video_sink || !self->priv->text_overlay) {
|
||||
if (!self->priv->video_sink) {
|
||||
GST_ERROR_OBJECT (self, "element could not be created");
|
||||
return;
|
||||
}
|
||||
|
||||
g_object_set (self->priv->video_sink, "sync", self->priv->sync, NULL);
|
||||
g_object_set (self->priv->text_overlay, "font-desc", DEFAULT_FONT, NULL);
|
||||
|
||||
/* take a ref before bin takes the ownership */
|
||||
gst_object_ref (self->priv->text_overlay);
|
||||
gst_object_ref (self->priv->video_sink);
|
||||
|
||||
gst_bin_add_many (GST_BIN (self),
|
||||
self->priv->text_overlay, self->priv->video_sink, NULL);
|
||||
|
||||
if (!gst_element_link (self->priv->text_overlay, self->priv->video_sink)) {
|
||||
GST_ERROR_OBJECT (self, "Could not link elements");
|
||||
}
|
||||
gst_bin_add (GST_BIN (self), self->priv->video_sink);
|
||||
|
||||
/* create ghost pad */
|
||||
target_pad =
|
||||
gst_element_get_static_pad (self->priv->text_overlay, "video_sink");
|
||||
sink_pad = gst_ghost_pad_new ("sink_pad", target_pad);
|
||||
gst_object_unref (target_pad);
|
||||
gst_element_add_pad (GST_ELEMENT (self), sink_pad);
|
||||
self->priv->ghost_pad =
|
||||
gst_ghost_pad_new_no_target ("sink_pad", GST_PAD_SINK);
|
||||
gst_element_add_pad (GST_ELEMENT (self), self->priv->ghost_pad);
|
||||
|
||||
/* attach or pad probe */
|
||||
sink_pad = gst_element_get_static_pad (self->priv->video_sink, "sink");
|
||||
gst_pad_add_data_probe (sink_pad, G_CALLBACK (on_video_sink_data_flow),
|
||||
(gpointer) self);
|
||||
|
||||
gst_object_unref (sink_pad);
|
||||
|
||||
self->priv->query = gst_query_new_position (GST_FORMAT_TIME);
|
||||
|
@ -282,12 +273,48 @@ display_current_fps (gpointer data)
|
|||
static void
|
||||
fps_display_sink_start (FPSDisplaySink * self)
|
||||
{
|
||||
GstPad *target_pad = NULL;
|
||||
|
||||
/* Init counters */
|
||||
self->priv->next_ts = GST_CLOCK_TIME_NONE;
|
||||
self->priv->last_ts = GST_CLOCK_TIME_NONE;
|
||||
self->priv->frames_rendered = G_GUINT64_CONSTANT (0);
|
||||
self->priv->frames_dropped = G_GUINT64_CONSTANT (0);
|
||||
|
||||
GST_WARNING ("use text-overlay? %d", self->priv->use_text_overlay);
|
||||
|
||||
if (self->priv->use_text_overlay) {
|
||||
if (!self->priv->text_overlay) {
|
||||
self->priv->text_overlay =
|
||||
gst_element_factory_make ("textoverlay", "fps-display-text-overlay");
|
||||
if (!self->priv->text_overlay) {
|
||||
GST_WARNING_OBJECT (self, "text-overlay element could not be created");
|
||||
self->priv->use_text_overlay = FALSE;
|
||||
goto no_text_overlay;
|
||||
}
|
||||
gst_object_ref (self->priv->text_overlay);
|
||||
g_object_set (self->priv->text_overlay,
|
||||
"font-desc", DEFAULT_FONT, "silent", FALSE, NULL);
|
||||
}
|
||||
gst_bin_add (GST_BIN (self), self->priv->text_overlay);
|
||||
|
||||
if (!gst_element_link (self->priv->text_overlay, self->priv->video_sink)) {
|
||||
GST_ERROR_OBJECT (self, "Could not link elements");
|
||||
}
|
||||
target_pad =
|
||||
gst_element_get_static_pad (self->priv->text_overlay, "video_sink");
|
||||
}
|
||||
no_text_overlay:
|
||||
if (!self->priv->use_text_overlay) {
|
||||
if (self->priv->text_overlay) {
|
||||
gst_element_unlink (self->priv->text_overlay, self->priv->video_sink);
|
||||
gst_bin_remove (GST_BIN (self), self->priv->text_overlay);
|
||||
}
|
||||
target_pad = gst_element_get_static_pad (self->priv->video_sink, "sink");
|
||||
}
|
||||
gst_ghost_pad_set_target (GST_GHOST_PAD (self->priv->ghost_pad), target_pad);
|
||||
gst_object_unref (target_pad);
|
||||
|
||||
/* Set a timeout for the fps display */
|
||||
self->priv->timeout_id =
|
||||
g_timeout_add (FPS_DISPLAY_INTERVAL_MS,
|
||||
|
@ -341,13 +368,15 @@ fps_display_sink_set_property (GObject * object, guint prop_id,
|
|||
case ARG_TEXT_OVERLAY:
|
||||
self->priv->use_text_overlay = g_value_get_boolean (value);
|
||||
|
||||
if (!(self->priv->use_text_overlay)) {
|
||||
GST_DEBUG_OBJECT (self, "text-overlay set to false");
|
||||
g_object_set (self->priv->text_overlay, "text", "", "silent", TRUE,
|
||||
NULL);
|
||||
} else {
|
||||
GST_DEBUG_OBJECT (self, "text-overlay set to true");
|
||||
g_object_set (self->priv->text_overlay, "silent", FALSE, NULL);
|
||||
if (self->priv->text_overlay) {
|
||||
if (!self->priv->use_text_overlay) {
|
||||
GST_DEBUG_OBJECT (self, "text-overlay set to false");
|
||||
g_object_set (self->priv->text_overlay, "text", "", "silent", TRUE,
|
||||
NULL);
|
||||
} else {
|
||||
GST_DEBUG_OBJECT (self, "text-overlay set to true");
|
||||
g_object_set (self->priv->text_overlay, "silent", FALSE, NULL);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -416,13 +416,7 @@ gst_dvd_spu_render_spu (GstDVDSpu * dvdspu, GstBuffer * buf)
|
|||
state->hl_rect.left, state->hl_rect.top,
|
||||
state->hl_rect.right, state->hl_rect.bottom);
|
||||
|
||||
/* We start rendering from the first line of the display rect */
|
||||
y = state->disp_rect.top;
|
||||
|
||||
/* Update our plane references to the first line of the disp_rect */
|
||||
planes[0] += state->Y_stride * y;
|
||||
planes[1] += state->UV_stride * (y / 2);
|
||||
planes[2] += state->UV_stride * (y / 2);
|
||||
GST_DEBUG ("vid_disp %d,%d", state->vid_width, state->vid_height);
|
||||
|
||||
/* When reading RLE data, we track the offset in nibbles... */
|
||||
state->cur_offsets[0] = state->pix_data[0] * 2;
|
||||
|
@ -442,18 +436,62 @@ gst_dvd_spu_render_spu (GstDVDSpu * dvdspu, GstBuffer * buf)
|
|||
} else
|
||||
state->cur_chg_col = NULL;
|
||||
|
||||
/* We start rendering from the first line of the display rect */
|
||||
y = state->disp_rect.top;
|
||||
/* start_y is always an even number and we render lines in pairs from there,
|
||||
* accumulating 2 lines of chroma then blending it. We might need to render a
|
||||
* single line at the end if the display rect ends on an even line too. */
|
||||
last_y = (state->disp_rect.bottom - 1) & ~(0x01);
|
||||
|
||||
/* center the image when display rectangle exceeds the video width */
|
||||
if (state->vid_width < state->disp_rect.right) {
|
||||
gint diff, disp_width;
|
||||
|
||||
disp_width = state->disp_rect.left - state->disp_rect.right;
|
||||
diff = (disp_width - state->vid_width) / 2;
|
||||
|
||||
/* fixme, this is not used yet */
|
||||
state->clip_rect.left = state->disp_rect.left + diff;
|
||||
state->clip_rect.right = state->disp_rect.right - diff;
|
||||
|
||||
GST_DEBUG ("clipping width to %d,%d", state->clip_rect.left,
|
||||
state->clip_rect.right);
|
||||
} else {
|
||||
state->clip_rect.left = state->disp_rect.left;
|
||||
state->clip_rect.right = state->disp_rect.right;
|
||||
}
|
||||
|
||||
/* for the height, chop off the bottom bits of the diplay rectangle because we
|
||||
* assume the picture is in the lower part. We should better check where it
|
||||
* is and do something more clever. */
|
||||
state->clip_rect.bottom = state->disp_rect.bottom;
|
||||
if (state->vid_height < state->disp_rect.bottom) {
|
||||
state->clip_rect.top = state->disp_rect.bottom - state->vid_height;
|
||||
GST_DEBUG ("clipping height to %d,%d", state->clip_rect.top,
|
||||
state->clip_rect.bottom);
|
||||
} else {
|
||||
state->clip_rect.top = state->disp_rect.top;
|
||||
/* Update our plane references to the first line of the disp_rect */
|
||||
planes[0] += state->Y_stride * y;
|
||||
planes[1] += state->UV_stride * (y / 2);
|
||||
planes[2] += state->UV_stride * (y / 2);
|
||||
}
|
||||
|
||||
for (state->cur_Y = y; state->cur_Y <= last_y; state->cur_Y++) {
|
||||
gboolean clip;
|
||||
|
||||
clip = (state->cur_Y < state->clip_rect.top
|
||||
|| state->cur_Y > state->clip_rect.bottom);
|
||||
|
||||
/* Reset the compositing buffer */
|
||||
dvdspu_clear_comp_buffers (state);
|
||||
/* Render even line */
|
||||
state->comp_last_x_ptr = state->comp_last_x;
|
||||
dvdspu_render_line (state, planes, &state->cur_offsets[0]);
|
||||
/* Advance the luminance output pointer */
|
||||
planes[0] += state->Y_stride;
|
||||
if (!clip) {
|
||||
/* Advance the luminance output pointer */
|
||||
planes[0] += state->Y_stride;
|
||||
}
|
||||
state->cur_Y++;
|
||||
|
||||
/* Render odd line */
|
||||
|
@ -462,10 +500,12 @@ gst_dvd_spu_render_spu (GstDVDSpu * dvdspu, GstBuffer * buf)
|
|||
/* Blend the accumulated UV compositing buffers onto the output */
|
||||
dvdspu_blend_comp_buffers (state, planes);
|
||||
|
||||
/* Update all the output pointers */
|
||||
planes[0] += state->Y_stride;
|
||||
planes[1] += state->UV_stride;
|
||||
planes[2] += state->UV_stride;
|
||||
if (!clip) {
|
||||
/* Update all the output pointers */
|
||||
planes[0] += state->Y_stride;
|
||||
planes[1] += state->UV_stride;
|
||||
planes[2] += state->UV_stride;
|
||||
}
|
||||
}
|
||||
if (state->cur_Y == state->disp_rect.bottom) {
|
||||
g_assert ((state->disp_rect.bottom & 0x01) == 0);
|
||||
|
|
|
@ -1366,6 +1366,12 @@ gst_dvd_spu_subpic_event (GstPad * pad, GstEvent * event)
|
|||
/* We don't forward flushes on the spu pad */
|
||||
gst_event_unref (event);
|
||||
goto done;
|
||||
case GST_EVENT_EOS:
|
||||
/* drop EOS on the subtitle pad, it means there are no more subtitles,
|
||||
* video might still continue, though */
|
||||
gst_event_unref (event);
|
||||
goto done;
|
||||
break;
|
||||
default:
|
||||
res = gst_pad_event_default (pad, event);
|
||||
break;
|
||||
|
|
|
@ -122,6 +122,7 @@ struct SpuState {
|
|||
GstBuffer *pix_buf; /* Current SPU packet the pix_data references */
|
||||
|
||||
SpuRect disp_rect;
|
||||
SpuRect clip_rect;
|
||||
SpuRect hl_rect;
|
||||
|
||||
guint32 current_clut[16]; /* Colour lookup table from incoming events */
|
||||
|
|
Loading…
Reference in a new issue