kate: port Kate subtitles to 1.0
authorBrendan Long <b.long@cablelabs.com>
Mon, 1 Apr 2013 18:47:13 +0000 (12:47 -0600)
committerTim-Philipp Müller <tim@centricular.net>
Sun, 14 Apr 2013 23:53:48 +0000 (00:53 +0100)
https://bugzilla.gnome.org/show_bug.cgi?id=697071

configure.ac
ext/kate/gstkatedec.c
ext/kate/gstkateenc.c
ext/kate/gstkateparse.c
ext/kate/gstkatespu.c
ext/kate/gstkatetag.c
ext/kate/gstkateutil.c
ext/kate/gstkateutil.h

index 2c61246..3574f9b 100644 (file)
@@ -318,7 +318,7 @@ GST_PLUGINS_NONPORTED=" aiff \
  cdxaparse \
  dccp faceoverlay \
  hdvparse ivfparse jp2kdecimator \
kate librfb \
+ librfb \
  mve mythtv nsf nuvdemux \
  patchdetect real \
  sdi stereo tta \
index 4a775aa..98790b2 100644 (file)
@@ -114,7 +114,8 @@ static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
 static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
     GST_PAD_SRC,
     GST_PAD_ALWAYS,
-    GST_STATIC_CAPS ("text/plain; text/x-pango-markup; " GST_KATE_SPU_MIME_TYPE)
+    GST_STATIC_CAPS ("text/x-raw, format={ pango-markup, utf8 }; "
+        GST_KATE_SPU_MIME_TYPE)
     );
 
 #define gst_kate_dec_parent_class parent_class
@@ -125,13 +126,18 @@ static void gst_kate_dec_set_property (GObject * object, guint prop_id,
 static void gst_kate_dec_get_property (GObject * object, guint prop_id,
     GValue * value, GParamSpec * pspec);
 
-static GstFlowReturn gst_kate_dec_chain (GstPad * pad, GstBuffer * buf);
+static GstFlowReturn gst_kate_dec_chain (GstPad * pad, GstObject * parent,
+    GstBuffer * buf);
 static GstStateChangeReturn gst_kate_dec_change_state (GstElement * element,
     GstStateChange transition);
-static gboolean gst_kate_dec_sink_query (GstPad * pad, GstQuery * query);
-static gboolean gst_kate_dec_sink_event (GstPad * pad, GstEvent * event);
-static gboolean gst_kate_dec_sink_handle_event (GstPad * pad, GstEvent * event);
-static GstCaps *gst_kate_dec_src_get_caps (GstPad * pad, GstCaps * filter);
+static gboolean gst_kate_dec_sink_query (GstPad * pad, GstObject * parent,
+    GstQuery * query);
+static gboolean gst_kate_dec_sink_event (GstPad * pad, GstObject * parent,
+    GstEvent * event);
+static gboolean gst_kate_dec_sink_handle_event (GstPad * pad,
+    GstObject * parent, GstEvent * event);
+static gboolean gst_kate_dec_src_query (GstPad * pad, GstObject * parent,
+    GstQuery * query);
 
 /* initialize the plugin's class */
 static void
@@ -190,8 +196,8 @@ gst_kate_dec_init (GstKateDec * dec)
   gst_element_add_pad (GST_ELEMENT (dec), dec->sinkpad);
 
   dec->srcpad = gst_pad_new_from_static_template (&src_factory, "src");
-  gst_pad_set_getcaps_function (dec->srcpad,
-      GST_DEBUG_FUNCPTR (gst_kate_dec_src_get_caps));
+  gst_pad_set_query_function (dec->srcpad,
+      GST_DEBUG_FUNCPTR (gst_kate_dec_src_query));
   gst_element_add_pad (GST_ELEMENT (dec), dec->srcpad);
 
   gst_kate_util_decode_base_init (&dec->decoder, TRUE);
@@ -237,9 +243,9 @@ gst_kate_dec_get_property (GObject * object, guint prop_id,
  */
 
 static GstFlowReturn
-gst_kate_dec_chain (GstPad * pad, GstBuffer * buf)
+gst_kate_dec_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
 {
-  GstKateDec *kd = GST_KATE_DEC (gst_pad_get_parent (pad));
+  GstKateDec *kd = GST_KATE_DEC (parent);
   const kate_event *ev = NULL;
   GstFlowReturn rflow = GST_FLOW_OK;
 
@@ -254,7 +260,6 @@ gst_kate_dec_chain (GstPad * pad, GstBuffer * buf)
       GST_ELEMENT_CAST (kd), pad, buf, kd->srcpad, kd->srcpad, &kd->src_caps,
       &ev);
   if (G_UNLIKELY (rflow != GST_FLOW_OK)) {
-    gst_object_unref (kd);
     gst_buffer_unref (buf);
     return rflow;
   }
@@ -288,8 +293,14 @@ gst_kate_dec_chain (GstPad * pad, GstBuffer * buf)
         GST_DEBUG_OBJECT (kd, "kate event: %s, escaped %s", ev->text, escaped);
         buffer = gst_buffer_new_and_alloc (len + 1);
         if (G_LIKELY (buffer)) {
-          const char *mime = plain ? "text/plain" : "text/x-pango-markup";
-          GstCaps *caps = gst_caps_new_empty_simple (mime);
+          GstCaps *caps;
+          if (plain) {
+            caps = gst_caps_new_empty_simple ("text/x-raw");
+          } else {
+            caps = gst_caps_new_simple ("text/x-raw", "format", G_TYPE_STRING,
+                "pango-markup, utf8", NULL);
+          }
+          gst_pad_push_event (kd->srcpad, gst_event_new_caps (caps));
           gst_caps_unref (caps);
           /* allocate and copy the NULs, but don't include them in passed size */
           gst_buffer_fill (buffer, 0, escaped, len + 1);
@@ -343,7 +354,6 @@ gst_kate_dec_chain (GstPad * pad, GstBuffer * buf)
   }
 
 not_in_seg:
-  gst_object_unref (kd);
   gst_buffer_unref (buf);
   return rflow;
 }
@@ -365,42 +375,39 @@ gst_kate_dec_change_state (GstElement * element, GstStateChange transition)
 }
 
 gboolean
