1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2010-2014 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 )
171 /* Check the version. */
173 if( elst
->file
&& !elst
->file
->undefined_64_ver
)
174 for( lsmash_entry_t
*entry
= elst
->list
->head
; entry
; entry
= entry
->next
)
176 isom_elst_entry_t
*data
= (isom_elst_entry_t
*)entry
->data
;
179 if( data
->segment_duration
> UINT32_MAX
180 || data
->media_time
> INT32_MAX
181 || data
->media_time
< INT32_MIN
)
184 /* Remember to rewrite entries. */
185 if( elst
->file
->fragment
&& !elst
->file
->bs
->unseekable
)
186 elst
->pos
= elst
->file
->bs
->written
;
188 isom_bs_put_box_common( bs
, elst
);
189 lsmash_bs_put_be32( bs
, elst
->list
->entry_count
);
190 for( lsmash_entry_t
*entry
= elst
->list
->head
; entry
; entry
= entry
->next
)
192 isom_elst_entry_t
*data
= (isom_elst_entry_t
*)entry
->data
;
195 lsmash_bs_put_be64( bs
, data
->segment_duration
);
196 lsmash_bs_put_be64( bs
, data
->media_time
);
200 lsmash_bs_put_be32( bs
, LSMASH_MIN( data
->segment_duration
, UINT32_MAX
) );
201 lsmash_bs_put_be32( bs
, data
->media_time
< 0 ? (uint32_t)data
->media_time
: LSMASH_MIN( data
->media_time
, INT32_MAX
) );
203 lsmash_bs_put_be32( bs
, data
->media_rate
);
208 static int isom_write_edts( lsmash_bs_t
*bs
, isom_box_t
*box
)
210 isom_bs_put_box_common( bs
, box
);
214 static int isom_write_tref( lsmash_bs_t
*bs
, isom_box_t
*box
)
216 isom_bs_put_box_common( bs
, box
);
220 static int isom_write_track_reference_type( lsmash_bs_t
*bs
, isom_box_t
*box
)
222 isom_tref_type_t
*ref
= (isom_tref_type_t
*)box
;
223 isom_bs_put_box_common( bs
, ref
);
224 for( uint32_t i
= 0; i
< ref
->ref_count
; i
++ )
225 lsmash_bs_put_be32( bs
, ref
->track_ID
[i
] );
229 static int isom_write_mdhd( lsmash_bs_t
*bs
, isom_box_t
*box
)
231 isom_mdhd_t
*mdhd
= (isom_mdhd_t
*)box
;
232 /* Check the version. */
233 if( (mdhd
->file
&& !mdhd
->file
->undefined_64_ver
)
234 && (mdhd
->creation_time
> UINT32_MAX
235 || mdhd
->modification_time
> UINT32_MAX
236 || mdhd
->duration
> UINT32_MAX
) )
241 isom_bs_put_box_common( bs
, mdhd
);
244 lsmash_bs_put_be64( bs
, mdhd
->creation_time
);
245 lsmash_bs_put_be64( bs
, mdhd
->modification_time
);
246 lsmash_bs_put_be32( bs
, mdhd
->timescale
);
247 lsmash_bs_put_be64( bs
, mdhd
->duration
);
251 lsmash_bs_put_be32( bs
, LSMASH_MIN( mdhd
->creation_time
, UINT32_MAX
) );
252 lsmash_bs_put_be32( bs
, LSMASH_MIN( mdhd
->modification_time
, UINT32_MAX
) );
253 lsmash_bs_put_be32( bs
, mdhd
->timescale
);
254 lsmash_bs_put_be32( bs
, LSMASH_MIN( mdhd
->duration
, UINT32_MAX
) );
256 lsmash_bs_put_be16( bs
, mdhd
->language
);
257 lsmash_bs_put_be16( bs
, mdhd
->quality
);
261 static int isom_write_hdlr( lsmash_bs_t
*bs
, isom_box_t
*box
)
263 isom_hdlr_t
*hdlr
= (isom_hdlr_t
*)box
;
264 isom_bs_put_box_common( bs
, hdlr
);
265 lsmash_bs_put_be32( bs
, hdlr
->componentType
);
266 lsmash_bs_put_be32( bs
, hdlr
->componentSubtype
);
267 lsmash_bs_put_be32( bs
, hdlr
->componentManufacturer
);
268 lsmash_bs_put_be32( bs
, hdlr
->componentFlags
);
269 lsmash_bs_put_be32( bs
, hdlr
->componentFlagsMask
);
270 lsmash_bs_put_bytes( bs
, hdlr
->componentName_length
, hdlr
->componentName
);
274 static int isom_write_vmhd( lsmash_bs_t
*bs
, isom_box_t
*box
)
276 isom_vmhd_t
*vmhd
= (isom_vmhd_t
*)box
;
277 isom_bs_put_box_common( bs
, vmhd
);
278 lsmash_bs_put_be16( bs
, vmhd
->graphicsmode
);
279 for( uint32_t i
= 0; i
< 3; i
++ )
280 lsmash_bs_put_be16( bs
, vmhd
->opcolor
[i
] );
284 static int isom_write_smhd( lsmash_bs_t
*bs
, isom_box_t
*box
)
286 isom_smhd_t
*smhd
= (isom_smhd_t
*)box
;
287 isom_bs_put_box_common( bs
, smhd
);
288 lsmash_bs_put_be16( bs
, smhd
->balance
);
289 lsmash_bs_put_be16( bs
, smhd
->reserved
);
293 static int isom_write_hmhd( lsmash_bs_t
*bs
, isom_box_t
*box
)
295 isom_hmhd_t
*hmhd
= (isom_hmhd_t
*)box
;
296 isom_bs_put_box_common( bs
, hmhd
);
297 lsmash_bs_put_be16( bs
, hmhd
->maxPDUsize
);
298 lsmash_bs_put_be16( bs
, hmhd
->avgPDUsize
);
299 lsmash_bs_put_be32( bs
, hmhd
->maxbitrate
);
300 lsmash_bs_put_be32( bs
, hmhd
->avgbitrate
);
301 lsmash_bs_put_be32( bs
, hmhd
->reserved
);
305 static int isom_write_nmhd( lsmash_bs_t
*bs
, isom_box_t
*box
)
307 isom_nmhd_t
*nmhd
= (isom_nmhd_t
*)box
;
308 isom_bs_put_box_common( bs
, nmhd
);
312 static int isom_write_gmin( lsmash_bs_t
*bs
, isom_box_t
*box
)
314 isom_gmin_t
*gmin
= (isom_gmin_t
*)box
;
315 isom_bs_put_box_common( bs
, gmin
);
316 lsmash_bs_put_be16( bs
, gmin
->graphicsmode
);
317 for( uint32_t i
= 0; i
< 3; i
++ )
318 lsmash_bs_put_be16( bs
, gmin
->opcolor
[i
] );
319 lsmash_bs_put_be16( bs
, gmin
->balance
);
320 lsmash_bs_put_be16( bs
, gmin
->reserved
);
324 static int isom_write_text( lsmash_bs_t
*bs
, isom_box_t
*box
)
326 isom_text_t
*text
= (isom_text_t
*)box
;
327 isom_bs_put_box_common( bs
, text
);
328 for( uint32_t i
= 0; i
< 9; i
++ )
329 lsmash_bs_put_be32( bs
, text
->matrix
[i
] );
333 static int isom_write_gmhd( lsmash_bs_t
*bs
, isom_box_t
*box
)
335 isom_bs_put_box_common( bs
, box
);
339 static int isom_write_dref( lsmash_bs_t
*bs
, isom_box_t
*box
)
341 isom_dref_t
*dref
= (isom_dref_t
*)box
;
342 isom_bs_put_box_common( bs
, dref
);
343 lsmash_bs_put_be32( bs
, dref
->list
.entry_count
);
347 static int isom_write_url( lsmash_bs_t
*bs
, isom_box_t
*box
)
349 isom_dref_entry_t
*url
= (isom_dref_entry_t
*)box
;
350 isom_bs_put_box_common( bs
, url
);
351 lsmash_bs_put_bytes( bs
, url
->location_length
, url
->location
);
355 static int isom_write_dinf( lsmash_bs_t
*bs
, isom_box_t
*box
)
357 isom_bs_put_box_common( bs
, box
);
361 static int isom_write_pasp( lsmash_bs_t
*bs
, isom_box_t
*box
)
363 isom_pasp_t
*pasp
= (isom_pasp_t
*)box
;
364 isom_bs_put_box_common( bs
, pasp
);
365 lsmash_bs_put_be32( bs
, pasp
->hSpacing
);
366 lsmash_bs_put_be32( bs
, pasp
->vSpacing
);
370 static int isom_write_clap( lsmash_bs_t
*bs
, isom_box_t
*box
)
372 isom_clap_t
*clap
= (isom_clap_t
*)box
;
373 isom_bs_put_box_common( bs
, clap
);
374 lsmash_bs_put_be32( bs
, clap
->cleanApertureWidthN
);
375 lsmash_bs_put_be32( bs
, clap
->cleanApertureWidthD
);
376 lsmash_bs_put_be32( bs
, clap
->cleanApertureHeightN
);
377 lsmash_bs_put_be32( bs
, clap
->cleanApertureHeightD
);
378 lsmash_bs_put_be32( bs
, clap
->horizOffN
);
379 lsmash_bs_put_be32( bs
, clap
->horizOffD
);
380 lsmash_bs_put_be32( bs
, clap
->vertOffN
);
381 lsmash_bs_put_be32( bs
, clap
->vertOffD
);
385 static int isom_write_colr( lsmash_bs_t
*bs
, isom_box_t
*box
)
387 isom_colr_t
*colr
= (isom_colr_t
*)box
;
388 if( colr
->color_parameter_type
!= ISOM_COLOR_PARAMETER_TYPE_NCLX
389 && colr
->color_parameter_type
!= QT_COLOR_PARAMETER_TYPE_NCLC
)
391 isom_bs_put_box_common( bs
, colr
);
392 lsmash_bs_put_be32( bs
, colr
->color_parameter_type
);
393 lsmash_bs_put_be16( bs
, colr
->primaries_index
);
394 lsmash_bs_put_be16( bs
, colr
->transfer_function_index
);
395 lsmash_bs_put_be16( bs
, colr
->matrix_index
);
396 if( colr
->color_parameter_type
== ISOM_COLOR_PARAMETER_TYPE_NCLX
)
397 lsmash_bs_put_byte( bs
, (colr
->full_range_flag
<< 7) | colr
->reserved
);
401 static int isom_write_gama( lsmash_bs_t
*bs
, isom_box_t
*box
)
403 isom_gama_t
*gama
= (isom_gama_t
*)box
;
406 /* Note: 'gama' box is superseded by 'colr' box.
407 * Therefore, writers of QTFF should never write both 'colr' and 'gama' box into an Image Description. */
408 if( isom_get_extension_box_format( &((isom_visual_entry_t
*)gama
->parent
)->extensions
, QT_BOX_TYPE_COLR
) )
410 isom_bs_put_box_common( bs
, gama
);
411 lsmash_bs_put_be32( bs
, gama
->level
);
415 static int isom_write_fiel( lsmash_bs_t
*bs
, isom_box_t
*box
)
417 isom_fiel_t
*fiel
= (isom_fiel_t
*)box
;
418 isom_bs_put_box_common( bs
, fiel
);
419 lsmash_bs_put_byte( bs
, fiel
->fields
);
420 lsmash_bs_put_byte( bs
, fiel
->detail
);
424 static int isom_write_cspc( lsmash_bs_t
*bs
, isom_box_t
*box
)
426 isom_cspc_t
*cspc
= (isom_cspc_t
*)box
;
427 isom_bs_put_box_common( bs
, cspc
);
428 lsmash_bs_put_be32( bs
, cspc
->pixel_format
);
432 static int isom_write_sgbt( lsmash_bs_t
*bs
, isom_box_t
*box
)
434 isom_sgbt_t
*sgbt
= (isom_sgbt_t
*)box
;
435 isom_bs_put_box_common( bs
, sgbt
);
436 lsmash_bs_put_byte( bs
, sgbt
->significantBits
);
440 static int isom_write_stsl( lsmash_bs_t
*bs
, isom_box_t
*box
)
442 isom_stsl_t
*stsl
= (isom_stsl_t
*)box
;
443 isom_bs_put_box_common( bs
, stsl
);
444 lsmash_bs_put_byte( bs
, stsl
->constraint_flag
);
445 lsmash_bs_put_byte( bs
, stsl
->scale_method
);
446 lsmash_bs_put_be16( bs
, stsl
->display_center_x
);
447 lsmash_bs_put_be16( bs
, stsl
->display_center_y
);
451 static int isom_write_esds( lsmash_bs_t
*bs
, isom_box_t
*box
)
453 isom_esds_t
*esds
= (isom_esds_t
*)box
;
454 isom_bs_put_box_common( bs
, esds
);
455 mp4sys_update_descriptor_size( esds
->ES
);
456 return mp4sys_write_descriptor( bs
, esds
->ES
);
459 static int isom_write_btrt( lsmash_bs_t
*bs
, isom_box_t
*box
)
461 isom_btrt_t
*btrt
= (isom_btrt_t
*)box
;
462 isom_bs_put_box_common( bs
, btrt
);
463 lsmash_bs_put_be32( bs
, btrt
->bufferSizeDB
);
464 lsmash_bs_put_be32( bs
, btrt
->maxBitrate
);
465 lsmash_bs_put_be32( bs
, btrt
->avgBitrate
);
469 static int isom_write_glbl( lsmash_bs_t
*bs
, isom_box_t
*box
)
471 isom_glbl_t
*glbl
= (isom_glbl_t
*)box
;
472 isom_bs_put_box_common( bs
, glbl
);
473 if( glbl
->header_data
&& glbl
->header_size
)
474 lsmash_bs_put_bytes( bs
, glbl
->header_size
, glbl
->header_data
);
478 static int isom_write_frma( lsmash_bs_t
*bs
, isom_box_t
*box
)
480 isom_frma_t
*frma
= (isom_frma_t
*)box
;
481 isom_bs_put_box_common( bs
, frma
);
482 lsmash_bs_put_be32( bs
, frma
->data_format
);
486 static int isom_write_enda( lsmash_bs_t
*bs
, isom_box_t
*box
)
488 isom_enda_t
*enda
= (isom_enda_t
*)box
;
489 isom_bs_put_box_common( bs
, enda
);
490 lsmash_bs_put_be16( bs
, enda
->littleEndian
);
494 static int isom_write_mp4a( lsmash_bs_t
*bs
, isom_box_t
*box
)
496 isom_mp4a_t
*mp4a
= (isom_mp4a_t
*)box
;
497 isom_bs_put_box_common( bs
, mp4a
);
498 lsmash_bs_put_be32( bs
, mp4a
->unknown
);
502 static int isom_write_chan( lsmash_bs_t
*bs
, isom_box_t
*box
)
504 isom_chan_t
*chan
= (isom_chan_t
*)box
;
505 isom_bs_put_box_common( bs
, chan
);
506 lsmash_bs_put_be32( bs
, chan
->channelLayoutTag
);
507 lsmash_bs_put_be32( bs
, chan
->channelBitmap
);
508 lsmash_bs_put_be32( bs
, chan
->numberChannelDescriptions
);
509 if( chan
->channelDescriptions
)
510 for( uint32_t i
= 0; i
< chan
->numberChannelDescriptions
; i
++ )
512 isom_channel_description_t
*channelDescriptions
= (isom_channel_description_t
*)(&chan
->channelDescriptions
[i
]);
513 if( !channelDescriptions
)
515 lsmash_bs_put_be32( bs
, channelDescriptions
->channelLabel
);
516 lsmash_bs_put_be32( bs
, channelDescriptions
->channelFlags
);
517 lsmash_bs_put_be32( bs
, channelDescriptions
->coordinates
[0] );
518 lsmash_bs_put_be32( bs
, channelDescriptions
->coordinates
[1] );
519 lsmash_bs_put_be32( bs
, channelDescriptions
->coordinates
[2] );
524 static int isom_write_terminator( lsmash_bs_t
*bs
, isom_box_t
*box
)
526 isom_bs_put_box_common( bs
, box
);
530 static int isom_write_wave( lsmash_bs_t
*bs
, isom_box_t
*box
)
532 isom_bs_put_box_common( bs
, box
);
536 static int isom_write_visual_description( lsmash_bs_t
*bs
, isom_box_t
*box
)
538 isom_visual_entry_t
*data
= (isom_visual_entry_t
*)box
;
541 isom_bs_put_box_common( bs
, data
);
542 lsmash_bs_put_bytes( bs
, 6, data
->reserved
);
543 lsmash_bs_put_be16( bs
, data
->data_reference_index
);
544 lsmash_bs_put_be16( bs
, data
->version
);
545 lsmash_bs_put_be16( bs
, data
->revision_level
);
546 lsmash_bs_put_be32( bs
, data
->vendor
);
547 lsmash_bs_put_be32( bs
, data
->temporalQuality
);
548 lsmash_bs_put_be32( bs
, data
->spatialQuality
);
549 lsmash_bs_put_be16( bs
, data
->width
);
550 lsmash_bs_put_be16( bs
, data
->height
);
551 lsmash_bs_put_be32( bs
, data
->horizresolution
);
552 lsmash_bs_put_be32( bs
, data
->vertresolution
);
553 lsmash_bs_put_be32( bs
, data
->dataSize
);
554 lsmash_bs_put_be16( bs
, data
->frame_count
);
555 lsmash_bs_put_bytes( bs
, 32, data
->compressorname
);
556 lsmash_bs_put_be16( bs
, data
->depth
);
557 lsmash_bs_put_be16( bs
, data
->color_table_ID
);
558 if( data
->color_table_ID
== 0 )
559 isom_bs_put_qt_color_table( bs
, &data
->color_table
);
563 static int isom_write_audio_description( lsmash_bs_t
*bs
, isom_box_t
*box
)
565 isom_audio_entry_t
*data
= (isom_audio_entry_t
*)box
;
568 isom_bs_put_box_common( bs
, data
);
569 lsmash_bs_put_bytes( bs
, 6, data
->reserved
);
570 lsmash_bs_put_be16( bs
, data
->data_reference_index
);
571 lsmash_bs_put_be16( bs
, data
->version
);
572 lsmash_bs_put_be16( bs
, data
->revision_level
);
573 lsmash_bs_put_be32( bs
, data
->vendor
);
574 lsmash_bs_put_be16( bs
, data
->channelcount
);
575 lsmash_bs_put_be16( bs
, data
->samplesize
);
576 lsmash_bs_put_be16( bs
, data
->compression_ID
);
577 lsmash_bs_put_be16( bs
, data
->packet_size
);
578 lsmash_bs_put_be32( bs
, data
->samplerate
);
579 if( data
->version
== 1 )
581 lsmash_bs_put_be32( bs
, data
->samplesPerPacket
);
582 lsmash_bs_put_be32( bs
, data
->bytesPerPacket
);
583 lsmash_bs_put_be32( bs
, data
->bytesPerFrame
);
584 lsmash_bs_put_be32( bs
, data
->bytesPerSample
);
586 else if( data
->version
== 2 )
588 lsmash_bs_put_be32( bs
, data
->sizeOfStructOnly
);
589 lsmash_bs_put_be64( bs
, data
->audioSampleRate
);
590 lsmash_bs_put_be32( bs
, data
->numAudioChannels
);
591 lsmash_bs_put_be32( bs
, data
->always7F000000
);
592 lsmash_bs_put_be32( bs
, data
->constBitsPerChannel
);
593 lsmash_bs_put_be32( bs
, data
->formatSpecificFlags
);
594 lsmash_bs_put_be32( bs
, data
->constBytesPerAudioPacket
);
595 lsmash_bs_put_be32( bs
, data
->constLPCMFramesPerAudioPacket
);
601 static int isom_write_hint_description( lsmash_bs_t
*bs
, lsmash_entry_t
*entry
)
603 isom_hint_entry_t
*data
= (isom_hint_entry_t
*)entry
->data
;
606 isom_bs_put_box_common( bs
, data
);
607 lsmash_bs_put_bytes( bs
, 6, data
->reserved
);
608 lsmash_bs_put_be16( bs
, data
->data_reference_index
);
609 if( data
->data
&& data
->data_length
)
610 lsmash_bs_put_bytes( bs
, data
->data_length
, data
->data
);
614 static int isom_write_metadata_description( lsmash_bs_t
*bs
, lsmash_entry_t
*entry
)
616 isom_metadata_entry_t
*data
= (isom_metadata_entry_t
*)entry
->data
;
619 isom_bs_put_box_common( bs
, data
);
620 lsmash_bs_put_bytes( bs
, 6, data
->reserved
);
621 lsmash_bs_put_be16( bs
, data
->data_reference_index
);
626 static int isom_write_qt_text_description( lsmash_bs_t
*bs
, isom_box_t
*box
)
628 isom_qt_text_entry_t
*data
= (isom_qt_text_entry_t
*)box
;
631 isom_bs_put_box_common( bs
, data
);
632 lsmash_bs_put_bytes( bs
, 6, data
->reserved
);
633 lsmash_bs_put_be16( bs
, data
->data_reference_index
);
634 lsmash_bs_put_be32( bs
, data
->displayFlags
);
635 lsmash_bs_put_be32( bs
, data
->textJustification
);
636 for( uint32_t i
= 0; i
< 3; i
++ )
637 lsmash_bs_put_be16( bs
, data
->bgColor
[i
] );
638 lsmash_bs_put_be16( bs
, data
->top
);
639 lsmash_bs_put_be16( bs
, data
->left
);
640 lsmash_bs_put_be16( bs
, data
->bottom
);
641 lsmash_bs_put_be16( bs
, data
->right
);
642 lsmash_bs_put_be32( bs
, data
->scrpStartChar
);
643 lsmash_bs_put_be16( bs
, data
->scrpHeight
);
644 lsmash_bs_put_be16( bs
, data
->scrpAscent
);
645 lsmash_bs_put_be16( bs
, data
->scrpFont
);
646 lsmash_bs_put_be16( bs
, data
->scrpFace
);
647 lsmash_bs_put_be16( bs
, data
->scrpSize
);
648 for( uint32_t i
= 0; i
< 3; i
++ )
649 lsmash_bs_put_be16( bs
, data
->scrpColor
[i
] );
650 lsmash_bs_put_byte( bs
, data
->font_name_length
);
651 if( data
->font_name
&& data
->font_name_length
)
652 lsmash_bs_put_bytes( bs
, data
->font_name_length
, data
->font_name
);
656 static int isom_write_ftab( lsmash_bs_t
*bs
, isom_box_t
*box
)
658 isom_ftab_t
*ftab
= (isom_ftab_t
*)box
;
659 assert( ftab
->list
);
660 isom_bs_put_box_common( bs
, ftab
);
661 lsmash_bs_put_be16( bs
, ftab
->list
->entry_count
);
662 for( lsmash_entry_t
*entry
= ftab
->list
->head
; entry
; entry
= entry
->next
)
664 isom_font_record_t
*data
= (isom_font_record_t
*)entry
->data
;
667 lsmash_bs_put_be16( bs
, data
->font_ID
);
668 lsmash_bs_put_byte( bs
, data
->font_name_length
);
669 if( data
->font_name
&& data
->font_name_length
)
670 lsmash_bs_put_bytes( bs
, data
->font_name_length
, data
->font_name
);
675 static int isom_write_tx3g_description( lsmash_bs_t
*bs
, isom_box_t
*box
)
677 isom_tx3g_entry_t
*data
= (isom_tx3g_entry_t
*)box
;
680 isom_bs_put_box_common( bs
, data
);
681 lsmash_bs_put_bytes( bs
, 6, data
->reserved
);
682 lsmash_bs_put_be16( bs
, data
->data_reference_index
);
683 lsmash_bs_put_be32( bs
, data
->displayFlags
);
684 lsmash_bs_put_byte( bs
, data
->horizontal_justification
);
685 lsmash_bs_put_byte( bs
, data
->vertical_justification
);
686 for( uint32_t i
= 0; i
< 4; i
++ )
687 lsmash_bs_put_byte( bs
, data
->background_color_rgba
[i
] );
688 lsmash_bs_put_be16( bs
, data
->top
);
689 lsmash_bs_put_be16( bs
, data
->left
);
690 lsmash_bs_put_be16( bs
, data
->bottom
);
691 lsmash_bs_put_be16( bs
, data
->right
);
692 lsmash_bs_put_be16( bs
, data
->startChar
);
693 lsmash_bs_put_be16( bs
, data
->endChar
);
694 lsmash_bs_put_be16( bs
, data
->font_ID
);
695 lsmash_bs_put_byte( bs
, data
->face_style_flags
);
696 lsmash_bs_put_byte( bs
, data
->font_size
);
697 for( uint32_t i
= 0; i
< 4; i
++ )
698 lsmash_bs_put_byte( bs
, data
->text_color_rgba
[i
] );
702 static int isom_write_stsd( lsmash_bs_t
*bs
, isom_box_t
*box
)
704 isom_stsd_t
*stsd
= (isom_stsd_t
*)box
;
705 isom_bs_put_box_common( bs
, stsd
);
706 lsmash_bs_put_be32( bs
, stsd
->list
.entry_count
);
710 static int isom_write_stts( lsmash_bs_t
*bs
, isom_box_t
*box
)
712 isom_stts_t
*stts
= (isom_stts_t
*)box
;
713 assert( stts
->list
);
714 isom_bs_put_box_common( bs
, stts
);
715 lsmash_bs_put_be32( bs
, stts
->list
->entry_count
);
716 for( lsmash_entry_t
*entry
= stts
->list
->head
; entry
; entry
= entry
->next
)
718 isom_stts_entry_t
*data
= (isom_stts_entry_t
*)entry
->data
;
721 lsmash_bs_put_be32( bs
, data
->sample_count
);
722 lsmash_bs_put_be32( bs
, data
->sample_delta
);
727 static int isom_write_ctts( lsmash_bs_t
*bs
, isom_box_t
*box
)
729 isom_ctts_t
*ctts
= (isom_ctts_t
*)box
;
730 assert( ctts
->list
);
731 isom_bs_put_box_common( bs
, ctts
);
732 lsmash_bs_put_be32( bs
, ctts
->list
->entry_count
);
733 for( lsmash_entry_t
*entry
= ctts
->list
->head
; entry
; entry
= entry
->next
)
735 isom_ctts_entry_t
*data
= (isom_ctts_entry_t
*)entry
->data
;
738 lsmash_bs_put_be32( bs
, data
->sample_count
);
739 lsmash_bs_put_be32( bs
, data
->sample_offset
);
744 static int isom_write_cslg( lsmash_bs_t
*bs
, isom_box_t
*box
)
746 isom_cslg_t
*cslg
= (isom_cslg_t
*)box
;
747 isom_bs_put_box_common( bs
, cslg
);
748 lsmash_bs_put_be32( bs
, cslg
->compositionToDTSShift
);
749 lsmash_bs_put_be32( bs
, cslg
->leastDecodeToDisplayDelta
);
750 lsmash_bs_put_be32( bs
, cslg
->greatestDecodeToDisplayDelta
);
751 lsmash_bs_put_be32( bs
, cslg
->compositionStartTime
);
752 lsmash_bs_put_be32( bs
, cslg
->compositionEndTime
);
756 static int isom_write_stsz( lsmash_bs_t
*bs
, isom_box_t
*box
)
758 isom_stsz_t
*stsz
= (isom_stsz_t
*)box
;
759 isom_bs_put_box_common( bs
, stsz
);
760 lsmash_bs_put_be32( bs
, stsz
->sample_size
);
761 lsmash_bs_put_be32( bs
, stsz
->sample_count
);
762 if( stsz
->sample_size
== 0 && stsz
->list
)
763 for( lsmash_entry_t
*entry
= stsz
->list
->head
; entry
; entry
= entry
->next
)
765 isom_stsz_entry_t
*data
= (isom_stsz_entry_t
*)entry
->data
;
768 lsmash_bs_put_be32( bs
, data
->entry_size
);
773 static int isom_write_stss( lsmash_bs_t
*bs
, isom_box_t
*box
)
775 isom_stss_t
*stss
= (isom_stss_t
*)box
;
776 assert( stss
->list
);
777 isom_bs_put_box_common( bs
, stss
);
778 lsmash_bs_put_be32( bs
, stss
->list
->entry_count
);
779 for( lsmash_entry_t
*entry
= stss
->list
->head
; entry
; entry
= entry
->next
)
781 isom_stss_entry_t
*data
= (isom_stss_entry_t
*)entry
->data
;
784 lsmash_bs_put_be32( bs
, data
->sample_number
);
789 static int isom_write_stps( lsmash_bs_t
*bs
, isom_box_t
*box
)
791 isom_stps_t
*stps
= (isom_stps_t
*)box
;
792 assert( stps
->list
);
793 isom_bs_put_box_common( bs
, stps
);
794 lsmash_bs_put_be32( bs
, stps
->list
->entry_count
);
795 for( lsmash_entry_t
*entry
= stps
->list
->head
; entry
; entry
= entry
->next
)
797 isom_stps_entry_t
*data
= (isom_stps_entry_t
*)entry
->data
;
800 lsmash_bs_put_be32( bs
, data
->sample_number
);
805 static int isom_write_sdtp( lsmash_bs_t
*bs
, isom_box_t
*box
)
807 isom_sdtp_t
*sdtp
= (isom_sdtp_t
*)box
;
808 assert( sdtp
->list
);
809 isom_bs_put_box_common( bs
, sdtp
);
810 for( lsmash_entry_t
*entry
= sdtp
->list
->head
; entry
; entry
= entry
->next
)
812 isom_sdtp_entry_t
*data
= (isom_sdtp_entry_t
*)entry
->data
;
815 uint8_t temp
= (data
->is_leading
<< 6)
816 | (data
->sample_depends_on
<< 4)
817 | (data
->sample_is_depended_on
<< 2)
818 | data
->sample_has_redundancy
;
819 lsmash_bs_put_byte( bs
, temp
);
824 static int isom_write_stsc( lsmash_bs_t
*bs
, isom_box_t
*box
)
826 isom_stsc_t
*stsc
= (isom_stsc_t
*)box
;
827 assert( stsc
->list
);
828 isom_bs_put_box_common( bs
, stsc
);
829 lsmash_bs_put_be32( bs
, stsc
->list
->entry_count
);
830 for( lsmash_entry_t
*entry
= stsc
->list
->head
; entry
; entry
= entry
->next
)
832 isom_stsc_entry_t
*data
= (isom_stsc_entry_t
*)entry
->data
;
835 lsmash_bs_put_be32( bs
, data
->first_chunk
);
836 lsmash_bs_put_be32( bs
, data
->samples_per_chunk
);
837 lsmash_bs_put_be32( bs
, data
->sample_description_index
);
842 static int isom_write_co64( lsmash_bs_t
*bs
, isom_box_t
*box
)
844 isom_stco_t
*co64
= (isom_stco_t
*)box
;
845 assert( co64
->list
);
846 isom_bs_put_box_common( bs
, co64
);
847 lsmash_bs_put_be32( bs
, co64
->list
->entry_count
);
848 for( lsmash_entry_t
*entry
= co64
->list
->head
; entry
; entry
= entry
->next
)
850 isom_co64_entry_t
*data
= (isom_co64_entry_t
*)entry
->data
;
853 lsmash_bs_put_be64( bs
, data
->chunk_offset
);
858 static int isom_write_stco( lsmash_bs_t
*bs
, isom_box_t
*box
)
860 isom_stco_t
*stco
= (isom_stco_t
*)box
;
861 if( stco
->large_presentation
)
862 return isom_write_co64( bs
, box
);
863 assert( stco
->list
);
864 isom_bs_put_box_common( bs
, stco
);
865 lsmash_bs_put_be32( bs
, stco
->list
->entry_count
);
866 for( lsmash_entry_t
*entry
= stco
->list
->head
; entry
; entry
= entry
->next
)
868 isom_stco_entry_t
*data
= (isom_stco_entry_t
*)entry
->data
;
871 lsmash_bs_put_be32( bs
, data
->chunk_offset
);
876 static int isom_write_sgpd( lsmash_bs_t
*bs
, isom_box_t
*box
)
878 isom_sgpd_t
*sgpd
= (isom_sgpd_t
*)box
;
879 assert( sgpd
->list
);
880 isom_bs_put_box_common( bs
, sgpd
);
881 lsmash_bs_put_be32( bs
, sgpd
->grouping_type
);
882 if( sgpd
->version
== 1 )
883 lsmash_bs_put_be32( bs
, sgpd
->default_length
);
884 lsmash_bs_put_be32( bs
, sgpd
->list
->entry_count
);
885 for( lsmash_entry_t
*entry
= sgpd
->list
->head
; entry
; entry
= entry
->next
)
889 switch( sgpd
->grouping_type
)
891 case ISOM_GROUP_TYPE_RAP
:
893 isom_rap_entry_t
*rap
= (isom_rap_entry_t
*)entry
->data
;
894 uint8_t temp
= (rap
->num_leading_samples_known
<< 7)
895 | rap
->num_leading_samples
;
896 lsmash_bs_put_byte( bs
, temp
);
899 case ISOM_GROUP_TYPE_ROLL
:
900 case ISOM_GROUP_TYPE_PROL
:
901 lsmash_bs_put_be16( bs
, ((isom_roll_entry_t
*)entry
->data
)->roll_distance
);
904 /* We don't consider other grouping types currently. */
905 // if( sgpd->version == 1 && !sgpd->default_length )
906 // lsmash_bs_put_be32( bs, ((isom_sgpd_t *)entry->data)->description_length );
913 static int isom_write_sbgp( lsmash_bs_t
*bs
, isom_box_t
*box
)
915 isom_sbgp_t
*sbgp
= (isom_sbgp_t
*)box
;
916 assert( sbgp
->list
);
917 isom_bs_put_box_common( bs
, sbgp
);
918 lsmash_bs_put_be32( bs
, sbgp
->grouping_type
);
919 if( sbgp
->version
== 1 )
920 lsmash_bs_put_be32( bs
, sbgp
->grouping_type_parameter
);
921 lsmash_bs_put_be32( bs
, sbgp
->list
->entry_count
);
922 for( lsmash_entry_t
*entry
= sbgp
->list
->head
; entry
; entry
= entry
->next
)
924 isom_group_assignment_entry_t
*data
= (isom_group_assignment_entry_t
*)entry
->data
;
927 lsmash_bs_put_be32( bs
, data
->sample_count
);
928 lsmash_bs_put_be32( bs
, data
->group_description_index
);
933 static int isom_write_stbl( lsmash_bs_t
*bs
, isom_box_t
*box
)
935 isom_bs_put_box_common( bs
, box
);
939 static int isom_write_minf( lsmash_bs_t
*bs
, isom_box_t
*box
)
941 isom_bs_put_box_common( bs
, box
);
945 static int isom_write_mdia( lsmash_bs_t
*bs
, isom_box_t
*box
)
947 isom_bs_put_box_common( bs
, box
);
951 static int isom_write_chpl( lsmash_bs_t
*bs
, isom_box_t
*box
)
953 isom_chpl_t
*chpl
= (isom_chpl_t
*)box
;
954 assert( chpl
->list
);
955 isom_bs_put_box_common( bs
, chpl
);
956 if( chpl
->version
== 1 )
958 lsmash_bs_put_byte( bs
, chpl
->unknown
);
959 lsmash_bs_put_be32( bs
, chpl
->list
->entry_count
);
961 else /* chpl->version == 0 */
962 lsmash_bs_put_byte( bs
, (uint8_t)chpl
->list
->entry_count
);
963 for( lsmash_entry_t
*entry
= chpl
->list
->head
; entry
; entry
= entry
->next
)
965 isom_chpl_entry_t
*data
= (isom_chpl_entry_t
*)entry
->data
;
968 lsmash_bs_put_be64( bs
, data
->start_time
);
969 lsmash_bs_put_byte( bs
, data
->chapter_name_length
);
970 lsmash_bs_put_bytes( bs
, data
->chapter_name_length
, data
->chapter_name
);
975 static int isom_write_mean( lsmash_bs_t
*bs
, isom_box_t
*box
)
977 isom_mean_t
*mean
= (isom_mean_t
*)box
;
978 isom_bs_put_box_common( bs
, mean
);
979 if( mean
->meaning_string
&& mean
->meaning_string_length
)
980 lsmash_bs_put_bytes( bs
, mean
->meaning_string_length
, mean
->meaning_string
);
984 static int isom_write_name( lsmash_bs_t
*bs
, isom_box_t
*box
)
986 isom_name_t
*name
= (isom_name_t
*)box
;
987 isom_bs_put_box_common( bs
, name
);
988 if( name
->name
&& name
->name_length
)
989 lsmash_bs_put_bytes( bs
, name
->name_length
, name
->name
);
993 static int isom_write_data( lsmash_bs_t
*bs
, isom_box_t
*box
)
995 isom_data_t
*data
= (isom_data_t
*)box
;
996 isom_bs_put_box_common( bs
, data
);
997 lsmash_bs_put_be16( bs
, data
->reserved
);
998 lsmash_bs_put_byte( bs
, data
->type_set_identifier
);
999 lsmash_bs_put_byte( bs
, data
->type_code
);
1000 lsmash_bs_put_be32( bs
, data
->the_locale
);
1001 if( data
->value
&& data
->value_length
)
1002 lsmash_bs_put_bytes( bs
, data
->value_length
, data
->value
);
1006 static int isom_write_metaitem( lsmash_bs_t
*bs
, isom_box_t
*box
)
1008 isom_bs_put_box_common( bs
, box
);
1012 static int isom_write_ilst( lsmash_bs_t
*bs
, isom_box_t
*box
)
1014 isom_bs_put_box_common( bs
, box
);
1018 static int isom_write_meta( lsmash_bs_t
*bs
, isom_box_t
*box
)
1020 isom_bs_put_box_common( bs
, box
);
1024 static int isom_write_cprt( lsmash_bs_t
*bs
, isom_box_t
*box
)
1026 isom_cprt_t
*cprt
= (isom_cprt_t
*)box
;
1027 isom_bs_put_box_common( bs
, cprt
);
1028 lsmash_bs_put_be16( bs
, cprt
->language
);
1029 lsmash_bs_put_bytes( bs
, cprt
->notice_length
, cprt
->notice
);
1033 static int isom_write_udta( lsmash_bs_t
*bs
, isom_box_t
*box
)
1035 isom_bs_put_box_common( bs
, box
);
1039 static int isom_write_trak( lsmash_bs_t
*bs
, isom_box_t
*box
)
1041 isom_bs_put_box_common( bs
, box
);
1045 static int isom_write_iods( lsmash_bs_t
*bs
, isom_box_t
*box
)
1047 isom_iods_t
*iods
= (isom_iods_t
*)box
;
1048 isom_bs_put_box_common( bs
, iods
);
1049 mp4sys_update_descriptor_size( iods
->OD
);
1050 return mp4sys_write_descriptor( bs
, iods
->OD
);
1053 static int isom_write_mvhd( lsmash_bs_t
*bs
, isom_box_t
*box
)
1055 isom_mvhd_t
*mvhd
= (isom_mvhd_t
*)box
;
1056 /* Check the version. */
1057 if( (mvhd
->file
&& !mvhd
->file
->undefined_64_ver
)
1058 && (mvhd
->creation_time
> UINT32_MAX
1059 || mvhd
->modification_time
> UINT32_MAX
1060 || mvhd
->duration
> UINT32_MAX
) )
1065 isom_bs_put_box_common( bs
, mvhd
);
1068 lsmash_bs_put_be64( bs
, mvhd
->creation_time
);
1069 lsmash_bs_put_be64( bs
, mvhd
->modification_time
);
1070 lsmash_bs_put_be32( bs
, mvhd
->timescale
);
1071 lsmash_bs_put_be64( bs
, mvhd
->duration
);
1075 lsmash_bs_put_be32( bs
, LSMASH_MIN( mvhd
->creation_time
, UINT32_MAX
) );
1076 lsmash_bs_put_be32( bs
, LSMASH_MIN( mvhd
->modification_time
, UINT32_MAX
) );
1077 lsmash_bs_put_be32( bs
, mvhd
->timescale
);
1078 lsmash_bs_put_be32( bs
, LSMASH_MIN( mvhd
->duration
, UINT32_MAX
) );
1080 lsmash_bs_put_be32( bs
, mvhd
->rate
);
1081 lsmash_bs_put_be16( bs
, mvhd
->volume
);
1082 lsmash_bs_put_be16( bs
, mvhd
->reserved
);
1083 lsmash_bs_put_be32( bs
, mvhd
->preferredLong
[0] );
1084 lsmash_bs_put_be32( bs
, mvhd
->preferredLong
[1] );
1085 for( int i
= 0; i
< 9; i
++ )
1086 lsmash_bs_put_be32( bs
, mvhd
->matrix
[i
] );
1087 lsmash_bs_put_be32( bs
, mvhd
->previewTime
);
1088 lsmash_bs_put_be32( bs
, mvhd
->previewDuration
);
1089 lsmash_bs_put_be32( bs
, mvhd
->posterTime
);
1090 lsmash_bs_put_be32( bs
, mvhd
->selectionTime
);
1091 lsmash_bs_put_be32( bs
, mvhd
->selectionDuration
);
1092 lsmash_bs_put_be32( bs
, mvhd
->currentTime
);
1093 lsmash_bs_put_be32( bs
, mvhd
->next_track_ID
);
1097 static void isom_bs_put_sample_flags( lsmash_bs_t
*bs
, isom_sample_flags_t
*flags
)
1099 uint32_t temp
= (flags
->reserved
<< 28)
1100 | (flags
->is_leading
<< 26)
1101 | (flags
->sample_depends_on
<< 24)
1102 | (flags
->sample_is_depended_on
<< 22)
1103 | (flags
->sample_has_redundancy
<< 20)
1104 | (flags
->sample_padding_value
<< 17)
1105 | (flags
->sample_is_non_sync_sample
<< 16)
1106 | flags
->sample_degradation_priority
;
1107 lsmash_bs_put_be32( bs
, temp
);
1110 static int isom_write_mehd( lsmash_bs_t
*bs
, isom_box_t
*box
)
1112 if( box
->manager
& LSMASH_PLACEHOLDER
)
1114 /* Movie Extends Header Box is not written immediately.
1115 * It's done after finishing all movie fragments.
1116 * The following will be overwritten by Movie Extends Header Box.
1117 * We use version 1 Movie Extends Header Box since it causes extra 4 bytes region
1118 * we cannot replace with empty Free Space Box as we place version 0 one. */
1119 box
->pos
= box
->file
->bs
->written
;
1120 lsmash_bs_put_be32( bs
, ISOM_BASEBOX_COMMON_SIZE
+ 12 );
1121 lsmash_bs_put_be32( bs
, ISOM_BOX_TYPE_FREE
.fourcc
);
1122 lsmash_bs_put_be32( bs
, 0 );
1123 lsmash_bs_put_be64( bs
, 0 );
1127 isom_mehd_t
*mehd
= (isom_mehd_t
*)box
;
1128 //mehd->version = mehd->fragment_duration > UINT32_MAX ? 1 : 0;
1129 isom_bs_put_box_common( bs
, mehd
);
1130 if( mehd
->version
== 1 )
1131 lsmash_bs_put_be64( bs
, mehd
->fragment_duration
);
1133 lsmash_bs_put_be32( bs
, LSMASH_MIN( mehd
->fragment_duration
, UINT32_MAX
) );
1138 static int isom_write_trex( lsmash_bs_t
*bs
, isom_box_t
*box
)
1140 isom_trex_t
*trex
= (isom_trex_t
*)box
;
1141 isom_bs_put_box_common( bs
, trex
);
1142 lsmash_bs_put_be32( bs
, trex
->track_ID
);
1143 lsmash_bs_put_be32( bs
, trex
->default_sample_description_index
);
1144 lsmash_bs_put_be32( bs
, trex
->default_sample_duration
);
1145 lsmash_bs_put_be32( bs
, trex
->default_sample_size
);
1146 isom_bs_put_sample_flags( bs
, &trex
->default_sample_flags
);
1150 static int isom_write_mvex( lsmash_bs_t
*bs
, isom_box_t
*box
)
1152 isom_bs_put_box_common( bs
, box
);
1156 static int isom_write_mfhd( lsmash_bs_t
*bs
, isom_box_t
*box
)
1158 isom_mfhd_t
*mfhd
= (isom_mfhd_t
*)box
;
1159 isom_bs_put_box_common( bs
, mfhd
);
1160 lsmash_bs_put_be32( bs
, mfhd
->sequence_number
);
1164 static int isom_write_tfhd( lsmash_bs_t
*bs
, isom_box_t
*box
)
1166 isom_tfhd_t
*tfhd
= (isom_tfhd_t
*)box
;
1167 isom_bs_put_box_common( bs
, tfhd
);
1168 lsmash_bs_put_be32( bs
, tfhd
->track_ID
);
1169 if( tfhd
->flags
& ISOM_TF_FLAGS_BASE_DATA_OFFSET_PRESENT
) lsmash_bs_put_be64( bs
, tfhd
->base_data_offset
);
1170 if( tfhd
->flags
& ISOM_TF_FLAGS_SAMPLE_DESCRIPTION_INDEX_PRESENT
) lsmash_bs_put_be32( bs
, tfhd
->sample_description_index
);
1171 if( tfhd
->flags
& ISOM_TF_FLAGS_DEFAULT_SAMPLE_DURATION_PRESENT
) lsmash_bs_put_be32( bs
, tfhd
->default_sample_duration
);
1172 if( tfhd
->flags
& ISOM_TF_FLAGS_DEFAULT_SAMPLE_SIZE_PRESENT
) lsmash_bs_put_be32( bs
, tfhd
->default_sample_size
);
1173 if( tfhd
->flags
& ISOM_TF_FLAGS_DEFAULT_SAMPLE_FLAGS_PRESENT
) isom_bs_put_sample_flags( bs
, &tfhd
->default_sample_flags
);
1177 static int isom_write_tfdt( lsmash_bs_t
*bs
, isom_box_t
*box
)
1179 isom_tfdt_t
*tfdt
= (isom_tfdt_t
*)box
;
1180 /* Check the version. */
1181 tfdt
->version
= tfdt
->baseMediaDecodeTime
> UINT32_MAX
? 1 : 0;
1183 isom_bs_put_box_common( bs
, tfdt
);
1184 if( tfdt
->version
== 1 )
1185 lsmash_bs_put_be64( bs
, tfdt
->baseMediaDecodeTime
);
1187 lsmash_bs_put_be32( bs
, tfdt
->baseMediaDecodeTime
);
1191 static int isom_write_trun( lsmash_bs_t
*bs
, isom_box_t
*box
)
1193 isom_trun_t
*trun
= (isom_trun_t
*)box
;
1194 isom_bs_put_box_common( bs
, trun
);
1195 lsmash_bs_put_be32( bs
, trun
->sample_count
);
1196 if( trun
->flags
& ISOM_TR_FLAGS_DATA_OFFSET_PRESENT
) lsmash_bs_put_be32( bs
, trun
->data_offset
);
1197 if( trun
->flags
& ISOM_TR_FLAGS_FIRST_SAMPLE_FLAGS_PRESENT
) isom_bs_put_sample_flags( bs
, &trun
->first_sample_flags
);
1198 if( trun
->optional
)
1199 for( lsmash_entry_t
*entry
= trun
->optional
->head
; entry
; entry
= entry
->next
)
1201 isom_trun_optional_row_t
*data
= (isom_trun_optional_row_t
*)entry
->data
;
1204 if( trun
->flags
& ISOM_TR_FLAGS_SAMPLE_DURATION_PRESENT
) lsmash_bs_put_be32( bs
, data
->sample_duration
);
1205 if( trun
->flags
& ISOM_TR_FLAGS_SAMPLE_SIZE_PRESENT
) lsmash_bs_put_be32( bs
, data
->sample_size
);
1206 if( trun
->flags
& ISOM_TR_FLAGS_SAMPLE_FLAGS_PRESENT
) isom_bs_put_sample_flags( bs
, &data
->sample_flags
);
1207 if( trun
->flags
& ISOM_TR_FLAGS_SAMPLE_COMPOSITION_TIME_OFFSET_PRESENT
) lsmash_bs_put_be32( bs
, data
->sample_composition_time_offset
);
1212 static int isom_write_traf( lsmash_bs_t
*bs
, isom_box_t
*box
)
1214 isom_bs_put_box_common( bs
, box
);
1218 static int isom_write_moof( lsmash_bs_t
*bs
, isom_box_t
*box
)
1220 isom_bs_put_box_common( bs
, box
);
1224 static int isom_write_tfra( lsmash_bs_t
*bs
, isom_box_t
*box
)
1226 isom_tfra_t
*tfra
= (isom_tfra_t
*)box
;
1227 isom_bs_put_box_common( bs
, tfra
);
1228 uint32_t temp
= (tfra
->reserved
<< 6)
1229 | (tfra
->length_size_of_traf_num
<< 4)
1230 | (tfra
->length_size_of_trun_num
<< 2)
1231 | tfra
->length_size_of_sample_num
;
1232 lsmash_bs_put_be32( bs
, tfra
->track_ID
);
1233 lsmash_bs_put_be32( bs
, temp
);
1234 lsmash_bs_put_be32( bs
, tfra
->number_of_entry
);
1237 void (*bs_put_funcs
[5])( lsmash_bs_t
*, uint64_t ) =
1239 lsmash_bs_put_byte_from_64
,
1240 lsmash_bs_put_be16_from_64
,
1241 lsmash_bs_put_be24_from_64
,
1242 lsmash_bs_put_be32_from_64
,
1245 void (*bs_put_time
) ( lsmash_bs_t
*, uint64_t ) = bs_put_funcs
[ tfra
->version
== 1 ? 4 : 3 ];
1246 void (*bs_put_moof_offset
) ( lsmash_bs_t
*, uint64_t ) = bs_put_funcs
[ tfra
->version
== 1 ? 4 : 3 ];
1247 void (*bs_put_traf_number
) ( lsmash_bs_t
*, uint64_t ) = bs_put_funcs
[ tfra
->length_size_of_traf_num
];
1248 void (*bs_put_trun_number
) ( lsmash_bs_t
*, uint64_t ) = bs_put_funcs
[ tfra
->length_size_of_trun_num
];
1249 void (*bs_put_sample_number
)( lsmash_bs_t
*, uint64_t ) = bs_put_funcs
[ tfra
->length_size_of_sample_num
];
1250 for( lsmash_entry_t
*entry
= tfra
->list
->head
; entry
; entry
= entry
->next
)
1252 isom_tfra_location_time_entry_t
*data
= (isom_tfra_location_time_entry_t
*)entry
->data
;
1255 bs_put_time ( bs
, data
->time
);
1256 bs_put_moof_offset ( bs
, data
->moof_offset
);
1257 bs_put_traf_number ( bs
, data
->traf_number
);
1258 bs_put_trun_number ( bs
, data
->trun_number
);
1259 bs_put_sample_number( bs
, data
->sample_number
);
1265 static int isom_write_mfro( lsmash_bs_t
*bs
, isom_box_t
*box
)
1267 isom_mfro_t
*mfro
= (isom_mfro_t
*)box
;
1268 isom_bs_put_box_common( bs
, mfro
);
1269 lsmash_bs_put_be32( bs
, mfro
->length
); /* determined at isom_write_mfra(). */
1273 static int isom_write_mfra( lsmash_bs_t
*bs
, isom_box_t
*box
)
1275 isom_mfra_t
*mfra
= (isom_mfra_t
*)box
;
1277 mfra
->mfro
->length
= mfra
->size
;
1278 isom_bs_put_box_common( bs
, mfra
);
1282 static int isom_write_mdat( lsmash_bs_t
*bs
, isom_box_t
*box
)
1284 isom_mdat_t
*mdat
= (isom_mdat_t
*)box
;
1285 lsmash_file_t
*file
= mdat
->file
;
1286 /* If any fragment, write the Media Data Box all at once. */
1287 if( file
->fragment
)
1289 /* Write the size and type fields of the Media Data Box. */
1290 mdat
->size
= ISOM_BASEBOX_COMMON_SIZE
+ file
->fragment
->pool_size
;
1291 if( mdat
->size
> UINT32_MAX
)
1292 mdat
->size
+= 8; /* large_size */
1293 isom_bs_put_box_common( bs
, mdat
);
1294 /* Write the samples in the current movie fragment. */
1295 for( lsmash_entry_t
*entry
= file
->fragment
->pool
->head
; entry
; entry
= entry
->next
)
1297 isom_sample_pool_t
*pool
= (isom_sample_pool_t
*)entry
->data
;
1300 lsmash_bs_put_bytes( bs
, pool
->size
, pool
->data
);
1302 mdat
->media_size
= file
->fragment
->pool_size
;
1305 if( mdat
->manager
& LSMASH_PLACEHOLDER
)
1307 /* Write the placeholder for large size. */
1308 if( !file
->free
&& !isom_add_free( file
) )
1310 isom_free_t
*skip
= file
->free
;
1311 skip
->pos
= bs
->offset
;
1312 skip
->size
= ISOM_BASEBOX_COMMON_SIZE
;
1313 skip
->manager
|= LSMASH_PLACEHOLDER
;
1314 if( isom_write_box( bs
, (isom_box_t
*)skip
) < 0 )
1316 /* Write an incomplete Media Data Box. */
1317 mdat
->pos
= bs
->offset
;
1318 mdat
->size
= ISOM_BASEBOX_COMMON_SIZE
;
1319 mdat
->manager
|= LSMASH_INCOMPLETE_BOX
;
1320 mdat
->manager
&= ~LSMASH_PLACEHOLDER
;
1321 isom_bs_put_box_common( bs
, mdat
);
1324 if( !bs
->unseekable
)
1326 /* Write the actual size. */
1327 uint64_t current_pos
= bs
->offset
;
1328 mdat
->size
= ISOM_BASEBOX_COMMON_SIZE
+ mdat
->media_size
;
1329 if( mdat
->size
> UINT32_MAX
)
1331 /* The placeholder is overwritten by the Media Data Box. */
1332 assert( file
->free
);
1333 mdat
->pos
= file
->free
->pos
;
1334 mdat
->size
+= file
->free
->size
;
1335 isom_remove_box_by_itself( file
->free
);
1337 lsmash_bs_write_seek( bs
, mdat
->pos
, SEEK_SET
);
1338 isom_bs_put_box_common( bs
, mdat
);
1339 /* isom_write_box() also calls lsmash_bs_flush_buffer() but it must do nothing. */
1340 int ret
= lsmash_bs_flush_buffer( bs
);
1341 lsmash_bs_write_seek( bs
, current_pos
, SEEK_SET
);
1347 static int isom_write_ftyp( lsmash_bs_t
*bs
, isom_box_t
*box
)
1349 isom_ftyp_t
*ftyp
= (isom_ftyp_t
*)box
;
1350 if( ftyp
->brand_count
== 0 )
1352 isom_bs_put_box_common( bs
, ftyp
);
1353 lsmash_bs_put_be32( bs
, ftyp
->major_brand
);
1354 lsmash_bs_put_be32( bs
, ftyp
->minor_version
);
1355 for( uint32_t i
= 0; i
< ftyp
->brand_count
; i
++ )
1356 lsmash_bs_put_be32( bs
, ftyp
->compatible_brands
[i
] );
1360 static int isom_write_moov( lsmash_bs_t
*bs
, isom_box_t
*box
)
1362 isom_bs_put_box_common( bs
, box
);
1366 static int isom_write_free( lsmash_bs_t
*bs
, isom_box_t
*box
)
1368 isom_free_t
*skip
= (isom_free_t
*)box
;
1369 isom_bs_put_box_common( bs
, skip
);
1370 if( skip
->data
&& skip
->length
)
1371 lsmash_bs_put_bytes( bs
, skip
->length
, skip
->data
);
1375 static int isom_write_sidx( lsmash_bs_t
*bs
, isom_box_t
*box
)
1377 isom_sidx_t
*sidx
= (isom_sidx_t
*)box
;
1378 /* Check the version. */
1379 if( sidx
->earliest_presentation_time
> UINT32_MAX
1380 || sidx
->first_offset
> UINT32_MAX
)
1385 isom_bs_put_box_common( bs
, sidx
);
1386 lsmash_bs_put_be32( bs
, sidx
->reference_ID
);
1387 lsmash_bs_put_be32( bs
, sidx
->timescale
);
1388 if( sidx
->version
== 0 )
1390 lsmash_bs_put_be32( bs
, LSMASH_MIN( sidx
->earliest_presentation_time
, UINT32_MAX
) );
1391 lsmash_bs_put_be32( bs
, LSMASH_MIN( sidx
->first_offset
, UINT32_MAX
) );
1395 lsmash_bs_put_be64( bs
, sidx
->earliest_presentation_time
);
1396 lsmash_bs_put_be64( bs
, sidx
->first_offset
);
1398 lsmash_bs_put_be16( bs
, sidx
->reserved
);
1399 lsmash_bs_put_be16( bs
, sidx
->reference_count
);
1400 for( lsmash_entry_t
*entry
= sidx
->list
->head
; entry
; entry
= entry
->next
)
1402 isom_sidx_referenced_item_t
*data
= (isom_sidx_referenced_item_t
*)entry
->data
;
1406 temp32
= (data
->reference_type
<< 31)
1407 | data
->reference_size
;
1408 lsmash_bs_put_be32( bs
, temp32
);
1409 lsmash_bs_put_be32( bs
, data
->subsegment_duration
);
1410 temp32
= (data
->starts_with_SAP
<< 31)
1411 | (data
->SAP_type
<< 28)
1412 | data
->SAP_delta_time
;
1413 lsmash_bs_put_be32( bs
, temp32
);
1418 int isom_write_box( lsmash_bs_t
*bs
, isom_box_t
*box
)
1421 /* Don't write any incomplete or already written box to a file. */
1422 if( !box
|| !box
->write
1423 || (bs
->stream
&& (box
->manager
& (LSMASH_INCOMPLETE_BOX
| LSMASH_WRITTEN_BOX
))) )
1425 if( box
->write( bs
, box
) < 0 )
1429 if( lsmash_bs_flush_buffer( bs
) < 0 )
1431 /* Don't write any child box if this box is a placeholder or an incomplete box. */
1432 if( box
->manager
& (LSMASH_PLACEHOLDER
| LSMASH_INCOMPLETE_BOX
) )
1435 box
->manager
|= LSMASH_WRITTEN_BOX
;
1437 return isom_write_children( bs
, box
);
1440 void isom_set_box_writer( isom_box_t
*box
)
1442 if( box
->manager
& LSMASH_BINARY_CODED_BOX
)
1444 box
->write
= isom_write_binary_coded_box
;
1447 else if( box
->manager
& LSMASH_UNKNOWN_BOX
)
1449 box
->write
= isom_write_unknown_box
;
1452 assert( box
->parent
);
1453 isom_box_t
*parent
= box
->parent
;
1454 if( lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_STSD
) )
1456 /* Check whether CODEC is RAW Video/Audio encapsulated in QTFF. */
1457 if( parent
->parent
&& parent
->parent
->parent
)
1459 isom_minf_t
*minf
= (isom_minf_t
*)parent
->parent
->parent
;
1461 box
->write
= isom_write_visual_description
;
1462 else if( minf
->smhd
)
1463 box
->write
= isom_write_audio_description
;
1467 if( lsmash_check_box_type_identical( box
->type
, QT_CODEC_TYPE_TEXT_TEXT
) )
1468 box
->write
= isom_write_qt_text_description
;
1469 else if( lsmash_check_box_type_identical( box
->type
, ISOM_CODEC_TYPE_TX3G_TEXT
) )
1470 box
->write
= isom_write_tx3g_description
;
1474 if( lsmash_check_box_type_identical( parent
->type
, QT_BOX_TYPE_WAVE
) )
1476 if( lsmash_check_box_type_identical( box
->type
, QT_BOX_TYPE_FRMA
) ) box
->write
= isom_write_frma
;
1477 else if( lsmash_check_box_type_identical( box
->type
, QT_BOX_TYPE_ENDA
) ) box
->write
= isom_write_enda
;
1478 else if( lsmash_check_box_type_identical( box
->type
, QT_BOX_TYPE_MP4A
) ) box
->write
= isom_write_mp4a
;
1479 else if( lsmash_check_box_type_identical( box
->type
, QT_BOX_TYPE_ESDS
) ) box
->write
= isom_write_esds
;
1480 else if( lsmash_check_box_type_identical( box
->type
, QT_BOX_TYPE_CHAN
) ) box
->write
= isom_write_chan
;
1481 else if( lsmash_check_box_type_identical( box
->type
, QT_BOX_TYPE_TERMINATOR
) ) box
->write
= isom_write_terminator
;
1482 else box
->write
= NULL
;
1485 if( lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_TREF
) )
1487 box
->write
= isom_write_track_reference_type
;
1490 static struct box_writer_table_tag
1492 lsmash_box_type_t type
;
1493 isom_extension_writer_t writer_func
;
1494 } box_writer_table
[128] = { { LSMASH_BOX_TYPE_INITIALIZER
, NULL
} };
1495 if( !box_writer_table
[0].writer_func
)
1497 /* Initialize the table. */
1499 #define ADD_BOX_WRITER_TABLE_ELEMENT( type, reader_func ) \
1500 box_writer_table[i++] = (struct box_writer_table_tag){ type, reader_func }
1501 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_FTYP
, isom_write_ftyp
);
1502 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_STYP
, isom_write_ftyp
);
1503 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_SIDX
, isom_write_sidx
);
1504 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_MOOV
, isom_write_moov
);
1505 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_MVHD
, isom_write_mvhd
);
1506 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_IODS
, isom_write_iods
);
1507 ADD_BOX_WRITER_TABLE_ELEMENT( QT_BOX_TYPE_CTAB
, isom_write_ctab
);
1508 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_ESDS
, isom_write_esds
);
1509 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_TRAK
, isom_write_trak
);
1510 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_TKHD
, isom_write_tkhd
);
1511 ADD_BOX_WRITER_TABLE_ELEMENT( QT_BOX_TYPE_TAPT
, isom_write_tapt
);
1512 ADD_BOX_WRITER_TABLE_ELEMENT( QT_BOX_TYPE_CLEF
, isom_write_clef
);
1513 ADD_BOX_WRITER_TABLE_ELEMENT( QT_BOX_TYPE_PROF
, isom_write_prof
);
1514 ADD_BOX_WRITER_TABLE_ELEMENT( QT_BOX_TYPE_ENOF
, isom_write_enof
);
1515 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_EDTS
, isom_write_edts
);
1516 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_ELST
, isom_write_elst
);
1517 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_TREF
, isom_write_tref
);
1518 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_MDIA
, isom_write_mdia
);
1519 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_MDHD
, isom_write_mdhd
);
1520 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_HDLR
, isom_write_hdlr
);
1521 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_MINF
, isom_write_minf
);
1522 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_VMHD
, isom_write_vmhd
);
1523 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_SMHD
, isom_write_smhd
);
1524 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_HMHD
, isom_write_hmhd
);
1525 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_NMHD
, isom_write_nmhd
);
1526 ADD_BOX_WRITER_TABLE_ELEMENT( QT_BOX_TYPE_GMHD
, isom_write_gmhd
);
1527 ADD_BOX_WRITER_TABLE_ELEMENT( QT_BOX_TYPE_GMIN
, isom_write_gmin
);
1528 ADD_BOX_WRITER_TABLE_ELEMENT( QT_BOX_TYPE_TEXT
, isom_write_text
);
1529 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_DINF
, isom_write_dinf
);
1530 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_DREF
, isom_write_dref
);
1531 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_URL
, isom_write_url
);
1532 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_STBL
, isom_write_stbl
);
1533 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_STSD
, isom_write_stsd
);
1534 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_BTRT
, isom_write_btrt
);
1535 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_COLR
, isom_write_colr
);
1536 ADD_BOX_WRITER_TABLE_ELEMENT( QT_BOX_TYPE_COLR
, isom_write_colr
);
1537 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_CLAP
, isom_write_clap
);
1538 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_PASP
, isom_write_pasp
);
1539 ADD_BOX_WRITER_TABLE_ELEMENT( QT_BOX_TYPE_GLBL
, isom_write_glbl
);
1540 ADD_BOX_WRITER_TABLE_ELEMENT( QT_BOX_TYPE_GAMA
, isom_write_gama
);
1541 ADD_BOX_WRITER_TABLE_ELEMENT( QT_BOX_TYPE_FIEL
, isom_write_fiel
);
1542 ADD_BOX_WRITER_TABLE_ELEMENT( QT_BOX_TYPE_CSPC
, isom_write_cspc
);
1543 ADD_BOX_WRITER_TABLE_ELEMENT( QT_BOX_TYPE_SGBT
, isom_write_sgbt
);
1544 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_STSL
, isom_write_stsl
);
1545 ADD_BOX_WRITER_TABLE_ELEMENT( QT_BOX_TYPE_WAVE
, isom_write_wave
);
1546 ADD_BOX_WRITER_TABLE_ELEMENT( QT_BOX_TYPE_MP4A
, isom_write_mp4a
);
1547 ADD_BOX_WRITER_TABLE_ELEMENT( QT_BOX_TYPE_CHAN
, isom_write_chan
);
1548 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_FTAB
, isom_write_ftab
);
1549 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_STTS
, isom_write_stts
);
1550 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_CTTS
, isom_write_ctts
);
1551 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_CSLG
, isom_write_cslg
);
1552 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_STSS
, isom_write_stss
);
1553 ADD_BOX_WRITER_TABLE_ELEMENT( QT_BOX_TYPE_STPS
, isom_write_stps
);
1554 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_SDTP
, isom_write_sdtp
);
1555 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_STSC
, isom_write_stsc
);
1556 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_STSZ
, isom_write_stsz
);
1557 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_STCO
, isom_write_stco
);
1558 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_CO64
, isom_write_stco
);
1559 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_SGPD
, isom_write_sgpd
);
1560 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_SBGP
, isom_write_sbgp
);
1561 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_UDTA
, isom_write_udta
);
1562 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_CHPL
, isom_write_chpl
);
1563 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_MVEX
, isom_write_mvex
);
1564 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_MEHD
, isom_write_mehd
);
1565 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_TREX
, isom_write_trex
);
1566 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_MOOF
, isom_write_moof
);
1567 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_MFHD
, isom_write_mfhd
);
1568 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_TRAF
, isom_write_traf
);
1569 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_TFHD
, isom_write_tfhd
);
1570 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_TFDT
, isom_write_tfdt
);
1571 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_TRUN
, isom_write_trun
);
1572 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_MDAT
, isom_write_mdat
);
1573 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_FREE
, isom_write_free
);
1574 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_SKIP
, isom_write_free
);
1575 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_META
, isom_write_meta
);
1576 ADD_BOX_WRITER_TABLE_ELEMENT( QT_BOX_TYPE_META
, isom_write_meta
);
1577 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_ILST
, isom_write_ilst
);
1578 ADD_BOX_WRITER_TABLE_ELEMENT( QT_BOX_TYPE_ILST
, isom_write_ilst
);
1579 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_MFRA
, isom_write_mfra
);
1580 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_TFRA
, isom_write_tfra
);
1581 ADD_BOX_WRITER_TABLE_ELEMENT( ISOM_BOX_TYPE_MFRO
, isom_write_mfro
);
1582 ADD_BOX_WRITER_TABLE_ELEMENT( LSMASH_BOX_TYPE_UNSPECIFIED
, NULL
);
1583 #undef ADD_BOX_WRITER_TABLE_ELEMENT
1585 for( int i
= 0; box_writer_table
[i
].writer_func
; i
++ )
1586 if( lsmash_check_box_type_identical( box
->type
, box_writer_table
[i
].type
) )
1588 box
->write
= box_writer_table
[i
].writer_func
;
1591 if( lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_ILST
)
1592 || lsmash_check_box_type_identical( parent
->type
, QT_BOX_TYPE_ILST
) )
1594 box
->write
= isom_write_metaitem
;
1597 if( parent
->parent
&& lsmash_check_box_type_identical( parent
->parent
->type
, ISOM_BOX_TYPE_ILST
) )
1599 if( lsmash_check_box_type_identical( box
->type
, ISOM_BOX_TYPE_MEAN
) )
1600 box
->write
= isom_write_mean
;
1601 else if( lsmash_check_box_type_identical( box
->type
, ISOM_BOX_TYPE_NAME
) )
1602 box
->write
= isom_write_name
;
1603 else if( lsmash_check_box_type_identical( box
->type
, ISOM_BOX_TYPE_DATA
) )
1604 box
->write
= isom_write_data
;
1608 else if( lsmash_check_box_type_identical( box
->type
, ISOM_BOX_TYPE_CPRT
) )
1610 /* Avoid confusing udta.cprt with ilst.cprt. */
1611 box
->write
= isom_write_cprt
;
1614 box
->write
= isom_write_unknown_box
;