static void gst_audio_segment_clip_reset (GstSegmentClip * base) { GstAudioSegmentClip *self = GST_AUDIO_SEGMENT_CLIP (base); GST_DEBUG_OBJECT (self, "Resetting internal state"); self->rate = self->framesize = 0; }
static gboolean gst_audio_segment_clip_set_caps (GstSegmentClip * base, GstCaps * caps) { GstAudioSegmentClip *self = GST_AUDIO_SEGMENT_CLIP (base); gboolean ret; GstStructure *s; gint rate, channels, width; s = gst_caps_get_structure (caps, 0); ret = gst_structure_get_int (s, "rate", &rate); ret = ret && gst_structure_get_int (s, "channels", &channels); ret = ret && gst_structure_get_int (s, "width", &width); if (ret) { GST_DEBUG_OBJECT (self, "Configured: rate %d channels %d width %d", rate, channels, width); self->rate = rate; self->framesize = (width / 8) * channels; } return ret; }
static gboolean gst_audio_segment_clip_set_caps (GstSegmentClip * base, GstCaps * caps) { GstAudioSegmentClip *self = GST_AUDIO_SEGMENT_CLIP (base); gboolean ret; GstAudioInfo info; gint rate, channels, width; gst_audio_info_init (&info); ret = gst_audio_info_from_caps (&info, caps); if (ret) { rate = GST_AUDIO_INFO_RATE (&info); channels = GST_AUDIO_INFO_CHANNELS (&info); width = GST_AUDIO_INFO_WIDTH (&info); GST_DEBUG_OBJECT (self, "Configured: rate %d channels %d width %d", rate, channels, width); self->rate = rate; self->framesize = (width / 8) * channels; } return ret; }
static GstFlowReturn gst_audio_segment_clip_clip_buffer (GstSegmentClip * base, GstBuffer * buffer, GstBuffer ** outbuf) { GstAudioSegmentClip *self = GST_AUDIO_SEGMENT_CLIP (base); GstSegment *segment = &base->segment; GstClockTime timestamp = GST_BUFFER_TIMESTAMP (buffer); GstClockTime duration = GST_BUFFER_DURATION (buffer); guint64 offset = GST_BUFFER_OFFSET (buffer); guint64 offset_end = GST_BUFFER_OFFSET_END (buffer); guint size = gst_buffer_get_size (buffer); if (!self->rate || !self->framesize) { GST_ERROR_OBJECT (self, "Not negotiated yet"); gst_buffer_unref (buffer); return GST_FLOW_NOT_NEGOTIATED; } if (segment->format != GST_FORMAT_DEFAULT && segment->format != GST_FORMAT_TIME) { GST_DEBUG_OBJECT (self, "Unsupported segment format %s", gst_format_get_name (segment->format)); *outbuf = buffer; return GST_FLOW_OK; } if (!GST_BUFFER_TIMESTAMP_IS_VALID (buffer)) { GST_WARNING_OBJECT (self, "Buffer without valid timestamp"); *outbuf = buffer; return GST_FLOW_OK; } *outbuf = gst_audio_buffer_clip (buffer, segment, self->rate, self->framesize); if (!*outbuf) { GST_DEBUG_OBJECT (self, "Buffer outside the configured segment"); /* Now return unexpected if we're before/after the end */ if (segment->format == GST_FORMAT_TIME) { if (segment->rate >= 0) { if (segment->stop != -1 && timestamp >= segment->stop) return GST_FLOW_EOS; } else { if (!GST_CLOCK_TIME_IS_VALID (duration)) duration = gst_util_uint64_scale_int (size, GST_SECOND, self->framesize * self->rate); if (segment->start != -1 && timestamp + duration <= segment->start) return GST_FLOW_EOS; } } else { if (segment->rate >= 0) { if (segment->stop != -1 && offset != -1 && offset >= segment->stop) return GST_FLOW_EOS; } else if (offset != -1 || offset_end != -1) { if (offset_end == -1) offset_end = offset + size / self->framesize; if (segment->start != -1 && offset_end <= segment->start) return GST_FLOW_EOS; } } } return GST_FLOW_OK; }