Merge branch 'master' into 0.11
[platform/upstream/gstreamer.git] / gst / encoding / gstsmartencoder.c
index 6d2e778..4ff4f4a 100644 (file)
@@ -78,9 +78,13 @@ static void gst_smart_encoder_dispose (GObject * object);
 
 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);
@@ -96,9 +100,10 @@ gst_smart_encoder_class_init (GstSmartEncoderClass * klass)
 
   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",
@@ -150,8 +155,7 @@ gst_smart_encoder_init (GstSmartEncoder * smart_encoder)
       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 =
@@ -198,7 +202,7 @@ gst_smart_encoder_reencode_gop (GstSmartEncoder * smart_encoder)
   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);
@@ -241,7 +245,7 @@ gst_smart_encoder_reencode_gop (GstSmartEncoder * smart_encoder)
 static GstFlowReturn
 gst_smart_encoder_push_pending_gop (GstSmartEncoder * smart_encoder)
 {
-  gint64 cstart, cstop;
+  guint64 cstart, cstop;
   GList *tmp;
   GstFlowReturn res = GST_FLOW_OK;
 
@@ -288,13 +292,13 @@ gst_smart_encoder_push_pending_gop (GstSmartEncoder * smart_encoder)
 }
 
 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);
@@ -335,42 +339,29 @@ gst_smart_encoder_chain (GstPad * pad, GstBuffer * buf)
       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);
@@ -387,30 +378,28 @@ smart_encoder_sink_event (GstPad * pad, GstEvent * event)
 
   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);
   }
 
@@ -418,6 +407,30 @@ smart_encoder_sink_getcaps (GstPad * pad)
   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  *
  ******************************************/
@@ -497,7 +510,7 @@ get_encoder (GstCaps * caps)
 }
 
 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);
@@ -509,6 +522,7 @@ static gboolean
 setup_recoder_pipeline (GstSmartEncoder * smart_encoder)
 {
   GstPad *tmppad;
+  GstCaps *caps;
 
   /* Fast path */
   if (G_UNLIKELY (smart_encoder->encoder))
@@ -517,14 +531,18 @@ setup_recoder_pipeline (GstSmartEncoder * smart_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");
@@ -535,8 +553,6 @@ setup_recoder_pipeline (GstSmartEncoder * smart_encoder)
   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.
@@ -545,8 +561,6 @@ setup_recoder_pipeline (GstSmartEncoder * smart_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);
 
@@ -574,15 +588,15 @@ setup_recoder_pipeline (GstSmartEncoder * smart_encoder)
 
 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;
   }