Merge branch 'master' into 0.11
[platform/upstream/gstreamer.git] / ext / theora / gsttheoraenc.c
index e77f8e6..9c8d6a4 100644 (file)
@@ -243,28 +243,16 @@ GST_STATIC_PAD_TEMPLATE ("src",
     GST_STATIC_CAPS ("video/x-theora")
     );
 
-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);
-}
-
-GST_BOILERPLATE_FULL (GstTheoraEnc, gst_theora_enc, GstElement,
-    GST_TYPE_ELEMENT, _do_init);
+#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));
 
 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);
@@ -276,21 +264,6 @@ static gboolean theora_enc_write_multipass_cache (GstTheoraEnc * enc,
     gboolean begin, gboolean eos);
 
 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;
@@ -414,11 +387,20 @@ 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>");
+
   gstelement_class->change_state = theora_enc_change_state;
 }
 
 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");
@@ -596,7 +578,7 @@ theora_enc_get_supported_formats (void)
 }
 
 static GstCaps *
-theora_enc_sink_getcaps (GstPad * pad)
+theora_enc_sink_getcaps (GstPad * pad, GstCaps * filter)
 {
   GstCaps *caps;
   char *supported_formats, *caps_string;
@@ -617,6 +599,15 @@ theora_enc_sink_getcaps (GstPad * pad)
   g_free (supported_formats);
   GST_DEBUG ("Supported caps: %" GST_PTR_FORMAT, caps);
 
+  if (filter) {
+    GstCaps *intersection;
+
+    intersection =
+        gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
+    gst_caps_unref (caps);
+    caps = intersection;
+  }
+
   return caps;
 }
 
@@ -713,8 +704,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) =
@@ -751,7 +741,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);
 
@@ -839,18 +829,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;
@@ -1015,17 +996,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);
       }
     }
@@ -1035,11 +1020,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);
@@ -1217,13 +1204,10 @@ theora_enc_chain (GstPad * pad, GstBuffer * buffer)
     buffers = g_slist_reverse (buffers);
 
     /* mark buffers and put on caps */
-    caps = gst_pad_get_caps (enc->srcpad);
+    caps = gst_pad_get_caps (enc->srcpad, NULL);
     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 */
@@ -1247,8 +1231,11 @@ theora_enc_chain (GstPad * pad, GstBuffer * buffer)
   {
     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);
@@ -1263,6 +1250,7 @@ theora_enc_chain (GstPad * pad, GstBuffer * buffer)
     if (enc->multipass_cache_fd
         && enc->multipass_mode == MULTIPASS_MODE_SECOND_PASS) {
       if (!theora_enc_read_multipass_cache (enc)) {
+        gst_buffer_unmap (buffer, data, size);
         ret = GST_FLOW_ERROR;
         goto multipass_read_failed;
       }
@@ -1275,6 +1263,7 @@ theora_enc_chain (GstPad * pad, GstBuffer * buffer)
     if (enc->multipass_cache_fd
         && enc->multipass_mode == MULTIPASS_MODE_FIRST_PASS) {
       if (!theora_enc_write_multipass_cache (enc, FALSE, FALSE)) {
+        gst_buffer_unmap (buffer, data, size);
         ret = GST_FLOW_ERROR;
         goto multipass_write_failed;
       }
@@ -1291,9 +1280,12 @@ theora_enc_chain (GstPad * pad, GstBuffer * buffer)
           next_time - enc->next_ts);
 
       enc->next_ts = next_time;
-      if (ret != GST_FLOW_OK)
+      if (ret != GST_FLOW_OK) {
+        gst_buffer_unmap (buffer, data, size);
         goto data_push;
+      }
     }
+    gst_buffer_unmap (buffer, data, size);
     gst_buffer_unref (buffer);
   }
 
@@ -1385,7 +1377,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: