katedec: Merge new tags with existing tags to prevent overwriting demuxer tags

https://bugzilla.gnome.org/show_bug.cgi?id=724699
This commit is contained in:
Brendan Long 2014-02-18 19:16:35 -06:00 committed by Sebastian Dröge
parent b47a4faf5f
commit 7f591f9c7e
3 changed files with 69 additions and 46 deletions

View file

@ -424,7 +424,6 @@ gst_kate_dec_sink_handle_event (GstPad * pad, GstObject * parent,
GstEvent * event) GstEvent * event)
{ {
GstKateDec *kd = GST_KATE_DEC (parent); GstKateDec *kd = GST_KATE_DEC (parent);
gboolean res = TRUE;
GST_LOG_OBJECT (pad, "Handling event on sink pad: %s", GST_LOG_OBJECT (pad, "Handling event on sink pad: %s",
GST_EVENT_TYPE_NAME (event)); GST_EVENT_TYPE_NAME (event));
@ -432,25 +431,29 @@ gst_kate_dec_sink_handle_event (GstPad * pad, GstObject * parent,
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, 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, 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, parent, event);
break; break;
case GST_EVENT_TAG:{
GstTagList *tags;
gst_event_parse_tag (event, &tags);
gst_kate_util_decoder_base_add_tags (&kd->decoder, tags, FALSE);
gst_event_unref (event);
event = gst_kate_util_decoder_base_get_tag_event (&kd->decoder);
break;
}
default: default:
res = gst_pad_event_default (pad, parent, event);
break; break;
} }
return res; return gst_pad_event_default (pad, parent, event);
} }
static gboolean static gboolean

View file