-gst_kate_dec_sink_query (GstPad * pad, GstQuery * query)
+gst_kate_dec_sink_query (GstPad * pad, GstObject * parent, GstQuery * query)
 {
-  GstKateDec *kd = GST_KATE_DEC (gst_pad_get_parent (pad));
+  GstKateDec *kd = GST_KATE_DEC (parent);
   gboolean res =
       gst_kate_decoder_base_sink_query (&kd->decoder, GST_ELEMENT_CAST (kd),
-      pad, query);
-  gst_object_unref (kd);
+      pad, parent, query);
   return res;
 }
 
 static gboolean
-gst_kate_dec_sink_event (GstPad * pad, GstEvent * event)
+gst_kate_dec_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
 {
-  GstKateDec *kd = (GstKateDec *) (gst_object_get_parent (GST_OBJECT (pad)));
+  GstKateDec *kd = GST_KATE_DEC (parent);
   gboolean res = TRUE;
 
   GST_LOG_OBJECT (pad, "Event on sink pad: %s", GST_EVENT_TYPE_NAME (event));
 
   /* Delay events till we've set caps */
   if (gst_kate_util_decoder_base_queue_event (&kd->decoder, event,
-          &gst_kate_dec_sink_handle_event, pad)) {
-    gst_object_unref (kd);
+          &gst_kate_dec_sink_handle_event, parent, pad)) {
     return TRUE;
   }
 
-  res = gst_kate_dec_sink_handle_event (pad, event);
-
-  gst_object_unref (kd);
+  res = gst_kate_dec_sink_handle_event (pad, parent, event);
 
   return res;
 }
 
 static gboolean
-gst_kate_dec_sink_handle_event (GstPad * pad, GstEvent * event)
+gst_kate_dec_sink_handle_event (GstPad * pad, GstObject * parent,
+    GstEvent * event)
 {
-  GstKateDec *kd = (GstKateDec *) (gst_object_get_parent (GST_OBJECT (pad)));
+  GstKateDec *kd = GST_KATE_DEC (parent);
   gboolean res = TRUE;
 
   GST_LOG_OBJECT (pad, "Handling event on sink pad: %s",
@@ -409,45 +416,57 @@ gst_kate_dec_sink_handle_event (GstPad * pad, GstEvent * event)
   switch (GST_EVENT_TYPE (event)) {
     case GST_EVENT_SEGMENT:
       gst_kate_util_decoder_base_segment_event (&kd->decoder, event);
-      res = gst_pad_event_default (pad, event);
+      res = gst_pad_event_default (pad, parent, event);
       break;
 
     case GST_EVENT_FLUSH_START:
       gst_kate_util_decoder_base_set_flushing (&kd->decoder, TRUE);
-      res = gst_pad_event_default (pad, event);
+      res = gst_pad_event_default (pad, parent, event);
       break;
 
     case GST_EVENT_FLUSH_STOP:
       gst_kate_util_decoder_base_set_flushing (&kd->decoder, FALSE);
-      res = gst_pad_event_default (pad, event);
+      res = gst_pad_event_default (pad, parent, event);
       break;
 
     default:
-      res = gst_pad_event_default (pad, event);
+      res = gst_pad_event_default (pad, parent, event);
       break;
   }
 
-  gst_object_unref (kd);
-
   return res;
 }
 
-static GstCaps *
-gst_kate_dec_src_get_caps (GstPad * pad, GstCaps * filter)
+static gboolean
+gst_kate_dec_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
 {
-  GstKateDec *kd = (GstKateDec *) (gst_object_get_parent (GST_OBJECT (pad)));
-  GstCaps *caps;
-
-  if (kd->src_caps) {
-    GST_DEBUG_OBJECT (kd, "We have src caps %" GST_PTR_FORMAT, kd->src_caps);
-    caps = kd->src_caps;
-  } else {
-    GST_DEBUG_OBJECT (kd, "We have no src caps, using template caps");
-    caps = gst_static_pad_template_get_caps (&src_factory);
-  }
+  GstKateDec *kd = GST_KATE_DEC (parent);
+  gboolean res = TRUE;
+
+  GST_LOG_OBJECT (pad, "Handling query on src pad: %s",
+      GST_QUERY_TYPE_NAME (query));
 
-  caps = gst_caps_copy (caps);
+  switch (GST_QUERY_TYPE (query)) {
+    case GST_QUERY_CAPS:{
+      GstCaps *caps;
 
-  gst_object_unref (kd);
-  return caps;
+      if (kd->src_caps) {
+        GST_DEBUG_OBJECT (kd, "We have src caps %" GST_PTR_FORMAT,
+            kd->src_caps);
+        caps = gst_caps_copy (kd->src_caps);
+      } else {
+        GST_DEBUG_OBJECT (kd, "We have no src caps, using template caps");
+        caps = gst_static_pad_template_get_caps (&src_factory);
+      }
+
+      gst_query_set_caps_result (query, caps);
+      gst_caps_unref (caps);
+      break;
+    }
+    default:
+      res = gst_pad_query_default (pad, parent, query);
+      break;
+  }
+
+  return res;
 }
index 989388c..89500bd 100644 (file)
@@ -120,7 +120,8 @@ enum
 static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
     GST_PAD_SINK,
     GST_PAD_ALWAYS,
-    GST_STATIC_CAPS ("text/plain; text/x-pango-markup; " GST_KATE_SPU_MIME_TYPE)
+    GST_STATIC_CAPS ("text/x-raw, format={ pango-markup, utf8 }; "
+        GST_KATE_SPU_MIME_TYPE)
     );
 
 static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
