static gboolean gst_kate_parse_sink_event (GstPad * pad, GstObject * parent, GstEvent * event) { gboolean ret; GstKateParse *parse; parse = GST_KATE_PARSE (parent); switch (GST_EVENT_TYPE (event)) { case GST_EVENT_FLUSH_STOP: gst_kate_parse_clear_queue (parse); ret = gst_pad_event_default (pad, parent, event); break; case GST_EVENT_EOS: if (!parse->streamheader_sent) { GST_DEBUG_OBJECT (parse, "Got EOS, pushing headers seen so far"); ret = gst_kate_parse_push_headers (parse); if (ret != GST_FLOW_OK) break; } gst_kate_parse_drain_queue_prematurely (parse); ret = gst_pad_event_default (pad, parent, event); break; default: if (!parse->streamheader_sent && GST_EVENT_IS_SERIALIZED (event) && GST_EVENT_TYPE (event) > GST_EVENT_CAPS) ret = gst_kate_parse_queue_event (parse, event); else ret = gst_pad_event_default (pad, parent, event); break; } return ret; }
static GstFlowReturn gst_kate_parse_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer) { GstKateParseClass *klass; GstKateParse *parse; parse = GST_KATE_PARSE (parent); klass = GST_KATE_PARSE_CLASS (G_OBJECT_GET_CLASS (parse)); g_assert (klass->parse_packet != NULL); if (G_UNLIKELY (!gst_pad_has_current_caps (pad))) return GST_FLOW_NOT_NEGOTIATED; return klass->parse_packet (parse, buffer); }
static GstFlowReturn gst_kate_parse_chain (GstPad * pad, GstBuffer * buffer) { GstKateParseClass *klass; GstKateParse *parse; parse = GST_KATE_PARSE (GST_PAD_PARENT (pad)); klass = GST_KATE_PARSE_CLASS (G_OBJECT_GET_CLASS (parse)); g_assert (klass->parse_packet != NULL); if (G_UNLIKELY (GST_PAD_CAPS (pad) == NULL)) return GST_FLOW_NOT_NEGOTIATED; return klass->parse_packet (parse, buffer); }
static gboolean gst_kate_parse_convert (GstPad * pad, GstFormat src_format, gint64 src_value, GstFormat * dest_format, gint64 * dest_value) { gboolean res = TRUE; GstKateParse *parse; parse = GST_KATE_PARSE (GST_PAD_PARENT (pad)); /* fixme: assumes atomic access to lots of instance variables modified from * the streaming thread, including 64-bit variables */ if (!parse->streamheader_sent) return FALSE; if (src_format == *dest_format) { *dest_value = src_value; return TRUE; } if (parse->sinkpad == pad && (src_format == GST_FORMAT_BYTES || *dest_format == GST_FORMAT_BYTES)) return FALSE; switch (src_format) { case GST_FORMAT_TIME: switch (*dest_format) { default: res = FALSE; } break; case GST_FORMAT_DEFAULT: switch (*dest_format) { case GST_FORMAT_TIME: *dest_value = kate_granule_time (&parse->ki, src_value) * GST_SECOND; break; default: res = FALSE; } break; default: res = FALSE; } return res; }
static GstStateChangeReturn gst_kate_parse_change_state (GstElement * element, GstStateChange transition) { GstKateParse *parse = GST_KATE_PARSE (element); GstStateChangeReturn ret; switch (transition) { case GST_STATE_CHANGE_READY_TO_PAUSED: kate_info_init (&parse->ki); kate_comment_init (&parse->kc); parse->packetno = 0; parse->streamheader_sent = FALSE; parse->streamheader = NULL; parse->buffer_queue = g_queue_new (); parse->event_queue = g_queue_new (); break; default: break; } ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); switch (transition) { case GST_STATE_CHANGE_PAUSED_TO_READY: kate_info_clear (&parse->ki); kate_comment_clear (&parse->kc); gst_kate_parse_clear_queue (parse); g_queue_free (parse->buffer_queue); parse->buffer_queue = NULL; g_queue_free (parse->event_queue); parse->event_queue = NULL; gst_kate_parse_free_stream_headers (parse); break; default: break; } return ret; }
static gboolean gst_kate_parse_src_query (GstPad * pad, GstObject * parent, GstQuery * query) { #if 1 // TODO GST_WARNING ("gst_kate_parse_src_query"); return FALSE; #else gint64 granulepos; GstKateParse *parse; gboolean res = FALSE; parse = GST_KATE_PARSE (parent); switch (GST_QUERY_TYPE (query)) { case GST_QUERY_POSITION: { GstFormat format; gint64 value; granulepos = parse->prev_granulepos; gst_query_parse_position (query, &format, NULL); /* and convert to the final format */ if (!(res = gst_kate_parse_convert (pad, GST_FORMAT_DEFAULT, granulepos, &format, &value))) goto error; /* fixme: support segments value = (value - parse->segment_start) + parse->segment_time; */ gst_query_set_position (query, format, value); GST_LOG_OBJECT (parse, "query %p: peer returned granulepos: %" G_GUINT64_FORMAT " - we return %" G_GUINT64_FORMAT " (format %u)", query, granulepos, value, format); break; } case GST_QUERY_DURATION: { /* fixme: not threadsafe */ /* query peer for total length */ if (!gst_pad_is_linked (parse->sinkpad)) { GST_WARNING_OBJECT (parse, "sink pad %" GST_PTR_FORMAT " is not linked", parse->sinkpad); goto error; } if (!(res = gst_pad_query (GST_PAD_PEER (parse->sinkpad), query))) goto error; break; } case GST_QUERY_CONVERT: { GstFormat src_fmt, dest_fmt; gint64 src_val, dest_val; gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val); if (!(res = gst_kate_parse_convert (pad, src_fmt, src_val, &dest_fmt, &dest_val))) goto error; gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val); break; } default: res = gst_pad_query_default (pad, query); break; } return res; error: { GST_WARNING_OBJECT (parse, "error handling query"); return res; } #endif }