mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 03:35:21 +00:00
gst/qtdemux/qtdemux.c: More qtdemux hackage -- parse a lot more atoms, extract a few tags. One might even mistake th...
Original commit message from CVS: * gst/qtdemux/qtdemux.c: (gst_qtdemux_loop_header), (gst_qtdemux_add_stream), (qtdemux_parse), (qtdemux_type_get), (qtdemux_dump_stsz), (qtdemux_dump_stco), (qtdemux_dump_co64), (qtdemux_dump_unknown), (qtdemux_parse_tree), (qtdemux_parse_udta), (qtdemux_tag_add), (get_size), (gst_qtdemux_handle_esds): More qtdemux hackage -- parse a lot more atoms, extract a few tags. One might even mistake this for tag support. Maybe it is. * gst/qtdemux/qtdemux.h:
This commit is contained in:
parent
eff307f168
commit
cdfd00d33e
3 changed files with 177 additions and 14 deletions
11
ChangeLog
11
ChangeLog
|
@ -1,3 +1,14 @@
|
|||
2004-04-30 David Schleef <ds@schleef.org>
|
||||
|
||||
* gst/qtdemux/qtdemux.c: (gst_qtdemux_loop_header),
|
||||
(gst_qtdemux_add_stream), (qtdemux_parse), (qtdemux_type_get),
|
||||
(qtdemux_dump_stsz), (qtdemux_dump_stco), (qtdemux_dump_co64),
|
||||
(qtdemux_dump_unknown), (qtdemux_parse_tree), (qtdemux_parse_udta),
|
||||
(qtdemux_tag_add), (get_size), (gst_qtdemux_handle_esds): More qtdemux
|
||||
hackage -- parse a lot more atoms, extract a few tags. One might even
|
||||
mistake this for tag support. Maybe it is.
|
||||
* gst/qtdemux/qtdemux.h:
|
||||
|
||||
2004-04-30 Colin Walters <walters@verbum.org>
|
||||
|
||||
* ext/alsa/gstalsasink.c (gst_alsa_sink_mmap): Plug a memleak.
|
||||
|
|
|
@ -30,6 +30,10 @@
|
|||
GST_DEBUG_CATEGORY_EXTERN (qtdemux_debug);
|
||||
#define GST_CAT_DEFAULT qtdemux_debug
|
||||
|
||||
/* temporary hack */
|
||||
#define g_print(...) /* */
|
||||
#define gst_util_dump_mem(a,b) /* */
|
||||
|
||||
#define QTDEMUX_GUINT32_GET(a) (GST_READ_UINT32_BE(a))
|
||||
#define QTDEMUX_GUINT24_GET(a) (GST_READ_UINT32_BE(a) >> 8)
|
||||
#define QTDEMUX_GUINT16_GET(a) (GST_READ_UINT16_BE(a))
|
||||
|
@ -158,6 +162,9 @@ static void qtdemux_parse (GstQTDemux * qtdemux, GNode * node, void *buffer,
|
|||
static QtNodeType *qtdemux_type_get (guint32 fourcc);
|
||||
static void qtdemux_node_dump (GstQTDemux * qtdemux, GNode * node);
|
||||
static void qtdemux_parse_tree (GstQTDemux * qtdemux);
|
||||
static void qtdemux_parse_udta (GstQTDemux * qtdemux, GNode * udta);
|
||||
static void qtdemux_tag_add (GstQTDemux * qtdemux, const char *tag,
|
||||
GNode * node);
|
||||
static void gst_qtdemux_handle_esds (GstQTDemux * qtdemux,
|
||||
QtDemuxStream * stream, GNode * esds);
|
||||
static GstCaps *qtdemux_video_caps (GstQTDemux * qtdemux, guint32 fourcc,
|
||||
|
@ -574,8 +581,9 @@ gst_qtdemux_loop_header (GstElement * element)
|
|||
} while (1);
|
||||
|
||||
qtdemux_parse_moov (qtdemux, GST_BUFFER_DATA (moov), length);
|
||||
if (1)
|
||||
if (1) {
|
||||
qtdemux_node_dump (qtdemux, qtdemux->moov_node);
|
||||
}
|
||||
qtdemux_parse_tree (qtdemux);
|
||||
qtdemux->state = QTDEMUX_STATE_MOVIE;
|
||||
break;
|
||||
|
@ -813,6 +821,22 @@ gst_qtdemux_add_stream (GstQTDemux * qtdemux, QtDemuxStream * stream)
|
|||
#define FOURCC_wave GST_MAKE_FOURCC('w','a','v','e')
|
||||
#define FOURCC_appl GST_MAKE_FOURCC('a','p','p','l')
|
||||
#define FOURCC_esds GST_MAKE_FOURCC('e','s','d','s')
|
||||
#define FOURCC_hnti GST_MAKE_FOURCC('h','n','t','i')
|
||||
#define FOURCC_rtp_ GST_MAKE_FOURCC('r','t','p',' ')
|
||||
#define FOURCC_sdp_ GST_MAKE_FOURCC('s','d','p',' ')
|
||||
#define FOURCC_meta GST_MAKE_FOURCC('m','e','t','a')
|
||||
#define FOURCC_ilst GST_MAKE_FOURCC('i','l','s','t')
|
||||
#define FOURCC__nam GST_MAKE_FOURCC(0xa9,'n','a','m')
|
||||
#define FOURCC__ART GST_MAKE_FOURCC(0xa9,'A','R','T')
|
||||
#define FOURCC__alb GST_MAKE_FOURCC(0xa9,'a','l','b')
|
||||
#define FOURCC_gnre GST_MAKE_FOURCC('g','n','r','e')
|
||||
#define FOURCC_trkn GST_MAKE_FOURCC('t','r','k','n')
|
||||
#define FOURCC_cpil GST_MAKE_FOURCC('c','p','i','l')
|
||||
#define FOURCC_tmpo GST_MAKE_FOURCC('t','m','p','o')
|
||||
#define FOURCC__too GST_MAKE_FOURCC(0xa9,'t','o','o')
|
||||
#define FOURCC_____ GST_MAKE_FOURCC('-','-','-','-')
|
||||
#define FOURCC_free GST_MAKE_FOURCC('f','r','e','e')
|
||||
#define FOURCC_data GST_MAKE_FOURCC('d','a','t','a')
|
||||
|
||||
|
||||
static void qtdemux_dump_mvhd (GstQTDemux * qtdemux, void *buffer, int depth);
|
||||
|
@ -840,7 +864,7 @@ QtNodeType qt_node_types[] = {
|
|||
qtdemux_dump_mvhd},
|
||||
{FOURCC_clip, "clipping", QT_CONTAINER,},
|
||||
{FOURCC_trak, "track", QT_CONTAINER,},
|
||||
{FOURCC_udta, "user data", 0,}, /* special container */
|
||||
{FOURCC_udta, "user data", QT_CONTAINER,}, /* special container */
|
||||
{FOURCC_ctab, "color table", 0,},
|
||||
{FOURCC_tkhd, "track header", 0,
|
||||
qtdemux_dump_tkhd},
|
||||
|
@ -886,15 +910,29 @@ QtNodeType qt_node_types[] = {
|
|||
qtdemux_dump_co64},
|
||||
{FOURCC_vide, "video media", 0},
|
||||
{FOURCC_cmov, "compressed movie", QT_CONTAINER},
|
||||
{FOURCC_dcom, "compressed data", 0,
|
||||
qtdemux_dump_dcom},
|
||||
{FOURCC_cmvd, "compressed movie data", 0,
|
||||
qtdemux_dump_cmvd},
|
||||
{FOURCC_hint, "hint", 0, qtdemux_dump_unknown},
|
||||
{FOURCC_mp4a, "mp4a", 0, qtdemux_dump_unknown},
|
||||
{FOURCC_mp4v, "mp4v", 0, qtdemux_dump_unknown},
|
||||
{FOURCC_dcom, "compressed data", 0, qtdemux_dump_dcom},
|
||||
{FOURCC_cmvd, "compressed movie data", 0, qtdemux_dump_cmvd},
|
||||
{FOURCC_hint, "hint", 0,},
|
||||
{FOURCC_mp4a, "mp4a", 0,},
|
||||
{FOURCC_mp4v, "mp4v", 0,},
|
||||
{FOURCC_wave, "wave", QT_CONTAINER},
|
||||
{FOURCC_appl, "appl", QT_CONTAINER},
|
||||
{FOURCC_hnti, "hnti", QT_CONTAINER},
|
||||
{FOURCC_rtp_, "rtp ", 0, qtdemux_dump_unknown},
|
||||
{FOURCC_sdp_, "sdp ", 0, qtdemux_dump_unknown},
|
||||
{FOURCC_meta, "meta", 0, qtdemux_dump_unknown},
|
||||
{FOURCC_ilst, "ilst", QT_CONTAINER,},
|
||||
{FOURCC__nam, "Name", QT_CONTAINER,},
|
||||
{FOURCC__ART, "Artist", QT_CONTAINER,},
|
||||
{FOURCC__alb, "Album", QT_CONTAINER,},
|
||||
{FOURCC_gnre, "Genre", QT_CONTAINER,},
|
||||
{FOURCC_trkn, "Track Number", QT_CONTAINER,},
|
||||
{FOURCC_cpil, "cpil", QT_CONTAINER,},
|
||||
{FOURCC_tmpo, "Tempo", QT_CONTAINER,},
|
||||
{FOURCC__too, "too", QT_CONTAINER,},
|
||||
{FOURCC_____, "----", QT_CONTAINER,},
|
||||
{FOURCC_data, "data", 0, qtdemux_dump_unknown},
|
||||
{FOURCC_free, "free", 0,},
|
||||
{0, "unknown", 0},
|
||||
};
|
||||
static int n_qt_node_types = sizeof (qt_node_types) / sizeof (qt_node_types[0]);
|
||||
|
@ -1125,6 +1163,31 @@ qtdemux_parse (GstQTDemux * qtdemux, GNode * node, void *buffer, int length)
|
|||
buf += len;
|
||||
}
|
||||
}
|
||||
} else if (fourcc == FOURCC_meta) {
|
||||
void *buf;
|
||||
guint32 len;
|
||||
|
||||
buf = buffer + 12;
|
||||
end = buffer + length;
|
||||
while (buf < end) {
|
||||
GNode *child;
|
||||
|
||||
if (buf + 8 >= end) {
|
||||
/* FIXME: get annoyed */
|
||||
GST_LOG ("buffer overrun");
|
||||
}
|
||||
len = QTDEMUX_GUINT32_GET (buf);
|
||||
if (len < 8) {
|
||||
GST_LOG ("bad length");
|
||||
break;
|
||||
}
|
||||
|
||||
child = g_node_new (buf);
|
||||
g_node_append (node, child);
|
||||
qtdemux_parse (qtdemux, child, buf, len);
|
||||
|
||||
buf += len;
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
if (fourcc == FOURCC_cmvd) {
|
||||
|
@ -1169,7 +1232,7 @@ qtdemux_type_get (guint32 fourcc)
|
|||
return qt_node_types + i;
|
||||
}
|
||||
|
||||
GST_LOG ("unknown QuickTime node type " GST_FOURCC_FORMAT,
|
||||
GST_ERROR ("unknown QuickTime node type " GST_FOURCC_FORMAT,
|
||||
GST_FOURCC_ARGS (fourcc));
|
||||
return qt_node_types + n_qt_node_types - 1;
|
||||
}
|
||||
|
@ -1478,7 +1541,7 @@ qtdemux_dump_stsc (GstQTDemux * qtdemux, void *buffer, int depth)
|
|||
static void
|
||||
qtdemux_dump_stsz (GstQTDemux * qtdemux, void *buffer, int depth)
|
||||
{
|
||||
int i;
|
||||
//int i;
|
||||
int n;
|
||||
int offset;
|
||||
int sample_size;
|
||||
|
@ -1493,19 +1556,21 @@ qtdemux_dump_stsz (GstQTDemux * qtdemux, void *buffer, int depth)
|
|||
QTDEMUX_GUINT32_GET (buffer + 16));
|
||||
n = QTDEMUX_GUINT32_GET (buffer + 16);
|
||||
offset = 20;
|
||||
#if 0
|
||||
for (i = 0; i < n; i++) {
|
||||
GST_LOG ("%*s sample size: %u", depth, "",
|
||||
QTDEMUX_GUINT32_GET (buffer + offset));
|
||||
|
||||
offset += 4;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
qtdemux_dump_stco (GstQTDemux * qtdemux, void *buffer, int depth)
|
||||
{
|
||||
int i;
|
||||
//int i;
|
||||
int n;
|
||||
int offset;
|
||||
|
||||
|
@ -1515,18 +1580,20 @@ qtdemux_dump_stco (GstQTDemux * qtdemux, void *buffer, int depth)
|
|||
QTDEMUX_GUINT32_GET (buffer + 12));
|
||||
n = QTDEMUX_GUINT32_GET (buffer + 12);
|
||||
offset = 16;
|
||||
#if 0
|
||||
for (i = 0; i < n; i++) {
|
||||
GST_LOG ("%*s chunk offset: %08x", depth, "",
|
||||
QTDEMUX_GUINT32_GET (buffer + offset));
|
||||
|
||||
offset += 4;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
qtdemux_dump_co64 (GstQTDemux * qtdemux, void *buffer, int depth)
|
||||
{
|
||||
int i;
|
||||
//int i;
|
||||
int n;
|
||||
int offset;
|
||||
|
||||
|
@ -1536,12 +1603,14 @@ qtdemux_dump_co64 (GstQTDemux * qtdemux, void *buffer, int depth)
|
|||
QTDEMUX_GUINT32_GET (buffer + 12));
|
||||
n = QTDEMUX_GUINT32_GET (buffer + 12);
|
||||
offset = 16;
|
||||
#if 0
|
||||
for (i = 0; i < n; i++) {
|
||||
GST_LOG ("%*s chunk offset: %" G_GUINT64_FORMAT, depth, "",
|
||||
QTDEMUX_GUINT64_GET (buffer + offset));
|
||||
|
||||
offset += 8;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1560,7 +1629,12 @@ qtdemux_dump_cmvd (GstQTDemux * qtdemux, void *buffer, int depth)
|
|||
static void
|
||||
qtdemux_dump_unknown (GstQTDemux * qtdemux, void *buffer, int depth)
|
||||
{
|
||||
GST_LOG ("%*s length: %d", depth, "", QTDEMUX_GUINT32_GET (buffer + 8));
|
||||
int len;
|
||||
|
||||
GST_LOG ("%*s length: %d", depth, "", QTDEMUX_GUINT32_GET (buffer + 0));
|
||||
|
||||
len = QTDEMUX_GUINT32_GET (buffer + 0);
|
||||
gst_util_dump_mem (buffer, len);
|
||||
|
||||
}
|
||||
|
||||
|
@ -1612,6 +1686,20 @@ qtdemux_parse_tree (GstQTDemux * qtdemux)
|
|||
{
|
||||
GNode *mvhd;
|
||||
GNode *trak;
|
||||
GNode *udta;
|
||||
|
||||
udta = qtdemux_tree_get_child_by_type (qtdemux->moov_node, FOURCC_udta);
|
||||
if (udta) {
|
||||
qtdemux_parse_udta (qtdemux, udta);
|
||||
|
||||
if (qtdemux->tag_list) {
|
||||
g_print ("calling gst_element_found_tags with %s\n",
|
||||
gst_structure_to_string (qtdemux->tag_list));
|
||||
gst_element_found_tags (GST_ELEMENT (qtdemux), qtdemux->tag_list);
|
||||
}
|
||||
} else {
|
||||
GST_LOG ("No udta node found.");
|
||||
}
|
||||
|
||||
mvhd = qtdemux_tree_get_child_by_type (qtdemux->moov_node, FOURCC_mvhd);
|
||||
if (mvhd == NULL) {
|
||||
|
@ -1633,6 +1721,7 @@ qtdemux_parse_tree (GstQTDemux * qtdemux)
|
|||
|
||||
while ((trak = qtdemux_tree_get_sibling_by_type (trak, FOURCC_trak)) != NULL)
|
||||
qtdemux_parse_trak (qtdemux, trak);
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -2000,6 +2089,67 @@ done2:
|
|||
gst_qtdemux_add_stream (qtdemux, stream);
|
||||
}
|
||||
|
||||
static void
|
||||
qtdemux_parse_udta (GstQTDemux * qtdemux, GNode * udta)
|
||||
{
|
||||
GNode *meta;
|
||||
GNode *ilst;
|
||||
GNode *node;
|
||||
|
||||
meta = qtdemux_tree_get_child_by_type (udta, FOURCC_meta);
|
||||
if (meta == NULL) {
|
||||
GST_LOG ("no meta");
|
||||
return;
|
||||
}
|
||||
|
||||
ilst = qtdemux_tree_get_child_by_type (meta, FOURCC_ilst);
|
||||
if (ilst == NULL) {
|
||||
GST_LOG ("no ilst");
|
||||
return;
|
||||
}
|
||||
|
||||
g_print ("new tag list\n");
|
||||
qtdemux->tag_list = gst_tag_list_new ();
|
||||
|
||||
node = qtdemux_tree_get_child_by_type (ilst, FOURCC__nam);
|
||||
if (node) {
|
||||
qtdemux_tag_add (qtdemux, GST_TAG_TITLE, node);
|
||||
}
|
||||
|
||||
node = qtdemux_tree_get_child_by_type (ilst, FOURCC__ART);
|
||||
if (node) {
|
||||
qtdemux_tag_add (qtdemux, GST_TAG_ARTIST, node);
|
||||
}
|
||||
|
||||
node = qtdemux_tree_get_child_by_type (ilst, FOURCC__alb);
|
||||
if (node) {
|
||||
qtdemux_tag_add (qtdemux, GST_TAG_ALBUM, node);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
qtdemux_tag_add (GstQTDemux * qtdemux, const char *tag, GNode * node)
|
||||
{
|
||||
GNode *data;
|
||||
char *s;
|
||||
int len;
|
||||
int type;
|
||||
|
||||
data = qtdemux_tree_get_child_by_type (node, FOURCC_data);
|
||||
if (data) {
|
||||
len = QTDEMUX_GUINT32_GET (data->data);
|
||||
type = QTDEMUX_GUINT32_GET (data->data + 8);
|
||||
if (type == 0x00000001) {
|
||||
s = g_strndup ((char *) data->data + 16, len - 16);
|
||||
g_print ("adding tag %s\n", s);
|
||||
gst_tag_list_add (qtdemux->tag_list, GST_TAG_MERGE_REPLACE, tag, s, NULL);
|
||||
g_free (s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* taken from ffmpeg */
|
||||
static unsigned int
|
||||
get_size (guint8 * ptr, guint8 ** end)
|
||||
|
|
|
@ -70,6 +70,8 @@ struct _GstQTDemux {
|
|||
|
||||
int offset;
|
||||
|
||||
GstTagList *tag_list;
|
||||
|
||||
/* track stuff */
|
||||
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue