1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2010-2015 L-SMASH project
6 * Authors: Yusuke Nakamura <muken.the.vfrmaniac@gmail.com>
8 * Permission to use, copy, modify, and/or distribute this software for any
9 * purpose with or without fee is hereby granted, provided that the above
10 * copyright notice and this permission notice appear in all copies.
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 *****************************************************************************/
21 /* This file is available under an ISC license. */
23 #include "common/internal.h" /* must be placed first */
32 #include "codecs/mp4a.h"
33 #include "codecs/mp4sys.h"
34 #include "codecs/description.h"
36 static int isom_write_children( lsmash_bs_t
*bs
, isom_box_t
*box
)
38 for( lsmash_entry_t
*entry
= box
->extensions
.head
; entry
; entry
= entry
->next
)
40 isom_box_t
*child
= (isom_box_t
*)entry
->data
;
43 int ret
= isom_write_box( bs
, child
);
50 static int isom_write_binary_coded_box( lsmash_bs_t
*bs
, isom_box_t
*box
)
52 lsmash_bs_put_bytes( bs
, box
->size
, box
->binary
);
56 static int isom_write_unknown_box( lsmash_bs_t
*bs
, isom_box_t
*box
)
58 isom_unknown_box_t
*unknown_box
= (isom_unknown_box_t
*)box
;
59 isom_bs_put_box_common( bs
, unknown_box
);
60 if( unknown_box
->unknown_field
61 && unknown_box
->unknown_size
)
62 lsmash_bs_put_bytes( bs
, unknown_box
->unknown_size
, unknown_box
->unknown_field
);
66 static void isom_bs_put_qt_color_table( lsmash_bs_t
*bs
, isom_qt_color_table_t
*color_table
)
68 lsmash_bs_put_be32( bs
, color_table
->seed
);
69 lsmash_bs_put_be16( bs
, color_table
->flags
);
70 lsmash_bs_put_be16( bs
, color_table
->size
);
71 isom_qt_color_array_t
*array
= color_table
->array
;
73 for( uint16_t i
= 0; i
<= color_table
->size
; i
++ )
75 lsmash_bs_put_be16( bs
, array
[i
].value
);
76 lsmash_bs_put_be16( bs
, array
[i
].r
);
77 lsmash_bs_put_be16( bs
, array
[i
].g
);
78 lsmash_bs_put_be16( bs
, array
[i
].b
);
82 static int isom_write_ctab( lsmash_bs_t
*bs
, isom_box_t
*box
)
84 isom_ctab_t
*ctab
= (isom_ctab_t
*)box
;
85 isom_bs_put_box_common( bs
, ctab
);
86 isom_bs_put_qt_color_table( bs
, &ctab
->color_table
);
90 static int isom_write_tkhd( lsmash_bs_t
*bs
, isom_box_t
*box
)
92 isom_tkhd_t
*tkhd
= (isom_tkhd_t
*)box
;
93 /* Check the version. */
94 if( (tkhd
->file
&& !tkhd
->file
->undefined_64_ver
)
95 && (tkhd
->creation_time
> UINT32_MAX
96 || tkhd
->modification_time
> UINT32_MAX
97 || tkhd
->duration
> UINT32_MAX
) )
102 isom_bs_put_box_common( bs
, tkhd
);
105 lsmash_bs_put_be64( bs
, tkhd
->creation_time
);
106 lsmash_bs_put_be64( bs
, tkhd
->modification_time
);
107 lsmash_bs_put_be32( bs
, tkhd
->track_ID
);
108 lsmash_bs_put_be32( bs
, tkhd
->reserved1
);
109 lsmash_bs_put_be64( bs
, tkhd
->duration
);
113 lsmash_bs_put_be32( bs
, LSMASH_MIN( tkhd
->creation_time
, UINT32_MAX
) );
114 lsmash_bs_put_be32( bs
, LSMASH_MIN( tkhd
->modification_time
, UINT32_MAX
) );
115 lsmash_bs_put_be32( bs
, tkhd
->track_ID
);
116 lsmash_bs_put_be32( bs
, tkhd
->reserved1
);
117 lsmash_bs_put_be32( bs
, LSMASH_MIN( tkhd
->duration
, UINT32_MAX
) );
119 lsmash_bs_put_be32( bs
, tkhd
->reserved2
[0] );
120 lsmash_bs_put_be32( bs
, tkhd
->reserved2
[1] );
121 lsmash_bs_put_be16( bs
, tkhd
->layer
);
122 lsmash_bs_put_be16( bs
, tkhd
->alternate_group
);
123 lsmash_bs_put_be16( bs
, tkhd
->volume
);
124 lsmash_bs_put_be16( bs
, tkhd
->reserved3
);
125 for( uint32_t i
= 0; i
< 9; i
++ )
126 lsmash_bs_put_be32( bs
, tkhd
->matrix
[i
] );
127 lsmash_bs_put_be32( bs
, tkhd
->width
);
128 lsmash_bs_put_be32( bs
, tkhd
->height
);
132 static int isom_write_clef( lsmash_bs_t
*bs
, isom_box_t
*box
)
134 isom_clef_t
*clef
= (isom_clef_t
*)box
;
135 isom_bs_put_box_common( bs
, clef
);
136 lsmash_bs_put_be32( bs
, clef
->width
);
137 lsmash_bs_put_be32( bs
, clef
->height
);
141 static int isom_write_prof( lsmash_bs_t
*bs
, isom_box_t
*box
)
143 isom_prof_t
*prof
= (isom_prof_t
*)box
;
144 isom_bs_put_box_common( bs
, prof
);
145 lsmash_bs_put_be32( bs
, prof
->width
);
146 lsmash_bs_put_be32( bs
, prof
->height
);
150 static int isom_write_enof( lsmash_bs_t
*bs
, isom_box_t
*box
)
152 isom_enof_t
*enof
= (isom_enof_t
*)box
;
153 isom_bs_put_box_common( bs
, enof
);
154 lsmash_bs_put_be32( bs
, enof
->width
);
155 lsmash_bs_put_be32( bs
, enof
->height
);
159 static int isom_write_tapt( lsmash_bs_t
*bs
, isom_box_t
*box
)
161 isom_bs_put_box_common( bs
, box
);
165 static int isom_write_elst( lsmash_bs_t
*bs
, isom_box_t
*box
)
167 isom_elst_t
*elst
= (isom_elst_t
*)box
;
168 assert( elst
->list
);
169 if( elst
->list
->entry_count
== 0 )
174 /* Check the version. */
175 if( !elst
->file
->undefined_64_ver
)
176 for( lsmash_entry_t
*entry
= elst
->list
->head
; entry
; entry
= entry
->next
)
178 isom_elst_entry_t
*data
= (isom_elst_entry_t
*)entry
->data
;
180 return LSMASH_ERR_NAMELESS
;
181 if( data
->segment_duration
> UINT32_MAX
182 || data
->media_time
> INT32_MAX
183 || data
->media_time
< INT32_MIN
)
186 /* Remember to rewrite entries. */
187 if( elst
->file
->fragment
&& !elst
->file
->bs
->unseekable
)
188 elst
->pos
= elst
->file
->bs
->written
;
191 isom_bs_put_box_common( bs
, elst
);
192 lsmash_bs_put_be32( bs
, elst
->list
->entry_count
);
193 for( lsmash_entry_t
*entry
= elst
->list
->head
; entry
; entry
= entry
->next
)
195 isom_elst_entry_t
*data
= (isom_elst_entry_t
*)entry
->data
;
198 lsmash_bs_put_be64( bs
, data
->segment_duration
);
199 lsmash_bs_put_be64( bs
, data
->media_time
);
203 lsmash_bs_put_be32( bs
, LSMASH_MIN( data
->segment_duration
, UINT32_MAX
) );
204 lsmash_bs_put_be32( bs
, data
->media_time
< 0 ? (uint32_t)data
->media_time
: LSMASH_MIN( data
->media_time
, INT32_MAX
) );
206 lsmash_bs_put_be32( bs
, data
->media_rate
);
211 static int isom_write_edts( lsmash_bs_t
*bs
, isom_box_t
*box
)
213 isom_bs_put_box_common( bs
, box
);
217 static int isom_write_tref( lsmash_bs_t
*bs
, isom_box_t
*box
)
219 isom_bs_put_box_common( bs
, box
);
223 static int isom_write_track_reference_type( lsmash_bs_t
*bs
, isom_box_t
*box
)
225 isom_tref_type_t
*ref
= (isom_tref_type_t
*)box
;
226 isom_bs_put_box_common( bs
, ref
);
227 for( uint32_t i
= 0; i
< ref
->ref_count
; i
++ )
228 lsmash_bs_put_be32( bs
, ref
->track_ID
[i
] );
232 static int isom_write_mdhd( lsmash_bs_t
*bs
, isom_box_t
*box
)
234 isom_mdhd_t
*mdhd
= (isom_mdhd_t
*)box
;
235 /* Check the version. */
236 if( (mdhd
->file
&& !mdhd
->file
->undefined_64_ver
)
237 && (mdhd
->creation_time
> UINT32_MAX
238 || mdhd
->modification_time
> UINT32_MAX
239 || mdhd
->duration
> UINT32_MAX
) )
244 isom_bs_put_box_common( bs
, mdhd
);
247 lsmash_bs_put_be64( bs
, mdhd
->creation_time
);
248 lsmash_bs_put_be64( bs
, mdhd
->modification_time
);
249 lsmash_bs_put_be32( bs
, mdhd
->timescale
);
250 lsmash_bs_put_be64( bs
, mdhd
->duration
);
254 lsmash_bs_put_be32( bs
, LSMASH_MIN( mdhd
->creation_time
, UINT32_MAX
) );
255 lsmash_bs_put_be32( bs
, LSMASH_MIN( mdhd
->modification_time
, UINT32_MAX
) );
256 lsmash_bs_put_be32( bs
, mdhd
->timescale
);
257 lsmash_bs_put_be32( bs
, LSMASH_MIN( mdhd
->duration
, UINT32_MAX
) );
259 lsmash_bs_put_be16( bs
, mdhd
->language
);
260 lsmash_bs_put_be16( bs
, mdhd
->quality
);
264 static int isom_write_hdlr( lsmash_bs_t
*bs
, isom_box_t
*box
)
266 isom_hdlr_t
*hdlr
= (isom_hdlr_t
*)box
;
267 isom_bs_put_box_common( bs
, hdlr
);
268 lsmash_bs_put_be32( bs
, hdlr
->componentType
);
269 lsmash_bs_put_be32( bs
, hdlr
->componentSubtype
);
270 lsmash_bs_put_be32( bs
, hdlr
->componentManufacturer
);
271 lsmash_bs_put_be32( bs
, hdlr
->componentFlags
);
272 lsmash_bs_put_be32( bs
, hdlr
->componentFlagsMask
);
273 lsmash_bs_put_bytes( bs
, hdlr
->componentName_length
, hdlr
->componentName
);
277 static int isom_write_vmhd( lsmash_bs_t
*bs
, isom_box_t
*box
)
279 isom_vmhd_t
*vmhd
= (isom_vmhd_t
*)box
;
280 isom_bs_put_box_common( bs
, vmhd
);
281 lsmash_bs_put_be16( bs
, vmhd
->graphicsmode
);
282 for( uint32_t i
= 0; i
< 3; i
++ )
283 lsmash_bs_put_be16( bs
, vmhd
->opcolor
[i
] );
287 static int isom_write_smhd( lsmash_bs_t
*bs
, isom_box_t
*box
)
289 isom_smhd_t
*smhd
= (isom_smhd_t
*)box
;
290 isom_bs_put_box_common( bs
, smhd
);
291 lsmash_bs_put_be16( bs
, smhd
->balance
);
292 lsmash_bs_put_be16( bs
, smhd
->reserved
);
296 static int isom_write_hmhd( lsmash_bs_t
*bs
, isom_box_t
*box
)
298 isom_hmhd_t
*hmhd
= (isom_hmhd_t
*)box
;
299 isom_bs_put_box_common( bs
, hmhd
);
300 lsmash_bs_put_be16( bs
, hmhd
->maxPDUsize
);
301 lsmash_bs_put_be16( bs
, hmhd
->avgPDUsize
);
302 lsmash_bs_put_be32( bs
, hmhd
->maxbitrate
);
303 lsmash_bs_put_be32( bs
, hmhd
->avgbitrate
);
304 lsmash_bs_put_be32( bs
, hmhd
->reserved
);
308 static int isom_write_nmhd( lsmash_bs_t
*bs
, isom_box_t
*box
)
310 isom_nmhd_t
*nmhd
= (isom_nmhd_t
*)box
;
311 isom_bs_put_box_common( bs
, nmhd
);
315 static int isom_write_gmin( lsmash_bs_t
*bs
, isom_box_t
*box
)
317 isom_gmin_t
*gmin
= (isom_gmin_t
*)box
;
318 isom_bs_put_box_common( bs
, gmin
);
319 lsmash_bs_put_be16( bs
, gmin
->graphicsmode
);
320 for( uint32_t i
= 0; i
< 3; i
++ )
321 lsmash_bs_put_be16( bs
, gmin
->opcolor
[i
] );
322 lsmash_bs_put_be16( bs
, gmin
->balance
);
323 lsmash_bs_put_be16( bs
, gmin
->reserved
);
327 static int isom_write_text( lsmash_bs_t
*bs
, isom_box_t
*box
)
329 isom_text_t
*text
= (isom_text_t
*)box
;
330 isom_bs_put_box_common( bs
, text
);
331 for( uint32_t i
= 0; i
< 9; i
++ )
332 lsmash_bs_put_be32( bs
, text
->matrix
[i
] );
336 static int isom_write_gmhd( lsmash_bs_t
*bs
, isom_box_t
*box
)
338 isom_bs_put_box_common( bs
, box
);
342 static int isom_write_dref( lsmash_bs_t
*bs
, isom_box_t
*box
)
344 isom_dref_t
*dref
= (isom_dref_t
*)box
;
345 isom_bs_put_box_common( bs
, dref
);
346 lsmash_bs_put_be32( bs
, dref
->list
.entry_count
);
350 static int isom_write_url( lsmash_bs_t
*bs
, isom_box_t
*box
)
352 isom_dref_entry_t
*url
= (isom_dref_entry_t
*)box
;
353 isom_bs_put_box_common( bs
, url
);
354 lsmash_bs_put_bytes( bs
, url
->location_length
, url
->location
);
358 static int isom_write_dinf( lsmash_bs_t
*bs
, isom_box_t
*box
)
360 isom_bs_put_box_common( bs
, box
);
364 static int isom_write_pasp( lsmash_bs_t
*bs
, isom_box_t
*box
)
366 isom_pasp_t
*pasp
= (isom_pasp_t
*)box
;
367 isom_bs_put_box_common( bs
, pasp
);
368 lsmash_bs_put_be32( bs
, pasp
->hSpacing
);
369 lsmash_bs_put_be32( bs
, pasp
->vSpacing
);
373 static int isom_write_clap( lsmash_bs_t
*bs
, isom_box_t
*box
)
375 isom_clap_t
*clap
= (isom_clap_t
*)box
;
376 isom_bs_put_box_common( bs
, clap
);
377 lsmash_bs_put_be32( bs
, clap
->cleanApertureWidthN
);
378 lsmash_bs_put_be32( bs
, clap
->cleanApertureWidthD
);
379 lsmash_bs_put_be32( bs
, clap
->cleanApertureHeightN
);
380 lsmash_bs_put_be32( bs
, clap
->cleanApertureHeightD
);
381 lsmash_bs_put_be32( bs
, clap
->horizOffN
);
382 lsmash_bs_put_be32( bs
, clap
->horizOffD
);
383 lsmash_bs_put_be32( bs
, clap
->vertOffN
);
384 lsmash_bs_put_be32( bs
, clap
->vertOffD
);
388 static int isom_write_colr( lsmash_bs_t
*bs
, isom_box_t
*box
)
390 isom_colr_t
*colr
= (isom_colr_t
*)box
;
391 if( colr
->color_parameter_type
!= ISOM_COLOR_PARAMETER_TYPE_NCLX
392 && colr
->color_parameter_type
!= QT_COLOR_PARAMETER_TYPE_NCLC
)
394 isom_bs_put_box_common( bs
, colr
);
395 lsmash_bs_put_be32( bs
, colr
->color_parameter_type
);
396 lsmash_bs_put_be16( bs
, colr
->primaries_index
);
397 lsmash_bs_put_be16( bs
, colr
->transfer_function_index
);
398 lsmash_bs_put_be16( bs
, colr
->matrix_index
);
399 if( colr
->color_parameter_type
== ISOM_COLOR_PARAMETER_TYPE_NCLX
)
400 lsmash_bs_put_byte( bs
, (colr
->full_range_flag
<< 7) | colr
->reserved
);
404 static int isom_write_gama( lsmash_bs_t
*bs
, isom_box_t
*box
)
406 isom_gama_t
*gama
= (isom_gama_t
*)box
;
409 /* Note: 'gama' box is superseded by 'colr' box.
410 * Therefore, writers of QTFF should never write both 'colr' and 'gama' box into an Image Description. */
411 if( isom_get_extension_box_format( &((isom_visual_entry_t
*)gama
->parent
)->extensions
, QT_BOX_TYPE_COLR
) )
413 isom_bs_put_box_common( bs
, gama
);
414 lsmash_bs_put_be32( bs
, gama
->level
);
418 static int isom_write_fiel( lsmash_bs_t
*bs
, isom_box_t
*box
)
420 isom_fiel_t
*fiel
= (isom_fiel_t
*)box
;
421 isom_bs_put_box_common( bs
, fiel
);
422 lsmash_bs_put_byte( bs
, fiel
->fields
);
423 lsmash_bs_put_byte( bs
, fiel
->detail
);
427 static int isom_write_cspc( lsmash_bs_t
*bs
, isom_box_t
*box
)
429 isom_cspc_t
*cspc
= (isom_cspc_t
*)box
;
430 isom_bs_put_box_common( bs
, cspc
);
431 lsmash_bs_put_be32( bs
, cspc
->pixel_format
);
435 static int isom_write_sgbt( lsmash_bs_t
*bs
, isom_box_t
*box
)
437 isom_sgbt_t
*sgbt
= (isom_sgbt_t
*)box
;
438 isom_bs_put_box_common( bs
, sgbt
);
439 lsmash_bs_put_byte( bs
, sgbt
->significantBits
);
443 static int isom_write_stsl( lsmash_bs_t
*bs
, isom_box_t
*box
)
445 isom_stsl_t
*stsl
= (isom_stsl_t
*)box
;
446 isom_bs_put_box_common( bs
, stsl
);
447 lsmash_bs_put_byte( bs
, stsl
->constraint_flag
);
448 lsmash_bs_put_byte( bs
, stsl
->scale_method
);
449 lsmash_bs_put_be16( bs
, stsl
->display_center_x
);
450 lsmash_bs_put_be16( bs
, stsl
->display_center_y
);
454 static int isom_write_esds( lsmash_bs_t
*bs
, isom_box_t
*box
)
456 isom_esds_t
*esds
= (isom_esds_t
*)box
;
457 isom_bs_put_box_common( bs
, esds
);
458 mp4sys_update_descriptor_size( esds
->ES
);
459 return mp4sys_write_descriptor( bs
, esds
->ES
);
462 static int isom_write_btrt( lsmash_bs_t
*bs
, isom_box_t
*box
)
464 isom_btrt_t
*btrt
= (isom_btrt_t
*)box
;
465 isom_bs_put_box_common( bs
, btrt
);
466 lsmash_bs_put_be32( bs
, btrt
->bufferSizeDB
);
467 lsmash_bs_put_be32( bs
, btrt
->maxBitrate
);
468 lsmash_bs_put_be32( bs
, btrt
->avgBitrate
);
472 static int isom_write_glbl( lsmash_bs_t
*bs
, isom_box_t
*box
)
474 isom_glbl_t
*glbl
= (isom_glbl_t
*)box
;
475 isom_bs_put_box_common( bs
, glbl
);
476 if( glbl
->header_data
&& glbl
->header_size
)
477 lsmash_bs_put_bytes( bs
, glbl
->header_size
, glbl
->header_data
);
481 static int isom_write_frma( lsmash_bs_t
*bs
, isom_box_t
*box
)
483 isom_frma_t
*frma
= (isom_frma_t
*)box
;
484 isom_bs_put_box_common( bs
, frma
);
485 lsmash_bs_put_be32( bs
, frma
->data_format
);
489 static int isom_write_enda( lsmash_bs_t
*bs
, isom_box_t
*box
)
491 isom_enda_t
*enda
= (isom_enda_t
*)box
;
492 isom_bs_put_box_common( bs
, enda
);
493 lsmash_bs_put_be16( bs
, enda
->littleEndian
);
497 static int isom_write_mp4a( lsmash_bs_t
*bs
, isom_box_t
*box
)
499 isom_mp4a_t
*mp4a
= (isom_mp4a_t
*)box
;
500 isom_bs_put_box_common( bs
, mp4a
);
501 lsmash_bs_put_be32( bs
, mp4a
->unknown
);
505 static int isom_write_chan( lsmash_bs_t
*bs
, isom_box_t
*box
)
507 isom_chan_t
*chan
= (isom_chan_t
*)box
;
508 isom_bs_put_box_common( bs
, chan
);
509 lsmash_bs_put_be32( bs
, chan
->channelLayoutTag
);
510 lsmash_bs_put_be32( bs
, chan
->channelBitmap
);
511 lsmash_bs_put_be32( bs
, chan
->numberChannelDescriptions
);
512 if( chan
->channelDescriptions
)
513 for( uint32_t i
= 0; i
< chan
->numberChannelDescriptions
; i
++ )
515 isom_channel_description_t
*channelDescriptions
= (isom_channel_description_t
*)(&chan
->channelDescriptions
[i
]);
516 lsmash_bs_put_be32( bs
, channelDescriptions
->channelLabel
);
517 lsmash_bs_put_be32( bs
, channelDescriptions
->channelFlags
);
518 lsmash_bs_put_be32( bs
, channelDescriptions
->coordinates
[0] );
519 lsmash_bs_put_be32( bs
, channelDescriptions
->coordinates
[1] );
520 lsmash_bs_put_be32( bs
, channelDescriptions
->coordinates
[2] );
525 static int isom_write_terminator( lsmash_bs_t
*bs
, isom_box_t
*box
)
527 isom_bs_put_box_common( bs
, box
);
531 static int isom_write_wave( lsmash_bs_t
*bs
, isom_box_t
*box
)
533 isom_bs_put_box_common( bs
, box
);
537 static int isom_write_visual_description( lsmash_bs_t
*bs
, isom_box_t
*box
)
539 isom_visual_entry_t
*data
= (isom_visual_entry_t
*)box
;
541 return LSMASH_ERR_NAMELESS
;
542 isom_bs_put_box_common( bs
, data
);
543 lsmash_bs_put_bytes( bs
, 6, data
->reserved
);
544 lsmash_bs_put_be16( bs
, data
->data_reference_index
);
545 lsmash_bs_put_be16( bs
, data
->version
);
546 lsmash_bs_put_be16( bs
, data
->revision_level
);
547 lsmash_bs_put_be32( bs
, data
->vendor
);
548 lsmash_bs_put_be32( bs
, data
->temporalQuality
);
549 lsmash_bs_put_be32( bs
, data
->spatialQuality
);
550 lsmash_bs_put_be16( bs
, data
->width
);
551 lsmash_bs_put_be16( bs
, data
->height
);
552 lsmash_bs_put_be32( bs
, data
->horizresolution
);
553 lsmash_bs_put_be32( bs
, data
->vertresolution
);
554 lsmash_bs_put_be32( bs
, data
->dataSize
);
555 lsmash_bs_put_be16( bs
, data
->frame_count
);
556 lsmash_bs_put_bytes( bs
, 32, data
->compressorname
);
557 lsmash_bs_put_be16( bs
, data
->depth
);
558 lsmash_bs_put_be16( bs
, data
->color_table_ID
);
559 if( data
->color_table_ID
== 0 )
560 isom_bs_put_qt_color_table( bs
, &data
->color_table
);
564 static int isom_write_audio_description( lsmash_bs_t
*bs
, isom_box_t
*box
)
566 isom_audio_entry_t
*data
= (isom_audio_entry_t
*)box
;
568 return LSMASH_ERR_NAMELESS
;
569 isom_bs_put_box_common( bs
, data
);
570 lsmash_bs_put_bytes( bs
, 6, data
->reserved
);
571 lsmash_bs_put_be16( bs
, data
->data_reference_index
);
572 lsmash_bs_put_be16( bs
, data
->version
);
573 lsmash_bs_put_be16( bs
, data
->revision_level
);
574 lsmash_bs_put_be32( bs
, data
->vendor
);
575 lsmash_bs_put_be16( bs
, data
->channelcount
);
576 lsmash_bs_put_be16( bs
, data
->samplesize
);
577 lsmash_bs_put_be16( bs
, data
->compression_ID
);
578 lsmash_bs_put_be16( bs
, data
->packet_size
);
579 lsmash_bs_put_be32( bs
, data
->samplerate
);
580 if( data
->version
== 1 )
582 lsmash_bs_put_be32( bs
, data
->samplesPerPacket
);
583 lsmash_bs_put_be32( bs
, data
->bytesPerPacket
);
584 lsmash_bs_put_be32( bs
, data
->bytesPerFrame
);
585 lsmash_bs_put_be32( bs
, data
->bytesPerSample
);
587 else if( data
->version
== 2 )
589 lsmash_bs_put_be32( bs
, data
->sizeOfStructOnly
);
590 lsmash_bs_put_be64( bs
, data
->audioSampleRate
);
591 lsmash_bs_put_be32( bs
, data
->numAudioChannels
);
592 lsmash_bs_put_be32( bs
, data
->always7F000000
);
593 lsmash_bs_put_be32( bs
, data
->constBitsPerChannel
);
594 lsmash_bs_put_be32( bs
, data
->formatSpecificFlags
);
595 lsmash_bs_put_be32( bs
, data
->constBytesPerAudioPacket
);
596 lsmash_bs_put_be32( bs
, data
->constLPCMFramesPerAudioPacket
);
602 static int isom_write_hint_description( lsmash_bs_t
*bs
, lsmash_entry_t
*entry
)
604 isom_hint_entry_t
*data
= (isom_hint_entry_t
*)entry
->data
;
606 return LSMASH_ERR_NAMELESS
;
607 isom_bs_put_box_common( bs
, data
);
608 lsmash_bs_put_bytes( bs
, 6, data
->reserved
);
609 lsmash_bs_put_be16( bs
, data
->data_reference_index
);
610 if( data
->data
&& data
->data_length
)
611 lsmash_bs_put_bytes( bs
, data
->data_length
, data
->data
);
615 static int isom_write_metadata_description( lsmash_bs_t
*bs
, lsmash_entry_t
*entry
)
617 isom_metadata_entry_t
*data
= (isom_metadata_entry_t
*)entry
->data
;
619 return LSMASH_ERR_NAMELESS
;
620 isom_bs_put_box_common( bs
, data
);
621 lsmash_bs_put_bytes( bs
, 6, data
->reserved
);
622 lsmash_bs_put_be16( bs
, data
->data_reference_index
);
627 static int isom_write_qt_text_description( lsmash_bs_t
*bs
, isom_box_t
*box
)
629 isom_qt_text_entry_t
*data
= (isom_qt_text_entry_t
*)box
;
631 return LSMASH_ERR_NAMELESS
;
632 isom_bs_put_box_common( bs
, data
);
633 lsmash_bs_put_bytes( bs
, 6, data
->reserved
);
634 lsmash_bs_put_be16( bs
, data
->data_reference_index
);
635 lsmash_bs_put_be32( bs
, data
->displayFlags
);
636 lsmash_bs_put_be32( bs
, data
->textJustification
);
637 for( uint32_t i
= 0; i
< 3; i
++ )
638 lsmash_bs_put_be16( bs
, data
->bgColor
[i
] );
639 lsmash_bs_put_be16( bs
, data
->top
);
640 lsmash_bs_put_be16( bs
, data
->left
);
641 lsmash_bs_put_be16( bs
, data
->bottom
);
642 lsmash_bs_put_be16( bs
, data
->right
);
643 lsmash_bs_put_be32( bs
, data
->scrpStartChar
);
644 lsmash_bs_put_be16( bs
, data
->scrpHeight
);
645 lsmash_bs_put_be16( bs
, data
->scrpAscent
);
646 lsmash_bs_put_be16( bs
, data
->scrpFont
);
647 lsmash_bs_put_be16( bs
, data
->scrpFace
);
648 lsmash_bs_put_be16( bs
, data
->scrpSize
);
649 for( uint32_t i
= 0; i
< 3; i
++ )
650 lsmash_bs_put_be16( bs
, data
->scrpColor
[i
] );
651 lsmash_bs_put_byte( bs
, data
->font_name_length
);
652 if( data
->font_name
&& data
->font_name_length
)
653 lsmash_bs_put_bytes( bs
, data
->font_name_length
, data
->font_name
);
657 static int isom_write_ftab( lsmash_bs_t
*bs
, isom_box_t
*box
)
659 isom_ftab_t
*ftab
= (isom_ftab_t
*)box
;
660 assert( ftab
->list
);
661 isom_bs_put_box_common( bs
, ftab
);
662 lsmash_bs_put_be16( bs
, ftab
->list
->entry_count
);
663 for( lsmash_entry_t
*entry
= ftab
->list
->head
; entry
; entry
= entry
->next
)
665 isom_font_record_t
*data
= (isom_font_record_t
*)entry
->data
;
667 return LSMASH_ERR_NAMELESS
;
668 lsmash_bs_put_be16( bs
, data
->font_ID
);
669 lsmash_bs_put_byte( bs
, data
->font_name_length
);
670 if( data
->font_name
&& data
->font_name_length
)
671 lsmash_bs_put_bytes( bs
, data
->font_name_length
, data
->font_name
);
676 static int isom_write_tx3g_description( lsmash_bs_t
*bs
, isom_box_t
*box
)
678 isom_tx3g_entry_t
*data
= (isom_tx3g_entry_t
*)box
;
680 return LSMASH_ERR_NAMELESS
;
681 isom_bs_put_box_common( bs
, data
);
682 lsmash_bs_put_bytes( bs
, 6, data
->reserved
);
683 lsmash_bs_put_be16( bs
, data
->data_reference_index
);
684 lsmash_bs_put_be32( bs
, data
->displayFlags
);
685 lsmash_bs_put_byte( bs
, data
->horizontal_justification
);
686 lsmash_bs_put_byte( bs
, data
->vertical_justification
);
687 for( uint32_t i
= 0; i
< 4; i
++ )
688 lsmash_bs_put_byte( bs
, data
->background_color_rgba
[i
] );
689 lsmash_bs_put_be16( bs
, data
->top
);
690 lsmash_bs_put_be16( bs
, data
->left
);
691 lsmash_bs_put_be16( bs
, data
->bottom
);
692 lsmash_bs_put_be16( bs
, data
->right
);
693 lsmash_bs_put_be16( bs
, data
->startChar
);
694 lsmash_bs_put_be16( bs
, data
->endChar
);
695 lsmash_bs_put_be16( bs
, data
->font_ID
);
696 lsmash_bs_put_byte( bs
, data
->face_style_flags
);
697 lsmash_bs_put_byte( bs
, data
->font_size
);
698 for( uint32_t i
= 0; i
< 4; i
++ )
699 lsmash_bs_put_byte( bs
, data
->text_color_rgba
[i
] );
703 static int isom_write_stsd( lsmash_bs_t
*bs
, isom_box_t
*box
)
705 isom_stsd_t
*stsd
= (isom_stsd_t
*)box
;
706 isom_bs_put_box_common( bs
, stsd
);
707 lsmash_bs_put_be32( bs
, stsd
->list
.entry_count
);
711 static int isom_write_stts( lsmash_bs_t
*bs
, isom_box_t
*box
)
713 isom_stts_t
*stts
= (isom_stts_t
*)box
;
714 assert( stts
->list
);
715 isom_bs_put_box_common( bs
, stts
);
716 lsmash_bs_put_be32( bs
, stts
->list
->entry_count
);
717 for( lsmash_entry_t
*entry
= stts
->list
->head
; entry
; entry
= entry
->next
)
719 isom_stts_entry_t
*data
= (isom_stts_entry_t
*)entry
->data
;
721 return LSMASH_ERR_NAMELESS
;
722 lsmash_bs_put_be32( bs
, data
->sample_count
);
723 lsmash_bs_put_be32( bs
, data
->sample_delta
);
728 static int isom_write_ctts( lsmash_bs_t
*bs
, isom_box_t
*box
)
730 isom_ctts_t
*ctts
= (isom_ctts_t
*)box
;
731 assert( ctts
->list
);
732 isom_bs_put_box_common( bs
, ctts
);
733 lsmash_bs_put_be32( bs
, ctts
->list
->entry_count
);
734 for( lsmash_entry_t
*entry
= ctts
->list
->head
; entry
; entry
= entry
->next
)
736 isom_ctts_entry_t
*data
= (isom_ctts_entry_t
*)entry
->data
;
738 return LSMASH_ERR_NAMELESS
;
739 lsmash_bs_put_be32( bs
, data
->sample_count
);
740 lsmash_bs_put_be32( bs
, data
->sample_offset
);
745 static int isom_write_cslg( lsmash_bs_t
*bs
, isom_box_t
*box
)
747 isom_cslg_t
*cslg
= (isom_cslg_t
*)box
;
748 isom_bs_put_box_common( bs
, cslg
);
749 lsmash_bs_put_be32( bs
, cslg
->compositionToDTSShift
);
750 lsmash_bs_put_be32( bs
, cslg
->leastDecodeToDisplayDelta
);
751 lsmash_bs_put_be32( bs
, cslg
->greatestDecodeToDisplayDelta
);
752 lsmash_bs_put_be32( bs
, cslg
->compositionStartTime
);
753 lsmash_bs_put_be32( bs
, cslg
->compositionEndTime
);
757 static int isom_write_stsz( lsmash_bs_t
*bs
, isom_box_t
*box
)
759 isom_stsz_t
*stsz
= (isom_stsz_t
*)box
;
760 isom_bs_put_box_common( bs
, stsz
);
761 lsmash_bs_put_be32( bs
, stsz
->sample_size
);
762 lsmash_bs_put_be32( bs
, stsz
->sample_count
);
763 if( stsz
->sample_size
== 0 && stsz
->list
)
764 for( lsmash_entry_t
*entry
= stsz
->list
->head
; entry
; entry
= entry
->next
)
766 isom_stsz_entry_t
*data
= (isom_stsz_entry_t
*)entry
->data
;
768 return LSMASH_ERR_NAMELESS
;
769 lsmash_bs_put_be32( bs
, data
->entry_size
);
774 static int isom_write_stz2( lsmash_bs_t
*bs
, isom_box_t
*box
)
776 isom_stz2_t
*stz2
= (isom_stz2_t
*)box
;
777 isom_bs_put_box_common( bs
, stz2
);
778 lsmash_bs_put_be32( bs
, (stz2
->reserved
<< 8) | stz2
->field_size
);
779 lsmash_bs_put_be32( bs
, stz2
->sample_count
);
780 if( stz2
->field_size
== 16 )
781 for( lsmash_entry_t
*entry
= stz2
->list
->head
; entry
; entry
= entry
->next
)
783 isom_stsz_entry_t
*data
= (isom_stsz_entry_t
*)entry
->data
;
785 return LSMASH_ERR_NAMELESS
;
786 assert( data
->entry_size
<= 0xffff );
787 lsmash_bs_put_be16( bs
, data
->entry_size
);
789 else if( stz2
->field_size
== 8 )
790 for( lsmash_entry_t
*entry
= stz2
->list
->head
; entry
; entry
= entry
->next
)
792 isom_stsz_entry_t
*data
= (isom_stsz_entry_t
*)entry
->data
;
794 return LSMASH_ERR_NAMELESS
;
795 assert( data
->entry_size
<= 0xff );
796 lsmash_bs_put_byte( bs
, data
->entry_size
);
798 else if( stz2
->field_size
== 4 )
800 isom_stsz_entry_t zero_padding
= { .entry_size
= 0 };
801 for( lsmash_entry_t
*entry
= stz2
->list
->head
; entry
; entry
= entry
->next
? entry
->next
->next
: entry
->next
)
803 isom_stsz_entry_t
*data_o
= (isom_stsz_entry_t
*)entry
->data
;
804 isom_stsz_entry_t
*data_e
= (isom_stsz_entry_t
*)(entry
->next
? entry
->next
->data
: &zero_padding
);
805 if( !data_o
|| !data_e
)
806 return LSMASH_ERR_NAMELESS
;
807 assert( data_o
->entry_size
<= 0xf && data_e
->entry_size
<= 0xf );
808 lsmash_bs_put_byte( bs
, (data_o
->entry_size
<< 4) | data_e
->entry_size
);
812 return LSMASH_ERR_NAMELESS
;
816 static int isom_write_stss( lsmash_bs_t
*bs
, isom_box_t
*box
)
818 isom_stss_t
*stss
= (isom_stss_t
*)box
;
819 assert( stss
->list
);
820 isom_bs_put_box_common( bs
, stss
);
821 lsmash_bs_put_be32( bs
, stss
->list
->entry_count
);
822 for( lsmash_entry_t
*entry
= stss
->list
->head
; entry
; entry
= entry
->next
)
824 isom_stss_entry_t
*data
= (isom_stss_entry_t
*)entry
->data
;
826 return LSMASH_ERR_NAMELESS
;
827 lsmash_bs_put_be32( bs
, data
->sample_number
);
832 static int isom_write_stps( lsmash_bs_t
*bs
, isom_box_t
*box
)
834 isom_stps_t
*stps
= (isom_stps_t
*)box
;
835 assert( stps
->list
);
836 isom_bs_put_box_common( bs
, stps
);
837 lsmash_bs_put_be32( bs
, stps
->list
->entry_count
);
838 for( lsmash_entry_t
*entry
= stps
->list
->head
; entry
; entry
= entry
->next
)
840 isom_stps_entry_t
*data
= (isom_stps_entry_t
*)entry
->data
;
842 return LSMASH_ERR_NAMELESS
;
843 lsmash_bs_put_be32( bs
, data
->sample_number
);
848 static int isom_write_sdtp( lsmash_bs_t
*bs
, isom_box_t
*box
)
850 isom_sdtp_t
*sdtp
= (isom_sdtp_t
*)box
;
851 assert( sdtp
->list
);
852 isom_bs_put_box_common( bs
, sdtp
);
853 for( lsmash_entry_t
*entry
= sdtp
->list
->head
; entry
; entry
= entry
->next
)
855 isom_sdtp_entry_t
*data
= (isom_sdtp_entry_t
*)entry
->data
;
857 return LSMASH_ERR_NAMELESS
;
858 uint8_t temp
= (data
->is_leading
<< 6)
859 | (data
->sample_depends_on
<< 4)
860 | (data
->sample_is_depended_on
<< 2)
861 | data
->sample_has_redundancy
;
862 lsmash_bs_put_byte( bs
, temp
);
867 static int isom_write_stsc( lsmash_bs_t
*bs
, isom_box_t
*box
)
869 isom_stsc_t
*stsc
= (isom_stsc_t
*)box
;
870 assert( stsc
->list
);
871 isom_bs_put_box_common( bs
, stsc
);
872 lsmash_bs_put_be32( bs
, stsc
->list
->entry_count
);
873 for( lsmash_entry_t
*entry
= stsc
->list
->head
; entry
; entry
= entry
->next
)
875 isom_stsc_entry_t
*data
= (isom_stsc_entry_t
*)entry
->data
;
877 return LSMASH_ERR_NAMELESS
;
878 lsmash_bs_put_be32( bs
, data
->first_chunk
);
879 lsmash_bs_put_be32( bs
, data
->samples_per_chunk
);
880 lsmash_bs_put_be32( bs
, data
->sample_description_index
);
885 static int isom_write_co64( lsmash_bs_t
*bs
, isom_box_t
*box
)
887 isom_stco_t
*co64
= (isom_stco_t
*)box
;
888 assert( co64
->list
);
889 isom_bs_put_box_common( bs
, co64
);
890 lsmash_bs_put_be32( bs
, co64
->list
->entry_count
);
891 for( lsmash_entry_t
*entry
= co64
->list
->head
; entry
; entry
= entry
->next
)
893 isom_co64_entry_t
*data
= (isom_co64_entry_t
*)entry
->data
;
895 return LSMASH_ERR_NAMELESS
;
896 lsmash_bs_put_be64( bs
, data
->chunk_offset
);
901 static int isom_write_stco( lsmash_bs_t
*bs
, isom_box_t
*box
)
903 isom_stco_t
*stco
= (isom_stco_t
*)box
;
904 if( stco
->large_presentation
)
905 return isom_write_co64( bs
, box
);
906 assert( stco
->list
);
907 isom_bs_put_box_common( bs
, stco
);
908 lsmash_bs_put_be32( bs
, stco
->list
->entry_count
);
909 for( lsmash_entry_t
*entry
= stco
->list
->head
; entry
; entry
= entry
->next
)
911 isom_stco_entry_t
*data
= (isom_stco_entry_t
*)entry
->data
;
913 return LSMASH_ERR_NAMELESS
;
914 lsmash_bs_put_be32( bs
, data
->chunk_offset
);
919 static int isom_write_sgpd( lsmash_bs_t
*bs
, isom_box_t
*box
)
921 isom_sgpd_t
*sgpd
= (isom_sgpd_t
*)box
;
922 assert( sgpd
->list
);
923 isom_bs_put_box_common( bs
, sgpd
);
924 lsmash_bs_put_be32( bs
, sgpd
->grouping_type
);
925 if( sgpd
->version
== 1 )
926 lsmash_bs_put_be32( bs
, sgpd
->default_length
);
927 lsmash_bs_put_be32( bs
, sgpd
->list
->entry_count
);
928 for( lsmash_entry_t
*entry
= sgpd
->list
->head
; entry
; entry
= entry
->next
)
931 return LSMASH_ERR_NAMELESS
;
932 switch( sgpd
->grouping_type
)
934 case ISOM_GROUP_TYPE_RAP
:
936 isom_rap_entry_t
*rap
= (isom_rap_entry_t
*)entry
->data
;
937 uint8_t temp
= (rap
->num_leading_samples_known
<< 7)
938 | rap
->num_leading_samples
;
939 lsmash_bs_put_byte( bs
, temp
);
942 case ISOM_GROUP_TYPE_ROLL
:
943 case ISOM_GROUP_TYPE_PROL
:
944 lsmash_bs_put_be16( bs
, ((isom_roll_entry_t
*)entry
->data
)->roll_distance
);
947 /* We don't consider other grouping types currently. */
948 // if( sgpd->version == 1 && !sgpd->default_length )
949 // lsmash_bs_put_be32( bs, ((isom_sgpd_t *)entry->data)->description_length );
956 static int isom_write_sbgp( lsmash_bs_t
*bs
, isom_box_t
*box
)
958 isom_sbgp_t
*sbgp
= (isom_sbgp_t
*)box
;
959 assert( sbgp
->list
);
960 isom_bs_put_box_common( bs
, sbgp
);
961 lsmash_bs_put_be32( bs
, sbgp
->grouping_type
);
962 if( sbgp
->version
== 1 )
963 lsmash_bs_put_be32( bs
, sbgp
->grouping_type_parameter
);
964 lsmash_bs_put_be32( bs
, sbgp
->list
->entry_count
);
965 for( lsmash_entry_t
*entry
= sbgp
->list
->head
; entry
; entry
= entry
->next
)
967 isom_group_assignment_entry_t
*data
= (isom_group_assignment_entry_t
*)entry
->data
;
969 return LSMASH_ERR_NAMELESS
;
970 lsmash_bs_put_be32( bs
, data
->sample_count
);
971 lsmash_bs_put_be32( bs
, data
->group_description_index
);
976 static int isom_write_stbl( lsmash_bs_t
*bs
, isom_box_t
*box
)
978 isom_bs_put_box_common( bs
, box
);
982 static int isom_write_minf( lsmash_bs_t
*bs
, isom_box_t
*box
)
984 isom_bs_put_box_common( bs
, box
);
988 static int isom_write_mdia( lsmash_bs_t
*bs
, isom_box_t
*box
)
990 isom_bs_put_box_common( bs
, box
);
994 static int isom_write_chpl( lsmash_bs_t
*bs
, isom_box_t
*box
)
996 isom_chpl_t
*chpl
= (isom_chpl_t
*)box
;
997 assert( chpl
->list
);
998 isom_bs_put_box_common( bs
, chpl
);
999 if( chpl
->version
== 1 )
1001 lsmash_bs_put_byte( bs
, chpl
->unknown
);
1002 lsmash_bs_put_be32( bs
, chpl
->list
->entry_count
);
1004 else /* chpl->version == 0 */
1005 lsmash_bs_put_byte( bs
, (uint8_t)chpl
->list
->entry_count
);
1006 for( lsmash_entry_t
*entry
= chpl
->list
->head
; entry
; entry
= entry
->next
)
1008 isom_chpl_entry_t
*data
= (isom_chpl_entry_t
*)entry
->data
;
1010 return LSMASH_ERR_NAMELESS
;
1011 lsmash_bs_put_be64( bs
, data
->start_time
);
1012 lsmash_bs_put_byte( bs
, data
->chapter_name_length
);
1013 lsmash_bs_put_bytes( bs
, data
->chapter_name_length
, data
->chapter_name
);
1018 static int isom_write_mean( lsmash_bs_t
*bs
, isom_box_t
*box
)
1020 isom_mean_t
*mean
= (isom_mean_t
*)box
;
1021 isom_bs_put_box_common( bs
, mean
);
1022 if( mean
->meaning_string
&& mean
->meaning_string_length
)
1023 lsmash_bs_put_bytes( bs
, mean
->meaning_string_length
, mean
->meaning_string
);
1027 static int isom_write_name( lsmash_bs_t
*bs
, isom_box_t
*box
)
1029 isom_name_t
*name
= (isom_name_t
*)box
;
1030 isom_bs_put_box_common( bs
, name
);
1031 if( name
->name
&& name
->name_length
)
1032 lsmash_bs_put_bytes( bs
, name
->name_length
, name
->name
);
1036 static int isom_write_data( lsmash_bs_t
*bs
, isom_box_t
*box
)
1038 isom_data_t
*data
= (isom_data_t
*)box
;
1039 isom_bs_put_box_common( bs
, data
);
1040 lsmash_bs_put_be16( bs
, data
->reserved
);
1041 lsmash_bs_put_byte( bs
, data
->type_set_identifier
);
1042 lsmash_bs_put_byte( bs
, data
->type_code
);
1043 lsmash_bs_put_be32( bs
, data
->the_locale
);
1044 if( data
->value
&& data
->value_length
)
1045 lsmash_bs_put_bytes( bs
, data
->value_length
, data
->value
);
1049 static int isom_write_metaitem( lsmash_bs_t
*bs
, isom_box_t
*box
)
1051 isom_bs_put_box_common( bs
, box
);
1055 static int isom_write_ilst( lsmash_bs_t
*bs
, isom_box_t
*box
)
1057 isom_bs_put_box_common( bs
, box
);
1061 static int isom_write_meta( lsmash_bs_t
*bs
, isom_box_t
*box
)
1063 isom_bs_put_box_common( bs
, box
);
1067 static int isom_write_cprt( lsmash_bs_t
*bs
, isom_box_t
*box
)
1069 isom_cprt_t
*cprt
= (isom_cprt_t
*)box
;
1070 isom_bs_put_box_common( bs
, cprt
);
1071 lsmash_bs_put_be16( bs
, cprt
->language
);
1072 lsmash_bs_put_bytes( bs
, cprt
->notice_length
, cprt
->notice
);
1076 static int isom_write_udta( lsmash_bs_t
*bs
, isom_box_t
*box
)
1078 isom_bs_put_box_common( bs
, box
);
1082 static int isom_write_trak( lsmash_bs_t
*bs
, isom_box_t
*box
)
1084 isom_bs_put_box_common( bs
, box
);
1088 static int isom_write_iods( lsmash_bs_t
*bs
, isom_box_t
*box
)
1090 isom_iods_t
*iods
= (isom_iods_t
*)box
;
1091 isom_bs_put_box_common( bs
, iods
);
1092 mp4sys_update_descriptor_size( iods
->OD
);
1093 return mp4sys_write_descriptor( bs
, iods
->OD
);
1096 static int isom_write_mvhd( lsmash_bs_t
*bs
, isom_box_t
*box
)
1098 isom_mvhd_t
*mvhd
= (isom_mvhd_t
*)box
;
1099 /* Check the version. */
1100 if( (mvhd
->file
&& !mvhd
->file
->undefined_64_ver
)
1101 && (mvhd
->creation_time
> UINT32_MAX
1102 || mvhd
->modification_time
> UINT32_MAX
1103 || mvhd
->duration
> UINT32_MAX
) )
1108 isom_bs_put_box_common( bs
, mvhd
);
1111 lsmash_bs_put_be64( bs
, mvhd
->creation_time
);
1112 lsmash_bs_put_be64( bs
, mvhd
->modification_time
);
1113 lsmash_bs_put_be32( bs
, mvhd
->timescale
);
1114 lsmash_bs_put_be64( bs
, mvhd
->duration
);
1118 lsmash_bs_put_be32( bs
, LSMASH_MIN( mvhd
->creation_time
, UINT32_MAX
) );
1119 lsmash_bs_put_be32( bs
, LSMASH_MIN( mvhd
->modification_time
, UINT32_MAX
) );
1120 lsmash_bs_put_be32( bs
, mvhd
->timescale
);
1121 lsmash_bs_put_be32( bs
, LSMASH_MIN( mvhd
->duration
, UINT32_MAX
) );
1123 lsmash_bs_put_be32( bs
, mvhd
->rate
);
1124 lsmash_bs_put_be16( bs
, mvhd
->volume
);
1125 lsmash_bs_put_be16( bs
, mvhd
->reserved
);
1126 lsmash_bs_put_be32( bs
, mvhd
->preferredLong
[0] );
1127 lsmash_bs_put_be32( bs
, mvhd
->preferredLong
[1] );
1128 for( int i
= 0; i
< 9; i
++ )
1129 lsmash_bs_put_be32( bs
, mvhd
->matrix
[i
] );
1130 lsmash_bs_put_be32( bs
, mvhd
->previewTime
);
1131 lsmash_bs_put_be32( bs
, mvhd
->previewDuration
);
1132 lsmash_bs_put_be32( bs
, mvhd
->posterTime
);
1133 lsmash_bs_put_be32( bs
, mvhd
->selectionTime
);
1134 lsmash_bs_put_be32( bs
, mvhd
->selectionDuration
);
1135 lsmash_bs_put_be32( bs
, mvhd
->currentTime
);
1136 lsmash_bs_put_be32( bs
, mvhd
->next_track_ID
);
1140 static void isom_bs_put_sample_flags( lsmash_bs_t
*bs
, isom_sample_flags_t
*flags
)
1142 uint32_t temp
= (flags
->reserved
<< 28)
1143 | (flags
->is_leading
<< 26)
1144 | (flags
->sample_depends_on
<< 24)
1145 | (flags
->sample_is_depended_on
<< 22)
1146 | (flags
->sample_has_redundancy
<< 20)
1147 | (flags
->sample_padding_value
<< 17)
1148 | (flags
->sample_is_non_sync_sample
<< 16)
1149 | flags
->sample_degradation_priority
;
1150 lsmash_bs_put_be32( bs
, temp
);
1153 static int isom_write_mehd( lsmash_bs_t
*bs
, isom_box_t
*box
)
1155 if( box
->manager
& LSMASH_PLACEHOLDER
)
1157 /* Movie Extends Header Box is not written immediately.
1158 * It's done after finishing all movie fragments.
1159 * The following will be overwritten by Movie Extends Header Box.
1160 * We use version 1 Movie Extends Header Box since it causes extra 4 bytes region
1161 * we cannot replace with empty Free Space Box as we place version 0 one. */
1162 box
->pos
= box
->file
->bs
->written
;
1163 lsmash_bs_put_be32( bs
, ISOM_BASEBOX_COMMON_SIZE
+ 12 );
1164 lsmash_bs_put_be32( bs
, ISOM_BOX_TYPE_FREE
.fourcc
);
1165 lsmash_bs_put_be32( bs
, 0 );
1166 lsmash_bs_put_be64( bs
, 0 );
1170 isom_mehd_t
*mehd
= (isom_mehd_t
*)box
;
1171 //mehd->version = mehd->fragment_duration > UINT32_MAX ? 1 : 0;
1172 isom_bs_put_box_common( bs
, mehd
);
1173 if( mehd
->version
== 1 )
1174 lsmash_bs_put_be64( bs
, mehd
->fragment_duration
);
1176 lsmash_bs_put_be32( bs
, LSMASH_MIN( mehd
->fragment_duration
, UINT32_MAX
) );
1181 static int isom_write_trex( lsmash_bs_t
*bs
, isom_box_t
*box
)
1183 isom_trex_t
*trex
= (isom_trex_t
*)box
;
1184 isom_bs_put_box_common( bs
, trex
);
1185 lsmash_bs_put_be32( bs
, trex
->track_ID
);
1186 lsmash_bs_put_be32( bs
, trex
->default_sample_description_index
);
1187 lsmash_bs_put_be32( bs
, trex
->default_sample_duration
);
1188 lsmash_bs_put_be32( bs
, trex
->default_sample_size
);
1189 isom_bs_put_sample_flags( bs
, &trex
->default_sample_flags
);
1193 static int isom_write_mvex( lsmash_bs_t
*bs
, isom_box_t
*box
)
1195 isom_bs_put_box_common( bs
, box
);
1199 static int isom_write_mfhd( lsmash_bs_t
*bs
, isom_box_t
*box
)
1201 isom_mfhd_t
*mfhd
= (isom_mfhd_t
*)box
;
1202 isom_bs_put_box_common( bs
, mfhd
);
1203 lsmash_bs_put_be32( bs
, mfhd
->sequence_number
);
1207 static int isom_write_tfhd( lsmash_bs_t
*bs
, isom_box_t
*box
)
1209 isom_tfhd_t
*tfhd
= (isom_tfhd_t
*)box
;
1210 isom_bs_put_box_common( bs
, tfhd
);
1211 lsmash_bs_put_be32( bs
, tfhd
->track_ID
);
1212 if( tfhd
->flags
& ISOM_TF_FLAGS_BASE_DATA_OFFSET_PRESENT
) lsmash_bs_put_be64( bs
, tfhd
->base_data_offset
);
1213 if( tfhd
->flags
& ISOM_TF_FLAGS_SAMPLE_DESCRIPTION_INDEX_PRESENT
) lsmash_bs_put_be32( bs
, tfhd
->sample_description_index
);
1214 if( tfhd
->flags
& ISOM_TF_FLAGS_DEFAULT_SAMPLE_DURATION_PRESENT
) lsmash_bs_put_be32( bs
, tfhd
->default_sample_duration
);
1215 if( tfhd
->flags
& ISOM_TF_FLAGS_DEFAULT_SAMPLE_SIZE_PRESENT
) lsmash_bs_put_be32( bs
, tfhd
->default_sample_size
);
1216 if( tfhd
->flags
& ISOM_TF_FLAGS_DEFAULT_SAMPLE_FLAGS_PRESENT
) isom_bs_put_sample_flags( bs
, &tfhd
->default_sample_flags
);
1220 static int isom_write_tfdt( lsmash_bs_t
*bs
, isom_box_t
*box
)
1222 isom_tfdt_t
*tfdt
= (isom_tfdt_t
*)box
;
1223 /* Check the version. */
1224 tfdt
->version
= tfdt
->baseMediaDecodeTime
> UINT32_MAX
? 1 : 0;
1226 isom_bs_put_box_common( bs
, tfdt
);
1227 if( tfdt
->version
== 1 )
1228 lsmash_bs_put_be64( bs
, tfdt
->baseMediaDecodeTime
);
1230 lsmash_bs_put_be32( bs
, tfdt
->baseMediaDecodeTime
);
1234 static int isom_write_trun( lsmash_bs_t
*bs
, isom_box_t
*box
)
1236 isom_trun_t
*trun
= (isom_trun_t
*)box
;
1237 isom_bs_put_box_common( bs
, trun
);
1238 lsmash_bs_put_be32( bs
, trun
->sample_count
);
1239 if( trun
->flags
& ISOM_TR_FLAGS_DATA_OFFSET_PRESENT
) lsmash_bs_put_be32( bs
, trun
->data_offset
);
1240 if( trun
->flags
& ISOM_TR_FLAGS_FIRST_SAMPLE_FLAGS_PRESENT
) isom_bs_put_sample_flags( bs
, &trun
->first_sample_flags
);
1241 if( trun
->optional
)
1242 for( lsmash_entry_t
*entry
= trun
->optional
->head
; entry
; entry
= entry
->next
)
1244 isom_trun_optional_row_t
*data
= (isom_trun_optional_row_t
*)entry
->data
;
1246 return LSMASH_ERR_NAMELESS
;
1247 if( trun
->flags
& ISOM_TR_FLAGS_SAMPLE_DURATION_PRESENT
) lsmash_bs_put_be32( bs
, data
->sample_duration
);
1248 if( trun
->flags
& ISOM_TR_FLAGS_SAMPLE_SIZE_PRESENT
) lsmash_bs_put_be32( bs
, data
->sample_size
);
1249 if( trun
->flags
& ISOM_TR_FLAGS_SAMPLE_FLAGS_PRESENT
) isom_bs_put_sample_flags( bs
, &data
->sample_flags
);
1250 if( trun
->flags
& ISOM_TR_FLAGS_SAMPLE_COMPOSITION_TIME_OFFSET_PRESENT
) lsmash_bs_put_be32( bs
, data
->sample_composition_time_offset
);
1255 static int isom_write_traf( lsmash_bs_t
*bs
, isom_box_t
*box
)
1257 isom_bs_put_box_common( bs
, box
);
1261 static int isom_write_moof( lsmash_bs_t
*bs
, isom_box_t
*box
)
1263 isom_bs_put_box_common( bs
, box
);
1267 static int isom_write_tfra( lsmash_bs_t
*bs
, isom_box_t
*box
)
1269 isom_tfra_t
*tfra
= (isom_tfra_t
*)box
;
1270 isom_bs_put_box_common( bs
, tfra
);
1271 uint32_t temp
= (tfra
->reserved
<< 6)
1272 | (tfra
->length_size_of_traf_num
<< 4)
1273 | (tfra
->length_size_of_trun_num
<< 2)
1274 | tfra
->length_size_of_sample_num
;
1275 lsmash_bs_put_be32( bs
, tfra
->track_ID
);
1276 lsmash_bs_put_be32( bs
, temp
);
1277 lsmash_bs_put_be32( bs
, tfra
->number_of_entry
);
1280 void (*bs_put_funcs
[5])( lsmash_bs_t
*, uint64_t ) =
1282 lsmash_bs_put_byte_from_64
,
1283 lsmash_bs_put_be16_from_64
,
1284 lsmash_bs_put_be24_from_64
,
1285 lsmash_bs_put_be32_from_64
,
1288 void (*bs_put_time
) ( lsmash_bs_t
*, uint64_t ) = bs_put_funcs
[ tfra
->version
== 1 ? 4 : 3 ];
1289 void (*bs_put_moof_offset
) ( lsmash_bs_t
*, uint64_t ) = bs_put_funcs
[ tfra
->version
== 1 ? 4 : 3 ];
1290 void (*bs_put_traf_number
) ( lsmash_bs_t
*, uint64_t ) = bs_put_funcs
[ tfra
->length_size_of_traf_num
];
1291 void (*bs_put_trun_number
) ( lsmash_bs_t
*, uint64_t ) = bs_put_funcs
[ tfra
->length_size_of_trun_num
];
1292 void (*bs_put_sample_number
)( lsmash_bs_t
*, uint64_t ) = bs_put_funcs
[ tfra
->length_size_of_sample_num
];
1293 for( lsmash_entry_t
*entry
= tfra
->list
->head
; entry
; entry
= entry
->next
)
1295 isom_tfra_location_time_entry_t
*data
= (isom_tfra_location_time_entry_t
*)entry
->data
;
1297 return LSMASH_ERR_NAMELESS
;
1298 bs_put_time ( bs
, data
->time
);
1299 bs_put_moof_offset ( bs
, data
->moof_offset
);
1300 bs_put_traf_number ( bs
, data
->traf_number
);
1301 bs_put_trun_number ( bs
, data
->trun_number
);
1302 bs_put_sample_number( bs
, data
->sample_number
);
1308 static int isom_write_mfro( lsmash_bs_t
*bs
, isom_box_t
*box
)
1310 isom_mfro_t
*mfro
= (isom_mfro_t
*)box
;
1311 isom_bs_put_box_common( bs
, mfro
);
1312 lsmash_bs_put_be32( bs
, mfro
->length
); /* determined at isom_write_mfra(). */
1316 static int isom_write_mfra( lsmash_bs_t
*bs
, isom_box_t
*box
)
1318 isom_mfra_t
*mfra
= (isom_mfra_t
*)box
;
1320 mfra
->mfro
->length
= mfra
->size
;
1321 isom_bs_put_box_common( bs
, mfra
);
1325 static int isom_write_mdat( lsmash_bs_t
*bs
, isom_box_t
*box
)
1327 isom_mdat_t
*mdat
= (isom_mdat_t
*)box
;
1328 lsmash_file_t
*file
= mdat
->file
;
1329 /* If any fragment, write the Media Data Box all at once. */
1330 if( file
->fragment
)
1332 /* Write the size and type fields of the Media Data Box. */
1333 mdat
->size
= ISOM_BASEBOX_COMMON_SIZE
+ file
->fragment
->pool_size
;
1334 if( mdat
->size
> UINT32_MAX
)
1335 mdat
->size
+= 8; /* large_size */
1336 isom_bs_put_box_common( bs
, mdat
);
1337 /* Write the samples in the current movie fragment. */
1338 for( lsmash_entry_t
*entry
= file
->fragment
->pool
->head
; entry
; entry
= entry
->next
)
1340 isom_sample_pool_t
*pool
= (isom_sample_pool_t
*)entry
->data
;
1342 return LSMASH_ERR_NAMELESS
;
1343 lsmash_bs_put_bytes( bs
, pool
->size
, pool
->data
);
1345 mdat
->media_size
= file
->fragment
->pool_size
;
1348 if( mdat
->manager
& LSMASH_PLACEHOLDER
)
1350 /* Write the placeholder for large size. */
1351 if( !file
->free
&& !isom_add_free( file
) )
1352 return LSMASH_ERR_NAMELESS
;
1353 isom_free_t
*skip
= file
->free
;
1354 skip
->pos
= bs
->offset
;
1355 skip
->size
= ISOM_BASEBOX_COMMON_SIZE
;
1356 skip
->manager
|= LSMASH_PLACEHOLDER
;
1357 int ret
= isom_write_box( bs
, (isom_box_t
*)skip
);
1360 /* Write an incomplete Media Data Box. */
1361 mdat
->pos
= bs
->offset
;
1362 mdat
->size
= ISOM_BASEBOX_COMMON_SIZE
;
1363 mdat
->manager
|= LSMASH_INCOMPLETE_BOX
;
1364 mdat
->manager
&= ~LSMASH_PLACEHOLDER
;
1365 isom_bs_put_box_common( bs
, mdat
);
1368 if( !bs
->unseekable
)
1370 /* Write the actual size. */
1371 uint64_t current_pos
= bs
->offset
;
1372 mdat
->size
= ISOM_BASEBOX_COMMON_SIZE
+ mdat
->media_size
;
1373 if( mdat
->size
> UINT32_MAX
)
1375 /* The placeholder is overwritten by the Media Data Box. */
1376 assert( file
->free
);
1377 mdat
->pos
= file
->free
->pos
;
1378 mdat
->size
+= file
->free
->size
;
1379 isom_remove_box_by_itself( file
->free
);
1381 lsmash_bs_write_seek( bs
, mdat
->pos
, SEEK_SET
);
1382 isom_bs_put_box_common( bs
, mdat
);
1383 /* isom_write_box() also calls lsmash_bs_flush_buffer() but it must do nothing. */
1384 int ret
= lsmash_bs_flush_buffer( bs
);
1385 lsmash_bs_write_seek( bs
, current_pos
, SEEK_SET
);
1388 return LSMASH_ERR_NAMELESS
;
1391 static int isom_write_ftyp( lsmash_bs_t
*bs
, isom_box_t
*box
)
1393 isom_ftyp_t
*ftyp
= (isom_ftyp_t
*)box
;
1394 if( ftyp
->brand_count
== 0 )
1396 isom_bs_put_box_common( bs
, ftyp
);
1397 lsmash_bs_put_be32( bs
, ftyp
->major_brand
);
1398 lsmash_bs_put_be32( bs
, ftyp
->minor_version
);
1399 for( uint32_t i
= 0; i
< ftyp
->brand_count
; i
++ )
1400 lsmash_bs_put_be32( bs
, ftyp
->compatible_brands
[i
] );
1404 static int isom_write_moov( lsmash_bs_t
*bs
, isom_box_t
*box
)
1406 isom_bs_put_box_common( bs
, box
);
1410 static int isom_write_free( lsmash_bs_t
*bs
, isom_box_t
*box
)
1412 isom_free_t
*skip
= (isom_free_t
*)box
;
1413 isom_bs_put_box_common( bs
, skip
);
1414 if( skip
->data
&& skip
->length
)
1415 lsmash_bs_put_bytes( bs
, skip
->length
, skip
->data
);
1419 static int isom_write_sidx( lsmash_bs_t
*bs
, isom_box_t
*box
)
1421 isom_sidx_t
*sidx
= (isom_sidx_t
*)box
;
1422 /* Check the version. */
1423 if( sidx
->earliest_presentation_time
> UINT32_MAX
1424 || sidx
->first_offset
> UINT32_MAX
)
1429 isom_bs_put_box_common( bs
, sidx
);
1430 lsmash_bs_put_be32( bs
, sidx
->reference_ID
);
1431 lsmash_bs_put_be32( bs
, sidx
->timescale
);
1432 if( sidx
->version
== 0 )
1434 lsmash_bs_put_be32( bs
, LSMASH_MIN( sidx
->earliest_presentation_time
, UINT32_MAX
) );
1435 lsmash_bs_put_be32( bs
, LSMASH_MIN( sidx
->first_offset
, UINT32_MAX
) );
1439 lsmash_bs_put_be64( bs
, sidx
->earliest_presentation_time
);
1440 lsmash_bs_put_be64( bs
, sidx
->first_offset
);
1442 lsmash_bs_put_be16( bs
, sidx
->reserved
);
1443 lsmash_bs_put_be16( bs
, sidx
->reference_count
);
1444 for( lsmash_entry_t
*entry
= sidx
->list
->head
; entry
; entry
= entry
->next
)
1446 isom_sidx_referenced_item_t
*data
= (isom_sidx_referenced_item_t
*)entry
->data
;
1448 return LSMASH_ERR_NAMELESS
;
1450 temp32
= (data
->reference_type
<< 31)
1451 | data
->reference_size
;
1452 lsmash_bs_put_be32( bs
, temp32
);
1453 lsmash_bs_put_be32( bs
, data
->subsegment_duration
);
1454 temp32
= (data
->starts_with_SAP
<< 31)
1455 | (data
->SAP_type
<< 28)
1456 | data
->SAP_delta_time
;
1457 lsmash_bs_put_be32( bs
, temp32
);
1462 int isom_write_box( lsmash_bs_t
*bs
, isom_box_t
*box
)
1465 /* Don't write any incomplete or already written box to a file. */
1466 if( !box
|| !box
->write
1467 || (bs
->stream
&& (box
->manager
& (LSMASH_INCOMPLETE_BOX
| LSMASH_WRITTEN_BOX
))) )
1469 int ret
= box
->write( bs
, box
);
1474 if( (ret
= lsmash_bs_flush_buffer( bs
)) < 0 )
1476 /* Don't write any child box if this box is a placeholder or an incomplete box. */
1477 if( box
->manager
& (LSMASH_PLACEHOLDER
| LSMASH_INCOMPLETE_BOX
) )
1480 box
->manager
|= LSMASH_WRITTEN_BOX
;
1482 return isom_write_children( bs
, box
);
1485 void isom_set_box_writer( isom_box_t
*box
)
1487 if( box
->manager
& LSMASH_BINARY_CODED_BOX
)
1489 box
->write
= isom_write_binary_coded_box
;
1492 else if( box
->manager
& LSMASH_UNKNOWN_BOX
)
1494 box
->write
= isom_write_unknown_box
;
1497 assert( box
->parent
);
1498 isom_box_t
*parent
= box
->parent
;
1499 if( lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_STSD
) )
1501 /* OK, this box is a sample entry.
1502 * Here, determine the suitable sample entry writer by media type if possible. */
1503 if( !isom_check_media_hdlr_from_stsd( (isom_stsd_t
*)parent
) )
1505 lsmash_media_type media_type
= isom_get_media_type_from_stsd( (isom_stsd_t
*)parent
);
1506 if( media_type
== ISOM_MEDIA_HANDLER_TYPE_VIDEO_TRACK
)
1507 box
->write
= isom_write_visual_description
;
1508 else if( media_type
== ISOM_MEDIA_HANDLER_TYPE_AUDIO_TRACK
)
1509 box
->write
= isom_write_audio_description
;
1510 else if( media_type
== ISOM_MEDIA_HANDLER_TYPE_TEXT_TRACK
)
1512 if( lsmash_check_box_type_identical( box
->type
, QT_CODEC_TYPE_TEXT_TEXT
) )
1513 box
->write
= isom_write_qt_text_description
;
1514 else if( lsmash_check_box_type_identical( box
->type
, ISOM_CODEC_TYPE_TX3G_TEXT
) )
1515 box
->write
= isom_write_tx3g_description
;
1520 if( lsmash_check_box_type_identical( parent
->type
, QT_BOX_TYPE_WAVE
) )
1522 if( lsmash_check_box_type_identical( box
->type
, QT_BOX_TYPE_FRMA
) ) box
->write
= isom_write_frma
;
1523 else if( lsmash_check_box_type_identical( box
->type
, QT_BOX_TYPE_ENDA
) ) box
->write
= isom_write_enda
;
1524 else if( lsmash_check_box_type_identical( box
->type
, QT_BOX_TYPE_MP4A
) ) box
->write
= isom_write_mp4a
;
1525 else if( lsmash_check_box_type_identical( box
->type
, QT_BOX_TYPE_ESDS
) ) box
->write
= isom_write_esds
;
1526 else if( lsmash_check_box_type_identical( box
->type
, QT_BOX_TYPE_CHAN
) ) box
->write
= isom_write_chan
;
1527 else if( lsmash_check_box_type_identical( box
->type
, QT_BOX_TYPE_TERMINATOR
) ) box
->write
= isom_write_terminator
;
1528 else box
->write
= NULL
;
1531 if( lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_TREF
) )
1533 box
->write
= isom_write_track_reference_type
;
1536 static struct box_writer_table_tag
1538 lsmash_box_type_t type
;
1539 isom_extension_writer_t writer_func
;
1540 } box_writer_table
[128] = { { LSMASH_BOX_TYPE_INITIALIZER
, NULL
} };
1541 if( !box_writer_table
[0].writer_func
)
1543 /* Initialize the table. */
1545 #define ADD_BOX_WRITER_TABLE_ELEMENT( type, reader_func ) \
1546 box_writer_table[i++] = (struct box_writer_table_tag){ type, reader_func }
1547 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_FTYP
, isom_write_ftyp
);
1548 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_STYP
, isom_write_ftyp
);
1549 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_SIDX
, isom_write_sidx
);
1550 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_MOOV
, isom_write_moov
);
1551 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_MVHD
, isom_write_mvhd
);
1552 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_IODS
, isom_write_iods
);
1553 ADD_BOX_WRITER_TABLE_ELEMENT( QT_BOX_TYPE_CTAB
, isom_write_ctab
);
1554 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_ESDS
, isom_write_esds
);
1555 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_TRAK
, isom_write_trak
);
1556 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_TKHD
, isom_write_tkhd
);
1557 ADD_BOX_WRITER_TABLE_ELEMENT( QT_BOX_TYPE_TAPT
, isom_write_tapt
);
1558 ADD_BOX_WRITER_TABLE_ELEMENT( QT_BOX_TYPE_CLEF
, isom_write_clef
);
1559 ADD_BOX_WRITER_TABLE_ELEMENT( QT_BOX_TYPE_PROF
, isom_write_prof
);
1560 ADD_BOX_WRITER_TABLE_ELEMENT( QT_BOX_TYPE_ENOF
, isom_write_enof
);
1561 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_EDTS
, isom_write_edts
);
1562 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_ELST
, isom_write_elst
);
1563 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_TREF
, isom_write_tref
);
1564 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_MDIA
, isom_write_mdia
);
1565 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_MDHD
, isom_write_mdhd
);
1566 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_HDLR
, isom_write_hdlr
);
1567 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_MINF
, isom_write_minf
);
1568 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_VMHD
, isom_write_vmhd
);
1569 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_SMHD
, isom_write_smhd
);
1570 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_HMHD
, isom_write_hmhd
);
1571 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_NMHD
, isom_write_nmhd
);
1572 ADD_BOX_WRITER_TABLE_ELEMENT( QT_BOX_TYPE_GMHD
, isom_write_gmhd
);
1573 ADD_BOX_WRITER_TABLE_ELEMENT( QT_BOX_TYPE_GMIN
, isom_write_gmin
);
1574 ADD_BOX_WRITER_TABLE_ELEMENT( QT_BOX_TYPE_TEXT
, isom_write_text
);
1575 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_DINF
, isom_write_dinf
);
1576 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_DREF
, isom_write_dref
);
1577 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_URL
, isom_write_url
);
1578 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_STBL
, isom_write_stbl
);
1579 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_STSD
, isom_write_stsd
);
1580 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_BTRT
, isom_write_btrt
);
1581 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_COLR
, isom_write_colr
);
1582 ADD_BOX_WRITER_TABLE_ELEMENT( QT_BOX_TYPE_COLR
, isom_write_colr
);
1583 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_CLAP
, isom_write_clap
);
1584 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_PASP
, isom_write_pasp
);
1585 ADD_BOX_WRITER_TABLE_ELEMENT( QT_BOX_TYPE_GLBL
, isom_write_glbl
);
1586 ADD_BOX_WRITER_TABLE_ELEMENT( QT_BOX_TYPE_GAMA
, isom_write_gama
);
1587 ADD_BOX_WRITER_TABLE_ELEMENT( QT_BOX_TYPE_FIEL
, isom_write_fiel
);
1588 ADD_BOX_WRITER_TABLE_ELEMENT( QT_BOX_TYPE_CSPC
, isom_write_cspc
);
1589 ADD_BOX_WRITER_TABLE_ELEMENT( QT_BOX_TYPE_SGBT
, isom_write_sgbt
);
1590 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_STSL
, isom_write_stsl
);
1591 ADD_BOX_WRITER_TABLE_ELEMENT( QT_BOX_TYPE_WAVE
, isom_write_wave
);
1592 ADD_BOX_WRITER_TABLE_ELEMENT( QT_BOX_TYPE_MP4A
, isom_write_mp4a
);
1593 ADD_BOX_WRITER_TABLE_ELEMENT( QT_BOX_TYPE_CHAN
, isom_write_chan
);
1594 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_FTAB
, isom_write_ftab
);
1595 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_STTS
, isom_write_stts
);
1596 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_CTTS
, isom_write_ctts
);
1597 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_CSLG
, isom_write_cslg
);
1598 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_STSS
, isom_write_stss
);
1599 ADD_BOX_WRITER_TABLE_ELEMENT( QT_BOX_TYPE_STPS
, isom_write_stps
);
1600 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_SDTP
, isom_write_sdtp
);
1601 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_STSC
, isom_write_stsc
);
1602 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_STSZ
, isom_write_stsz
);
1603 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_STZ2
, isom_write_stz2
);
1604 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_STCO
, isom_write_stco
);
1605 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_CO64
, isom_write_stco
);
1606 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_SGPD
, isom_write_sgpd
);
1607 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_SBGP
, isom_write_sbgp
);
1608 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_UDTA
, isom_write_udta
);
1609 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_CHPL
, isom_write_chpl
);
1610 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_MVEX
, isom_write_mvex
);
1611 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_MEHD
, isom_write_mehd
);
1612 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_TREX
, isom_write_trex
);
1613 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_MOOF
, isom_write_moof
);
1614 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_MFHD
, isom_write_mfhd
);
1615 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_TRAF
, isom_write_traf
);
1616 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_TFHD
, isom_write_tfhd
);
1617 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_TFDT
, isom_write_tfdt
);
1618 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_TRUN
, isom_write_trun
);
1619 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_MDAT
, isom_write_mdat
);
1620 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_FREE
, isom_write_free
);
1621 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_SKIP
, isom_write_free
);
1622 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_META
, isom_write_meta
);
1623 ADD_BOX_WRITER_TABLE_ELEMENT( QT_BOX_TYPE_META
, isom_write_meta
);
1624 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_ILST
, isom_write_ilst
);
1625 ADD_BOX_WRITER_TABLE_ELEMENT( QT_BOX_TYPE_ILST
, isom_write_ilst
);
1626 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_MFRA
, isom_write_mfra
);
1627 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_TFRA
, isom_write_tfra
);
1628 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_MFRO
, isom_write_mfro
);
1629 ADD_BOX_WRITER_TABLE_ELEMENT( LSMASH_BOX_TYPE_UNSPECIFIED
, NULL
);
1630 #undef ADD_BOX_WRITER_TABLE_ELEMENT
1632 for( int i
= 0; box_writer_table
[i
].writer_func
; i
++ )
1633 if( lsmash_check_box_type_identical( box
->type
, box_writer_table
[i
].type
) )
1635 box
->write
= box_writer_table
[i
].writer_func
;
1638 if( lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_ILST
)
1639 || lsmash_check_box_type_identical( parent
->type
, QT_BOX_TYPE_ILST
) )
1641 box
->write
= isom_write_metaitem
;
1644 if( parent
->parent
&& lsmash_check_box_type_identical( parent
->parent
->type
, ISOM_BOX_TYPE_ILST
) )
1646 if( lsmash_check_box_type_identical( box
->type
, ISOM_BOX_TYPE_MEAN
) )
1647 box
->write
= isom_write_mean
;
1648 else if( lsmash_check_box_type_identical( box
->type
, ISOM_BOX_TYPE_NAME
) )
1649 box
->write
= isom_write_name
;
1650 else if( lsmash_check_box_type_identical( box
->type
, ISOM_BOX_TYPE_DATA
) )
1651 box
->write
= isom_write_data
;
1655 else if( lsmash_check_box_type_identical( box
->type
, ISOM_BOX_TYPE_CPRT
) )
1657 /* Avoid confusing udta.cprt with ilst.cprt. */
1658 box
->write
= isom_write_cprt
;
1661 box
->write
= isom_write_unknown_box
;