Merge branch 'master' into 0.11
[platform/upstream/gstreamer.git] / ext / theora / gsttheoraenc.c
index acc5bd6..6a29fc9 100644 (file)
@@ -243,30 +243,18 @@ GST_STATIC_PAD_TEMPLATE ("src",
     GST_STATIC_CAPS ("video/x-theora")
     );
 
-static GstCaps *theora_enc_src_caps;
-
-static void
-_do_init (GType object_type)
-{
-  const GInterfaceInfo preset_interface_info = {
-    NULL,                       /* interface_init */
-    NULL,                       /* interface_finalize */
-    NULL                        /* interface_data */
-  };
-
-  g_type_add_interface_static (object_type, GST_TYPE_PRESET,
-      &preset_interface_info);
-}
+#define gst_theora_enc_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstTheoraEnc, gst_theora_enc,
+    GST_TYPE_ELEMENT, G_IMPLEMENT_INTERFACE (GST_TYPE_PRESET, NULL));
 
-GST_BOILERPLATE_FULL (GstTheoraEnc, gst_theora_enc, GstElement,
-    GST_TYPE_ELEMENT, _do_init);
+static GstCaps *theora_enc_src_caps;
 
 static gboolean theora_enc_sink_event (GstPad * pad, GstEvent * event);
 static gboolean theora_enc_src_event (GstPad * pad, GstEvent * event);
 static GstFlowReturn theora_enc_chain (GstPad * pad, GstBuffer * buffer);
 static GstStateChangeReturn theora_enc_change_state (GstElement * element,
     GstStateChange transition);
-static GstCaps *theora_enc_sink_getcaps (GstPad * pad);
+static GstCaps *theora_enc_sink_getcaps (GstPad * pad, GstCaps * filter);
 static gboolean theora_enc_sink_setcaps (GstPad * pad, GstCaps * caps);
 static void theora_enc_get_property (GObject * object, guint prop_id,
     GValue * value, GParamSpec * pspec);
@@ -280,21 +268,6 @@ static gboolean theora_enc_write_multipass_cache (GstTheoraEnc * enc,
 static char *theora_enc_get_supported_formats (void);
 
 static void
-gst_theora_enc_base_init (gpointer g_class)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&theora_enc_src_factory));
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&theora_enc_sink_factory));
-  gst_element_class_set_details_simple (element_class,
-      "Theora video encoder", "Codec/Encoder/Video",
-      "encode raw YUV video to a theora stream",
-      "Wim Taymans <wim@fluendo.com>");
-}
-
-static void
 gst_theora_enc_class_init (GstTheoraEncClass * klass)
 {
   GObjectClass *gobject_class = (GObjectClass *) klass;
@@ -419,6 +392,15 @@ gst_theora_enc_class_init (GstTheoraEncClass * klass)
           THEORA_DEF_MULTIPASS_MODE,
           (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&theora_enc_src_factory));
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&theora_enc_sink_factory));
+  gst_element_class_set_details_simple (gstelement_class,
+      "Theora video encoder", "Codec/Encoder/Video",
+      "encode raw YUV video to a theora stream",
+      "Wim Taymans <wim@fluendo.com>");
+
   caps_string = g_strdup_printf ("video/x-raw-yuv, "
       "format = (fourcc) { %s }, "
       "framerate = (fraction) [1/MAX, MAX], "
@@ -431,7 +413,7 @@ gst_theora_enc_class_init (GstTheoraEncClass * klass)
 }
 
 static void
-gst_theora_enc_init (GstTheoraEnc * enc, GstTheoraEncClass * g_class)
+gst_theora_enc_init (GstTheoraEnc * enc)
 {
   enc->sinkpad =
       gst_pad_new_from_static_template (&theora_enc_sink_factory, "sink");
@@ -610,15 +592,15 @@ theora_enc_get_supported_formats (void)
 }
 
 static GstCaps *
-theora_enc_sink_getcaps (GstPad * pad)
+theora_enc_sink_getcaps (GstPad * pad, GstCaps * filter)
 {
   GstTheoraEnc *encoder;
   GstPad *peer;
   GstCaps *caps;
 
   /* If we already have caps return them */
-  if (GST_PAD_CAPS (pad))
-    return gst_caps_ref (GST_PAD_CAPS (pad));
+  if ((caps = gst_pad_get_current_caps (pad)) != NULL)
+    return caps;
 
   encoder = GST_THEORA_ENC (gst_pad_get_parent (pad));
   if (!encoder)
@@ -631,7 +613,7 @@ theora_enc_sink_getcaps (GstPad * pad)
     GstStructure *s;
     guint i, n;
 
-    peer_caps = gst_pad_get_caps (peer);
+    peer_caps = gst_pad_get_caps (peer, NULL);
 
     /* Translate peercaps to YUV */
     peer_caps = gst_caps_make_writable (peer_caps);
@@ -656,6 +638,15 @@ theora_enc_sink_getcaps (GstPad * pad)
 
   gst_object_unref (encoder);
 
+  if (filter) {
+    GstCaps *intersection;
+
+    intersection =
+        gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
+    gst_caps_unref (caps);
+    caps = intersection;
+  }
+
   return caps;
 }
 
@@ -756,8 +747,7 @@ theora_buffer_from_packet (GstTheoraEnc * enc, ogg_packet * packet,
     goto done;
   }
 
-  memcpy (GST_BUFFER_DATA (buf), packet->packet, packet->bytes);
-  gst_buffer_set_caps (buf, GST_PAD_CAPS (enc->srcpad));
+  gst_buffer_fill (buf, 0, packet->packet, packet->bytes);
   /* see ext/ogg/README; OFFSET_END takes "our" granulepos, OFFSET its
    * time representation */
   GST_BUFFER_OFFSET_END (buf) =
@@ -794,7 +784,7 @@ theora_push_buffer (GstTheoraEnc * enc, GstBuffer * buffer)
 {
   GstFlowReturn ret;
 
-  enc->bytes_out += GST_BUFFER_SIZE (buffer);
+  enc->bytes_out += gst_buffer_get_size (buffer);
 
   ret = gst_pad_push (enc->srcpad, buffer);
 
@@ -882,18 +872,9 @@ theora_enc_sink_event (GstPad * pad, GstEvent * event)
   enc = GST_THEORA_ENC (GST_PAD_PARENT (pad));
 
   switch (GST_EVENT_TYPE (event)) {
-    case GST_EVENT_NEWSEGMENT:
+    case GST_EVENT_SEGMENT:
     {
-      gboolean update;
-      gdouble rate, applied_rate;
-      GstFormat format;
-      gint64 start, stop, time;
-
-      gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate,
-          &format, &start, &stop, &time);
-
-      gst_segment_set_newsegment_full (&enc->segment, update, rate,
-          applied_rate, format, start, stop, time);
+      gst_event_copy_segment (event, &enc->segment);
 
       res = gst_pad_push_event (enc->srcpad, event);
       break;
@@ -1058,17 +1039,21 @@ theora_enc_read_multipass_cache (GstTheoraEnc * enc)
 
   while (!done) {
     if (gst_adapter_available (enc->multipass_cache_adapter) == 0) {
+      guint8 *data;
+      gsize size;
+
       cache_buf = gst_buffer_new_and_alloc (512);
+
+      data = gst_buffer_map (cache_buf, &size, NULL, GST_MAP_READ);
       stat = g_io_channel_read_chars (enc->multipass_cache_fd,
-          (gchar *) GST_BUFFER_DATA (cache_buf), GST_BUFFER_SIZE (cache_buf),
-          &bytes_read, NULL);
+          (gchar *) data, size, &bytes_read, NULL);
 
       if (bytes_read <= 0) {
+        gst_buffer_unmap (cache_buf, data, 0);
         gst_buffer_unref (cache_buf);
         break;
       } else {
-        GST_BUFFER_SIZE (cache_buf) = bytes_read;
-
+        gst_buffer_unmap (cache_buf, data, bytes_read);
         gst_adapter_push (enc->multipass_cache_adapter, cache_buf);
       }
     }
@@ -1078,11 +1063,13 @@ theora_enc_read_multipass_cache (GstTheoraEnc * enc)
     bytes_read =
         MIN (gst_adapter_available (enc->multipass_cache_adapter), 512);
 
-    cache_data = gst_adapter_peek (enc->multipass_cache_adapter, bytes_read);
+    cache_data = gst_adapter_map (enc->multipass_cache_adapter, bytes_read);
 
     bytes_consumed =
         th_encode_ctl (enc->encoder, TH_ENCCTL_2PASS_IN, (guint8 *) cache_data,
         bytes_read);
+    gst_adapter_unmap (enc->multipass_cache_adapter, 0);
+
     done = bytes_consumed <= 0;
     if (bytes_consumed > 0)
       gst_adapter_flush (enc->multipass_cache_adapter, bytes_consumed);
@@ -1151,8 +1138,11 @@ theora_enc_encode_and_push (GstTheoraEnc * enc, ogg_packet op,
   GstFlowReturn ret;
   th_ycbcr_buffer ycbcr;
   gint res;
+  guint8 *data;
+  gsize size;
 
-  theora_enc_init_buffer (ycbcr, &enc->info, GST_BUFFER_DATA (buffer));
+  data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ);
+  theora_enc_init_buffer (ycbcr, &enc->info, data);
 
   if (theora_enc_is_discontinuous (enc, running_time, duration)) {
     theora_enc_reset (enc);
@@ -1198,6 +1188,9 @@ theora_enc_encode_and_push (GstTheoraEnc * enc, ogg_packet op,
     if (ret != GST_FLOW_OK)
       goto data_push;
   }
+
+done:
+  gst_buffer_unmap (buffer, data, size);
   gst_buffer_unref (buffer);
 
   return ret;
@@ -1205,18 +1198,18 @@ theora_enc_encode_and_push (GstTheoraEnc * enc, ogg_packet op,
   /* ERRORS */
 multipass_read_failed:
   {
-    gst_buffer_unref (buffer);
-    return ret;
+    GST_DEBUG_OBJECT (enc, "multipass read failed");
+    goto done;
   }
 multipass_write_failed:
   {
-    gst_buffer_unref (buffer);
-    return ret;
+    GST_DEBUG_OBJECT (enc, "multipass write failed");
+    goto done;
   }
 data_push:
   {
-    gst_buffer_unref (buffer);
-    return ret;
+    GST_DEBUG_OBJECT (enc, "error pushing buffer: %s", gst_flow_get_name (ret));
+    goto done;
   }
 }
 
@@ -1345,9 +1338,6 @@ theora_enc_chain (GstPad * pad, GstBuffer * buffer)
     caps = theora_set_header_on_caps (caps, buffers);
     GST_DEBUG ("here are the caps: %" GST_PTR_FORMAT, caps);
     gst_pad_set_caps (enc->srcpad, caps);
-
-    g_slist_foreach (buffers, (GFunc) gst_buffer_set_caps, caps);
-
     gst_caps_unref (caps);
 
     /* push out the header buffers */
@@ -1444,7 +1434,7 @@ theora_enc_change_state (GstElement * element, GstStateChange transition)
       break;
   }
 
-  ret = parent_class->change_state (element, transition);
+  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
 
   switch (transition) {
     case GST_STATE_CHANGE_PLAYING_TO_PAUSED: