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);
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 <ogg.k.ogg.k@googlemail.com>");
-}
+static GstCaps *gst_kate_dec_src_get_caps (GstPad * pad, GstCaps * filter);
/* initialize the plugin's class */
static void
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 <ogg.k.ogg.k@googlemail.com>");
}
/* initialize the new element
* 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");
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;
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;
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;
}
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;
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 <ogg.k.ogg.k@googlemail.com>");
-}
+#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
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);
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 <ogg.k.ogg.k@googlemail.com>");
}
/* initialize the new element
* 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");
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");
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
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");
#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)) {
("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));
("no text in text packet"));
rflow = GST_FLOW_ERROR;
}
+ gst_buffer_unmap (buf, text, text_len);
}
return rflow;
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;
} else {
GST_WARNING_OBJECT (ke, "Packet has no MIME type, ignored");
}
+ gst_caps_unref (caps);
}
gst_buffer_unref (buf);
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 */
}
/* 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);
}
}
}
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) {
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,
GstBuffer * buf);
static void
-gst_kate_parse_base_init (gpointer g_class)
+gst_kate_parse_class_init (GstKateParseClass * klass)
{
- GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
+ GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
- gst_element_class_add_pad_template (element_class,
+ 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 (element_class,
+ gst_element_class_add_pad_template (gstelement_class,
gst_static_pad_template_get (&gst_kate_parse_sink_factory));
- gst_element_class_set_details_simple (element_class, "Kate stream parser",
+
+ gst_element_class_set_details_simple (gstelement_class, "Kate stream parser",
"Codec/Parser/Subtitle",
"parse raw kate streams",
"Vincent Penquerc'h <ogg.k.ogg.k at googlemail dot com>");
-}
-
-static void
-gst_kate_parse_class_init (GstKateParseClass * klass)
-{
- GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
-
- gstelement_class->change_state = gst_kate_parse_change_state;
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");
/* 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),
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;
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;
}
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);
}
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);
gst_kate_parse_parse_packet (GstKateParse * parse, GstBuffer * buf)
{
GstFlowReturn ret = GST_FLOW_OK;
+ guint8 header[1];
+ gsize size;
g_assert (parse);
parse->packetno++;
+ size = gst_buffer_extract (buf, 0, header, 1);
+
GST_LOG_OBJECT (parse, "Got packet %02x, %u bytes",
- GST_BUFFER_SIZE (buf) ? GST_BUFFER_DATA (buf)[0] : -1,
- GST_BUFFER_SIZE (buf));
+ size ? header[0] : -1, gst_buffer_get_size (buf));
- if (GST_BUFFER_SIZE (buf) > 0 && GST_BUFFER_DATA (buf)[0] & 0x80) {
- GST_DEBUG_OBJECT (parse, "Found header %02x", GST_BUFFER_DATA (buf)[0]);
+ 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);
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);
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:
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);
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
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;
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));
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
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);
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]);
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;
}
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);
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 <ogg.k.ogg.k@googlemail.com>");
-}
+#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);
"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 <ogg.k.ogg.k@googlemail.com>");
+
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;
GstKateTag *kt;
gchar *encoder = NULL;
GstBuffer *new_buf;
+ guint8 *data;
+ gsize size;
kt = GST_KATE_TAG (parse);
+ data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ);
+
/* rewrite the language and category */
- if (GST_BUFFER_SIZE (buffer) >= 64 && GST_BUFFER_DATA (buffer)[0] == 0x80) {
- GstBuffer *new_buffer = gst_buffer_copy (buffer);
+ 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,
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);
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 */
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));
/* 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);
}
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;
-
- 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);
- }
+ GstSegment seg;
+
+ 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) {
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");
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,