mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 18:21:04 +00:00
kate: port Kate subtitles to 1.0
https://bugzilla.gnome.org/show_bug.cgi?id=697071
This commit is contained in:
parent
58e1894139
commit
b261bd516f
8 changed files with 206 additions and 189 deletions
|
@ -318,7 +318,7 @@ GST_PLUGINS_NONPORTED=" aiff \
|
||||||
cdxaparse \
|
cdxaparse \
|
||||||
dccp faceoverlay \
|
dccp faceoverlay \
|
||||||
hdvparse ivfparse jp2kdecimator \
|
hdvparse ivfparse jp2kdecimator \
|
||||||
kate librfb \
|
librfb \
|
||||||
mve mythtv nsf nuvdemux \
|
mve mythtv nsf nuvdemux \
|
||||||
patchdetect real \
|
patchdetect real \
|
||||||
sdi stereo tta \
|
sdi stereo tta \
|
||||||
|
|
|
@ -114,7 +114,8 @@ static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
|
||||||
static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
|
static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
|
||||||
GST_PAD_SRC,
|
GST_PAD_SRC,
|
||||||
GST_PAD_ALWAYS,
|
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
|
#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,
|
static void gst_kate_dec_get_property (GObject * object, guint prop_id,
|
||||||
GValue * value, GParamSpec * pspec);
|
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,
|
static GstStateChangeReturn gst_kate_dec_change_state (GstElement * element,
|
||||||
GstStateChange transition);
|
GstStateChange transition);
|
||||||
static gboolean gst_kate_dec_sink_query (GstPad * pad, GstQuery * query);
|
static gboolean gst_kate_dec_sink_query (GstPad * pad, GstObject * parent,
|
||||||
static gboolean gst_kate_dec_sink_event (GstPad * pad, GstEvent * event);
|
GstQuery * query);
|
||||||
static gboolean gst_kate_dec_sink_handle_event (GstPad * pad, GstEvent * event);
|
static gboolean gst_kate_dec_sink_event (GstPad * pad, GstObject * parent,
|
||||||
static GstCaps *gst_kate_dec_src_get_caps (GstPad * pad, GstCaps * filter);
|
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 */
|
/* initialize the plugin's class */
|
||||||
static void
|
static void
|
||||||
|
@ -190,8 +196,8 @@ gst_kate_dec_init (GstKateDec * dec)
|
||||||
gst_element_add_pad (GST_ELEMENT (dec), dec->sinkpad);
|
gst_element_add_pad (GST_ELEMENT (dec), dec->sinkpad);
|
||||||
|
|
||||||
dec->srcpad = gst_pad_new_from_static_template (&src_factory, "src");
|
dec->srcpad = gst_pad_new_from_static_template (&src_factory, "src");
|
||||||
gst_pad_set_getcaps_function (dec->srcpad,
|
gst_pad_set_query_function (dec->srcpad,
|
||||||
GST_DEBUG_FUNCPTR (gst_kate_dec_src_get_caps));
|
GST_DEBUG_FUNCPTR (gst_kate_dec_src_query));
|
||||||
gst_element_add_pad (GST_ELEMENT (dec), dec->srcpad);
|
gst_element_add_pad (GST_ELEMENT (dec), dec->srcpad);
|
||||||
|
|
||||||
gst_kate_util_decode_base_init (&dec->decoder, TRUE);
|
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
|
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;
|
const kate_event *ev = NULL;
|
||||||
GstFlowReturn rflow = GST_FLOW_OK;
|
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,
|
GST_ELEMENT_CAST (kd), pad, buf, kd->srcpad, kd->srcpad, &kd->src_caps,
|
||||||
&ev);
|
&ev);
|
||||||
if (G_UNLIKELY (rflow != GST_FLOW_OK)) {
|
if (G_UNLIKELY (rflow != GST_FLOW_OK)) {
|
||||||
gst_object_unref (kd);
|
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
return rflow;
|
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);
|
GST_DEBUG_OBJECT (kd, "kate event: %s, escaped %s", ev->text, escaped);
|
||||||
buffer = gst_buffer_new_and_alloc (len + 1);
|
buffer = gst_buffer_new_and_alloc (len + 1);
|
||||||
if (G_LIKELY (buffer)) {
|
if (G_LIKELY (buffer)) {
|
||||||
const char *mime = plain ? "text/plain" : "text/x-pango-markup";
|
GstCaps *caps;
|
||||||
GstCaps *caps = gst_caps_new_empty_simple (mime);
|
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);
|
gst_caps_unref (caps);
|
||||||
/* allocate and copy the NULs, but don't include them in passed size */
|
/* allocate and copy the NULs, but don't include them in passed size */
|
||||||
gst_buffer_fill (buffer, 0, escaped, len + 1);
|
gst_buffer_fill (buffer, 0, escaped, len + 1);
|
||||||
|
@ -343,7 +354,6 @@ gst_kate_dec_chain (GstPad * pad, GstBuffer * buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
not_in_seg:
|
not_in_seg:
|
||||||
gst_object_unref (kd);
|
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
return rflow;
|
return rflow;
|
||||||
}
|
}
|
||||||
|
@ -365,42 +375,39 @@ gst_kate_dec_change_state (GstElement * element, GstStateChange transition)
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
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 =
|
gboolean res =
|
||||||
gst_kate_decoder_base_sink_query (&kd->decoder, GST_ELEMENT_CAST (kd),
|
gst_kate_decoder_base_sink_query (&kd->decoder, GST_ELEMENT_CAST (kd),
|
||||||
pad, query);
|
pad, parent, query);
|
||||||
gst_object_unref (kd);
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
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;
|
gboolean res = TRUE;
|
||||||
|
|
||||||
GST_LOG_OBJECT (pad, "Event on sink pad: %s", GST_EVENT_TYPE_NAME (event));
|
GST_LOG_OBJECT (pad, "Event on sink pad: %s", GST_EVENT_TYPE_NAME (event));
|
||||||
|
|
||||||
/* Delay events till we've set caps */
|
/* Delay events till we've set caps */
|
||||||
if (gst_kate_util_decoder_base_queue_event (&kd->decoder, event,
|
if (gst_kate_util_decoder_base_queue_event (&kd->decoder, event,
|
||||||
&gst_kate_dec_sink_handle_event, pad)) {
|
&gst_kate_dec_sink_handle_event, parent, pad)) {
|
||||||
gst_object_unref (kd);
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = gst_kate_dec_sink_handle_event (pad, event);
|
res = gst_kate_dec_sink_handle_event (pad, parent, event);
|
||||||
|
|
||||||
gst_object_unref (kd);
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
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;
|
gboolean res = TRUE;
|
||||||
|
|
||||||
GST_LOG_OBJECT (pad, "Handling event on sink pad: %s",
|
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)) {
|
switch (GST_EVENT_TYPE (event)) {
|
||||||
case GST_EVENT_SEGMENT:
|
case GST_EVENT_SEGMENT:
|
||||||
gst_kate_util_decoder_base_segment_event (&kd->decoder, event);
|
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;
|
break;
|
||||||
|
|
||||||
case GST_EVENT_FLUSH_START:
|
case GST_EVENT_FLUSH_START:
|
||||||
gst_kate_util_decoder_base_set_flushing (&kd->decoder, TRUE);
|
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;
|
break;
|
||||||
|
|
||||||
case GST_EVENT_FLUSH_STOP:
|
case GST_EVENT_FLUSH_STOP:
|
||||||
gst_kate_util_decoder_base_set_flushing (&kd->decoder, FALSE);
|
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;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
res = gst_pad_event_default (pad, event);
|
res = gst_pad_event_default (pad, parent, event);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_object_unref (kd);
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstCaps *
|
static gboolean
|
||||||
gst_kate_dec_src_get_caps (GstPad * pad, GstCaps * filter)
|
gst_kate_dec_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
|
||||||
{
|
{
|
||||||
GstKateDec *kd = (GstKateDec *) (gst_object_get_parent (GST_OBJECT (pad)));
|
GstKateDec *kd = GST_KATE_DEC (parent);
|
||||||
GstCaps *caps;
|
gboolean res = TRUE;
|
||||||
|
|
||||||
if (kd->src_caps) {
|
GST_LOG_OBJECT (pad, "Handling query on src pad: %s",
|
||||||
GST_DEBUG_OBJECT (kd, "We have src caps %" GST_PTR_FORMAT, kd->src_caps);
|
GST_QUERY_TYPE_NAME (query));
|
||||||
caps = kd->src_caps;
|
|
||||||
} else {
|
switch (GST_QUERY_TYPE (query)) {
|
||||||
GST_DEBUG_OBJECT (kd, "We have no src caps, using template caps");
|
case GST_QUERY_CAPS:{
|
||||||
caps = gst_static_pad_template_get_caps (&src_factory);
|
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);
|
return res;
|
||||||
|
|
||||||
gst_object_unref (kd);
|
|
||||||
return caps;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,7 +120,8 @@ enum
|
||||||
static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
|
static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
|
||||||
GST_PAD_SINK,
|
GST_PAD_SINK,
|
||||||
GST_PAD_ALWAYS,
|
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",
|
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 void gst_kate_enc_dispose (GObject * object);
|
||||||
|
|
||||||
static gboolean gst_kate_enc_setcaps (GstPad * pad, GstCaps * caps);
|
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,
|
static GstStateChangeReturn gst_kate_enc_change_state (GstElement * element,
|
||||||
GstStateChange transition);
|
GstStateChange transition);
|
||||||
static gboolean gst_kate_enc_sink_event (GstPad * pad, GstEvent * event);
|
static gboolean gst_kate_enc_sink_event (GstPad * pad, GstObject * parent,
|
||||||
static const GstQueryType *gst_kate_enc_source_query_type (GstPad * pad);
|
GstEvent * event);
|
||||||
static gboolean gst_kate_enc_source_query (GstPad * pad, GstQuery * query);
|
static gboolean gst_kate_enc_source_query (GstPad * pad, GstObject * parent,
|
||||||
|
GstQuery * query);
|
||||||
|
|
||||||
#define gst_kate_enc_parent_class parent_class
|
#define gst_kate_enc_parent_class parent_class
|
||||||
G_DEFINE_TYPE_WITH_CODE (GstKateEnc, gst_kate_enc, GST_TYPE_ELEMENT,
|
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);
|
gst_element_add_pad (GST_ELEMENT (ke), ke->sinkpad);
|
||||||
|
|
||||||
ke->srcpad = gst_pad_new_from_static_template (&src_factory, "src");
|
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_pad_set_query_function (ke->srcpad,
|
||||||
GST_DEBUG_FUNCPTR (gst_kate_enc_source_query));
|
GST_DEBUG_FUNCPTR (gst_kate_enc_source_query));
|
||||||
gst_element_add_pad (GST_ELEMENT (ke), ke->srcpad);
|
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) {
|
if (ke->category != NULL) {
|
||||||
GstStructure *s = gst_caps_get_structure (caps, 0);
|
GstStructure *s = gst_caps_get_structure (caps, 0);
|
||||||
|
|
||||||
if (gst_structure_has_name (s, "text/plain") ||
|
if (gst_structure_has_name (s, "text/plain")) {
|
||||||
gst_structure_has_name (s, "text/x-pango-markup")) {
|
|
||||||
if (strcmp (ke->category, "K-SPU") == 0 ||
|
if (strcmp (ke->category, "K-SPU") == 0 ||
|
||||||
strcmp (ke->category, "spu-subtitles") == 0) {
|
strcmp (ke->category, "spu-subtitles") == 0) {
|
||||||
GST_ELEMENT_WARNING (ke, LIBRARY, SETTINGS, (NULL),
|
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)));
|
gst_kate_util_get_error_message (ret)));
|
||||||
rflow = GST_FLOW_ERROR;
|
rflow = GST_FLOW_ERROR;
|
||||||
} else {
|
} else {
|
||||||
const char *text;
|
GstMapInfo info;
|
||||||
size_t text_len;
|
|
||||||
gboolean need_unmap = TRUE;
|
gboolean need_unmap = TRUE;
|
||||||
kate_float t0 = start / (double) GST_SECOND;
|
kate_float t0 = start / (double) GST_SECOND;
|
||||||
kate_float t1 = stop / (double) GST_SECOND;
|
kate_float t1 = stop / (double) GST_SECOND;
|
||||||
|
|
||||||
text = gst_buffer_map (buf, &text_len, NULL, GST_MAP_READ);
|
if (!gst_buffer_map (buf, &info, GST_MAP_READ)) {
|
||||||
if (text == NULL) {
|
info.data = NULL;
|
||||||
text = "";
|
info.size = 0;
|
||||||
text_len = 0;
|
|
||||||
need_unmap = FALSE;
|
need_unmap = FALSE;
|
||||||
|
GST_WARNING_OBJECT (buf, "Failed to map buffer");
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_LOG_OBJECT (ke, "Encoding text: %*.*s (%u bytes) from %f to %f",
|
GST_LOG_OBJECT (ke, "Encoding text: %*.*s (%u bytes) from %f to %f",
|
||||||
(int) text_len, (int) text_len, GST_BUFFER_DATA (buf),
|
(int) info.size, (int) info.size, info.data, (int) info.size, t0, t1);
|
||||||
GST_BUFFER_SIZE (buf), t0, t1);
|
ret = kate_encode_text (&ke->k, t0, t1, (const char *) info.data, info.size,
|
||||||
ret = kate_encode_text (&ke->k, t0, t1, text, text_len, &kp);
|
&kp);
|
||||||
if (G_UNLIKELY (ret < 0)) {
|
if (G_UNLIKELY (ret < 0)) {
|
||||||
GST_ELEMENT_ERROR (ke, STREAM, ENCODE, (NULL),
|
GST_ELEMENT_ERROR (ke, STREAM, ENCODE, (NULL),
|
||||||
("Failed to encode text: %s", gst_kate_util_get_error_message (ret)));
|
("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);
|
rflow = gst_kate_enc_chain_push_packet (ke, &kp, start, stop - start + 1);
|
||||||
}
|
}
|
||||||
if (need_unmap)
|
if (need_unmap)
|
||||||
gst_buffer_unmap (buf, text, text_len);
|
gst_buffer_unmap (buf, &info);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rflow;
|
return rflow;
|
||||||
|
@ -961,9 +960,9 @@ gst_kate_enc_chain_text (GstKateEnc * ke, GstBuffer * buf,
|
||||||
* this function does the actual processing
|
* this function does the actual processing
|
||||||
*/
|
*/
|
||||||
static GstFlowReturn
|
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;
|
GstFlowReturn rflow = GST_FLOW_OK;
|
||||||
GstCaps *caps;
|
GstCaps *caps;
|
||||||
const gchar *mime_type = NULL;
|
const gchar *mime_type = NULL;
|
||||||
|
@ -1007,9 +1006,6 @@ gst_kate_enc_chain (GstPad * pad, GstBuffer * buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
|
|
||||||
gst_object_unref (ke);
|
|
||||||
|
|
||||||
GST_LOG_OBJECT (ke, "Leaving chain function");
|
GST_LOG_OBJECT (ke, "Leaving chain function");
|
||||||
|
|
||||||
return rflow;
|
return rflow;
|
||||||
|
@ -1192,27 +1188,11 @@ gst_kate_enc_convert (GstPad * pad, GstFormat src_fmt, gint64 src_val,
|
||||||
return res;
|
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
|
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;
|
gboolean res = FALSE;
|
||||||
|
|
||||||
ke = GST_KATE_ENC (gst_pad_get_parent (pad));
|
|
||||||
|
|
||||||
GST_DEBUG ("source query %d", GST_QUERY_TYPE (query));
|
GST_DEBUG ("source query %d", GST_QUERY_TYPE (query));
|
||||||
|
|
||||||
switch (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);
|
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)) {
|
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);
|
gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
|
||||||
res = TRUE;
|
res = TRUE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
res = gst_pad_query_default (pad, query);
|
res = gst_pad_query_default (pad, parent, query);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_object_unref (ke);
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
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;
|
const GstStructure *structure;
|
||||||
gboolean ret;
|
gboolean ret;
|
||||||
|
|
||||||
|
@ -1359,7 +1337,7 @@ gst_kate_enc_sink_event (GstPad * pad, GstEvent * event)
|
||||||
} else {
|
} else {
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
}
|
}
|
||||||
ret = gst_pad_event_default (pad, event);
|
ret = gst_pad_event_default (pad, parent, event);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GST_EVENT_EOS:
|
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;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
GST_LOG_OBJECT (ke, "Got unhandled event");
|
GST_LOG_OBJECT (ke, "Got unhandled event");
|
||||||
ret = gst_pad_event_default (pad, event);
|
ret = gst_pad_event_default (pad, parent, event);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_object_unref (ke);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,11 +86,14 @@ static GstStaticPadTemplate gst_kate_parse_src_factory =
|
||||||
#define gst_kate_parse_parent_class parent_class
|
#define gst_kate_parse_parent_class parent_class
|
||||||
G_DEFINE_TYPE (GstKateParse, gst_kate_parse, GST_TYPE_ELEMENT);
|
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,
|
static GstStateChangeReturn gst_kate_parse_change_state (GstElement * element,
|
||||||
GstStateChange transition);
|
GstStateChange transition);
|
||||||
static gboolean gst_kate_parse_sink_event (GstPad * pad, GstEvent * event);
|
static gboolean gst_kate_parse_sink_event (GstPad * pad, GstObject * parent,
|
||||||
static gboolean gst_kate_parse_src_query (GstPad * pad, GstQuery * query);
|
GstEvent * event);
|
||||||
|
static gboolean gst_kate_parse_src_query (GstPad * pad, GstObject * parent,
|
||||||
|
GstQuery * query);
|
||||||
#if 0
|
#if 0
|
||||||
static gboolean gst_kate_parse_convert (GstPad * pad,
|
static gboolean gst_kate_parse_convert (GstPad * pad,
|
||||||
GstFormat src_format, gint64 src_value,
|
GstFormat src_format, gint64 src_value,
|
||||||
|
@ -144,7 +147,7 @@ gst_kate_parse_drain_event_queue (GstKateParse * parse)
|
||||||
GstEvent *event;
|
GstEvent *event;
|
||||||
|
|
||||||
event = GST_EVENT_CAST (g_queue_pop_head (parse->event_queue));
|
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;
|
headers = parse->streamheader;
|
||||||
while (headers) {
|
while (headers) {
|
||||||
guint8 *data;
|
GstMapInfo info;
|
||||||
gsize size;
|
|
||||||
|
|
||||||
outbuf = GST_BUFFER_CAST (headers->data);
|
outbuf = GST_BUFFER_CAST (headers->data);
|
||||||
|
|
||||||
data = gst_buffer_map (outbuf, &size, NULL, GST_MAP_READ);
|
if (!gst_buffer_map (outbuf, &info, GST_MAP_READ)) {
|
||||||
kate_packet_wrap (&packet, size, data);
|
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);
|
ret = kate_decode_headerin (&parse->ki, &parse->kc, &packet);
|
||||||
if (G_UNLIKELY (ret < 0)) {
|
if (G_UNLIKELY (ret < 0)) {
|
||||||
GST_WARNING_OBJECT (parse, "Failed to decode header: %s",
|
GST_WARNING_OBJECT (parse, "Failed to decode header: %s",
|
||||||
gst_kate_util_get_error_message (ret));
|
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 */
|
/* takes ownership of outbuf, which was previously in parse->streamheader */
|
||||||
outbuf_list = g_list_append (outbuf_list, outbuf);
|
outbuf_list = g_list_append (outbuf_list, outbuf);
|
||||||
headers = headers->next;
|
headers = headers->next;
|
||||||
|
@ -379,7 +385,7 @@ gst_kate_parse_parse_packet (GstKateParse * parse, GstBuffer * buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_kate_parse_chain (GstPad * pad, GstBuffer * buffer)
|
gst_kate_parse_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
|
||||||
{
|
{
|
||||||
GstKateParseClass *klass;
|
GstKateParseClass *klass;
|
||||||
GstKateParse *parse;
|
GstKateParse *parse;
|
||||||
|
@ -406,39 +412,36 @@ gst_kate_parse_queue_event (GstKateParse * parse, GstEvent * event)
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_kate_parse_sink_event (GstPad * pad, GstEvent * event)
|
gst_kate_parse_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
|
||||||
{
|
{
|
||||||
gboolean ret;
|
gboolean ret;
|
||||||
GstKateParse *parse;
|
GstKateParse *parse;
|
||||||
|
|
||||||
parse = GST_KATE_PARSE (gst_pad_get_parent (pad));
|
parse = GST_KATE_PARSE (parent);
|
||||||
|
|
||||||
switch (GST_EVENT_TYPE (event)) {
|
switch (GST_EVENT_TYPE (event)) {
|
||||||
case GST_EVENT_FLUSH_START:
|
case GST_EVENT_FLUSH_START:
|
||||||
gst_kate_parse_clear_queue (parse);
|
gst_kate_parse_clear_queue (parse);
|
||||||
ret = gst_pad_event_default (pad, event);
|
ret = gst_pad_event_default (pad, parent, event);
|
||||||
break;
|
break;
|
||||||
case GST_EVENT_EOS:
|
case GST_EVENT_EOS:
|
||||||
if (!parse->streamheader_sent) {
|
if (!parse->streamheader_sent) {
|
||||||
GST_DEBUG_OBJECT (parse, "Got EOS, pushing headers seen so far");
|
GST_DEBUG_OBJECT (parse, "Got EOS, pushing headers seen so far");
|
||||||
ret = gst_kate_parse_push_headers (parse);
|
ret = gst_kate_parse_push_headers (parse);
|
||||||
if (ret != GST_FLOW_OK)
|
if (ret != GST_FLOW_OK)
|
||||||
goto done;
|
break;
|
||||||
}
|
}
|
||||||
gst_kate_parse_drain_queue_prematurely (parse);
|
gst_kate_parse_drain_queue_prematurely (parse);
|
||||||
ret = gst_pad_event_default (pad, event);
|
ret = gst_pad_event_default (pad, parent, event);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (!parse->streamheader_sent && GST_EVENT_IS_SERIALIZED (event))
|
if (!parse->streamheader_sent && GST_EVENT_IS_SERIALIZED (event))
|
||||||
ret = gst_kate_parse_queue_event (parse, event);
|
ret = gst_kate_parse_queue_event (parse, event);
|
||||||
else
|
else
|
||||||
ret = gst_pad_event_default (pad, event);
|
ret = gst_pad_event_default (pad, parent, event);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
|
||||||
gst_object_unref (parse);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -493,7 +496,7 @@ gst_kate_parse_convert (GstPad * pad,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_kate_parse_src_query (GstPad * pad, GstQuery * query)
|
gst_kate_parse_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
|
||||||
{
|
{
|
||||||
#if 1
|
#if 1
|
||||||
// TODO
|
// TODO
|
||||||
|
@ -504,7 +507,7 @@ gst_kate_parse_src_query (GstPad * pad, GstQuery * query)
|
||||||
GstKateParse *parse;
|
GstKateParse *parse;
|
||||||
gboolean res = FALSE;
|
gboolean res = FALSE;
|
||||||
|
|
||||||
parse = GST_KATE_PARSE (GST_PAD_PARENT (pad));
|
parse = GST_KATE_PARSE (parent);
|
||||||
|
|
||||||
switch (GST_QUERY_TYPE (query)) {
|
switch (GST_QUERY_TYPE (query)) {
|
||||||
case GST_QUERY_POSITION:
|
case GST_QUERY_POSITION:
|
||||||
|
|
|
@ -276,17 +276,19 @@ gst_kate_spu_decode_command_sequence (GstKateEnc * ke, GstBuffer * buf,
|
||||||
guint16 date;
|
guint16 date;
|
||||||
guint16 next_command_sequence;
|
guint16 next_command_sequence;
|
||||||
const guint8 *ptr;
|
const guint8 *ptr;
|
||||||
guint8 *data;
|
GstMapInfo info;
|
||||||
guint16 sz;
|
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;
|
goto out_of_range;
|
||||||
|
|
||||||
ptr = data + command_sequence_offset;
|
ptr = info.data + command_sequence_offset;
|
||||||
sz = size - command_sequence_offset;
|
sz = info.size - command_sequence_offset;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (ke, "Decoding command sequence at %u (%u bytes)",
|
GST_DEBUG_OBJECT (ke, "Decoding command sequence at %u (%u bytes)",
|
||||||
command_sequence_offset, sz);
|
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) {
|
if (next_command_sequence != command_sequence_offset) {
|
||||||
GST_DEBUG_OBJECT (ke, "Jumping to next sequence at offset %u",
|
GST_DEBUG_OBJECT (ke, "Jumping to next sequence at offset %u",
|
||||||
next_command_sequence);
|
next_command_sequence);
|
||||||
gst_buffer_unmap (buf, data, size);
|
gst_buffer_unmap (buf, &info);
|
||||||
return gst_kate_spu_decode_command_sequence (ke, buf,
|
return gst_kate_spu_decode_command_sequence (ke, buf,
|
||||||
next_command_sequence);
|
next_command_sequence);
|
||||||
} else {
|
} else {
|
||||||
gst_buffer_unmap (buf, data, size);
|
gst_buffer_unmap (buf, &info);
|
||||||
GST_DEBUG_OBJECT (ke, "No more sequences to decode");
|
GST_DEBUG_OBJECT (ke, "No more sequences to decode");
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
gst_buffer_unmap (buf, data, size);
|
gst_buffer_unmap (buf, &info);
|
||||||
GST_ELEMENT_ERROR (ke, STREAM, ENCODE, (NULL),
|
GST_ELEMENT_ERROR (ke, STREAM, ENCODE, (NULL),
|
||||||
("Invalid SPU command: %u", cmd));
|
("Invalid SPU command: %u", cmd));
|
||||||
return GST_FLOW_ERROR;
|
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"));
|
GST_ELEMENT_ERROR (ke, STREAM, ENCODE, (NULL), ("Error parsing SPU"));
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
|
|
||||||
/* ERRORS */
|
/* ERRORS */
|
||||||
out_of_range:
|
out_of_range:
|
||||||
{
|
{
|
||||||
gst_buffer_unmap (buf, data, size);
|
gst_buffer_unmap (buf, &info);
|
||||||
GST_ELEMENT_ERROR (ke, STREAM, DECODE, (NULL),
|
GST_ELEMENT_ERROR (ke, STREAM, DECODE, (NULL),
|
||||||
("Command sequence offset %u is out of range %u",
|
("Command sequence offset %u is out of range %u",
|
||||||
command_sequence_offset, size));
|
command_sequence_offset, info.size));
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -465,8 +467,7 @@ GstFlowReturn
|
||||||
gst_kate_spu_decode_spu (GstKateEnc * ke, GstBuffer * buf, kate_region * kr,
|
gst_kate_spu_decode_spu (GstKateEnc * ke, GstBuffer * buf, kate_region * kr,
|
||||||
kate_bitmap * kb, kate_palette * kp)
|
kate_bitmap * kb, kate_palette * kp)
|
||||||
{
|
{
|
||||||
guint8 *data;
|
GstMapInfo info;
|
||||||
gsize size;
|
|
||||||
const guint8 *ptr;
|
const guint8 *ptr;
|
||||||
size_t sz;
|
size_t sz;
|
||||||
guint16 packet_size;
|
guint16 packet_size;
|
||||||
|
@ -479,10 +480,12 @@ gst_kate_spu_decode_spu (GstKateEnc * ke, GstBuffer * buf, kate_region * kr,
|
||||||
guint16 next_command_sequence;
|
guint16 next_command_sequence;
|
||||||
guint16 code;
|
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;
|
ptr = info.data;
|
||||||
sz = size;
|
sz = info.size;
|
||||||
|
|
||||||
/* before decoding anything, initialize to sensible defaults */
|
/* before decoding anything, initialize to sensible defaults */
|
||||||
memset (ke->spu_colormap, 0, sizeof (ke->spu_colormap));
|
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);
|
packet_size = GST_KATE_UINT16_BE (ptr);
|
||||||
ADVANCE (2);
|
ADVANCE (2);
|
||||||
GST_DEBUG_OBJECT (ke, "packet size %u (GstBuffer size %u)", packet_size,
|
GST_DEBUG_OBJECT (ke, "packet size %u (GstBuffer size %u)", packet_size,
|
||||||
size);
|
info.size);
|
||||||
|
|
||||||
CHECK (2);
|
CHECK (2);
|
||||||
next_command_sequence = GST_KATE_UINT16_BE (ptr);
|
next_command_sequence = GST_KATE_UINT16_BE (ptr);
|
||||||
ADVANCE (2);
|
ADVANCE (2);
|
||||||
ptr = data + next_command_sequence;
|
ptr = info.data + next_command_sequence;
|
||||||
sz = size - next_command_sequence;
|
sz = info.size - next_command_sequence;
|
||||||
GST_DEBUG_OBJECT (ke, "next command sequence at %u for %u",
|
GST_DEBUG_OBJECT (ke, "next command sequence at %u for %u",
|
||||||
next_command_sequence, (guint) sz);
|
next_command_sequence, (guint) sz);
|
||||||
|
|
||||||
rflow = gst_kate_spu_decode_command_sequence (ke, buf, next_command_sequence);
|
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);
|
gst_buffer_unmap (buf, &info);
|
||||||
return rflow;
|
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");
|
GST_WARNING_OBJECT (ke, "SPU area is empty, nothing to encode");
|
||||||
kate_bitmap_init (kb);
|
kate_bitmap_init (kb);
|
||||||
kb->width = kb->height = 0;
|
kb->width = kb->height = 0;
|
||||||
gst_buffer_unmap (buf, data, size);
|
gst_buffer_unmap (buf, &info);
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create the palette */
|
/* create the palette */
|
||||||
rflow = gst_kate_spu_create_spu_palette (ke, kp);
|
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);
|
gst_buffer_unmap (buf, &info);
|
||||||
return rflow;
|
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->type = kate_bitmap_type_paletted;
|
||||||
kb->pixels = (unsigned char *) g_malloc (kb->width * kb->height);
|
kb->pixels = (unsigned char *) g_malloc (kb->width * kb->height);
|
||||||
if (G_UNLIKELY (!kb->pixels)) {
|
if (G_UNLIKELY (!kb->pixels)) {
|
||||||
gst_buffer_unmap (buf, data, size);
|
gst_buffer_unmap (buf, &info);
|
||||||
GST_ELEMENT_ERROR (ke, STREAM, ENCODE, (NULL),
|
GST_ELEMENT_ERROR (ke, STREAM, ENCODE, (NULL),
|
||||||
("Failed to allocate memory for pixel data"));
|
("Failed to allocate memory for pixel data"));
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
n = 0;
|
n = 0;
|
||||||
pixptr[0] = data + ke->spu_pix_data[0];
|
pixptr[0] = info.data + ke->spu_pix_data[0];
|
||||||
pixptr[1] = data + ke->spu_pix_data[1];
|
pixptr[1] = info.data + ke->spu_pix_data[1];
|
||||||
nybble_offset[0] = 0;
|
nybble_offset[0] = 0;
|
||||||
nybble_offset[1] = 0;
|
nybble_offset[1] = 0;
|
||||||
max_nybbles[0] = 2 * (packet_size - ke->spu_pix_data[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 */
|
probably going to end before the next one while being readable */
|
||||||
//ke->hide_time = ke->show_time + (1000 * 90 / 1024);
|
//ke->hide_time = ke->show_time + (1000 * 90 / 1024);
|
||||||
}
|
}
|
||||||
gst_buffer_unmap (buf, data, size);
|
gst_buffer_unmap (buf, &info);
|
||||||
|
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -266,52 +266,57 @@ gst_kate_tag_parse_packet (GstKateParse * parse, GstBuffer * buffer)
|
||||||
GstKateTag *kt;
|
GstKateTag *kt;
|
||||||
gchar *encoder = NULL;
|
gchar *encoder = NULL;
|
||||||
GstBuffer *new_buf;
|
GstBuffer *new_buf;
|
||||||
guint8 *data;
|
GstMapInfo info;
|
||||||
gsize size;
|
|
||||||
|
|
||||||
kt = GST_KATE_TAG (parse);
|
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 */
|
/* rewrite the language and category */
|
||||||
if (size >= 64 && data[0] == 0x80) {
|
if (info.size >= 64 && info.data[0] == 0x80) {
|
||||||
GstBuffer *new_buffer;
|
GstBuffer *new_buffer;
|
||||||
|
|
||||||
gst_buffer_unmap (buffer, data, size);
|
gst_buffer_unmap (buffer, &info);
|
||||||
new_buffer = gst_buffer_copy (buffer);
|
new_buffer = gst_buffer_copy (buffer);
|
||||||
gst_buffer_unref (buffer);
|
|
||||||
buffer = new_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 */
|
/* language is at offset 32, 16 bytes, zero terminated */
|
||||||
if (kt->language) {
|
if (kt->language) {
|
||||||
strncpy ((char *) data + 32, kt->language, 15);
|
strncpy ((char *) info.data + 32, kt->language, 15);
|
||||||
data[47] = 0;
|
info.data[47] = 0;
|
||||||
}
|
}
|
||||||
/* category is at offset 48, 16 bytes, zero terminated */
|
/* category is at offset 48, 16 bytes, zero terminated */
|
||||||
if (kt->category) {
|
if (kt->category) {
|
||||||
strncpy ((char *) data + 48, kt->category, 15);
|
strncpy ((char *) info.data + 48, kt->category, 15);
|
||||||
data[63] = 0;
|
info.data[63] = 0;
|
||||||
}
|
}
|
||||||
if (kt->original_canvas_width >= 0) {
|
if (kt->original_canvas_width >= 0) {
|
||||||
guint16 v = encode_canvas_size (kt->original_canvas_width);
|
guint16 v = encode_canvas_size (kt->original_canvas_width);
|
||||||
data[16] = v & 0xff;
|
info.data[16] = v & 0xff;
|
||||||
data[17] = (v >> 8) & 0xff;
|
info.data[17] = (v >> 8) & 0xff;
|
||||||
}
|
}
|
||||||
if (kt->original_canvas_height >= 0) {
|
if (kt->original_canvas_height >= 0) {
|
||||||
guint16 v = encode_canvas_size (kt->original_canvas_height);
|
guint16 v = encode_canvas_size (kt->original_canvas_height);
|
||||||
data[18] = v & 0xff;
|
info.data[18] = v & 0xff;
|
||||||
data[19] = (v >> 8) & 0xff;
|
info.data[19] = (v >> 8) & 0xff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* rewrite the comments packet */
|
/* rewrite the comments packet */
|
||||||
if (size >= 9 && data[0] == 0x81) {
|
if (info.size >= 9 && info.data[0] == 0x81) {
|
||||||
old_tags =
|
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);
|
(const guint8 *) "\201kate\0\0\0\0", 9, &encoder);
|
||||||
user_tags = gst_tag_setter_get_tag_list (GST_TAG_SETTER (kt));
|
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 */
|
/* build new tag list */
|
||||||
new_tags = gst_tag_list_merge (user_tags, old_tags,
|
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;
|
buffer = new_buf;
|
||||||
} else {
|
} else {
|
||||||
gst_buffer_unmap (buffer, data, size);
|
gst_buffer_unmap (buffer, &info);
|
||||||
}
|
}
|
||||||
|
|
||||||
return GST_KATE_PARSE_CLASS (parent_class)->parse_packet (parse, buffer);
|
return GST_KATE_PARSE_CLASS (parent_class)->parse_packet (parse, buffer);
|
||||||
|
|
|
@ -60,7 +60,6 @@ gst_kate_util_set_header_on_caps (GstElement * element, GstCaps * caps,
|
||||||
GValue value = { 0 };
|
GValue value = { 0 };
|
||||||
GstBuffer *buffer = headers->data;
|
GstBuffer *buffer = headers->data;
|
||||||
g_assert (buffer);
|
g_assert (buffer);
|
||||||
GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_IN_CAPS);
|
|
||||||
g_value_init (&value, GST_TYPE_BUFFER);
|
g_value_init (&value, GST_TYPE_BUFFER);
|
||||||
/* as in theoraenc, we need to copy to avoid circular references */
|
/* as in theoraenc, we need to copy to avoid circular references */
|
||||||
buffer = gst_buffer_copy (buffer);
|
buffer = gst_buffer_copy (buffer);
|
||||||
|
@ -142,7 +141,8 @@ gst_kate_util_decode_base_reset (GstKateDecoderBase * decoder)
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
gst_kate_util_decoder_base_queue_event (GstKateDecoderBase * decoder,
|
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;
|
gboolean can_be_queued;
|
||||||
|
|
||||||
|
@ -163,6 +163,7 @@ gst_kate_util_decoder_base_queue_event (GstKateDecoderBase * decoder,
|
||||||
item = g_slice_new (GstKateDecoderBaseQueuedEvent);
|
item = g_slice_new (GstKateDecoderBaseQueuedEvent);
|
||||||
if (item) {
|
if (item) {
|
||||||
item->event = event;
|
item->event = event;
|
||||||
|
item->parent = parent;
|
||||||
item->pad = pad;
|
item->pad = pad;
|
||||||
item->handler = handler;
|
item->handler = handler;
|
||||||
g_queue_push_tail (decoder->event_queue, item);
|
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) {
|
while (decoder->event_queue->length) {
|
||||||
GstKateDecoderBaseQueuedEvent *item = (GstKateDecoderBaseQueuedEvent *)
|
GstKateDecoderBaseQueuedEvent *item = (GstKateDecoderBaseQueuedEvent *)
|
||||||
g_queue_pop_head (decoder->event_queue);
|
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);
|
g_slice_free (GstKateDecoderBaseQueuedEvent, item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -250,29 +251,34 @@ gst_kate_util_decoder_base_chain_kate_packet (GstKateDecoderBase * decoder,
|
||||||
int ret;
|
int ret;
|
||||||
GstFlowReturn rflow = GST_FLOW_OK;
|
GstFlowReturn rflow = GST_FLOW_OK;
|
||||||
gboolean is_header;
|
gboolean is_header;
|
||||||
guint8 *data;
|
GstMapInfo info;
|
||||||
gsize size;
|
gsize header_size;
|
||||||
guint8 header[1];
|
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_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) {
|
if (!is_header && decoder->tags) {
|
||||||
/* after we've processed headers, send any tags before processing the data packet */
|
/* 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_OBJECT (element, "Not a header, sending tags for pad %s:%s",
|
||||||
GST_DEBUG_PAD_NAME (tagpad));
|
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;
|
decoder->tags = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
|
if (gst_buffer_map (buf, &info, GST_MAP_READ)) {
|
||||||
kate_packet_wrap (&kp, size, data);
|
kate_packet_wrap (&kp, info.size, info.data);
|
||||||
ret = kate_high_decode_packetin (&decoder->k, &kp, ev);
|
ret = kate_high_decode_packetin (&decoder->k, &kp, ev);
|
||||||
gst_buffer_unmap (buf, data, size);
|
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)) {
|
if (G_UNLIKELY (ret < 0)) {
|
||||||
GST_ELEMENT_ERROR (element, STREAM, DECODE, (NULL),
|
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) {
|
strcmp (decoder->k.ki->category, "spu-subtitles") == 0) {
|
||||||
*src_caps = gst_caps_new_empty_simple ("subpicture/x-dvd");
|
*src_caps = gst_caps_new_empty_simple ("subpicture/x-dvd");
|
||||||
} else if (decoder->k.ki->text_markup_type == kate_markup_none) {
|
} 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 {
|
} 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);
|
GST_INFO_OBJECT (srcpad, "Setting caps: %" GST_PTR_FORMAT, *src_caps);
|
||||||
if (!gst_pad_set_caps (srcpad, *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);
|
gst_tag_list_unref (old);
|
||||||
|
|
||||||
if (decoder->initialized) {
|
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;
|
decoder->tags = NULL;
|
||||||
} else {
|
} else {
|
||||||
/* Only push them as messages for the time being. *
|
/* 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))
|
if (gst_tag_list_is_empty (evtags))
|
||||||
gst_tag_list_unref (evtags);
|
gst_tag_list_unref (evtags);
|
||||||
else
|
else
|
||||||
gst_element_found_tags_for_pad (element, tagpad, evtags);
|
gst_pad_push_event (tagpad, gst_event_new_tag (evtags));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -611,7 +618,7 @@ gst_kate_decoder_base_convert (GstKateDecoderBase * decoder,
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
gst_kate_decoder_base_sink_query (GstKateDecoderBase * decoder,
|
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)) {
|
switch (GST_QUERY_TYPE (query)) {
|
||||||
case GST_QUERY_CONVERT:
|
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);
|
gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
|
||||||
if (!gst_kate_decoder_base_convert (decoder, element, pad, src_fmt,
|
if (!gst_kate_decoder_base_convert (decoder, element, pad, src_fmt,
|
||||||
src_val, &dest_fmt, &dest_val)) {
|
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);
|
gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return gst_pad_query_default (pad, query);
|
return gst_pad_query_default (pad, parent, query);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,8 @@ G_BEGIN_DECLS enum
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
GstEvent * event;
|
GstEvent * event;
|
||||||
gboolean (*handler)(GstPad *, GstEvent *);
|
gboolean (*handler)(GstPad *, GstObject*, GstEvent *);
|
||||||
|
GstObject * parent;
|
||||||
GstPad *pad;
|
GstPad *pad;
|
||||||
} GstKateDecoderBaseQueuedEvent;
|
} GstKateDecoderBaseQueuedEvent;
|
||||||
|
|
||||||
|
@ -95,9 +96,11 @@ extern gboolean gst_kate_decoder_base_convert (GstKateDecoderBase * decoder,
|
||||||
GstElement * element, GstPad * pad, GstFormat src_fmt, gint64 src_val,
|
GstElement * element, GstPad * pad, GstFormat src_fmt, gint64 src_val,
|
||||||
GstFormat * dest_fmt, gint64 * dest_val);
|
GstFormat * dest_fmt, gint64 * dest_val);
|
||||||
extern gboolean gst_kate_decoder_base_sink_query (GstKateDecoderBase * decoder,
|
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
|
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 *
|
extern const char *
|
||||||
gst_kate_util_get_error_message (int ret);
|
gst_kate_util_get_error_message (int ret);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue