mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-23 07:38:16 +00:00
asfdemux: Store/Handle global metadata (not specific to one stream).
This allows us to store (and handle) PAR information which might be stored there.
This commit is contained in:
parent
6aa267cfc8
commit
1cc2eed416
2 changed files with 88 additions and 56 deletions
|
@ -187,6 +187,11 @@ gst_asf_demux_reset (GstASFDemux * demux)
|
||||||
gst_caps_unref (demux->metadata);
|
gst_caps_unref (demux->metadata);
|
||||||
demux->metadata = NULL;
|
demux->metadata = NULL;
|
||||||
}
|
}
|
||||||
|
if (demux->global_metadata) {
|
||||||
|
gst_structure_free (demux->global_metadata);
|
||||||
|
demux->global_metadata = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
demux->state = GST_ASF_DEMUX_STATE_HEADER;
|
demux->state = GST_ASF_DEMUX_STATE_HEADER;
|
||||||
g_free (demux->objpath);
|
g_free (demux->objpath);
|
||||||
demux->objpath = NULL;
|
demux->objpath = NULL;
|
||||||
|
@ -1878,11 +1883,22 @@ gst_asf_demux_add_video_stream (GstASFDemux * demux,
|
||||||
|
|
||||||
s = gst_asf_demux_get_metadata_for_stream (demux, id);
|
s = gst_asf_demux_get_metadata_for_stream (demux, id);
|
||||||
if (gst_structure_get_int (s, "AspectRatioX", &ax) &&
|
if (gst_structure_get_int (s, "AspectRatioX", &ax) &&
|
||||||
gst_structure_get_int (s, "AspectRatioY", &ay)) {
|
gst_structure_get_int (s, "AspectRatioY", &ay) && (ax > 0 && ay > 0)) {
|
||||||
/* only copy sane values */
|
gst_caps_set_simple (caps, "pixel-aspect-ratio", GST_TYPE_FRACTION,
|
||||||
if (ax > 0 && ay > 0) {
|
ax, ay, NULL);
|
||||||
gst_caps_set_simple (caps, "pixel-aspect-ratio", GST_TYPE_FRACTION,
|
|
||||||
ax, ay, NULL);
|
} else {
|
||||||
|
guint ax, ay;
|
||||||
|
/* retry with the global metadata */
|
||||||
|
GST_DEBUG ("Retrying with global metadata %" GST_PTR_FORMAT,
|
||||||
|
demux->global_metadata);
|
||||||
|
s = demux->global_metadata;
|
||||||
|
if (gst_structure_get_uint (s, "AspectRatioX", &ax) &&
|
||||||
|
gst_structure_get_uint (s, "AspectRatioY", &ay)) {
|
||||||
|
GST_DEBUG ("ax:%d, ay:%d", ax, ay);
|
||||||
|
if (ax > 0 && ay > 0)
|
||||||
|
gst_caps_set_simple (caps, "pixel-aspect-ratio", GST_TYPE_FRACTION,
|
||||||
|
ax, ay, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* remove the framerate we will guess and add it later */
|
/* remove the framerate we will guess and add it later */
|
||||||
|
@ -2081,8 +2097,7 @@ not_enough_data:
|
||||||
}
|
}
|
||||||
|
|
||||||
static const gchar *
|
static const gchar *
|
||||||
gst_asf_demux_get_gst_tag_from_tag_name (const gchar * name_utf16le,
|
gst_asf_demux_get_gst_tag_from_tag_name (const gchar * name_utf8)
|
||||||
gsize name_len)
|
|
||||||
{
|
{
|
||||||
const struct
|
const struct
|
||||||
{
|
{
|
||||||
|
@ -2098,14 +2113,9 @@ gst_asf_demux_get_gst_tag_from_tag_name (const gchar * name_utf16le,
|
||||||
"WM/Year", GST_TAG_DATE}
|
"WM/Year", GST_TAG_DATE}
|
||||||
/* { "WM/Composer", GST_TAG_COMPOSER } */
|
/* { "WM/Composer", GST_TAG_COMPOSER } */
|
||||||
};
|
};
|
||||||
gchar *name_utf8;
|
gsize out = strlen (name_utf8);
|
||||||
gsize in, out;
|
|
||||||
guint i;
|
guint i;
|
||||||
|
|
||||||
/* convert name to UTF-8 */
|
|
||||||
name_utf8 = g_convert (name_utf16le, name_len, "UTF-8", "UTF-16LE", &in,
|
|
||||||
&out, NULL);
|
|
||||||
|
|
||||||
if (name_utf8 == NULL) {
|
if (name_utf8 == NULL) {
|
||||||
GST_WARNING ("Failed to convert name to UTF8, skipping");
|
GST_WARNING ("Failed to convert name to UTF8, skipping");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -2114,13 +2124,10 @@ gst_asf_demux_get_gst_tag_from_tag_name (const gchar * name_utf16le,
|
||||||
for (i = 0; i < G_N_ELEMENTS (tags); ++i) {
|
for (i = 0; i < G_N_ELEMENTS (tags); ++i) {
|
||||||
if (strncmp (tags[i].asf_name, name_utf8, out) == 0) {
|
if (strncmp (tags[i].asf_name, name_utf8, out) == 0) {
|
||||||
GST_LOG ("map tagname '%s' -> '%s'", name_utf8, tags[i].gst_name);
|
GST_LOG ("map tagname '%s' -> '%s'", name_utf8, tags[i].gst_name);
|
||||||
g_free (name_utf8);
|
|
||||||
return tags[i].gst_name;
|
return tags[i].gst_name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_LOG ("unhandled tagname '%s'", name_utf8);
|
|
||||||
g_free (name_utf8);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2237,6 +2244,7 @@ gst_asf_demux_process_ext_content_desc (GstASFDemux * demux, guint8 * data,
|
||||||
GValue tag_value = { 0, };
|
GValue tag_value = { 0, };
|
||||||
gsize in, out;
|
gsize in, out;
|
||||||
gchar *name;
|
gchar *name;
|
||||||
|
gchar *name_utf8 = NULL;
|
||||||
gchar *value;
|
gchar *value;
|
||||||
|
|
||||||
/* Descriptor */
|
/* Descriptor */
|
||||||
|
@ -2256,8 +2264,16 @@ gst_asf_demux_process_ext_content_desc (GstASFDemux * demux, guint8 * data,
|
||||||
goto not_enough_data;
|
goto not_enough_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_tag_name = gst_asf_demux_get_gst_tag_from_tag_name (name, name_len);
|
name_utf8 =
|
||||||
if (gst_tag_name != NULL) {
|
g_convert (name, name_len, "UTF-8", "UTF-16LE", &in, &out, NULL);
|
||||||
|
|
||||||
|
GST_DEBUG ("Found tag/metadata %s", name_utf8);
|
||||||
|
|
||||||
|
gst_tag_name = gst_asf_demux_get_gst_tag_from_tag_name (name_utf8);
|
||||||
|
|
||||||
|
GST_DEBUG ("gst_tag_name %s", gst_tag_name);
|
||||||
|
|
||||||
|
if (name_utf8 != NULL) {
|
||||||
switch (datatype) {
|
switch (datatype) {
|
||||||
case ASF_DEMUX_DATA_TYPE_UTF16LE_STRING:{
|
case ASF_DEMUX_DATA_TYPE_UTF16LE_STRING:{
|
||||||
gchar *value_utf8;
|
gchar *value_utf8;
|
||||||
|
@ -2265,49 +2281,58 @@ gst_asf_demux_process_ext_content_desc (GstASFDemux * demux, guint8 * data,
|
||||||
value_utf8 = g_convert (value, value_len, "UTF-8", "UTF-16LE",
|
value_utf8 = g_convert (value, value_len, "UTF-8", "UTF-16LE",
|
||||||
&in, &out, NULL);
|
&in, &out, NULL);
|
||||||
|
|
||||||
|
GST_DEBUG ("string value %s", value_utf8);
|
||||||
|
|
||||||
/* get rid of tags with empty value */
|
/* get rid of tags with empty value */
|
||||||
if (value_utf8 != NULL && *value_utf8 != '\0') {
|
if (value_utf8 != NULL && *value_utf8 != '\0') {
|
||||||
value_utf8[out] = '\0';
|
value_utf8[out] = '\0';
|
||||||
|
|
||||||
if (strcmp (gst_tag_name, GST_TAG_DATE) == 0) {
|
if (gst_tag_name != NULL) {
|
||||||
guint year = atoi (value_utf8);
|
if (strcmp (gst_tag_name, GST_TAG_DATE) == 0) {
|
||||||
|
guint year = atoi (value_utf8);
|
||||||
|
|
||||||
if (year > 0) {
|
if (year > 0) {
|
||||||
GDate *date = g_date_new_dmy (1, 1, year);
|
GDate *date = g_date_new_dmy (1, 1, year);
|
||||||
|
|
||||||
g_value_init (&tag_value, GST_TYPE_DATE);
|
g_value_init (&tag_value, GST_TYPE_DATE);
|
||||||
gst_value_set_date (&tag_value, date);
|
gst_value_set_date (&tag_value, date);
|
||||||
g_date_free (date);
|
g_date_free (date);
|
||||||
}
|
}
|
||||||
} else if (strcmp (gst_tag_name, GST_TAG_GENRE) == 0) {
|
} else if (strcmp (gst_tag_name, GST_TAG_GENRE) == 0) {
|
||||||
guint id3v1_genre_id;
|
guint id3v1_genre_id;
|
||||||
const gchar *genre_str;
|
const gchar *genre_str;
|
||||||
|
|
||||||
if (sscanf (value_utf8, "(%u)", &id3v1_genre_id) == 1 &&
|
if (sscanf (value_utf8, "(%u)", &id3v1_genre_id) == 1 &&
|
||||||
((genre_str = gst_tag_id3_genre_get (id3v1_genre_id)))) {
|
((genre_str = gst_tag_id3_genre_get (id3v1_genre_id)))) {
|
||||||
GST_DEBUG ("Genre: %s -> %s", value_utf8, genre_str);
|
GST_DEBUG ("Genre: %s -> %s", value_utf8, genre_str);
|
||||||
g_free (value_utf8);
|
g_free (value_utf8);
|
||||||
value_utf8 = g_strdup (genre_str);
|
value_utf8 = g_strdup (genre_str);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
GType tag_type;
|
||||||
|
|
||||||
|
/* convert tag from string to other type if required */
|
||||||
|
tag_type = gst_tag_get_type (gst_tag_name);
|
||||||
|
g_value_init (&tag_value, tag_type);
|
||||||
|
if (!gst_value_deserialize (&tag_value, value_utf8)) {
|
||||||
|
GValue from_val = { 0, };
|
||||||
|
|
||||||
|
g_value_init (&from_val, G_TYPE_STRING);
|
||||||
|
g_value_set_string (&from_val, value_utf8);
|
||||||
|
if (!g_value_transform (&from_val, &tag_value)) {
|
||||||
|
GST_WARNING_OBJECT (demux,
|
||||||
|
"Could not transform string tag to " "%s tag type %s",
|
||||||
|
gst_tag_name, g_type_name (tag_type));
|
||||||
|
g_value_unset (&tag_value);
|
||||||
|
}
|
||||||
|
g_value_unset (&from_val);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
GType tag_type;
|
/* metadata ! */
|
||||||
|
GST_DEBUG ("Setting metadata");
|
||||||
/* convert tag from string to other type if required */
|
g_value_init (&tag_value, G_TYPE_STRING);
|
||||||
tag_type = gst_tag_get_type (gst_tag_name);
|
g_value_set_string (&tag_value, value_utf8);
|
||||||
g_value_init (&tag_value, tag_type);
|
|
||||||
if (!gst_value_deserialize (&tag_value, value_utf8)) {
|
|
||||||
GValue from_val = { 0, };
|
|
||||||
|
|
||||||
g_value_init (&from_val, G_TYPE_STRING);
|
|
||||||
g_value_set_string (&from_val, value_utf8);
|
|
||||||
if (!g_value_transform (&from_val, &tag_value)) {
|
|
||||||
GST_WARNING_OBJECT (demux,
|
|
||||||
"Could not transform string tag to " "%s tag type %s",
|
|
||||||
gst_tag_name, g_type_name (tag_type));
|
|
||||||
g_value_unset (&tag_value);
|
|
||||||
}
|
|
||||||
g_value_unset (&from_val);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if (value_utf8 == NULL) {
|
} else if (value_utf8 == NULL) {
|
||||||
GST_WARNING ("Failed to convert string value to UTF8, skipping");
|
GST_WARNING ("Failed to convert string value to UTF8, skipping");
|
||||||
|
@ -2339,10 +2364,16 @@ gst_asf_demux_process_ext_content_desc (GstASFDemux * demux, guint8 * data,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (G_IS_VALUE (&tag_value)) {
|
if (G_IS_VALUE (&tag_value)) {
|
||||||
gst_tag_list_add_values (taglist, GST_TAG_MERGE_APPEND,
|
if (gst_tag_name) {
|
||||||
gst_tag_name, &tag_value, NULL);
|
gst_tag_list_add_values (taglist, GST_TAG_MERGE_APPEND,
|
||||||
|
gst_tag_name, &tag_value, NULL);
|
||||||
|
|
||||||
g_value_unset (&tag_value);
|
g_value_unset (&tag_value);
|
||||||
|
} else {
|
||||||
|
GST_DEBUG ("Setting global metadata %s", name_utf8);
|
||||||
|
gst_structure_set_value (demux->global_metadata, name_utf8,
|
||||||
|
&tag_value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3575,6 +3606,7 @@ gst_asf_demux_change_state (GstElement * element, GstStateChange transition)
|
||||||
demux->segment_running = FALSE;
|
demux->segment_running = FALSE;
|
||||||
demux->adapter = gst_adapter_new ();
|
demux->adapter = gst_adapter_new ();
|
||||||
demux->metadata = gst_caps_new_empty ();
|
demux->metadata = gst_caps_new_empty ();
|
||||||
|
demux->global_metadata = gst_structure_empty_new ("metadata");
|
||||||
demux->data_size = 0;
|
demux->data_size = 0;
|
||||||
demux->data_offset = 0;
|
demux->data_offset = 0;
|
||||||
demux->index_offset = 0;
|
demux->index_offset = 0;
|
||||||
|
|
|
@ -136,7 +136,7 @@ struct _GstASFDemux {
|
||||||
|
|
||||||
GstCaps *metadata; /* metadata, for delayed parsing; one
|
GstCaps *metadata; /* metadata, for delayed parsing; one
|
||||||
* structure ('stream-N') per stream */
|
* structure ('stream-N') per stream */
|
||||||
|
GstStructure *global_metadata; /* metadata which isn't specific to one stream */
|
||||||
GSList *ext_stream_props; /* for delayed processing (buffers) */
|
GSList *ext_stream_props; /* for delayed processing (buffers) */
|
||||||
GSList *mut_ex_streams; /* mutually exclusive streams */
|
GSList *mut_ex_streams; /* mutually exclusive streams */
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue