1 /* GStreamer
2 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3 * Copyright (C) <2003> David A. Schleef <ds@schleef.org>
4 * Copyright (C) <2006> Wim Taymans <wim@fluendo.com>
5 * Copyright (C) <2007> Julien Moutte <julien@fluendo.com>
6 * Copyright (C) <2009> Tim-Philipp Müller <tim centricular net>
7 * Copyright (C) <2009> STEricsson <benjamin.gaignard@stericsson.com>
8 * Copyright (C) <2013> Sreerenj Balachandran <sreerenj.balachandran@intel.com>
9 * Copyright (C) <2013> Intel Corporation
10 * Copyright (C) <2014> Centricular Ltd
11 * Copyright (C) <2015> YouView TV Ltd.
12 * Copyright (C) <2016> British Broadcasting Corporation
13 *
14 * This library is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU Library General Public
16 * License as published by the Free Software Foundation; either
17 * version 2 of the License, or (at your option) any later version.
18 *
19 * This library is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * Library General Public License for more details.
23 *
24 * You should have received a copy of the GNU Library General Public
25 * License along with this library; if not, write to the
26 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
27 * Boston, MA 02110-1301, USA.
28 */
29
30 #ifdef HAVE_CONFIG_H
31 #include "config.h"
32 #endif
33
34 #include "qtdemux_tree.h"
35 #include "qtdemux_types.h"
36 #include "fourcc.h"
37
38 GNode *
qtdemux_tree_get_child_by_type(GNode * node,guint32 fourcc)39 qtdemux_tree_get_child_by_type (GNode * node, guint32 fourcc)
40 {
41 GNode *child;
42 guint8 *buffer;
43 guint32 child_fourcc;
44
45 for (child = g_node_first_child (node); child;
46 child = g_node_next_sibling (child)) {
47 buffer = (guint8 *) child->data;
48
49 child_fourcc = QT_FOURCC (buffer + 4);
50
51 if (G_UNLIKELY (child_fourcc == fourcc)) {
52 return child;
53 }
54 }
55 return NULL;
56 }
57
58 GNode *
qtdemux_tree_get_child_by_type_full(GNode * node,guint32 fourcc,GstByteReader * parser)59 qtdemux_tree_get_child_by_type_full (GNode * node, guint32 fourcc,
60 GstByteReader * parser)
61 {
62 GNode *child;
63 guint8 *buffer;
64 guint32 child_fourcc, child_len;
65
66 for (child = g_node_first_child (node); child;
67 child = g_node_next_sibling (child)) {
68 buffer = (guint8 *) child->data;
69
70 child_len = QT_UINT32 (buffer);
71 child_fourcc = QT_FOURCC (buffer + 4);
72
73 if (G_UNLIKELY (child_fourcc == fourcc)) {
74 if (G_UNLIKELY (child_len < (4 + 4)))
75 return NULL;
76 /* FIXME: must verify if atom length < parent atom length */
77 gst_byte_reader_init (parser, buffer + (4 + 4), child_len - (4 + 4));
78 return child;
79 }
80 }
81 return NULL;
82 }
83
84 GNode *
qtdemux_tree_get_child_by_index(GNode * node,guint index)85 qtdemux_tree_get_child_by_index (GNode * node, guint index)
86 {
87 return g_node_nth_child (node, index);
88 }
89
90 GNode *
qtdemux_tree_get_sibling_by_type_full(GNode * node,guint32 fourcc,GstByteReader * parser)91 qtdemux_tree_get_sibling_by_type_full (GNode * node, guint32 fourcc,
92 GstByteReader * parser)
93 {
94 GNode *child;
95 guint8 *buffer;
96 guint32 child_fourcc, child_len;
97
98 for (child = g_node_next_sibling (node); child;
99 child = g_node_next_sibling (child)) {
100 buffer = (guint8 *) child->data;
101
102 child_fourcc = QT_FOURCC (buffer + 4);
103
104 if (child_fourcc == fourcc) {
105 if (parser) {
106 child_len = QT_UINT32 (buffer);
107 if (G_UNLIKELY (child_len < (4 + 4)))
108 return NULL;
109 /* FIXME: must verify if atom length < parent atom length */
110 gst_byte_reader_init (parser, buffer + (4 + 4), child_len - (4 + 4));
111 }
112 return child;
113 }
114 }
115 return NULL;
116 }
117
118 GNode *
qtdemux_tree_get_sibling_by_type(GNode * node,guint32 fourcc)119 qtdemux_tree_get_sibling_by_type (GNode * node, guint32 fourcc)
120 {
121 return qtdemux_tree_get_sibling_by_type_full (node, fourcc, NULL);
122 }
123