Line data Source code
1 : /*
2 : * GPAC - Multimedia Framework C SDK
3 : *
4 : * Authors: Jean Le Feuvre
5 : * Copyright (c) Telecom ParisTech 2000-2021
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 :
30 :
31 3722 : GF_Err gf_isom_base_sample_entry_read(GF_SampleEntryBox *ptr, GF_BitStream *bs)
32 : {
33 3722 : gf_bs_read_data(bs, ptr->reserved, 6);
34 3722 : ptr->dataReferenceIndex = gf_bs_read_u16(bs);
35 3722 : if (!ptr->dataReferenceIndex) {
36 112 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[ISO file] dataReferenceIndex set to 0 in sample entry, overriding to 1\n"));
37 112 : ptr->dataReferenceIndex = 1;
38 : }
39 3722 : return GF_OK;
40 : }
41 :
42 5591 : void gf_isom_sample_entry_predestroy(GF_SampleEntryBox *ptr)
43 : {
44 5591 : }
45 :
46 897 : void gf_isom_sample_entry_init(GF_SampleEntryBox *ent)
47 : {
48 897 : ent->internal_type = GF_ISOM_SAMPLE_ENTRY_MP4S;
49 897 : }
50 :
51 3326 : void gf_isom_video_sample_entry_init(GF_VisualSampleEntryBox *ent)
52 : {
53 : gf_isom_sample_entry_init((GF_SampleEntryBox*)ent);
54 3326 : ent->internal_type = GF_ISOM_SAMPLE_ENTRY_VIDEO;
55 3326 : ent->horiz_res = ent->vert_res = 0x00480000;
56 3326 : ent->frames_per_sample = 1;
57 3326 : ent->bit_depth = 0x18;
58 3326 : ent->color_table_index = -1;
59 3326 : }
60 :
61 2233 : GF_Err gf_isom_video_sample_entry_read(GF_VisualSampleEntryBox *ptr, GF_BitStream *bs)
62 : {
63 : GF_Err e;
64 2233 : ISOM_DECREASE_SIZE(ptr, 78)
65 :
66 2233 : e = gf_isom_base_sample_entry_read((GF_SampleEntryBox *)ptr, bs);
67 2233 : if (e) return e;
68 :
69 2233 : ptr->version = gf_bs_read_u16(bs);
70 2233 : ptr->revision = gf_bs_read_u16(bs);
71 2233 : ptr->vendor = gf_bs_read_u32(bs);
72 2233 : ptr->temporal_quality = gf_bs_read_u32(bs);
73 2233 : ptr->spatial_quality = gf_bs_read_u32(bs);
74 2233 : ptr->Width = gf_bs_read_u16(bs);
75 2233 : ptr->Height = gf_bs_read_u16(bs);
76 2233 : ptr->horiz_res = gf_bs_read_u32(bs);
77 2233 : ptr->vert_res = gf_bs_read_u32(bs);
78 2233 : ptr->entry_data_size = gf_bs_read_u32(bs);
79 2233 : ptr->frames_per_sample = gf_bs_read_u16(bs);
80 2233 : gf_bs_read_data(bs, ptr->compressor_name, 32);
81 2233 : ptr->compressor_name[32] = 0;
82 2233 : ptr->bit_depth = gf_bs_read_u16(bs);
83 2233 : ptr->color_table_index = gf_bs_read_u16(bs);
84 2233 : return GF_OK;
85 : }
86 :
87 : #ifndef GPAC_DISABLE_ISOM_WRITE
88 2016 : void gf_isom_video_sample_entry_write(GF_VisualSampleEntryBox *ptr, GF_BitStream *bs)
89 : {
90 2016 : gf_bs_write_data(bs, ptr->reserved, 6);
91 2016 : gf_bs_write_u16(bs, ptr->dataReferenceIndex);
92 :
93 2016 : gf_bs_write_u16(bs, ptr->version);
94 2016 : gf_bs_write_u16(bs, ptr->revision);
95 2016 : gf_bs_write_u32(bs, ptr->vendor);
96 2016 : gf_bs_write_u32(bs, ptr->temporal_quality);
97 2016 : gf_bs_write_u32(bs, ptr->spatial_quality);
98 2016 : gf_bs_write_u16(bs, ptr->Width);
99 2016 : gf_bs_write_u16(bs, ptr->Height);
100 2016 : gf_bs_write_u32(bs, ptr->horiz_res);
101 2016 : gf_bs_write_u32(bs, ptr->vert_res);
102 2016 : gf_bs_write_u32(bs, ptr->entry_data_size);
103 2016 : gf_bs_write_u16(bs, ptr->frames_per_sample);
104 2016 : gf_bs_write_data(bs, ptr->compressor_name, 32);
105 2016 : gf_bs_write_u16(bs, ptr->bit_depth);
106 2016 : gf_bs_write_u16(bs, ptr->color_table_index);
107 :
108 :
109 2016 : if (gf_sys_old_arch_compat()) {
110 : //patch for old export
111 1973 : GF_Box *clap = gf_isom_box_find_child(ptr->child_boxes, GF_ISOM_BOX_TYPE_CLAP);
112 1973 : GF_Box *pasp = gf_isom_box_find_child(ptr->child_boxes, GF_ISOM_BOX_TYPE_PASP);
113 1973 : GF_Box *colr = gf_isom_box_find_child(ptr->child_boxes, GF_ISOM_BOX_TYPE_COLR);
114 1973 : GF_Box *mdcv = gf_isom_box_find_child(ptr->child_boxes, GF_ISOM_BOX_TYPE_MDCV);
115 1973 : GF_Box *clli = gf_isom_box_find_child(ptr->child_boxes, GF_ISOM_BOX_TYPE_CLLI);
116 1973 : GF_Box *ccst = gf_isom_box_find_child(ptr->child_boxes, GF_ISOM_BOX_TYPE_CCST);
117 1973 : GF_Box *auxi = gf_isom_box_find_child(ptr->child_boxes, GF_ISOM_BOX_TYPE_AUXI);
118 1973 : GF_Box *rvcc = gf_isom_box_find_child(ptr->child_boxes, GF_ISOM_BOX_TYPE_RVCC);
119 1973 : GF_Box *sinf = gf_isom_box_find_child(ptr->child_boxes, GF_ISOM_BOX_TYPE_SINF);
120 1973 : GF_Box *btrt = gf_isom_box_find_child(ptr->child_boxes, GF_ISOM_BOX_TYPE_BTRT);
121 1973 : GF_Box *fiel = gf_isom_box_find_child(ptr->child_boxes, GF_QT_BOX_TYPE_FIEL);
122 1973 : GF_Box *gamma = gf_isom_box_find_child(ptr->child_boxes, GF_QT_BOX_TYPE_GAMA);
123 :
124 1973 : if (clap) {
125 1 : gf_list_del_item(ptr->child_boxes, clap);
126 1 : gf_list_add(ptr->child_boxes, clap);
127 : }
128 1973 : if (pasp) {
129 109 : gf_list_del_item(ptr->child_boxes, pasp);
130 109 : gf_list_add(ptr->child_boxes, pasp);
131 : }
132 1973 : if (colr) {
133 227 : gf_list_del_item(ptr->child_boxes, colr);
134 227 : gf_list_add(ptr->child_boxes, colr);
135 : }
136 1973 : if (fiel) {
137 17 : gf_list_del_item(ptr->child_boxes, fiel);
138 17 : gf_list_add(ptr->child_boxes, fiel);
139 : }
140 1973 : if (gamma) {
141 9 : gf_list_del_item(ptr->child_boxes, gamma);
142 9 : gf_list_add(ptr->child_boxes, gamma);
143 : }
144 1973 : if (mdcv) {
145 1 : gf_list_del_item(ptr->child_boxes, mdcv);
146 1 : gf_list_add(ptr->child_boxes, mdcv);
147 : }
148 1973 : if (clli) {
149 1 : gf_list_del_item(ptr->child_boxes, clli);
150 1 : gf_list_add(ptr->child_boxes, clli);
151 : }
152 1973 : if (ccst) {
153 1 : gf_list_del_item(ptr->child_boxes, ccst);
154 1 : gf_list_add(ptr->child_boxes, ccst);
155 : }
156 1973 : if (auxi) {
157 1 : gf_list_del_item(ptr->child_boxes, auxi);
158 1 : gf_list_add(ptr->child_boxes, auxi);
159 : }
160 1973 : if (rvcc) {
161 1 : gf_list_del_item(ptr->child_boxes, rvcc);
162 1 : gf_list_add(ptr->child_boxes, rvcc);
163 : }
164 1973 : if (sinf) {
165 377 : gf_list_del_item(ptr->child_boxes, sinf);
166 377 : gf_list_add(ptr->child_boxes, sinf);
167 : }
168 1973 : if (btrt) {
169 1508 : gf_list_del_item(ptr->child_boxes, btrt);
170 1508 : gf_list_add(ptr->child_boxes, btrt);
171 : }
172 : }
173 :
174 2016 : }
175 :
176 3521 : void gf_isom_video_sample_entry_size(GF_VisualSampleEntryBox *ent)
177 : {
178 3521 : ent->size += 78;
179 3521 : }
180 :
181 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
182 :
183 :
184 :
185 1368 : void gf_isom_audio_sample_entry_init(GF_AudioSampleEntryBox *ptr)
186 : {
187 : gf_isom_sample_entry_init((GF_SampleEntryBox*)ptr);
188 1368 : ptr->internal_type = GF_ISOM_SAMPLE_ENTRY_AUDIO;
189 :
190 1368 : ptr->channel_count = 2;
191 1368 : ptr->bitspersample = 16;
192 1368 : }
193 :
194 974 : GF_Err gf_isom_audio_sample_entry_read(GF_AudioSampleEntryBox *ptr, GF_BitStream *bs)
195 : {
196 : GF_Err e;
197 974 : ISOM_DECREASE_SIZE(ptr, 28)
198 :
199 974 : e = gf_isom_base_sample_entry_read((GF_SampleEntryBox *)ptr, bs);
200 974 : if (e) return e;
201 :
202 974 : ptr->version = gf_bs_read_u16(bs);
203 974 : ptr->revision = gf_bs_read_u16(bs);
204 974 : ptr->vendor = gf_bs_read_u32(bs);
205 974 : ptr->channel_count = gf_bs_read_u16(bs);
206 974 : ptr->bitspersample = gf_bs_read_u16(bs);
207 974 : ptr->compression_id = gf_bs_read_u16(bs);
208 974 : ptr->packet_size = gf_bs_read_u16(bs);
209 974 : ptr->samplerate_hi = gf_bs_read_u16(bs);
210 974 : ptr->samplerate_lo = gf_bs_read_u16(bs);
211 :
212 974 : if (!ptr->qtff_mode) return GF_OK;
213 : //QT only
214 89 : if (ptr->version==1) {
215 89 : ISOM_DECREASE_SIZE(ptr, 16)
216 89 : gf_bs_read_data(bs, (char *) ptr->extensions, 16);
217 0 : } else if (ptr->version==2) {
218 0 : ISOM_DECREASE_SIZE(ptr, 36)
219 0 : gf_bs_read_data(bs, (char *) ptr->extensions, 36);
220 : }
221 : return GF_OK;
222 : }
223 :
224 : #ifndef GPAC_DISABLE_ISOM_WRITE
225 :
226 17 : GF_Box *gf_isom_audio_sample_get_audio_codec_cfg_box(GF_AudioSampleEntryBox *ptr)
227 : {
228 : GF_MPEGAudioSampleEntryBox *mpga = (GF_MPEGAudioSampleEntryBox *) ptr;
229 18 : switch (ptr->type) {
230 2 : case GF_ISOM_BOX_TYPE_MP4A:
231 2 : return (GF_Box *)mpga->esd;
232 0 : case GF_ISOM_BOX_TYPE_AC3:
233 : case GF_ISOM_BOX_TYPE_EC3:
234 0 : return (GF_Box *)mpga->cfg_ac3;
235 0 : case GF_ISOM_BOX_TYPE_OPUS:
236 0 : return (GF_Box *)mpga->cfg_opus;
237 0 : case GF_ISOM_BOX_TYPE_MHA1:
238 : case GF_ISOM_BOX_TYPE_MHA2:
239 0 : return (GF_Box *)mpga->cfg_mha;
240 0 : case GF_ISOM_BOX_TYPE_MLPA:
241 0 : return (GF_Box *)mpga->cfg_mlp;
242 : }
243 : return NULL;
244 : }
245 810 : void gf_isom_audio_sample_entry_write(GF_AudioSampleEntryBox *ptr, GF_BitStream *bs)
246 : {
247 810 : gf_bs_write_data(bs, ptr->reserved, 6);
248 810 : gf_bs_write_u16(bs, ptr->dataReferenceIndex);
249 :
250 810 : gf_bs_write_u16(bs, ptr->version);
251 810 : gf_bs_write_u16(bs, ptr->revision);
252 810 : gf_bs_write_u32(bs, ptr->vendor);
253 810 : gf_bs_write_u16(bs, ptr->channel_count);
254 810 : gf_bs_write_u16(bs, ptr->bitspersample);
255 810 : gf_bs_write_u16(bs, ptr->compression_id);
256 810 : gf_bs_write_u16(bs, ptr->packet_size);
257 810 : gf_bs_write_u16(bs, ptr->samplerate_hi);
258 810 : gf_bs_write_u16(bs, ptr->samplerate_lo);
259 :
260 810 : if (ptr->qtff_mode) {
261 : GF_Box *codec_ext = NULL;
262 65 : if (ptr->qtff_mode==GF_ISOM_AUDIO_QTFF_ON_NOEXT) {
263 : codec_ext = gf_isom_audio_sample_get_audio_codec_cfg_box(ptr);
264 : }
265 :
266 65 : if (ptr->version==1) {
267 : //direct copy of data
268 65 : if (ptr->qtff_mode==GF_ISOM_AUDIO_QTFF_ON_EXT_VALID) {
269 64 : gf_bs_write_data(bs, (char *) ptr->extensions, 16);
270 : } else {
271 1 : gf_bs_write_u32(bs, codec_ext ? 1024 : 1);
272 1 : gf_bs_write_u32(bs, codec_ext ? 0 : ptr->bitspersample/8);
273 1 : gf_bs_write_u32(bs, codec_ext ? 0 : ptr->bitspersample/8*ptr->channel_count);
274 1 : gf_bs_write_u32(bs, codec_ext ? 0 : ptr->bitspersample <= 16 ? ptr->bitspersample/8 : 2);
275 : }
276 0 : } else if (ptr->version==2) {
277 0 : gf_bs_write_data(bs, (char *) ptr->extensions, 36);
278 : }
279 : }
280 810 : }
281 :
282 1522 : void gf_isom_audio_sample_entry_size(GF_AudioSampleEntryBox *ptr)
283 : {
284 1522 : ptr->size += 28;
285 1522 : if (ptr->qtff_mode) {
286 115 : if (ptr->version==1) {
287 115 : ptr->size+=16;
288 0 : } else if (ptr->version==2) {
289 0 : ptr->size += 36;
290 : }
291 : }
292 1522 : }
293 :
294 :
295 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
296 :
297 :
298 :
299 : GF_EXPORT
300 0 : GF_3GPConfig *gf_isom_3gp_config_get(GF_ISOFile *the_file, u32 trackNumber, u32 StreamDescriptionIndex)
301 : {
302 : GF_3GPConfig *config, *res;
303 : GF_TrackBox *trak;
304 : GF_SampleEntryBox *entry;
305 0 : trak = gf_isom_get_track_from_file(the_file, trackNumber);
306 0 : if (!trak || !StreamDescriptionIndex) return NULL;
307 :
308 : config = NULL;
309 0 : entry = (GF_SampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->child_boxes, StreamDescriptionIndex-1);
310 0 : if (!entry) return NULL;
311 0 : switch (entry->type) {
312 0 : case GF_ISOM_SUBTYPE_3GP_AMR:
313 : case GF_ISOM_SUBTYPE_3GP_AMR_WB:
314 : case GF_ISOM_SUBTYPE_3GP_EVRC:
315 : case GF_ISOM_SUBTYPE_3GP_QCELP:
316 : case GF_ISOM_SUBTYPE_3GP_SMV:
317 0 : if (! ((GF_MPEGAudioSampleEntryBox*)entry)->cfg_3gpp) return NULL;
318 0 : config = & ((GF_MPEGAudioSampleEntryBox*)entry)->cfg_3gpp->cfg;
319 0 : break;
320 0 : case GF_ISOM_SUBTYPE_3GP_H263:
321 0 : if (! ((GF_MPEGVisualSampleEntryBox*)entry)->cfg_3gpp) return NULL;
322 0 : config = & ((GF_MPEGVisualSampleEntryBox*)entry)->cfg_3gpp->cfg;
323 0 : break;
324 : default:
325 : return NULL;
326 : }
327 : if (!config) return NULL;
328 :
329 0 : res = (GF_3GPConfig*)gf_malloc(sizeof(GF_3GPConfig));
330 0 : if (res)
331 : memcpy(res, config, sizeof(GF_3GPConfig));
332 : return res;
333 : }
334 :
335 : GF_EXPORT
336 12 : GF_AC3Config *gf_isom_ac3_config_get(GF_ISOFile *the_file, u32 trackNumber, u32 StreamDescriptionIndex)
337 : {
338 : GF_AC3Config *res;
339 : GF_TrackBox *trak;
340 : GF_MPEGAudioSampleEntryBox *entry;
341 12 : trak = gf_isom_get_track_from_file(the_file, trackNumber);
342 12 : if (!trak || !StreamDescriptionIndex) return NULL;
343 :
344 12 : entry = (GF_MPEGAudioSampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->child_boxes, StreamDescriptionIndex-1);
345 12 : if (!entry || !entry->cfg_ac3) return NULL;
346 : if (!entry->cfg_ac3) return NULL;
347 12 : if ( (entry->cfg_ac3->type!=GF_ISOM_BOX_TYPE_DAC3) && (entry->cfg_ac3->type!=GF_ISOM_BOX_TYPE_DEC3) ) return NULL;
348 :
349 12 : res = (GF_AC3Config*)gf_malloc(sizeof(GF_AC3Config));
350 12 : if (res)
351 12 : memcpy(res, &entry->cfg_ac3->cfg, sizeof(GF_AC3Config));
352 : return res;
353 : }
354 :
355 : GF_EXPORT
356 2 : GF_Err gf_isom_flac_config_get(GF_ISOFile *the_file, u32 trackNumber, u32 StreamDescriptionIndex, u8 **dsi, u32 *dsi_size)
357 : {
358 : u32 type;
359 : GF_TrackBox *trak;
360 : GF_MPEGAudioSampleEntryBox *entry;
361 2 : trak = gf_isom_get_track_from_file(the_file, trackNumber);
362 2 : if (dsi) *dsi = NULL;
363 2 : if (dsi_size) *dsi_size = 0;
364 2 : if (!trak || !StreamDescriptionIndex) return GF_BAD_PARAM;
365 :
366 2 : entry = (GF_MPEGAudioSampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->child_boxes, StreamDescriptionIndex-1);
367 :
368 2 : type = entry->type;
369 2 : if (type==GF_ISOM_BOX_TYPE_ENCA) {
370 0 : gf_isom_get_original_format_type(the_file, trackNumber, StreamDescriptionIndex, &type);
371 : }
372 :
373 2 : if (type!=GF_ISOM_BOX_TYPE_FLAC) return GF_BAD_PARAM;
374 2 : if (!entry->cfg_flac) return GF_OK;
375 2 : if (dsi) {
376 2 : *dsi = gf_malloc(sizeof(u8)*entry->cfg_flac->dataSize);
377 2 : memcpy(*dsi, entry->cfg_flac->data, entry->cfg_flac->dataSize);
378 : }
379 2 : if (dsi_size) *dsi_size = entry->cfg_flac->dataSize;
380 : return GF_OK;
381 : }
382 :
383 : GF_EXPORT
384 2 : GF_Err gf_isom_truehd_config_get(GF_ISOFile *the_file, u32 trackNumber, u32 StreamDescriptionIndex, u32 *format_info, u32 *peak_data_rate)
385 : {
386 : GF_TrackBox *trak;
387 : GF_MPEGAudioSampleEntryBox *entry;
388 2 : trak = gf_isom_get_track_from_file(the_file, trackNumber);
389 2 : if (!trak || !StreamDescriptionIndex) return GF_BAD_PARAM;
390 :
391 2 : entry = (GF_MPEGAudioSampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->child_boxes, StreamDescriptionIndex-1);
392 2 : if (!entry) return GF_BAD_PARAM;
393 2 : if (entry->type != GF_ISOM_SUBTYPE_MLPA) return GF_BAD_PARAM;
394 :
395 2 : if (!entry->cfg_mlp) return GF_ISOM_INVALID_FILE;
396 2 : if (format_info) *format_info = entry->cfg_mlp->format_info;
397 2 : if (peak_data_rate) *peak_data_rate = entry->cfg_mlp->peak_data_rate;
398 : return GF_OK;
399 : }
400 :
401 : #ifndef GPAC_DISABLE_ISOM_WRITE
402 1 : GF_Err gf_isom_truehd_config_new(GF_ISOFile *the_file, u32 trackNumber, char *URLname, char *URNname, u32 format, u32 peak_rate, u32 *outDescriptionIndex)
403 : {
404 : GF_TrackBox *trak;
405 : GF_Err e;
406 : u32 dataRefIndex;
407 : GF_MPEGAudioSampleEntryBox *entry;
408 : GF_SampleDescriptionBox *stsd;
409 :
410 1 : e = CanAccessMovie(the_file, GF_ISOM_OPEN_WRITE);
411 1 : if (e) return e;
412 :
413 1 : trak = gf_isom_get_track_from_file(the_file, trackNumber);
414 1 : if (!trak || !trak->Media) return GF_BAD_PARAM;
415 :
416 : //get or create the data ref
417 1 : e = Media_FindDataRef(trak->Media->information->dataInformation->dref, URLname, URNname, &dataRefIndex);
418 1 : if (e) return e;
419 1 : if (!dataRefIndex) {
420 1 : e = Media_CreateDataRef(the_file, trak->Media->information->dataInformation->dref, URLname, URNname, &dataRefIndex);
421 1 : if (e) return e;
422 : }
423 1 : if (!the_file->keep_utc)
424 1 : trak->Media->mediaHeader->modificationTime = gf_isom_get_mp4time();
425 :
426 1 : stsd = trak->Media->information->sampleTable->SampleDescription;
427 : //create a new entry
428 1 : entry = (GF_MPEGAudioSampleEntryBox *)gf_isom_box_new_parent(&stsd->child_boxes, GF_ISOM_BOX_TYPE_MLPA);
429 1 : if (!entry) return GF_OUT_OF_MEM;
430 1 : entry->cfg_mlp = (GF_TrueHDConfigBox *)gf_isom_box_new_parent(&entry->child_boxes, GF_ISOM_BOX_TYPE_DMLP);
431 1 : if (!entry->cfg_mlp) return GF_OUT_OF_MEM;
432 1 : entry->cfg_mlp->format_info = format;
433 1 : entry->cfg_mlp->peak_data_rate = (u16) peak_rate;
434 1 : entry->dataReferenceIndex = dataRefIndex;
435 1 : *outDescriptionIndex = gf_list_count(stsd->child_boxes);
436 1 : return e;
437 : }
438 : #endif
439 :
440 : #ifndef GPAC_DISABLE_ISOM_WRITE
441 : GF_EXPORT
442 2 : GF_Err gf_isom_opus_config_new(GF_ISOFile *the_file, u32 trackNumber, GF_OpusSpecificBox *cfg, char *URLname, char *URNname, u32 *outDescriptionIndex)
443 : {
444 : GF_TrackBox *trak;
445 : GF_Err e;
446 : u32 dataRefIndex;
447 : GF_MPEGAudioSampleEntryBox *entry;
448 : GF_SampleDescriptionBox *stsd;
449 : ptrdiff_t offset;
450 :
451 2 : e = CanAccessMovie(the_file, GF_ISOM_OPEN_WRITE);
452 2 : if (e) return e;
453 :
454 2 : trak = gf_isom_get_track_from_file(the_file, trackNumber);
455 2 : if (!trak || !trak->Media || !cfg) return GF_BAD_PARAM;
456 :
457 : //get or create the data ref
458 2 : e = Media_FindDataRef(trak->Media->information->dataInformation->dref, URLname, URNname, &dataRefIndex);
459 2 : if (e) return e;
460 2 : if (!dataRefIndex) {
461 2 : e = Media_CreateDataRef(the_file, trak->Media->information->dataInformation->dref, URLname, URNname, &dataRefIndex);
462 2 : if (e) return e;
463 : }
464 2 : if (!the_file->keep_utc)
465 2 : trak->Media->mediaHeader->modificationTime = gf_isom_get_mp4time();
466 :
467 2 : stsd = trak->Media->information->sampleTable->SampleDescription;
468 : //create a new entry
469 2 : entry = (GF_MPEGAudioSampleEntryBox *)gf_isom_box_new_parent(&stsd->child_boxes, GF_ISOM_BOX_TYPE_OPUS);
470 2 : if (!entry) return GF_OUT_OF_MEM;
471 2 : entry->cfg_opus = (GF_OpusSpecificBox*)gf_isom_box_new_parent(&entry->child_boxes, GF_ISOM_BOX_TYPE_DOPS);
472 2 : if (!entry->cfg_opus) return GF_OUT_OF_MEM;
473 : //skip box header
474 : offset = (ptrdiff_t)&cfg->version - (ptrdiff_t)cfg;
475 2 : memcpy((char*)entry->cfg_opus + offset, (char*)cfg + offset, sizeof(GF_OpusSpecificBox) - (size_t)offset);
476 :
477 2 : entry->dataReferenceIndex = dataRefIndex;
478 2 : *outDescriptionIndex = gf_list_count(stsd->child_boxes);
479 2 : return e;
480 : }
481 : #endif
482 :
483 : GF_EXPORT
484 0 : GF_Err gf_isom_opus_config_get(GF_ISOFile *the_file, u32 trackNumber, u32 StreamDescriptionIndex, u8 **dsi, u32 *dsi_size)
485 : {
486 : u32 type;
487 : GF_TrackBox *trak;
488 : GF_MPEGAudioSampleEntryBox *entry;
489 0 : trak = gf_isom_get_track_from_file(the_file, trackNumber);
490 0 : if (dsi) *dsi = NULL;
491 0 : if (dsi_size) *dsi_size = 0;
492 0 : if (!trak || !StreamDescriptionIndex) return GF_BAD_PARAM;
493 :
494 0 : entry = (GF_MPEGAudioSampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->child_boxes, StreamDescriptionIndex-1);
495 :
496 0 : type = entry->type;
497 0 : if (type==GF_ISOM_BOX_TYPE_ENCA) {
498 0 : gf_isom_get_original_format_type(the_file, trackNumber, StreamDescriptionIndex, &type);
499 : }
500 0 : if (type != GF_ISOM_SUBTYPE_OPUS)
501 : return GF_BAD_PARAM;
502 :
503 0 : if (!entry->cfg_opus)
504 : return GF_BAD_PARAM;
505 :
506 0 : if (dsi && dsi_size) {
507 0 : GF_BitStream *bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
508 0 : gf_isom_box_size((GF_Box *)entry->cfg_opus);
509 0 : gf_isom_box_write((GF_Box *)entry->cfg_opus, bs);
510 0 : gf_bs_get_content(bs, dsi, dsi_size);
511 0 : gf_bs_del(bs);
512 : }
513 : return GF_OK;
514 : }
515 :
516 : #ifndef GPAC_DISABLE_ISOM_WRITE
517 :
518 : GF_EXPORT
519 21 : GF_Err gf_isom_3gp_config_new(GF_ISOFile *the_file, u32 trackNumber, GF_3GPConfig *cfg, const char *URLname, const char *URNname, u32 *outDescriptionIndex)
520 : {
521 : GF_TrackBox *trak;
522 : GF_Err e;
523 : u32 dataRefIndex;
524 : u32 cfg_type;
525 : GF_SampleDescriptionBox *stsd;
526 :
527 21 : e = CanAccessMovie(the_file, GF_ISOM_OPEN_WRITE);
528 21 : if (e) return e;
529 :
530 21 : trak = gf_isom_get_track_from_file(the_file, trackNumber);
531 21 : if (!trak || !trak->Media || !cfg) return GF_BAD_PARAM;
532 :
533 21 : switch (cfg->type) {
534 12 : case GF_ISOM_SUBTYPE_3GP_AMR:
535 : case GF_ISOM_SUBTYPE_3GP_AMR_WB:
536 12 : if (trak->Media->handler->handlerType!=GF_ISOM_MEDIA_AUDIO) return GF_BAD_PARAM;
537 : cfg_type = GF_ISOM_BOX_TYPE_DAMR;
538 : break;
539 1 : case GF_ISOM_SUBTYPE_3GP_EVRC:
540 1 : if (trak->Media->handler->handlerType!=GF_ISOM_MEDIA_AUDIO) return GF_BAD_PARAM;
541 : cfg_type = GF_ISOM_BOX_TYPE_DEVC;
542 : break;
543 3 : case GF_ISOM_SUBTYPE_3GP_QCELP:
544 3 : if (trak->Media->handler->handlerType!=GF_ISOM_MEDIA_AUDIO) return GF_BAD_PARAM;
545 : cfg_type = GF_ISOM_BOX_TYPE_DQCP;
546 : break;
547 0 : case GF_ISOM_SUBTYPE_3GP_SMV:
548 0 : if (trak->Media->handler->handlerType!=GF_ISOM_MEDIA_AUDIO) return GF_BAD_PARAM;
549 : cfg_type = GF_ISOM_BOX_TYPE_DSMV;
550 : break;
551 5 : case GF_ISOM_SUBTYPE_3GP_H263:
552 5 : if (!gf_isom_is_video_handler_type(trak->Media->handler->handlerType)) return GF_BAD_PARAM;
553 : cfg_type = GF_ISOM_BOX_TYPE_D263;
554 : break;
555 : case 0:
556 : return GF_BAD_PARAM;
557 0 : default:
558 0 : return GF_NOT_SUPPORTED;
559 : }
560 :
561 : //get or create the data ref
562 21 : e = Media_FindDataRef(trak->Media->information->dataInformation->dref, (char *)URLname, (char *)URNname, &dataRefIndex);
563 21 : if (e) return e;
564 21 : if (!dataRefIndex) {
565 16 : e = Media_CreateDataRef(the_file, trak->Media->information->dataInformation->dref, (char *)URLname, (char *)URNname, &dataRefIndex);
566 16 : if (e) return e;
567 : }
568 21 : if (!the_file->keep_utc)
569 21 : trak->Media->mediaHeader->modificationTime = gf_isom_get_mp4time();
570 :
571 21 : stsd = trak->Media->information->sampleTable->SampleDescription;
572 :
573 21 : switch (cfg->type) {
574 16 : case GF_ISOM_SUBTYPE_3GP_AMR:
575 : case GF_ISOM_SUBTYPE_3GP_AMR_WB:
576 : case GF_ISOM_SUBTYPE_3GP_EVRC:
577 : case GF_ISOM_SUBTYPE_3GP_QCELP:
578 : case GF_ISOM_SUBTYPE_3GP_SMV:
579 : {
580 16 : GF_MPEGAudioSampleEntryBox *entry = (GF_MPEGAudioSampleEntryBox *) gf_isom_box_new_parent(&stsd->child_boxes, cfg->type);
581 16 : if (!entry) return GF_OUT_OF_MEM;
582 16 : entry->cfg_3gpp = (GF_3GPPConfigBox *) gf_isom_box_new_parent(&entry->child_boxes, cfg_type);
583 16 : if (!entry->cfg_3gpp) {
584 0 : gf_isom_box_del((GF_Box *) entry);
585 0 : return GF_OUT_OF_MEM;
586 : }
587 16 : memcpy(&entry->cfg_3gpp->cfg, cfg, sizeof(GF_3GPConfig));
588 16 : entry->samplerate_hi = trak->Media->mediaHeader->timeScale;
589 16 : entry->dataReferenceIndex = dataRefIndex;
590 16 : *outDescriptionIndex = gf_list_count(trak->Media->information->sampleTable->SampleDescription->child_boxes);
591 : }
592 16 : break;
593 5 : case GF_ISOM_SUBTYPE_3GP_H263:
594 : {
595 5 : GF_MPEGVisualSampleEntryBox *entry = (GF_MPEGVisualSampleEntryBox *) gf_isom_box_new_parent(&stsd->child_boxes, cfg->type);
596 5 : if (!entry) return GF_OUT_OF_MEM;
597 5 : entry->cfg_3gpp = (GF_3GPPConfigBox *) gf_isom_box_new_parent(&entry->child_boxes, cfg_type);
598 5 : if (!entry->cfg_3gpp) {
599 0 : gf_isom_box_del((GF_Box *) entry);
600 0 : return GF_OUT_OF_MEM;
601 : }
602 5 : memcpy(&entry->cfg_3gpp->cfg, cfg, sizeof(GF_3GPConfig));
603 5 : entry->dataReferenceIndex = dataRefIndex;
604 5 : *outDescriptionIndex = gf_list_count(trak->Media->information->sampleTable->SampleDescription->child_boxes);
605 : }
606 5 : break;
607 : }
608 : return e;
609 : }
610 :
611 : GF_EXPORT
612 0 : GF_Err gf_isom_3gp_config_update(GF_ISOFile *the_file, u32 trackNumber, GF_3GPConfig *param, u32 DescriptionIndex)
613 : {
614 : GF_TrackBox *trak;
615 : GF_Err e;
616 : GF_3GPConfig *cfg;
617 : GF_MPEGAudioSampleEntryBox *a_entry;
618 : GF_MPEGVisualSampleEntryBox *v_entry;
619 :
620 0 : e = CanAccessMovie(the_file, GF_ISOM_OPEN_WRITE);
621 0 : if (e) return e;
622 :
623 0 : trak = gf_isom_get_track_from_file(the_file, trackNumber);
624 0 : if (!trak || !trak->Media || !param || !DescriptionIndex) return GF_BAD_PARAM;
625 :
626 : cfg = NULL;
627 0 : a_entry = (GF_MPEGAudioSampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->child_boxes, DescriptionIndex-1);
628 0 : if (!a_entry) return GF_BAD_PARAM;
629 : v_entry = (GF_MPEGVisualSampleEntryBox *) a_entry;
630 :
631 0 : switch (a_entry->type) {
632 0 : case GF_ISOM_SUBTYPE_3GP_AMR:
633 : case GF_ISOM_SUBTYPE_3GP_AMR_WB:
634 : case GF_ISOM_SUBTYPE_3GP_EVRC:
635 : case GF_ISOM_SUBTYPE_3GP_QCELP:
636 : case GF_ISOM_SUBTYPE_3GP_SMV:
637 0 : cfg = &a_entry->cfg_3gpp->cfg;
638 0 : break;
639 0 : case GF_ISOM_SUBTYPE_3GP_H263:
640 0 : cfg = & v_entry->cfg_3gpp->cfg;
641 0 : break;
642 : default:
643 : break;
644 : }
645 0 : if (!cfg || (cfg->type != param->type)) return GF_BAD_PARAM;
646 : memcpy(cfg, param, sizeof(GF_3GPConfig));
647 0 : return GF_OK;
648 : }
649 :
650 : GF_EXPORT
651 11 : GF_Err gf_isom_ac3_config_new(GF_ISOFile *the_file, u32 trackNumber, GF_AC3Config *cfg, const char *URLname, const char *URNname, u32 *outDescriptionIndex)
652 : {
653 : GF_TrackBox *trak;
654 : GF_Err e;
655 : u32 dataRefIndex;
656 : GF_MPEGAudioSampleEntryBox *entry;
657 :
658 11 : e = CanAccessMovie(the_file, GF_ISOM_OPEN_WRITE);
659 11 : if (e) return e;
660 :
661 11 : trak = gf_isom_get_track_from_file(the_file, trackNumber);
662 11 : if (!trak || !trak->Media || !cfg) return GF_BAD_PARAM;
663 :
664 : //get or create the data ref
665 11 : e = Media_FindDataRef(trak->Media->information->dataInformation->dref, (char *)URLname, (char *)URNname, &dataRefIndex);
666 11 : if (e) return e;
667 11 : if (!dataRefIndex) {
668 10 : e = Media_CreateDataRef(the_file, trak->Media->information->dataInformation->dref, (char *)URLname, (char *)URNname, &dataRefIndex);
669 10 : if (e) return e;
670 : }
671 11 : if (!the_file->keep_utc)
672 11 : trak->Media->mediaHeader->modificationTime = gf_isom_get_mp4time();
673 :
674 11 : if (cfg->is_ec3) {
675 2 : entry = (GF_MPEGAudioSampleEntryBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_EC3);
676 2 : if (!entry) return GF_OUT_OF_MEM;
677 2 : entry->cfg_ac3 = (GF_AC3ConfigBox *) gf_isom_box_new_parent(&entry->child_boxes, GF_ISOM_BOX_TYPE_DEC3);
678 : } else {
679 9 : entry = (GF_MPEGAudioSampleEntryBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_AC3);
680 9 : if (!entry) return GF_OUT_OF_MEM;
681 9 : entry->cfg_ac3 = (GF_AC3ConfigBox *) gf_isom_box_new_parent(&entry->child_boxes, GF_ISOM_BOX_TYPE_DAC3);
682 : }
683 11 : if (!entry->cfg_ac3) {
684 0 : gf_isom_box_del((GF_Box *) entry);
685 0 : return GF_OUT_OF_MEM;
686 : }
687 11 : memcpy(&entry->cfg_ac3->cfg, cfg, sizeof(GF_AC3Config));
688 11 : entry->samplerate_hi = trak->Media->mediaHeader->timeScale;
689 11 : entry->dataReferenceIndex = dataRefIndex;
690 11 : e = gf_list_add(trak->Media->information->sampleTable->SampleDescription->child_boxes, entry);
691 11 : *outDescriptionIndex = gf_list_count(trak->Media->information->sampleTable->SampleDescription->child_boxes);
692 11 : return e;
693 : }
694 :
695 : GF_EXPORT
696 2 : GF_Err gf_isom_flac_config_new(GF_ISOFile *the_file, u32 trackNumber, u8 *metadata, u32 metadata_size, const char *URLname, const char *URNname, u32 *outDescriptionIndex)
697 : {
698 : GF_TrackBox *trak;
699 : GF_Err e;
700 : u32 dataRefIndex;
701 : GF_MPEGAudioSampleEntryBox *entry;
702 :
703 2 : e = CanAccessMovie(the_file, GF_ISOM_OPEN_WRITE);
704 2 : if (e) return e;
705 :
706 2 : trak = gf_isom_get_track_from_file(the_file, trackNumber);
707 2 : if (!trak || !trak->Media) return GF_BAD_PARAM;
708 :
709 : //get or create the data ref
710 2 : e = Media_FindDataRef(trak->Media->information->dataInformation->dref, (char *)URLname, (char *)URNname, &dataRefIndex);
711 2 : if (e) return e;
712 2 : if (!dataRefIndex) {
713 2 : e = Media_CreateDataRef(the_file, trak->Media->information->dataInformation->dref, (char *)URLname, (char *)URNname, &dataRefIndex);
714 2 : if (e) return e;
715 : }
716 2 : if (!the_file->keep_utc)
717 2 : trak->Media->mediaHeader->modificationTime = gf_isom_get_mp4time();
718 :
719 2 : entry = (GF_MPEGAudioSampleEntryBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_FLAC);
720 2 : if (!entry) return GF_OUT_OF_MEM;
721 2 : entry->cfg_flac = (GF_FLACConfigBox *) gf_isom_box_new_parent(&entry->child_boxes, GF_ISOM_BOX_TYPE_DFLA);
722 :
723 2 : if (!entry->cfg_flac) {
724 0 : gf_isom_box_del((GF_Box *) entry);
725 0 : return GF_OUT_OF_MEM;
726 : }
727 2 : entry->cfg_flac->dataSize = metadata_size;
728 2 : entry->cfg_flac->data = gf_malloc(sizeof(u8)*metadata_size);
729 2 : memcpy(entry->cfg_flac->data, metadata, sizeof(u8)*metadata_size);
730 2 : entry->samplerate_hi = trak->Media->mediaHeader->timeScale;
731 2 : entry->dataReferenceIndex = dataRefIndex;
732 2 : e = gf_list_add(trak->Media->information->sampleTable->SampleDescription->child_boxes, entry);
733 2 : *outDescriptionIndex = gf_list_count(trak->Media->information->sampleTable->SampleDescription->child_boxes);
734 2 : return e;
735 : }
736 :
737 :
738 :
739 : GF_EXPORT
740 7 : GF_Err gf_isom_new_mj2k_description(GF_ISOFile *the_file, u32 trackNumber, const char *URLname, const char *URNname, u32 *outDescriptionIndex, u8 *dsi, u32 dsi_len)
741 : {
742 : GF_TrackBox *trak;
743 : GF_Err e;
744 7 : u32 dataRefIndex=0;
745 :
746 7 : e = CanAccessMovie(the_file, GF_ISOM_OPEN_WRITE);
747 7 : if (e) return e;
748 :
749 7 : trak = gf_isom_get_track_from_file(the_file, trackNumber);
750 7 : if (!trak || !trak->Media) return GF_BAD_PARAM;
751 :
752 : //get or create the data ref
753 7 : e = Media_FindDataRef(trak->Media->information->dataInformation->dref, (char *)URLname, (char *)URNname, &dataRefIndex);
754 7 : if (e) return e;
755 7 : if (!dataRefIndex) {
756 5 : e = Media_CreateDataRef(the_file, trak->Media->information->dataInformation->dref, (char *)URLname, (char *)URNname, &dataRefIndex);
757 5 : if (e) return e;
758 : }
759 7 : if (!the_file->keep_utc)
760 7 : trak->Media->mediaHeader->modificationTime = gf_isom_get_mp4time();
761 :
762 7 : GF_MPEGVisualSampleEntryBox *entry = (GF_MPEGVisualSampleEntryBox *) gf_isom_box_new_parent(&trak->Media->information->sampleTable->SampleDescription->child_boxes, GF_ISOM_BOX_TYPE_MJP2);
763 7 : if (!entry) return GF_OUT_OF_MEM;
764 7 : entry->jp2h = (GF_J2KHeaderBox *) gf_isom_box_new_parent(&entry->child_boxes, GF_ISOM_BOX_TYPE_JP2H);
765 7 : if (!entry->jp2h) {
766 0 : gf_isom_box_del_parent(&trak->Media->information->sampleTable->SampleDescription->child_boxes, (GF_Box *) entry);
767 0 : return GF_OUT_OF_MEM;
768 : }
769 7 : if (dsi && dsi_len) {
770 5 : GF_BitStream *bs = gf_bs_new(dsi, dsi_len, GF_BITSTREAM_READ);
771 5 : entry->jp2h->size = dsi_len;
772 5 : gf_isom_box_read((GF_Box *)entry->jp2h, bs);
773 5 : gf_bs_del(bs);
774 : }
775 7 : entry->dataReferenceIndex = dataRefIndex;
776 7 : *outDescriptionIndex = gf_list_count(trak->Media->information->sampleTable->SampleDescription->child_boxes);
777 7 : return e;
778 : }
779 :
780 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
781 :
782 :
783 :
784 : GF_EXPORT
785 5 : GF_Err gf_isom_get_dims_description(GF_ISOFile *movie, u32 trackNumber, u32 descriptionIndex, GF_DIMSDescription *desc)
786 : {
787 : GF_DIMSSampleEntryBox *dims;
788 : GF_TrackBox *trak;
789 5 : trak = gf_isom_get_track_from_file(movie, trackNumber);
790 5 : if (!trak || !descriptionIndex || !desc) return GF_BAD_PARAM;
791 :
792 5 : dims = (GF_DIMSSampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->child_boxes, descriptionIndex-1);
793 5 : if (!dims) return GF_BAD_PARAM;
794 5 : if (dims->type != GF_ISOM_BOX_TYPE_DIMS) return GF_BAD_PARAM;
795 :
796 : memset(desc, 0, sizeof(GF_DIMSDescription));
797 5 : if (dims->config) {
798 5 : desc->profile = dims->config->profile;
799 5 : desc->level = dims->config->level;
800 5 : desc->pathComponents = dims->config->pathComponents;
801 5 : desc->fullRequestHost = dims->config->fullRequestHost;
802 5 : desc->containsRedundant = dims->config->containsRedundant;
803 5 : desc->streamType = dims->config->streamType;
804 5 : desc->textEncoding = dims->config->textEncoding;
805 5 : desc->contentEncoding = dims->config->contentEncoding;
806 : }
807 5 : if (dims->scripts) {
808 0 : desc->content_script_types = dims->scripts->content_script_types;
809 : }
810 : return GF_OK;
811 : }
812 :
813 : #ifndef GPAC_DISABLE_ISOM_WRITE
814 :
815 : GF_EXPORT
816 2 : GF_Err gf_isom_new_dims_description(GF_ISOFile *movie, u32 trackNumber, GF_DIMSDescription *desc, const char *URLname, const char *URNname, u32 *outDescriptionIndex)
817 : {
818 : GF_TrackBox *trak;
819 : GF_Err e;
820 : u32 dataRefIndex;
821 : GF_DIMSSampleEntryBox *dims;
822 :
823 2 : e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE);
824 2 : if (e) return e;
825 :
826 2 : trak = gf_isom_get_track_from_file(movie, trackNumber);
827 2 : if (!trak || !trak->Media) return GF_BAD_PARAM;
828 :
829 2 : if (trak->Media->handler->handlerType != GF_ISOM_MEDIA_SCENE) return GF_BAD_PARAM;
830 :
831 : //get or create the data ref
832 2 : e = Media_FindDataRef(trak->Media->information->dataInformation->dref, (char *)URLname, (char *)URNname, &dataRefIndex);
833 2 : if (e) return e;
834 2 : if (!dataRefIndex) {
835 2 : e = Media_CreateDataRef(movie, trak->Media->information->dataInformation->dref, (char *)URLname, (char *)URNname, &dataRefIndex);
836 2 : if (e) return e;
837 : }
838 2 : if (!movie->keep_utc)
839 2 : trak->Media->mediaHeader->modificationTime = gf_isom_get_mp4time();
840 :
841 2 : dims = (GF_DIMSSampleEntryBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_DIMS);
842 2 : if (!dims) return GF_OUT_OF_MEM;
843 2 : dims->dataReferenceIndex = dataRefIndex;
844 2 : gf_list_add(trak->Media->information->sampleTable->SampleDescription->child_boxes, dims);
845 2 : if (outDescriptionIndex) *outDescriptionIndex = gf_list_count(trak->Media->information->sampleTable->SampleDescription->child_boxes);
846 :
847 2 : dims->config = (GF_DIMSSceneConfigBox*) gf_isom_box_new_parent(&dims->child_boxes, GF_ISOM_BOX_TYPE_DIMC);
848 2 : if (!dims->config) return GF_OUT_OF_MEM;
849 :
850 2 : dims->config->profile = desc->profile;
851 2 : dims->config->level = desc->level;
852 2 : dims->config->pathComponents = desc->pathComponents;
853 2 : dims->config->fullRequestHost = desc->fullRequestHost;
854 2 : dims->config->containsRedundant = desc->containsRedundant;
855 2 : if (!dims->config->containsRedundant) dims->config->containsRedundant = 1;
856 2 : dims->config->streamType = desc->streamType;
857 2 : dims->config->textEncoding = gf_strdup(desc->textEncoding ? desc->textEncoding : "");
858 2 : dims->config->contentEncoding = gf_strdup(desc->contentEncoding ? desc->contentEncoding : "");
859 :
860 2 : if (desc->content_script_types) {
861 0 : dims->scripts = (GF_DIMSScriptTypesBox*) gf_isom_box_new_parent(&dims->child_boxes, GF_ISOM_BOX_TYPE_DIST);
862 0 : if (!dims->scripts) return GF_OUT_OF_MEM;
863 0 : dims->scripts->content_script_types = gf_strdup(desc->content_script_types);
864 : }
865 : return e;
866 : }
867 :
868 : #if 0 //unused
869 : GF_Err gf_isom_update_dims_description(GF_ISOFile *movie, u32 trackNumber, GF_DIMSDescription *desc, char *URLname, char *URNname, u32 DescriptionIndex)
870 : {
871 : GF_TrackBox *trak;
872 : GF_Err e;
873 : GF_DIMSSampleEntryBox *dims;
874 :
875 : e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE);
876 : if (e) return e;
877 :
878 : trak = gf_isom_get_track_from_file(movie, trackNumber);
879 : if (!trak || !trak->Media || !desc || !DescriptionIndex) return GF_BAD_PARAM;
880 :
881 : dims = (GF_DIMSSampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->child_boxes, DescriptionIndex-1);
882 : if (!dims) return GF_BAD_PARAM;
883 : if (dims->type != GF_ISOM_BOX_TYPE_DIMS) return GF_BAD_PARAM;
884 : if (!dims->config) {
885 : dims->config = (GF_DIMSSceneConfigBox*) gf_isom_box_new_parent(&dims->child_boxes, GF_ISOM_BOX_TYPE_DIMC);
886 : if (!dims->config) return GF_OUT_OF_MEM;
887 : }
888 :
889 : if (!movie->keep_utc)
890 : trak->Media->mediaHeader->modificationTime = gf_isom_get_mp4time();
891 :
892 : dims->config->profile = desc->profile;
893 : dims->config->level = desc->level;
894 : dims->config->pathComponents = desc->pathComponents;
895 : dims->config->fullRequestHost = desc->fullRequestHost;
896 : dims->config->containsRedundant = desc->containsRedundant;
897 : dims->config->streamType = desc->streamType;
898 :
899 : if (dims->config->textEncoding) gf_free(dims->config->textEncoding);
900 : dims->config->textEncoding = gf_strdup(desc->textEncoding ? desc->textEncoding : "");
901 :
902 : if (dims->config->contentEncoding) gf_free(dims->config->contentEncoding);
903 : dims->config->contentEncoding = gf_strdup(desc->contentEncoding ? desc->contentEncoding : "");
904 :
905 : if (desc->content_script_types) {
906 : if (!dims->scripts) {
907 : dims->scripts = (GF_DIMSScriptTypesBox*) gf_isom_box_new_parent(&dims->child_boxes, GF_ISOM_BOX_TYPE_DIST);
908 : if (!dims->scripts) return GF_OUT_OF_MEM;
909 : }
910 : if (dims->scripts->content_script_types) gf_free(dims->scripts->content_script_types);
911 : dims->scripts->content_script_types = gf_strdup(desc->content_script_types ? desc->content_script_types :"");
912 : } else if (dims->scripts) {
913 : gf_isom_box_del_parent(&dims->child_boxes, (GF_Box *) dims->scripts);
914 : dims->scripts = NULL;
915 : }
916 : return GF_OK;
917 : }
918 : #endif
919 :
920 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
921 :
922 5 : GF_Err LSR_UpdateESD(GF_LASeRSampleEntryBox *lsr, GF_ESD *esd)
923 : {
924 5 : GF_BitRateBox *btrt = gf_isom_sample_entry_get_bitrate((GF_SampleEntryBox *)lsr, GF_TRUE);
925 :
926 5 : if (lsr->descr) gf_isom_box_del_parent(&lsr->child_boxes, (GF_Box *) lsr->descr);
927 5 : lsr->descr = NULL;
928 5 : btrt->avgBitrate = esd->decoderConfig->avgBitrate;
929 5 : btrt->maxBitrate = esd->decoderConfig->maxBitrate;
930 5 : btrt->bufferSizeDB = esd->decoderConfig->bufferSizeDB;
931 :
932 5 : if (gf_list_count(esd->IPIDataSet)
933 5 : || gf_list_count(esd->IPMPDescriptorPointers)
934 5 : || esd->langDesc
935 5 : || gf_list_count(esd->extensionDescriptors)
936 5 : || esd->ipiPtr || esd->qos || esd->RegDescriptor) {
937 :
938 0 : lsr->descr = (GF_MPEG4ExtensionDescriptorsBox *)gf_isom_box_new_parent(&lsr->child_boxes, GF_ISOM_BOX_TYPE_M4DS);
939 0 : if (!lsr->descr) return GF_OUT_OF_MEM;
940 0 : if (esd->RegDescriptor) {
941 0 : gf_list_add(lsr->descr->descriptors, esd->RegDescriptor);
942 0 : esd->RegDescriptor = NULL;
943 : }
944 0 : if (esd->qos) {
945 0 : gf_list_add(lsr->descr->descriptors, esd->qos);
946 0 : esd->qos = NULL;
947 : }
948 0 : if (esd->ipiPtr) {
949 0 : gf_list_add(lsr->descr->descriptors, esd->ipiPtr);
950 0 : esd->ipiPtr= NULL;
951 : }
952 :
953 0 : while (gf_list_count(esd->IPIDataSet)) {
954 0 : GF_Descriptor *desc = (GF_Descriptor *)gf_list_get(esd->IPIDataSet, 0);
955 0 : gf_list_rem(esd->IPIDataSet, 0);
956 0 : gf_list_add(lsr->descr->descriptors, desc);
957 : }
958 0 : while (gf_list_count(esd->IPMPDescriptorPointers)) {
959 0 : GF_Descriptor *desc = (GF_Descriptor *)gf_list_get(esd->IPMPDescriptorPointers, 0);
960 0 : gf_list_rem(esd->IPMPDescriptorPointers, 0);
961 0 : gf_list_add(lsr->descr->descriptors, desc);
962 : }
963 0 : if (esd->langDesc) {
964 0 : gf_list_add(lsr->descr->descriptors, esd->langDesc);
965 0 : esd->langDesc = NULL;
966 : }
967 0 : while (gf_list_count(esd->extensionDescriptors)) {
968 0 : GF_Descriptor *desc = (GF_Descriptor *)gf_list_get(esd->extensionDescriptors, 0);
969 0 : gf_list_rem(esd->extensionDescriptors, 0);
970 0 : gf_list_add(lsr->descr->descriptors, desc);
971 : }
972 : }
973 :
974 : /*update GF_AVCConfig*/
975 5 : if (!lsr->lsr_config) {
976 3 : lsr->lsr_config = (GF_LASERConfigurationBox *)gf_isom_box_new_parent(&lsr->child_boxes, GF_ISOM_BOX_TYPE_LSRC);
977 3 : if (!lsr->lsr_config) return GF_OUT_OF_MEM;
978 : }
979 5 : if (esd->decoderConfig->decoderSpecificInfo && esd->decoderConfig->decoderSpecificInfo->data) {
980 5 : lsr->lsr_config->hdr = gf_realloc(lsr->lsr_config->hdr, sizeof(char) * esd->decoderConfig->decoderSpecificInfo->dataLength);
981 5 : lsr->lsr_config->hdr_size = esd->decoderConfig->decoderSpecificInfo->dataLength;
982 5 : memcpy(lsr->lsr_config->hdr, esd->decoderConfig->decoderSpecificInfo->data, sizeof(char)*esd->decoderConfig->decoderSpecificInfo->dataLength);
983 : }
984 5 : gf_odf_desc_del((GF_Descriptor *)esd);
985 5 : return GF_OK;
986 : }
987 :
988 : /* MetadataSampleEntry */
989 : GF_EXPORT
990 1 : GF_Err gf_isom_get_xml_metadata_description(GF_ISOFile *file, u32 track, u32 sampleDescription,
991 : const char **_namespace, const char **schema_loc, const char **content_encoding)
992 : {
993 : GF_TrackBox *trak;
994 : GF_MetaDataSampleEntryBox *ptr;
995 1 : if (_namespace) *_namespace = NULL;
996 1 : if (content_encoding) *content_encoding = NULL;
997 1 : if (schema_loc) *schema_loc = NULL;
998 1 : trak = gf_isom_get_track_from_file(file, track);
999 1 : if (!trak || !sampleDescription) return GF_BAD_PARAM;
1000 1 : ptr = (GF_MetaDataSampleEntryBox*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->child_boxes, sampleDescription-1);
1001 1 : if (!ptr) return GF_BAD_PARAM;
1002 :
1003 1 : if (schema_loc) *schema_loc = ptr->xml_schema_loc;
1004 1 : if (_namespace) *_namespace = ptr->xml_namespace;
1005 1 : if (content_encoding) *content_encoding = ptr->content_encoding;
1006 : return GF_OK;
1007 : }
1008 :
1009 : #ifndef GPAC_DISABLE_ISOM_WRITE
1010 :
1011 3 : GF_Err gf_isom_new_xml_metadata_description(GF_ISOFile *movie, u32 trackNumber,
1012 : const char *_namespace, const char *schema_loc, const char *content_encoding,
1013 : u32 *outDescriptionIndex)
1014 : {
1015 : GF_TrackBox *trak;
1016 : GF_Err e;
1017 : u32 dataRefIndex;
1018 : GF_MetaDataSampleEntryBox *metad;
1019 : char *URLname = NULL;
1020 : char *URNname = NULL;
1021 :
1022 3 : e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE);
1023 3 : if (e) return e;
1024 :
1025 3 : trak = gf_isom_get_track_from_file(movie, trackNumber);
1026 3 : if (!trak || !trak->Media || !_namespace)
1027 : return GF_BAD_PARAM;
1028 :
1029 2 : switch (trak->Media->handler->handlerType) {
1030 : case GF_ISOM_MEDIA_MPEG_SUBT:
1031 : case GF_ISOM_MEDIA_META:
1032 : case GF_ISOM_MEDIA_TEXT:
1033 : break;
1034 : default:
1035 : return GF_BAD_PARAM;
1036 : }
1037 :
1038 : //get or create the data ref
1039 2 : e = Media_FindDataRef(trak->Media->information->dataInformation->dref, URLname, URNname, &dataRefIndex);
1040 2 : if (e) return e;
1041 2 : if (!dataRefIndex) {
1042 2 : e = Media_CreateDataRef(movie, trak->Media->information->dataInformation->dref, URLname, URNname, &dataRefIndex);
1043 2 : if (e) return e;
1044 : }
1045 2 : if (!movie->keep_utc)
1046 2 : trak->Media->mediaHeader->modificationTime = gf_isom_get_mp4time();
1047 :
1048 2 : metad = (GF_MetaDataSampleEntryBox*) gf_isom_box_new(GF_ISOM_BOX_TYPE_METX);
1049 2 : if (!metad) return GF_OUT_OF_MEM;
1050 :
1051 2 : metad->dataReferenceIndex = dataRefIndex;
1052 2 : metad->xml_namespace = gf_strdup(_namespace);
1053 2 : if (content_encoding) metad->content_encoding = gf_strdup(content_encoding);
1054 2 : if (schema_loc) metad->xml_schema_loc = gf_strdup(schema_loc);
1055 :
1056 2 : e = gf_list_add(trak->Media->information->sampleTable->SampleDescription->child_boxes, metad);
1057 2 : if (outDescriptionIndex) *outDescriptionIndex = gf_list_count(trak->Media->information->sampleTable->SampleDescription->child_boxes);
1058 : return e;
1059 : }
1060 :
1061 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
1062 :
1063 : /* XMLSubtitleSampleEntry */
1064 : GF_EXPORT
1065 23 : GF_Err gf_isom_xml_subtitle_get_description(GF_ISOFile *the_file, u32 trackNumber, u32 StreamDescriptionIndex,
1066 : const char **xmlnamespace, const char **xml_schema_loc, const char **mimes)
1067 : {
1068 : GF_TrackBox *trak;
1069 : GF_MetaDataSampleEntryBox *entry;
1070 23 : if (xmlnamespace) *xmlnamespace = NULL;
1071 23 : if (xml_schema_loc) *xml_schema_loc = NULL;
1072 23 : if (mimes) *mimes = NULL;
1073 23 : trak = gf_isom_get_track_from_file(the_file, trackNumber);
1074 23 : if (!trak || !StreamDescriptionIndex) return GF_BAD_PARAM;
1075 :
1076 23 : entry = (GF_MetaDataSampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->child_boxes, StreamDescriptionIndex-1);
1077 23 : if (!entry) return GF_BAD_PARAM;
1078 :
1079 23 : if ((entry->type!=GF_ISOM_BOX_TYPE_STPP) && (entry->type!=GF_ISOM_BOX_TYPE_METX)) {
1080 : return GF_BAD_PARAM;
1081 : }
1082 :
1083 23 : if (entry->mime_type) {
1084 0 : if (mimes) *mimes = entry->mime_type;
1085 : }
1086 23 : if (entry->xml_schema_loc) {
1087 7 : if (xml_schema_loc) *xml_schema_loc = entry->xml_schema_loc;
1088 : }
1089 23 : if (xmlnamespace)
1090 23 : *xmlnamespace = entry->xml_namespace;
1091 : return GF_OK;
1092 : }
1093 :
1094 :
1095 : GF_EXPORT
1096 1195 : const char *gf_isom_subtitle_get_mime(GF_ISOFile *the_file, u32 trackNumber, u32 StreamDescriptionIndex)
1097 : {
1098 : GF_TrackBox *trak;
1099 : GF_TextConfigBox *mime;
1100 : GF_MetaDataSampleEntryBox *entry;
1101 1195 : trak = gf_isom_get_track_from_file(the_file, trackNumber);
1102 1195 : if (!trak || !StreamDescriptionIndex) return NULL;
1103 :
1104 1195 : entry = (GF_MetaDataSampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->child_boxes, StreamDescriptionIndex-1);
1105 1195 : if (!entry) return NULL;
1106 :
1107 1195 : mime = (GF_TextConfigBox *) gf_isom_box_find_child(entry->child_boxes, GF_ISOM_BOX_TYPE_MIME);
1108 1195 : if (!mime) return NULL;
1109 0 : return mime->config;
1110 : }
1111 :
1112 :
1113 : #ifndef GPAC_DISABLE_ISOM_WRITE
1114 :
1115 : GF_EXPORT
1116 0 : GF_Err gf_isom_subtitle_set_mime(GF_ISOFile *the_file, u32 trackNumber, u32 StreamDescriptionIndex, const char *codec_params)
1117 : {
1118 : GF_TrackBox *trak;
1119 : GF_Err e;
1120 : GF_TextConfigBox *mime;
1121 : GF_MetaDataSampleEntryBox *entry;
1122 :
1123 0 : e = CanAccessMovie(the_file, GF_ISOM_OPEN_WRITE);
1124 0 : if (e) return e;
1125 :
1126 0 : trak = gf_isom_get_track_from_file(the_file, trackNumber);
1127 0 : if (!trak || !StreamDescriptionIndex) return GF_BAD_PARAM;
1128 :
1129 0 : entry = (GF_MetaDataSampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->child_boxes, StreamDescriptionIndex-1);
1130 0 : if (!entry) return GF_BAD_PARAM;
1131 :
1132 0 : mime = (GF_TextConfigBox *) gf_isom_box_find_child(entry->child_boxes, GF_ISOM_BOX_TYPE_MIME);
1133 0 : if (!mime) {
1134 0 : if (!codec_params) return GF_OK;
1135 0 : mime = (GF_TextConfigBox *) gf_isom_box_new_parent(&entry->child_boxes, GF_ISOM_BOX_TYPE_MIME);
1136 0 : if (!mime) return GF_OUT_OF_MEM;
1137 : }
1138 0 : if (!codec_params) {
1139 0 : gf_isom_box_del_parent(&entry->child_boxes, (GF_Box *)mime);
1140 0 : return GF_OK;
1141 : }
1142 0 : if (mime->config) gf_free(mime->config);
1143 0 : mime->config = gf_strdup(codec_params);
1144 0 : return GF_OK;
1145 : }
1146 :
1147 : GF_EXPORT
1148 21 : GF_Err gf_isom_new_xml_subtitle_description(GF_ISOFile *movie, u32 trackNumber,
1149 : const char *xmlnamespace, const char *xml_schema_loc, const char *mimes,
1150 : u32 *outDescriptionIndex)
1151 : {
1152 : GF_TrackBox *trak;
1153 : GF_Err e;
1154 : u32 dataRefIndex;
1155 : GF_MetaDataSampleEntryBox *stpp;
1156 : char *URLname = NULL;
1157 : char *URNname = NULL;
1158 :
1159 21 : e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE);
1160 21 : if (e) return e;
1161 :
1162 21 : trak = gf_isom_get_track_from_file(movie, trackNumber);
1163 21 : if (!trak || !trak->Media) return GF_BAD_PARAM;
1164 :
1165 21 : switch (trak->Media->handler->handlerType) {
1166 : case GF_ISOM_MEDIA_MPEG_SUBT:
1167 : case GF_ISOM_MEDIA_META:
1168 : case GF_ISOM_MEDIA_TEXT:
1169 : break;
1170 : default:
1171 : return GF_BAD_PARAM;
1172 : }
1173 :
1174 21 : if (!xmlnamespace) {
1175 1 : GF_LOG(GF_LOG_WARNING, GF_LOG_PARSER, ("XML (Subtitle, Metadata or Text) SampleEntry: namespace is mandatory. Abort.\n"));
1176 : return GF_BAD_PARAM;
1177 : }
1178 :
1179 : //get or create the data ref
1180 20 : e = Media_FindDataRef(trak->Media->information->dataInformation->dref, URLname, URNname, &dataRefIndex);
1181 20 : if (e) return e;
1182 20 : if (!dataRefIndex) {
1183 20 : e = Media_CreateDataRef(movie, trak->Media->information->dataInformation->dref, URLname, URNname, &dataRefIndex);
1184 20 : if (e) return e;
1185 : }
1186 20 : if (!movie->keep_utc)
1187 20 : trak->Media->mediaHeader->modificationTime = gf_isom_get_mp4time();
1188 :
1189 20 : stpp = (GF_MetaDataSampleEntryBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_STPP);
1190 20 : if (!stpp) return GF_OUT_OF_MEM;
1191 20 : stpp->dataReferenceIndex = dataRefIndex;
1192 20 : gf_list_add(trak->Media->information->sampleTable->SampleDescription->child_boxes, stpp);
1193 20 : if (outDescriptionIndex) *outDescriptionIndex = gf_list_count(trak->Media->information->sampleTable->SampleDescription->child_boxes);
1194 :
1195 20 : stpp->xml_namespace = gf_strdup(xmlnamespace);
1196 20 : if (xml_schema_loc) stpp->xml_schema_loc = gf_strdup(xml_schema_loc); //optional
1197 20 : if (mimes) stpp->mime_type = gf_strdup(mimes); //optional
1198 : return e;
1199 : }
1200 :
1201 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
1202 :
1203 :
1204 : /* SimpleTextSampleEntry: also used for MetadataTextSampleEntry and SubtitleTextSampleEntry */
1205 : GF_EXPORT
1206 36 : GF_Err gf_isom_stxt_get_description(GF_ISOFile *the_file, u32 trackNumber, u32 StreamDescriptionIndex,
1207 : const char **mime, const char **encoding, const char **config)
1208 : {
1209 : GF_TrackBox *trak;
1210 : GF_MetaDataSampleEntryBox *entry;
1211 36 : if (mime) *mime = NULL;
1212 36 : if (config) *config = NULL;
1213 36 : if (encoding) *encoding = NULL;
1214 36 : trak = gf_isom_get_track_from_file(the_file, trackNumber);
1215 36 : if (!trak || !StreamDescriptionIndex) return GF_BAD_PARAM;
1216 :
1217 36 : entry = (GF_MetaDataSampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->child_boxes, StreamDescriptionIndex-1);
1218 72 : if (!entry ||
1219 36 : ((entry->type!=GF_ISOM_BOX_TYPE_STXT) &&
1220 8 : (entry->type!=GF_ISOM_BOX_TYPE_METT) &&
1221 : (entry->type!=GF_ISOM_BOX_TYPE_SBTT))) {
1222 : return GF_BAD_PARAM;
1223 : }
1224 :
1225 36 : if (entry->config) {
1226 8 : if (config) *config = entry->config->config;
1227 : }
1228 36 : if (entry->mime_type) {
1229 36 : if (mime) *mime = entry->mime_type;
1230 : }
1231 36 : if (entry->content_encoding) {
1232 16 : if (encoding) *encoding = entry->content_encoding;
1233 : }
1234 : return GF_OK;
1235 : }
1236 :
1237 : #ifndef GPAC_DISABLE_ISOM_WRITE
1238 25 : GF_Err gf_isom_new_stxt_description(GF_ISOFile *movie, u32 trackNumber, u32 type,
1239 : const char *mime, const char *encoding, const char * config,
1240 : u32 *outDescriptionIndex)
1241 : {
1242 : GF_TrackBox *trak;
1243 : GF_Err e;
1244 : u32 dataRefIndex;
1245 : GF_MetaDataSampleEntryBox *sample_entry;
1246 : char *URLname = NULL;
1247 : char *URNname = NULL;
1248 :
1249 25 : e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE);
1250 25 : if (e) return e;
1251 :
1252 25 : trak = gf_isom_get_track_from_file(movie, trackNumber);
1253 25 : if (!trak || !trak->Media) return GF_BAD_PARAM;
1254 :
1255 25 : switch (trak->Media->handler->handlerType) {
1256 : case GF_ISOM_MEDIA_MPEG_SUBT:
1257 : case GF_ISOM_MEDIA_META:
1258 : case GF_ISOM_MEDIA_SCENE:
1259 : case GF_ISOM_MEDIA_TEXT:
1260 : case GF_ISOM_MEDIA_SUBT:
1261 : break;
1262 : default:
1263 : return GF_BAD_PARAM;
1264 : }
1265 25 : switch (type) {
1266 : case GF_ISOM_SUBTYPE_SBTT:
1267 : case GF_ISOM_SUBTYPE_STXT:
1268 : case GF_ISOM_SUBTYPE_METT:
1269 : break;
1270 0 : default:
1271 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("SampleEntry shall be either Metadata, Subtitle or SimpleText. Abort.\n"));
1272 : return GF_BAD_PARAM;
1273 : }
1274 :
1275 25 : if (!mime) {
1276 4 : GF_LOG(GF_LOG_WARNING, GF_LOG_PARSER, ("Text (Metadata, Subtitle or SimpleText) SampleEntry: mime is mandatory. Using text/plain.\n"));
1277 : mime = "text/plain";
1278 : }
1279 :
1280 : //get or create the data ref
1281 25 : e = Media_FindDataRef(trak->Media->information->dataInformation->dref, URLname, URNname, &dataRefIndex);
1282 25 : if (e) return e;
1283 25 : if (!dataRefIndex) {
1284 25 : e = Media_CreateDataRef(movie, trak->Media->information->dataInformation->dref, URLname, URNname, &dataRefIndex);
1285 25 : if (e) return e;
1286 : }
1287 25 : if (!movie->keep_utc)
1288 25 : trak->Media->mediaHeader->modificationTime = gf_isom_get_mp4time();
1289 :
1290 25 : sample_entry = (GF_MetaDataSampleEntryBox *) gf_isom_box_new(type);
1291 25 : if (!sample_entry) return GF_OUT_OF_MEM;
1292 25 : sample_entry->dataReferenceIndex = dataRefIndex;
1293 25 : gf_list_add(trak->Media->information->sampleTable->SampleDescription->child_boxes, sample_entry);
1294 25 : if (outDescriptionIndex) *outDescriptionIndex = gf_list_count(trak->Media->information->sampleTable->SampleDescription->child_boxes);
1295 :
1296 25 : sample_entry->mime_type = gf_strdup(mime);
1297 25 : if (encoding) sample_entry->content_encoding = gf_strdup(encoding);
1298 25 : if (config) {
1299 10 : sample_entry->config = (GF_TextConfigBox*) gf_isom_box_new_parent(&sample_entry->child_boxes, GF_ISOM_BOX_TYPE_TXTC);
1300 10 : if (!sample_entry->config) return GF_OUT_OF_MEM;
1301 10 : sample_entry->config->config = gf_strdup(config);
1302 10 : if (!sample_entry->config->config) return GF_OUT_OF_MEM;
1303 : }
1304 : return e;
1305 : }
1306 :
1307 : #if 0 //unused
1308 :
1309 : /*! updates simple streaming text config
1310 : \param isom_file the target ISO file
1311 : \param trackNumber the target track
1312 : \param encoding the text encoding, if any
1313 : \param config the configuration string, if any
1314 : \param sampleDescriptionIndex the target sample description index
1315 : \return error if any
1316 : */
1317 : GF_Err gf_isom_update_stxt_description(GF_ISOFile *movie, u32 trackNumber,
1318 : const char *encoding, const char *config,
1319 : u32 DescriptionIndex)
1320 : {
1321 : GF_TrackBox *trak;
1322 : GF_Err e;
1323 : GF_MetaDataSampleEntryBox *sample_entry;
1324 :
1325 : e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE);
1326 : if (e) return e;
1327 :
1328 : trak = gf_isom_get_track_from_file(movie, trackNumber);
1329 : if (!trak || !trak->Media || !DescriptionIndex) return GF_BAD_PARAM;
1330 :
1331 : sample_entry = (GF_MetaDataSampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->child_boxes, DescriptionIndex-1);
1332 : if (!sample_entry) return GF_BAD_PARAM;
1333 : if (sample_entry->type != GF_ISOM_BOX_TYPE_METT &&
1334 : sample_entry->type != GF_ISOM_BOX_TYPE_SBTT &&
1335 : sample_entry->type != GF_ISOM_BOX_TYPE_STXT) {
1336 : return GF_BAD_PARAM;
1337 : }
1338 :
1339 : if (!sample_entry->config) {
1340 : sample_entry->config = (GF_TextConfigBox*) gf_isom_box_new_parent(&sample_entry->child_boxes, GF_ISOM_BOX_TYPE_TXTC);
1341 : if (!sample_entry->config) return GF_OUT_OF_MEM;
1342 : }
1343 : if (!movie->keep_utc)
1344 : trak->Media->mediaHeader->modificationTime = gf_isom_get_mp4time();
1345 :
1346 : if (sample_entry->config->config) {
1347 : gf_free(sample_entry->config->config);
1348 : }
1349 : sample_entry->config->config = gf_strdup(config);
1350 :
1351 : if (sample_entry->content_encoding) {
1352 : gf_free(sample_entry->content_encoding);
1353 : }
1354 : if (encoding) {
1355 : sample_entry->content_encoding = gf_strdup(encoding);
1356 : }
1357 : return GF_OK;
1358 : }
1359 : #endif
1360 :
1361 :
1362 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
1363 :
1364 : #ifndef GPAC_DISABLE_VTT
1365 :
1366 6 : GF_WebVTTSampleEntryBox *gf_webvtt_isom_get_description(GF_ISOFile *movie, u32 trackNumber, u32 descriptionIndex)
1367 : {
1368 : GF_WebVTTSampleEntryBox *wvtt;
1369 : GF_TrackBox *trak;
1370 :
1371 6 : if (!descriptionIndex) return NULL;
1372 :
1373 6 : trak = gf_isom_get_track_from_file(movie, trackNumber);
1374 6 : if (!trak || !trak->Media) return NULL;
1375 :
1376 6 : switch (trak->Media->handler->handlerType) {
1377 : case GF_ISOM_MEDIA_TEXT:
1378 : break;
1379 : default:
1380 : return NULL;
1381 : }
1382 :
1383 6 : wvtt = (GF_WebVTTSampleEntryBox*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->child_boxes, descriptionIndex - 1);
1384 6 : if (!wvtt) return NULL;
1385 6 : switch (wvtt->type) {
1386 : case GF_ISOM_BOX_TYPE_WVTT:
1387 : break;
1388 : default:
1389 : return NULL;
1390 : }
1391 6 : return wvtt;
1392 : }
1393 :
1394 : GF_EXPORT
1395 4 : const char *gf_isom_get_webvtt_config(GF_ISOFile *file, u32 track, u32 index)
1396 : {
1397 4 : GF_WebVTTSampleEntryBox *wvtt = gf_webvtt_isom_get_description(file, track, index);
1398 4 : if (!wvtt) return NULL;
1399 4 : return wvtt->config ? wvtt->config->string : NULL;
1400 : }
1401 :
1402 : #endif /*GPAC_DISABLE_VTT*/
1403 :
1404 : #ifndef GPAC_DISABLE_ISOM_WRITE
1405 :
1406 : #ifndef GPAC_DISABLE_VTT
1407 :
1408 : #if 0 //unused
1409 : /*! updates a WebVTT sample description
1410 : \param isom_file the target ISO file
1411 : \param trackNumber the target track
1412 : \param sampleDescriptionIndex the target sample description index to update
1413 : \param config the WebVTT configuration string
1414 : \return error if any
1415 : */
1416 : GF_Err gf_isom_update_webvtt_description(GF_ISOFile *movie, u32 trackNumber, u32 descriptionIndex, const char *config)
1417 : {
1418 : GF_Err e;
1419 : GF_WebVTTSampleEntryBox *wvtt;
1420 : GF_TrackBox *trak;
1421 :
1422 : e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE);
1423 : if (e) return GF_BAD_PARAM;
1424 :
1425 : trak = gf_isom_get_track_from_file(movie, trackNumber);
1426 : if (!trak || !trak->Media) return GF_BAD_PARAM;
1427 :
1428 : switch (trak->Media->handler->handlerType) {
1429 : case GF_ISOM_MEDIA_TEXT:
1430 : case GF_ISOM_MEDIA_SUBT:
1431 : case GF_ISOM_MEDIA_MPEG_SUBT:
1432 : break;
1433 : default:
1434 : return GF_BAD_PARAM;
1435 : }
1436 :
1437 : wvtt = (GF_WebVTTSampleEntryBox*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->child_boxes, descriptionIndex - 1);
1438 : if (!wvtt) return GF_BAD_PARAM;
1439 : switch (wvtt->type) {
1440 : case GF_ISOM_BOX_TYPE_WVTT:
1441 : break;
1442 : default:
1443 : return GF_BAD_PARAM;
1444 : }
1445 : if (!movie->keep_utc)
1446 : trak->Media->mediaHeader->modificationTime = gf_isom_get_mp4time();
1447 :
1448 : if (wvtt->config) gf_isom_box_del_parent(&wvtt->child_boxes, (GF_Box *)wvtt->config);
1449 : wvtt->config = (GF_StringBox *)boxstring_new_with_data(GF_ISOM_BOX_TYPE_VTTC_CONFIG, config, &wvtt->child_boxes);
1450 : return GF_OK;
1451 : }
1452 : #endif
1453 :
1454 :
1455 42 : GF_Err gf_isom_new_webvtt_description(GF_ISOFile *movie, u32 trackNumber, const char *URLname, const char *URNname, u32 *outDescriptionIndex, const char *config)
1456 : {
1457 : GF_TrackBox *trak;
1458 : GF_Err e;
1459 : u32 dataRefIndex;
1460 : GF_WebVTTSampleEntryBox *wvtt;
1461 :
1462 42 : e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE);
1463 42 : if (e) return e;
1464 :
1465 42 : trak = gf_isom_get_track_from_file(movie, trackNumber);
1466 42 : if (!trak || !trak->Media) return GF_BAD_PARAM;
1467 :
1468 42 : switch (trak->Media->handler->handlerType) {
1469 : case GF_ISOM_MEDIA_TEXT:
1470 : case GF_ISOM_MEDIA_SUBT:
1471 : case GF_ISOM_MEDIA_MPEG_SUBT:
1472 : break;
1473 : default:
1474 : return GF_BAD_PARAM;
1475 : }
1476 :
1477 : //get or create the data ref
1478 42 : e = Media_FindDataRef(trak->Media->information->dataInformation->dref, (char *)URLname, (char *)URNname, &dataRefIndex);
1479 42 : if (e) return e;
1480 42 : if (!dataRefIndex) {
1481 42 : e = Media_CreateDataRef(movie, trak->Media->information->dataInformation->dref, (char *)URLname, (char *)URNname, &dataRefIndex);
1482 42 : if (e) return e;
1483 : }
1484 42 : if (!movie->keep_utc)
1485 42 : trak->Media->mediaHeader->modificationTime = gf_isom_get_mp4time();
1486 :
1487 42 : wvtt = (GF_WebVTTSampleEntryBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_WVTT);
1488 42 : if (!wvtt) return GF_OUT_OF_MEM;
1489 42 : wvtt->dataReferenceIndex = dataRefIndex;
1490 42 : gf_list_add(trak->Media->information->sampleTable->SampleDescription->child_boxes, wvtt);
1491 42 : if (outDescriptionIndex) *outDescriptionIndex = gf_list_count(trak->Media->information->sampleTable->SampleDescription->child_boxes);
1492 :
1493 42 : if (config) {
1494 42 : wvtt->config = (GF_StringBox *)boxstring_new_with_data(GF_ISOM_BOX_TYPE_VTTC_CONFIG, config, &wvtt->child_boxes);
1495 : }
1496 : return e;
1497 : }
1498 :
1499 : #endif /*GPAC_DISABLE_VTT*/
1500 :
1501 5405 : GF_BitRateBox *gf_isom_sample_entry_get_bitrate(GF_SampleEntryBox *ent, Bool create)
1502 : {
1503 5405 : u32 i=0;
1504 : GF_BitRateBox *a;
1505 17563 : while ((a = (GF_BitRateBox *)gf_list_enum(ent->child_boxes, &i))) {
1506 9895 : if (a->type==GF_ISOM_BOX_TYPE_BTRT) return a;
1507 : }
1508 2263 : if (!create) return NULL;
1509 822 : a = (GF_BitRateBox *) gf_isom_box_new_parent(&ent->child_boxes, GF_ISOM_BOX_TYPE_BTRT);
1510 822 : return a;
1511 : }
1512 :
1513 : GF_EXPORT
1514 1624 : GF_Err gf_isom_update_bitrate(GF_ISOFile *movie, u32 trackNumber, u32 sampleDescriptionIndex, u32 average_bitrate, u32 max_bitrate, u32 decode_buffer_size)
1515 : {
1516 : GF_BitRateBox *a;
1517 : GF_Err e;
1518 : GF_SampleEntryBox *ent;
1519 : u32 i, count;
1520 : GF_TrackBox *trak;
1521 :
1522 1624 : e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE);
1523 1624 : if (e) return GF_BAD_PARAM;
1524 :
1525 1624 : trak = gf_isom_get_track_from_file(movie, trackNumber);
1526 :
1527 1624 : if (!trak || !trak->Media) return GF_BAD_PARAM;
1528 :
1529 1624 : count = gf_list_count(trak->Media->information->sampleTable->SampleDescription->child_boxes);
1530 3255 : for (i=0; i<count; i++) {
1531 : u32 ent_type;
1532 : GF_ProtectionSchemeInfoBox *sinf;
1533 : GF_ESDBox *esds=NULL;
1534 1631 : if (sampleDescriptionIndex && (sampleDescriptionIndex!=i+1)) continue;
1535 :
1536 1623 : ent = (GF_SampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->child_boxes, i);
1537 1623 : if (!ent) return GF_BAD_PARAM;
1538 :
1539 1623 : ent_type = ent->type;
1540 : switch (ent_type) {
1541 105 : case GF_ISOM_BOX_TYPE_ENCV:
1542 : case GF_ISOM_BOX_TYPE_ENCA:
1543 : case GF_ISOM_BOX_TYPE_ENCS:
1544 105 : sinf = (GF_ProtectionSchemeInfoBox *) gf_isom_box_find_child(ent->child_boxes, GF_ISOM_BOX_TYPE_SINF);
1545 105 : if (sinf && sinf->original_format)
1546 105 : ent_type = sinf->original_format->data_format;
1547 : break;
1548 : }
1549 1623 : switch (ent_type) {
1550 173 : case GF_ISOM_BOX_TYPE_MP4V:
1551 173 : esds = ((GF_MPEGVisualSampleEntryBox *)ent)->esd;
1552 173 : break;
1553 253 : case GF_ISOM_BOX_TYPE_MP4A:
1554 253 : esds = ((GF_MPEGAudioSampleEntryBox *)ent)->esd;
1555 253 : break;
1556 2 : case GF_ISOM_BOX_TYPE_MP4S:
1557 2 : esds = ((GF_MPEGSampleEntryBox *) ent)->esd;
1558 2 : break;
1559 : }
1560 : //using mpeg4 esd
1561 428 : if (esds) {
1562 428 : if (esds->desc && esds->desc->decoderConfig) {
1563 428 : esds->desc->decoderConfig->avgBitrate = average_bitrate;
1564 428 : esds->desc->decoderConfig->maxBitrate = max_bitrate;
1565 428 : if (decode_buffer_size)
1566 416 : esds->desc->decoderConfig->bufferSizeDB = decode_buffer_size;
1567 : }
1568 428 : continue;
1569 : }
1570 :
1571 : //using BTRT
1572 1195 : if (!max_bitrate && average_bitrate) max_bitrate = average_bitrate;
1573 1195 : a = gf_isom_sample_entry_get_bitrate(ent, max_bitrate ? GF_TRUE : GF_FALSE);
1574 :
1575 1195 : if (!max_bitrate) {
1576 132 : if (a) {
1577 10 : gf_isom_box_del_parent(&ent->child_boxes, (GF_Box *) a);
1578 : }
1579 : } else {
1580 1063 : a->avgBitrate = average_bitrate;
1581 1063 : a->maxBitrate = max_bitrate;
1582 1063 : if (decode_buffer_size)
1583 1023 : a->bufferSizeDB = decode_buffer_size;
1584 : }
1585 : }
1586 : return GF_OK;
1587 : }
1588 :
1589 :
1590 : GF_EXPORT
1591 3 : GF_Err gf_isom_tmcd_config_new(GF_ISOFile *the_file, u32 trackNumber, u32 fps_num, u32 fps_den, s32 frames_per_counter_tick, Bool is_drop, Bool is_counter, u32 *outDescriptionIndex)
1592 : {
1593 : GF_TrackBox *trak;
1594 : GF_Err e;
1595 : u32 dataRefIndex;
1596 : GF_Box *tmcd;
1597 : GF_GenericMediaHeaderInfoBox *gmin;
1598 : GF_TimeCodeMediaInformationBox *tcmi;
1599 : GF_TimeCodeSampleEntryBox *entry;
1600 :
1601 3 : e = CanAccessMovie(the_file, GF_ISOM_OPEN_WRITE);
1602 3 : if (e) return e;
1603 :
1604 3 : trak = gf_isom_get_track_from_file(the_file, trackNumber);
1605 3 : if (!trak || !trak->Media) return GF_BAD_PARAM;
1606 :
1607 : //get or create the data ref
1608 3 : e = Media_FindDataRef(trak->Media->information->dataInformation->dref, NULL, NULL, &dataRefIndex);
1609 3 : if (e) return e;
1610 3 : if (!dataRefIndex) {
1611 3 : e = Media_CreateDataRef(the_file, trak->Media->information->dataInformation->dref, NULL, NULL, &dataRefIndex);
1612 3 : if (e) return e;
1613 : }
1614 3 : if (!the_file->keep_utc)
1615 3 : trak->Media->mediaHeader->modificationTime = gf_isom_get_mp4time();
1616 :
1617 3 : gmin = (GF_GenericMediaHeaderInfoBox *) gf_isom_box_find_child(trak->Media->information->InfoHeader->child_boxes, GF_QT_BOX_TYPE_GMIN);
1618 3 : if (!gmin) {
1619 3 : gmin = (GF_GenericMediaHeaderInfoBox *) gf_isom_box_new_parent(&trak->Media->information->InfoHeader->child_boxes, GF_QT_BOX_TYPE_GMIN);
1620 3 : if (!gmin) return GF_OUT_OF_MEM;
1621 : }
1622 :
1623 3 : tmcd = gf_isom_box_find_child(trak->Media->information->InfoHeader->child_boxes, GF_QT_BOX_TYPE_TMCD);
1624 3 : if (!tmcd) {
1625 : //default container box, use GMHD to create it
1626 3 : tmcd = gf_isom_box_new_parent(&trak->Media->information->InfoHeader->child_boxes, GF_ISOM_BOX_TYPE_GMHD);
1627 3 : if (!tmcd) return GF_OUT_OF_MEM;
1628 3 : tmcd->type = GF_QT_BOX_TYPE_TMCD;
1629 : }
1630 3 : tcmi = (GF_TimeCodeMediaInformationBox *) gf_isom_box_find_child(tmcd->child_boxes, GF_QT_BOX_TYPE_TCMI);
1631 3 : if (!tcmi) {
1632 3 : tcmi = (GF_TimeCodeMediaInformationBox *) gf_isom_box_new_parent(&tmcd->child_boxes, GF_QT_BOX_TYPE_TCMI);
1633 3 : if (!tcmi) return GF_OUT_OF_MEM;
1634 : }
1635 :
1636 3 : entry = (GF_TimeCodeSampleEntryBox *) gf_isom_box_new_ex(GF_QT_BOX_TYPE_TMCD, GF_ISOM_BOX_TYPE_STSD, GF_FALSE, GF_FALSE);
1637 3 : if (!entry) return GF_OUT_OF_MEM;
1638 3 : entry->flags = 0;
1639 3 : if (is_drop) entry->flags |= 0x00000001;
1640 3 : if (is_counter) entry->flags |= 0x00000008;
1641 :
1642 3 : entry->timescale = fps_num;
1643 3 : entry->frame_duration = fps_den;
1644 3 : entry->frames_per_counter_tick = (u8) frames_per_counter_tick;
1645 :
1646 3 : entry->dataReferenceIndex = dataRefIndex;
1647 3 : e = gf_list_add(trak->Media->information->sampleTable->SampleDescription->child_boxes, entry);
1648 3 : *outDescriptionIndex = gf_list_count(trak->Media->information->sampleTable->SampleDescription->child_boxes);
1649 3 : return e;
1650 : }
1651 :
1652 1 : GF_Err gf_isom_new_mpha_description(GF_ISOFile *movie, u32 trackNumber, const char *URLname, const char *URNname, u32 *outDescriptionIndex, u8 *dsi, u32 dsi_size)
1653 : {
1654 : GF_TrackBox *trak;
1655 : GF_Err e;
1656 : u32 dataRefIndex;
1657 : GF_MPEGAudioSampleEntryBox *mpa;
1658 :
1659 1 : e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE);
1660 1 : if (e) return e;
1661 1 : if (dsi_size<6) return GF_BAD_PARAM;
1662 :
1663 1 : trak = gf_isom_get_track_from_file(movie, trackNumber);
1664 1 : if (!trak || !trak->Media) return GF_BAD_PARAM;
1665 :
1666 1 : switch (trak->Media->handler->handlerType) {
1667 : case GF_ISOM_MEDIA_AUDIO:
1668 : break;
1669 : default:
1670 : return GF_BAD_PARAM;
1671 : }
1672 :
1673 : //get or create the data ref
1674 1 : e = Media_FindDataRef(trak->Media->information->dataInformation->dref, (char *)URLname, (char *)URNname, &dataRefIndex);
1675 1 : if (e) return e;
1676 1 : if (!dataRefIndex) {
1677 1 : e = Media_CreateDataRef(movie, trak->Media->information->dataInformation->dref, (char *)URLname, (char *)URNname, &dataRefIndex);
1678 1 : if (e) return e;
1679 : }
1680 1 : if (!movie->keep_utc)
1681 1 : trak->Media->mediaHeader->modificationTime = gf_isom_get_mp4time();
1682 :
1683 1 : mpa = (GF_MPEGAudioSampleEntryBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_MHA1);
1684 1 : if (!mpa) return GF_OUT_OF_MEM;
1685 1 : mpa->dataReferenceIndex = dataRefIndex;
1686 1 : gf_list_add(trak->Media->information->sampleTable->SampleDescription->child_boxes, mpa);
1687 1 : if (outDescriptionIndex) *outDescriptionIndex = gf_list_count(trak->Media->information->sampleTable->SampleDescription->child_boxes);
1688 :
1689 1 : mpa->cfg_mha = (GF_MHAConfigBox *) gf_isom_box_new_parent(&mpa->child_boxes, GF_ISOM_BOX_TYPE_MHAC);
1690 1 : if (!mpa->cfg_mha) return GF_OUT_OF_MEM;
1691 1 : mpa->cfg_mha->configuration_version = dsi[0];
1692 1 : mpa->cfg_mha->mha_pl_indication = dsi[1];
1693 1 : mpa->cfg_mha->reference_channel_layout = dsi[2];
1694 1 : mpa->cfg_mha->mha_config_size = dsi[3];
1695 1 : mpa->cfg_mha->mha_config_size <<= 8;
1696 1 : mpa->cfg_mha->mha_config_size |= dsi[4];
1697 1 : mpa->cfg_mha->mha_config = gf_malloc(sizeof(u8) * mpa->cfg_mha->mha_config_size);
1698 1 : if (!mpa->cfg_mha->mha_config) return GF_OUT_OF_MEM;
1699 1 : memcpy(mpa->cfg_mha->mha_config, dsi+5, dsi_size-5);
1700 1 : return GF_OK;
1701 : }
1702 :
1703 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
1704 :
1705 : GF_EXPORT
1706 4 : GF_Err gf_isom_get_tmcd_config(GF_ISOFile *movie, u32 trackNumber, u32 descriptionIndex, u32 *tmcd_flags, u32 *tmcd_fps_num, u32 *tmcd_fps_den, u32 *tmcd_fpt)
1707 : {
1708 : GF_TimeCodeSampleEntryBox *tmcd;
1709 : GF_TrackBox *trak;
1710 4 : trak = gf_isom_get_track_from_file(movie, trackNumber);
1711 4 : if (!trak || !descriptionIndex) return GF_BAD_PARAM;
1712 :
1713 4 : tmcd = (GF_TimeCodeSampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->child_boxes, descriptionIndex-1);
1714 4 : if (!tmcd) return GF_BAD_PARAM;
1715 4 : if (tmcd->type != GF_QT_BOX_TYPE_TMCD) return GF_BAD_PARAM;
1716 :
1717 4 : if (tmcd_flags) *tmcd_flags = tmcd->flags;
1718 4 : if (tmcd_fps_num) *tmcd_fps_num = tmcd->timescale;
1719 4 : if (tmcd_fps_den) *tmcd_fps_den = tmcd->frame_duration;
1720 4 : if (tmcd_fpt) *tmcd_fpt = tmcd->frames_per_counter_tick;
1721 : return GF_OK;
1722 : }
1723 :
1724 : GF_EXPORT
1725 5 : GF_Err gf_isom_get_pcm_config(GF_ISOFile *movie, u32 trackNumber, u32 descriptionIndex, u32 *flags, u32 *pcm_size)
1726 : {
1727 : GF_AudioSampleEntryBox *aent;
1728 : GF_PCMConfigBox *pcmC;
1729 : GF_TrackBox *trak;
1730 5 : trak = gf_isom_get_track_from_file(movie, trackNumber);
1731 5 : if (!trak || !descriptionIndex) return GF_BAD_PARAM;
1732 :
1733 5 : aent = (GF_AudioSampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->child_boxes, descriptionIndex-1);
1734 5 : if (!aent) return GF_BAD_PARAM;
1735 5 : if ((aent->type != GF_ISOM_BOX_TYPE_IPCM) && (aent->type != GF_ISOM_BOX_TYPE_FPCM))
1736 : return GF_BAD_PARAM;
1737 :
1738 5 : pcmC = (GF_PCMConfigBox *) gf_isom_box_find_child(aent->child_boxes, GF_ISOM_BOX_TYPE_PCMC);
1739 5 : if (!pcmC) return GF_NON_COMPLIANT_BITSTREAM;
1740 :
1741 5 : if (flags) *flags = pcmC->format_flags;
1742 5 : if (pcm_size) *pcm_size = pcmC->PCM_sample_size;
1743 : return GF_OK;
1744 : }
1745 :
1746 :
1747 :
1748 : #endif /*GPAC_DISABLE_ISOM*/
|