diff --git a/ext/kate/gstkatedec.c b/ext/kate/gstkatedec.c index df3607024f..901f9b40ea 100644 --- a/ext/kate/gstkatedec.c +++ b/ext/kate/gstkatedec.c @@ -117,7 +117,8 @@ static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src", GST_STATIC_CAPS ("text/plain; text/x-pango-markup; " GST_KATE_SPU_MIME_TYPE) ); -GST_BOILERPLATE (GstKateDec, gst_kate_dec, GstElement, GST_TYPE_ELEMENT); +#define gst_kate_dec_parent_class parent_class +G_DEFINE_TYPE (GstKateDec, gst_kate_dec, GST_TYPE_ELEMENT); static void gst_kate_dec_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); @@ -130,23 +131,7 @@ static GstStateChangeReturn gst_kate_dec_change_state (GstElement * element, 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); - -static void -gst_kate_dec_base_init (gpointer gclass) -{ - - GstElementClass *element_class = GST_ELEMENT_CLASS (gclass); - - 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, - "Kate stream text decoder", "Codec/Decoder/Subtitle", - "Decodes Kate text streams", - "Vincent Penquerc'h "); -} +static GstCaps *gst_kate_dec_src_get_caps (GstPad * pad, GstCaps * filter); /* initialize the plugin's class */ static void @@ -170,6 +155,16 @@ gst_kate_dec_class_init (GstKateDecClass * klass) gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_kate_dec_change_state); + + 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 (&sink_factory)); + + gst_element_class_set_details_simple (gstelement_class, + "Kate stream text decoder", "Codec/Decoder/Subtitle", + "Decodes Kate text streams", + "Vincent Penquerc'h "); } /* initialize the new element @@ -178,7 +173,7 @@ gst_kate_dec_class_init (GstKateDecClass * klass) * initialize structure */ static void -gst_kate_dec_init (GstKateDec * dec, GstKateDecClass * gclass) +gst_kate_dec_init (GstKateDec * dec) { GST_DEBUG_OBJECT (dec, "gst_kate_dec_init"); @@ -295,11 +290,10 @@ gst_kate_dec_chain (GstPad * pad, GstBuffer * buf) if (G_LIKELY (buffer)) { const char *mime = plain ? "text/plain" : "text/x-pango-markup"; GstCaps *caps = gst_caps_new_simple (mime, NULL); - gst_buffer_set_caps (buffer, caps); gst_caps_unref (caps); /* allocate and copy the NULs, but don't include them in passed size */ - memcpy (GST_BUFFER_DATA (buffer), escaped, len + 1); - GST_BUFFER_SIZE (buffer) = len; + 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; @@ -330,9 +324,6 @@ gst_kate_dec_chain (GstPad * pad, GstBuffer * buf) if (ev->bitmap && ev->palette) { GstBuffer *buffer = gst_kate_spu_encode_spu (kd, ev); if (buffer) { - GstCaps *caps = gst_caps_new_simple (GST_KATE_SPU_MIME_TYPE, NULL); - gst_buffer_set_caps (buffer, caps); - gst_caps_unref (caps); GST_BUFFER_TIMESTAMP (buffer) = ev->start_time * GST_SECOND; GST_BUFFER_DURATION (buffer) = (ev->end_time - ev->start_time) * GST_SECOND; @@ -416,8 +407,8 @@ gst_kate_dec_sink_handle_event (GstPad * pad, GstEvent * event) GST_EVENT_TYPE_NAME (event)); switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_NEWSEGMENT: - gst_kate_util_decoder_base_new_segment_event (&kd->decoder, event); + case GST_EVENT_SEGMENT: + gst_kate_util_decoder_base_segment_event (&kd->decoder, event); res = gst_pad_event_default (pad, event); break; @@ -442,7 +433,7 @@ gst_kate_dec_sink_handle_event (GstPad * pad, GstEvent * event) } static GstCaps * -gst_kate_dec_src_get_caps (GstPad * pad) +gst_kate_dec_src_get_caps (GstPad * pad, GstCaps * filter) { GstKateDec *kd = (GstKateDec *) (gst_object_get_parent (GST_OBJECT (pad))); GstCaps *caps; diff --git a/ext/kate/gstkateenc.c b/ext/kate/gstkateenc.c index 6befaf8c5d..e1630dfd29 100644 --- a/ext/kate/gstkateenc.c +++ b/ext/kate/gstkateenc.c @@ -142,26 +142,10 @@ static GstStateChangeReturn gst_kate_enc_change_state (GstElement * element, 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 void gst_kate_enc_add_interfaces (GType kateenc_type); -GST_BOILERPLATE_FULL (GstKateEnc, gst_kate_enc, GstElement, - GST_TYPE_ELEMENT, gst_kate_enc_add_interfaces); - -static void -gst_kate_enc_base_init (gpointer gclass) -{ - - GstElementClass *element_class = GST_ELEMENT_CLASS (gclass); - - 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, "Kate stream encoder", - "Codec/Encoder/Subtitle", - "Encodes Kate streams from text or subpictures", - "Vincent Penquerc'h "); -} +#define gst_kate_enc_parent_class parent_class +G_DEFINE_TYPE_WITH_CODE (GstKateEnc, gst_kate_enc, GST_TYPE_ELEMENT, + G_IMPLEMENT_INTERFACE (GST_TYPE_TAG_SETTER, NULL)); /* initialize the plugin's class */ static void @@ -173,8 +157,6 @@ gst_kate_enc_class_init (GstKateEncClass * klass) gobject_class = (GObjectClass *) klass; gstelement_class = (GstElementClass *) klass; - parent_class = g_type_class_peek_parent (klass); - gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_kate_enc_set_property); gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_kate_enc_get_property); gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_kate_enc_dispose); @@ -228,15 +210,16 @@ gst_kate_enc_class_init (GstKateEncClass * klass) gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_kate_enc_change_state); -} -static void -gst_kate_enc_add_interfaces (GType kateenc_type) -{ - static const GInterfaceInfo tag_setter_info = { NULL, NULL, NULL }; + 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 (&sink_factory)); - g_type_add_interface_static (kateenc_type, GST_TYPE_TAG_SETTER, - &tag_setter_info); + gst_element_class_set_details_simple (gstelement_class, "Kate stream encoder", + "Codec/Encoder/Subtitle", + "Encodes Kate streams from text or subpictures", + "Vincent Penquerc'h "); } /* initialize the new element @@ -245,7 +228,7 @@ gst_kate_enc_add_interfaces (GType kateenc_type) * initialize structure */ static void -gst_kate_enc_init (GstKateEnc * ke, GstKateEncClass * gclass) +gst_kate_enc_init (GstKateEnc * ke) { GST_DEBUG_OBJECT (ke, "gst_kate_enc_init"); @@ -254,8 +237,6 @@ gst_kate_enc_init (GstKateEnc * ke, GstKateEncClass * gclass) GST_DEBUG_FUNCPTR (gst_kate_enc_chain)); gst_pad_set_event_function (ke->sinkpad, GST_DEBUG_FUNCPTR (gst_kate_enc_sink_event)); - gst_pad_set_setcaps_function (ke->sinkpad, - GST_DEBUG_FUNCPTR (gst_kate_enc_setcaps)); gst_element_add_pad (GST_ELEMENT (ke), ke->sinkpad); ke->srcpad = gst_pad_new_from_static_template (&src_factory, "src"); @@ -410,14 +391,14 @@ gst_kate_enc_create_buffer (GstKateEnc * ke, kate_packet * kp, g_return_val_if_fail (kp != NULL, NULL); g_return_val_if_fail (kp->data != NULL, NULL); - buffer = gst_buffer_try_new_and_alloc (kp->nbytes); + buffer = gst_buffer_new_allocate (NULL, kp->nbytes, 0); if (G_UNLIKELY (!buffer)) { GST_WARNING_OBJECT (ke, "Failed to allocate buffer for %u bytes", (guint) kp->nbytes); return NULL; } - memcpy (GST_BUFFER_DATA (buffer), kp->data, kp->nbytes); + gst_buffer_fill (buffer, 0, kp->data, kp->nbytes); /* same system as other Ogg codecs, as per ext/ogg/README: OFFSET_END is the granulepos @@ -644,16 +625,6 @@ gst_kate_enc_send_headers (GstKateEnc * ke) if (caps) { GST_DEBUG_OBJECT (ke, "here are the caps: %" GST_PTR_FORMAT, caps); gst_pad_set_caps (ke->srcpad, caps); - - GST_LOG_OBJECT (ke, "setting caps on headers"); - item = headers; - while (item) { - GstBuffer *buffer = item->data; - GST_LOG_OBJECT (ke, "settings caps on header %p", buffer); - gst_buffer_set_caps (buffer, caps); - item = item->next; - } - gst_caps_unref (caps); GST_LOG_OBJECT (ke, "pushing headers"); @@ -869,7 +840,7 @@ gst_kate_enc_chain_spu (GstKateEnc * ke, GstBuffer * buf) #endif GST_DEBUG_OBJECT (ke, "Encoding %ux%u SPU: (%u bytes) from %f to %f", (guint) kbitmap->width, (guint) kbitmap->height, - GST_BUFFER_SIZE (buf), t0, t1); + gst_buffer_get_size (buf), t0, t1); ret = kate_encode_set_region (&ke->k, kregion); if (G_UNLIKELY (ret < 0)) { @@ -953,15 +924,18 @@ gst_kate_enc_chain_text (GstKateEnc * ke, GstBuffer * buf, ("kate_encode_set_markup_type: %d", ret)); rflow = GST_FLOW_ERROR; } else { - const char *text = (const char *) GST_BUFFER_DATA (buf); + char *text; + gsize text_len; + + text = gst_buffer_map (buf, &text_len, NULL, GST_MAP_READ); if (text) { - size_t text_len = GST_BUFFER_SIZE (buf); kate_float t0 = start / (double) GST_SECOND; kate_float t1 = stop / (double) GST_SECOND; 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); + (int) text_len, (int) text_len, text, text_len, t0, t1); + ret = kate_encode_text (&ke->k, t0, t1, text, text_len, &kp); + if (G_UNLIKELY (ret < 0)) { GST_ELEMENT_ERROR (ke, STREAM, ENCODE, (NULL), ("Failed to encode text: %d", ret)); @@ -976,6 +950,7 @@ gst_kate_enc_chain_text (GstKateEnc * ke, GstBuffer * buf, ("no text in text packet")); rflow = GST_FLOW_ERROR; } + gst_buffer_unmap (buf, text, text_len); } return rflow; @@ -992,10 +967,10 @@ gst_kate_enc_chain (GstPad * pad, GstBuffer * buf) GstCaps *caps; const gchar *mime_type = NULL; - GST_DEBUG_OBJECT (ke, "got packet, %u bytes", GST_BUFFER_SIZE (buf)); + GST_DEBUG_OBJECT (ke, "got packet, %u bytes", gst_buffer_get_size (buf)); /* get the type of the data we're being sent */ - caps = GST_PAD_CAPS (pad); + caps = gst_pad_get_current_caps (pad); if (G_UNLIKELY (caps == NULL)) { GST_WARNING_OBJECT (ke, "No input caps set"); rflow = GST_FLOW_NOT_NEGOTIATED; @@ -1027,6 +1002,7 @@ gst_kate_enc_chain (GstPad * pad, GstBuffer * buf) } else { GST_WARNING_OBJECT (ke, "Packet has no MIME type, ignored"); } + gst_caps_unref (caps); } gst_buffer_unref (buf); @@ -1261,38 +1237,46 @@ static gboolean gst_kate_enc_sink_event (GstPad * pad, GstEvent * event) { GstKateEnc *ke = GST_KATE_ENC (gst_pad_get_parent (pad)); - GstStructure *structure; + const GstStructure *structure; gboolean ret; switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_NEWSEGMENT: + case GST_EVENT_CAPS: + { + GstCaps *caps; + + gst_event_parse_caps (event, &caps); + ret = gst_kate_enc_setcaps (pad, caps); + gst_event_unref (event); + break; + } + case GST_EVENT_SEGMENT: GST_LOG_OBJECT (ke, "Got newsegment event"); if (ke->initialized) { GST_LOG_OBJECT (ke, "ensuring all headers are in"); if (gst_kate_enc_flush_headers (ke) != GST_FLOW_OK) { GST_WARNING_OBJECT (ke, "Failed to flush headers"); } else { - GstFormat format; - gint64 timestamp; + GstSegment seg; - gst_event_parse_new_segment (event, NULL, NULL, &format, ×tamp, - NULL, NULL); - if (format != GST_FORMAT_TIME || !GST_CLOCK_TIME_IS_VALID (timestamp)) { + gst_event_copy_segment (event, &seg); + if (seg.format != GST_FORMAT_TIME + || !GST_CLOCK_TIME_IS_VALID (seg.start)) { GST_WARNING_OBJECT (ke, "No time in newsegment event %p, format %d, timestamp %" - G_GINT64_FORMAT, event, (int) format, timestamp); + G_GINT64_FORMAT, event, (int) seg.format, seg.start); /* to be safe, we'd need to generate a keepalive anyway, but we'd have to guess at the timestamp to use; a good guess would be the last known timestamp plus the keepalive time, but if we then get a packet with a timestamp less than this, it would fail to encode, which would be Bad. If we don't encode a keepalive, we run the risk of stalling the pipeline and hanging, which is Very Bad. Oh dear. We can't exit(-1), can we ? */ } else { - float t = timestamp / (double) GST_SECOND; + float t = seg.start / (double) GST_SECOND; if (ke->delayed_spu && t - ke->delayed_start / (double) GST_SECOND >= ke->default_spu_duration) { if (G_UNLIKELY (gst_kate_enc_flush_waiting (ke, - timestamp) != GST_FLOW_OK)) { + seg.start) != GST_FLOW_OK)) { GST_WARNING_OBJECT (ke, "Failed to encode delayed packet"); /* continue with new segment handling anyway */ } @@ -1307,7 +1291,7 @@ gst_kate_enc_sink_event (GstPad * pad, GstEvent * event) /* we only generate a keepalive if there is no SPU waiting, as it would mean out of sequence start times - and granulepos */ if (!ke->delayed_spu) { - gst_kate_enc_generate_keepalive (ke, timestamp); + gst_kate_enc_generate_keepalive (ke, seg.start); } } } @@ -1319,7 +1303,7 @@ gst_kate_enc_sink_event (GstPad * pad, GstEvent * event) case GST_EVENT_CUSTOM_DOWNSTREAM: GST_LOG_OBJECT (ke, "Got custom downstream event"); /* adapted from the dvdsubdec element */ - structure = event->structure; + structure = gst_event_get_structure (event); if (structure != NULL && gst_structure_has_name (structure, "application/x-gst-dvd")) { if (ke->initialized) { diff --git a/ext/kate/gstkateparse.c b/ext/kate/gstkateparse.c index 6a72edec99..80c7ca41b3 100644 --- a/ext/kate/gstkateparse.c +++ b/ext/kate/gstkateparse.c @@ -83,7 +83,8 @@ static GstStaticPadTemplate gst_kate_parse_src_factory = GST_STATIC_CAPS ("subtitle/x-kate; application/x-kate") ); -GST_BOILERPLATE (GstKateParse, gst_kate_parse, GstElement, GST_TYPE_ELEMENT); +#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 GstStateChangeReturn gst_kate_parse_change_state (GstElement * element, @@ -98,21 +99,6 @@ static gboolean gst_kate_parse_convert (GstPad * pad, static GstFlowReturn gst_kate_parse_parse_packet (GstKateParse * parse, GstBuffer * buf); -static void -gst_kate_parse_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 (&gst_kate_parse_src_factory)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_kate_parse_sink_factory)); - gst_element_class_set_details_simple (element_class, "Kate stream parser", - "Codec/Parser/Subtitle", - "parse raw kate streams", - "Vincent Penquerc'h "); -} - static void gst_kate_parse_class_init (GstKateParseClass * klass) { @@ -120,11 +106,21 @@ gst_kate_parse_class_init (GstKateParseClass * klass) gstelement_class->change_state = gst_kate_parse_change_state; + gst_element_class_add_pad_template (gstelement_class, + gst_static_pad_template_get (&gst_kate_parse_src_factory)); + gst_element_class_add_pad_template (gstelement_class, + gst_static_pad_template_get (&gst_kate_parse_sink_factory)); + + gst_element_class_set_details_simple (gstelement_class, "Kate stream parser", + "Codec/Parser/Subtitle", + "parse raw kate streams", + "Vincent Penquerc'h "); + klass->parse_packet = GST_DEBUG_FUNCPTR (gst_kate_parse_parse_packet); } static void -gst_kate_parse_init (GstKateParse * parse, GstKateParseClass * g_class) +gst_kate_parse_init (GstKateParse * parse) { parse->sinkpad = gst_pad_new_from_static_template (&gst_kate_parse_sink_factory, "sink"); @@ -166,7 +162,7 @@ gst_kate_parse_push_headers (GstKateParse * parse) /* get the headers into the caps, passing them to kate as we go */ caps = gst_kate_util_set_header_on_caps (&parse->element, - gst_pad_get_negotiated_caps (parse->sinkpad), parse->streamheader); + gst_pad_get_current_caps (parse->sinkpad), parse->streamheader); if (G_UNLIKELY (!caps)) { GST_ELEMENT_ERROR (parse, STREAM, DECODE, (NULL), @@ -184,13 +180,18 @@ gst_kate_parse_push_headers (GstKateParse * parse) headers = parse->streamheader; while (headers) { + guint8 *data; + gsize size; + outbuf = GST_BUFFER_CAST (headers->data); - kate_packet_wrap (&packet, GST_BUFFER_SIZE (outbuf), - GST_BUFFER_DATA (outbuf)); + + data = gst_buffer_map (outbuf, &size, NULL, GST_MAP_READ); + kate_packet_wrap (&packet, size, data); ret = kate_decode_headerin (&parse->ki, &parse->kc, &packet); if (G_UNLIKELY (ret < 0)) { GST_WARNING_OBJECT (parse, "kate_decode_headerin returned %d", ret); } + gst_buffer_unmap (outbuf, data, size); /* takes ownership of outbuf, which was previously in parse->streamheader */ outbuf_list = g_list_append (outbuf_list, outbuf); headers = headers->next; @@ -203,7 +204,6 @@ gst_kate_parse_push_headers (GstKateParse * parse) headers = outbuf_list; while (headers) { outbuf = GST_BUFFER_CAST (headers->data); - gst_buffer_set_caps (outbuf, GST_PAD_CAPS (parse->srcpad)); gst_pad_push (parse->srcpad, outbuf); headers = headers->next; } @@ -255,8 +255,6 @@ gst_kate_parse_push_buffer (GstKateParse * parse, GstBuffer * buf, GST_BUFFER_OFFSET_END (buf) = granulepos; GST_BUFFER_TIMESTAMP (buf) = GST_BUFFER_OFFSET (buf); - gst_buffer_set_caps (buf, GST_PAD_CAPS (parse->srcpad)); - return gst_pad_push (parse->srcpad, buf); } @@ -318,7 +316,7 @@ gst_kate_parse_queue_buffer (GstKateParse * parse, GstBuffer * buf) GstFlowReturn ret = GST_FLOW_OK; gint64 granpos; - buf = gst_buffer_make_metadata_writable (buf); + buf = gst_buffer_make_writable (buf); /* oggdemux stores the granule pos in the offset end */ granpos = GST_BUFFER_OFFSET_END (buf); @@ -347,17 +345,20 @@ static GstFlowReturn gst_kate_parse_parse_packet (GstKateParse * parse, GstBuffer * buf) { GstFlowReturn ret = GST_FLOW_OK; + guint8 header[1]; + gsize size; g_assert (parse); parse->packetno++; - GST_LOG_OBJECT (parse, "Got packet %02x, %u bytes", - GST_BUFFER_SIZE (buf) ? GST_BUFFER_DATA (buf)[0] : -1, - GST_BUFFER_SIZE (buf)); + size = gst_buffer_extract (buf, 0, header, 1); - if (GST_BUFFER_SIZE (buf) > 0 && GST_BUFFER_DATA (buf)[0] & 0x80) { - GST_DEBUG_OBJECT (parse, "Found header %02x", GST_BUFFER_DATA (buf)[0]); + GST_LOG_OBJECT (parse, "Got packet %02x, %u bytes", + size ? header[0] : -1, gst_buffer_get_size (buf)); + + if (size > 0 && header[0] & 0x80) { + GST_DEBUG_OBJECT (parse, "Found header %02x", header[0]); /* if 0x80 is set, it's streamheader, * so put it on the streamheader list and return */ parse->streamheader = g_list_append (parse->streamheader, buf); @@ -387,7 +388,7 @@ gst_kate_parse_chain (GstPad * pad, GstBuffer * buffer) g_assert (klass->parse_packet != NULL); - if (G_UNLIKELY (GST_PAD_CAPS (pad) == NULL)) + if (G_UNLIKELY (!gst_pad_has_current_caps (pad))) return GST_FLOW_NOT_NEGOTIATED; return klass->parse_packet (parse, buffer); @@ -602,7 +603,7 @@ gst_kate_parse_change_state (GstElement * element, GstStateChange transition) break; } - ret = parent_class->change_state (element, transition); + ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); switch (transition) { case GST_STATE_CHANGE_PAUSED_TO_READY: diff --git a/ext/kate/gstkatespu.c b/ext/kate/gstkatespu.c index 4392916341..85606495e7 100644 --- a/ext/kate/gstkatespu.c +++ b/ext/kate/gstkatespu.c @@ -276,17 +276,17 @@ gst_kate_spu_decode_command_sequence (GstKateEnc * ke, GstBuffer * buf, guint16 date; guint16 next_command_sequence; const guint8 *ptr; + guint8 *data; guint16 sz; + gsize size; - if (command_sequence_offset >= GST_BUFFER_SIZE (buf)) { - GST_ELEMENT_ERROR (ke, STREAM, DECODE, (NULL), - ("Command sequence offset %u is out of range %u", - command_sequence_offset, GST_BUFFER_SIZE (buf))); - return GST_FLOW_ERROR; - } + data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ); - ptr = GST_BUFFER_DATA (buf) + command_sequence_offset; - sz = GST_BUFFER_SIZE (buf) - command_sequence_offset; + if (command_sequence_offset >= size) + goto out_of_range; + + ptr = data + command_sequence_offset; + sz = size - command_sequence_offset; GST_DEBUG_OBJECT (ke, "Decoding command sequence at %u (%u bytes)", command_sequence_offset, sz); @@ -353,21 +353,35 @@ 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); return gst_kate_spu_decode_command_sequence (ke, buf, next_command_sequence); } else { + gst_buffer_unmap (buf, data, size); GST_DEBUG_OBJECT (ke, "No more sequences to decode"); return GST_FLOW_OK; } break; default: + gst_buffer_unmap (buf, data, size); GST_ELEMENT_ERROR (ke, STREAM, ENCODE, (NULL), ("Invalid SPU command: %u", cmd)); return GST_FLOW_ERROR; } } + gst_buffer_unmap (buf, data, size); 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_ELEMENT_ERROR (ke, STREAM, DECODE, (NULL), + ("Command sequence offset %u is out of range %u", + command_sequence_offset, size)); + return GST_FLOW_ERROR; + } } static inline int @@ -451,8 +465,10 @@ GstFlowReturn gst_kate_spu_decode_spu (GstKateEnc * ke, GstBuffer * buf, kate_region * kr, kate_bitmap * kb, kate_palette * kp) { - const guint8 *ptr = GST_BUFFER_DATA (buf); - size_t sz = GST_BUFFER_SIZE (buf); + guint8 *data; + gsize size; + const guint8 *ptr; + size_t sz; guint16 packet_size; guint16 x, y; size_t n; @@ -463,6 +479,11 @@ 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); + + ptr = data; + sz = size; + /* before decoding anything, initialize to sensible defaults */ memset (ke->spu_colormap, 0, sizeof (ke->spu_colormap)); memset (ke->spu_alpha, 0, sizeof (ke->spu_alpha)); @@ -476,19 +497,21 @@ 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, - GST_BUFFER_SIZE (buf)); + size); CHECK (2); next_command_sequence = GST_KATE_UINT16_BE (ptr); ADVANCE (2); - ptr = GST_BUFFER_DATA (buf) + next_command_sequence; - sz = GST_BUFFER_SIZE (buf) - next_command_sequence; + ptr = data + next_command_sequence; + sz = 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)) + if (G_UNLIKELY (rflow != GST_FLOW_OK)) { + gst_buffer_unmap (buf, data, size); return rflow; + } /* if no addresses or sizes were given, or if they define an empty SPU, nothing more to do */ if (G_UNLIKELY (ke->spu_right - ke->spu_left < 0 @@ -501,13 +524,16 @@ 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); return GST_FLOW_OK; } /* create the palette */ rflow = gst_kate_spu_create_spu_palette (ke, kp); - if (G_UNLIKELY (rflow != GST_FLOW_OK)) + if (G_UNLIKELY (rflow != GST_FLOW_OK)) { + gst_buffer_unmap (buf, data, size); return rflow; + } /* create the bitmap */ kate_bitmap_init (kb); @@ -517,14 +543,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_ELEMENT_ERROR (ke, STREAM, ENCODE, (NULL), ("Failed to allocate memory for pixel data")); return GST_FLOW_ERROR; } n = 0; - pixptr[0] = GST_BUFFER_DATA (buf) + ke->spu_pix_data[0]; - pixptr[1] = GST_BUFFER_DATA (buf) + ke->spu_pix_data[1]; + pixptr[0] = data + ke->spu_pix_data[0]; + pixptr[1] = 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]); @@ -591,6 +618,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); return GST_FLOW_OK; } @@ -856,15 +884,12 @@ gst_kate_spu_encode_spu (GstKateDec * kd, const kate_event * ev) bytes[3] = first_commands_offset & 0xff; /* Create a buffer with those values */ - buffer = gst_buffer_new (); + buffer = gst_buffer_new_wrapped (bytes, nbytes); if (G_UNLIKELY (!buffer)) { GST_WARNING_OBJECT (kd, "Failed to allocate %" G_GSIZE_FORMAT " byte buffer", nbytes); goto error; } - GST_BUFFER_DATA (buffer) = bytes; - GST_BUFFER_MALLOCDATA (buffer) = bytes; - GST_BUFFER_SIZE (buffer) = nbytes; GST_BUFFER_OFFSET_END (buffer) = GST_SECOND * (ev->end_time); GST_BUFFER_OFFSET (buffer) = GST_SECOND * (ev->start_time); GST_BUFFER_TIMESTAMP (buffer) = GST_SECOND * (ev->start_time); diff --git a/ext/kate/gstkatetag.c b/ext/kate/gstkatetag.c index 34d8cf26df..38e2a3c35a 100644 --- a/ext/kate/gstkatetag.c +++ b/ext/kate/gstkatetag.c @@ -97,38 +97,19 @@ static void gst_kate_tag_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); static void gst_kate_tag_dispose (GObject * object); - -#define _do_init(type) \ - G_STMT_START{ \ - static const GInterfaceInfo tag_setter_info = { \ - NULL, \ - NULL, \ - NULL \ - }; \ - g_type_add_interface_static (type, GST_TYPE_TAG_SETTER, \ - &tag_setter_info); \ - }G_STMT_END - -GST_BOILERPLATE_FULL (GstKateTag, gst_kate_tag, GstKateParse, - GST_TYPE_KATE_PARSE, _do_init); - -static void -gst_kate_tag_base_init (gpointer g_class) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); - - gst_element_class_set_details_simple (element_class, "Kate stream tagger", - "Formatter/Metadata", - "Retags kate streams", "Vincent Penquerc'h "); -} +#define gst_kate_tag_parent_class parent_class +G_DEFINE_TYPE_WITH_CODE (GstKateTag, gst_kate_tag, GST_TYPE_KATE_PARSE, + G_IMPLEMENT_INTERFACE (GST_TYPE_TAG_SETTER, NULL)); static void gst_kate_tag_class_init (GstKateTagClass * klass) { GObjectClass *gobject_class; + GstElementClass *gstelement_class; GstKateParseClass *gstkateparse_class; gobject_class = (GObjectClass *) klass; + gstelement_class = (GstElementClass *) klass; gstkateparse_class = GST_KATE_PARSE_CLASS (klass); gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_kate_tag_set_property); @@ -155,12 +136,16 @@ gst_kate_tag_class_init (GstKateTagClass * klass) "Set the height of the canvas this stream was authored for (0 is unspecified)", 0, G_MAXINT, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + gst_element_class_set_details_simple (gstelement_class, "Kate stream tagger", + "Formatter/Metadata", + "Retags kate streams", "Vincent Penquerc'h "); + gstkateparse_class->parse_packet = GST_DEBUG_FUNCPTR (gst_kate_tag_parse_packet); } static void -gst_kate_tag_init (GstKateTag * kt, GstKateTagClass * g_class) +gst_kate_tag_init (GstKateTag * kt) { kt->language = NULL; kt->category = NULL; @@ -281,44 +266,52 @@ gst_kate_tag_parse_packet (GstKateParse * parse, GstBuffer * buffer) GstKateTag *kt; gchar *encoder = NULL; GstBuffer *new_buf; + guint8 *data; + gsize size; kt = GST_KATE_TAG (parse); - /* rewrite the language and category */ - if (GST_BUFFER_SIZE (buffer) >= 64 && GST_BUFFER_DATA (buffer)[0] == 0x80) { - GstBuffer *new_buffer = gst_buffer_copy (buffer); + data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ); + /* rewrite the language and category */ + if (size >= 64 && data[0] == 0x80) { + GstBuffer *new_buffer; + + gst_buffer_unmap (buffer, data, size); + new_buffer = gst_buffer_copy (buffer); gst_buffer_unref (buffer); buffer = new_buffer; + data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READWRITE); /* language is at offset 32, 16 bytes, zero terminated */ if (kt->language) { - strncpy ((char *) GST_BUFFER_DATA (buffer) + 32, kt->language, 15); - GST_BUFFER_DATA (buffer)[47] = 0; + strncpy ((char *) data + 32, kt->language, 15); + data[47] = 0; } /* category is at offset 48, 16 bytes, zero terminated */ if (kt->category) { - strncpy ((char *) GST_BUFFER_DATA (buffer) + 48, kt->category, 15); - GST_BUFFER_DATA (buffer)[63] = 0; + strncpy ((char *) data + 48, kt->category, 15); + data[63] = 0; } if (kt->original_canvas_width >= 0) { guint16 v = encode_canvas_size (kt->original_canvas_width); - GST_BUFFER_DATA (buffer)[16] = v & 0xff; - GST_BUFFER_DATA (buffer)[17] = (v >> 8) & 0xff; + data[16] = v & 0xff; + data[17] = (v >> 8) & 0xff; } if (kt->original_canvas_height >= 0) { guint16 v = encode_canvas_size (kt->original_canvas_height); - GST_BUFFER_DATA (buffer)[18] = v & 0xff; - GST_BUFFER_DATA (buffer)[19] = (v >> 8) & 0xff; + data[18] = v & 0xff; + data[19] = (v >> 8) & 0xff; } } /* rewrite the comments packet */ - if (GST_BUFFER_SIZE (buffer) >= 9 && GST_BUFFER_DATA (buffer)[0] == 0x81) { + if (size >= 9 && data[0] == 0x81) { old_tags = - gst_tag_list_from_vorbiscomment_buffer (buffer, + gst_tag_list_from_vorbiscomment (data, 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); /* build new tag list */ new_tags = gst_tag_list_merge (user_tags, old_tags, @@ -328,16 +321,18 @@ gst_kate_tag_parse_packet (GstKateParse * parse, GstBuffer * buffer) new_buf = gst_tag_list_to_vorbiscomment_buffer (new_tags, (const guint8 *) "\201kate\0\0\0\0", 9, encoder); - gst_buffer_copy_metadata (new_buf, buffer, GST_BUFFER_COPY_TIMESTAMPS); + gst_buffer_copy_into (new_buf, buffer, GST_BUFFER_COPY_TIMESTAMPS, 0, -1); gst_tag_list_free (new_tags); g_free (encoder); gst_buffer_unref (buffer); /* the buffer will have the framing bit used by Vorbis, but we don't use it */ - --GST_BUFFER_SIZE (new_buf); + gst_buffer_resize (new_buf, 0, gst_buffer_get_size (new_buf) - 1); buffer = new_buf; + } else { + gst_buffer_unmap (buffer, data, size); } return GST_KATE_PARSE_CLASS (parent_class)->parse_packet (parse, buffer); diff --git a/ext/kate/gstkateutil.c b/ext/kate/gstkateutil.c index 3062d5cd80..811a838d4d 100644 --- a/ext/kate/gstkateutil.c +++ b/ext/kate/gstkateutil.c @@ -247,12 +247,16 @@ gst_kate_util_decoder_base_chain_kate_packet (GstKateDecoderBase * decoder, int ret; GstFlowReturn rflow = GST_FLOW_OK; gboolean is_header; + guint8 *data; + gsize size; + guint8 header[1]; + + size = gst_buffer_extract (buf, 0, header, 1); GST_DEBUG_OBJECT (element, "got kate packet, %u bytes, type %02x", - GST_BUFFER_SIZE (buf), - GST_BUFFER_SIZE (buf) == 0 ? -1 : GST_BUFFER_DATA (buf)[0]); + gst_buffer_get_size (buf), size == 0 ? -1 : header[0]); - is_header = GST_BUFFER_SIZE (buf) > 0 && (GST_BUFFER_DATA (buf)[0] & 0x80); + is_header = size > 0 && (header[0] & 0x80); if (!is_header && decoder->tags) { /* after we've processed headers, send any tags before processing the data packet */ @@ -262,8 +266,11 @@ gst_kate_util_decoder_base_chain_kate_packet (GstKateDecoderBase * decoder, decoder->tags = NULL; } - kate_packet_wrap (&kp, GST_BUFFER_SIZE (buf), GST_BUFFER_DATA (buf)); + 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 (G_UNLIKELY (ret < 0)) { GST_ELEMENT_ERROR (element, STREAM, DECODE, (NULL), ("Failed to decode Kate packet: %d", ret)); @@ -277,7 +284,7 @@ gst_kate_util_decoder_base_chain_kate_packet (GstKateDecoderBase * decoder, /* headers may be interesting to retrieve information from */ if (G_UNLIKELY (is_header)) { - switch (GST_BUFFER_DATA (buf)[0]) { + switch (header[0]) { case 0x80: /* ID header */ GST_INFO_OBJECT (element, "Parsed ID header: language %s, category %s", decoder->k.ki->language, decoder->k.ki->category); @@ -484,37 +491,23 @@ gst_kate_util_decoder_base_set_flushing (GstKateDecoderBase * decoder, } void -gst_kate_util_decoder_base_new_segment_event (GstKateDecoderBase * decoder, +gst_kate_util_decoder_base_segment_event (GstKateDecoderBase * decoder, GstEvent * event) { - gboolean update; - gdouble rate; - GstFormat format; - gint64 start, stop, time; - gdouble arate; + GstSegment seg; - gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format, - &start, &stop, &time); - GST_DEBUG_OBJECT (decoder, "kate pad segment:" - " Update %d, rate %g arate %g format %d start %" GST_TIME_FORMAT - " %" GST_TIME_FORMAT " position %" GST_TIME_FORMAT, - update, rate, arate, format, GST_TIME_ARGS (start), - GST_TIME_ARGS (stop), GST_TIME_ARGS (time)); - if (!update) { - /* Tiger uses this segment is used to remap the video running time to the - Kate running time. The sending of segment updates to keep streams in sync - does kinda rain on our parade though, and since we don't need these, - we just ignore those here */ - gst_segment_set_newsegment_full (&decoder->kate_segment, update, rate, - arate, format, start, stop, time); - } + gst_event_copy_segment (event, &seg); + + GST_DEBUG_OBJECT (decoder, "kate pad segment: %" GST_SEGMENT_FORMAT, &seg); + + decoder->kate_segment = seg; } gboolean gst_kate_util_decoder_base_update_segment (GstKateDecoderBase * decoder, GstElement * element, GstBuffer * buf) { - gint64 clip_start = 0, clip_stop = 0; + guint64 clip_start = 0, clip_stop = 0; gboolean in_seg; if (decoder->kate_flushing) { @@ -538,8 +531,7 @@ gst_kate_util_decoder_base_update_segment (GstKateDecoderBase * decoder, if (in_seg) { if (GST_BUFFER_TIMESTAMP_IS_VALID (buf)) { - gst_segment_set_last_stop (&decoder->kate_segment, GST_FORMAT_TIME, - clip_start); + decoder->kate_segment.position = clip_start; } } else { GST_INFO_OBJECT (element, "Kate buffer not in segment, ignored"); diff --git a/ext/kate/gstkateutil.h b/ext/kate/gstkateutil.h index 27b6f70f31..a837369dba 100644 --- a/ext/kate/gstkateutil.h +++ b/ext/kate/gstkateutil.h @@ -82,7 +82,7 @@ extern void gst_kate_util_decoder_base_set_flushing (GstKateDecoderBase * decoder, gboolean flushing); extern void -gst_kate_util_decoder_base_new_segment_event (GstKateDecoderBase * decoder, +gst_kate_util_decoder_base_segment_event (GstKateDecoderBase * decoder, GstEvent * event); extern gboolean gst_kate_util_decoder_base_update_segment (GstKateDecoderBase * decoder,