oggmux: generate message headers from received tags

Some message headers can be deduced from tags (eg, "Language").

https://bugzilla.gnome.org/show_bug.cgi?id=563251
This commit is contained in:
Vincent Penquerc'h 2011-08-18 16:36:23 +01:00 committed by Sebastian Dröge
parent 53c8656248
commit 29038283bc
2 changed files with 86 additions and 4 deletions

View file

@ -361,6 +361,18 @@ gst_ogg_mux_sink_event (GstPad * pad, GstEvent * event)
gst_segment_init (&ogg_pad->segment, GST_FORMAT_TIME);
break;
}
case GST_EVENT_TAG:{
GstTagList *tags;
gst_event_parse_tag (event, &tags);
tags = gst_tag_list_merge (ogg_pad->tags, tags, GST_TAG_MERGE_APPEND);
if (ogg_pad->tags)
gst_tag_list_free (ogg_pad->tags);
ogg_pad->tags = tags;
GST_DEBUG_OBJECT (ogg_mux, "Got tags %" GST_PTR_FORMAT, ogg_pad->tags);
break;
}
default:
break;
}
@ -1170,7 +1182,7 @@ gst_ogg_mux_make_fishead (GstOggMux * mux, ogg_stream_state * os)
GST_DEBUG_OBJECT (mux, "Creating fishead");
fishead = gst_buffer_new_and_alloc (64);
gst_byte_writer_init_with_buffer (&bw, fishead, TRUE);
gst_byte_writer_init_with_buffer (&bw, fishead, FALSE);
gst_byte_writer_put_string_utf8 (&bw, "fishead");
gst_byte_writer_put_int16_le (&bw, 3); /* version major */
gst_byte_writer_put_int16_le (&bw, 0); /* version minor */
@ -1189,6 +1201,65 @@ gst_ogg_mux_byte_writer_put_string_utf8 (GstByteWriter * bw, const char *s)
gst_byte_writer_put_data (bw, (const guint8 *) s, strlen (s));
}
static void
gst_ogg_mux_add_fisbone_message_header (GstOggMux * mux, GstByteWriter * bw,
const char *tag, const char *value)
{
/* It is valid to pass NULL as the value to omit the tag */
if (!value)
return;
GST_DEBUG_OBJECT (mux, "Adding fisbone message header %s: %s", tag, value);
gst_ogg_mux_byte_writer_put_string_utf8 (bw, tag);
gst_ogg_mux_byte_writer_put_string_utf8 (bw, ": ");
gst_ogg_mux_byte_writer_put_string_utf8 (bw, value);
gst_ogg_mux_byte_writer_put_string_utf8 (bw, "\r\n");
}
static void
gst_ogg_mux_add_fisbone_message_header_from_tags (GstOggMux * mux,
GstByteWriter * bw, const char *header, const char *tag,
const GstTagList * tags)
{
GString *s;
guint size = gst_tag_list_get_tag_size (tags, tag), n;
GST_DEBUG_OBJECT (mux, "Found %u tags for name %s", size, tag);
if (size == 0)
return;
s = g_string_new ("");
for (n = 0; n < size; ++n) {
gchar *tmp;
if (n)
g_string_append (s, ", ");
gst_tag_list_get_string_index (tags, tag, n, &tmp);
g_string_append (s, tmp);
}
gst_ogg_mux_add_fisbone_message_header (mux, bw, header, s->str);
g_string_free (s, FALSE);
}
/* This is a basic placeholder to generate roles for the tracks.
For tracks with more than one video, both video tracks will get
tagged with a "video/main" role, but we have no way of knowing
which one is the main one, if any. We could just pick one. For
audio, it's more complicated as we don't know which is music,
which is dubbing, etc. For kate, we could take a pretty good
guess based on the category, as role essentially is category.
For now, leave this as is. */
static const char *
gst_ogg_mux_get_default_role (GstOggPadData * pad)
{
const char *type = gst_ogg_stream_get_media_type (&pad->map);
if (type) {
if (!strncmp (type, "video/", strlen ("video/")))
return "video/main";
if (!strncmp (type, "audio/", strlen ("audio/")))
return "audio/main";
if (!strcmp (type + strlen (type) - strlen ("kate"), "kate"))
return "text/caption";
}
return NULL;
}
static void
gst_ogg_mux_make_fisbone (GstOggMux * mux, ogg_stream_state * os,
GstOggPadData * pad)
@ -1211,10 +1282,14 @@ gst_ogg_mux_make_fisbone (GstOggMux * mux, ogg_stream_state * os,
gst_byte_writer_put_uint8 (&bw, pad->map.granuleshift);
gst_byte_writer_fill (&bw, 0, 3); /* padding */
/* message header fields - MIME type for now */
gst_ogg_mux_byte_writer_put_string_utf8 (&bw, "Content-Type: ");
gst_ogg_mux_byte_writer_put_string_utf8 (&bw,
gst_ogg_mux_add_fisbone_message_header (mux, &bw, "Content-Type",
gst_ogg_stream_get_media_type (&pad->map));
gst_ogg_mux_byte_writer_put_string_utf8 (&bw, "\r\n");
gst_ogg_mux_add_fisbone_message_header (mux, &bw, "Role",
gst_ogg_mux_get_default_role (pad));
gst_ogg_mux_add_fisbone_message_header_from_tags (mux, &bw, "Language",
GST_TAG_LANGUAGE_CODE, pad->tags);
gst_ogg_mux_add_fisbone_message_header_from_tags (mux, &bw, "Title",
GST_TAG_TITLE, pad->tags);
gst_ogg_mux_submit_skeleton_header_packet (mux, os,
gst_byte_writer_reset_and_get_buffer (&bw), 0, 0);
@ -1952,6 +2027,11 @@ gst_ogg_mux_clear_collectpads (GstCollectPads * collect)
oggpad->buffer = NULL;
}
if (oggpad->tags) {
gst_tag_list_free (oggpad->tags);
oggpad->tags = NULL;
}
gst_segment_init (&oggpad->segment, GST_FORMAT_TIME);
}
}

View file

@ -83,6 +83,8 @@ typedef struct
gint64 keyframe_granule; /* granule of last preceding keyframe */
GstPadEventFunction collect_event;
GstTagList *tags;
}
GstOggPadData;