1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2010-2017 L-SMASH project
6 * Authors: Takashi Hirata <silverfilain@gmail.com>
7 * Yusuke Nakamura <muken.the.vfrmaniac@gmail.com>
9 * Permission to use, copy, modify, and/or distribute this software for any
10 * purpose with or without fee is hereby granted, provided that the above
11 * copyright notice and this permission notice appear in all copies.
13 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 *****************************************************************************/
22 /* This file is available under an ISC license. */
24 #include "common/internal.h" /* must be placed first */
32 #include "description.h"
34 #define MP4SYS_INTERNAL
37 /***************************************************************************
39 ***************************************************************************/
41 #define ALWAYS_28BITS_LENGTH_CODING 1 // for some weird (but originator's) devices
43 static const lsmash_class_t lsmash_mp4sys_class
=
48 /* List of Class Tags for Descriptors */
51 MP4SYS_DESCRIPTOR_TAG_Forbidden
= 0x00, /* Forbidden */
52 MP4SYS_DESCRIPTOR_TAG_ObjectDescrTag
= 0x01, /* ObjectDescrTag */
53 MP4SYS_DESCRIPTOR_TAG_InitialObjectDescrTag
= 0x02, /* InitialObjectDescrTag */
54 MP4SYS_DESCRIPTOR_TAG_ES_DescrTag
= 0x03, /* ES_DescrTag */
55 MP4SYS_DESCRIPTOR_TAG_DecoderConfigDescrTag
= 0x04, /* DecoderConfigDescrTag */
56 MP4SYS_DESCRIPTOR_TAG_DecSpecificInfoTag
= 0x05, /* DecSpecificInfoTag */
57 MP4SYS_DESCRIPTOR_TAG_SLConfigDescrTag
= 0x06, /* SLConfigDescrTag */
58 MP4SYS_DESCRIPTOR_TAG_ContentIdentDescrTag
= 0x07, /* ContentIdentDescrTag */
59 MP4SYS_DESCRIPTOR_TAG_SupplContentIdentDescrTag
= 0x08, /* SupplContentIdentDescrTag */
60 MP4SYS_DESCRIPTOR_TAG_IPI_DescrPointerTag
= 0x09, /* IPI_DescrPointerTag */
61 MP4SYS_DESCRIPTOR_TAG_IPMP_DescrPointerTag
= 0x0A, /* IPMP_DescrPointerTag */
62 MP4SYS_DESCRIPTOR_TAG_IPMP_DescrTag
= 0x0B, /* IPMP_DescrTag */
63 MP4SYS_DESCRIPTOR_TAG_QoS_DescrTag
= 0x0C, /* QoS_DescrTag */
64 MP4SYS_DESCRIPTOR_TAG_RegistrationDescrTag
= 0x0D, /* RegistrationDescrTag */
65 MP4SYS_DESCRIPTOR_TAG_ES_ID_IncTag
= 0x0E, /* ES_ID_IncTag */
66 MP4SYS_DESCRIPTOR_TAG_ES_ID_RefTag
= 0x0F, /* ES_ID_RefTag */
67 MP4SYS_DESCRIPTOR_TAG_MP4_IOD_Tag
= 0x10, /* MP4_IOD_Tag, InitialObjectDescriptor for MP4 */
68 MP4SYS_DESCRIPTOR_TAG_MP4_OD_Tag
= 0x11, /* MP4_OD_Tag, ObjectDescriptor for MP4 */
69 MP4SYS_DESCRIPTOR_TAG_IPI_DescrPointerRefTag
= 0x12, /* IPI_DescrPointerRefTag */
70 MP4SYS_DESCRIPTOR_TAG_ExtendedProfileLevelDescrTag
= 0x13, /* ExtendedProfileLevelDescrTag */
71 MP4SYS_DESCRIPTOR_TAG_profileLevelIndicationIndexDescrTag
= 0x14, /* profileLevelIndicationIndexDescrTag */
72 MP4SYS_DESCRIPTOR_TAG_ContentClassificationDescrTag
= 0x40, /* ContentClassificationDescrTag */
73 MP4SYS_DESCRIPTOR_TAG_KeyWordDescrTag
= 0x41, /* KeyWordDescrTag */
74 MP4SYS_DESCRIPTOR_TAG_RatingDescrTag
= 0x42, /* RatingDescrTag */
75 MP4SYS_DESCRIPTOR_TAG_LanguageDescrTag
= 0x43, /* LanguageDescrTag */
76 MP4SYS_DESCRIPTOR_TAG_ShortTextualDescrTag
= 0x44, /* ShortTextualDescrTag */
77 MP4SYS_DESCRIPTOR_TAG_ExpandedTextualDescrTag
= 0x45, /* ExpandedTextualDescrTag */
78 MP4SYS_DESCRIPTOR_TAG_ContentCreatorNameDescrTag
= 0x46, /* ContentCreatorNameDescrTag */
79 MP4SYS_DESCRIPTOR_TAG_ContentCreationDateDescrTag
= 0x47, /* ContentCreationDateDescrTag */
80 MP4SYS_DESCRIPTOR_TAG_OCICreatorNameDescrTag
= 0x48, /* OCICreatorNameDescrTag */
81 MP4SYS_DESCRIPTOR_TAG_OCICreationDateDescrTag
= 0x49, /* OCICreationDateDescrTag */
82 MP4SYS_DESCRIPTOR_TAG_SmpteCameraPositionDescrTag
= 0x4A, /* SmpteCameraPositionDescrTag */
83 MP4SYS_DESCRIPTOR_TAG_Forbidden1
= 0xFF, /* Forbidden */
84 } mp4sys_descriptor_tag
;
85 // MP4SYS_DESCRIPTOR_TAG_ES_DescrRemoveRefTag = 0x07, /* FIXME: (command tag), see 14496-14 Object Descriptors */
89 uint32_t size
; // 2^28 at most
90 mp4sys_descriptor_tag tag
;
91 } mp4sys_descriptor_head_t
;
93 typedef struct mp4sys_descriptor_tag mp4sys_descriptor_t
;
95 typedef void (*mp4sys_descriptor_destructor_t
)( void * );
96 typedef int (*mp4sys_descriptor_writer_t
)( lsmash_bs_t
*, void * );
98 #define MP4SYS_DESCRIPTOR_COMMON \
99 const lsmash_class_t *class; \
100 mp4sys_descriptor_t *parent; \
101 mp4sys_descriptor_destructor_t destruct; \
102 mp4sys_descriptor_writer_t write; \
103 mp4sys_descriptor_head_t header; \
104 lsmash_entry_list_t children
106 struct mp4sys_descriptor_tag
108 MP4SYS_DESCRIPTOR_COMMON
;
113 MP4SYS_DESCRIPTOR_COMMON
;
114 } mp4sys_BaseDescriptor_t
;
116 /* DecoderSpecificInfo */
117 /* contents varies depends on ObjectTypeIndication and StreamType. */
120 MP4SYS_DESCRIPTOR_COMMON
;
122 } mp4sys_DecoderSpecificInfo_t
;
124 /* DecoderConfigDescriptor */
127 MP4SYS_DESCRIPTOR_COMMON
;
128 lsmash_mp4sys_object_type_indication objectTypeIndication
;
129 lsmash_mp4sys_stream_type streamType
;
130 uint8_t upStream
; /* bit(1), always 0 in this muxer, used for interactive contents. */
131 uint8_t reserved
; /* const bit(1), always 1. */
132 uint32_t bufferSizeDB
; /* maybe CPB size in bytes, NOT bits. */
134 uint32_t avgBitrate
; /* 0 if VBR */
135 mp4sys_DecoderSpecificInfo_t
*decSpecificInfo
; /* can be NULL. */
136 /* 14496-1 seems to say if we are in IOD(InitialObjectDescriptor), we might use this.
137 * See ExtensionProfileLevelDescr, The Initial Object Descriptor.
138 * But I don't think this is mandatory despite 14496-1, because 14496-14 says, in OD or IOD,
139 * we have to use ES_ID_Inc instead of ES_Descriptor, which does not have DecoderConfigDescriptor. */
140 // profileLevelIndicationIndexDescriptor profileLevelIndicationIndexDescr [0..255];
141 } mp4sys_DecoderConfigDescriptor_t
;
143 /* SLConfigDescriptor */
146 MP4SYS_DESCRIPTOR_COMMON
;
147 uint8_t predefined
; /* default the values from a set of predefined parameter sets as detailed below.
149 * 0x01 : null SL packet header
150 * 0x02 : Reserved for use in MP4 files
151 * 0x03 - 0xFF : Reserved for ISO use
152 * MP4 file that does not use URL_Flag shall have constant value 0x02. */
154 * The following fields are placed if predefined == 0x00. */
155 unsigned useAccessUnitStartFlag
: 1;
156 unsigned useAccessUnitEndFlag
: 1;
157 unsigned useRandomAccessPointFlag
: 1;
158 unsigned hasRandomAccessUnitsOnlyFlag
: 1;
159 unsigned usePaddingFlag
: 1;
160 unsigned useTimeStampsFlag
: 1;
161 unsigned useIdleFlag
: 1;
162 unsigned durationFlag
: 1;
163 uint32_t timeStampResolution
;
164 uint32_t OCRResolution
;
165 uint8_t timeStampLength
;
168 uint8_t instantBitrateLength
;
169 unsigned degradationPriorityLength
: 4;
170 unsigned AU_seqNumLength
: 5;
171 unsigned packetSeqNumLength
: 5;
172 unsigned reserved
: 2;
173 /* The following fields are placed if durationFlag is true. */
175 uint16_t accessUnitDuration
;
176 uint16_t compositionUnitDuration
;
177 /* The following fields are placed if useTimeStampsFlag is false. */
178 uint64_t startDecodingTimeStamp
;
179 uint64_t startCompositionTimeStamp
;
180 } mp4sys_SLConfigDescriptor_t
;
183 typedef struct mp4sys_ES_Descriptor_t
185 MP4SYS_DESCRIPTOR_COMMON
;
187 unsigned streamDependenceFlag
: 1; /* no stream depencies between streams in this muxer, ES_ID of another elementary stream */
188 unsigned URL_Flag
: 1; /* no external URL referencing stream in MP4 */
189 unsigned OCRstreamFlag
: 1; /* no Object Clock Reference stream in this muxer (shall be false in MP4, useful if we're importing from MPEG-2?) */
190 unsigned streamPriority
: 5; /* no priority among streams in this muxer, higher is important */
191 uint16_t dependsOn_ES_ID
;
195 mp4sys_DecoderConfigDescriptor_t
*decConfigDescr
; /* cannot be NULL. */
196 mp4sys_SLConfigDescriptor_t
*slConfigDescr
;
197 /* descriptors below are not mandatory, I think Language Descriptor may somewhat useful */
199 IPI_DescrPointer ipiPtr[0 .. 1]; // used to indicate using other ES's IP_IdentificationDataSet
200 IP_IdentificationDataSet ipIDS[0 .. 255]; // abstract class, actually ContentIdentificationDescriptor(for commercial contents management),
201 // or SupplementaryContentIdentificationDescriptor(for embedding titles)
202 IPMP_DescriptorPointer ipmpDescrPtr[0 .. 255]; // used to intellectual property / protection management
203 LanguageDescriptor langDescr[0 .. 255]; // used to identify the language of the audio/speech or text object
204 QoS_Descriptor qosDescr[0 .. 1]; // used to achieve QoS
205 RegistrationDescriptor regDescr[0 .. 1]; // used to carry elementary streams with data whose format is not recognized by ISO/IEC 14496-1
206 ExtensionDescriptor extDescr[0 .. 255]; // abstract class, actually defined no subclass, maybe useless
208 } mp4sys_ES_Descriptor_t
;
210 /* 14496-14 Object Descriptors (ES_ID_Inc) */
213 MP4SYS_DESCRIPTOR_COMMON
;
215 } mp4sys_ES_ID_Inc_t
;
217 /* 14496-1 ObjectDescriptor / InitialObjectDescriptor */
220 MP4SYS_DESCRIPTOR_COMMON
;
221 unsigned ObjectDescriptorID
: 10;
222 unsigned URL_Flag
: 1;
223 unsigned includeInlineProfileLevelFlag
: 1; /* for OD, reserved and set to 1 */
224 unsigned reserved
: 4; /* 0b1111 */
228 mp4sys_ODProfileLevelIndication ODProfileLevelIndication
;
229 mp4sys_sceneProfileLevelIndication sceneProfileLevelIndication
;
230 mp4a_audioProfileLevelIndication audioProfileLevelIndication
;
231 mp4sys_visualProfileLevelIndication visualProfileLevelIndication
;
232 mp4sys_graphicsProfileLevelIndication graphicsProfileLevelIndication
;
234 lsmash_entry_list_t esDescr
; /* List of ES_ID_Inc, not ES_Descriptor defined in 14496-1. 14496-14 overrides. */
235 // OCI_Descriptor ociDescr[0 .. 255];
236 // IPMP_DescriptorPointer ipmpDescrPtr[0 .. 255];
237 // ExtensionDescriptor extDescr[0 .. 255];
238 } mp4sys_ObjectDescriptor_t
;
240 static void mp4sys_remove_predefined_descriptor( void *opaque_descriptor
, size_t offset_of_descriptor
)
242 assert( opaque_descriptor
);
243 mp4sys_descriptor_t
*descriptor
= (mp4sys_descriptor_t
*)opaque_descriptor
;
244 if( descriptor
->parent
)
246 mp4sys_descriptor_t
**p
= (mp4sys_descriptor_t
**)(((int8_t *)descriptor
->parent
) + offset_of_descriptor
);
247 if( *p
== descriptor
)
252 /* We always free descriptors through the children list of the parent descriptor.
253 * Therefore, don't free descriptors through any list other than the children list. */
254 static void mp4sys_remove_descriptor_in_predefined_list( void *opaque_descriptor
, size_t offset_of_list
)
256 assert( opaque_descriptor
);
257 mp4sys_descriptor_t
*descriptor
= (mp4sys_descriptor_t
*)opaque_descriptor
;
258 if( descriptor
->parent
)
260 lsmash_entry_list_t
*list
= (lsmash_entry_list_t
*)(((int8_t *)descriptor
->parent
) + offset_of_list
);
261 for( lsmash_entry_t
*entry
= list
->head
; entry
; entry
= entry
->next
)
262 if( descriptor
== entry
->data
)
264 /* We don't free this descriptor here.
265 * Because of freeing an entry of the list here, don't pass the list to free this descriptor.
268 lsmash_remove_entry_direct( list
, entry
, NULL
);
274 static void mp4sys_remove_all_child_descriptors( lsmash_entry_list_t
*children
);
276 /* Free a descriptor and its children. */
277 static void mp4sys_destruct_descriptor( mp4sys_descriptor_t
*descriptor
)
281 if( descriptor
->destruct
)
282 descriptor
->destruct( descriptor
);
283 mp4sys_remove_all_child_descriptors( &descriptor
->children
);
284 lsmash_free( descriptor
);
287 static void mp4sys_remove_all_child_descriptors( lsmash_entry_list_t
*children
)
289 lsmash_remove_entries( children
, mp4sys_destruct_descriptor
);
292 /* Remove a descriptor by the pointer containing its address.
293 * In addition, remove from the children list of the parent descriptor if possible.
294 * Don't call this function within a function freeing one or more entries of any children list because of double free.
295 * Basically, don't use this function as a callback function. */
296 void mp4sys_remove_descriptor( void *opaque_descriptor
)
298 if( !opaque_descriptor
)
300 mp4sys_descriptor_t
*descriptor
= (mp4sys_descriptor_t
*)opaque_descriptor
;
301 if( descriptor
->parent
)
303 mp4sys_descriptor_t
*parent
= descriptor
->parent
;
304 for( lsmash_entry_t
*entry
= parent
->children
.head
; entry
; entry
= entry
->next
)
305 if( descriptor
== entry
->data
)
307 /* Free the corresponding entry here, therefore don't call this function as a callback function
308 * if a function frees the same entry later and calls this function. */
309 lsmash_remove_entry_direct( &parent
->children
, entry
, mp4sys_destruct_descriptor
);
313 mp4sys_destruct_descriptor( descriptor
);
316 static void mp4sys_remove_DecoderSpecificInfo( mp4sys_DecoderSpecificInfo_t
*dsi
)
320 lsmash_free( dsi
->data
);
321 mp4sys_remove_predefined_descriptor( dsi
, offsetof( mp4sys_DecoderConfigDescriptor_t
, decSpecificInfo
) );
324 static void mp4sys_remove_DecoderConfigDescriptor( mp4sys_DecoderConfigDescriptor_t
*dcd
)
328 mp4sys_remove_predefined_descriptor( dcd
, offsetof( mp4sys_ES_Descriptor_t
, decConfigDescr
) );
331 static void mp4sys_remove_SLConfigDescriptor( mp4sys_SLConfigDescriptor_t
*slcd
)
335 mp4sys_remove_predefined_descriptor( slcd
, offsetof( mp4sys_ES_Descriptor_t
, slConfigDescr
) );
338 static void mp4sys_remove_ES_Descriptor( mp4sys_ES_Descriptor_t
*esd
)
340 if( !esd
|| (esd
->parent
&& (esd
->parent
->header
.tag
== MP4SYS_DESCRIPTOR_TAG_ObjectDescrTag
341 || esd
->parent
->header
.tag
== MP4SYS_DESCRIPTOR_TAG_InitialObjectDescrTag
)) )
343 mp4sys_remove_descriptor_in_predefined_list( esd
, offsetof( mp4sys_ObjectDescriptor_t
, esDescr
) );
346 static void mp4sys_remove_ES_ID_Inc( mp4sys_ES_ID_Inc_t
*es_id_inc
)
350 mp4sys_remove_descriptor_in_predefined_list( es_id_inc
, offsetof( mp4sys_ObjectDescriptor_t
, esDescr
) );
353 static void mp4sys_remove_ObjectDescriptor( mp4sys_ObjectDescriptor_t
*od
)
357 static inline uint32_t mp4sys_get_descriptor_header_size( uint32_t payload_size_in_byte
)
359 #if ALWAYS_28BITS_LENGTH_CODING
360 return 4 + 1; /* +4 means 28bits length coding, +1 means tag's space */
362 /* descriptor length will be split into 7bits
363 * see 14496-1 Expandable classes and Length encoding of descriptors and commands */
365 for( i
= 1; payload_size_in_byte
>> ( 7 * i
); i
++ );
366 return i
+ 1; /* +1 means tag's space */
370 /* returns total size of descriptor, including header, 2 at least */
371 static inline uint32_t mp4sys_get_descriptor_size( uint32_t payload_size_in_byte
)
373 return payload_size_in_byte
+ mp4sys_get_descriptor_header_size( payload_size_in_byte
);
376 static inline void mp4sys_write_descriptor_header( lsmash_bs_t
*bs
, mp4sys_descriptor_head_t
*header
)
378 lsmash_bs_put_byte( bs
, header
->tag
);
379 /* Descriptor length will be splitted into 7bits.
380 * See 14496-1 Expandable classes and Length encoding of descriptors and commands */
381 #if ALWAYS_28BITS_LENGTH_CODING
382 lsmash_bs_put_byte( bs
, ( header
->size
>> 21 ) | 0x80 );
383 lsmash_bs_put_byte( bs
, ( header
->size
>> 14 ) | 0x80 );
384 lsmash_bs_put_byte( bs
, ( header
->size
>> 7 ) | 0x80 );
386 for( uint32_t i
= mp4sys_get_descriptor_size( header
->size
) - header
->size
- 2; i
; i
-- ){
387 lsmash_bs_put_byte( bs
, ( header
->size
>> ( 7 * i
) ) | 0x80 );
390 lsmash_bs_put_byte( bs
, header
->size
& 0x7F );
393 int mp4sys_write_descriptor( lsmash_bs_t
*bs
, void *opaque_descriptor
);
395 static int mp4sys_write_DecoderSpecificInfo( lsmash_bs_t
*bs
, mp4sys_DecoderSpecificInfo_t
*dsi
)
397 if( dsi
->data
&& dsi
->header
.size
!= 0 )
398 lsmash_bs_put_bytes( bs
, dsi
->header
.size
, dsi
->data
);
402 static int mp4sys_write_DecoderConfigDescriptor( lsmash_bs_t
*bs
, mp4sys_DecoderConfigDescriptor_t
*dcd
)
404 lsmash_bs_put_byte( bs
, dcd
->objectTypeIndication
);
406 temp
= (dcd
->streamType
& 0x3F) << 2;
407 temp
|= (dcd
->upStream
& 0x01) << 1;
408 temp
|= dcd
->reserved
& 0x01;
409 lsmash_bs_put_byte( bs
, temp
);
410 lsmash_bs_put_be24( bs
, dcd
->bufferSizeDB
);
411 lsmash_bs_put_be32( bs
, dcd
->maxBitrate
);
412 lsmash_bs_put_be32( bs
, dcd
->avgBitrate
);
413 /* Here, profileLevelIndicationIndexDescriptor is omitted. */
417 static int mp4sys_write_SLConfigDescriptor( lsmash_bs_t
*bs
, mp4sys_SLConfigDescriptor_t
*slcd
)
419 lsmash_bs_put_byte( bs
, slcd
->predefined
);
420 if( slcd
->predefined
== 0x00 )
423 temp8
= slcd
->useAccessUnitStartFlag
<< 7;
424 temp8
|= slcd
->useAccessUnitEndFlag
<< 6;
425 temp8
|= slcd
->useRandomAccessPointFlag
<< 5;
426 temp8
|= slcd
->hasRandomAccessUnitsOnlyFlag
<< 4;
427 temp8
|= slcd
->usePaddingFlag
<< 3;
428 temp8
|= slcd
->useTimeStampsFlag
<< 2;
429 temp8
|= slcd
->useIdleFlag
<< 1;
430 temp8
|= slcd
->durationFlag
;
431 lsmash_bs_put_byte( bs
, temp8
);
432 lsmash_bs_put_be32( bs
, slcd
->timeStampResolution
);
433 lsmash_bs_put_be32( bs
, slcd
->OCRResolution
);
434 lsmash_bs_put_byte( bs
, slcd
->timeStampLength
);
435 lsmash_bs_put_byte( bs
, slcd
->OCRLength
);
436 lsmash_bs_put_byte( bs
, slcd
->AU_Length
);
437 lsmash_bs_put_byte( bs
, slcd
->instantBitrateLength
);
439 temp16
= slcd
->degradationPriorityLength
<< 12;
440 temp16
|= slcd
->AU_seqNumLength
<< 7;
441 temp16
|= slcd
->packetSeqNumLength
<< 2;
442 temp16
|= slcd
->reserved
;
443 lsmash_bs_put_be16( bs
, temp16
);
445 if( slcd
->durationFlag
)
447 lsmash_bs_put_be32( bs
, slcd
->timeScale
);
448 lsmash_bs_put_be16( bs
, slcd
->accessUnitDuration
);
449 lsmash_bs_put_be16( bs
, slcd
->compositionUnitDuration
);
451 if( !slcd
->useTimeStampsFlag
)
453 lsmash_bits_t
*bits
= lsmash_bits_create( bs
);
455 return LSMASH_ERR_MEMORY_ALLOC
;
456 lsmash_bits_put( bits
, slcd
->timeStampLength
, slcd
->startDecodingTimeStamp
);
457 lsmash_bits_put( bits
, slcd
->timeStampLength
, slcd
->startCompositionTimeStamp
);
458 lsmash_bits_put_align( bits
);
459 lsmash_bits_cleanup( bits
);
464 static int mp4sys_write_ES_Descriptor( lsmash_bs_t
*bs
, mp4sys_ES_Descriptor_t
*esd
)
466 lsmash_bs_put_be16( bs
, esd
->ES_ID
);
468 temp
= esd
->streamDependenceFlag
<< 7;
469 temp
|= esd
->URL_Flag
<< 6;
470 temp
|= esd
->OCRstreamFlag
<< 5;
471 temp
|= esd
->streamPriority
;
472 lsmash_bs_put_byte( bs
, temp
);
473 if( esd
->streamDependenceFlag
)
474 lsmash_bs_put_be16( bs
, esd
->dependsOn_ES_ID
);
477 lsmash_bs_put_byte( bs
, esd
->URLlength
);
478 lsmash_bs_put_bytes( bs
, esd
->URLlength
, esd
->URLstring
);
480 if( esd
->OCRstreamFlag
)
481 lsmash_bs_put_be16( bs
, esd
->OCR_ES_Id
);
482 /* Here, some syntax elements are omitted due to previous flags (all 0). */
486 static int mp4sys_write_ES_ID_Inc( lsmash_bs_t
*bs
, mp4sys_ES_ID_Inc_t
*es_id_inc
)
488 lsmash_bs_put_be32( bs
, es_id_inc
->Track_ID
);
492 static int mp4sys_write_ObjectDescriptor( lsmash_bs_t
*bs
, mp4sys_ObjectDescriptor_t
*od
)
494 uint16_t temp
= (od
->ObjectDescriptorID
<< 6);
495 // temp |= (0x0 << 5); /* URL_Flag */
496 temp
|= (od
->includeInlineProfileLevelFlag
<< 4); /* if MP4_OD, includeInlineProfileLevelFlag is 0x1. */
497 temp
|= 0xF; /* reserved */
498 lsmash_bs_put_be16( bs
, temp
);
499 /* here, since we don't support URL_Flag, we put ProfileLevelIndications */
500 if( od
->header
.tag
== MP4SYS_DESCRIPTOR_TAG_MP4_IOD_Tag
)
502 lsmash_bs_put_byte( bs
, od
->ODProfileLevelIndication
);
503 lsmash_bs_put_byte( bs
, od
->sceneProfileLevelIndication
);
504 lsmash_bs_put_byte( bs
, od
->audioProfileLevelIndication
);
505 lsmash_bs_put_byte( bs
, od
->visualProfileLevelIndication
);
506 lsmash_bs_put_byte( bs
, od
->graphicsProfileLevelIndication
);
511 static int mp4sys_write_children( lsmash_bs_t
*bs
, mp4sys_descriptor_t
*descriptor
)
513 for( lsmash_entry_t
*entry
= descriptor
->children
.head
; entry
; entry
= entry
->next
)
515 mp4sys_descriptor_t
*child
= (mp4sys_descriptor_t
*)entry
->data
;
518 int ret
= mp4sys_write_descriptor( bs
, child
);
525 int mp4sys_write_descriptor( lsmash_bs_t
*bs
, void *opaque_descriptor
)
527 if( !bs
|| !opaque_descriptor
)
528 return LSMASH_ERR_NAMELESS
;
529 mp4sys_descriptor_t
*descriptor
= (mp4sys_descriptor_t
*)opaque_descriptor
;
530 mp4sys_write_descriptor_header( bs
, &descriptor
->header
);
531 if( !descriptor
->write
)
533 int err
= descriptor
->write( bs
, descriptor
);
536 return mp4sys_write_children( bs
, descriptor
);
539 /* descriptor size updater */
540 uint32_t mp4sys_update_descriptor_size( void *opaque_descriptor
)
542 assert( opaque_descriptor
);
543 mp4sys_descriptor_t
*descriptor
= (mp4sys_descriptor_t
*)opaque_descriptor
;
545 if( descriptor
->write
)
547 uint32_t header_size
= descriptor
->header
.size
;
548 /* Calculate the size of this descriptor excluding its children with a fake bytestream writer. */
550 lsmash_bs_t fake_bs
= { NULL
};
551 mp4sys_write_descriptor_header( &fake_bs
, &descriptor
->header
);
552 if( descriptor
->write( &fake_bs
, descriptor
) == 0 )
553 size
= lsmash_bs_get_valid_data_size( &fake_bs
);
555 /* Calculate the size including the children if no error. */
556 if( size
>= mp4sys_get_descriptor_header_size( header_size
) )
558 for( lsmash_entry_t
*entry
= descriptor
->children
.head
; entry
; entry
= entry
->next
)
560 size
+= mp4sys_update_descriptor_size( entry
->data
);
561 /* Calculate the size of this descriptor excluding its header. */
562 size
-= mp4sys_get_descriptor_header_size( header_size
);
563 descriptor
->header
.size
= size
;
564 /* Now, we get the actual size of this descriptor. */
565 size
+= mp4sys_get_descriptor_header_size( size
);
569 /* Invalid descriptor */
570 descriptor
->header
.size
= 0;
575 descriptor
->header
.size
= 0;
579 static inline void *mp4sys_construct_descriptor_orig
582 mp4sys_descriptor_t
*parent
,
583 mp4sys_descriptor_destructor_t destructor
,
584 mp4sys_descriptor_writer_t writer
587 assert( size
>= sizeof(mp4sys_BaseDescriptor_t
) );
588 mp4sys_descriptor_t
*descriptor
= lsmash_malloc_zero( size
);
591 descriptor
->class = &lsmash_mp4sys_class
;
592 descriptor
->parent
= parent
;
593 descriptor
->destruct
= destructor
;
594 descriptor
->write
= writer
;
598 #define mp4sys_construct_descriptor( size, parent, destructor, writer ) \
599 mp4sys_construct_descriptor_orig \
602 (mp4sys_descriptor_t *)parent, \
603 (mp4sys_descriptor_destructor_t)destructor, \
604 (mp4sys_descriptor_writer_t)writer \
607 #define MP4SYS_CONSTRUCT_DESCRIPTOR( var, descriptor_name, parent, ret ) \
608 mp4sys_##descriptor_name##_t *var = \
609 mp4sys_construct_descriptor \
611 sizeof(mp4sys_##descriptor_name##_t), \
613 mp4sys_remove_##descriptor_name, \
614 mp4sys_write_##descriptor_name \
619 static mp4sys_DecoderSpecificInfo_t
*mp4sys_add_DecoderSpecificInfo( mp4sys_DecoderConfigDescriptor_t
*dcd
)
623 MP4SYS_CONSTRUCT_DESCRIPTOR( dsi
, DecoderSpecificInfo
, dcd
, NULL
);
624 dsi
->header
.tag
= MP4SYS_DESCRIPTOR_TAG_DecSpecificInfoTag
;
625 if( lsmash_add_entry( &dcd
->children
, dsi
) < 0 )
627 mp4sys_remove_descriptor( dsi
);
630 dcd
->decSpecificInfo
= dsi
;
635 bufferSizeDB is byte unit, NOT bit unit.
636 avgBitrate is 0 if VBR
638 static mp4sys_DecoderConfigDescriptor_t
*mp4sys_add_DecoderConfigDescriptor
640 mp4sys_ES_Descriptor_t
*esd
645 MP4SYS_CONSTRUCT_DESCRIPTOR( dcd
, DecoderConfigDescriptor
, esd
, NULL
);
646 dcd
->header
.tag
= MP4SYS_DESCRIPTOR_TAG_DecoderConfigDescrTag
;
647 if( lsmash_add_entry( &esd
->children
, dcd
) < 0 )
649 mp4sys_remove_descriptor( dcd
);
652 esd
->decConfigDescr
= dcd
;
656 static mp4sys_SLConfigDescriptor_t
*mp4sys_add_SLConfigDescriptor( mp4sys_ES_Descriptor_t
*esd
)
660 MP4SYS_CONSTRUCT_DESCRIPTOR( slcd
, SLConfigDescriptor
, esd
, NULL
);
661 slcd
->header
.tag
= MP4SYS_DESCRIPTOR_TAG_SLConfigDescrTag
;
662 if( lsmash_add_entry( &esd
->children
, slcd
) < 0 )
664 mp4sys_remove_descriptor( slcd
);
667 esd
->slConfigDescr
= slcd
;
671 /* NOTE: This is only for MP4_IOD and MP4_OD, not for ISO Base Media's ObjectDescriptor and InitialObjectDescriptor */
672 static mp4sys_ES_ID_Inc_t
*mp4sys_add_ES_ID_Inc( mp4sys_ObjectDescriptor_t
*od
)
675 || (od
->header
.tag
!= MP4SYS_DESCRIPTOR_TAG_MP4_IOD_Tag
676 && od
->header
.tag
!= MP4SYS_DESCRIPTOR_TAG_MP4_OD_Tag
) )
678 MP4SYS_CONSTRUCT_DESCRIPTOR( es_id_inc
, ES_ID_Inc
, od
, NULL
);
679 es_id_inc
->header
.tag
= MP4SYS_DESCRIPTOR_TAG_ES_ID_IncTag
;
680 if( lsmash_add_entry( &od
->children
, es_id_inc
) < 0 )
682 mp4sys_remove_descriptor( es_id_inc
);
685 if( lsmash_add_entry( &od
->esDescr
, es_id_inc
) < 0 )
687 lsmash_remove_entry_tail( &od
->children
, mp4sys_remove_ES_ID_Inc
);
693 int mp4sys_create_ES_ID_Inc( mp4sys_ObjectDescriptor_t
*od
, uint32_t Track_ID
)
695 mp4sys_ES_ID_Inc_t
*es_id_inc
= mp4sys_add_ES_ID_Inc( od
);
697 return LSMASH_ERR_NAMELESS
;
698 es_id_inc
->Track_ID
= Track_ID
;
702 /* ES_ID of the ES Descriptor is stored as 0 when the ES Descriptor is built into sample descriptions in MP4 file format
703 * since the lower 16 bits of the track_ID is used, instead of ES_ID, for the identifier of the elemental stream within the track. */
704 mp4sys_ES_Descriptor_t
*mp4sys_create_ES_Descriptor( uint16_t ES_ID
)
706 MP4SYS_CONSTRUCT_DESCRIPTOR( esd
, ES_Descriptor
, NULL
, NULL
);
707 esd
->header
.tag
= MP4SYS_DESCRIPTOR_TAG_ES_DescrTag
;
712 /* NOTE: This is only for MP4_OD, not for ISO Base Media's ObjectDescriptor */
713 mp4sys_ObjectDescriptor_t
*mp4sys_create_ObjectDescriptor( uint16_t ObjectDescriptorID
)
715 MP4SYS_CONSTRUCT_DESCRIPTOR( od
, ObjectDescriptor
, NULL
, NULL
);
716 od
->header
.tag
= MP4SYS_DESCRIPTOR_TAG_MP4_OD_Tag
;
717 od
->ObjectDescriptorID
= ObjectDescriptorID
;
718 od
->includeInlineProfileLevelFlag
= 1; /* 1 as part of reserved flag. */
719 od
->ODProfileLevelIndication
= MP4SYS_OD_PLI_NONE_REQUIRED
;
720 od
->sceneProfileLevelIndication
= MP4SYS_SCENE_PLI_NONE_REQUIRED
;
721 od
->audioProfileLevelIndication
= MP4A_AUDIO_PLI_NONE_REQUIRED
;
722 od
->visualProfileLevelIndication
= MP4SYS_VISUAL_PLI_NONE_REQUIRED
;
723 od
->graphicsProfileLevelIndication
= MP4SYS_GRAPHICS_PLI_NONE_REQUIRED
;
727 /* NOTE: This is only for MP4_IOD, not for Iso Base Media's InitialObjectDescriptor */
728 int mp4sys_to_InitialObjectDescriptor
730 mp4sys_ObjectDescriptor_t
*od
,
731 uint8_t include_inline_pli
,
732 mp4sys_ODProfileLevelIndication od_pli
,
733 mp4sys_sceneProfileLevelIndication scene_pli
,
734 mp4a_audioProfileLevelIndication audio_pli
,
735 mp4sys_visualProfileLevelIndication visual_pli
,
736 mp4sys_graphicsProfileLevelIndication graph_pli
740 return LSMASH_ERR_NAMELESS
;
741 od
->header
.tag
= MP4SYS_DESCRIPTOR_TAG_MP4_IOD_Tag
;
742 od
->includeInlineProfileLevelFlag
= include_inline_pli
;
743 od
->ODProfileLevelIndication
= od_pli
;
744 od
->sceneProfileLevelIndication
= scene_pli
;
745 od
->audioProfileLevelIndication
= audio_pli
;
746 od
->visualProfileLevelIndication
= visual_pli
;
747 od
->graphicsProfileLevelIndication
= graph_pli
;
752 bufferSizeDB is byte unit, NOT bit unit.
753 avgBitrate is 0 if VBR
755 int mp4sys_update_DecoderConfigDescriptor( mp4sys_ES_Descriptor_t
*esd
, uint32_t bufferSizeDB
, uint32_t maxBitrate
, uint32_t avgBitrate
)
757 if( !esd
|| !esd
->decConfigDescr
)
758 return LSMASH_ERR_NAMELESS
;
759 mp4sys_DecoderConfigDescriptor_t
*dcd
= esd
->decConfigDescr
;
760 dcd
->bufferSizeDB
= bufferSizeDB
;
761 dcd
->maxBitrate
= maxBitrate
;
762 dcd
->avgBitrate
= avgBitrate
;
766 void mp4sys_print_descriptor( FILE *fp
, mp4sys_descriptor_t
*descriptor
, int indent
);
768 static void mp4sys_print_descriptor_header( FILE *fp
, mp4sys_descriptor_head_t
*header
, int indent
)
770 static const char *descriptor_names_table
[256] =
774 "InitialObjectDescriptor",
776 "DecoderConfigDescriptor",
777 "DecoderSpecificInfo",
778 "SLConfigDescriptor",
779 [0x0E] = "ES_ID_Inc",
780 [0x0F] = "ES_ID_Ref",
784 if( descriptor_names_table
[ header
->tag
] )
785 lsmash_ifprintf( fp
, indent
, "[tag = 0x%02"PRIx8
": %s]\n", header
->tag
, descriptor_names_table
[ header
->tag
] );
787 lsmash_ifprintf( fp
, indent
, "[tag = 0x%02"PRIx8
"]\n", header
->tag
);
788 lsmash_ifprintf( fp
, ++indent
, "expandableClassSize = %"PRIu32
"\n", header
->size
);
791 static void mp4sys_print_DecoderSpecificInfo( FILE *fp
, mp4sys_descriptor_t
*descriptor
, int indent
)
793 extern void mp4a_print_AudioSpecificConfig( FILE *, uint8_t *, uint32_t, int );
794 if( !descriptor
->parent
|| descriptor
->parent
->header
.tag
!= MP4SYS_DESCRIPTOR_TAG_DecoderConfigDescrTag
)
796 mp4sys_DecoderConfigDescriptor_t
*dcd
= (mp4sys_DecoderConfigDescriptor_t
*)descriptor
->parent
;
797 if( dcd
->streamType
!= MP4SYS_STREAM_TYPE_AudioStream
798 || dcd
->objectTypeIndication
!= MP4SYS_OBJECT_TYPE_Audio_ISO_14496_3
)
799 return; /* We support only AudioSpecificConfig here currently. */
800 mp4sys_DecoderSpecificInfo_t
*dsi
= (mp4sys_DecoderSpecificInfo_t
*)descriptor
;
801 mp4a_print_AudioSpecificConfig( fp
, dsi
->data
, dsi
->header
.size
, indent
);
804 static void mp4sys_print_DecoderConfigDescriptor( FILE *fp
, mp4sys_descriptor_t
*descriptor
, int indent
)
806 mp4sys_DecoderConfigDescriptor_t
*dcd
= (mp4sys_DecoderConfigDescriptor_t
*)descriptor
;
807 static const char *object_type_indication_descriptions_table
[256] =
810 "Systems ISO/IEC 14496-1 (a)",
811 "Systems ISO/IEC 14496-1 (b)",
812 "Interaction Stream",
813 "Systems ISO/IEC 14496-1 Extended BIFS Configuration",
814 "Systems ISO/IEC 14496-1 AFX",
816 "Synthesized Texture Stream",
817 "Streaming Text Stream",
819 "Simple Aggregation Format (SAF) Stream",
820 [0x20] = "Visual ISO/IEC 14496-2",
821 [0x21] = "Visual ITU-T Recommendation H.264 | ISO/IEC 14496-10",
822 [0x22] = "Parameter Sets for ITU-T Recommendation H.264 | ISO/IEC 14496-10",
823 [0x40] = "Audio ISO/IEC 14496-3",
824 [0x60] = "Visual ISO/IEC 13818-2 Simple Profile",
825 [0x61] = "Visual ISO/IEC 13818-2 Main Profile",
826 [0x62] = "Visual ISO/IEC 13818-2 SNR Profile",
827 [0x63] = "Visual ISO/IEC 13818-2 Spatial Profile",
828 [0x64] = "Visual ISO/IEC 13818-2 High Profile",
829 [0x65] = "Visual ISO/IEC 13818-2 422 Profile",
830 [0x66] = "Audio ISO/IEC 13818-7 Main Profile",
831 [0x67] = "Audio ISO/IEC 13818-7 LowComplexity Profile",
832 [0x68] = "Audio ISO/IEC 13818-7 Scaleable Sampling Rate Profile",
833 [0x69] = "Audio ISO/IEC 13818-3",
834 [0x6A] = "Visual ISO/IEC 11172-2",
835 [0x6B] = "Audio ISO/IEC 11172-3",
836 [0x6C] = "Visual ISO/IEC 10918-1",
837 [0x6D] = "Portable Network Graphics",
838 [0x6E] = "Visual ISO/IEC 15444-1 (JPEG 2000)",
839 [0xA0] = "EVRC Voice",
840 [0xA1] = "SMV Voice",
841 [0xA2] = "3GPP2 Compact Multimedia Format (CMF)",
842 [0xA3] = "SMPTE VC-1 Video",
843 [0xA4] = "Dirac Video Coder",
844 [0xA5] = "AC-3 Audio",
845 [0xA6] = "Enhanced AC-3 audio",
846 [0xA7] = "DRA Audio",
847 [0xA8] = "ITU G.719 Audio",
848 [0xA9] = "DTS Coherent Acoustics audio",
849 [0xAA] = "DTS-HD High Resolution Audio",
850 [0xAB] = "DTS-HD Master Audio",
851 [0xAC] = "DTS Express low bit rate audio",
852 [0xE1] = "13K Voice",
853 [0xFF] = "no object type specified"
855 static const char *stream_type_descriptions_table
[64] =
858 "ObjectDescriptorStream",
859 "ClockReferenceStream",
860 "SceneDescriptionStream",
865 "ObjectContentInfoStream",
867 "Interaction Stream",
872 if( object_type_indication_descriptions_table
[ dcd
->objectTypeIndication
] )
873 lsmash_ifprintf( fp
, indent
, "objectTypeIndication = 0x%02"PRIx8
" (%s)\n", dcd
->objectTypeIndication
, object_type_indication_descriptions_table
[ dcd
->objectTypeIndication
] );
875 lsmash_ifprintf( fp
, indent
, "objectTypeIndication = 0x%02"PRIx8
"\n", dcd
->objectTypeIndication
);
876 if( stream_type_descriptions_table
[ dcd
->streamType
] )
877 lsmash_ifprintf( fp
, indent
, "streamType = 0x%02"PRIx8
" (%s)\n", dcd
->streamType
, stream_type_descriptions_table
[ dcd
->streamType
] );
879 lsmash_ifprintf( fp
, indent
, "streamType = 0x%02"PRIx8
"\n", dcd
->streamType
);
880 lsmash_ifprintf( fp
, indent
, "upStream = %"PRIu8
"\n", dcd
->upStream
);
881 lsmash_ifprintf( fp
, indent
, "reserved = %"PRIu8
"\n", dcd
->reserved
);
882 lsmash_ifprintf( fp
, indent
, "bufferSizeDB = %"PRIu32
"\n", dcd
->bufferSizeDB
);
883 lsmash_ifprintf( fp
, indent
, "maxBitrate = %"PRIu32
"\n", dcd
->maxBitrate
);
884 lsmash_ifprintf( fp
, indent
, "avgBitrate = %"PRIu32
"%s\n", dcd
->avgBitrate
, dcd
->avgBitrate
? "" : " (variable bitrate)" );
887 static void mp4sys_print_SLConfigDescriptor( FILE *fp
, mp4sys_descriptor_t
*descriptor
, int indent
)
889 mp4sys_SLConfigDescriptor_t
*slcd
= (mp4sys_SLConfigDescriptor_t
*)descriptor
;
890 lsmash_ifprintf( fp
, indent
, "predefined = %"PRIu8
"\n", slcd
->predefined
);
891 if( slcd
->predefined
== 0 )
893 lsmash_ifprintf( fp
, indent
, "useAccessUnitStartFlag = %"PRIu8
"\n", slcd
->useAccessUnitStartFlag
);
894 lsmash_ifprintf( fp
, indent
, "useAccessUnitEndFlag = %"PRIu8
"\n", slcd
->useAccessUnitEndFlag
);
895 lsmash_ifprintf( fp
, indent
, "useRandomAccessPointFlag = %"PRIu8
"\n", slcd
->useRandomAccessPointFlag
);
896 lsmash_ifprintf( fp
, indent
, "hasRandomAccessUnitsOnlyFlag = %"PRIu8
"\n", slcd
->hasRandomAccessUnitsOnlyFlag
);
897 lsmash_ifprintf( fp
, indent
, "usePaddingFlag = %"PRIu8
"\n", slcd
->usePaddingFlag
);
898 lsmash_ifprintf( fp
, indent
, "useTimeStampsFlag = %"PRIu8
"\n", slcd
->useTimeStampsFlag
);
899 lsmash_ifprintf( fp
, indent
, "useIdleFlag = %"PRIu8
"\n", slcd
->useIdleFlag
);
900 lsmash_ifprintf( fp
, indent
, "durationFlag = %"PRIu8
"\n", slcd
->durationFlag
);
901 lsmash_ifprintf( fp
, indent
, "timeStampResolution = %"PRIu32
"\n", slcd
->timeStampResolution
);
902 lsmash_ifprintf( fp
, indent
, "OCRResolution = %"PRIu32
"\n", slcd
->OCRResolution
);
903 lsmash_ifprintf( fp
, indent
, "timeStampLength = %"PRIu8
"\n", slcd
->timeStampLength
);
904 lsmash_ifprintf( fp
, indent
, "OCRLength = %"PRIu8
"\n", slcd
->OCRLength
);
905 lsmash_ifprintf( fp
, indent
, "AU_Length = %"PRIu8
"\n", slcd
->AU_Length
);
906 lsmash_ifprintf( fp
, indent
, "instantBitrateLength = %"PRIu8
"\n", slcd
->instantBitrateLength
);
907 lsmash_ifprintf( fp
, indent
, "degradationPriorityLength = %"PRIu8
"\n", slcd
->degradationPriorityLength
);
908 lsmash_ifprintf( fp
, indent
, "AU_seqNumLength = %"PRIu8
"\n", slcd
->AU_seqNumLength
);
909 lsmash_ifprintf( fp
, indent
, "packetSeqNumLength = %"PRIu8
"\n", slcd
->packetSeqNumLength
);
910 lsmash_ifprintf( fp
, indent
, "reserved = 0x%01"PRIx8
"\n", slcd
->reserved
);
912 if( slcd
->durationFlag
)
914 lsmash_ifprintf( fp
, indent
, "timeScale = %"PRIu32
"\n", slcd
->timeScale
);
915 lsmash_ifprintf( fp
, indent
, "accessUnitDuration = %"PRIu16
"\n", slcd
->accessUnitDuration
);
916 lsmash_ifprintf( fp
, indent
, "compositionUnitDuration = %"PRIu16
"\n", slcd
->compositionUnitDuration
);
918 if( !slcd
->useTimeStampsFlag
)
920 lsmash_ifprintf( fp
, indent
, "startDecodingTimeStamp = %"PRIu64
"\n", slcd
->startDecodingTimeStamp
);
921 lsmash_ifprintf( fp
, indent
, "startCompositionTimeStamp = %"PRIu64
"\n", slcd
->startCompositionTimeStamp
);
925 static void mp4sys_print_ES_Descriptor( FILE *fp
, mp4sys_descriptor_t
*descriptor
, int indent
)
927 mp4sys_ES_Descriptor_t
*esd
= (mp4sys_ES_Descriptor_t
*)descriptor
;
928 lsmash_ifprintf( fp
, indent
, "ES_ID = %"PRIu16
"\n", esd
->ES_ID
);
929 lsmash_ifprintf( fp
, indent
, "streamDependenceFlag = %"PRIu8
"\n", esd
->streamDependenceFlag
);
930 lsmash_ifprintf( fp
, indent
, "URL_Flag = %"PRIu8
"\n", esd
->URL_Flag
);
931 lsmash_ifprintf( fp
, indent
, "OCRstreamFlag = %"PRIu8
"\n", esd
->OCRstreamFlag
);
932 lsmash_ifprintf( fp
, indent
, "streamPriority = %"PRIu8
"\n", esd
->streamPriority
);
933 if( esd
->streamDependenceFlag
)
934 lsmash_ifprintf( fp
, indent
, "dependsOn_ES_ID = %"PRIu16
"\n", esd
->dependsOn_ES_ID
);
937 lsmash_ifprintf( fp
, indent
, "URLlength = %"PRIu8
"\n", esd
->URLlength
);
938 lsmash_ifprintf( fp
, indent
, "URLstring = %s\n", esd
->URLstring
);
940 if( esd
->OCRstreamFlag
)
941 lsmash_ifprintf( fp
, indent
, "OCR_ES_Id = %"PRIu16
"\n", esd
->OCR_ES_Id
);
944 static void mp4sys_print_ES_ID_Inc( FILE *fp
, mp4sys_descriptor_t
*descriptor
, int indent
)
946 mp4sys_ES_ID_Inc_t
*es_id_inc
= (mp4sys_ES_ID_Inc_t
*)descriptor
;
947 lsmash_ifprintf( fp
, indent
, "Track_ID = %"PRIu32
"\n", es_id_inc
->Track_ID
);
950 static void mp4sys_print_ObjectDescriptor( FILE *fp
, mp4sys_descriptor_t
*descriptor
, int indent
)
952 mp4sys_ObjectDescriptor_t
*od
= (mp4sys_ObjectDescriptor_t
*)descriptor
;
953 lsmash_ifprintf( fp
, indent
, "ObjectDescriptorID = %"PRIu16
"\n", od
->ObjectDescriptorID
);
954 lsmash_ifprintf( fp
, indent
, "URL_Flag = %"PRIu8
"\n", od
->URL_Flag
);
955 if( od
->header
.tag
== MP4SYS_DESCRIPTOR_TAG_InitialObjectDescrTag
956 || od
->header
.tag
== MP4SYS_DESCRIPTOR_TAG_MP4_IOD_Tag
)
958 lsmash_ifprintf( fp
, indent
, "includeInlineProfileLevelFlag = %"PRIu8
"\n", od
->includeInlineProfileLevelFlag
);
959 lsmash_ifprintf( fp
, indent
, "reserved = 0x%01"PRIx8
"\n", od
->reserved
);
962 lsmash_ifprintf( fp
, indent
, "reserved = 0x%02"PRIx8
"\n", od
->reserved
| (od
->includeInlineProfileLevelFlag
<< 4) );
965 lsmash_ifprintf( fp
, indent
, "URLlength = %"PRIu8
"\n", od
->URLlength
);
966 lsmash_ifprintf( fp
, indent
, "URLstring = %s\n", od
->URLstring
);
970 if( od
->header
.tag
== MP4SYS_DESCRIPTOR_TAG_InitialObjectDescrTag
971 || od
->header
.tag
== MP4SYS_DESCRIPTOR_TAG_MP4_IOD_Tag
)
973 lsmash_ifprintf( fp
, indent
, "ODProfileLevelIndication = 0x%02"PRIx8
"\n", od
->ODProfileLevelIndication
);
974 lsmash_ifprintf( fp
, indent
, "sceneProfileLevelIndication = 0x%02"PRIx8
"\n", od
->sceneProfileLevelIndication
);
975 lsmash_ifprintf( fp
, indent
, "audioProfileLevelIndication = 0x%02"PRIx8
"\n", od
->audioProfileLevelIndication
);
976 lsmash_ifprintf( fp
, indent
, "visualProfileLevelIndication = 0x%02"PRIx8
"\n", od
->visualProfileLevelIndication
);
977 lsmash_ifprintf( fp
, indent
, "graphicsProfileLevelIndication = 0x%02"PRIx8
"\n", od
->graphicsProfileLevelIndication
);
982 void mp4sys_print_descriptor( FILE *fp
, mp4sys_descriptor_t
*descriptor
, int indent
)
986 mp4sys_print_descriptor_header( fp
, &descriptor
->header
, indent
++ );
987 switch( descriptor
->header
.tag
)
989 case MP4SYS_DESCRIPTOR_TAG_ObjectDescrTag
:
990 case MP4SYS_DESCRIPTOR_TAG_InitialObjectDescrTag
:
991 case MP4SYS_DESCRIPTOR_TAG_MP4_OD_Tag
:
992 case MP4SYS_DESCRIPTOR_TAG_MP4_IOD_Tag
:
993 mp4sys_print_ObjectDescriptor( fp
, descriptor
, indent
);
995 case MP4SYS_DESCRIPTOR_TAG_ES_DescrTag
:
996 mp4sys_print_ES_Descriptor( fp
, descriptor
, indent
);
998 case MP4SYS_DESCRIPTOR_TAG_DecoderConfigDescrTag
:
999 mp4sys_print_DecoderConfigDescriptor( fp
, descriptor
, indent
);
1001 case MP4SYS_DESCRIPTOR_TAG_DecSpecificInfoTag
:
1002 mp4sys_print_DecoderSpecificInfo( fp
, descriptor
, indent
);
1004 case MP4SYS_DESCRIPTOR_TAG_SLConfigDescrTag
:
1005 mp4sys_print_SLConfigDescriptor( fp
, descriptor
, indent
);
1007 case MP4SYS_DESCRIPTOR_TAG_ES_ID_IncTag
:
1008 mp4sys_print_ES_ID_Inc( fp
, descriptor
, indent
);
1013 for( lsmash_entry_t
*entry
= descriptor
->children
.head
; entry
; entry
= entry
->next
)
1015 mp4sys_print_descriptor( fp
, entry
->data
, indent
);
1018 int mp4sys_print_codec_specific( FILE *fp
, lsmash_file_t
*file
, isom_box_t
*box
, int level
)
1020 assert( !(box
->manager
& LSMASH_BINARY_CODED_BOX
) );
1021 isom_esds_t
*esds
= (isom_esds_t
*)box
;
1023 lsmash_ifprintf( fp
, indent
++, "[%s: Elemental Stream Descriptor Box]\n", isom_4cc2str( esds
->type
.fourcc
) );
1024 lsmash_ifprintf( fp
, indent
, "position = %"PRIu64
"\n", esds
->pos
);
1025 lsmash_ifprintf( fp
, indent
, "size = %"PRIu64
"\n", esds
->size
);
1026 lsmash_ifprintf( fp
, indent
, "version = %"PRIu8
"\n", esds
->version
);
1027 lsmash_ifprintf( fp
, indent
, "flags = 0x%06"PRIx32
"\n", esds
->flags
& 0x00ffffff );
1028 mp4sys_print_descriptor( fp
, (mp4sys_descriptor_t
*)esds
->ES
, indent
);
1032 mp4sys_descriptor_t
*mp4sys_get_descriptor( lsmash_bs_t
*bs
, void *parent
);
1034 static void mp4sys_get_descriptor_header( lsmash_bs_t
*bs
, mp4sys_descriptor_head_t
*header
)
1036 header
->tag
= lsmash_bs_get_byte( bs
);
1037 uint8_t temp
= lsmash_bs_get_byte( bs
);
1038 int nextByte
= temp
& 0x80;
1039 uint32_t sizeOfInstance
= temp
& 0x7F;
1042 temp
= lsmash_bs_get_byte( bs
);
1043 nextByte
= temp
& 0x80;
1044 sizeOfInstance
= (sizeOfInstance
<< 7) | (temp
& 0x7F);
1046 header
->size
= sizeOfInstance
;
1049 static mp4sys_DecoderSpecificInfo_t
*mp4sys_get_DecoderSpecificInfo( lsmash_bs_t
*bs
, mp4sys_descriptor_head_t
*header
, void *parent
)
1051 mp4sys_DecoderSpecificInfo_t
*dsi
= mp4sys_add_DecoderSpecificInfo( parent
);
1054 dsi
->header
.size
= header
->size
;
1055 if( dsi
->header
.size
)
1057 dsi
->data
= lsmash_bs_get_bytes( bs
, dsi
->header
.size
);
1060 mp4sys_remove_descriptor( dsi
);
1067 static mp4sys_DecoderConfigDescriptor_t
*mp4sys_get_DecoderConfigDescriptor( lsmash_bs_t
*bs
, mp4sys_descriptor_head_t
*header
, void *parent
)
1069 mp4sys_DecoderConfigDescriptor_t
*dcd
= mp4sys_add_DecoderConfigDescriptor( parent
);
1072 uint64_t end_pos
= header
->size
+ lsmash_bs_count( bs
);
1073 dcd
->header
.size
= header
->size
;
1074 dcd
->objectTypeIndication
= lsmash_bs_get_byte( bs
);
1075 uint8_t temp
= lsmash_bs_get_byte( bs
);
1076 dcd
->streamType
= (temp
>> 2) & 0x3F;
1077 dcd
->upStream
= (temp
>> 1) & 0x01;
1078 dcd
->reserved
= temp
& 0x01;
1079 dcd
->bufferSizeDB
= lsmash_bs_get_be24( bs
);
1080 dcd
->maxBitrate
= lsmash_bs_get_be32( bs
);
1081 dcd
->avgBitrate
= lsmash_bs_get_be32( bs
);
1082 while( lsmash_bs_count( bs
) < end_pos
)
1084 mp4sys_descriptor_t
*desc
= mp4sys_get_descriptor( bs
, dcd
);
1087 if( desc
->header
.tag
== MP4SYS_DESCRIPTOR_TAG_DecSpecificInfoTag
)
1088 dcd
->decSpecificInfo
= (mp4sys_DecoderSpecificInfo_t
*)desc
;
1090 mp4sys_remove_descriptor( desc
);
1098 static mp4sys_SLConfigDescriptor_t
*mp4sys_get_SLConfigDescriptor( lsmash_bs_t
*bs
, mp4sys_descriptor_head_t
*header
, void *parent
)
1100 mp4sys_SLConfigDescriptor_t
*slcd
= mp4sys_add_SLConfigDescriptor( parent
);
1103 slcd
->header
.size
= header
->size
;
1104 slcd
->predefined
= lsmash_bs_get_byte( bs
);
1105 if( slcd
->predefined
== 0x00 )
1107 uint8_t temp8
= lsmash_bs_get_byte( bs
);
1108 slcd
->useAccessUnitStartFlag
= (temp8
>> 7) & 0x01;
1109 slcd
->useAccessUnitEndFlag
= (temp8
>> 6) & 0x01;
1110 slcd
->useRandomAccessPointFlag
= (temp8
>> 5) & 0x01;
1111 slcd
->hasRandomAccessUnitsOnlyFlag
= (temp8
>> 4) & 0x01;
1112 slcd
->usePaddingFlag
= (temp8
>> 3) & 0x01;
1113 slcd
->useTimeStampsFlag
= (temp8
>> 2) & 0x01;
1114 slcd
->useIdleFlag
= (temp8
>> 1) & 0x01;
1115 slcd
->durationFlag
= temp8
& 0x01;
1116 slcd
->timeStampResolution
= lsmash_bs_get_be32( bs
);
1117 slcd
->OCRResolution
= lsmash_bs_get_be32( bs
);
1118 slcd
->timeStampLength
= lsmash_bs_get_byte( bs
);
1119 slcd
->OCRLength
= lsmash_bs_get_byte( bs
);
1120 slcd
->AU_Length
= lsmash_bs_get_byte( bs
);
1121 slcd
->instantBitrateLength
= lsmash_bs_get_byte( bs
);
1122 uint16_t temp16
= lsmash_bs_get_be16( bs
);
1123 slcd
->degradationPriorityLength
= (temp16
>> 12) & 0x0F;
1124 slcd
->AU_seqNumLength
= (temp16
>> 7) & 0x1F;
1125 slcd
->packetSeqNumLength
= (temp16
>> 2) & 0x1F;
1126 slcd
->reserved
= temp16
& 0x03;
1128 else if( slcd
->predefined
== 0x01 )
1130 slcd
->timeStampResolution
= 1000;
1131 slcd
->timeStampLength
= 32;
1133 else if( slcd
->predefined
== 0x02 )
1134 slcd
->useTimeStampsFlag
= 1;
1135 if( slcd
->durationFlag
)
1137 slcd
->timeScale
= lsmash_bs_get_be32( bs
);
1138 slcd
->accessUnitDuration
= lsmash_bs_get_be16( bs
);
1139 slcd
->compositionUnitDuration
= lsmash_bs_get_be16( bs
);
1141 if( !slcd
->useTimeStampsFlag
)
1143 lsmash_bits_t
*bits
= lsmash_bits_create( bs
);
1146 mp4sys_remove_descriptor( slcd
);
1149 slcd
->startDecodingTimeStamp
= lsmash_bits_get( bits
, slcd
->timeStampLength
);
1150 slcd
->startCompositionTimeStamp
= lsmash_bits_get( bits
, slcd
->timeStampLength
);
1151 lsmash_bits_cleanup( bits
);
1156 static mp4sys_ES_Descriptor_t
*mp4sys_get_ES_Descriptor( lsmash_bs_t
*bs
, mp4sys_descriptor_head_t
*header
, void *parent
)
1158 MP4SYS_CONSTRUCT_DESCRIPTOR( esd
, ES_Descriptor
, parent
, NULL
);
1159 if( parent
&& lsmash_add_entry( &((mp4sys_descriptor_t
*)parent
)->children
, esd
) < 0 )
1161 mp4sys_remove_descriptor( esd
);
1164 uint64_t end_pos
= header
->size
+ lsmash_bs_count( bs
);
1165 esd
->header
= *header
;
1166 esd
->ES_ID
= lsmash_bs_get_be16( bs
);
1167 uint8_t temp
= lsmash_bs_get_byte( bs
);
1168 esd
->streamDependenceFlag
= (temp
>> 7) & 0x01;
1169 esd
->URL_Flag
= (temp
>> 6) & 0x01;
1170 esd
->OCRstreamFlag
= (temp
>> 5) & 0x01;
1171 esd
->streamPriority
= temp
& 0x1F;
1172 if( esd
->streamDependenceFlag
)
1173 esd
->dependsOn_ES_ID
= lsmash_bs_get_be16( bs
);
1176 size_t length
= lsmash_bs_get_byte( bs
);
1177 lsmash_bs_read_data( bs
, (uint8_t *)esd
->URLstring
, &length
);
1178 esd
->URLlength
= length
;
1180 if( esd
->OCRstreamFlag
)
1181 esd
->OCR_ES_Id
= lsmash_bs_get_be16( bs
);
1182 /* DecoderConfigDescriptor and SLConfigDescriptor are mandatory. */
1183 while( lsmash_bs_count( bs
) < end_pos
)
1185 mp4sys_descriptor_t
*desc
= mp4sys_get_descriptor( bs
, esd
);
1188 if( desc
->header
.tag
== MP4SYS_DESCRIPTOR_TAG_DecoderConfigDescrTag
)
1189 esd
->decConfigDescr
= (mp4sys_DecoderConfigDescriptor_t
*)desc
;
1190 else if( desc
->header
.tag
== MP4SYS_DESCRIPTOR_TAG_SLConfigDescrTag
)
1191 esd
->slConfigDescr
= (mp4sys_SLConfigDescriptor_t
*)desc
;
1193 mp4sys_remove_descriptor( desc
);
1198 if( !esd
->decConfigDescr
|| !esd
->slConfigDescr
)
1200 mp4sys_remove_descriptor( esd
);
1206 static mp4sys_ES_ID_Inc_t
*mp4sys_get_ES_ID_Inc( lsmash_bs_t
*bs
, mp4sys_descriptor_head_t
*header
, void *parent
)
1208 mp4sys_ES_ID_Inc_t
*es_id_inc
= mp4sys_add_ES_ID_Inc( parent
);
1211 es_id_inc
->header
.size
= header
->size
;
1212 es_id_inc
->Track_ID
= lsmash_bs_get_be32( bs
);
1216 static mp4sys_ObjectDescriptor_t
*mp4sys_get_ObjectDescriptor( lsmash_bs_t
*bs
, mp4sys_descriptor_head_t
*header
, void *parent
)
1218 MP4SYS_CONSTRUCT_DESCRIPTOR( od
, ObjectDescriptor
, parent
, NULL
);
1219 if( parent
&& lsmash_add_entry( &((mp4sys_descriptor_t
*)parent
)->children
, od
) < 0 )
1221 mp4sys_remove_descriptor( od
);
1224 od
->header
= *header
;
1225 uint64_t end_pos
= header
->size
+ lsmash_bs_count( bs
);
1226 uint16_t temp16
= lsmash_bs_get_be16( bs
);
1227 od
->ObjectDescriptorID
= (temp16
>> 6) & 0x03FF;
1228 od
->URL_Flag
= (temp16
>> 5) & 0x0001;
1229 od
->includeInlineProfileLevelFlag
= (temp16
>> 4) & 0x0001;
1230 od
->reserved
= temp16
& 0x000F;
1233 size_t length
= lsmash_bs_get_byte( bs
);
1234 lsmash_bs_read_data( bs
, (uint8_t *)od
->URLstring
, &length
);
1235 od
->URLlength
= length
;
1239 if( od
->header
.tag
== MP4SYS_DESCRIPTOR_TAG_InitialObjectDescrTag
1240 || od
->header
.tag
== MP4SYS_DESCRIPTOR_TAG_MP4_IOD_Tag
)
1242 od
->ODProfileLevelIndication
= lsmash_bs_get_byte( bs
);
1243 od
->sceneProfileLevelIndication
= lsmash_bs_get_byte( bs
);
1244 od
->audioProfileLevelIndication
= lsmash_bs_get_byte( bs
);
1245 od
->visualProfileLevelIndication
= lsmash_bs_get_byte( bs
);
1246 od
->graphicsProfileLevelIndication
= lsmash_bs_get_byte( bs
);
1248 const mp4sys_descriptor_tag at_least_one_descriptor_tag
1249 = od
->header
.tag
== MP4SYS_DESCRIPTOR_TAG_MP4_OD_Tag
1250 || od
->header
.tag
== MP4SYS_DESCRIPTOR_TAG_MP4_IOD_Tag
1251 ? MP4SYS_DESCRIPTOR_TAG_ES_ID_IncTag
1252 : MP4SYS_DESCRIPTOR_TAG_ES_DescrTag
;
1253 while( lsmash_bs_count( bs
) < end_pos
&& od
->esDescr
.entry_count
< 255 )
1255 mp4sys_descriptor_t
*desc
= mp4sys_get_descriptor( bs
, od
);
1258 if( desc
->header
.tag
!= at_least_one_descriptor_tag
)
1260 mp4sys_remove_descriptor( desc
);
1268 mp4sys_descriptor_t
*mp4sys_get_descriptor( lsmash_bs_t
*bs
, void *parent
)
1270 mp4sys_descriptor_head_t header
;
1271 mp4sys_get_descriptor_header( bs
, &header
);
1272 uint64_t end_pos
= header
.size
+ lsmash_bs_count( bs
);
1273 mp4sys_descriptor_t
*desc
;
1274 switch( header
.tag
)
1276 case MP4SYS_DESCRIPTOR_TAG_ObjectDescrTag
:
1277 case MP4SYS_DESCRIPTOR_TAG_InitialObjectDescrTag
:
1278 case MP4SYS_DESCRIPTOR_TAG_MP4_OD_Tag
:
1279 case MP4SYS_DESCRIPTOR_TAG_MP4_IOD_Tag
:
1280 desc
= (mp4sys_descriptor_t
*)mp4sys_get_ObjectDescriptor( bs
, &header
, parent
);
1282 case MP4SYS_DESCRIPTOR_TAG_ES_DescrTag
:
1283 desc
= (mp4sys_descriptor_t
*)mp4sys_get_ES_Descriptor( bs
, &header
, parent
);
1285 case MP4SYS_DESCRIPTOR_TAG_DecoderConfigDescrTag
:
1286 desc
= (mp4sys_descriptor_t
*)mp4sys_get_DecoderConfigDescriptor( bs
, &header
, parent
);
1288 case MP4SYS_DESCRIPTOR_TAG_DecSpecificInfoTag
:
1289 desc
= (mp4sys_descriptor_t
*)mp4sys_get_DecoderSpecificInfo( bs
, &header
, parent
);
1291 case MP4SYS_DESCRIPTOR_TAG_SLConfigDescrTag
:
1292 desc
= (mp4sys_descriptor_t
*)mp4sys_get_SLConfigDescriptor( bs
, &header
, parent
);
1294 case MP4SYS_DESCRIPTOR_TAG_ES_ID_IncTag
:
1295 desc
= (mp4sys_descriptor_t
*)mp4sys_get_ES_ID_Inc( bs
, &header
, parent
);
1298 desc
= lsmash_malloc_zero( sizeof(mp4sys_descriptor_t
) );
1301 desc
->parent
= parent
;
1302 desc
->header
= header
;
1306 /* Skip extra bytes if present. */
1307 uint64_t skip_bytes
= end_pos
- lsmash_bs_count( bs
);
1310 fprintf( stderr
, "[MPEG-4 Systems Descriptor Tag = 0x%02"PRIx8
"] has more bytes than expected: %"PRId64
"\n", header
.tag
, skip_bytes
);
1311 if( !bs
->unseekable
)
1313 /* The stream is seekable. So, skip by seeking the stream. */
1314 uint64_t start
= lsmash_bs_get_stream_pos( bs
);
1315 lsmash_bs_read_seek( bs
, skip_bytes
, SEEK_CUR
);
1316 uint64_t end
= lsmash_bs_get_stream_pos( bs
);
1317 bs
->buffer
.count
+= end
- start
;
1320 /* The stream is unseekable. So, skip by reading the stream. */
1321 lsmash_bs_skip_bytes_64( bs
, skip_bytes
);
1326 static uint8_t *mp4sys_export_DecoderSpecificInfo( mp4sys_ES_Descriptor_t
*esd
, uint32_t *dsi_payload_length
)
1328 if( !esd
|| !esd
->decConfigDescr
|| !esd
->decConfigDescr
->decSpecificInfo
)
1330 mp4sys_DecoderSpecificInfo_t
*dsi
= (mp4sys_DecoderSpecificInfo_t
*)esd
->decConfigDescr
->decSpecificInfo
;
1331 uint8_t *dsi_payload
= NULL
;
1332 /* DecoderSpecificInfo can be absent. */
1333 if( dsi
->header
.size
)
1335 dsi_payload
= lsmash_memdup( dsi
->data
, dsi
->header
.size
);
1339 if( dsi_payload_length
)
1340 *dsi_payload_length
= dsi
->header
.size
;
1344 /* Sumamry is needed to decide ProfileLevelIndication.
1345 * Currently, support audio's only. */
1346 int mp4sys_setup_summary_from_DecoderSpecificInfo( lsmash_audio_summary_t
*summary
, mp4sys_ES_Descriptor_t
*esd
)
1348 uint32_t dsi_payload_length
= UINT32_MAX
; /* arbitrary */
1349 uint8_t *dsi_payload
= mp4sys_export_DecoderSpecificInfo( esd
, &dsi_payload_length
);
1350 if( !dsi_payload
&& dsi_payload_length
)
1351 return LSMASH_ERR_NAMELESS
;
1353 if( dsi_payload_length
)
1355 lsmash_codec_specific_t
*cs
= lsmash_create_codec_specific_data( LSMASH_CODEC_SPECIFIC_DATA_TYPE_MP4SYS_DECODER_CONFIG
,
1356 LSMASH_CODEC_SPECIFIC_FORMAT_STRUCTURED
);
1359 err
= LSMASH_ERR_MEMORY_ALLOC
;
1362 lsmash_mp4sys_decoder_parameters_t
*params
= (lsmash_mp4sys_decoder_parameters_t
*)cs
->data
.structured
;
1363 mp4sys_DecoderConfigDescriptor_t
*dcd
= esd
->decConfigDescr
;
1364 params
->objectTypeIndication
= dcd
->objectTypeIndication
;
1365 params
->streamType
= dcd
->streamType
;
1366 params
->bufferSizeDB
= dcd
->bufferSizeDB
;
1367 params
->maxBitrate
= dcd
->maxBitrate
;
1368 params
->avgBitrate
= dcd
->avgBitrate
;
1369 if( (err
= mp4a_setup_summary_from_AudioSpecificConfig( summary
, dsi_payload
, dsi_payload_length
)) < 0
1370 || (err
= lsmash_set_mp4sys_decoder_specific_info( params
, dsi_payload
, dsi_payload_length
)) < 0
1371 || (err
= lsmash_add_entry( &summary
->opaque
->list
, cs
)) < 0 )
1373 lsmash_destroy_codec_specific_data( cs
);
1378 lsmash_free( dsi_payload
);
1382 /**** following functions are for facilitation purpose ****/
1384 mp4sys_ES_Descriptor_t
*mp4sys_setup_ES_Descriptor( mp4sys_ES_Descriptor_params_t
*params
)
1388 mp4sys_ES_Descriptor_t
*esd
= mp4sys_create_ES_Descriptor( params
->ES_ID
);
1391 /* DecoderConfigDescriptor */
1392 mp4sys_DecoderConfigDescriptor_t
*dcd
= mp4sys_add_DecoderConfigDescriptor( esd
);
1395 dcd
->objectTypeIndication
= params
->objectTypeIndication
;
1396 dcd
->streamType
= params
->streamType
;
1399 dcd
->bufferSizeDB
= params
->bufferSizeDB
;
1400 dcd
->maxBitrate
= params
->maxBitrate
;
1401 dcd
->avgBitrate
= params
->avgBitrate
;
1402 /* DecoderSpecificInfo */
1403 if( params
->dsi_payload
&& params
->dsi_payload_length
!= 0 )
1405 mp4sys_DecoderSpecificInfo_t
*dsi
= mp4sys_add_DecoderSpecificInfo( dcd
);
1408 dsi
->data
= lsmash_memdup( params
->dsi_payload
, params
->dsi_payload_length
);
1411 dsi
->header
.size
= params
->dsi_payload_length
;
1413 /* SLConfigDescriptor */
1415 mp4sys_SLConfigDescriptor_t
*slcd
= mp4sys_add_SLConfigDescriptor( esd
);
1418 slcd
->predefined
= 0x02; /* MP4 file which does not use URL_Flag shall have constant value 0x02 */
1419 slcd
->useTimeStampsFlag
= 1; /* set to 1 if predefined == 2 */
1423 mp4sys_remove_descriptor( esd
);
1427 int lsmash_set_mp4sys_decoder_specific_info( lsmash_mp4sys_decoder_parameters_t
*param
, uint8_t *payload
, uint32_t payload_length
)
1429 if( !param
|| !payload
|| payload_length
== 0 )
1430 return LSMASH_ERR_FUNCTION_PARAM
;
1433 param
->dsi
= lsmash_malloc_zero( sizeof(lsmash_mp4sys_decoder_specific_info_t
) );
1435 return LSMASH_ERR_MEMORY_ALLOC
;
1439 lsmash_freep( ¶m
->dsi
->payload
);
1440 param
->dsi
->payload_length
= 0;
1442 param
->dsi
->payload
= lsmash_memdup( payload
, payload_length
);
1443 if( !param
->dsi
->payload
)
1444 return LSMASH_ERR_MEMORY_ALLOC
;
1445 param
->dsi
->payload_length
= payload_length
;
1449 void lsmash_destroy_mp4sys_decoder_specific_info( lsmash_mp4sys_decoder_parameters_t
*param
)
1451 if( !param
|| !param
->dsi
)
1453 lsmash_free( param
->dsi
->payload
);
1454 lsmash_freep( ¶m
->dsi
);
1457 void mp4sys_destruct_decoder_config( void *data
)
1461 lsmash_destroy_mp4sys_decoder_specific_info( data
);
1462 lsmash_free( data
);
1465 uint8_t *lsmash_create_mp4sys_decoder_config( lsmash_mp4sys_decoder_parameters_t
*param
, uint32_t *data_length
)
1467 if( !param
|| !data_length
)
1469 mp4sys_ES_Descriptor_params_t esd_param
= { 0 };
1470 esd_param
.ES_ID
= 0; /* Within sample description, ES_ID is stored as 0. */
1471 esd_param
.objectTypeIndication
= param
->objectTypeIndication
;
1472 esd_param
.streamType
= param
->streamType
;
1473 esd_param
.bufferSizeDB
= param
->bufferSizeDB
;
1474 esd_param
.maxBitrate
= param
->maxBitrate
;
1475 esd_param
.avgBitrate
= param
->avgBitrate
;
1477 && param
->dsi
->payload
1478 && param
->dsi
->payload_length
)
1480 esd_param
.dsi_payload
= param
->dsi
->payload
;
1481 esd_param
.dsi_payload_length
= param
->dsi
->payload_length
;
1483 mp4sys_ES_Descriptor_t
*esd
= mp4sys_setup_ES_Descriptor( &esd_param
);
1486 lsmash_bs_t
*bs
= lsmash_bs_create();
1489 mp4sys_remove_descriptor( esd
);
1492 lsmash_bs_put_be32( bs
, 0 ); /* update later */
1493 lsmash_bs_put_be32( bs
, ISOM_BOX_TYPE_ESDS
.fourcc
);
1494 lsmash_bs_put_be32( bs
, 0 );
1495 mp4sys_update_descriptor_size( esd
);
1496 mp4sys_write_descriptor( bs
, esd
);
1497 mp4sys_remove_descriptor( esd
);
1498 uint8_t *data
= lsmash_bs_export_data( bs
, data_length
);
1499 lsmash_bs_cleanup( bs
);
1502 /* Update box size. */
1503 LSMASH_SET_BE32( data
, *data_length
);
1507 int mp4sys_construct_decoder_config( lsmash_codec_specific_t
*dst
, lsmash_codec_specific_t
*src
)
1509 assert( dst
&& dst
->data
.structured
&& src
&& src
->data
.unstructured
);
1510 if( src
->size
< ISOM_FULLBOX_COMMON_SIZE
+ 23 )
1511 return LSMASH_ERR_INVALID_DATA
;
1512 lsmash_mp4sys_decoder_parameters_t
*param
= (lsmash_mp4sys_decoder_parameters_t
*)dst
->data
.structured
;
1513 uint8_t *data
= src
->data
.unstructured
;
1514 uint64_t size
= LSMASH_GET_BE32( data
);
1515 data
+= ISOM_BASEBOX_COMMON_SIZE
;
1518 size
= LSMASH_GET_BE64( data
);
1521 if( size
!= src
->size
)
1522 return LSMASH_ERR_INVALID_DATA
;
1523 data
+= 4; /* Skip version and flags. */
1524 lsmash_bs_t
*bs
= lsmash_bs_create();
1526 return LSMASH_ERR_MEMORY_ALLOC
;
1527 int err
= lsmash_bs_import_data( bs
, data
, src
->size
- (data
- src
->data
.unstructured
) );
1530 lsmash_bs_cleanup( bs
);
1533 mp4sys_ES_Descriptor_t
*esd
= (mp4sys_ES_Descriptor_t
*)mp4sys_get_descriptor( bs
, NULL
);
1534 lsmash_bs_cleanup( bs
);
1535 if( !esd
|| esd
->header
.tag
!= MP4SYS_DESCRIPTOR_TAG_ES_DescrTag
|| !esd
->decConfigDescr
)
1536 return LSMASH_ERR_INVALID_DATA
;
1537 mp4sys_DecoderConfigDescriptor_t
*dcd
= esd
->decConfigDescr
;
1538 param
->objectTypeIndication
= dcd
->objectTypeIndication
;
1539 param
->streamType
= dcd
->streamType
;
1540 param
->bufferSizeDB
= dcd
->bufferSizeDB
;
1541 param
->maxBitrate
= dcd
->maxBitrate
;
1542 param
->avgBitrate
= dcd
->avgBitrate
;
1543 mp4sys_DecoderSpecificInfo_t
*dsi
= dcd
->decSpecificInfo
;
1547 && (err
= lsmash_set_mp4sys_decoder_specific_info( param
, dsi
->data
, dsi
->header
.size
)) < 0 )
1549 mp4sys_remove_descriptor( esd
);
1552 mp4sys_remove_descriptor( esd
);
1556 int mp4sys_copy_decoder_config( lsmash_codec_specific_t
*dst
, lsmash_codec_specific_t
*src
)
1558 assert( src
&& src
->format
== LSMASH_CODEC_SPECIFIC_FORMAT_STRUCTURED
&& src
->data
.structured
);
1559 assert( dst
&& dst
->format
== LSMASH_CODEC_SPECIFIC_FORMAT_STRUCTURED
&& dst
->data
.structured
);
1560 lsmash_mp4sys_decoder_parameters_t
*src_data
= (lsmash_mp4sys_decoder_parameters_t
*)src
->data
.structured
;
1561 lsmash_mp4sys_decoder_parameters_t
*dst_data
= (lsmash_mp4sys_decoder_parameters_t
*)dst
->data
.structured
;
1562 lsmash_destroy_mp4sys_decoder_specific_info( dst_data
);
1563 *dst_data
= *src_data
;
1564 dst_data
->dsi
= NULL
;
1565 if( !src_data
->dsi
|| !src_data
->dsi
->payload
|| src_data
->dsi
->payload_length
== 0 )
1567 return lsmash_set_mp4sys_decoder_specific_info( dst_data
, src_data
->dsi
->payload
, src_data
->dsi
->payload_length
);
1570 lsmash_mp4sys_object_type_indication
lsmash_mp4sys_get_object_type_indication( lsmash_summary_t
*summary
)
1573 return MP4SYS_OBJECT_TYPE_Forbidden
;
1574 lsmash_codec_specific_t
*orig
= isom_get_codec_specific( summary
->opaque
, LSMASH_CODEC_SPECIFIC_DATA_TYPE_MP4SYS_DECODER_CONFIG
);
1576 return MP4SYS_OBJECT_TYPE_Forbidden
;
1577 /* Found decoder configuration.
1578 * Let's get objectTypeIndication. */
1579 lsmash_mp4sys_object_type_indication objectTypeIndication
;
1580 if( orig
->format
== LSMASH_CODEC_SPECIFIC_FORMAT_STRUCTURED
)
1581 objectTypeIndication
= ((lsmash_mp4sys_decoder_parameters_t
*)orig
->data
.structured
)->objectTypeIndication
;
1584 lsmash_codec_specific_t
*conv
= lsmash_convert_codec_specific_format( orig
, LSMASH_CODEC_SPECIFIC_FORMAT_STRUCTURED
);
1586 return MP4SYS_OBJECT_TYPE_Forbidden
;
1587 objectTypeIndication
= ((lsmash_mp4sys_decoder_parameters_t
*)conv
->data
.structured
)->objectTypeIndication
;
1588 lsmash_destroy_codec_specific_data( conv
);
1590 return objectTypeIndication
;
1593 int lsmash_get_mp4sys_decoder_specific_info( lsmash_mp4sys_decoder_parameters_t
*param
, uint8_t **payload
, uint32_t *payload_length
)
1595 if( !param
|| !payload
|| !payload_length
)
1596 return LSMASH_ERR_FUNCTION_PARAM
;
1597 if( !param
->dsi
|| !param
->dsi
->payload
|| param
->dsi
->payload_length
== 0 )
1600 *payload_length
= 0;
1603 uint8_t *temp
= lsmash_memdup( param
->dsi
->payload
, param
->dsi
->payload_length
);
1605 return LSMASH_ERR_MEMORY_ALLOC
;
1607 *payload_length
= param
->dsi
->payload_length
;