1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2010-2017 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 */
37 #include "importer/importer.h"
39 static void isom_clear_compat_flags
44 /* Clear flags for compatibility. */
45 memset( (int8_t *)file
+ COMPAT_FLAGS_OFFSET
, 0, sizeof(lsmash_file_t
) - COMPAT_FLAGS_OFFSET
);
46 file
->min_isom_version
= UINT8_MAX
; /* undefined value */
49 int isom_check_compatibility
54 if( LSMASH_IS_NON_EXISTING_BOX( file
) )
55 return LSMASH_ERR_FUNCTION_PARAM
;
56 isom_clear_compat_flags( file
);
57 /* Get the brand container. */
58 isom_ftyp_t
*ftyp
= LSMASH_IS_EXISTING_BOX( file
->ftyp
)
60 : (isom_ftyp_t
*)lsmash_get_entry_data( &file
->styp_list
, 1 );
61 /* Check brand to decide mandatory boxes. */
62 if( LSMASH_IS_NON_EXISTING_BOX( ftyp
) )
64 /* No brand declaration means this file is a MP4 version 1 or QuickTime file format. */
65 if( LSMASH_IS_EXISTING_BOX( file
->moov
->iods
) )
67 file
->mp4_version1
= 1;
68 file
->isom_compatible
= 1;
72 file
->qt_compatible
= 1;
73 file
->undefined_64_ver
= 1;
77 for( uint32_t i
= 0; i
<= ftyp
->brand_count
; i
++ )
79 uint32_t brand
= (i
== ftyp
->brand_count
? ftyp
->major_brand
: ftyp
->compatible_brands
[i
]);
82 case ISOM_BRAND_TYPE_QT
:
83 file
->qt_compatible
= 1;
85 case ISOM_BRAND_TYPE_MP41
:
86 file
->mp4_version1
= 1;
88 case ISOM_BRAND_TYPE_MP42
:
89 file
->mp4_version2
= 1;
91 case ISOM_BRAND_TYPE_AVC1
:
92 case ISOM_BRAND_TYPE_ISOM
:
93 file
->max_isom_version
= LSMASH_MAX( file
->max_isom_version
, 1 );
94 file
->min_isom_version
= LSMASH_MIN( file
->min_isom_version
, 1 );
96 case ISOM_BRAND_TYPE_ISO2
:
97 file
->max_isom_version
= LSMASH_MAX( file
->max_isom_version
, 2 );
98 file
->min_isom_version
= LSMASH_MIN( file
->min_isom_version
, 2 );
100 case ISOM_BRAND_TYPE_ISO3
:
101 file
->max_isom_version
= LSMASH_MAX( file
->max_isom_version
, 3 );
102 file
->min_isom_version
= LSMASH_MIN( file
->min_isom_version
, 3 );
104 case ISOM_BRAND_TYPE_ISO4
:
105 file
->max_isom_version
= LSMASH_MAX( file
->max_isom_version
, 4 );
106 file
->min_isom_version
= LSMASH_MIN( file
->min_isom_version
, 4 );
108 case ISOM_BRAND_TYPE_ISO5
:
109 file
->max_isom_version
= LSMASH_MAX( file
->max_isom_version
, 5 );
110 file
->min_isom_version
= LSMASH_MIN( file
->min_isom_version
, 5 );
112 case ISOM_BRAND_TYPE_ISO6
:
113 file
->max_isom_version
= LSMASH_MAX( file
->max_isom_version
, 6 );
114 file
->min_isom_version
= LSMASH_MIN( file
->min_isom_version
, 6 );
116 case ISOM_BRAND_TYPE_ISO7
:
117 file
->max_isom_version
= LSMASH_MAX( file
->max_isom_version
, 7 );
118 file
->min_isom_version
= LSMASH_MIN( file
->min_isom_version
, 7 );
120 case ISOM_BRAND_TYPE_M4A
:
121 case ISOM_BRAND_TYPE_M4B
:
122 case ISOM_BRAND_TYPE_M4P
:
123 case ISOM_BRAND_TYPE_M4V
:
124 file
->itunes_movie
= 1;
126 case ISOM_BRAND_TYPE_3GP4
:
127 file
->max_3gpp_version
= LSMASH_MAX( file
->max_3gpp_version
, 4 );
129 case ISOM_BRAND_TYPE_3GP5
:
130 file
->max_3gpp_version
= LSMASH_MAX( file
->max_3gpp_version
, 5 );
132 case ISOM_BRAND_TYPE_3GE6
:
133 case ISOM_BRAND_TYPE_3GG6
:
134 case ISOM_BRAND_TYPE_3GP6
:
135 case ISOM_BRAND_TYPE_3GR6
:
136 case ISOM_BRAND_TYPE_3GS6
:
137 file
->max_3gpp_version
= LSMASH_MAX( file
->max_3gpp_version
, 6 );
139 case ISOM_BRAND_TYPE_3GP7
:
140 file
->max_3gpp_version
= LSMASH_MAX( file
->max_3gpp_version
, 7 );
142 case ISOM_BRAND_TYPE_3GP8
:
143 file
->max_3gpp_version
= LSMASH_MAX( file
->max_3gpp_version
, 8 );
145 case ISOM_BRAND_TYPE_3GE9
:
146 case ISOM_BRAND_TYPE_3GF9
:
147 case ISOM_BRAND_TYPE_3GG9
:
148 case ISOM_BRAND_TYPE_3GH9
:
149 case ISOM_BRAND_TYPE_3GM9
:
150 case ISOM_BRAND_TYPE_3GP9
:
151 case ISOM_BRAND_TYPE_3GR9
:
152 case ISOM_BRAND_TYPE_3GS9
:
153 case ISOM_BRAND_TYPE_3GT9
:
154 file
->max_3gpp_version
= LSMASH_MAX( file
->max_3gpp_version
, 9 );
161 case ISOM_BRAND_TYPE_AVC1
:
162 case ISOM_BRAND_TYPE_ISO2
:
163 case ISOM_BRAND_TYPE_ISO3
:
164 case ISOM_BRAND_TYPE_ISO4
:
165 case ISOM_BRAND_TYPE_ISO5
:
166 case ISOM_BRAND_TYPE_ISO6
:
167 file
->avc_extensions
= 1;
169 case ISOM_BRAND_TYPE_3GP4
:
170 case ISOM_BRAND_TYPE_3GP5
:
171 case ISOM_BRAND_TYPE_3GP6
:
172 case ISOM_BRAND_TYPE_3GP7
:
173 case ISOM_BRAND_TYPE_3GP8
:
174 case ISOM_BRAND_TYPE_3GP9
:
175 file
->forbid_tref
= 1;
177 case ISOM_BRAND_TYPE_3GH9
:
178 case ISOM_BRAND_TYPE_3GM9
:
179 case ISOM_BRAND_TYPE_DASH
:
180 case ISOM_BRAND_TYPE_DSMS
:
181 case ISOM_BRAND_TYPE_LMSG
:
182 case ISOM_BRAND_TYPE_MSDH
:
183 case ISOM_BRAND_TYPE_MSIX
:
184 case ISOM_BRAND_TYPE_SIMS
:
185 file
->media_segment
= 1;
191 file
->isom_compatible
= !file
->qt_compatible
192 || file
->mp4_version1
193 || file
->mp4_version2
194 || file
->itunes_movie
195 || file
->max_3gpp_version
;
196 file
->undefined_64_ver
= file
->qt_compatible
|| file
->itunes_movie
;
197 if( file
->flags
& LSMASH_FILE_MODE_WRITE
)
199 /* Media Segment is incompatible with ISO Base Media File Format version 4 or former must be compatible with
200 * version 6 or later since it requires default-base-is-moof and Track Fragment Base Media Decode Time Box. */
201 if( file
->media_segment
&& (file
->min_isom_version
< 5 || (file
->max_isom_version
&& file
->max_isom_version
< 6)) )
202 return LSMASH_ERR_INVALID_DATA
;
203 file
->allow_moof_base
= (file
->max_isom_version
>= 5 && file
->min_isom_version
>= 5)
204 || (file
->max_isom_version
== 0 && file
->min_isom_version
== UINT8_MAX
&& file
->media_segment
);
209 int isom_check_mandatory_boxes
214 assert( LSMASH_IS_EXISTING_BOX( file
) );
215 /* A movie requires at least one track. */
216 if( !file
->moov
->trak_list
.head
)
217 return LSMASH_ERR_INVALID_DATA
;
218 for( lsmash_entry_t
*entry
= file
->moov
->trak_list
.head
; entry
; entry
= entry
->next
)
220 isom_trak_t
*trak
= (isom_trak_t
*)entry
->data
;
221 if( LSMASH_IS_NON_EXISTING_BOX( trak
)
222 || LSMASH_IS_NON_EXISTING_BOX( trak
->tkhd
)
223 || LSMASH_IS_NON_EXISTING_BOX( trak
->mdia
->mdhd
)
224 || LSMASH_IS_NON_EXISTING_BOX( trak
->mdia
->hdlr
)
225 || LSMASH_IS_NON_EXISTING_BOX( trak
->mdia
->minf
->dinf
->dref
)
226 || LSMASH_IS_NON_EXISTING_BOX( trak
->mdia
->minf
->stbl
->stsd
)
227 || (LSMASH_IS_NON_EXISTING_BOX( trak
->mdia
->minf
->stbl
->stsz
)
228 && LSMASH_IS_NON_EXISTING_BOX( trak
->mdia
->minf
->stbl
->stz2
))
229 || LSMASH_IS_NON_EXISTING_BOX( trak
->mdia
->minf
->stbl
->stts
)
230 || LSMASH_IS_NON_EXISTING_BOX( trak
->mdia
->minf
->stbl
->stsc
)
231 || LSMASH_IS_NON_EXISTING_BOX( trak
->mdia
->minf
->stbl
->stco
) )
232 return LSMASH_ERR_INVALID_DATA
;
233 if( file
->qt_compatible
&& LSMASH_IS_NON_EXISTING_BOX( trak
->mdia
->minf
->hdlr
) )
234 return LSMASH_ERR_INVALID_DATA
;
235 isom_stbl_t
*stbl
= trak
->mdia
->minf
->stbl
;
236 if( !stbl
->stsd
->list
.head
)
237 return LSMASH_ERR_INVALID_DATA
;
239 && (!stbl
->stsd
->list
.head
240 || !stbl
->stts
->list
|| !stbl
->stts
->list
->head
241 || !stbl
->stsc
->list
|| !stbl
->stsc
->list
->head
242 || !stbl
->stco
->list
|| !stbl
->stco
->list
->head
) )
243 return LSMASH_ERR_INVALID_DATA
;
245 if( !file
->fragment
)
247 if( LSMASH_IS_NON_EXISTING_BOX( file
->moov
->mvex
) )
248 return LSMASH_ERR_INVALID_DATA
;
249 for( lsmash_entry_t
*entry
= file
->moov
->mvex
->trex_list
.head
; entry
; entry
= entry
->next
)
250 if( LSMASH_IS_NON_EXISTING_BOX( (isom_trex_t
*)entry
->data
) )
251 return LSMASH_ERR_INVALID_DATA
;
255 int isom_rearrange_data
258 lsmash_adhoc_remux_t
*remux
,
270 lsmash_bs_t
*bs
= file
->bs
;
273 while( read_num
== size
)
275 ret64
= lsmash_bs_write_seek( bs
, read_pos
, SEEK_SET
);
278 ret
= lsmash_bs_read_data( bs
, buf
[buf_switch
], &read_num
);
281 read_pos
= bs
->offset
;
283 ret64
= lsmash_bs_write_seek( bs
, write_pos
, SEEK_SET
);
286 ret
= lsmash_bs_write_data( bs
, buf
[buf_switch
], size
);
289 write_pos
= bs
->offset
;
291 remux
->func( remux
->param
, write_pos
, file_size
); // FIXME:
293 ret
= lsmash_bs_write_data( bs
, buf
[buf_switch
^ 0x1], read_num
);
297 remux
->func( remux
->param
, file_size
, file_size
); // FIXME:
301 static int isom_set_brands
304 lsmash_brand_type major_brand
,
305 uint32_t minor_version
,
306 lsmash_brand_type
*brands
,
310 if( brand_count
> 50 )
311 return LSMASH_ERR_FUNCTION_PARAM
; /* We support setting brands up to 50. */
312 if( major_brand
== 0 && (!brands
|| brand_count
== 0 || brands
[0] == 0) )
314 if( file
->flags
& LSMASH_FILE_MODE_INITIALIZATION
)
316 /* Absence of File Type Box means this file is a QuickTime or MP4 version 1 format file. */
317 isom_remove_box_by_itself( file
->ftyp
);
318 /* Anyway we use QTFF as a default file format. */
319 isom_clear_compat_flags( file
);
320 file
->qt_compatible
= 1;
324 /* The absence of the Segment Type Box is allowed.
325 * We set brands from the initialization segment after switching to this segment. */
326 for( lsmash_entry_t
*entry
= file
->styp_list
.head
; entry
; entry
= entry
->next
)
327 isom_remove_box_by_itself( entry
->data
);
328 if( LSMASH_IS_EXISTING_BOX( file
->initializer
) )
330 /* Copy flags for compatibility. */
331 memcpy( (int8_t *)file
+ COMPAT_FLAGS_OFFSET
, file
->initializer
, sizeof(lsmash_file_t
) - COMPAT_FLAGS_OFFSET
);
332 file
->isom_compatible
= 1;
333 file
->allow_moof_base
= 1;
334 file
->media_segment
= 1;
335 if( file
->min_isom_version
< 5 )
336 file
->min_isom_version
= 5;
337 if( file
->max_isom_version
< 6 )
338 file
->max_isom_version
= 6;
343 else if( major_brand
== 0 )
345 major_brand
= brands
[0];
346 lsmash_log( NULL
, LSMASH_LOG_WARNING
,
347 "major_brand is not specified. Use the first brand in the compatible brand list as major_brand.\n" );
352 if( file
->flags
& LSMASH_FILE_MODE_INITIALIZATION
)
354 /* Add File Type Box if absent yet. */
355 if( LSMASH_IS_NON_EXISTING_BOX( file
->ftyp
) && LSMASH_IS_BOX_ADDITION_FAILURE( isom_add_ftyp( file
) ) )
356 return LSMASH_ERR_NAMELESS
;
361 /* Add Segment Type Box if absent yet. */
362 ftyp
= file
->styp_list
.head
&& LSMASH_IS_EXISTING_BOX( (isom_styp_t
*)file
->styp_list
.head
->data
)
363 ? (isom_styp_t
*)file
->styp_list
.head
->data
364 : isom_add_styp( file
);
365 if( LSMASH_IS_NON_EXISTING_BOX( ftyp
) )
366 return LSMASH_ERR_NAMELESS
;
368 /* Allocate an array of compatible brands.
369 * ISO/IEC 14496-12 doesn't forbid the absence of brands in the compatible brand list.
370 * For a reason of safety, however, we set at least one brand in the list. */
371 size_t alloc_size
= (brand_count
? brand_count
: 1) * sizeof(uint32_t);
372 lsmash_brand_type
*compatible_brands
;
373 if( !file
->compatible_brands
)
374 compatible_brands
= lsmash_malloc( alloc_size
);
376 compatible_brands
= lsmash_realloc( file
->compatible_brands
, alloc_size
);
377 if( !compatible_brands
)
378 return LSMASH_ERR_MEMORY_ALLOC
;
379 /* Set compatible brands. */
381 for( uint32_t i
= 0; i
< brand_count
; i
++ )
382 compatible_brands
[i
] = brands
[i
];
385 /* At least one compatible brand. */
386 compatible_brands
[0] = major_brand
;
389 file
->compatible_brands
= compatible_brands
;
390 /* Duplicate an array of compatible brands. */
391 lsmash_free( ftyp
->compatible_brands
);
392 ftyp
->compatible_brands
= lsmash_memdup( compatible_brands
, alloc_size
);
393 if( !ftyp
->compatible_brands
)
395 lsmash_freep( &file
->compatible_brands
);
396 return LSMASH_ERR_MEMORY_ALLOC
;
398 ftyp
->size
= ISOM_BASEBOX_COMMON_SIZE
+ 8 + brand_count
* 4;
399 ftyp
->major_brand
= major_brand
;
400 ftyp
->minor_version
= minor_version
;
401 ftyp
->brand_count
= brand_count
;
402 file
->brand_count
= brand_count
;
403 return isom_check_compatibility( file
);
406 /*******************************
408 *******************************/
410 void lsmash_discard_boxes
415 if( LSMASH_IS_NON_EXISTING_BOX( root
)
416 || LSMASH_IS_NON_EXISTING_BOX( root
->file
) )
418 isom_remove_all_extension_boxes( &root
->file
->extensions
);
423 const char *filename
,
425 lsmash_file_parameters_t
*param
428 if( !filename
|| !param
)
429 return LSMASH_ERR_FUNCTION_PARAM
;
430 char mode
[4] = { 0 };
431 lsmash_file_mode file_mode
= 0;
434 memcpy( mode
, "w+b", 4 );
435 file_mode
= LSMASH_FILE_MODE_WRITE
436 | LSMASH_FILE_MODE_BOX
437 | LSMASH_FILE_MODE_INITIALIZATION
438 | LSMASH_FILE_MODE_MEDIA
;
440 else if( open_mode
== 1 )
442 memcpy( mode
, "rb", 3 );
443 file_mode
= LSMASH_FILE_MODE_READ
;
446 return LSMASH_ERR_FUNCTION_PARAM
;
448 _setmode( _fileno( stdin
), _O_BINARY
);
449 _setmode( _fileno( stdout
), _O_BINARY
);
450 _setmode( _fileno( stderr
), _O_BINARY
);
454 if( !strcmp( filename
, "-" ) )
456 if( file_mode
& LSMASH_FILE_MODE_READ
)
461 else if( file_mode
& LSMASH_FILE_MODE_WRITE
)
465 file_mode
|= LSMASH_FILE_MODE_FRAGMENTED
;
469 stream
= lsmash_fopen( filename
, mode
);
471 return LSMASH_ERR_NAMELESS
;
472 memset( param
, 0, sizeof(lsmash_file_parameters_t
) );
473 param
->mode
= file_mode
;
474 param
->opaque
= (void *)stream
;
475 param
->read
= lsmash_fread_wrapper
;
476 param
->write
= lsmash_fwrite_wrapper
;
477 param
->seek
= seekable
? lsmash_fseek_wrapper
: NULL
;
478 param
->major_brand
= 0;
479 param
->brands
= NULL
;
480 param
->brand_count
= 0;
481 param
->minor_version
= 0;
482 param
->max_chunk_duration
= 0.5;
483 param
->max_async_tolerance
= 2.0;
484 param
->max_chunk_size
= 4 * 1024 * 1024;
485 param
->max_read_size
= 4 * 1024 * 1024;
489 int lsmash_close_file
491 lsmash_file_parameters_t
*param
495 return LSMASH_ERR_NAMELESS
;
498 int ret
= fclose( (FILE *)param
->opaque
);
499 param
->opaque
= NULL
;
500 return ret
== 0 ? 0 : LSMASH_ERR_UNKNOWN
;
503 lsmash_file_t
*lsmash_set_file
506 lsmash_file_parameters_t
*param
509 if( LSMASH_IS_NON_EXISTING_BOX( root
) || !param
)
511 lsmash_file_t
*file
= isom_add_file( root
);
512 if( LSMASH_IS_NON_EXISTING_BOX( file
) )
514 lsmash_bs_t
*bs
= lsmash_bs_create();
518 file
->flags
= param
->mode
;
519 file
->bs
->stream
= param
->opaque
;
520 file
->bs
->read
= param
->read
;
521 file
->bs
->write
= param
->write
;
522 file
->bs
->seek
= param
->seek
;
523 file
->bs
->unseekable
= (param
->seek
== NULL
);
524 file
->bs
->buffer
.max_size
= param
->max_read_size
;
525 file
->max_chunk_duration
= param
->max_chunk_duration
;
526 file
->max_async_tolerance
= LSMASH_MAX( param
->max_async_tolerance
, 2 * param
->max_chunk_duration
);
527 file
->max_chunk_size
= param
->max_chunk_size
;
528 if( (file
->flags
& LSMASH_FILE_MODE_WRITE
)
529 && (file
->flags
& LSMASH_FILE_MODE_BOX
) )
531 /* Construction of Segment Index Box requires seekability at our current implementation.
532 * If segment is not so large, data rearrangement can be avoided by buffering i.e. the
533 * seekability is not essential, but at present we don't support buffering of all materials
535 if( (file
->flags
& LSMASH_FILE_MODE_INDEX
) && file
->bs
->unseekable
)
537 /* Establish the fragment handler if required. */
538 if( file
->flags
& LSMASH_FILE_MODE_FRAGMENTED
)
540 file
->fragment
= lsmash_malloc_zero( sizeof(isom_fragment_manager_t
) );
541 if( !file
->fragment
)
543 file
->fragment
->first_moof_pos
= FIRST_MOOF_POS_UNDETERMINED
;
544 file
->fragment
->pool
= lsmash_create_entry_list();
545 if( !file
->fragment
->pool
)
548 else if( file
->bs
->unseekable
)
549 /* For unseekable output operations, LSMASH_FILE_MODE_FRAGMENTED shall be set. */
551 /* Establish file types. */
552 if( isom_set_brands( file
, param
->major_brand
,
553 param
->minor_version
,
554 param
->brands
, param
->brand_count
) < 0 )
556 /* Create the movie header if the initialization of the streams is required. */
557 if( (file
->flags
& LSMASH_FILE_MODE_INITIALIZATION
) && !isom_movie_create( file
) )
560 if( LSMASH_IS_NON_EXISTING_BOX( root
->file
) )
564 isom_remove_box_by_itself( file
);
568 int64_t lsmash_read_file
571 lsmash_file_parameters_t
*param
574 if( LSMASH_IS_NON_EXISTING_BOX( file
) )
575 return (int64_t)LSMASH_ERR_FUNCTION_PARAM
;
577 return (int64_t)LSMASH_ERR_NAMELESS
;
578 int64_t ret
= LSMASH_ERR_NAMELESS
;
579 if( file
->flags
& (LSMASH_FILE_MODE_READ
| LSMASH_FILE_MODE_DUMP
) )
581 importer_t
*importer
= lsmash_importer_alloc( file
->root
);
583 return (int64_t)LSMASH_ERR_MEMORY_ALLOC
;
584 lsmash_importer_set_file( importer
, file
);
585 ret
= lsmash_importer_find( importer
, "ISOBMFF/QTFF", !file
->bs
->unseekable
);
590 if( LSMASH_IS_EXISTING_BOX( file
->ftyp
) )
593 isom_ftyp_t
*ftyp
= file
->ftyp
;
594 param
->major_brand
= ftyp
->major_brand
? ftyp
->major_brand
: ISOM_BRAND_TYPE_QT
;
595 param
->minor_version
= ftyp
->minor_version
;
596 param
->brands
= file
->compatible_brands
;
597 param
->brand_count
= file
->brand_count
;
599 else if( file
->styp_list
.head
&& LSMASH_IS_EXISTING_BOX( (isom_styp_t
*)file
->styp_list
.head
->data
) )
602 isom_styp_t
*styp
= (isom_styp_t
*)file
->styp_list
.head
->data
;
603 param
->major_brand
= styp
->major_brand
? styp
->major_brand
: ISOM_BRAND_TYPE_QT
;
604 param
->minor_version
= styp
->minor_version
;
605 param
->brands
= file
->compatible_brands
;
606 param
->brand_count
= file
->brand_count
;
610 param
->major_brand
= file
->mp4_version1
? ISOM_BRAND_TYPE_MP41
: ISOM_BRAND_TYPE_QT
;
611 param
->minor_version
= 0;
612 param
->brands
= NULL
;
613 param
->brand_count
= 0;
620 int lsmash_activate_file
626 if( !root
|| !file
|| file
->root
!= root
)
627 return LSMASH_ERR_FUNCTION_PARAM
;
632 int lsmash_switch_media_segment
635 lsmash_file_t
*successor
,
636 lsmash_adhoc_remux_t
*remux
639 if( LSMASH_IS_NON_EXISTING_BOX( root
) || !remux
)
640 return LSMASH_ERR_FUNCTION_PARAM
;
641 lsmash_file_t
*predecessor
= root
->file
;
642 if( LSMASH_IS_NON_EXISTING_BOX( predecessor
) || LSMASH_IS_NON_EXISTING_BOX( successor
)
643 || predecessor
== successor
644 || predecessor
->root
!= successor
->root
645 || LSMASH_IS_NON_EXISTING_BOX( predecessor
->root
) || LSMASH_IS_NON_EXISTING_BOX( successor
->root
)
646 || predecessor
->root
!= root
|| successor
->root
!= root
647 || (successor
->flags
& LSMASH_FILE_MODE_INITIALIZATION
)
648 || !(successor
->flags
& LSMASH_FILE_MODE_MEDIA
)
649 || !(predecessor
->flags
& LSMASH_FILE_MODE_WRITE
) || !(successor
->flags
& LSMASH_FILE_MODE_WRITE
)
650 || !(predecessor
->flags
& LSMASH_FILE_MODE_BOX
) || !(successor
->flags
& LSMASH_FILE_MODE_BOX
)
651 || !(predecessor
->flags
& LSMASH_FILE_MODE_FRAGMENTED
) || !(successor
->flags
& LSMASH_FILE_MODE_FRAGMENTED
)
652 || !(predecessor
->flags
& LSMASH_FILE_MODE_SEGMENT
) || !(successor
->flags
& LSMASH_FILE_MODE_SEGMENT
)
653 || (!(predecessor
->flags
& LSMASH_FILE_MODE_MEDIA
) && !(predecessor
->flags
& LSMASH_FILE_MODE_INITIALIZATION
)) )
654 return LSMASH_ERR_FUNCTION_PARAM
;
655 int ret
= isom_finish_final_fragment_movie( predecessor
, remux
);
658 if( predecessor
->flags
& LSMASH_FILE_MODE_INITIALIZATION
)
660 if( predecessor
->initializer
!= predecessor
)
661 return LSMASH_ERR_INVALID_DATA
;
662 successor
->initializer
= predecessor
;
665 successor
->initializer
= predecessor
->initializer
;
666 isom_styp_t
*styp
= (isom_styp_t
*)lsmash_get_entry_data( &successor
->styp_list
, 1 );
667 if( LSMASH_IS_NON_EXISTING_BOX( styp
) )
669 ret
= isom_set_brands( successor
, 0, 0, NULL
, 0 );
671 return LSMASH_ERR_NAMELESS
;
673 successor
->fragment_count
= predecessor
->fragment_count
;
674 root
->file
= successor
;