1 /*
2 * The contents of this file are subject to the Mozilla Public License
3 * Version 1.1 (the "License"); you may not use this file except in
4 * compliance with the License. You may obtain a copy of the License at
5 * http://www.mozilla.org/MPL/.
6 *
7 * Software distributed under the License is distributed on an "AS IS"
8 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
9 * License for the specific language governing rights and limitations
10 * under the License.
11 *
12 * The Original Code is Fluendo MPEG Demuxer plugin.
13 *
14 * The Initial Developer of the Original Code is Fluendo, S.L.
15 * Portions created by Fluendo, S.L. are Copyright (C) 2005
16 * Fluendo, S.L. All Rights Reserved.
17 *
18 * Contributor(s): Wim Taymans <wim@fluendo.com>
19 * Jan Schmidt <thaytan@noraisin.net>
20 */
21
22 #include <string.h>
23
24 #include <gst/gst.h>
25
26 #include "gstmpegdesc.h"
27
28 void
gst_mpeg_descriptor_free(GstMPEGDescriptor * desc)29 gst_mpeg_descriptor_free (GstMPEGDescriptor * desc)
30 {
31 g_return_if_fail (desc != NULL);
32
33 g_free (desc);
34 }
35
36 static guint
gst_mpeg_descriptor_parse_1(guint8 * data,guint size)37 gst_mpeg_descriptor_parse_1 (guint8 * data, guint size)
38 {
39 #ifndef GST_DISABLE_GST_DEBUG
40 guint8 tag;
41 #endif
42 guint8 length;
43
44 /* need at least 2 bytes for tag and length */
45 if (size < 2)
46 return 0;
47
48 #ifndef GST_DISABLE_GST_DEBUG
49 tag = *data;
50 #endif
51 data += 1;
52 length = *data++;
53 size -= 2;
54
55 GST_DEBUG ("tag: 0x%02x, length: %d", tag, length);
56
57 if (length > size)
58 return 0;
59
60 return length + 2;
61 }
62
63 GstMPEGDescriptor *
gst_mpeg_descriptor_parse(guint8 * data,guint size)64 gst_mpeg_descriptor_parse (guint8 * data, guint size)
65 {
66 guint8 *current;
67 guint consumed, total, n_desc;
68 GstMPEGDescriptor *result;
69
70 g_return_val_if_fail (data != NULL, NULL);
71
72 current = data;
73 total = 0;
74 n_desc = 0;
75
76 do {
77 consumed = gst_mpeg_descriptor_parse_1 (current, size);
78
79 if (consumed > 0) {
80 current += consumed;
81 total += consumed;
82 size -= consumed;
83 n_desc++;
84 }
85 }
86 while (consumed > 0);
87
88 GST_DEBUG ("parsed %d descriptors", n_desc);
89
90 if (total == 0)
91 return NULL;
92
93 result = g_malloc (sizeof (GstMPEGDescriptor) + total);
94 result->n_desc = n_desc;
95 result->data_length = total;
96 result->data = ((guint8 *) result) + sizeof (GstMPEGDescriptor);
97
98 memcpy (result->data, data, total);
99
100 return result;
101 }
102
103 guint
gst_mpeg_descriptor_n_desc(GstMPEGDescriptor * desc)104 gst_mpeg_descriptor_n_desc (GstMPEGDescriptor * desc)
105 {
106 g_return_val_if_fail (desc != NULL, 0);
107
108 return desc->n_desc;
109 }
110
111 guint8 *
gst_mpeg_descriptor_find(GstMPEGDescriptor * desc,gint tag)112 gst_mpeg_descriptor_find (GstMPEGDescriptor * desc, gint tag)
113 {
114 gint length;
115 guint8 *current;
116 guint size;
117
118 g_return_val_if_fail (desc != NULL, NULL);
119
120 current = desc->data;
121 length = desc->data_length;
122
123 while (length > 0) {
124 if (DESC_TAG (current) == tag)
125 return current;
126
127 size = DESC_LENGTH (current) + 2;
128
129 current += size;
130 length -= size;
131 }
132 return NULL;
133 }
134
135 guint8 *
gst_mpeg_descriptor_nth(GstMPEGDescriptor * desc,guint i)136 gst_mpeg_descriptor_nth (GstMPEGDescriptor * desc, guint i)
137 {
138 gint length;
139 guint8 *current;
140 guint size;
141
142 g_return_val_if_fail (desc != NULL, NULL);
143
144 if (i > desc->n_desc)
145 return NULL;
146
147 current = desc->data;
148 length = desc->data_length;
149
150 while (length > 0) {
151 if (i == 0)
152 return current;
153
154 size = DESC_LENGTH (current) + 2;
155
156 current += size;
157 length -= size;
158 i--;
159 }
160 return NULL;
161 }
162