static gboolean setup_recoder_pipeline (GstSmartEncoder * smart_encoder);
-static GstFlowReturn gst_smart_encoder_chain (GstPad * pad, GstBuffer * buf);
-static gboolean smart_encoder_sink_event (GstPad * pad, GstEvent * event);
-static GstCaps *smart_encoder_sink_getcaps (GstPad * pad);
+static GstFlowReturn gst_smart_encoder_chain (GstPad * pad, GstObject * parent,
+ GstBuffer * buf);
+static gboolean smart_encoder_sink_event (GstPad * pad, GstObject * parent,
+ GstEvent * event);
+static gboolean smart_encoder_sink_query (GstPad * pad, GstObject * parent,
+ GstQuery * query);
+static GstCaps *smart_encoder_sink_getcaps (GstPad * pad, GstCaps * filter);
static GstStateChangeReturn
gst_smart_encoder_change_state (GstElement * element,
GstStateChange transition);
gst_smart_encoder_parent_class = g_type_class_peek_parent (klass);
- gst_element_class_add_static_pad_template (element_class, &src_template);
- gst_element_class_add_static_pad_template (element_class,
- &sink_template);
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&src_template));
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&sink_template));
gst_element_class_set_details_simple (element_class, "Smart Video Encoder",
"Codec/Recoder/Video",
gst_pad_new_from_static_template (&sink_template, "sink");
gst_pad_set_chain_function (smart_encoder->sinkpad, gst_smart_encoder_chain);
gst_pad_set_event_function (smart_encoder->sinkpad, smart_encoder_sink_event);
- gst_pad_set_getcaps_function (smart_encoder->sinkpad,
- smart_encoder_sink_getcaps);
+ gst_pad_set_query_function (smart_encoder->sinkpad, smart_encoder_sink_query);
gst_element_add_pad (GST_ELEMENT (smart_encoder), smart_encoder->sinkpad);
smart_encoder->srcpad =
gst_pad_push_event (smart_encoder->internal_srcpad,
gst_event_new_flush_start ());
gst_pad_push_event (smart_encoder->internal_srcpad,
- gst_event_new_flush_stop ());
+ gst_event_new_flush_stop (TRUE));
/* push newsegment */
GST_INFO ("Pushing newsegment %" GST_PTR_FORMAT, smart_encoder->newsegment);
static GstFlowReturn
gst_smart_encoder_push_pending_gop (GstSmartEncoder * smart_encoder)
{
- gint64 cstart, cstop;
+ guint64 cstart, cstop;
GList *tmp;
GstFlowReturn res = GST_FLOW_OK;
}
static GstFlowReturn
-gst_smart_encoder_chain (GstPad * pad, GstBuffer * buf)
+gst_smart_encoder_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
{
GstSmartEncoder *smart_encoder;
GstFlowReturn res = GST_FLOW_OK;
gboolean discont, keyframe;
- smart_encoder = GST_SMART_ENCODER (gst_object_get_parent (GST_OBJECT (pad)));
+ smart_encoder = GST_SMART_ENCODER (parent);
discont = GST_BUFFER_IS_DISCONT (buf);
keyframe = !GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT);
GST_TIME_ARGS (smart_encoder->gop_stop));
beach:
- gst_object_unref (smart_encoder);
return res;
}
static gboolean
-smart_encoder_sink_event (GstPad * pad, GstEvent * event)
+smart_encoder_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
gboolean res = TRUE;
- GstSmartEncoder *smart_encoder = GST_SMART_ENCODER (gst_pad_get_parent (pad));
+ GstSmartEncoder *smart_encoder = GST_SMART_ENCODER (parent);
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_FLUSH_STOP:
smart_encoder_reset (smart_encoder);
break;
- case GST_EVENT_NEWSEGMENT:
+ case GST_EVENT_SEGMENT:
{
- GstFormat format;
- gdouble rate, arate;
- gint64 start, stop, time;
- gboolean update;
-
- gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
- &start, &stop, &time);
- GST_DEBUG_OBJECT (smart_encoder,
- "newsegment: update %d, rate %g, arate %g, start %" GST_TIME_FORMAT
- ", stop %" GST_TIME_FORMAT ", time %" GST_TIME_FORMAT,
- update, rate, arate, GST_TIME_ARGS (start), GST_TIME_ARGS (stop),
- GST_TIME_ARGS (time));
- if (format != GST_FORMAT_TIME)
+ gst_event_copy_segment (event, smart_encoder->segment);
+
+ GST_DEBUG_OBJECT (smart_encoder, "segment: %" GST_SEGMENT_FORMAT,
+ smart_encoder->segment);
+ if (smart_encoder->segment->format != GST_FORMAT_TIME)
GST_ERROR
("smart_encoder can not handle streams not specified in GST_FORMAT_TIME");
- /* now configure the values */
- gst_segment_set_newsegment_full (smart_encoder->segment, update,
- rate, arate, format, start, stop, time);
-
/* And keep a copy for further usage */
if (smart_encoder->newsegment)
gst_event_unref (smart_encoder->newsegment);
res = gst_pad_push_event (smart_encoder->srcpad, event);
- gst_object_unref (smart_encoder);
return res;
}
static GstCaps *
-smart_encoder_sink_getcaps (GstPad * pad)
+smart_encoder_sink_getcaps (GstPad * pad, GstCaps * filter)
{
GstCaps *peer, *tmpl, *res;
GstSmartEncoder *smart_encoder = GST_SMART_ENCODER (gst_pad_get_parent (pad));
- /* Try getting it from downstream */
- peer = gst_pad_peer_get_caps_reffed (smart_encoder->srcpad);
-
/* Use computed caps */
if (smart_encoder->available_caps)
tmpl = gst_caps_ref (smart_encoder->available_caps);
else
tmpl = gst_static_pad_template_get_caps (&src_template);
+ /* Try getting it from downstream */
+ peer = gst_pad_peer_query_caps (smart_encoder->srcpad, tmpl);
+
if (peer == NULL) {
res = tmpl;
} else {
- res = gst_caps_intersect (peer, tmpl);
- gst_caps_unref (peer);
+ res = peer;
gst_caps_unref (tmpl);
}
return res;
}
+static gboolean
+smart_encoder_sink_query (GstPad * pad, GstObject * parent, GstQuery * query)
+{
+ gboolean res;
+
+ switch (GST_QUERY_TYPE (query)) {
+ case GST_QUERY_CAPS:
+ {
+ GstCaps *filter, *caps;
+
+ gst_query_parse_caps (query, &filter);
+ caps = smart_encoder_sink_getcaps (pad, filter);
+ gst_query_set_caps_result (query, caps);
+ gst_caps_unref (caps);
+ res = TRUE;
+ break;
+ }
+ default:
+ res = gst_pad_query_default (pad, parent, query);
+ break;
+ }
+ return res;
+}
+
/*****************************************
* Internal encoder/decoder pipeline *
******************************************/
}
static GstFlowReturn
-internal_chain (GstPad * pad, GstBuffer * buf)
+internal_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
{
GstSmartEncoder *smart_encoder =
g_object_get_qdata ((GObject *) pad, INTERNAL_ELEMENT);
setup_recoder_pipeline (GstSmartEncoder * smart_encoder)
{
GstPad *tmppad;
+ GstCaps *caps;
/* Fast path */
if (G_UNLIKELY (smart_encoder->encoder))
GST_DEBUG ("Creating internal decoder and encoder");
/* Create decoder/encoder */
- smart_encoder->decoder = get_decoder (GST_PAD_CAPS (smart_encoder->sinkpad));
+ caps = gst_pad_get_current_caps (smart_encoder->sinkpad);
+ smart_encoder->decoder = get_decoder (caps);
if (G_UNLIKELY (smart_encoder->decoder == NULL))
goto no_decoder;
+ gst_caps_unref (caps);
gst_element_set_bus (smart_encoder->decoder, GST_ELEMENT_BUS (smart_encoder));
- smart_encoder->encoder = get_encoder (GST_PAD_CAPS (smart_encoder->sinkpad));
+ caps = gst_pad_get_current_caps (smart_encoder->sinkpad);
+ smart_encoder->encoder = get_encoder (caps);
if (G_UNLIKELY (smart_encoder->encoder == NULL))
goto no_encoder;
+ gst_caps_unref (caps);
gst_element_set_bus (smart_encoder->encoder, GST_ELEMENT_BUS (smart_encoder));
GST_DEBUG ("Creating internal pads");
smart_encoder->internal_srcpad = gst_pad_new ("internal_src", GST_PAD_SRC);
g_object_set_qdata ((GObject *) smart_encoder->internal_srcpad,
INTERNAL_ELEMENT, smart_encoder);
- gst_pad_set_caps (smart_encoder->internal_srcpad,
- GST_PAD_CAPS (smart_encoder->sinkpad));
gst_pad_set_active (smart_encoder->internal_srcpad, TRUE);
/* Sink pad which will get the buffers from the encoder.
smart_encoder->internal_sinkpad = gst_pad_new ("internal_sink", GST_PAD_SINK);
g_object_set_qdata ((GObject *) smart_encoder->internal_sinkpad,
INTERNAL_ELEMENT, smart_encoder);
- gst_pad_set_caps (smart_encoder->internal_sinkpad,
- GST_PAD_CAPS (smart_encoder->sinkpad));
gst_pad_set_chain_function (smart_encoder->internal_sinkpad, internal_chain);
gst_pad_set_active (smart_encoder->internal_sinkpad, TRUE);
no_decoder:
{
- GST_WARNING ("Couldn't find a decoder for %" GST_PTR_FORMAT,
- GST_PAD_CAPS (smart_encoder->sinkpad));
+ GST_WARNING ("Couldn't find a decoder for %" GST_PTR_FORMAT, caps);
+ gst_caps_unref (caps);
return FALSE;
}
no_encoder:
{
- GST_WARNING ("Couldn't find an encoder for %" GST_PTR_FORMAT,
- GST_PAD_CAPS (smart_encoder->sinkpad));
+ GST_WARNING ("Couldn't find an encoder for %" GST_PTR_FORMAT, caps);
+ gst_caps_unref (caps);
return FALSE;
}