mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-07 16:08:51 +00:00
gst/qtdemux/: Streamline tag handling and pass unparsed tags as binary blob in private tag.
Original commit message from CVS: * gst/qtdemux/qtdemux.c: (qtdemux_tag_add_str), (qtdemux_tag_add_tmpo), (qtdemux_tag_add_covr), (qtdemux_tag_add_date), (qtdemux_tag_add_gnre), (qtdemux_tag_add_blob), (qtdemux_parse_udta): * gst/qtdemux/qtdemux.h: * gst/qtdemux/quicktime.c: (plugin_init): Streamline tag handling and pass unparsed tags as binary blob in private tag.
This commit is contained in:
parent
4c7c4c00da
commit
455e24c0a3
4 changed files with 113 additions and 102 deletions
11
ChangeLog
11
ChangeLog
|
@ -1,3 +1,14 @@
|
||||||
|
2009-01-05 Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
|
||||||
|
|
||||||
|
* gst/qtdemux/qtdemux.c: (qtdemux_tag_add_str),
|
||||||
|
(qtdemux_tag_add_tmpo), (qtdemux_tag_add_covr),
|
||||||
|
(qtdemux_tag_add_date), (qtdemux_tag_add_gnre),
|
||||||
|
(qtdemux_tag_add_blob), (qtdemux_parse_udta):
|
||||||
|
* gst/qtdemux/qtdemux.h:
|
||||||
|
* gst/qtdemux/quicktime.c: (plugin_init):
|
||||||
|
Streamline tag handling and pass unparsed tags as binary blob
|
||||||
|
in private tag.
|
||||||
|
|
||||||
2009-01-05 Sebastian Dröge <sebastian.droege@collabora.co.uk>
|
2009-01-05 Sebastian Dröge <sebastian.droege@collabora.co.uk>
|
||||||
|
|
||||||
* gst/audiofx/Makefile.am:
|
* gst/audiofx/Makefile.am:
|
||||||
|
|
|
@ -3882,7 +3882,8 @@ unknown_stream:
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
qtdemux_tag_add_str (GstQTDemux * qtdemux, const char *tag, GNode * node)
|
qtdemux_tag_add_str (GstQTDemux * qtdemux, const char *tag, const char *dummy,
|
||||||
|
GNode * node)
|
||||||
{
|
{
|
||||||
const gchar *env_vars[] = { "GST_QT_TAG_ENCODING", "GST_TAG_ENCODING", NULL };
|
const gchar *env_vars[] = { "GST_QT_TAG_ENCODING", "GST_TAG_ENCODING", NULL };
|
||||||
GNode *data;
|
GNode *data;
|
||||||
|
@ -3955,7 +3956,8 @@ qtdemux_tag_add_num (GstQTDemux * qtdemux, const char *tag1,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
qtdemux_tag_add_tmpo (GstQTDemux * qtdemux, const char *tag1, GNode * node)
|
qtdemux_tag_add_tmpo (GstQTDemux * qtdemux, const char *tag1, const char *dummy,
|
||||||
|
GNode * node)
|
||||||
{
|
{
|
||||||
GNode *data;
|
GNode *data;
|
||||||
int len;
|
int len;
|
||||||
|
@ -3981,7 +3983,8 @@ qtdemux_tag_add_tmpo (GstQTDemux * qtdemux, const char *tag1, GNode * node)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
qtdemux_tag_add_covr (GstQTDemux * qtdemux, const char *tag1, GNode * node)
|
qtdemux_tag_add_covr (GstQTDemux * qtdemux, const char *tag1, const char *dummy,
|
||||||
|
GNode * node)
|
||||||
{
|
{
|
||||||
GNode *data;
|
GNode *data;
|
||||||
int len;
|
int len;
|
||||||
|
@ -4005,7 +4008,8 @@ qtdemux_tag_add_covr (GstQTDemux * qtdemux, const char *tag1, GNode * node)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
qtdemux_tag_add_date (GstQTDemux * qtdemux, const char *tag, GNode * node)
|
qtdemux_tag_add_date (GstQTDemux * qtdemux, const char *tag, const char *dummy,
|
||||||
|
GNode * node)
|
||||||
{
|
{
|
||||||
GNode *data;
|
GNode *data;
|
||||||
char *s;
|
char *s;
|
||||||
|
@ -4039,7 +4043,8 @@ qtdemux_tag_add_date (GstQTDemux * qtdemux, const char *tag, GNode * node)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
qtdemux_tag_add_gnre (GstQTDemux * qtdemux, const char *tag, GNode * node)
|
qtdemux_tag_add_gnre (GstQTDemux * qtdemux, const char *tag, const char *dummy,
|
||||||
|
GNode * node)
|
||||||
{
|
{
|
||||||
static const gchar *genres[] = {
|
static const gchar *genres[] = {
|
||||||
"N/A", "Blues", "Classic Rock", "Country", "Dance", "Disco",
|
"N/A", "Blues", "Classic Rock", "Country", "Dance", "Disco",
|
||||||
|
@ -4092,12 +4097,88 @@ qtdemux_tag_add_gnre (GstQTDemux * qtdemux, const char *tag, GNode * node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef void (*GstQTDemuxAddTagFunc) (GstQTDemux * demux,
|
||||||
|
const char *tag, const char *tag_bis, GNode * node);
|
||||||
|
|
||||||
|
static const struct
|
||||||
|
{
|
||||||
|
guint32 fourcc;
|
||||||
|
const gchar *gst_tag;
|
||||||
|
const gchar *gst_tag_bis;
|
||||||
|
const GstQTDemuxAddTagFunc func;
|
||||||
|
} add_funcs[] = {
|
||||||
|
{
|
||||||
|
FOURCC__nam, GST_TAG_TITLE, NULL, qtdemux_tag_add_str}, {
|
||||||
|
FOURCC__grp, GST_TAG_ARTIST, NULL, qtdemux_tag_add_str}, {
|
||||||
|
FOURCC__wrt, GST_TAG_ARTIST, NULL, qtdemux_tag_add_str}, {
|
||||||
|
FOURCC__ART, GST_TAG_ARTIST, NULL, qtdemux_tag_add_str}, {
|
||||||
|
FOURCC__alb, GST_TAG_ALBUM, NULL, qtdemux_tag_add_str}, {
|
||||||
|
FOURCC_cprt, GST_TAG_COPYRIGHT, NULL, qtdemux_tag_add_str}, {
|
||||||
|
FOURCC__cpy, GST_TAG_COPYRIGHT, NULL, qtdemux_tag_add_str}, {
|
||||||
|
FOURCC__cmt, GST_TAG_COMMENT, NULL, qtdemux_tag_add_str}, {
|
||||||
|
FOURCC__des, GST_TAG_DESCRIPTION, NULL, qtdemux_tag_add_str}, {
|
||||||
|
FOURCC__day, GST_TAG_DATE, NULL, qtdemux_tag_add_date}, {
|
||||||
|
FOURCC__too, GST_TAG_COMMENT, NULL, qtdemux_tag_add_str}, {
|
||||||
|
FOURCC_trkn, GST_TAG_TRACK_NUMBER, GST_TAG_TRACK_COUNT, qtdemux_tag_add_num}, {
|
||||||
|
FOURCC_disk, GST_TAG_ALBUM_VOLUME_NUMBER, GST_TAG_ALBUM_VOLUME_COUNT,
|
||||||
|
qtdemux_tag_add_num}, {
|
||||||
|
FOURCC_disc, GST_TAG_ALBUM_VOLUME_NUMBER, GST_TAG_ALBUM_VOLUME_COUNT,
|
||||||
|
qtdemux_tag_add_num}, {
|
||||||
|
FOURCC__gen, GST_TAG_GENRE, NULL, qtdemux_tag_add_str}, {
|
||||||
|
FOURCC_gnre, GST_TAG_GENRE, NULL, qtdemux_tag_add_gnre}, {
|
||||||
|
FOURCC_tmpo, GST_TAG_BEATS_PER_MINUTE, NULL, qtdemux_tag_add_tmpo}, {
|
||||||
|
FOURCC_covr, GST_TAG_PREVIEW_IMAGE, NULL, qtdemux_tag_add_covr}, {
|
||||||
|
FOURCC_kywd, GST_TAG_KEYWORDS, NULL, qtdemux_tag_add_str}, {
|
||||||
|
FOURCC_keyw, GST_TAG_KEYWORDS, NULL, qtdemux_tag_add_str}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
qtdemux_tag_add_blob (GNode * node, GstQTDemux * demux)
|
||||||
|
{
|
||||||
|
gint len;
|
||||||
|
guint8 *data;
|
||||||
|
GstBuffer *buf;
|
||||||
|
gchar *media_type, *style;
|
||||||
|
GstCaps *caps;
|
||||||
|
|
||||||
|
data = node->data;
|
||||||
|
len = QT_UINT32 (data);
|
||||||
|
buf = gst_buffer_new_and_alloc (len);
|
||||||
|
memcpy (GST_BUFFER_DATA (buf), data, len);
|
||||||
|
|
||||||
|
/* heuristic to determine style of tag */
|
||||||
|
if (QT_FOURCC (data + 4) == FOURCC_____ ||
|
||||||
|
(len > 8 + 12 && QT_FOURCC (data + 12) == FOURCC_data))
|
||||||
|
style = "itunes";
|
||||||
|
else if (demux->major_brand == GST_MAKE_FOURCC ('q', 't', ' ', ' '))
|
||||||
|
style = "quicktime";
|
||||||
|
/* fall back to assuming iso/3gp tag style */
|
||||||
|
else
|
||||||
|
style = "iso";
|
||||||
|
|
||||||
|
media_type = g_strdup_printf ("application/x-gst-qt-%c%c%c%c-tag",
|
||||||
|
g_ascii_tolower (data[4]), g_ascii_tolower (data[5]),
|
||||||
|
g_ascii_tolower (data[6]), g_ascii_tolower (data[7]));
|
||||||
|
caps = gst_caps_new_simple (media_type, "style", G_TYPE_STRING, style, NULL);
|
||||||
|
gst_buffer_set_caps (buf, caps);
|
||||||
|
gst_caps_unref (caps);
|
||||||
|
g_free (media_type);
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (demux, "adding private tag; size %d, caps %" GST_PTR_FORMAT,
|
||||||
|
GST_BUFFER_SIZE (buf), caps);
|
||||||
|
|
||||||
|
gst_tag_list_add (demux->tag_list, GST_TAG_MERGE_APPEND,
|
||||||
|
GST_QT_DEMUX_PRIVATE_TAG, buf, NULL);
|
||||||
|
gst_buffer_unref (buf);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
qtdemux_parse_udta (GstQTDemux * qtdemux, GNode * udta)
|
qtdemux_parse_udta (GstQTDemux * qtdemux, GNode * udta)
|
||||||
{
|
{
|
||||||
GNode *meta;
|
GNode *meta;
|
||||||
GNode *ilst;
|
GNode *ilst;
|
||||||
GNode *node;
|
GNode *node;
|
||||||
|
gint i;
|
||||||
|
|
||||||
meta = qtdemux_tree_get_child_by_type (udta, FOURCC_meta);
|
meta = qtdemux_tree_get_child_by_type (udta, FOURCC_meta);
|
||||||
if (meta != NULL) {
|
if (meta != NULL) {
|
||||||
|
@ -4114,107 +4195,18 @@ qtdemux_parse_udta (GstQTDemux * qtdemux, GNode * udta)
|
||||||
GST_DEBUG_OBJECT (qtdemux, "new tag list");
|
GST_DEBUG_OBJECT (qtdemux, "new tag list");
|
||||||
qtdemux->tag_list = gst_tag_list_new ();
|
qtdemux->tag_list = gst_tag_list_new ();
|
||||||
|
|
||||||
node = qtdemux_tree_get_child_by_type (ilst, FOURCC__nam);
|
for (i = 0; i < G_N_ELEMENTS (add_funcs); ++i) {
|
||||||
if (node) {
|
node = qtdemux_tree_get_child_by_type (ilst, add_funcs[i].fourcc);
|
||||||
qtdemux_tag_add_str (qtdemux, GST_TAG_TITLE, node);
|
|
||||||
}
|
|
||||||
|
|
||||||
node = qtdemux_tree_get_child_by_type (ilst, FOURCC__ART);
|
|
||||||
if (node) {
|
|
||||||
qtdemux_tag_add_str (qtdemux, GST_TAG_ARTIST, node);
|
|
||||||
} else {
|
|
||||||
node = qtdemux_tree_get_child_by_type (ilst, FOURCC__wrt);
|
|
||||||
if (node) {
|
if (node) {
|
||||||
qtdemux_tag_add_str (qtdemux, GST_TAG_ARTIST, node);
|
add_funcs[i].func (qtdemux, add_funcs[i].gst_tag,
|
||||||
} else {
|
add_funcs[i].gst_tag_bis, node);
|
||||||
node = qtdemux_tree_get_child_by_type (ilst, FOURCC__grp);
|
g_node_destroy (node);
|
||||||
if (node) {
|
|
||||||
qtdemux_tag_add_str (qtdemux, GST_TAG_ARTIST, node);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
node = qtdemux_tree_get_child_by_type (ilst, FOURCC__alb);
|
/* parsed nodes have been removed, pass along remainder as blob */
|
||||||
if (node) {
|
g_node_children_foreach (ilst, G_TRAVERSE_ALL,
|
||||||
qtdemux_tag_add_str (qtdemux, GST_TAG_ALBUM, node);
|
(GNodeForeachFunc) qtdemux_tag_add_blob, qtdemux);
|
||||||
}
|
|
||||||
|
|
||||||
node = qtdemux_tree_get_child_by_type (ilst, FOURCC__cpy);
|
|
||||||
if (node) {
|
|
||||||
qtdemux_tag_add_str (qtdemux, GST_TAG_COPYRIGHT, node);
|
|
||||||
} else {
|
|
||||||
node = qtdemux_tree_get_child_by_type (ilst, FOURCC_cprt);
|
|
||||||
if (node)
|
|
||||||
qtdemux_tag_add_str (qtdemux, GST_TAG_COPYRIGHT, node);
|
|
||||||
}
|
|
||||||
|
|
||||||
node = qtdemux_tree_get_child_by_type (ilst, FOURCC__cmt);
|
|
||||||
if (node) {
|
|
||||||
qtdemux_tag_add_str (qtdemux, GST_TAG_COMMENT, node);
|
|
||||||
}
|
|
||||||
|
|
||||||
node = qtdemux_tree_get_child_by_type (ilst, FOURCC__des);
|
|
||||||
if (node) {
|
|
||||||
qtdemux_tag_add_str (qtdemux, GST_TAG_DESCRIPTION, node);
|
|
||||||
}
|
|
||||||
|
|
||||||
node = qtdemux_tree_get_child_by_type (ilst, FOURCC__day);
|
|
||||||
if (node) {
|
|
||||||
qtdemux_tag_add_date (qtdemux, GST_TAG_DATE, node);
|
|
||||||
}
|
|
||||||
|
|
||||||
node = qtdemux_tree_get_child_by_type (ilst, FOURCC__too);
|
|
||||||
if (node) {
|
|
||||||
qtdemux_tag_add_str (qtdemux, GST_TAG_COMMENT, node);
|
|
||||||
}
|
|
||||||
|
|
||||||
node = qtdemux_tree_get_child_by_type (ilst, FOURCC_trkn);
|
|
||||||
if (node) {
|
|
||||||
qtdemux_tag_add_num (qtdemux, GST_TAG_TRACK_NUMBER,
|
|
||||||
GST_TAG_TRACK_COUNT, node);
|
|
||||||
}
|
|
||||||
|
|
||||||
node = qtdemux_tree_get_child_by_type (ilst, FOURCC_disc);
|
|
||||||
if (node) {
|
|
||||||
qtdemux_tag_add_num (qtdemux, GST_TAG_ALBUM_VOLUME_NUMBER,
|
|
||||||
GST_TAG_ALBUM_VOLUME_COUNT, node);
|
|
||||||
} else {
|
|
||||||
node = qtdemux_tree_get_child_by_type (ilst, FOURCC_disk);
|
|
||||||
if (node) {
|
|
||||||
qtdemux_tag_add_num (qtdemux, GST_TAG_ALBUM_VOLUME_NUMBER,
|
|
||||||
GST_TAG_ALBUM_VOLUME_COUNT, node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
node = qtdemux_tree_get_child_by_type (ilst, FOURCC_gnre);
|
|
||||||
if (node) {
|
|
||||||
qtdemux_tag_add_gnre (qtdemux, GST_TAG_GENRE, node);
|
|
||||||
} else {
|
|
||||||
node = qtdemux_tree_get_child_by_type (ilst, FOURCC__gen);
|
|
||||||
if (node) {
|
|
||||||
qtdemux_tag_add_str (qtdemux, GST_TAG_GENRE, node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
node = qtdemux_tree_get_child_by_type (ilst, FOURCC_tmpo);
|
|
||||||
if (node) {
|
|
||||||
qtdemux_tag_add_tmpo (qtdemux, GST_TAG_BEATS_PER_MINUTE, node);
|
|
||||||
}
|
|
||||||
|
|
||||||
node = qtdemux_tree_get_child_by_type (ilst, FOURCC_covr);
|
|
||||||
if (node) {
|
|
||||||
qtdemux_tag_add_covr (qtdemux, GST_TAG_PREVIEW_IMAGE, node);
|
|
||||||
}
|
|
||||||
|
|
||||||
node = qtdemux_tree_get_child_by_type (ilst, FOURCC_keyw);
|
|
||||||
if (node) {
|
|
||||||
qtdemux_tag_add_str (qtdemux, GST_TAG_KEYWORDS, node);
|
|
||||||
} else {
|
|
||||||
node = qtdemux_tree_get_child_by_type (ilst, FOURCC_kywd);
|
|
||||||
if (node) {
|
|
||||||
qtdemux_tag_add_str (qtdemux, GST_TAG_KEYWORDS, node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,9 @@ GST_DEBUG_CATEGORY_EXTERN (qtdemux_debug);
|
||||||
|
|
||||||
#define GST_QTDEMUX_CAST(obj) ((GstQTDemux *)(obj))
|
#define GST_QTDEMUX_CAST(obj) ((GstQTDemux *)(obj))
|
||||||
|
|
||||||
|
/* qtdemux produces these for atoms it cannot parse */
|
||||||
|
#define GST_QT_DEMUX_PRIVATE_TAG "private-qt-tag"
|
||||||
|
|
||||||
#define GST_QTDEMUX_MAX_STREAMS 8
|
#define GST_QTDEMUX_MAX_STREAMS 8
|
||||||
|
|
||||||
typedef struct _GstQTDemux GstQTDemux;
|
typedef struct _GstQTDemux GstQTDemux;
|
||||||
|
|
|
@ -35,6 +35,11 @@ plugin_init (GstPlugin * plugin)
|
||||||
bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
|
bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
|
||||||
#endif /* ENABLE_NLS */
|
#endif /* ENABLE_NLS */
|
||||||
|
|
||||||
|
/* ensure private tag is registered */
|
||||||
|
gst_tag_register (GST_QT_DEMUX_PRIVATE_TAG, GST_TAG_FLAG_META,
|
||||||
|
GST_TYPE_BUFFER, "QT atom", "unparsed QT tag atom",
|
||||||
|
gst_tag_merge_use_first);
|
||||||
|
|
||||||
if (!gst_element_register (plugin, "qtdemux",
|
if (!gst_element_register (plugin, "qtdemux",
|
||||||
GST_RANK_PRIMARY, GST_TYPE_QTDEMUX))
|
GST_RANK_PRIMARY, GST_TYPE_QTDEMUX))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
Loading…
Reference in a new issue