GstClockTime next_ts;
GstClockTime prev_ts;
GstClockTime frame_duration;
+ gboolean seen_keyframe;
+ gboolean is_video;
guint64 framecount;
guint64 bytecount;
parse->priv->upstream_has_duration = FALSE;
parse->priv->idx_interval = 0;
parse->priv->exact_position = TRUE;
+ parse->priv->seen_keyframe = FALSE;
parse->priv->last_ts = GST_CLOCK_TIME_NONE;
parse->priv->last_offset = 0;
parse->priv->next_ts = next_ts;
parse->priv->last_ts = GST_CLOCK_TIME_NONE;
parse->priv->discont = TRUE;
+ parse->priv->seen_keyframe = FALSE;
break;
}
2, (const GstIndexAssociation *) &associations);
GST_OBJECT_UNLOCK (parse);
- parse->priv->index_last_offset = offset;
- parse->priv->index_last_ts = ts;
+ if (key) {
+ parse->priv->index_last_offset = offset;
+ parse->priv->index_last_ts = ts;
+ }
ret = TRUE;
parse->priv->upstream_has_duration);
}
+/* checks src caps to determine if dealing with audio or video */
+/* TODO maybe forego automagic stuff and let subclass configure it ? */
+static void
+gst_base_parse_check_media (GstBaseParse * parse)
+{
+ GstCaps *caps;
+ GstStructure *s;
+
+ caps = GST_PAD_CAPS (parse->srcpad);
+ if (G_LIKELY (caps) && (s = gst_caps_get_structure (caps, 0))) {
+ parse->priv->is_video =
+ g_str_has_prefix (gst_structure_get_name (s), "video");
+ } else {
+ /* historical default */
+ parse->priv->is_video = FALSE;
+ }
+
+ GST_DEBUG_OBJECT (parse, "media is video == %d", parse->priv->is_video);
+}
+
/**
* gst_base_parse_handle_and_push_buffer:
* @parse: #GstBaseParse.
parse->priv->pad_mode == GST_ACTIVATE_PULL ? "loop" : "chain");
gst_pad_push_event (parse->srcpad, parse->pending_segment);
parse->pending_segment = NULL;
+
+ /* have caps; check identity */
+ gst_base_parse_check_media (parse);
}
/* update bitrates and optionally post corresponding tags
else
ret = GST_BASE_PARSE_FLOW_CLIP;
+ parse->priv->seen_keyframe |= parse->priv->is_video &&
+ !GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
+
if (ret == GST_BASE_PARSE_FLOW_CLIP) {
if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer) &&
GST_CLOCK_TIME_IS_VALID (parse->segment.stop) &&
GST_CLOCK_TIME_IS_VALID (parse->segment.start) &&
GST_BUFFER_TIMESTAMP (buffer) + GST_BUFFER_DURATION (buffer) +
parse->priv->lead_in_ts < parse->segment.start) {
- GST_LOG_OBJECT (parse, "Dropped frame, before segment");
- ret = GST_BASE_PARSE_FLOW_DROPPED;
+ if (parse->priv->seen_keyframe) {
+ GST_LOG_OBJECT (parse, "Frame before segment, after keyframe");
+ ret = GST_FLOW_OK;
+ } else {
+ GST_LOG_OBJECT (parse, "Dropped frame, before segment");
+ ret = GST_BASE_PARSE_FLOW_DROPPED;
+ }
} else {
ret = GST_FLOW_OK;
}
"mark DISCONT, we did a seek to another position");
parse->priv->offset = seekpos;
parse->priv->last_offset = seekpos;
+ parse->priv->seen_keyframe = FALSE;
parse->priv->discont = TRUE;
parse->priv->next_ts = start_ts;
parse->priv->last_ts = GST_CLOCK_TIME_NONE;