Merge branch 'master' into 0.11
[platform/upstream/gstreamer.git] / ext / ogg / gstoggmux.c
index b8815a1..b5ab6ef 100644 (file)
@@ -107,16 +107,13 @@ static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink_%d",
         "subtitle/x-kate; application/x-kate")
     );
 
-static void gst_ogg_mux_base_init (gpointer g_class);
-static void gst_ogg_mux_class_init (GstOggMuxClass * klass);
-static void gst_ogg_mux_init (GstOggMux * ogg_mux);
 static void gst_ogg_mux_finalize (GObject * object);
 
 static GstFlowReturn
 gst_ogg_mux_collected (GstCollectPads * pads, GstOggMux * ogg_mux);
 static gboolean gst_ogg_mux_handle_src_event (GstPad * pad, GstEvent * event);
 static GstPad *gst_ogg_mux_request_new_pad (GstElement * element,
-    GstPadTemplate * templ, const gchar * name);
+    GstPadTemplate * templ, const gchar * name, const GstCaps * caps);
 static void gst_ogg_mux_release_pad (GstElement * element, GstPad * pad);
 
 static void gst_ogg_mux_set_property (GObject * object,
@@ -126,57 +123,10 @@ static void gst_ogg_mux_get_property (GObject * object,
 static GstStateChangeReturn gst_ogg_mux_change_state (GstElement * element,
     GstStateChange transition);
 
-static GstElementClass *parent_class = NULL;
-
 /*static guint gst_ogg_mux_signals[LAST_SIGNAL] = { 0 }; */
-
-GType
-gst_ogg_mux_get_type (void)
-{
-  static GType ogg_mux_type = 0;
-
-  if (G_UNLIKELY (ogg_mux_type == 0)) {
-    static const GTypeInfo ogg_mux_info = {
-      sizeof (GstOggMuxClass),
-      gst_ogg_mux_base_init,
-      NULL,
-      (GClassInitFunc) gst_ogg_mux_class_init,
-      NULL,
-      NULL,
-      sizeof (GstOggMux),
-      0,
-      (GInstanceInitFunc) gst_ogg_mux_init,
-    };
-    static const GInterfaceInfo preset_info = {
-      NULL,
-      NULL,
-      NULL
-    };
-
-    ogg_mux_type =
-        g_type_register_static (GST_TYPE_ELEMENT, "GstOggMux", &ogg_mux_info,
-        0);
-
-    g_type_add_interface_static (ogg_mux_type, GST_TYPE_PRESET, &preset_info);
-  }
-  return ogg_mux_type;
-}
-
-static void
-gst_ogg_mux_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 (&src_factory));
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&sink_factory));
-
-  gst_element_class_set_details_simple (element_class,
-      "Ogg muxer", "Codec/Muxer",
-      "mux ogg streams (info about ogg: http://xiph.org)",
-      "Wim Taymans <wim@fluendo.com>");
-}
+#define gst_ogg_mux_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstOggMux, gst_ogg_mux, GST_TYPE_ELEMENT,
+    G_IMPLEMENT_INTERFACE (GST_TYPE_PRESET, NULL));
 
 static void
 gst_ogg_mux_class_init (GstOggMuxClass * klass)
@@ -187,12 +137,20 @@ gst_ogg_mux_class_init (GstOggMuxClass * klass)
   gobject_class = (GObjectClass *) klass;
   gstelement_class = (GstElementClass *) klass;
 
-  parent_class = g_type_class_peek_parent (klass);
-
   gobject_class->finalize = gst_ogg_mux_finalize;
   gobject_class->get_property = gst_ogg_mux_get_property;
   gobject_class->set_property = gst_ogg_mux_set_property;
 
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&src_factory));
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&sink_factory));
+
+  gst_element_class_set_details_simple (gstelement_class,
+      "Ogg muxer", "Codec/Muxer",
+      "mux ogg streams (info about ogg: http://xiph.org)",
+      "Wim Taymans <wim@fluendo.com>");
+
   gstelement_class->request_new_pad = gst_ogg_mux_request_new_pad;
   gstelement_class->release_pad = gst_ogg_mux_release_pad;
 
