From 513367a88cb5875c92418f9c2a93b0f3f19ab99a Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Fri, 8 May 2009 17:42:12 +0100 Subject: 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. --- gst/dvdspu/gstdvdspu.c | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) (limited to 'gst/dvdspu/gstdvdspu.c') 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); -- cgit v1.2.1