@@ -136,12 +137,14 @@ static void gst_kate_enc_get_property (GObject * object, guint prop_id,
 static void gst_kate_enc_dispose (GObject * object);
 
 static gboolean gst_kate_enc_setcaps (GstPad * pad, GstCaps * caps);
-static GstFlowReturn gst_kate_enc_chain (GstPad * pad, GstBuffer * buf);
+static GstFlowReturn gst_kate_enc_chain (GstPad * pad, GstObject * parent,
+    GstBuffer * buf);
 static GstStateChangeReturn gst_kate_enc_change_state (GstElement * element,
     GstStateChange transition);
-static gboolean gst_kate_enc_sink_event (GstPad * pad, GstEvent * event);
-static const GstQueryType *gst_kate_enc_source_query_type (GstPad * pad);
-static gboolean gst_kate_enc_source_query (GstPad * pad, GstQuery * query);
+static gboolean gst_kate_enc_sink_event (GstPad * pad, GstObject * parent,
+    GstEvent * event);
+static gboolean gst_kate_enc_source_query (GstPad * pad, GstObject * parent,
+    GstQuery * query);
 
 #define gst_kate_enc_parent_class parent_class
 G_DEFINE_TYPE_WITH_CODE (GstKateEnc, gst_kate_enc, GST_TYPE_ELEMENT,
@@ -240,8 +243,6 @@ gst_kate_enc_init (GstKateEnc * ke)
   gst_element_add_pad (GST_ELEMENT (ke), ke->sinkpad);
 
   ke->srcpad = gst_pad_new_from_static_template (&src_factory, "src");
-  gst_pad_set_query_type_function (ke->srcpad,
-      GST_DEBUG_FUNCPTR (gst_kate_enc_source_query_type));
   gst_pad_set_query_function (ke->srcpad,
       GST_DEBUG_FUNCPTR (gst_kate_enc_source_query));
   gst_element_add_pad (GST_ELEMENT (ke), ke->srcpad);
@@ -520,8 +521,7 @@ gst_kate_enc_setcaps (GstPad * pad, GstCaps * caps)
   if (ke->category != NULL) {
     GstStructure *s = gst_caps_get_structure (caps, 0);
 
-    if (gst_structure_has_name (s, "text/plain") ||
-        gst_structure_has_name (s, "text/x-pango-markup")) {
+    if (gst_structure_has_name (s, "text/plain")) {
       if (strcmp (ke->category, "K-SPU") == 0 ||
           strcmp (ke->category, "spu-subtitles") == 0) {
         GST_ELEMENT_WARNING (ke, LIBRARY, SETTINGS, (NULL),
@@ -926,23 +926,22 @@ gst_kate_enc_chain_text (GstKateEnc * ke, GstBuffer * buf,
             gst_kate_util_get_error_message (ret)));
     rflow = GST_FLOW_ERROR;
   } else {
-    const char *text;
-    size_t text_len;
+    GstMapInfo info;
     gboolean need_unmap = TRUE;
     kate_float t0 = start / (double) GST_SECOND;
     kate_float t1 = stop / (double) GST_SECOND;
 
-    text = gst_buffer_map (buf, &text_len, NULL, GST_MAP_READ);
-    if (text == NULL) {
-      text = "";
-      text_len = 0;
+    if (!gst_buffer_map (buf, &info, GST_MAP_READ)) {
+      info.data = NULL;
+      info.size = 0;
       need_unmap = FALSE;
+      GST_WARNING_OBJECT (buf, "Failed to map buffer");
     }
 
     GST_LOG_OBJECT (ke, "Encoding text: %*.*s (%u bytes) from %f to %f",
-        (int) text_len, (int) text_len, GST_BUFFER_DATA (buf),
-        GST_BUFFER_SIZE (buf), t0, t1);
-    ret = kate_encode_text (&ke->k, t0, t1, text, text_len, &kp);
+        (int) info.size, (int) info.size, info.data, (int) info.size, t0, t1);
+    ret = kate_encode_text (&ke->k, t0, t1, (const char *) info.data, info.size,
+        &kp);
     if (G_UNLIKELY (ret < 0)) {
       GST_ELEMENT_ERROR (ke, STREAM, ENCODE, (NULL),
           ("Failed to encode text: %s", gst_kate_util_get_error_message (ret)));
@@ -951,7 +950,7 @@ gst_kate_enc_chain_text (GstKateEnc * ke, GstBuffer * buf,
       rflow = gst_kate_enc_chain_push_packet (ke, &kp, start, stop - start + 1);
     }
     if (need_unmap)
-      gst_buffer_unmap (buf, text, text_len);
+      gst_buffer_unmap (buf, &info);
   }
 
   return rflow;
@@ -961,9 +960,9 @@ gst_kate_enc_chain_text (GstKateEnc * ke, GstBuffer * buf,
  * this function does the actual processing
  */
 static GstFlowReturn
-gst_kate_enc_chain (GstPad * pad, GstBuffer * buf)
+gst_kate_enc_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
 {
-  GstKateEnc *ke = GST_KATE_ENC (gst_pad_get_parent (pad));
+  GstKateEnc *ke = GST_KATE_ENC (parent);
   GstFlowReturn rflow = GST_FLOW_OK;
   GstCaps *caps;
   const gchar *mime_type = NULL;
@@ -1007,9 +1006,6 @@ gst_kate_enc_chain (GstPad * pad, GstBuffer * buf)
   }
 
   gst_buffer_unref (buf);
-
-  gst_object_unref (ke);
-
   GST_LOG_OBJECT (ke, "Leaving chain function");
 
   return rflow;
@@ -1192,27 +1188,11 @@ gst_kate_enc_convert (GstPad * pad, GstFormat src_fmt, gint64 src_val,
   return res;
 }
 
-#if 1
-static const GstQueryType *
-gst_kate_enc_source_query_type (GstPad * pad)
-{
-  static const GstQueryType types[] = {
-    GST_QUERY_CONVERT,
-    0
-  };
-
-  return types;
-}
-#endif
-
 static gboolean
-gst_kate_enc_source_query (GstPad * pad, GstQuery * query)
+gst_kate_enc_source_query (GstPad * pad, GstObject * parent, GstQuery * query)
 {
-  GstKateEnc *ke;
   gboolean res = FALSE;
 
-  ke = GST_KATE_ENC (gst_pad_get_parent (pad));
-
   GST_DEBUG ("source query %d", GST_QUERY_TYPE (query));
 
   switch (GST_QUERY_TYPE (query)) {
@@ -1223,26 +1203,24 @@ gst_kate_enc_source_query (GstPad * pad, GstQuery * query)
 
       gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
       if (!gst_kate_enc_convert (pad, src_fmt, src_val, &dest_fmt, &dest_val)) {
-        return gst_pad_query_default (pad, query);
+        return gst_pad_query_default (pad, parent, query);
       }
       gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
       res = TRUE;
     }
       break;
     default:
-      res = gst_pad_query_default (pad, query);
+      res = gst_pad_query_default (pad, parent, query);
       break;
   }
 
-  gst_object_unref (ke);
-
   return res;
 }
 
 static gboolean
-gst_kate_enc_sink_event (GstPad * pad, GstEvent * event)
+gst_kate_enc_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
 {
-  GstKateEnc *ke = GST_KATE_ENC (gst_pad_get_parent (pad));
+  GstKateEnc *ke = GST_KATE_ENC (parent);
   const GstStructure *structure;
   gboolean ret;
 
@@ -1359,7 +1337,7 @@ gst_kate_enc_sink_event (GstPad * pad, GstEvent * event)
       } else {
         g_assert_not_reached ();
       }
-      ret = gst_pad_event_default (pad, event);
+      ret = gst_pad_event_default (pad, parent, event);
       break;
 
     case GST_EVENT_EOS:
@@ -1394,15 +1372,14 @@ gst_kate_enc_sink_event (GstPad * pad, GstEvent * event)
           }
         }
       }
-      ret = gst_pad_event_default (pad, event);
+      ret = gst_pad_event_default (pad, parent, event);
       break;
 
     default:
       GST_LOG_OBJECT (ke, "Got unhandled event");
-      ret = gst_pad_event_default (pad, event);
+      ret = gst_pad_event_default (pad, parent, event);
       break;
   }
 
-  gst_object_unref (ke);
   return ret;
 }
index b72f861..02e5895 100644 (file)
@@ -86,11 +86,14 @@ static GstStaticPadTemplate gst_kate_parse_src_factory =
 #define gst_kate_parse_parent_class parent_class
 G_DEFINE_TYPE (GstKateParse, gst_kate_parse, GST_TYPE_ELEMENT);
 
-static GstFlowReturn gst_kate_parse_chain (GstPad * pad, GstBuffer * buffer);
+static GstFlowReturn gst_kate_parse_chain (GstPad * pad, GstObject * parent,
+    GstBuffer * buffer);
 static GstStateChangeReturn gst_kate_parse_change_state (GstElement * element,
     GstStateChange transition);
-static gboolean gst_kate_parse_sink_event (GstPad * pad, GstEvent * event);
-static gboolean gst_kate_parse_src_query (GstPad * pad, GstQuery * query);
+static gboolean gst_kate_parse_sink_event (GstPad * pad, GstObject * parent,
+    GstEvent * event);
+static gboolean gst_kate_parse_src_query (GstPad * pad, GstObject * parent,
+    GstQuery * query);
 #if 0
 static gboolean gst_kate_parse_convert (GstPad * pad,
     GstFormat src_format, gint64 src_value,
@@ -144,7 +147,7 @@ gst_kate_parse_drain_event_queue (GstKateParse * parse)
     GstEvent *event;
 
     event = GST_EVENT_CAST (g_queue_pop_head (parse->event_queue));
-    gst_pad_event_default (parse->sinkpad, event);
+    gst_pad_event_default (parse->sinkpad, NULL, event);
   }
 }
 
@@ -180,19 +183,22 @@ gst_kate_parse_push_headers (GstKateParse * parse)
 
   headers = parse->streamheader;
   while (headers) {
-    guint8 *data;
-    gsize size;
+    GstMapInfo info;
 
     outbuf = GST_BUFFER_CAST (headers->data);
 
-    data = gst_buffer_map (outbuf, &size, NULL, GST_MAP_READ);
-    kate_packet_wrap (&packet, size, data);
+    if (!gst_buffer_map (outbuf, &info, GST_MAP_READ)) {
+      GST_WARNING_OBJECT (outbuf, "Failed to map buffer");
+      continue;
+    }
+
+    kate_packet_wrap (&packet, info.size, info.data);
     ret = kate_decode_headerin (&parse->ki, &parse->kc, &packet);
     if (G_UNLIKELY (ret < 0)) {
       GST_WARNING_OBJECT (parse, "Failed to decode header: %s",
           gst_kate_util_get_error_message (ret));
     }
-    gst_buffer_unmap (outbuf, data, size);
+    gst_buffer_unmap (outbuf, &info);
     /* takes ownership of outbuf, which was previously in parse->streamheader */
     outbuf_list = g_list_append (outbuf_list, outbuf);
     headers = headers->next;
@@ -379,7 +385,7 @@ gst_kate_parse_parse_packet (GstKateParse * parse, GstBuffer * buf)
 }
 
 static GstFlowReturn
