mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-30 13:41:48 +00:00
deinterlace: First try to handle DVD still frames correctly
This helps a bit with bug #582740 but still doesn't make it work.
This commit is contained in:
parent
85ba1b3e6a
commit
29111fa1f8
2 changed files with 63 additions and 3 deletions
|
@ -687,6 +687,8 @@ gst_deinterlace_init (GstDeinterlace * self, GstDeinterlaceClass * klass)
|
|||
self->fields = DEFAULT_FIELDS;
|
||||
self->field_layout = DEFAULT_FIELD_LAYOUT;
|
||||
|
||||
self->still_frame_mode = FALSE;
|
||||
|
||||
gst_deinterlace_reset (self);
|
||||
}
|
||||
|
||||
|
@ -703,6 +705,10 @@ gst_deinterlace_reset_history (GstDeinterlace * self)
|
|||
}
|
||||
memset (self->field_history, 0, MAX_FIELD_HISTORY * sizeof (GstPicture));
|
||||
self->history_count = 0;
|
||||
|
||||
if (self->last_buffer)
|
||||
gst_buffer_unref (self->last_buffer);
|
||||
self->last_buffer = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -913,7 +919,9 @@ gst_deinterlace_push_history (GstDeinterlace * self, GstBuffer * buffer)
|
|||
self->history_count += fields_to_push;
|
||||
GST_DEBUG_OBJECT (self, "push, size(history): %d", self->history_count);
|
||||
|
||||
gst_buffer_unref (buffer);
|
||||
if (self->last_buffer)
|
||||
gst_buffer_unref (self->last_buffer);
|
||||
self->last_buffer = buffer;
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
|
@ -928,7 +936,8 @@ gst_deinterlace_chain (GstPad * pad, GstBuffer * buf)
|
|||
|
||||
self = GST_DEINTERLACE (GST_PAD_PARENT (pad));
|
||||
|
||||
if (self->mode == GST_DEINTERLACE_MODE_DISABLED || (!self->interlaced
|
||||
if (self->still_frame_mode ||
|
||||
self->mode == GST_DEINTERLACE_MODE_DISABLED || (!self->interlaced
|
||||
&& self->mode != GST_DEINTERLACE_MODE_INTERLACED))
|
||||
return gst_pad_push (self->srcpad, buf);
|
||||
|
||||
|
@ -1345,7 +1354,41 @@ gst_deinterlace_sink_event (GstPad * pad, GstEvent * event)
|
|||
GST_LOG_OBJECT (pad, "received %s event", GST_EVENT_TYPE_NAME (event));
|
||||
|
||||
switch (GST_EVENT_TYPE (event)) {
|
||||
case GST_EVENT_FLUSH_STOP:
|
||||
case GST_EVENT_CUSTOM_DOWNSTREAM:{
|
||||
const GstStructure *s = gst_event_get_structure (event);
|
||||
|
||||
if (gst_structure_has_name (s, "application/x-gst-dvd")) {
|
||||
const gchar *event_type;
|
||||
gboolean still_state;
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Received DVD event: %" GST_PTR_FORMAT, s);
|
||||
|
||||
event_type = gst_structure_get_string (s, "event");
|
||||
if (event_type && !strcmp (event_type, "dvd-still") &&
|
||||
gst_structure_get_boolean (s, "still-state", &still_state)) {
|
||||
|
||||
if (still_state) {
|
||||
GstFlowReturn ret;
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Handling still frame");
|
||||
self->still_frame_mode = TRUE;
|
||||
if (self->last_buffer) {
|
||||
ret =
|
||||
gst_pad_push (self->srcpad,
|
||||
gst_buffer_ref (self->last_buffer));
|
||||
GST_DEBUG_OBJECT (self, "Pushed still frame, result: %s",
|
||||
gst_flow_get_name (ret));
|
||||
} else {
|
||||
GST_WARNING_OBJECT (self, "No pending buffer!");
|
||||
}
|
||||
} else {
|
||||
GST_DEBUG_OBJECT (self, "Ending still frames");
|
||||
self->still_frame_mode = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* fall through */
|
||||
case GST_EVENT_EOS:
|
||||
case GST_EVENT_NEWSEGMENT:
|
||||
gst_deinterlace_reset_history (self);
|
||||
|
@ -1354,6 +1397,15 @@ gst_deinterlace_sink_event (GstPad * pad, GstEvent * event)
|
|||
default:
|
||||
res = gst_pad_event_default (pad, event);
|
||||
break;
|
||||
|
||||
case GST_EVENT_FLUSH_STOP:
|
||||
if (self->still_frame_mode) {
|
||||
GST_DEBUG_OBJECT (self, "Ending still frames");
|
||||
self->still_frame_mode = FALSE;
|
||||
}
|
||||
res = gst_pad_event_default (pad, event);
|
||||
gst_deinterlace_reset_history (self);
|
||||
break;
|
||||
}
|
||||
|
||||
gst_object_unref (self);
|
||||
|
|
|
@ -225,6 +225,14 @@ struct _GstDeinterlace
|
|||
GstPicture field_history[MAX_FIELD_HISTORY];
|
||||
guint history_count;
|
||||
|
||||
/* Set to TRUE if we're in still frame mode,
|
||||
i.e. just forward all buffers
|
||||
*/
|
||||
gboolean still_frame_mode;
|
||||
|
||||
/* Last buffer that was pushed in */
|
||||
GstBuffer *last_buffer;
|
||||
|
||||
/* Number of bytes of actual data in each scanline. May be less than
|
||||
OverlayPitch since the overlay's scanlines might have alignment
|
||||
requirements. Generally equal to FrameWidth * 2.
|
||||
|
|
Loading…
Reference in a new issue