From 36dcabe1c9dfd7119ff558eef0e3f030d6f6d88f Mon Sep 17 00:00:00 2001 From: Yusuke Nakamura Date: Thu, 20 Nov 2014 01:32:42 +0900 Subject: [PATCH] importer: Wrap timeline constructor in importer. --- cli/muxer.c | 6 +++++ core/timeline.c | 38 +++++++++++++++++++++++++++++++- core/timeline.h | 11 +++++++++- importer/importer.c | 9 ++++++++ importer/importer.h | 28 +++++++++++++++--------- importer/isobm_imp.c | 62 ++++++++++++++++++++++++++++++++-------------------- 6 files changed, 118 insertions(+), 36 deletions(-) diff --git a/cli/muxer.c b/cli/muxer.c index e1a8968..58f79b3 100644 --- a/cli/muxer.c +++ b/cli/muxer.c @@ -734,6 +734,12 @@ static int open_input_files( muxer_t *muxer ) input->current_track_number ++ ) { input_track_t *in_track = &input->track[input->current_track_number - 1]; + int err = lsmash_importer_construct_timeline( input->importer, input->current_track_number ); + if( err < 0 && err != LSMASH_ERR_PATCH_WELCOME ) + { + in_track->active = 0; + continue; + } in_track->summary = lsmash_duplicate_summary( input->importer, input->current_track_number ); if( !in_track->summary ) return ERROR_MSG( "failed to get input summary.\n" ); diff --git a/core/timeline.c b/core/timeline.c index cb75c7e..08cc405 100644 --- a/core/timeline.c +++ b/core/timeline.c @@ -34,6 +34,8 @@ #include "codecs/mp4sys.h" #include "codecs/description.h" +#include "importer/importer.h" + #define NO_RANDOM_ACCESS_POINT 0xffffffff typedef struct @@ -659,7 +661,7 @@ static int isom_get_random_access_point_grouping_info return 0; } -int lsmash_construct_timeline( lsmash_root_t *root, uint32_t track_ID ) +int isom_construct_timeline( lsmash_root_t *root, uint32_t track_ID ) { if( isom_check_initializer_present( root ) < 0 ) return LSMASH_ERR_FUNCTION_PARAM; @@ -1338,6 +1340,40 @@ fail: return err; } +int lsmash_construct_timeline( lsmash_root_t *root, uint32_t track_ID ) +{ + if( !root + || !root->file + || track_ID == 0 ) + return LSMASH_ERR_FUNCTION_PARAM; + uint32_t track_number; + if( root->file->initializer ) + { + if( !root->file->initializer->moov ) + return LSMASH_ERR_INVALID_DATA; + track_number = 1; + int track_found = 0; + for( lsmash_entry_t *entry = root->file->initializer->moov->trak_list.head; entry; entry = entry->next ) + { + isom_trak_t *trak = (isom_trak_t *)entry->data; + if( !trak + || !trak->tkhd ) + continue; + if( trak->tkhd->track_ID == track_ID ) + { + track_found = 1; + break; + } + ++track_number; + } + if( !track_found ) + return LSMASH_ERR_NAMELESS; + } + else + track_number = track_ID; + return lsmash_importer_construct_timeline( root->file->importer, track_number ); +} + int lsmash_get_dts_from_media_timeline( lsmash_root_t *root, uint32_t track_ID, uint32_t sample_number, uint64_t *dts ) { if( !sample_number || !dts ) diff --git a/core/timeline.h b/core/timeline.h index 1e236a1..a25ac76 100644 --- a/core/timeline.h +++ b/core/timeline.h @@ -23,6 +23,15 @@ #ifndef LSMASH_TIMELINE_H #define LSMASH_TIMELINE_H -void isom_remove_timelines( lsmash_file_t *file ); +void isom_remove_timelines +( + lsmash_file_t *file +); + +int isom_construct_timeline +( + lsmash_root_t *root, + uint32_t track_ID +); #endif /* LSMASH_TIMELINE_H */ diff --git a/importer/importer.c b/importer/importer.c index 3a3c15b..3999dbb 100644 --- a/importer/importer.c +++ b/importer/importer.c @@ -231,6 +231,15 @@ uint32_t lsmash_importer_get_last_delta( importer_t *importer, uint32_t track_nu return importer->funcs.get_last_delta( importer, track_number ); } +int lsmash_importer_construct_timeline( importer_t *importer, uint32_t track_number ) +{ + if( !importer ) + return LSMASH_ERR_FUNCTION_PARAM; + if( !importer->funcs.construct_timeline ) + return LSMASH_ERR_PATCH_WELCOME; + return importer->funcs.construct_timeline( importer, track_number ); +} + uint32_t lsmash_importer_get_track_count( importer_t *importer ) { if( !importer || !importer->summaries ) diff --git a/importer/importer.h b/importer/importer.h index e9afe2a..f5461bd 100644 --- a/importer/importer.h +++ b/importer/importer.h @@ -34,10 +34,11 @@ typedef struct importer_tag importer_t; #include "core/box.h" #include "codecs/description.h" -typedef void ( *importer_cleanup ) ( importer_t * ); -typedef int ( *importer_get_accessunit ) ( importer_t *, uint32_t, lsmash_sample_t ** ); -typedef int ( *importer_probe ) ( importer_t * ); -typedef uint32_t ( *importer_get_last_duration )( importer_t *, uint32_t ); +typedef void ( *importer_cleanup ) ( importer_t * ); +typedef int ( *importer_get_accessunit ) ( importer_t *, uint32_t, lsmash_sample_t ** ); +typedef int ( *importer_probe ) ( importer_t * ); +typedef uint32_t ( *importer_get_last_duration ) ( importer_t *, uint32_t ); +typedef int ( *importer_construct_timeline )( importer_t *, uint32_t ); typedef enum { @@ -49,12 +50,13 @@ typedef enum typedef struct { - lsmash_class_t class; - int detectable; - importer_probe probe; - importer_get_accessunit get_accessunit; - importer_get_last_duration get_last_delta; - importer_cleanup cleanup; + lsmash_class_t class; + int detectable; + importer_probe probe; + importer_get_accessunit get_accessunit; + importer_get_last_duration get_last_delta; + importer_cleanup cleanup; + importer_construct_timeline construct_timeline; } importer_functions; struct importer_tag @@ -119,6 +121,12 @@ uint32_t lsmash_importer_get_last_delta uint32_t track_number ); +int lsmash_importer_construct_timeline +( + importer_t *importer, + uint32_t track_number +); + uint32_t lsmash_importer_get_track_count ( importer_t *importer diff --git a/importer/isobm_imp.c b/importer/isobm_imp.c index a1070d0..f64aaaa 100644 --- a/importer/isobm_imp.c +++ b/importer/isobm_imp.c @@ -161,30 +161,7 @@ static int isobm_importer_probe( importer_t *importer ) err = LSMASH_ERR_PATCH_WELCOME; goto fail; } - if( (err = lsmash_construct_timeline( root, isobm_imp->track_ID )) < 0 ) - goto fail; lsmash_summary_t *summary = lsmash_get_summary( root, isobm_imp->track_ID, 1 ); - summary->max_au_length = lsmash_get_max_sample_size_in_media_timeline( root, isobm_imp->track_ID ); - if( summary->summary_type == LSMASH_SUMMARY_TYPE_VIDEO ) - { - lsmash_media_ts_list_t ts_list; - if( (err = lsmash_get_media_timestamps( root, isobm_imp->track_ID, &ts_list )) < 0 ) - goto fail; - uint32_t last_sample_delta; - if( (err = lsmash_get_last_sample_delta_from_media_timeline( root, isobm_imp->track_ID, &last_sample_delta )) < 0 ) - goto fail; - isobm_imp->timebase = last_sample_delta; - for( uint32_t i = 1; i < ts_list.sample_count; i++ ) - isobm_imp->timebase = lsmash_get_gcd( isobm_imp->timebase, ts_list.timestamp[i].dts - ts_list.timestamp[i - 1].dts ); - lsmash_sort_timestamps_composition_order( &ts_list ); - for( uint32_t i = 1; i < ts_list.sample_count; i++ ) - isobm_imp->timebase = lsmash_get_gcd( isobm_imp->timebase, ts_list.timestamp[i].cts - ts_list.timestamp[i - 1].cts ); - lsmash_delete_media_timestamps( &ts_list ); - if( isobm_imp->timebase == 0 ) - isobm_imp->timebase = 1; - ((lsmash_video_summary_t *)summary)->timebase = isobm_imp->timebase; - ((lsmash_video_summary_t *)summary)->timescale = lsmash_get_media_timescale( root, isobm_imp->track_ID ); - } if( (err = lsmash_add_entry( importer->summaries, summary )) < 0 ) { lsmash_cleanup_summary( (lsmash_summary_t *)summary ); @@ -213,6 +190,42 @@ static uint32_t isobm_importer_get_last_delta( importer_t *importer, uint32_t tr return last_sample_delta / isobm_imp->timebase; } +static int isobm_importer_construct_timeline( importer_t *importer, uint32_t track_number ) +{ + lsmash_root_t *root = importer->root; + uint32_t track_ID = lsmash_get_track_ID( root, track_number ); + int err = isom_construct_timeline( root, track_ID ); + if( err < 0 ) + return err; + if( root && root == importer->file->root ) + { + lsmash_summary_t *summary = lsmash_get_entry_data( importer->summaries, track_number ); + summary->max_au_length = lsmash_get_max_sample_size_in_media_timeline( root, track_ID ); + if( summary->summary_type == LSMASH_SUMMARY_TYPE_VIDEO ) + { + lsmash_media_ts_list_t ts_list; + if( (err = lsmash_get_media_timestamps( root, track_ID, &ts_list )) < 0 ) + return err; + uint32_t last_sample_delta; + if( (err = lsmash_get_last_sample_delta_from_media_timeline( root, track_ID, &last_sample_delta )) < 0 ) + return err; + isobm_importer_t *isobm_imp = (isobm_importer_t *)importer->info; + isobm_imp->timebase = last_sample_delta; + for( uint32_t i = 1; i < ts_list.sample_count; i++ ) + isobm_imp->timebase = lsmash_get_gcd( isobm_imp->timebase, ts_list.timestamp[i].dts - ts_list.timestamp[i - 1].dts ); + lsmash_sort_timestamps_composition_order( &ts_list ); + for( uint32_t i = 1; i < ts_list.sample_count; i++ ) + isobm_imp->timebase = lsmash_get_gcd( isobm_imp->timebase, ts_list.timestamp[i].cts - ts_list.timestamp[i - 1].cts ); + lsmash_delete_media_timestamps( &ts_list ); + if( isobm_imp->timebase == 0 ) + isobm_imp->timebase = 1; + ((lsmash_video_summary_t *)summary)->timebase = isobm_imp->timebase; + ((lsmash_video_summary_t *)summary)->timescale = lsmash_get_media_timescale( root, track_ID ); + } + } + return 0; +} + const importer_functions isobm_importer = { { "ISOBMFF/QTFF", offsetof( importer_t, log_level ) }, @@ -220,5 +233,6 @@ const importer_functions isobm_importer = isobm_importer_probe, isobm_importer_get_accessunit, isobm_importer_get_last_delta, - isobm_importer_cleanup + isobm_importer_cleanup, + isobm_importer_construct_timeline }; -- 2.11.4.GIT