-gst_kate_parse_chain (GstPad * pad, GstBuffer * buffer)
+gst_kate_parse_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
 {
   GstKateParseClass *klass;
   GstKateParse *parse;
@@ -406,39 +412,36 @@ gst_kate_parse_queue_event (GstKateParse * parse, GstEvent * event)
 }
 
 static gboolean
-gst_kate_parse_sink_event (GstPad * pad, GstEvent * event)
+gst_kate_parse_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
 {
   gboolean ret;
   GstKateParse *parse;
 
-  parse = GST_KATE_PARSE (gst_pad_get_parent (pad));
+  parse = GST_KATE_PARSE (parent);
 
   switch (GST_EVENT_TYPE (event)) {
     case GST_EVENT_FLUSH_START:
       gst_kate_parse_clear_queue (parse);
-      ret = gst_pad_event_default (pad, event);
+      ret = gst_pad_event_default (pad, parent, event);
       break;
     case GST_EVENT_EOS:
       if (!parse->streamheader_sent) {
         GST_DEBUG_OBJECT (parse, "Got EOS, pushing headers seen so far");
         ret = gst_kate_parse_push_headers (parse);
         if (ret != GST_FLOW_OK)
-          goto done;
+          break;
       }
       gst_kate_parse_drain_queue_prematurely (parse);
-      ret = gst_pad_event_default (pad, event);
+      ret = gst_pad_event_default (pad, parent, event);
       break;
     default:
       if (!parse->streamheader_sent && GST_EVENT_IS_SERIALIZED (event))
         ret = gst_kate_parse_queue_event (parse, event);
       else
-        ret = gst_pad_event_default (pad, event);
+        ret = gst_pad_event_default (pad, parent, event);
       break;
   }
 
-done:
-  gst_object_unref (parse);
-
   return ret;
 }
 
@@ -493,7 +496,7 @@ gst_kate_parse_convert (GstPad * pad,
 #endif
 
 static gboolean
-gst_kate_parse_src_query (GstPad * pad, GstQuery * query)
+gst_kate_parse_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
 {
 #if 1
   // TODO
@@ -504,7 +507,7 @@ gst_kate_parse_src_query (GstPad * pad, GstQuery * query)
   GstKateParse *parse;
   gboolean res = FALSE;
 
-  parse = GST_KATE_PARSE (GST_PAD_PARENT (pad));
+  parse = GST_KATE_PARSE (parent);
 
   switch (GST_QUERY_TYPE (query)) {
     case GST_QUERY_POSITION:
index 1efbd6a..a3336a4 100644 (file)
@@ -276,17 +276,19 @@ gst_kate_spu_decode_command_sequence (GstKateEnc * ke, GstBuffer * buf,
   guint16 date;
   guint16 next_command_sequence;
   const guint8 *ptr;
-  guint8 *data;
+  GstMapInfo info;
   guint16 sz;
-  gsize size;
 
-  data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+  if (!gst_buffer_map (buf, &info, GST_MAP_READ)) {
+    GST_ERROR_OBJECT (ke, (NULL), ("Failed to map buffer"));
+    return GST_FLOW_ERROR;
+  }
 
-  if (command_sequence_offset >= size)
+  if (command_sequence_offset >= info.size)
     goto out_of_range;
 
-  ptr = data + command_sequence_offset;
-  sz = size - command_sequence_offset;
+  ptr = info.data + command_sequence_offset;
+  sz = info.size - command_sequence_offset;
 
   GST_DEBUG_OBJECT (ke, "Decoding command sequence at %u (%u bytes)",
       command_sequence_offset, sz);
@@ -353,33 +355,33 @@ gst_kate_spu_decode_command_sequence (GstKateEnc * ke, GstBuffer * buf,
         if (next_command_sequence != command_sequence_offset) {
           GST_DEBUG_OBJECT (ke, "Jumping to next sequence at offset %u",
               next_command_sequence);
-          gst_buffer_unmap (buf, data, size);
+          gst_buffer_unmap (buf, &info);
           return gst_kate_spu_decode_command_sequence (ke, buf,
               next_command_sequence);
         } else {
-          gst_buffer_unmap (buf, data, size);
+          gst_buffer_unmap (buf, &info);
           GST_DEBUG_OBJECT (ke, "No more sequences to decode");
           return GST_FLOW_OK;
         }
         break;
       default:
-        gst_buffer_unmap (buf, data, size);
+        gst_buffer_unmap (buf, &info);
         GST_ELEMENT_ERROR (ke, STREAM, ENCODE, (NULL),
             ("Invalid SPU command: %u", cmd));
         return GST_FLOW_ERROR;
     }
   }
-  gst_buffer_unmap (buf, data, size);
+  gst_buffer_unmap (buf, &info);
   GST_ELEMENT_ERROR (ke, STREAM, ENCODE, (NULL), ("Error parsing SPU"));
   return GST_FLOW_ERROR;
 
   /* ERRORS */
 out_of_range:
   {
-    gst_buffer_unmap (buf, data, size);
+    gst_buffer_unmap (buf, &info);
     GST_ELEMENT_ERROR (ke, STREAM, DECODE, (NULL),
         ("Command sequence offset %u is out of range %u",
-            command_sequence_offset, size));
+            command_sequence_offset, info.size));
     return GST_FLOW_ERROR;
   }
 }
