From b261bd516f65a713d6753b65177378185ebaba80 Mon Sep 17 00:00:00 2001 From: Brendan Long Date: Mon, 1 Apr 2013 12:47:13 -0600 Subject: [PATCH] kate: port Kate subtitles to 1.0 https://bugzilla.gnome.org/show_bug.cgi?id=697071 --- configure.ac | 2 +- ext/kate/gstkatedec.c | 113 +++++++++++++++++++++++----------------- ext/kate/gstkateenc.c | 79 ++++++++++------------------ ext/kate/gstkateparse.c | 45 ++++++++-------- ext/kate/gstkatespu.c | 57 ++++++++++---------- ext/kate/gstkatetag.c | 43 ++++++++------- ext/kate/gstkateutil.c | 47 ++++++++++------- ext/kate/gstkateutil.h | 9 ++-- 8 files changed, 206 insertions(+), 189 deletions(-) diff --git a/configure.ac b/configure.ac index 2c612468e2..3574f9bec4 100644 --- a/configure.ac +++ b/configure.ac @@ -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 \ diff --git a/ext/kate/gstkatedec.c b/ext/kate/gstkatedec.c index 4a775aa440..98790b2022 100644 --- a/ext/kate/gstkatedec.c +++ b/ext/kate/gstkatedec.c @@ -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; + GstKateDec *kd = GST_KATE_DEC (parent); + gboolean res = TRUE; - 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); + GST_LOG_OBJECT (pad, "Handling query on src pad: %s", + GST_QUERY_TYPE_NAME (query)); + + switch (GST_QUERY_TYPE (query)) { + case GST_QUERY_CAPS:{ + GstCaps *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; } - caps = gst_caps_copy (caps); - - gst_object_unref (kd); - return caps; + return res; } diff --git a/ext/kate/gstkateenc.c b/ext/kate/gstkateenc.c index 989388c8bd..89500bdec6 100644 --- a/ext/kate/gstkateenc.c +++ b/ext/kate/gstkateenc.c @@ -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; } diff --git a/ext/kate/gstkateparse.c b/ext/kate/gstkateparse.c index b72f861091..02e5895bf9 100644 --- a/ext/kate/gstkateparse.c +++ b/ext/kate/gstkateparse.c @@ -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: diff --git a/ext/kate/gstkatespu.c b/ext/kate/gstkatespu.c index 1efbd6a475..a3336a4219 100644 --- a/ext/kate/gstkatespu.c +++ b/ext/kate/gstkatespu.c @@ -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; } diff --git a/ext/kate/gstkatetag.c b/ext/kate/gstkatetag.c index 1aa3a9a448..c6df6d67ee 100644 --- a/ext/kate/gstkatetag.c +++ b/ext/kate/gstkatetag.c @@ -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); diff --git a/ext/kate/gstkateutil.c b/ext/kate/gstkateutil.c index 36ca7aff06..8ebbe91d59 100644 --- a/ext/kate/gstkateutil.c +++ b/ext/kate/gstkateutil.c @@ -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); } } diff --git a/ext/kate/gstkateutil.h b/ext/kate/gstkateutil.h index 784debf3fd..12ec0b8111 100644 --- a/ext/kate/gstkateutil.h +++ b/ext/kate/gstkateutil.h @@ -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);