@@ -326,26 +284,20 @@ gst_ogg_mux_sink_event (GstPad * pad, GstEvent * event)
   GST_DEBUG_OBJECT (pad, "Got %s event", GST_EVENT_TYPE_NAME (event));
 
   switch (GST_EVENT_TYPE (event)) {
-    case GST_EVENT_NEWSEGMENT:{
-      gboolean update;
-      gdouble rate;
-      gdouble applied_rate;
-      GstFormat format;
-      gint64 start, stop, position;
+    case GST_EVENT_SEGMENT:
+    {
+      const GstSegment *segment;
 
-      gst_event_parse_new_segment_full (event, &update, &rate,
-          &applied_rate, &format, &start, &stop, &position);
+      gst_event_parse_segment (event, &segment);
 
       /* We don't support non time NEWSEGMENT events */
-      if (format != GST_FORMAT_TIME) {
+      if (segment->format != GST_FORMAT_TIME) {
         gst_event_unref (event);
         event = NULL;
         break;
       }
 
-      gst_segment_set_newsegment_full (&ogg_pad->segment, update, rate,
-          applied_rate, format, start, stop, position);
-
+      gst_segment_copy_into (segment, &ogg_pad->segment);
       break;
     }
     case GST_EVENT_FLUSH_STOP:{
@@ -394,7 +346,7 @@ gst_ogg_mux_generate_serialno (GstOggMux * ogg_mux)
 
 static GstPad *
 gst_ogg_mux_request_new_pad (GstElement * element,
-    GstPadTemplate * templ, const gchar * req_name)
+    GstPadTemplate * templ, const gchar * req_name, const GstCaps * caps)
 {
   GstOggMux *ogg_mux;
   GstPad *newpad;
@@ -525,9 +477,8 @@ gst_ogg_mux_buffer_from_page (GstOggMux * mux, ogg_page * page, gboolean delta)
 
   /* allocate space for header and body */
   buffer = gst_buffer_new_and_alloc (page->header_len + page->body_len);
-  memcpy (GST_BUFFER_DATA (buffer), page->header, page->header_len);
-  memcpy (GST_BUFFER_DATA (buffer) + page->header_len,
-      page->body, page->body_len);
+  gst_buffer_fill (buffer, 0, page->header, page->header_len);
+  gst_buffer_fill (buffer, page->header_len, page->body, page->body_len);
 
   /* Here we set granulepos as our OFFSET_END to give easy direct access to
    * this value later. Before we push it, we reset this to OFFSET + SIZE
@@ -547,11 +498,9 @@ static GstFlowReturn
 gst_ogg_mux_push_buffer (GstOggMux * mux, GstBuffer * buffer,
     GstOggPadData * oggpad)
 {
-  GstCaps *caps;
-
   /* fix up OFFSET and OFFSET_END again */
   GST_BUFFER_OFFSET (buffer) = mux->offset;
-  mux->offset += GST_BUFFER_SIZE (buffer);
+  mux->offset += gst_buffer_get_size (buffer);
   GST_BUFFER_OFFSET_END (buffer) = mux->offset;
 
   /* Ensure we have monotonically increasing timestamps in the output. */
@@ -563,11 +512,6 @@ gst_ogg_mux_push_buffer (GstOggMux * mux, GstBuffer * buffer,
       mux->last_ts = run_time;
   }
 
-  caps = gst_pad_get_negotiated_caps (mux->srcpad);
-  gst_buffer_set_caps (buffer, caps);
-  if (caps)
-    gst_caps_unref (caps);
-
   return gst_pad_push (mux->srcpad, buffer);
 }
 
@@ -788,9 +732,10 @@ gst_ogg_mux_decorate_buffer (GstOggMux * ogg_mux, GstOggPadData * pad,
   GstClockTime next_time;
   GstClockTimeDiff diff;
   ogg_packet packet;
+  gsize size;
 
   /* ensure messing with metadata is ok */
-  buf = gst_buffer_make_metadata_writable (buf);
+  buf = gst_buffer_make_writable (buf);
 
   /* convert time to running time, so we need no longer bother about that */
   time = GST_BUFFER_TIMESTAMP (buf);
@@ -809,9 +754,10 @@ gst_ogg_mux_decorate_buffer (GstOggMux * ogg_mux, GstOggPadData * pad,
       pad->map.granulerate_n <= 0 || pad->map.granulerate_d <= 0)
     goto no_granule;
 
-  packet.packet = GST_BUFFER_DATA (buf);
-  packet.bytes = GST_BUFFER_SIZE (buf);
+  packet.packet = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+  packet.bytes = size;
   duration = gst_ogg_stream_get_packet_duration (&pad->map, &packet);
+  gst_buffer_unmap (buf, packet.packet, size);
 
   /* give up if no duration can be determined, relying on upstream */
   if (G_UNLIKELY (duration < 0)) {
@@ -945,19 +891,22 @@ gst_ogg_mux_queue_pads (GstOggMux * ogg_mux)
           /* and we have one */
           ogg_packet packet;
           gboolean is_header;
+          gsize size;
 
-          packet.packet = GST_BUFFER_DATA (buf);
-          packet.bytes = GST_BUFFER_SIZE (buf);
+          packet.packet = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+          packet.bytes = size;
 
           /* if we're not yet in data mode, ensure we're setup on the first packet */
           if (!pad->have_type) {
+            GstCaps *caps;
+
             /* Use headers in caps, if any; this will allow us to be resilient
              * to starting streams on the fly, and some streams (like VP8
              * at least) do not send headers packets, as other muxers don't
              * expect/need them. */
+            caps = gst_pad_get_current_caps (GST_PAD_CAST (data->pad));
             pad->have_type =
-                gst_ogg_stream_setup_map_from_caps_headers (&pad->map,
-                GST_BUFFER_CAPS (buf));
+                gst_ogg_stream_setup_map_from_caps_headers (&pad->map, caps);
 
             if (!pad->have_type) {
               /* fallback on the packet */
@@ -965,11 +914,13 @@ gst_ogg_mux_queue_pads (GstOggMux * ogg_mux)
             }
             if (!pad->have_type) {
               GST_ERROR_OBJECT (pad, "mapper didn't recognise input stream "
-                  "(pad caps: %" GST_PTR_FORMAT ")", GST_PAD_CAPS (pad));
+                  "(pad caps: %" GST_PTR_FORMAT ")", caps);
             } else {
               GST_DEBUG_OBJECT (pad, "caps detected: %" GST_PTR_FORMAT,
                   pad->map.caps);
             }
+            if (caps)
+              gst_caps_unref (caps);
           }
 
           if (pad->have_type)
@@ -977,6 +928,8 @@ gst_ogg_mux_queue_pads (GstOggMux * ogg_mux)
           else                  /* fallback (FIXME 0.11: remove IN_CAPS hack) */
             is_header = GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_IN_CAPS);
 
+          gst_buffer_unmap (buf, packet.packet, size);
+
           if (is_header) {
             GST_DEBUG_OBJECT (ogg_mux,
                 "got header buffer in control state, ignoring");
@@ -1139,7 +1092,8 @@ gst_ogg_mux_set_header_on_caps (GstCaps * caps, GList * buffers)
     walk = walk->next;
 
     /* mark buffer */
-    GST_LOG ("Setting IN_CAPS on buffer of length %d", GST_BUFFER_SIZE (buf));
+    GST_LOG ("Setting IN_CAPS on buffer of length %d",
+        gst_buffer_get_size (buf));
     GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_IN_CAPS);
 
     g_value_init (&value, GST_TYPE_BUFFER);
@@ -1207,6 +1161,7 @@ gst_ogg_mux_send_headers (GstOggMux * mux)
     GstCaps *caps;
     GstStructure *structure;
     GstBuffer *hbuf;
+    gsize size;
 
     pad = (GstOggPadData *) walk->data;
     thepad = pad->collect.pad;
@@ -1238,8 +1193,8 @@ gst_ogg_mux_send_headers (GstOggMux * mux)
     }
 
     /* create a packet from the buffer */
-    packet.packet = GST_BUFFER_DATA (buf);
-    packet.bytes = GST_BUFFER_SIZE (buf);
+    packet.packet = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+    packet.bytes = size;
     packet.granulepos = GST_BUFFER_OFFSET_END (buf);
     if (packet.granulepos == -1)
       packet.granulepos = 0;
@@ -1251,6 +1206,8 @@ gst_ogg_mux_send_headers (GstOggMux * mux)
 
     /* swap the packet in */
     ogg_stream_packetin (&pad->map.stream, &packet);
+
+    gst_buffer_unmap (buf, packet.packet, size);
     gst_buffer_unref (buf);
 
     GST_LOG_OBJECT (thepad, "flushing out BOS page");
@@ -1303,12 +1260,13 @@ gst_ogg_mux_send_headers (GstOggMux * mux)
       GstBuffer *buf = GST_BUFFER (hwalk->data);
       ogg_packet packet;
       ogg_page page;
+      gsize size;
 
       hwalk = hwalk->next;
 
       /* create a packet from the buffer */
-      packet.packet = GST_BUFFER_DATA (buf);
-      packet.bytes = GST_BUFFER_SIZE (buf);
+      packet.packet = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+      packet.bytes = size;
       packet.granulepos = GST_BUFFER_OFFSET_END (buf);
       if (packet.granulepos == -1)
         packet.granulepos = 0;
@@ -1320,6 +1278,7 @@ gst_ogg_mux_send_headers (GstOggMux * mux)
 
       /* swap the packet in */
       ogg_stream_packetin (&pad->map.stream, &packet);
+      gst_buffer_unmap (buf, packet.packet, size);
       gst_buffer_unref (buf);
 
       /* if last header, flush page */
@@ -1350,7 +1309,7 @@ gst_ogg_mux_send_headers (GstOggMux * mux)
   /* hbufs holds all buffers for the headers now */
 
   /* create caps with the buffers */
-  caps = gst_pad_get_caps (mux->srcpad);
+  caps = gst_pad_get_caps (mux->srcpad, NULL);
   if (caps) {
     caps = gst_ogg_mux_set_header_on_caps (caps, hbufs);
     gst_pad_set_caps (mux->srcpad, caps);
@@ -1476,6 +1435,7 @@ gst_ogg_mux_process_best_pad (GstOggMux * ogg_mux, GstOggPadData * best)
     GstOggPadData *pad = ogg_mux->pulling;
     gint64 duration;
     gboolean force_flush;
+    gsize size;
 
     GST_LOG_OBJECT (ogg_mux->pulling->collect.pad, "pulling from pad");
 
@@ -1499,8 +1459,8 @@ gst_ogg_mux_process_best_pad (GstOggMux * ogg_mux, GstOggPadData * best)
           GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));
     }
     /* create a packet from the buffer */
-    packet.packet = GST_BUFFER_DATA (buf);
-    packet.bytes = GST_BUFFER_SIZE (buf);
+    packet.packet = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+    packet.bytes = size;
     packet.granulepos = GST_BUFFER_OFFSET_END (buf);
     if (packet.granulepos == -1)
       packet.granulepos = 0;
@@ -1589,6 +1549,7 @@ gst_ogg_mux_process_best_pad (GstOggMux * ogg_mux, GstOggPadData * best)
       GST_DEBUG_OBJECT (pad->collect.pad, "swapping in BOS packet");
 
     ogg_stream_packetin (&pad->map.stream, &packet);
+    gst_buffer_unmap (buf, packet.packet, size);
     pad->data_pushed = TRUE;
 
     gp_time = GST_BUFFER_OFFSET (pad->buffer);