summaryrefslogtreecommitdiffstats
path: root/gst/dvdspu
diff options
context:
space:
mode:
Diffstat (limited to 'gst/dvdspu')
-rw-r--r--gst/dvdspu/gstdvdspu-render.c2
-rw-r--r--gst/dvdspu/gstdvdspu.c56
2 files changed, 43 insertions, 15 deletions
diff --git a/gst/dvdspu/gstdvdspu-render.c b/gst/dvdspu/gstdvdspu-render.c
index e3bae8b6..a8dadee2 100644
--- a/gst/dvdspu/gstdvdspu-render.c
+++ b/gst/dvdspu/gstdvdspu-render.c
@@ -400,6 +400,8 @@ gst_dvd_spu_render_spu (GstDVDSpu * dvdspu, GstBuffer * buf)
gint y, last_y;
/* Set up our initial state */
+ if (G_UNLIKELY (state->pix_buf == NULL))
+ return;
/* Store the start of each plane */
planes[0] = GST_BUFFER_DATA (buf);
diff --git a/gst/dvdspu/gstdvdspu.c b/gst/dvdspu/gstdvdspu.c
index 3b4c1a0c..703c405b 100644
--- a/gst/dvdspu/gstdvdspu.c
+++ b/gst/dvdspu/gstdvdspu.c
@@ -94,7 +94,7 @@ static GstFlowReturn gst_dvd_spu_video_chain (GstPad * pad, GstBuffer * buf);
static gboolean gst_dvd_spu_video_event (GstPad * pad, GstEvent * event);
static GstFlowReturn gst_dvd_spu_buffer_alloc (GstPad * sinkpad, guint64 offset,
guint size, GstCaps * caps, GstBuffer ** buf);
-static void gst_dvd_spu_redraw_still (GstDVDSpu * dvdspu);
+static void gst_dvd_spu_redraw_still (GstDVDSpu * dvdspu, gboolean force);
static void gst_dvd_spu_check_still_updates (GstDVDSpu * dvdspu);
static GstFlowReturn gst_dvd_spu_subpic_chain (GstPad * pad, GstBuffer * buf);
@@ -413,13 +413,16 @@ gst_dvd_spu_video_event (GstPad * pad, GstEvent * event)
break;
}
- GST_DEBUG_OBJECT (dvdspu,
- "DVD event of type %s on video pad", event_type);
-
if (strcmp (event_type, "dvd-still") == 0) {
gboolean in_still;
if (gst_structure_get_boolean (structure, "still-state", &in_still)) {
+ GstBuffer *to_push = NULL;
+
+ GST_DEBUG_OBJECT (dvdspu,
+ "DVD event of type %s on video pad: in-still = %d", event_type,
+ in_still);
+
DVD_SPU_LOCK (dvdspu);
if (in_still) {
state->flags |= SPU_STATE_STILL_FRAME;
@@ -429,15 +432,24 @@ gst_dvd_spu_video_event (GstPad * pad, GstEvent * event)
/* And re-draw the still frame to make sure it appears on
* screen, otherwise the last frame might have been discarded
* by QoS */
- gst_dvd_spu_redraw_still (dvdspu);
- } else
+ gst_dvd_spu_redraw_still (dvdspu, TRUE);
+ to_push = dvdspu->pending_frame;
+ dvdspu->pending_frame = NULL;
+
+ } else {
state->flags &= ~(SPU_STATE_STILL_FRAME);
+ }
DVD_SPU_UNLOCK (dvdspu);
+ if (to_push)
+ gst_pad_push (dvdspu->srcpad, to_push);
}
gst_event_unref (event);
res = TRUE;
- } else
+ } else {
+ GST_DEBUG_OBJECT (dvdspu,
+ "DVD event of type %s on video pad", event_type);
res = gst_pad_event_default (pad, event);
+ }
break;
}
case GST_EVENT_NEWSEGMENT:
@@ -633,15 +645,17 @@ no_ref_frame:
/* With SPU LOCK */
static void
-gst_dvd_spu_redraw_still (GstDVDSpu * dvdspu)
+gst_dvd_spu_redraw_still (GstDVDSpu * dvdspu, gboolean force)
{
/* If we have an active SPU command set and a reference frame, copy the
* frame, redraw the SPU and store it as the pending frame for output */
if (dvdspu->ref_frame) {
- if ((dvdspu->spu_state.flags & SPU_STATE_FORCED_DSP) ||
- ((dvdspu->spu_state.flags & SPU_STATE_FORCED_ONLY) == 0 &&
- (dvdspu->spu_state.flags & SPU_STATE_DISPLAY))) {
- GstBuffer *buf = gst_buffer_copy (dvdspu->ref_frame);
+ gboolean redraw = (dvdspu->spu_state.flags & SPU_STATE_FORCED_DSP);
+ redraw |= (dvdspu->spu_state.flags & SPU_STATE_FORCED_ONLY) == 0 &&
+ (dvdspu->spu_state.flags & SPU_STATE_DISPLAY);
+
+ if (redraw) {
+ GstBuffer *buf = gst_buffer_ref (dvdspu->ref_frame);
buf = gst_buffer_make_writable (buf);
@@ -654,9 +668,21 @@ gst_dvd_spu_redraw_still (GstDVDSpu * dvdspu)
/* Render the SPU overlay onto the buffer */
gst_dvd_spu_render_spu (dvdspu, buf);
gst_buffer_replace (&dvdspu->pending_frame, buf);
+ gst_buffer_unref (buf);
+ } else if (force) {
+ /* Simply output the reference frame */
+ GstBuffer *buf = gst_buffer_ref (dvdspu->ref_frame);
+ buf = gst_buffer_make_metadata_writable (buf);
+ GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
+ GST_BUFFER_TIMESTAMP (buf) = GST_CLOCK_TIME_NONE;
+ GST_BUFFER_DURATION (buf) = GST_CLOCK_TIME_NONE;
+
+ GST_DEBUG_OBJECT (dvdspu, "Pushing reference frame at start of still");
+
+ gst_buffer_replace (&dvdspu->pending_frame, buf);
+ gst_buffer_unref (buf);
} else {
- GST_LOG_OBJECT (dvdspu,
- "Redraw due to Still Frame skipped - no SPU to draw");
+ GST_LOG_OBJECT (dvdspu, "Redraw due to Still Frame skipped");
}
} else {
GST_LOG_OBJECT (dvdspu, "Not redrawing still frame - no ref frame");
@@ -1000,7 +1026,7 @@ gst_dvd_spu_handle_dvd_event (GstDVDSpu * dvdspu, GstEvent * event)
}
if (hl_change && (state->flags & SPU_STATE_STILL_FRAME)) {
- gst_dvd_spu_redraw_still (dvdspu);
+ gst_dvd_spu_redraw_still (dvdspu, FALSE);
}
gst_event_unref (event);