summaryrefslogtreecommitdiffstats
path: root/gst
diff options
context:
space:
mode:
authorJan Schmidt <thaytan@noraisin.net>2009-05-08 17:42:12 +0100
committerJan Schmidt <thaytan@noraisin.net>2009-05-11 17:04:09 +0100
commit513367a88cb5875c92418f9c2a93b0f3f19ab99a (patch)
tree8a5b7c5d47bcee90f05859d62898c9054a65e00f /gst
parent571a7746fcf18fba066779a43c23683a9d554051 (diff)
downloadgst-plugins-bad-513367a88cb5875c92418f9c2a93b0f3f19ab99a.tar.gz
gst-plugins-bad-513367a88cb5875c92418f9c2a93b0f3f19ab99a.tar.bz2
gst-plugins-bad-513367a88cb5875c92418f9c2a93b0f3f19ab99a.zip
dvdspu: Always push a frame at the start of a still frame, and fix a leak.
Make sure to push the frame for a still frame, with discont = true and timestamp=none, so that it gets displayed by the sink. Also, don't leak each rendered video frame during still menus.
Diffstat (limited to 'gst')
-rw-r--r--gst/dvdspu/gstdvdspu.c34
1 files changed, 24 insertions, 10 deletions
diff --git a/gst/dvdspu/gstdvdspu.c b/gst/dvdspu/gstdvdspu.c
index 3b4c1a0c..50b6b603 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);
@@ -429,7 +429,7 @@ 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);
+ gst_dvd_spu_redraw_still (dvdspu, TRUE);
} else
state->flags &= ~(SPU_STATE_STILL_FRAME);
DVD_SPU_UNLOCK (dvdspu);
@@ -633,15 +633,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 +656,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 +1014,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);