@ -114,6 +114,7 @@ gst_kate_util_decode_base_init (GstKateDecoderBase * decoder,
decoder->original_canvas_width = 0; decoder->original_canvas_width = 0;
decoder->original_canvas_height = 0; decoder->original_canvas_height = 0;
decoder->tags = NULL; decoder->tags = NULL;
decoder->tags_changed = FALSE;
decoder->initialized = FALSE; decoder->initialized = FALSE;
decoder->delay_events = delay_events; decoder->delay_events = delay_events;
decoder->event_queue = NULL; decoder->event_queue = NULL;
@ -130,6 +131,7 @@ gst_kate_util_decode_base_reset (GstKateDecoderBase * decoder)
gst_tag_list_unref (decoder->tags); gst_tag_list_unref (decoder->tags);
decoder->tags = NULL; decoder->tags = NULL;
} }
decoder->tags_changed = FALSE;
decoder->original_canvas_width = 0; decoder->original_canvas_width = 0;
decoder->original_canvas_height = 0; decoder->original_canvas_height = 0;
if (decoder->event_queue) { if (decoder->event_queue) {
@ -207,6 +209,33 @@ gst_kate_util_decoder_base_drain_event_queue (GstKateDecoderBase * decoder)
} }
} }
void
gst_kate_util_decoder_base_add_tags (GstKateDecoderBase * decoder,
GstTagList * tags, gboolean take_ownership_of_tags)
{
if (!decoder->tags) {
if (!take_ownership_of_tags)
tags = gst_tag_list_ref (tags);
decoder->tags = tags;
} else {
GstTagList *old = decoder->tags;
decoder->tags = gst_tag_list_merge (old, tags, GST_TAG_MERGE_REPLACE);
gst_tag_list_unref (old);
if (take_ownership_of_tags)
gst_tag_list_unref (tags);
}
decoder->tags_changed = TRUE;
}
GstEvent *
gst_kate_util_decoder_base_get_tag_event (GstKateDecoderBase * decoder)
{
if (!decoder->tags)
return NULL;
decoder->tags_changed = FALSE;
return gst_event_new_tag (gst_tag_list_ref (decoder->tags));
}
gboolean gboolean
gst_kate_util_decoder_base_get_property (GstKateDecoderBase * decoder, gst_kate_util_decoder_base_get_property (GstKateDecoderBase * decoder,
GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) GObject * object, guint prop_id, GValue * value, GParamSpec * pspec)
@ -264,12 +293,12 @@ gst_kate_util_decoder_base_chain_kate_packet (GstKateDecoderBase * decoder,
is_header = header_size > 0 && (header[0] & 0x80); is_header = header_size > 0 && (header[0] & 0x80);
if (!is_header && decoder->tags) { if (!is_header && decoder->tags_changed) {
/* 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_pad_push_event (tagpad, gst_event_new_tag (decoder->tags)); gst_pad_push_event (tagpad,
decoder->tags = NULL; gst_kate_util_decoder_base_get_tag_event (decoder));
} }
if (gst_buffer_map (buf, &info, GST_MAP_READ)) { if (gst_buffer_map (buf, &info, GST_MAP_READ)) {
@ -322,23 +351,17 @@ gst_kate_util_decoder_base_chain_kate_packet (GstKateDecoderBase * decoder,
} }
} }
if (decoder->k.ki->language && *decoder->k.ki->language) { if (decoder->k.ki->language && *decoder->k.ki->language) {
GstTagList *old = decoder->tags, *tags = gst_tag_list_new_empty (); GstTagList *tags = gst_tag_list_new_empty ();
if (tags) { gchar *lang_code;
gchar *lang_code;
/* en_GB -> en */ /* en_GB -> en */
lang_code = g_ascii_strdown (decoder->k.ki->language, -1); lang_code = g_ascii_strdown (decoder->k.ki->language, -1);
g_strdelimit (lang_code, NULL, '\0'); g_strdelimit (lang_code, NULL, '\0');
gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_LANGUAGE_CODE, gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_LANGUAGE_CODE,
lang_code, NULL); lang_code, NULL);
g_free (lang_code); g_free (lang_code);
/* TODO: category - where should it go ? */ /* TODO: category - where should it go ? */
decoder->tags = gst_kate_util_decoder_base_add_tags (decoder, tags, TRUE);
gst_tag_list_merge (decoder->tags, tags, GST_TAG_MERGE_REPLACE);
gst_tag_list_unref (tags);
if (old)
gst_tag_list_unref (old);
}
} }
/* update properties */ /* update properties */
@ -360,36 +383,28 @@ gst_kate_util_decoder_base_chain_kate_packet (GstKateDecoderBase * decoder,
GST_INFO_OBJECT (element, "Parsed comments header"); GST_INFO_OBJECT (element, "Parsed comments header");
{ {
gchar *encoder = NULL; gchar *encoder = NULL;
GstTagList *old = decoder->tags, *list = GstTagList *list = gst_tag_list_from_vorbiscomment_buffer (buf,
gst_tag_list_from_vorbiscomment_buffer (buf,
(const guint8 *) "\201kate\0\0\0\0", 9, &encoder); (const guint8 *) "\201kate\0\0\0\0", 9, &encoder);
if (list) { if (!list) {
decoder->tags =
gst_tag_list_merge (decoder->tags, list, GST_TAG_MERGE_REPLACE);
gst_tag_list_unref (list);
}
if (!decoder->tags) {
GST_ERROR_OBJECT (element, "failed to decode comment header"); GST_ERROR_OBJECT (element, "failed to decode comment header");
decoder->tags = gst_tag_list_new_empty (); list = gst_tag_list_new_empty ();
} }
if (encoder) { if (encoder) {
gst_tag_list_add (decoder->tags, GST_TAG_MERGE_REPLACE, gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
GST_TAG_ENCODER, encoder, NULL); GST_TAG_ENCODER, encoder, NULL);
g_free (encoder); g_free (encoder);
} }
gst_tag_list_add (decoder->tags, GST_TAG_MERGE_REPLACE, gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
GST_TAG_SUBTITLE_CODEC, "Kate", NULL); GST_TAG_SUBTITLE_CODEC, "Kate", NULL);
gst_tag_list_add (decoder->tags, GST_TAG_MERGE_REPLACE, gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
GST_TAG_ENCODER_VERSION, decoder->k.ki->bitstream_version_major, GST_TAG_ENCODER_VERSION, decoder->k.ki->bitstream_version_major,
NULL); NULL);
if (old) gst_kate_util_decoder_base_add_tags (decoder, list, TRUE);
gst_tag_list_unref (old);
if (decoder->initialized) { if (decoder->initialized) {
gst_pad_push_event (tagpad, gst_event_new_tag (decoder->tags)); gst_pad_push_event (tagpad,
decoder->tags = NULL; gst_event_new_tag (gst_tag_list_ref (decoder->tags)));
} }
} }
break; break;
@ -425,10 +440,9 @@ gst_kate_util_decoder_base_chain_kate_packet (GstKateDecoderBase * decoder,
} }
} }
} }
if (gst_tag_list_is_empty (evtags)) gst_kate_util_decoder_base_add_tags (decoder, evtags, TRUE);
gst_tag_list_unref (evtags); gst_pad_push_event (tagpad,
else gst_kate_util_decoder_base_get_tag_event (decoder));
gst_pad_push_event (tagpad, gst_event_new_tag (evtags));
} }
} }
#endif #endif

View file

@ -61,6 +61,7 @@ typedef struct
gboolean initialized; gboolean initialized;
GstTagList *tags; GstTagList *tags;
gboolean tags_changed;
gchar *language; gchar *language;
gchar *category; gchar *category;
@ -110,6 +111,11 @@ extern gboolean
gst_kate_util_decoder_base_queue_event (GstKateDecoderBase * decoder, gst_kate_util_decoder_base_queue_event (GstKateDecoderBase * decoder,
GstEvent * event, gboolean (*handler)(GstPad *, GstObject *, GstEvent *), GstEvent * event, gboolean (*handler)(GstPad *, GstObject *, GstEvent *),
GstObject * parent, GstPad * pad); GstObject * parent, GstPad * pad);
extern void
gst_kate_util_decoder_base_add_tags (GstKateDecoderBase * decoder,
GstTagList * tags, gboolean take_ownership_of_tags);
extern GstEvent *
gst_kate_util_decoder_base_get_tag_event (GstKateDecoderBase * decoder);
extern const char * extern const char *
gst_kate_util_get_error_message (int ret); gst_kate_util_get_error_message (int ret);