static GstFlowReturn gst_kate_tiger_kate_chain (GstPad * pad, GstBuffer * buf) { GstKateTiger *tiger = GST_KATE_TIGER (gst_pad_get_parent (pad)); const kate_event *ev = NULL; GstFlowReturn rflow = GST_FLOW_OK; g_mutex_lock (tiger->mutex); GST_LOG_OBJECT (tiger, "Got kate buffer"); rflow = gst_kate_util_decoder_base_chain_kate_packet (&tiger->decoder, GST_ELEMENT_CAST (tiger), pad, buf, tiger->srcpad, &ev); if (G_LIKELY (rflow == GST_FLOW_OK)) { if (ev) { int ret = tiger_renderer_add_event (tiger->tr, ev->ki, ev); GST_INFO_OBJECT (tiger, "adding event for %p from %f to %f: %p, \"%s\"", ev->ki, ev->start_time, ev->end_time, ev->bitmap, ev->text); if (G_UNLIKELY (ret < 0)) { GST_WARNING_OBJECT (tiger, "failed to add Kate event to Tiger renderer: %d", ret); } } } gst_object_unref (tiger); gst_buffer_unref (buf); g_mutex_unlock (tiger->mutex); return rflow; }
static GstFlowReturn gst_kate_dec_chain (GstPad * pad, GstBuffer * buf) { GstKateDec *kd = GST_KATE_DEC (gst_pad_get_parent (pad)); const kate_event *ev = NULL; GstFlowReturn rflow = GST_FLOW_OK; if (!gst_kate_util_decoder_base_update_segment (&kd->decoder, GST_ELEMENT_CAST (kd), buf)) { GST_WARNING_OBJECT (kd, "Out of segment!"); goto not_in_seg; } rflow = gst_kate_util_decoder_base_chain_kate_packet (&kd->decoder, 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; } if (ev) { gchar *escaped; GstBuffer *buffer; size_t len; gboolean plain = TRUE; if (kd->remove_markup && ev->text_markup_type != kate_markup_none) { size_t len0 = ev->len + 1; escaped = g_strdup (ev->text); if (escaped) { kate_text_remove_markup (ev->text_encoding, escaped, &len0); } plain = TRUE; } else if (ev->text_markup_type == kate_markup_none) { /* no pango markup yet, escape text */ /* TODO: actually do the pango thing */ escaped = g_strdup (ev->text); plain = TRUE; } else { escaped = g_strdup (ev->text); plain = FALSE; } if (G_LIKELY (escaped)) { len = strlen (escaped); if (len > 0) { 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); 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); gst_buffer_resize (buffer, 0, len); GST_BUFFER_TIMESTAMP (buffer) = ev->start_time * GST_SECOND; GST_BUFFER_DURATION (buffer) = (ev->end_time - ev->start_time) * GST_SECOND; rflow = gst_pad_push (kd->srcpad, buffer); if (rflow == GST_FLOW_NOT_LINKED) { GST_DEBUG_OBJECT (kd, "source pad not linked, ignored"); } else if (rflow != GST_FLOW_OK) { GST_WARNING_OBJECT (kd, "failed to push buffer: %s", gst_flow_get_name (rflow)); } } else { GST_ELEMENT_ERROR (kd, STREAM, DECODE, (NULL), ("Failed to create buffer")); rflow = GST_FLOW_ERROR; } } else { GST_WARNING_OBJECT (kd, "Empty string, nothing to do"); rflow = GST_FLOW_OK; } g_free (escaped); } else { GST_ELEMENT_ERROR (kd, STREAM, DECODE, (NULL), ("Failed to allocate string")); rflow = GST_FLOW_ERROR; } // if there's a background paletted bitmap, construct a DVD SPU for it if (ev->bitmap && ev->palette) { GstBuffer *buffer = gst_kate_spu_encode_spu (kd, ev); if (buffer) { GST_BUFFER_TIMESTAMP (buffer) = ev->start_time * GST_SECOND; GST_BUFFER_DURATION (buffer) = (ev->end_time - ev->start_time) * GST_SECOND; rflow = gst_pad_push (kd->srcpad, buffer); if (rflow == GST_FLOW_NOT_LINKED) { GST_DEBUG_OBJECT (kd, "source pad not linked, ignored"); } else if (rflow != GST_FLOW_OK) { GST_WARNING_OBJECT (kd, "failed to push buffer: %s", gst_flow_get_name (rflow)); } } else { GST_ELEMENT_ERROR (kd, STREAM, DECODE, (NULL), ("failed to create SPU from paletted bitmap")); rflow = GST_FLOW_ERROR; } } } not_in_seg: gst_object_unref (kd); gst_buffer_unref (buf); return rflow; }