Merge branch 'master' into 0.11
[platform/upstream/gstreamer.git] / ext / ogg / gstoggmux.c
index 5341d6c..922409b 100644 (file)
@@ -27,7 +27,7 @@
  * <refsect2>
  * <title>Example pipelines</title>
  * |[
- * gst-launch v4l2src num-buffers=500 ! video/x-raw-yuv,width=320,height=240 ! ffmpegcolorspace ! theoraenc ! oggmux ! filesink location=video.ogg
+ * gst-launch v4l2src num-buffers=500 ! video/x-raw,width=320,height=240 ! videoconvert ! theoraenc ! oggmux ! filesink location=video.ogg
  * ]| Encodes a video stream captured from a v4l2-compatible camera to Ogg/Theora
  * (the encoding will stop automatically after 500 frames)
  * </refsect2>
@@ -100,26 +100,40 @@ static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
     GST_STATIC_CAPS ("application/ogg")
     );
 
-static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink_%d",
+static GstStaticPadTemplate video_sink_factory =
+    GST_STATIC_PAD_TEMPLATE ("video_%u",
     GST_PAD_SINK,
     GST_PAD_REQUEST,
     GST_STATIC_CAPS ("video/x-theora; "
-        "audio/x-vorbis; audio/x-flac; audio/x-speex; audio/x-celt; "
-        "application/x-ogm-video; application/x-ogm-audio; video/x-dirac; "
-        "video/x-smoke; video/x-vp8; text/x-cmml, encoded = (boolean) TRUE; "
-        "subtitle/x-kate; application/x-kate; audio/x-opus")
+        "application/x-ogm-video; video/x-dirac; "
+        "video/x-smoke; video/x-vp8; ")
+    );
+
+static GstStaticPadTemplate audio_sink_factory =
+    GST_STATIC_PAD_TEMPLATE ("audio_%u",
+    GST_PAD_SINK,
+    GST_PAD_REQUEST,
+    GST_STATIC_CAPS
+    ("audio/x-vorbis; audio/x-flac; audio/x-speex; audio/x-celt; "
+        "application/x-ogm-audio; audio/x-opus")
+    );
+
+static GstStaticPadTemplate subtitle_sink_factory =
+    GST_STATIC_PAD_TEMPLATE ("subtitle_%u",
+    GST_PAD_SINK,
+    GST_PAD_REQUEST,
+    GST_STATIC_CAPS ("text/x-cmml, encoded = (boolean) TRUE; "
+        "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 (GstCollectPads2 * pads, GstOggMux * ogg_mux);
-static gboolean gst_ogg_mux_handle_src_event (GstPad * pad, GstEvent * event);
+static gboolean gst_ogg_mux_handle_src_event (GstPad * pad, GstObject * parent,
+    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,
@@ -129,57 +143,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)
@@ -190,12 +157,24 @@ 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 (&video_sink_factory));
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&audio_sink_factory));
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&subtitle_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;
 
@@ -325,35 +304,29 @@ gst_ogg_mux_sinkconnect (GstPad * pad, GstPad * peer)
 }
 
 static gboolean
