diff options
| -rw-r--r-- | gst/deinterlace/gstdeinterlace.c | 58 | ||||
| -rw-r--r-- | gst/deinterlace/gstdeinterlace.h | 8 | 
2 files changed, 63 insertions, 3 deletions
diff --git a/gst/deinterlace/gstdeinterlace.c b/gst/deinterlace/gstdeinterlace.c index 3ad27d8f..748e4923 100644 --- a/gst/deinterlace/gstdeinterlace.c +++ b/gst/deinterlace/gstdeinterlace.c @@ -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); diff --git a/gst/deinterlace/gstdeinterlace.h b/gst/deinterlace/gstdeinterlace.h index d4bbf0bb..9d5b3b9a 100644 --- a/gst/deinterlace/gstdeinterlace.h +++ b/gst/deinterlace/gstdeinterlace.h @@ -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.  | 
