1 /*
2 * GPAC - Multimedia Framework C SDK
3 *
4 * Authors: Jean Le Feuvre
5 * Copyright (c) Telecom ParisTech 2006-2012
6 * All rights reserved
7 *
8 * This file is part of GPAC / ISO Media File Format sub-project
9 *
10 * GPAC is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU Lesser General Public License as published by
12 * the Free Software Foundation either version 2, or (at your option)
13 * any later version.
14 *
15 * GPAC is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library see the file COPYING. If not, write to
22 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 */
25
26 #include <gpac/internal/isomedia_dev.h>
27
28 #ifndef GPAC_DISABLE_ISOM
29
ilst_del(GF_Box * s)30 void ilst_del(GF_Box *s)
31 {
32 GF_ItemListBox *ptr = (GF_ItemListBox *)s;
33 if (ptr == NULL) return;
34 gf_free(ptr);
35 }
36
ilst_Read(GF_Box * s,GF_BitStream * bs)37 GF_Err ilst_Read(GF_Box *s, GF_BitStream *bs)
38 {
39 GF_Err e;
40 u32 sub_type;
41 GF_Box *a;
42 GF_ItemListBox *ptr = (GF_ItemListBox *)s;
43 while (ptr->size) {
44 /*if no ilst type coded, break*/
45 sub_type = gf_bs_peek_bits(bs, 32, 0);
46 if (sub_type) {
47 e = gf_isom_parse_box(&a, bs);
48 if (e) return e;
49 if (ptr->size<a->size) return GF_ISOM_INVALID_FILE;
50 ptr->size -= a->size;
51 gf_list_add(ptr->other_boxes, a);
52 }
53 else {
54 gf_bs_read_u32(bs);
55 ptr->size -= 4;
56 }
57 }
58 return GF_OK;
59 }
60
ilst_New()61 GF_Box *ilst_New()
62 {
63 ISOM_DECL_BOX_ALLOC(GF_ItemListBox, GF_ISOM_BOX_TYPE_ILST);
64 tmp->other_boxes = gf_list_new();
65 return (GF_Box *)tmp;
66 }
67
68 #ifndef GPAC_DISABLE_ISOM_WRITE
69
ilst_Write(GF_Box * s,GF_BitStream * bs)70 GF_Err ilst_Write(GF_Box *s, GF_BitStream *bs)
71 {
72 GF_Err e;
73 // GF_ItemListBox *ptr = (GF_ItemListBox *)s;
74
75 e = gf_isom_box_write_header(s, bs);
76 if (e) return e;
77
78 return GF_OK;
79 }
80
81
ilst_Size(GF_Box * s)82 GF_Err ilst_Size(GF_Box *s)
83 {
84 GF_Err e;
85 // GF_ItemListBox *ptr = (GF_ItemListBox *)s;
86
87 e = gf_isom_box_get_size(s);
88 if (e) return e;
89
90 return GF_OK;
91 }
92
93 #endif /*GPAC_DISABLE_ISOM_WRITE*/
94
ListItem_del(GF_Box * s)95 void ListItem_del(GF_Box *s)
96 {
97 GF_ListItemBox *ptr = (GF_ListItemBox *)s;
98 if (ptr == NULL) return;
99 if (ptr->data != NULL) {
100 if (ptr->data->data) gf_free(ptr->data->data);
101 gf_free(ptr->data);
102 }
103 gf_free(ptr);
104 }
105
ListItem_Read(GF_Box * s,GF_BitStream * bs)106 GF_Err ListItem_Read(GF_Box *s, GF_BitStream *bs)
107 {
108 GF_Err e;
109 u32 sub_type;
110 GF_Box *a = NULL;
111 GF_ListItemBox *ptr = (GF_ListItemBox *)s;
112
113 /*iTunes way: there's a data atom containing the data*/
114 sub_type = gf_bs_peek_bits(bs, 32, 4);
115 if (sub_type == GF_ISOM_BOX_TYPE_DATA) {
116 e = gf_isom_parse_box(&a, bs);
117 if (e) return e;
118 if (ptr->size<a->size) return GF_ISOM_INVALID_FILE;
119 ptr->size -= a->size;
120
121 if (a && ptr->data) gf_isom_box_del((GF_Box *)ptr->data);
122 ptr->data = (GF_DataBox *)a;
123 }
124 /*QT way*/
125 else {
126 ptr->data->type = 0;
127 ptr->data->dataSize = gf_bs_read_u16(bs);
128 gf_bs_read_u16(bs);
129 ptr->data->data = (char *)gf_malloc(sizeof(char)*(ptr->data->dataSize + 1));
130 gf_bs_read_data(bs, ptr->data->data, ptr->data->dataSize);
131 ptr->data->data[ptr->data->dataSize] = 0;
132 ptr->size -= ptr->data->dataSize;
133 }
134 return GF_OK;
135 }
136
ListItem_New(u32 type)137 GF_Box *ListItem_New(u32 type)
138 {
139 ISOM_DECL_BOX_ALLOC(GF_ListItemBox, type);
140
141 tmp->data = (GF_DataBox *)gf_isom_box_new(GF_ISOM_BOX_TYPE_DATA);
142
143 if (tmp->data == NULL) {
144 gf_free(tmp);
145 return NULL;
146 }
147
148 return (GF_Box *)tmp;
149 }
150
151 #ifndef GPAC_DISABLE_ISOM_WRITE
152
ListItem_Write(GF_Box * s,GF_BitStream * bs)153 GF_Err ListItem_Write(GF_Box *s, GF_BitStream *bs)
154 {
155 GF_Err e;
156 GF_ListItemBox *ptr = (GF_ListItemBox *)s;
157
158 e = gf_isom_box_write_header(s, bs);
159 if (e) return e;
160
161 /*iTune way*/
162 if (ptr->data->type) return gf_isom_box_write((GF_Box*)ptr->data, bs);
163 /*QT way*/
164 gf_bs_write_u16(bs, ptr->data->dataSize);
165 gf_bs_write_u16(bs, 0);
166 gf_bs_write_data(bs, ptr->data->data, ptr->data->dataSize);
167 return GF_OK;
168 }
169
ListItem_Size(GF_Box * s)170 GF_Err ListItem_Size(GF_Box *s)
171 {
172 GF_Err e;
173 GF_ListItemBox *ptr = (GF_ListItemBox *)s;
174
175 e = gf_isom_box_get_size(s);
176 if (e) return e;
177
178 /*iTune way*/
179 if (ptr->data && ptr->data->type) {
180 e = gf_isom_box_size((GF_Box *)ptr->data);
181 if (e) return e;
182 ptr->size += ptr->data->size;
183 }
184 /*QT way*/
185 else if (ptr->data) {
186 ptr->size += ptr->data->dataSize + 4;
187 }
188 return GF_OK;
189 }
190
191 #endif /*GPAC_DISABLE_ISOM_WRITE*/
192
data_del(GF_Box * s)193 void data_del(GF_Box *s)
194 {
195 GF_DataBox *ptr = (GF_DataBox *)s;
196 if (ptr == NULL) return;
197 if (ptr->data)
198 gf_free(ptr->data);
199 gf_free(ptr);
200
201 }
202
data_Read(GF_Box * s,GF_BitStream * bs)203 GF_Err data_Read(GF_Box *s, GF_BitStream *bs)
204 {
205 GF_Err e;
206 GF_DataBox *ptr = (GF_DataBox *)s;
207
208 e = gf_isom_full_box_read(s, bs);
209 if (e) return e;
210 ptr->reserved = gf_bs_read_int(bs, 32);
211 ptr->size -= 4;
212 if (ptr->size) {
213 ptr->dataSize = (u32)ptr->size;
214 ptr->data = (char*)gf_malloc(ptr->dataSize * sizeof(ptr->data[0]) + 1);
215 if (ptr->data == NULL) return GF_OUT_OF_MEM;
216 ptr->data[ptr->dataSize] = 0;
217 gf_bs_read_data(bs, ptr->data, ptr->dataSize);
218 }
219
220 return GF_OK;
221 }
222
data_New()223 GF_Box *data_New()
224 {
225 ISOM_DECL_BOX_ALLOC(GF_DataBox, GF_ISOM_BOX_TYPE_DATA);
226
227 gf_isom_full_box_init((GF_Box *)tmp);
228
229 return (GF_Box *)tmp;
230 }
231
232 #ifndef GPAC_DISABLE_ISOM_WRITE
233
data_Write(GF_Box * s,GF_BitStream * bs)234 GF_Err data_Write(GF_Box *s, GF_BitStream *bs)
235 {
236 GF_Err e;
237 GF_DataBox *ptr = (GF_DataBox *)s;
238
239 e = gf_isom_full_box_write(s, bs);
240 if (e) return e;
241 gf_bs_write_int(bs, ptr->reserved, 32);
242 if (ptr->data != NULL && ptr->dataSize > 0) {
243 gf_bs_write_data(bs, ptr->data, ptr->dataSize);
244 }
245 return GF_OK;
246 }
247
data_Size(GF_Box * s)248 GF_Err data_Size(GF_Box *s)
249 {
250 GF_Err e;
251 GF_DataBox *ptr = (GF_DataBox *)s;
252 e = gf_isom_full_box_get_size(s);
253 if (e) return e;
254 ptr->size += 4;
255 if (ptr->data != NULL && ptr->dataSize > 0) {
256 ptr->size += ptr->dataSize;
257 }
258 return GF_OK;
259 }
260
261 #endif /*GPAC_DISABLE_ISOM_WRITE*/
262
gf_isom_apple_get_meta_extensions(GF_ISOFile * mov)263 GF_MetaBox *gf_isom_apple_get_meta_extensions(GF_ISOFile *mov)
264 {
265 u32 i;
266 GF_MetaBox *meta;
267 GF_UserDataMap *map;
268
269 if (!mov || !mov->moov) return NULL;
270
271 if (!mov->moov->udta) return NULL;
272 map = udta_getEntry(mov->moov->udta, GF_ISOM_BOX_TYPE_META, NULL);
273 if (!map) return NULL;
274
275 for (i = 0; i < gf_list_count(map->other_boxes); i++) {
276 meta = (GF_MetaBox*)gf_list_get(map->other_boxes, i);
277
278 if (meta != NULL && meta->handler != NULL && meta->handler->handlerType == GF_ISOM_HANDLER_TYPE_MDIR) return meta;
279 }
280
281 return NULL;
282 }
283
284 #ifndef GPAC_DISABLE_ISOM_WRITE
gf_isom_apple_create_meta_extensions(GF_ISOFile * mov)285 GF_MetaBox *gf_isom_apple_create_meta_extensions(GF_ISOFile *mov)
286 {
287 GF_Err e;
288 u32 i;
289 GF_MetaBox *meta;
290 GF_UserDataMap *map;
291
292 if (!mov || !mov->moov) return NULL;
293
294 if (!mov->moov->udta) {
295 e = moov_AddBox((GF_Box*)mov->moov, gf_isom_box_new(GF_ISOM_BOX_TYPE_UDTA));
296 if (e) return NULL;
297 }
298
299 map = udta_getEntry(mov->moov->udta, GF_ISOM_BOX_TYPE_META, NULL);
300 if (map) {
301 for (i = 0; i < gf_list_count(map->other_boxes); i++) {
302 meta = (GF_MetaBox*)gf_list_get(map->other_boxes, i);
303
304 if (meta != NULL && meta->handler != NULL && meta->handler->handlerType == GF_ISOM_HANDLER_TYPE_MDIR) return meta;
305 }
306 }
307
308 meta = (GF_MetaBox *)gf_isom_box_new(GF_ISOM_BOX_TYPE_META);
309
310 if (meta != NULL) {
311 meta->handler = (GF_HandlerBox *)gf_isom_box_new(GF_ISOM_BOX_TYPE_HDLR);
312 if (meta->handler == NULL) {
313 gf_isom_box_del((GF_Box *)meta);
314 return NULL;
315 }
316 meta->handler->handlerType = GF_ISOM_HANDLER_TYPE_MDIR;
317 if (!meta->other_boxes) meta->other_boxes = gf_list_new();
318 gf_list_add(meta->other_boxes, gf_isom_box_new(GF_ISOM_BOX_TYPE_ILST));
319 udta_AddBox(mov->moov->udta, (GF_Box *)meta);
320 }
321
322 return meta;
323 }
324 #endif /*GPAC_DISABLE_ISOM_WRITE*/
325
326
327 #endif /*GPAC_DISABLE_ISOM*/
328