-gst_ogg_mux_sink_event (GstPad * pad, GstEvent * event)
+gst_ogg_mux_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
 {
-  GstOggMux *ogg_mux = GST_OGG_MUX (gst_pad_get_parent (pad));
+  GstOggMux *ogg_mux = GST_OGG_MUX (parent);
   GstOggPadData *ogg_pad = (GstOggPadData *) gst_pad_get_element_private (pad);
   gboolean ret = FALSE;
 
   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:{
@@ -378,9 +351,8 @@ gst_ogg_mux_sink_event (GstPad * pad, GstEvent * event)
 
   /* now GstCollectPads can take care of the rest, e.g. EOS */
   if (event != NULL)
-    ret = ogg_pad->collect_event (pad, event);
+    ret = ogg_pad->collect_event (pad, parent, event);
 
-  gst_object_unref (ogg_mux);
   return ret;
 }
 
@@ -414,7 +386,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;
@@ -430,12 +402,15 @@ gst_ogg_mux_request_new_pad (GstElement * element,
 
   klass = GST_ELEMENT_GET_CLASS (element);
 
-  if (templ != gst_element_class_get_pad_template (klass, "sink_%d"))
+  if (templ != gst_element_class_get_pad_template (klass, "video_%u") &&
+      templ != gst_element_class_get_pad_template (klass, "audio_%u") &&
+      templ != gst_element_class_get_pad_template (klass, "subtitle_%u")) {
     goto wrong_template;
+  }
 
   {
     guint32 serial;
-    gchar *name;
+    gchar *name = NULL;
 
     if (req_name == NULL || strlen (req_name) < 6) {
       /* no name given when requesting the pad, use random serial number */
@@ -454,7 +429,15 @@ gst_ogg_mux_request_new_pad (GstElement * element,
     }
     /* create new pad with the name */
     GST_DEBUG_OBJECT (ogg_mux, "Creating new pad for serial %d", serial);
-    name = g_strdup_printf ("sink_%d", serial);
+
+    if (templ == gst_element_class_get_pad_template (klass, "video_%u")) {
+      name = g_strdup_printf ("video_%u", serial);
+    } else if (templ == gst_element_class_get_pad_template (klass, "audio_%u")) {
+      name = g_strdup_printf ("audio_%u", serial);
+    } else if (templ == gst_element_class_get_pad_template (klass,
+            "subtitle_%u")) {
+      name = g_strdup_printf ("subtitle_%u", serial);
+    }
     newpad = gst_pad_new_from_template (templ, name);
     g_free (name);
 
@@ -529,7 +512,8 @@ gst_ogg_mux_release_pad (GstElement * element, GstPad * pad)
 
 /* handle events */
 static gboolean
-gst_ogg_mux_handle_src_event (GstPad * pad, GstEvent * event)
+gst_ogg_mux_handle_src_event (GstPad * pad, GstObject * parent,
+    GstEvent * event)
 {
   GstEventType type;
 
@@ -543,7 +527,7 @@ gst_ogg_mux_handle_src_event (GstPad * pad, GstEvent * event)
       break;
   }
 
-  return gst_pad_event_default (pad, event);
+  return gst_pad_event_default (pad, parent, event);
 }
 
 static GstBuffer *
@@ -553,9 +537,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
@@ -575,11 +558,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. */
@@ -591,11 +572,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);
 }
 
@@ -810,9 +786,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);
@@ -831,9 +808,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)) {
@@ -963,19 +941,22 @@ gst_ogg_mux_queue_pads (GstOggMux * ogg_mux, gboolean * popped)
           /* 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 */
@@ -983,11 +964,13 @@ gst_ogg_mux_queue_pads (GstOggMux * ogg_mux, gboolean * popped)
             }
             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)
@@ -995,6 +978,8 @@ gst_ogg_mux_queue_pads (GstOggMux * ogg_mux, gboolean * popped)
           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");
@@ -1058,7 +1043,7 @@ gst_ogg_mux_get_headers (GstOggPadData * pad)
 
   GST_LOG_OBJECT (thepad, "getting headers");
 
-  caps = gst_pad_get_negotiated_caps (thepad);
+  caps = gst_pad_get_current_caps (thepad);
   if (caps != NULL) {
     const GValue *streamheader;
 
@@ -1124,7 +1109,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 %" G_GSIZE_FORMAT,
+        gst_buffer_get_size (buf));
     GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_IN_CAPS);
 
     g_value_init (&value, GST_TYPE_BUFFER);
