static GstFlowReturn gst_span_plc_chain (GstPad * pad, GstBuffer * buffer) { GstSpanPlc *plc = GST_SPAN_PLC (GST_PAD_PARENT (pad)); GstClockTime buffer_duration; if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer)) plc->last_stop = GST_BUFFER_TIMESTAMP (buffer); else GST_WARNING_OBJECT (plc, "Buffer has no timestamp!"); if (GST_BUFFER_DURATION_IS_VALID (buffer)) { buffer_duration = GST_BUFFER_DURATION (buffer); } else { GST_WARNING_OBJECT (plc, "Buffer has no duration!"); buffer_duration = (GST_BUFFER_SIZE (buffer) / (plc->sample_rate * sizeof (guint16))) * GST_SECOND; GST_DEBUG_OBJECT (plc, "Buffer duration : %" GST_TIME_FORMAT, GST_TIME_ARGS (buffer_duration)); } plc->last_stop += buffer_duration; if (plc->plc_state->missing_samples != 0) buffer = gst_buffer_make_writable (buffer); plc_rx (plc->plc_state, (int16_t *) GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer) / 2); return gst_pad_push (plc->srcpad, buffer); }
static GstStateChangeReturn gst_span_plc_change_state (GstElement * element, GstStateChange transition) { GstSpanPlc *plc = GST_SPAN_PLC (element); GstStateChangeReturn ret; switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: gst_span_plc_flush (plc, TRUE); break; default: break; } ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); switch (transition) { case GST_STATE_CHANGE_READY_TO_NULL: gst_span_plc_flush (plc, FALSE); default: break; } return ret; }
static gboolean gst_span_plc_event_sink (GstPad * pad, GstObject * parent, GstEvent * event) { GstSpanPlc *plc = GST_SPAN_PLC (parent); GST_DEBUG_OBJECT (plc, "received event %s", GST_EVENT_TYPE_NAME (event)); switch (GST_EVENT_TYPE (event)) { case GST_EVENT_CAPS: { GstCaps *caps; gst_event_parse_caps (event, &caps); gst_span_plc_setcaps_sink (plc, caps); break; } case GST_EVENT_GAP: { GstClockTime timestamp; GstClockTime duration; gst_event_parse_gap (event, ×tamp, &duration); gst_span_plc_send_fillin (plc, timestamp, duration); gst_event_unref (event); return TRUE; } case GST_EVENT_FLUSH_STOP: gst_span_plc_flush (plc, TRUE); break; default: break; } return gst_pad_push_event (plc->srcpad, event); }
static void gst_span_plc_dispose (GObject * object) { GstSpanPlc *plc = GST_SPAN_PLC (object); if (plc->plc_state) plc_free (plc->plc_state); plc->plc_state = NULL; G_OBJECT_CLASS (parent_class)->dispose (object); }
static GstFlowReturn gst_span_plc_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer) { GstSpanPlc *plc = GST_SPAN_PLC (parent); GstMapInfo map; buffer = gst_buffer_make_writable (buffer); gst_buffer_map (buffer, &map, GST_MAP_READWRITE); plc_rx (plc->plc_state, (int16_t *) map.data, map.size / 2); gst_buffer_unmap (buffer, &map); return gst_pad_push (plc->srcpad, buffer); }
static gboolean gst_span_plc_event_sink (GstPad * pad, GstEvent * event) { gboolean ret = FALSE; GstSpanPlc *plc = GST_SPAN_PLC (gst_pad_get_parent (pad)); GST_DEBUG_OBJECT (plc, "received event %s", GST_EVENT_TYPE_NAME (event)); switch (GST_EVENT_TYPE (event)) { case GST_EVENT_NEWSEGMENT: { GstFormat format; gdouble rate; gint64 start, stop, time; gboolean update; gst_event_parse_new_segment (event, &update, &rate, &format, &start, &stop, &time); if (format != GST_FORMAT_TIME) goto newseg_wrong_format; if (update) { /* time progressed without data, see if we can fill the gap with * some concealment data */ if (plc->last_stop < start) gst_span_plc_send_fillin (plc, start - plc->last_stop); } plc->last_stop = start; break; } case GST_EVENT_FLUSH_START: gst_span_plc_flush (plc, TRUE); break; default: break; } ret = gst_pad_push_event (plc->srcpad, event); gst_object_unref (plc); return ret; newseg_wrong_format: { GST_DEBUG_OBJECT (plc, "received non TIME newsegment"); gst_object_unref (plc); return FALSE; } }
static gboolean gst_span_plc_setcaps_sink (GstPad * pad, GstCaps * caps) { GstSpanPlc *plc = GST_SPAN_PLC (gst_pad_get_parent (pad)); GstStructure *s = NULL; gboolean ret = FALSE; ret = gst_pad_set_caps (plc->srcpad, caps); s = gst_caps_get_structure (caps, 0); if (s) { gst_structure_get_int (s, "rate", &plc->sample_rate); GST_DEBUG_OBJECT (plc, "setcaps: got sample rate : %d", plc->sample_rate); } gst_span_plc_flush (plc, TRUE); gst_object_unref (plc); return ret; }