 +
 +  gst_buffer_unref (buf);
 +  gst_caps_unref (caps);
-+
-+}
-+
++}
 +GST_END_TEST;
 +
++GST_START_TEST (test_kate_empty_identification_header)
++{
++  GstElement *katedec;
++  GstBuffer *inbuffer;
++  GstBus *bus;
++
++  katedec = setup_katedec ();
++  bus = gst_bus_new ();
++
++  fail_unless (gst_element_set_state (katedec,
++          GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
++      "could not set to playing");
++
++  inbuffer = gst_buffer_new_and_alloc (0);
++  ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
++
++  /* set a bus here so we avoid getting state change messages */
++  gst_element_set_bus (katedec, bus);
++
++  fail_unless_equals_int (gst_pad_push (mydecsrcpad, inbuffer), GST_FLOW_ERROR);
++  /* ... but it ends up being collected on the global buffer list */
++  fail_unless_equals_int (g_list_length (buffers), 0);
++
++  gst_element_set_bus (katedec, NULL);
++
++  /* cleanup */
++  gst_object_unref (GST_OBJECT (bus));
++  cleanup_katedec (katedec);
++}
++GST_END_TEST;
++
++/* FIXME: also tests comment header */
++GST_START_TEST (test_kate_identification_header)
++{
++  GstElement *katedec;
++  GstBuffer *inbuffer;
++  GstBus *bus;
++  GstMessage *message;
++  GstTagList *tag_list;
++  gchar *language;
++  gchar *title;
++
++  katedec = setup_katedec ();
++  fail_unless (gst_element_set_state (katedec,
++          GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
++      "could not set to playing");
++  bus = gst_bus_new ();
++
++  inbuffer = gst_buffer_new_and_alloc (sizeof (kate_header_0x80));
++  memcpy (GST_BUFFER_DATA (inbuffer), kate_header_0x80, sizeof (kate_header_0x80));
++  ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
++  gst_buffer_ref (inbuffer);
++
++  gst_element_set_bus (katedec, bus);
++  /* pushing gives away my reference ... */
++  fail_unless (gst_pad_push (mydecsrcpad, inbuffer) == GST_FLOW_OK);
++  /* ... and nothing ends up on the global buffer list */
++  ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
++  gst_buffer_unref (inbuffer);
++  fail_unless (g_list_length (buffers) == 0);
++
++  inbuffer = gst_buffer_new_and_alloc (sizeof (kate_header_0x81));
++  memcpy (GST_BUFFER_DATA (inbuffer), kate_header_0x81, sizeof (kate_header_0x81));
++  ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
++  gst_buffer_ref (inbuffer);
++
++  /* pushing gives away my reference ... */
++  fail_unless (gst_pad_push (mydecsrcpad, inbuffer) == GST_FLOW_OK);
++  /* ... and nothing ends up on the global buffer list */
++  ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
++  gst_buffer_unref (inbuffer);
++  fail_unless (g_list_length (buffers) == 0);
++  /* there's a tag message waiting */
++  fail_if ((message = gst_bus_pop (bus)) == NULL);
++  gst_message_parse_tag (message, &tag_list);
++  fail_unless_equals_int (gst_tag_list_get_tag_size (tag_list, GST_TAG_LANGUAGE_CODE),
++      1);
++  fail_unless (gst_tag_list_get_string (tag_list, GST_TAG_LANGUAGE_CODE, &language));
++  fail_unless_equals_string (language, "en_GB");
++  g_free (language);
++  fail_unless_equals_int (gst_tag_list_get_tag_size (tag_list, "title"), 1);
++  fail_unless (gst_tag_list_get_string (tag_list, GST_TAG_TITLE, &title));
++  fail_unless_equals_string (title, "Tiger");
++  g_free (title);
++  gst_tag_list_free (tag_list);
++  gst_message_unref (message);
++
++  /* cleanup */
++  gst_bus_set_flushing (bus, TRUE);
++  gst_element_set_bus (katedec, NULL);
++  gst_object_unref (GST_OBJECT (bus));
++  cleanup_katedec (katedec);
++}
++GST_END_TEST;
++
++GST_START_TEST (test_kate_encode_empty)
++{
++  GstElement *kateenc;
++  GstBuffer *inbuffer;
++  GstBus *bus;
++
++  kateenc = setup_kateenc ();
++  fail_unless (gst_element_set_state (kateenc,
++          GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
++      "could not set to playing");
++  bus = gst_bus_new ();
++
++  inbuffer = gst_buffer_new_and_alloc (0);
++  GST_BUFFER_TIMESTAMP (inbuffer) = GST_BUFFER_OFFSET (inbuffer) = 1*GST_SECOND;
++  GST_BUFFER_DURATION (inbuffer) = 5*GST_SECOND;
++  ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
++  gst_buffer_ref (inbuffer);
++  fail_unless (gst_pad_push_event (myencsrcpad, gst_event_new_eos ()) == TRUE);
++
++  gst_element_set_bus (kateenc, bus);
++  /* pushing gives away my reference ... */
++  fail_unless (gst_pad_push (myencsrcpad, inbuffer) == GST_FLOW_ERROR);
++
++  gst_element_set_bus (kateenc, NULL);
++
++  /* cleanup */
++  gst_object_unref (GST_OBJECT (bus));
++  cleanup_kateenc (kateenc);
++}
++GST_END_TEST;
++
++GST_START_TEST (test_kate_encode_simple)
++{
++  GstElement *kateenc;
++  GstBuffer *inbuffer, *outbuffer;
++  GstBus *bus;
++  const gchar *test_string="";
++  int i, num_buffers;
++  unsigned char packet_type;
++
++  kateenc = setup_kateenc ();
++  fail_unless (gst_element_set_state (kateenc,
++          GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
++      "could not set to playing");
++  bus = gst_bus_new ();
++
++  inbuffer = gst_buffer_new_and_alloc (strlen (test_string)+1);
++  memcpy (GST_BUFFER_DATA (inbuffer), test_string, strlen (test_string)+1);
++  GST_BUFFER_TIMESTAMP (inbuffer) = GST_BUFFER_OFFSET (inbuffer) = 1*GST_SECOND;
++  GST_BUFFER_DURATION (inbuffer) = 5*GST_SECOND;
++  ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
++  gst_buffer_ref (inbuffer);
++
++  gst_element_set_bus (kateenc, bus);
++  /* pushing gives away my reference ... */
++  fail_unless (gst_pad_push (myencsrcpad, inbuffer) == GST_FLOW_OK);
++  /* ... and nothing ends up on the global buffer list */
++  ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
++  gst_buffer_unref (inbuffer);
++  fail_unless (gst_pad_push_event (myencsrcpad, gst_event_new_eos ()) == TRUE);
++
++  /* check buffers are the type we expect */
++  num_buffers = g_list_length (buffers);
++  fail_unless (num_buffers >= 9+1+1); /* at least 9 headers, 1 data, 1 eos */
++  for (i = 0; i < num_buffers; ++i) {
++    outbuffer = GST_BUFFER (buffers->data);
++    fail_if (outbuffer == NULL);
++
++    if (i < num_buffers-2) {
++      /* different headers packets */
++      packet_type = (0x80 | i);
++    }
++    else if (i == num_buffers-2) {
++      /* text data packet */
++      packet_type = 0;
++    }
++    else {
++      /* eos data packet */
++      packet_type = 0x7f;
++    }
++
++    fail_if (GST_BUFFER_SIZE (outbuffer) == 0);
++    fail_unless (GST_BUFFER_DATA (outbuffer)[0] == packet_type);
++
++    buffers = g_list_remove (buffers, outbuffer);
++
++    ASSERT_BUFFER_REFCOUNT (outbuffer, "outbuffer", 1);
++    gst_buffer_unref (outbuffer);
++    outbuffer = NULL;
++  }
++
++  /* cleanup */
++  gst_bus_set_flushing (bus, TRUE);
++  gst_element_set_bus (kateenc, NULL);
++  gst_object_unref (GST_OBJECT (bus));
++  cleanup_kateenc (kateenc);
++  g_list_free (buffers);
++}
++GST_END_TEST;
 +
 +Suite *
 +kate_suite (void)

+    gst_buffer_set_caps (buffer, caps);
+    item = item->next;
+  }
+
+  GST_LOG_OBJECT (ke, "pushing headers");
+  item = headers;

+
+/*
+conversions on the sink:
+  - nothing
+conversions on the source:
+  - default is granules at num/den rate
+  - default -> time is possible
+  - bytes do not mean anything, packets can be any number of bytes, and we
+    have no way to know the number of bytes emitted without decoding
+*/
+
+static gboolean