@@ -1142,10 +1128,8 @@ gst_ogg_mux_set_header_on_caps (GstCaps * caps, GList * buffers)
 
 static void
 gst_ogg_mux_create_header_packet_with_flags (ogg_packet * packet,
-    GstBuffer * buf, gboolean bos, gboolean eos)
+    gboolean bos, gboolean eos)
 {
-  packet->packet = GST_BUFFER_DATA (buf);
-  packet->bytes = GST_BUFFER_SIZE (buf);
   packet->granulepos = 0;
   /* mark BOS and packet number */
   packet->b_o_s = bos;
@@ -1154,11 +1138,9 @@ gst_ogg_mux_create_header_packet_with_flags (ogg_packet * packet,
 }
 
 static void
-gst_ogg_mux_create_header_packet (ogg_packet * packet, GstBuffer * buf,
-    GstOggPadData * pad)
+gst_ogg_mux_create_header_packet (ogg_packet * packet, GstOggPadData * pad)
 {
-  gst_ogg_mux_create_header_packet_with_flags (packet, buf, pad->packetno == 0,
-      0);
+  gst_ogg_mux_create_header_packet_with_flags (packet, pad->packetno == 0, 0);
   packet->packetno = pad->packetno++;
 }
 
@@ -1167,7 +1149,11 @@ gst_ogg_mux_submit_skeleton_header_packet (GstOggMux * mux,
     ogg_stream_state * os, GstBuffer * buf, gboolean bos, gboolean eos)
 {
   ogg_packet packet;
-  gst_ogg_mux_create_header_packet_with_flags (&packet, buf, bos, eos);
+  gsize size;
+
+  packet.packet = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+  packet.bytes = size;
+  gst_ogg_mux_create_header_packet_with_flags (&packet, bos, eos);
   ogg_stream_packetin (os, &packet);
   gst_buffer_unref (buf);
 }
@@ -1180,8 +1166,7 @@ gst_ogg_mux_make_fishead (GstOggMux * mux, ogg_stream_state * os)
 
   GST_DEBUG_OBJECT (mux, "Creating fishead");
 
-  fishead = gst_buffer_new_and_alloc (64);
-  gst_byte_writer_init_with_buffer (&bw, fishead, FALSE);
+  gst_byte_writer_init_with_size (&bw, 64, TRUE);
   gst_byte_writer_put_string_utf8 (&bw, "fishead");
   gst_byte_writer_put_int16_le (&bw, 3);        /* version major */
   gst_byte_writer_put_int16_le (&bw, 0);        /* version minor */
@@ -1190,7 +1175,8 @@ gst_ogg_mux_make_fishead (GstOggMux * mux, ogg_stream_state * os)
   gst_byte_writer_put_int64_le (&bw, 0);        /* base time numerator */
   gst_byte_writer_put_int64_le (&bw, 1000);     /* ...and denominator */
   gst_byte_writer_fill (&bw, ' ', 20);  /* UTC time */
-  g_assert (gst_byte_writer_get_pos (&bw) == GST_BUFFER_SIZE (fishead));
+  g_assert (gst_byte_writer_get_pos (&bw) == 64);
+  fishead = gst_byte_writer_reset_and_get_buffer (&bw);
   gst_ogg_mux_submit_skeleton_header_packet (mux, os, fishead, 1, 0);
 }
 
@@ -1357,10 +1343,11 @@ gst_ogg_mux_send_headers (GstOggMux * mux)
     GstCaps *caps;
     GstStructure *structure;
     GstBuffer *hbuf;
+    gsize size;
 
     pad = (GstOggPadData *) walk->data;
     thepad = pad->collect.pad;
-    caps = gst_pad_get_negotiated_caps (thepad);
+    caps = gst_pad_get_current_caps (thepad);
     structure = gst_caps_get_structure (caps, 0);
 
     walk = walk->next;
@@ -1385,10 +1372,15 @@ gst_ogg_mux_send_headers (GstOggMux * mux)
     }
 
     /* create a packet from the buffer */
-    gst_ogg_mux_create_header_packet (&packet, buf, pad);
+    packet.packet = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+    packet.bytes = size;
+
+    gst_ogg_mux_create_header_packet (&packet, pad);
 
     /* 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");
@@ -1448,14 +1440,20 @@ gst_ogg_mux_send_headers (GstOggMux * mux)
     while (hwalk) {
       GstBuffer *buf = GST_BUFFER (hwalk->data);
       ogg_packet packet;
+      ogg_page page;
+      gsize size;
 
       hwalk = hwalk->next;
 
       /* create a packet from the buffer */
-      gst_ogg_mux_create_header_packet (&packet, buf, pad);
+      packet.packet = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+      packet.bytes = size;
+
+      gst_ogg_mux_create_header_packet (&packet, pad);
 
       /* 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 */
@@ -1501,7 +1499,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_query_caps (mux->srcpad, NULL);
   if (caps) {
     caps = gst_ogg_mux_set_header_on_caps (caps, hbufs);
     gst_pad_set_caps (mux->srcpad, caps);
@@ -1646,6 +1644,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");
 
@@ -1669,8 +1668,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;
@@ -1760,6 +1759,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);
@@ -1916,7 +1916,7 @@ gst_ogg_mux_collected (GstCollectPads2 * pads, GstOggMux * ogg_mux)
 
   if (best->eos && all_pads_eos (pads)) {
     gst_pad_push_event (ogg_mux->srcpad, gst_event_new_eos ());
-    return GST_FLOW_UNEXPECTED;
+    return GST_FLOW_EOS;
   }
 
   return ret;