@@ -465,8 +467,7 @@ GstFlowReturn
 gst_kate_spu_decode_spu (GstKateEnc * ke, GstBuffer * buf, kate_region * kr,
     kate_bitmap * kb, kate_palette * kp)
 {
-  guint8 *data;
-  gsize size;
+  GstMapInfo info;
   const guint8 *ptr;
   size_t sz;
   guint16 packet_size;
@@ -479,10 +480,12 @@ gst_kate_spu_decode_spu (GstKateEnc * ke, GstBuffer * buf, kate_region * kr,
   guint16 next_command_sequence;
   guint16 code;
 
-  data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+  if (!gst_buffer_map (buf, &info, GST_MAP_READ)) {
+    GST_ERROR_OBJECT (ke, (NULL), ("Failed to map buffer"));
+  }
 
-  ptr = data;
-  sz = size;
+  ptr = info.data;
+  sz = info.size;
 
   /* before decoding anything, initialize to sensible defaults */
   memset (ke->spu_colormap, 0, sizeof (ke->spu_colormap));
@@ -497,19 +500,19 @@ gst_kate_spu_decode_spu (GstKateEnc * ke, GstBuffer * buf, kate_region * kr,
   packet_size = GST_KATE_UINT16_BE (ptr);
   ADVANCE (2);
   GST_DEBUG_OBJECT (ke, "packet size %u (GstBuffer size %u)", packet_size,
-      size);
+      info.size);
 
   CHECK (2);
   next_command_sequence = GST_KATE_UINT16_BE (ptr);
   ADVANCE (2);
-  ptr = data + next_command_sequence;
-  sz = size - next_command_sequence;
+  ptr = info.data + next_command_sequence;
+  sz = info.size - next_command_sequence;
   GST_DEBUG_OBJECT (ke, "next command sequence at %u for %u",
       next_command_sequence, (guint) sz);
 
   rflow = gst_kate_spu_decode_command_sequence (ke, buf, next_command_sequence);
   if (G_UNLIKELY (rflow != GST_FLOW_OK)) {
-    gst_buffer_unmap (buf, data, size);
+    gst_buffer_unmap (buf, &info);
     return rflow;
   }
 
@@ -524,14 +527,14 @@ gst_kate_spu_decode_spu (GstKateEnc * ke, GstBuffer * buf, kate_region * kr,
     GST_WARNING_OBJECT (ke, "SPU area is empty, nothing to encode");
     kate_bitmap_init (kb);
     kb->width = kb->height = 0;
-    gst_buffer_unmap (buf, data, size);
+    gst_buffer_unmap (buf, &info);
     return GST_FLOW_OK;
   }
 
   /* create the palette */
   rflow = gst_kate_spu_create_spu_palette (ke, kp);
   if (G_UNLIKELY (rflow != GST_FLOW_OK)) {
-    gst_buffer_unmap (buf, data, size);
+    gst_buffer_unmap (buf, &info);
     return rflow;
   }
 
@@ -543,15 +546,15 @@ gst_kate_spu_decode_spu (GstKateEnc * ke, GstBuffer * buf, kate_region * kr,
   kb->type = kate_bitmap_type_paletted;
   kb->pixels = (unsigned char *) g_malloc (kb->width * kb->height);
   if (G_UNLIKELY (!kb->pixels)) {
-    gst_buffer_unmap (buf, data, size);
+    gst_buffer_unmap (buf, &info);
     GST_ELEMENT_ERROR (ke, STREAM, ENCODE, (NULL),
         ("Failed to allocate memory for pixel data"));
     return GST_FLOW_ERROR;
   }
 
   n = 0;
-  pixptr[0] = data + ke->spu_pix_data[0];
-  pixptr[1] = data + ke->spu_pix_data[1];
+  pixptr[0] = info.data + ke->spu_pix_data[0];
+  pixptr[1] = info.data + ke->spu_pix_data[1];
   nybble_offset[0] = 0;
   nybble_offset[1] = 0;
   max_nybbles[0] = 2 * (packet_size - ke->spu_pix_data[0]);
@@ -618,7 +621,7 @@ gst_kate_spu_decode_spu (GstKateEnc * ke, GstBuffer * buf, kate_region * kr,
        probably going to end before the next one while being readable */
     //ke->hide_time = ke->show_time + (1000 * 90 / 1024);
   }
-  gst_buffer_unmap (buf, data, size);
+  gst_buffer_unmap (buf, &info);
 
   return GST_FLOW_OK;
 }
index 1aa3a9a..c6df6d6 100644 (file)
@@ -266,52 +266,57 @@ gst_kate_tag_parse_packet (GstKateParse * parse, GstBuffer * buffer)
   GstKateTag *kt;
   gchar *encoder = NULL;
   GstBuffer *new_buf;
-  guint8 *data;
-  gsize size;
+  GstMapInfo info;
 
   kt = GST_KATE_TAG (parse);
 
-  data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ);
+  if (!gst_buffer_map (buffer, &info, GST_MAP_READ)) {
+    GST_ERROR_OBJECT (buffer, (NULL), ("Failed to map buffer"));
+    return GST_FLOW_ERROR;
+  }
 
   /* rewrite the language and category */
-  if (size >= 64 && data[0] == 0x80) {
+  if (info.size >= 64 && info.data[0] == 0x80) {
     GstBuffer *new_buffer;
 
-    gst_buffer_unmap (buffer, data, size);
+    gst_buffer_unmap (buffer, &info);
     new_buffer = gst_buffer_copy (buffer);
-    gst_buffer_unref (buffer);
     buffer = new_buffer;
 
-    data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READWRITE);
+    if (!gst_buffer_map (buffer, &info, GST_MAP_READWRITE)) {
+      GST_ERROR_OBJECT (buffer, (NULL),
+          ("Failed to map copied buffer READWRITE"));
+      return GST_FLOW_ERROR;
+    }
     /* language is at offset 32, 16 bytes, zero terminated */
     if (kt->language) {
-      strncpy ((char *) data + 32, kt->language, 15);
-      data[47] = 0;
+      strncpy ((char *) info.data + 32, kt->language, 15);
+      info.data[47] = 0;
     }
     /* category is at offset 48, 16 bytes, zero terminated */
     if (kt->category) {
-      strncpy ((char *) data + 48, kt->category, 15);
-      data[63] = 0;
+      strncpy ((char *) info.data + 48, kt->category, 15);
+      info.data[63] = 0;
     }
     if (kt->original_canvas_width >= 0) {
       guint16 v = encode_canvas_size (kt->original_canvas_width);
-      data[16] = v & 0xff;
-      data[17] = (v >> 8) & 0xff;
+      info.data[16] = v & 0xff;
+      info.data[17] = (v >> 8) & 0xff;
     }
     if (kt->original_canvas_height >= 0) {
       guint16 v = encode_canvas_size (kt->original_canvas_height);
-      data[18] = v & 0xff;
-      data[19] = (v >> 8) & 0xff;
+      info.data[18] = v & 0xff;
+      info.data[19] = (v >> 8) & 0xff;
     }
   }
 
   /*  rewrite the comments packet */
-  if (size >= 9 && data[0] == 0x81) {
+  if (info.size >= 9 && info.data[0] == 0x81) {
     old_tags =
-        gst_tag_list_from_vorbiscomment (data, size,
+        gst_tag_list_from_vorbiscomment (info.data, info.size,
         (const guint8 *) "\201kate\0\0\0\0", 9, &encoder);
     user_tags = gst_tag_setter_get_tag_list (GST_TAG_SETTER (kt));
-    gst_buffer_unmap (buffer, data, size);
+    gst_buffer_unmap (buffer, &info);
 
     /* build new tag list */
     new_tags = gst_tag_list_merge (user_tags, old_tags,
@@ -332,7 +337,7 @@ gst_kate_tag_parse_packet (GstKateParse * parse, GstBuffer * buffer)
 
     buffer = new_buf;
   } else {
-    gst_buffer_unmap (buffer, data, size);
+    gst_buffer_unmap (buffer, &info);
   }
 
   return GST_KATE_PARSE_CLASS (parent_class)->parse_packet (parse, buffer);
index 36ca7af..8ebbe91 100644 (file)
@@ -60,7 +60,6 @@ gst_kate_util_set_header_on_caps (GstElement * element, GstCaps * caps,
     GValue value = { 0 };
     GstBuffer *buffer = headers->data;
     g_assert (buffer);
-    GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_IN_CAPS);
     g_value_init (&value, GST_TYPE_BUFFER);
     /* as in theoraenc, we need to copy to avoid circular references */
     buffer = gst_buffer_copy (buffer);
@@ -142,7 +141,8 @@ gst_kate_util_decode_base_reset (GstKateDecoderBase * decoder)
 
 gboolean
 gst_kate_util_decoder_base_queue_event (GstKateDecoderBase * decoder,
-    GstEvent * event, gboolean (*handler) (GstPad *, GstEvent *), GstPad * pad)
+    GstEvent * event, gboolean (*handler) (GstPad *, GstObject *, GstEvent *),
+    GstObject * parent, GstPad * pad)
 {
   gboolean can_be_queued;
 
@@ -163,6 +163,7 @@ gst_kate_util_decoder_base_queue_event (GstKateDecoderBase * decoder,
     item = g_slice_new (GstKateDecoderBaseQueuedEvent);
     if (item) {
       item->event = event;
+      item->parent = parent;
       item->pad = pad;
       item->handler = handler;
       g_queue_push_tail (decoder->event_queue, item);
@@ -199,7 +200,7 @@ gst_kate_util_decoder_base_drain_event_queue (GstKateDecoderBase * decoder)
   while (decoder->event_queue->length) {
     GstKateDecoderBaseQueuedEvent *item = (GstKateDecoderBaseQueuedEvent *)
         g_queue_pop_head (decoder->event_queue);
-    (*item->handler) (item->pad, item->event);
+    (*item->handler) (item->pad, item->parent, item->event);
     g_slice_free (GstKateDecoderBaseQueuedEvent, item);
   }
 }
@@ -250,29 +251,34 @@ gst_kate_util_decoder_base_chain_kate_packet (GstKateDecoderBase * decoder,
   int ret;
   GstFlowReturn rflow = GST_FLOW_OK;
   gboolean is_header;
-  guint8 *data;
-  gsize size;
+  GstMapInfo info;
+  gsize header_size;
   guint8 header[1];
 
-  size = gst_buffer_extract (buf, 0, header, 1);
+  header_size = gst_buffer_extract (buf, 0, header, 1);
 
   GST_DEBUG_OBJECT (element, "got kate packet, %u bytes, type %02x",
-      gst_buffer_get_size (buf), size == 0 ? -1 : header[0]);
+      gst_buffer_get_size (buf), header_size == 0 ? -1 : header[0]);
 
-  is_header = size > 0 && (header[0] & 0x80);
+  is_header = header_size > 0 && (header[0] & 0x80);
 
   if (!is_header && decoder->tags) {
     /* after we've processed headers, send any tags before processing the data packet */
     GST_DEBUG_OBJECT (element, "Not a header, sending tags for pad %s:%s",
         GST_DEBUG_PAD_NAME (tagpad));
-    gst_element_found_tags_for_pad (element, tagpad, decoder->tags);
+    gst_pad_push_event (tagpad, gst_event_new_tag (decoder->tags));
     decoder->tags = NULL;
   }
 
-  data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
-  kate_packet_wrap (&kp, size, data);
-  ret = kate_high_decode_packetin (&decoder->k, &kp, ev);
-  gst_buffer_unmap (buf, data, size);
+  if (gst_buffer_map (buf, &info, GST_MAP_READ)) {
+    kate_packet_wrap (&kp, info.size, info.data);
+    ret = kate_high_decode_packetin (&decoder->k, &kp, ev);
+    gst_buffer_unmap (buf, &info);
+  } else {
+    GST_ELEMENT_ERROR (element, STREAM, DECODE, (NULL),
+        ("Failed to map buffer"));
+    return GST_FLOW_ERROR;
+  }
 
   if (G_UNLIKELY (ret < 0)) {
     GST_ELEMENT_ERROR (element, STREAM, DECODE, (NULL),
@@ -301,9 +307,10 @@ gst_kate_util_decoder_base_chain_kate_packet (GstKateDecoderBase * decoder,
               strcmp (decoder->k.ki->category, "spu-subtitles") == 0) {
             *src_caps = gst_caps_new_empty_simple ("subpicture/x-dvd");
           } else if (decoder->k.ki->text_markup_type == kate_markup_none) {
-            *src_caps = gst_caps_new_empty_simple ("text/plain");
+            *src_caps = gst_caps_new_empty_simple ("text/x-raw");
           } else {
-            *src_caps = gst_caps_new_empty_simple ("text/x-pango-markup");
+            *src_caps = gst_caps_new_simple ("text/x-raw", "format",
+                G_TYPE_STRING, "pango-markup, utf8", NULL);
           }
           GST_INFO_OBJECT (srcpad, "Setting caps: %" GST_PTR_FORMAT, *src_caps);
           if (!gst_pad_set_caps (srcpad, *src_caps)) {
@@ -378,7 +385,7 @@ gst_kate_util_decoder_base_chain_kate_packet (GstKateDecoderBase * decoder,
             gst_tag_list_unref (old);
 
           if (decoder->initialized) {
-            gst_element_found_tags_for_pad (element, tagpad, decoder->tags);
+            gst_pad_push_event (tagpad, gst_event_new_tag (decoder->tags));
             decoder->tags = NULL;
           } else {
             /* Only push them as messages for the time being. *
@@ -424,7 +431,7 @@ gst_kate_util_decoder_base_chain_kate_packet (GstKateDecoderBase * decoder,
       if (gst_tag_list_is_empty (evtags))
         gst_tag_list_unref (evtags);
       else
-        gst_element_found_tags_for_pad (element, tagpad, evtags);
+        gst_pad_push_event (tagpad, gst_event_new_tag (evtags));
     }
   }
 #endif
@@ -611,7 +618,7 @@ gst_kate_decoder_base_convert (GstKateDecoderBase * decoder,
 
 gboolean
 gst_kate_decoder_base_sink_query (GstKateDecoderBase * decoder,
-    GstElement * element, GstPad * pad, GstQuery * query)
+    GstElement * element, GstPad * pad, GstObject * parent, GstQuery * query)
 {
   switch (GST_QUERY_TYPE (query)) {
     case GST_QUERY_CONVERT:
@@ -622,13 +629,13 @@ gst_kate_decoder_base_sink_query (GstKateDecoderBase * decoder,
       gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
       if (!gst_kate_decoder_base_convert (decoder, element, pad, src_fmt,
               src_val, &dest_fmt, &dest_val)) {
-        return gst_pad_query_default (pad, query);
+        return gst_pad_query_default (pad, parent, query);
       }
       gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
       return TRUE;
     }
     default:
-      return gst_pad_query_default (pad, query);
+      return gst_pad_query_default (pad, parent, query);
   }
 }
 
index 784debf..12ec0b8 100644 (file)
@@ -38,7 +38,8 @@ G_BEGIN_DECLS enum
 typedef struct
 {
   GstEvent * event;
-  gboolean (*handler)(GstPad *, GstEvent *);
+  gboolean (*handler)(GstPad *, GstObject*, GstEvent *);
+  GstObject * parent;
   GstPad *pad;
 } GstKateDecoderBaseQueuedEvent;
 
@@ -95,9 +96,11 @@ extern gboolean gst_kate_decoder_base_convert (GstKateDecoderBase * decoder,
     GstElement * element, GstPad * pad, GstFormat src_fmt, gint64 src_val,
     GstFormat * dest_fmt, gint64 * dest_val);
 extern gboolean gst_kate_decoder_base_sink_query (GstKateDecoderBase * decoder,
-    GstElement * element, GstPad * pad, GstQuery * query);
+    GstElement * element, GstPad * pad, GstObject * parent, GstQuery * query);
 extern gboolean
-gst_kate_util_decoder_base_queue_event (GstKateDecoderBase * decoder, GstEvent * event, gboolean (*handler)(GstPad *, GstEvent *), GstPad * pad);
+gst_kate_util_decoder_base_queue_event (GstKateDecoderBase * decoder,
+    GstEvent * event, gboolean (*handler)(GstPad *, GstObject *, GstEvent *),
+    GstObject * parent, GstPad * pad);
 extern const char *
 gst_kate_util_get_error_message (int ret);