From 32ae212640ff52b8b75a057bda2ed12bdf7c7bff Mon Sep 17 00:00:00 2001 From: Yusuke Nakamura Date: Wed, 19 Nov 2014 20:27:08 +0900 Subject: [PATCH] importer: Allocate sample buffer in individual importers. --- cli/a52_imp.c | 50 +++++++++++++------------- cli/adts_imp.c | 31 +++++++++-------- cli/als_imp.c | 40 ++++++++++----------- cli/amr_imp.c | 25 ++++++------- cli/dts_imp.c | 25 ++++++------- cli/importer.c | 7 ++-- cli/importer.h | 8 ++--- cli/isobm_imp.c | 33 +++++++----------- cli/mp3_imp.c | 33 ++++++++++-------- cli/muxer.c | 14 ++++---- cli/nalu_imp.c | 106 +++++++++++++++++++++++++++++--------------------------- cli/vc1_imp.c | 37 ++++++++++---------- cli/wave_imp.c | 28 +++++++-------- 13 files changed, 219 insertions(+), 218 deletions(-) diff --git a/cli/a52_imp.c b/cli/a52_imp.c index 96837b5..a7ec282 100644 --- a/cli/a52_imp.c +++ b/cli/a52_imp.c @@ -148,7 +148,7 @@ static int ac3_buffer_frame( uint8_t *buffer, lsmash_bs_t *bs ) return 0; } -static int ac3_importer_get_accessunit( importer_t *importer, uint32_t track_number, lsmash_sample_t *buffered_sample ) +static int ac3_importer_get_accessunit( importer_t *importer, uint32_t track_number, lsmash_sample_t **p_sample ) { if( !importer->info ) return LSMASH_ERR_NAMELESS; @@ -163,16 +163,11 @@ static int ac3_importer_get_accessunit( importer_t *importer, uint32_t track_num if( current_status == IMPORTER_ERROR ) return LSMASH_ERR_NAMELESS; if( current_status == IMPORTER_EOF ) - { - buffered_sample->length = 0; - return 0; - } + return IMPORTER_EOF; lsmash_ac3_specific_parameters_t *param = &info->dac3_param; uint32_t frame_size = ac3_frame_size_table[ param->frmsizecod >> 1 ][ param->fscod ]; if( param->fscod == 0x1 && param->frmsizecod & 0x1 ) frame_size += 2; - if( buffered_sample->length < frame_size ) - return LSMASH_ERR_NAMELESS; if( current_status == IMPORTER_CHANGE ) { lsmash_codec_specific_t *cs = isom_get_codec_specific( summary->opaque, LSMASH_CODEC_SPECIFIC_DATA_TYPE_ISOM_AUDIO_AC_3 ); @@ -185,12 +180,16 @@ static int ac3_importer_get_accessunit( importer_t *importer, uint32_t track_num summary->channels = ac3_get_channel_count( param ); //summary->layout_tag = ac3_channel_layout_table[ param->acmod ][ param->lfeon ]; } - memcpy( buffered_sample->data, ac3_imp->buffer, frame_size ); - buffered_sample->length = frame_size; - buffered_sample->dts = ac3_imp->au_number++ * summary->samples_in_frame; - buffered_sample->cts = buffered_sample->dts; - buffered_sample->prop.ra_flags = ISOM_SAMPLE_RANDOM_ACCESS_FLAG_SYNC; - buffered_sample->prop.pre_roll.distance = 1; /* MDCT */ + lsmash_sample_t *sample = lsmash_create_sample( frame_size ); + if( !sample ) + return LSMASH_ERR_MEMORY_ALLOC; + *p_sample = sample; + memcpy( sample->data, ac3_imp->buffer, frame_size ); + sample->length = frame_size; + sample->dts = ac3_imp->au_number++ * summary->samples_in_frame; + sample->cts = sample->dts; + sample->prop.ra_flags = ISOM_SAMPLE_RANDOM_ACCESS_FLAG_SYNC; + sample->prop.pre_roll.distance = 1; /* MDCT */ lsmash_bs_t *bs = info->bits->bs; ac3_imp->next_frame_pos += frame_size; lsmash_bs_read_seek( bs, ac3_imp->next_frame_pos, SEEK_SET ); @@ -482,7 +481,7 @@ static int eac3_importer_get_next_accessunit_internal( importer_t *importer ) return bs->error ? LSMASH_ERR_NAMELESS : 0; } -static int eac3_importer_get_accessunit( importer_t *importer, uint32_t track_number, lsmash_sample_t *buffered_sample ) +static int eac3_importer_get_accessunit( importer_t *importer, uint32_t track_number, lsmash_sample_t **p_sample ) { if( !importer->info ) return LSMASH_ERR_NAMELESS; @@ -494,13 +493,10 @@ static int eac3_importer_get_accessunit( importer_t *importer, uint32_t track_nu eac3_importer_t *eac3_imp = (eac3_importer_t *)importer->info; eac3_info_t *info = &eac3_imp->info; importer_status current_status = importer->status; - if( current_status == IMPORTER_ERROR || buffered_sample->length < eac3_imp->au_length ) + if( current_status == IMPORTER_ERROR ) return LSMASH_ERR_NAMELESS; if( current_status == IMPORTER_EOF && eac3_imp->au_length == 0 ) - { - buffered_sample->length = 0; - return 0; - } + return IMPORTER_EOF; if( current_status == IMPORTER_CHANGE ) { lsmash_codec_specific_t *cs = isom_get_codec_specific( summary->opaque, LSMASH_CODEC_SPECIFIC_DATA_TYPE_ISOM_AUDIO_EC_3 ); @@ -514,12 +510,16 @@ static int eac3_importer_get_accessunit( importer_t *importer, uint32_t track_nu eac3_update_sample_rate( &summary->frequency, &info->dec3_param, &eac3_imp->current_fscod2 ); eac3_update_channel_count( &summary->channels, &info->dec3_param ); } - memcpy( buffered_sample->data, eac3_imp->au, eac3_imp->au_length ); - buffered_sample->length = eac3_imp->au_length; - buffered_sample->dts = eac3_imp->au_number++ * summary->samples_in_frame; - buffered_sample->cts = buffered_sample->dts; - buffered_sample->prop.ra_flags = ISOM_SAMPLE_RANDOM_ACCESS_FLAG_SYNC; - buffered_sample->prop.pre_roll.distance = 1; /* MDCT */ + lsmash_sample_t *sample = lsmash_create_sample( eac3_imp->au_length ); + if( !sample ) + return LSMASH_ERR_MEMORY_ALLOC; + *p_sample = sample; + memcpy( sample->data, eac3_imp->au, eac3_imp->au_length ); + sample->length = eac3_imp->au_length; + sample->dts = eac3_imp->au_number++ * summary->samples_in_frame; + sample->cts = sample->dts; + sample->prop.ra_flags = ISOM_SAMPLE_RANDOM_ACCESS_FLAG_SYNC; + sample->prop.pre_roll.distance = 1; /* MDCT */ if( importer->status == IMPORTER_EOF ) { eac3_imp->au_length = 0; diff --git a/cli/adts_imp.c b/cli/adts_imp.c index cbd6849..79d1fad 100644 --- a/cli/adts_imp.c +++ b/cli/adts_imp.c @@ -302,9 +302,9 @@ static lsmash_audio_summary_t *mp4sys_adts_create_summary static int mp4sys_adts_get_accessunit ( - importer_t *importer, - uint32_t track_number, - lsmash_sample_t *buffered_sample + importer_t *importer, + uint32_t track_number, + lsmash_sample_t **p_sample ) { if( !importer->info ) @@ -314,13 +314,10 @@ static int mp4sys_adts_get_accessunit mp4sys_adts_importer_t *adts_imp = (mp4sys_adts_importer_t *)importer->info; importer_status current_status = importer->status; uint16_t raw_data_block_size = adts_imp->variable_header.raw_data_block_size[ adts_imp->raw_data_block_idx ]; - if( current_status == IMPORTER_ERROR || buffered_sample->length < raw_data_block_size ) + if( current_status == IMPORTER_ERROR ) return LSMASH_ERR_NAMELESS; if( current_status == IMPORTER_EOF ) - { - buffered_sample->length = 0; - return 0; - } + return IMPORTER_EOF; if( current_status == IMPORTER_CHANGE ) { lsmash_audio_summary_t *summary = mp4sys_adts_create_summary( &adts_imp->header ); @@ -335,23 +332,27 @@ static int mp4sys_adts_get_accessunit } lsmash_bs_t *bs = importer->bs; /* read a raw_data_block(), typically == payload of a ADTS frame */ - if( lsmash_bs_get_bytes_ex( bs, raw_data_block_size, buffered_sample->data ) != raw_data_block_size ) + lsmash_sample_t *sample = lsmash_create_sample( raw_data_block_size ); + if( !sample ) + return LSMASH_ERR_MEMORY_ALLOC; + *p_sample = sample; + if( lsmash_bs_get_bytes_ex( bs, raw_data_block_size, sample->data ) != raw_data_block_size ) { importer->status = IMPORTER_ERROR; return LSMASH_ERR_INVALID_DATA; } - buffered_sample->length = raw_data_block_size; - buffered_sample->dts = adts_imp->au_number ++ * adts_imp->samples_in_frame; - buffered_sample->cts = buffered_sample->dts; - buffered_sample->prop.ra_flags = ISOM_SAMPLE_RANDOM_ACCESS_FLAG_SYNC; - buffered_sample->prop.pre_roll.distance = 1; /* MDCT */ + sample->length = raw_data_block_size; + sample->dts = adts_imp->au_number ++ * adts_imp->samples_in_frame; + sample->cts = sample->dts; + sample->prop.ra_flags = ISOM_SAMPLE_RANDOM_ACCESS_FLAG_SYNC; + sample->prop.pre_roll.distance = 1; /* MDCT */ /* now we succeeded to read current frame, so "return" takes 0 always below. */ /* skip adts_raw_data_block_error_check() */ if( adts_imp->header.protection_absent == 0 && adts_imp->variable_header.number_of_raw_data_blocks_in_frame != 0 - && lsmash_bs_get_bytes_ex( bs, 2, buffered_sample->data ) != 2 ) + && lsmash_bs_get_bytes_ex( bs, 2, sample->data ) != 2 ) { importer->status = IMPORTER_ERROR; return 0; diff --git a/cli/als_imp.c b/cli/als_imp.c index defcd4e..43febcd 100644 --- a/cli/als_imp.c +++ b/cli/als_imp.c @@ -209,7 +209,7 @@ static int als_parse_specific_config( lsmash_bs_t *bs, mp4a_als_importer_t *als_ return 0; } -static int mp4a_als_importer_get_accessunit( importer_t *importer, uint32_t track_number, lsmash_sample_t *buffered_sample ) +static int mp4a_als_importer_get_accessunit( importer_t *importer, uint32_t track_number, lsmash_sample_t **p_sample ) { if( !importer->info ) return LSMASH_ERR_NAMELESS; @@ -221,19 +221,20 @@ static int mp4a_als_importer_get_accessunit( importer_t *importer, uint32_t trac mp4a_als_importer_t *als_imp = (mp4a_als_importer_t *)importer->info; importer_status current_status = importer->status; if( current_status == IMPORTER_EOF ) - { - buffered_sample->length = 0; - return 0; - } + return IMPORTER_EOF; lsmash_bs_t *bs = importer->bs; als_specific_config_t *alssc = &als_imp->alssc; if( alssc->number_of_ra_units == 0 ) { - memcpy( buffered_sample->data, lsmash_bs_get_buffer_data( bs ), alssc->access_unit_size ); - buffered_sample->length = alssc->access_unit_size; - buffered_sample->cts = 0; - buffered_sample->dts = 0; - buffered_sample->prop.ra_flags = ISOM_SAMPLE_RANDOM_ACCESS_FLAG_SYNC; + lsmash_sample_t *sample = lsmash_create_sample( alssc->access_unit_size ); + if( !sample ) + return LSMASH_ERR_MEMORY_ALLOC; + *p_sample = sample; + memcpy( sample->data, lsmash_bs_get_buffer_data( bs ), alssc->access_unit_size ); + sample->length = alssc->access_unit_size; + sample->cts = 0; + sample->dts = 0; + sample->prop.ra_flags = ISOM_SAMPLE_RANDOM_ACCESS_FLAG_SYNC; importer->status = IMPORTER_EOF; return 0; } @@ -243,21 +244,20 @@ static int mp4a_als_importer_get_accessunit( importer_t *importer, uint32_t trac else /* if( alssc->ra_flag == 1 ) */ /* We don't export ra_unit_size into a sample. */ au_length = lsmash_bs_get_be32( bs ); - if( buffered_sample->length < au_length ) - { - lsmash_log( importer, LSMASH_LOG_WARNING, "the buffer has not enough size.\n" ); - return LSMASH_ERR_NAMELESS; - } - if( lsmash_bs_get_bytes_ex( bs, au_length, buffered_sample->data ) != au_length ) + lsmash_sample_t *sample = lsmash_create_sample( au_length ); + if( !sample ) + return LSMASH_ERR_MEMORY_ALLOC; + *p_sample = sample; + if( lsmash_bs_get_bytes_ex( bs, au_length, sample->data ) != au_length ) { lsmash_log( importer, LSMASH_LOG_WARNING, "failed to read an access unit.\n" ); importer->status = IMPORTER_ERROR; return LSMASH_ERR_INVALID_DATA; } - buffered_sample->length = au_length; - buffered_sample->dts = als_imp->au_number ++ * als_imp->samples_in_frame; - buffered_sample->cts = buffered_sample->dts; - buffered_sample->prop.ra_flags = ISOM_SAMPLE_RANDOM_ACCESS_FLAG_SYNC; + sample->length = au_length; + sample->dts = als_imp->au_number ++ * als_imp->samples_in_frame; + sample->cts = sample->dts; + sample->prop.ra_flags = ISOM_SAMPLE_RANDOM_ACCESS_FLAG_SYNC; if( als_imp->au_number == alssc->number_of_ra_units ) importer->status = IMPORTER_EOF; return 0; diff --git a/cli/amr_imp.c b/cli/amr_imp.c index 9101a48..93bc08c 100644 --- a/cli/amr_imp.c +++ b/cli/amr_imp.c @@ -70,9 +70,9 @@ static void amr_cleanup static int amr_get_accessunit ( - importer_t *importer, - uint32_t track_number, - lsmash_sample_t *buffered_sample + importer_t *importer, + uint32_t track_number, + lsmash_sample_t **p_sample ) { if( !importer->info ) @@ -85,8 +85,7 @@ static int amr_get_accessunit { /* EOF */ importer->status = IMPORTER_EOF; - buffered_sample->length = 0; - return 0; + return IMPORTER_EOF; } /* Each speech frame consists of one speech frame header and one speech data. * At the end of each speech data, octet alignment if needed. @@ -116,18 +115,20 @@ static int amr_get_accessunit importer->status = IMPORTER_ERROR; return read_size < 0 ? LSMASH_ERR_INVALID_DATA : LSMASH_ERR_NAMELESS; } - if( buffered_sample->length < read_size ) - return LSMASH_ERR_NAMELESS; - if( lsmash_bs_get_bytes_ex( bs, read_size, buffered_sample->data ) != read_size ) + lsmash_sample_t *sample = lsmash_create_sample( read_size ); + if( !sample ) + return LSMASH_ERR_MEMORY_ALLOC; + *p_sample = sample; + if( lsmash_bs_get_bytes_ex( bs, read_size, sample->data ) != read_size ) { lsmash_log( importer, LSMASH_LOG_WARNING, "the stream is truncated at the end.\n" ); importer->status = IMPORTER_EOF; return LSMASH_ERR_INVALID_DATA; } - buffered_sample->length = read_size; - buffered_sample->dts = amr_imp->au_number ++ * amr_imp->samples_in_frame; - buffered_sample->cts = buffered_sample->dts; - buffered_sample->prop.ra_flags = ISOM_SAMPLE_RANDOM_ACCESS_FLAG_SYNC; + sample->length = read_size; + sample->dts = amr_imp->au_number ++ * amr_imp->samples_in_frame; + sample->cts = sample->dts; + sample->prop.ra_flags = ISOM_SAMPLE_RANDOM_ACCESS_FLAG_SYNC; return 0; } diff --git a/cli/dts_imp.c b/cli/dts_imp.c index 8d31a9c..91a0120 100644 --- a/cli/dts_imp.c +++ b/cli/dts_imp.c @@ -201,7 +201,7 @@ static int dts_importer_get_next_accessunit_internal( importer_t *importer ) return bs->error ? LSMASH_ERR_NAMELESS : 0; } -static int dts_importer_get_accessunit( importer_t *importer, uint32_t track_number, lsmash_sample_t *buffered_sample ) +static int dts_importer_get_accessunit( importer_t *importer, uint32_t track_number, lsmash_sample_t **p_sample ) { if( !importer->info ) return LSMASH_ERR_NAMELESS; @@ -213,21 +213,22 @@ static int dts_importer_get_accessunit( importer_t *importer, uint32_t track_num dts_importer_t *dts_imp = (dts_importer_t *)importer->info; dts_info_t *info = &dts_imp->info; importer_status current_status = importer->status; - if( current_status == IMPORTER_ERROR || buffered_sample->length < dts_imp->au_length ) + if( current_status == IMPORTER_ERROR ) return LSMASH_ERR_NAMELESS; if( current_status == IMPORTER_EOF && dts_imp->au_length == 0 ) - { - buffered_sample->length = 0; - return 0; - } + return IMPORTER_EOF; if( current_status == IMPORTER_CHANGE ) summary->max_au_length = 0; - memcpy( buffered_sample->data, dts_imp->au, dts_imp->au_length ); - buffered_sample->length = dts_imp->au_length; - buffered_sample->dts = dts_imp->au_number++ * summary->samples_in_frame; - buffered_sample->cts = buffered_sample->dts; - buffered_sample->prop.ra_flags = ISOM_SAMPLE_RANDOM_ACCESS_FLAG_SYNC; - buffered_sample->prop.pre_roll.distance = !!(info->flags & DTS_EXT_SUBSTREAM_LBR_FLAG); /* MDCT */ + lsmash_sample_t *sample = lsmash_create_sample( dts_imp->au_length ); + if( !sample ) + return LSMASH_ERR_MEMORY_ALLOC; + *p_sample = sample; + memcpy( sample->data, dts_imp->au, dts_imp->au_length ); + sample->length = dts_imp->au_length; + sample->dts = dts_imp->au_number++ * summary->samples_in_frame; + sample->cts = sample->dts; + sample->prop.ra_flags = ISOM_SAMPLE_RANDOM_ACCESS_FLAG_SYNC; + sample->prop.pre_roll.distance = !!(info->flags & DTS_EXT_SUBSTREAM_LBR_FLAG); /* MDCT */ if( importer->status == IMPORTER_EOF ) { dts_imp->au_length = 0; diff --git a/cli/importer.c b/cli/importer.c index bc90ded..50578a3 100644 --- a/cli/importer.c +++ b/cli/importer.c @@ -177,13 +177,14 @@ fail: } /* 0 if success, positive if changed, negative if failed */ -int lsmash_importer_get_access_unit( importer_t *importer, uint32_t track_number, lsmash_sample_t *buffered_sample ) +int lsmash_importer_get_access_unit( importer_t *importer, uint32_t track_number, lsmash_sample_t **p_sample ) { - if( !importer || !buffered_sample->data || buffered_sample->length == 0 ) + if( !importer || !p_sample ) return LSMASH_ERR_FUNCTION_PARAM; if( !importer->funcs.get_accessunit ) return LSMASH_ERR_NAMELESS; - return importer->funcs.get_accessunit( importer, track_number, buffered_sample ); + *p_sample = NULL; + return importer->funcs.get_accessunit( importer, track_number, p_sample ); } /* Return 0 if failed, otherwise succeeded. */ diff --git a/cli/importer.h b/cli/importer.h index 67202b5..6a0cb51 100644 --- a/cli/importer.h +++ b/cli/importer.h @@ -36,7 +36,7 @@ struct importer_tag; typedef void ( *importer_cleanup ) ( struct importer_tag * ); -typedef int ( *importer_get_accessunit ) ( struct importer_tag *, uint32_t, lsmash_sample_t * ); +typedef int ( *importer_get_accessunit ) ( struct importer_tag *, uint32_t, lsmash_sample_t ** ); typedef int ( *importer_probe ) ( struct importer_tag * ); typedef uint32_t ( *importer_get_last_duration )( struct importer_tag *, uint32_t ); @@ -88,9 +88,9 @@ void lsmash_importer_close int lsmash_importer_get_access_unit ( - importer_t *importer, - uint32_t track_number, - lsmash_sample_t *buffered_sample + importer_t *importer, + uint32_t track_number, + lsmash_sample_t **p_sample ); uint32_t lsmash_importer_get_last_delta diff --git a/cli/isobm_imp.c b/cli/isobm_imp.c index 4a7ea85..0fb1614 100644 --- a/cli/isobm_imp.c +++ b/cli/isobm_imp.c @@ -74,7 +74,7 @@ static void isobm_importer_cleanup( importer_t *importer ) remove_isobm_importer( importer->info ); } -static int isobm_importer_get_accessunit( importer_t *importer, uint32_t track_number, lsmash_sample_t *buffered_sample ) +static int isobm_importer_get_accessunit( importer_t *importer, uint32_t track_number, lsmash_sample_t **p_sample ) { if( !importer->info ) return LSMASH_ERR_NAMELESS; @@ -84,10 +84,7 @@ static int isobm_importer_get_accessunit( importer_t *importer, uint32_t track_n if( current_status == IMPORTER_ERROR ) return LSMASH_ERR_NAMELESS; if( current_status == IMPORTER_EOF ) - { - buffered_sample->length = 0; - return 0; - } + return IMPORTER_EOF; isobm_importer_t *isobm_imp = (isobm_importer_t *)importer->info; lsmash_root_t *root = isobm_imp->root; uint32_t track_ID = lsmash_get_track_ID( root, track_number ); @@ -102,36 +99,32 @@ static int isobm_importer_get_accessunit( importer_t *importer, uint32_t track_n { /* No more samples. */ importer->status = IMPORTER_EOF; - buffered_sample->length = 0; - return 0; + return IMPORTER_EOF; } } - if( buffered_sample->length < sample->length ) - return LSMASH_ERR_NAMELESS; - memcpy( buffered_sample->data, sample->data, sample->length ); - buffered_sample->length = sample->length; - buffered_sample->dts = sample->dts / isobm_imp->timebase; - buffered_sample->cts = sample->cts / isobm_imp->timebase; - buffered_sample->pos = sample->pos; - buffered_sample->index = sample->index; - buffered_sample->prop = sample->prop; - lsmash_delete_sample( sample ); - if( buffered_sample->index != isobm_imp->current_sample_description_index ) + sample->dts /= isobm_imp->timebase; + sample->cts /= isobm_imp->timebase; + if( sample->index != isobm_imp->current_sample_description_index ) { /* Update the active summary. */ - lsmash_summary_t *summary = lsmash_get_summary( isobm_imp->root, isobm_imp->track_ID, buffered_sample->index ); + lsmash_summary_t *summary = lsmash_get_summary( isobm_imp->root, isobm_imp->track_ID, sample->index ); if( !summary ) + { + lsmash_delete_sample( sample ); return LSMASH_ERR_NAMELESS; + } lsmash_remove_entry( importer->summaries, track_number, lsmash_cleanup_summary ); if( lsmash_add_entry( importer->summaries, summary ) < 0 ) { + lsmash_delete_sample( sample ); lsmash_cleanup_summary( (lsmash_summary_t *)summary ); return LSMASH_ERR_MEMORY_ALLOC; } - isobm_imp->current_sample_description_index = buffered_sample->index; + isobm_imp->current_sample_description_index = sample->index; importer->status = IMPORTER_OK; current_status = IMPORTER_CHANGE; } + *p_sample = sample; ++ isobm_imp->au_number; return current_status; } diff --git a/cli/mp3_imp.c b/cli/mp3_imp.c index 114c0ba..c9e9e14 100644 --- a/cli/mp3_imp.c +++ b/cli/mp3_imp.c @@ -243,7 +243,7 @@ static int parse_vbri_header( mp4sys_mp3_importer_t *mp3_imp, mp4sys_mp3_header_ return memcmp( frame + 36, "VBRI", 4 ) == 0; } -static int mp4sys_mp3_get_accessunit( importer_t *importer, uint32_t track_number, lsmash_sample_t *buffered_sample ) +static int mp4sys_mp3_get_accessunit( importer_t *importer, uint32_t track_number, lsmash_sample_t **p_sample ) { if( !importer->info ) return LSMASH_ERR_NAMELESS; @@ -290,13 +290,10 @@ static int mp4sys_mp3_get_accessunit( importer_t *importer, uint32_t track_numbe } if( frame_size <= 4 ) return LSMASH_ERR_INVALID_DATA; - if( current_status == IMPORTER_ERROR || buffered_sample->length < frame_size ) + if( current_status == IMPORTER_ERROR ) return LSMASH_ERR_NAMELESS; if( current_status == IMPORTER_EOF ) - { - buffered_sample->length = 0; - return 0; - } + return IMPORTER_EOF; if( current_status == IMPORTER_CHANGE ) { lsmash_audio_summary_t *summary = mp4sys_mp3_create_summary( header, 1 ); /* FIXME: use legacy mode. */ @@ -310,7 +307,15 @@ static int mp4sys_mp3_get_accessunit( importer_t *importer, uint32_t track_numbe mp3_imp->samples_in_frame = summary->samples_in_frame; } /* read a frame's data. */ - uint8_t *frame_data = buffered_sample->data; + lsmash_sample_t *sample = *p_sample; + if( !sample ) + { + sample = lsmash_create_sample( MP4SYS_MP3_MAX_FRAME_LENGTH ); + if( !sample ) + return LSMASH_ERR_MEMORY_ALLOC; + *p_sample = sample; + } + uint8_t *frame_data = sample->data; memcpy( frame_data, mp3_imp->raw_header, MP4SYS_MP3_HEADER_LENGTH ); frame_size -= MP4SYS_MP3_HEADER_LENGTH; if( lsmash_bs_get_bytes_ex( importer->bs, frame_size, frame_data + MP4SYS_MP3_HEADER_LENGTH ) != frame_size ) @@ -318,11 +323,11 @@ static int mp4sys_mp3_get_accessunit( importer_t *importer, uint32_t track_numbe importer->status = IMPORTER_ERROR; return LSMASH_ERR_INVALID_DATA; } - buffered_sample->length = MP4SYS_MP3_HEADER_LENGTH + frame_size; - buffered_sample->dts = mp3_imp->au_number ++ * mp3_imp->samples_in_frame; - buffered_sample->cts = buffered_sample->dts; - buffered_sample->prop.ra_flags = ISOM_SAMPLE_RANDOM_ACCESS_FLAG_SYNC; - buffered_sample->prop.pre_roll.distance = header->layer == MP4SYS_LAYER_III ? 1 : 0; /* Layer III uses MDCT */ + sample->length = MP4SYS_MP3_HEADER_LENGTH + frame_size; + sample->dts = mp3_imp->au_number ++ * mp3_imp->samples_in_frame; + sample->cts = sample->dts; + sample->prop.ra_flags = ISOM_SAMPLE_RANDOM_ACCESS_FLAG_SYNC; + sample->prop.pre_roll.distance = header->layer == MP4SYS_LAYER_III ? 1 : 0; /* Layer III uses MDCT */ int vbr_header_present = 0; if( mp3_imp->au_number == 1 @@ -361,7 +366,7 @@ static int mp4sys_mp3_get_accessunit( importer_t *importer, uint32_t track_numbe if( mp3_imp->main_data_size[i] == 0 ) break; } - buffered_sample->prop.pre_roll.distance += mp3_imp->prev_preroll_count; + sample->prop.pre_roll.distance += mp3_imp->prev_preroll_count; mp3_imp->prev_preroll_count = i; } uint16_t side_info_size; @@ -427,7 +432,7 @@ static int mp4sys_mp3_get_accessunit( importer_t *importer, uint32_t track_numbe mp3_imp->header = new_header; if( vbr_header_present ) - return mp4sys_mp3_get_accessunit( importer, track_number, buffered_sample ); + return mp4sys_mp3_get_accessunit( importer, track_number, &sample ); return 0; } diff --git a/cli/muxer.c b/cli/muxer.c index b8d4938..afb2f69 100644 --- a/cli/muxer.c +++ b/cli/muxer.c @@ -1054,20 +1054,18 @@ static int do_mux( muxer_t *muxer ) /* Get a new sample data if the track doesn't hold any one. */ if( !sample ) { - /* Allocate sample buffer. */ - sample = lsmash_create_sample( out_track->summary->max_au_length ); - if( !sample ) - return ERROR_MSG( "failed to alloc memory for buffer.\n" ); /* lsmash_importer_get_access_unit() returns 1 if there're any changes in stream's properties. */ - int ret = lsmash_importer_get_access_unit( input->importer, input->current_track_number, sample ); - if( ret == -1 ) + int ret = lsmash_importer_get_access_unit( input->importer, input->current_track_number, &sample ); + if( ret == LSMASH_ERR_MEMORY_ALLOC ) + return ERROR_MSG( "failed to alloc memory for buffer.\n" ); + else if( ret <= -1 ) { lsmash_delete_sample( sample ); ERROR_MSG( "failed to get a frame from input file. Maybe corrupted.\n" "Aborting muxing operation and trying to let output be valid file.\n" ); break; } - else if( ret == 1 ) + else if( ret == 1 ) /* a change of stream's properties */ { input_track_t *in_track = &input->track[input->current_track_number - 1]; lsmash_cleanup_summary( in_track->summary ); @@ -1080,7 +1078,7 @@ static int do_mux( muxer_t *muxer ) break; } } - if( sample->length == 0 ) + else if( ret == 2 ) /* EOF */ { /* No more appendable samples in this track. */ lsmash_delete_sample( sample ); diff --git a/cli/nalu_imp.c b/cli/nalu_imp.c index 4253fd0..e36c1cc 100644 --- a/cli/nalu_imp.c +++ b/cli/nalu_imp.c @@ -387,9 +387,9 @@ static inline void h264_importer_check_eof( importer_t *importer, h264_access_un static int h264_importer_get_accessunit ( - importer_t *importer, - uint32_t track_number, - lsmash_sample_t *buffered_sample + importer_t *importer, + uint32_t track_number, + lsmash_sample_t **p_sample ) { if( !importer->info ) @@ -399,13 +399,10 @@ static int h264_importer_get_accessunit h264_importer_t *h264_imp = (h264_importer_t *)importer->info; h264_info_t *info = &h264_imp->info; importer_status current_status = importer->status; - if( current_status == IMPORTER_ERROR || buffered_sample->length < h264_imp->max_au_length ) + if( current_status == IMPORTER_ERROR ) return LSMASH_ERR_NAMELESS; if( current_status == IMPORTER_EOF ) - { - buffered_sample->length = 0; - return 0; - } + return IMPORTER_EOF; int err = h264_get_access_unit_internal( importer, 0 ); if( err < 0 ) { @@ -433,41 +430,45 @@ static int h264_importer_get_accessunit } importer->status = IMPORTER_OK; } + lsmash_sample_t *sample = lsmash_create_sample( h264_imp->max_au_length ); + if( !sample ) + return LSMASH_ERR_MEMORY_ALLOC; + *p_sample = sample; h264_access_unit_t *au = &info->au; h264_picture_info_t *picture = &au->picture; - buffered_sample->dts = h264_imp->ts_list.timestamp[ au->number - 1 ].dts; - buffered_sample->cts = h264_imp->ts_list.timestamp[ au->number - 1 ].cts; + sample->dts = h264_imp->ts_list.timestamp[ au->number - 1 ].dts; + sample->cts = h264_imp->ts_list.timestamp[ au->number - 1 ].cts; if( au->number < h264_imp->num_undecodable ) - buffered_sample->prop.leading = ISOM_SAMPLE_IS_UNDECODABLE_LEADING; + sample->prop.leading = ISOM_SAMPLE_IS_UNDECODABLE_LEADING; else - buffered_sample->prop.leading = picture->independent || buffered_sample->cts >= h264_imp->last_intra_cts + sample->prop.leading = picture->independent || sample->cts >= h264_imp->last_intra_cts ? ISOM_SAMPLE_IS_NOT_LEADING : ISOM_SAMPLE_IS_UNDECODABLE_LEADING; if( picture->independent ) - h264_imp->last_intra_cts = buffered_sample->cts; + h264_imp->last_intra_cts = sample->cts; if( h264_imp->composition_reordering_present && !picture->disposable && !picture->idr ) - buffered_sample->prop.allow_earlier = QT_SAMPLE_EARLIER_PTS_ALLOWED; - buffered_sample->prop.independent = picture->independent ? ISOM_SAMPLE_IS_INDEPENDENT : ISOM_SAMPLE_IS_NOT_INDEPENDENT; - buffered_sample->prop.disposable = picture->disposable ? ISOM_SAMPLE_IS_DISPOSABLE : ISOM_SAMPLE_IS_NOT_DISPOSABLE; - buffered_sample->prop.redundant = picture->has_redundancy ? ISOM_SAMPLE_HAS_REDUNDANCY : ISOM_SAMPLE_HAS_NO_REDUNDANCY; - buffered_sample->prop.post_roll.identifier = picture->frame_num; + sample->prop.allow_earlier = QT_SAMPLE_EARLIER_PTS_ALLOWED; + sample->prop.independent = picture->independent ? ISOM_SAMPLE_IS_INDEPENDENT : ISOM_SAMPLE_IS_NOT_INDEPENDENT; + sample->prop.disposable = picture->disposable ? ISOM_SAMPLE_IS_DISPOSABLE : ISOM_SAMPLE_IS_NOT_DISPOSABLE; + sample->prop.redundant = picture->has_redundancy ? ISOM_SAMPLE_HAS_REDUNDANCY : ISOM_SAMPLE_HAS_NO_REDUNDANCY; + sample->prop.post_roll.identifier = picture->frame_num; if( picture->random_accessible ) { if( picture->idr ) - buffered_sample->prop.ra_flags = ISOM_SAMPLE_RANDOM_ACCESS_FLAG_SYNC; + sample->prop.ra_flags = ISOM_SAMPLE_RANDOM_ACCESS_FLAG_SYNC; else if( picture->recovery_frame_cnt ) { - buffered_sample->prop.ra_flags = ISOM_SAMPLE_RANDOM_ACCESS_FLAG_POST_ROLL_START; - buffered_sample->prop.post_roll.complete = (picture->frame_num + picture->recovery_frame_cnt) % info->sps.MaxFrameNum; + sample->prop.ra_flags = ISOM_SAMPLE_RANDOM_ACCESS_FLAG_POST_ROLL_START; + sample->prop.post_roll.complete = (picture->frame_num + picture->recovery_frame_cnt) % info->sps.MaxFrameNum; } else { - buffered_sample->prop.ra_flags = ISOM_SAMPLE_RANDOM_ACCESS_FLAG_RAP; + sample->prop.ra_flags = ISOM_SAMPLE_RANDOM_ACCESS_FLAG_RAP; if( !picture->broken_link_flag ) - buffered_sample->prop.ra_flags |= QT_SAMPLE_RANDOM_ACCESS_FLAG_PARTIAL_SYNC; + sample->prop.ra_flags |= QT_SAMPLE_RANDOM_ACCESS_FLAG_PARTIAL_SYNC; } } - buffered_sample->length = au->length; - memcpy( buffered_sample->data, au->data, au->length ); + sample->length = au->length; + memcpy( sample->data, au->data, au->length ); return current_status; } @@ -1232,7 +1233,7 @@ static inline void hevc_importer_check_eof( importer_t *importer, hevc_access_un importer->status = IMPORTER_OK; } -static int hevc_importer_get_accessunit( importer_t *importer, uint32_t track_number, lsmash_sample_t *buffered_sample ) +static int hevc_importer_get_accessunit( importer_t *importer, uint32_t track_number, lsmash_sample_t **p_sample ) { if( !importer->info ) return LSMASH_ERR_NAMELESS; @@ -1241,13 +1242,10 @@ static int hevc_importer_get_accessunit( importer_t *importer, uint32_t track_nu hevc_importer_t *hevc_imp = (hevc_importer_t *)importer->info; hevc_info_t *info = &hevc_imp->info; importer_status current_status = importer->status; - if( current_status == IMPORTER_ERROR || buffered_sample->length < hevc_imp->max_au_length ) + if( current_status == IMPORTER_ERROR ) return LSMASH_ERR_NAMELESS; if( current_status == IMPORTER_EOF ) - { - buffered_sample->length = 0; - return 0; - } + return IMPORTER_EOF; int err = hevc_get_access_unit_internal( importer, 0 ); if( err < 0 ) { @@ -1275,58 +1273,62 @@ static int hevc_importer_get_accessunit( importer_t *importer, uint32_t track_nu } importer->status = IMPORTER_OK; } + lsmash_sample_t *sample = lsmash_create_sample( hevc_imp->max_au_length ); + if( !sample ) + return LSMASH_ERR_MEMORY_ALLOC; + *p_sample = sample; hevc_access_unit_t *au = &info->au; hevc_picture_info_t *picture = &au->picture; - buffered_sample->dts = hevc_imp->ts_list.timestamp[ au->number - 1 ].dts; - buffered_sample->cts = hevc_imp->ts_list.timestamp[ au->number - 1 ].cts; + sample->dts = hevc_imp->ts_list.timestamp[ au->number - 1 ].dts; + sample->cts = hevc_imp->ts_list.timestamp[ au->number - 1 ].cts; /* Set property of disposability. */ if( picture->sublayer_nonref && au->TemporalId == hevc_imp->max_TemporalId ) /* Sub-layer non-reference pictures are not referenced by subsequent pictures of * the same sub-layer in decoding order. */ - buffered_sample->prop.disposable = ISOM_SAMPLE_IS_DISPOSABLE; + sample->prop.disposable = ISOM_SAMPLE_IS_DISPOSABLE; else - buffered_sample->prop.disposable = ISOM_SAMPLE_IS_NOT_DISPOSABLE; + sample->prop.disposable = ISOM_SAMPLE_IS_NOT_DISPOSABLE; /* Set property of leading. */ if( picture->radl || picture->rasl ) - buffered_sample->prop.leading = picture->radl ? ISOM_SAMPLE_IS_DECODABLE_LEADING : ISOM_SAMPLE_IS_UNDECODABLE_LEADING; + sample->prop.leading = picture->radl ? ISOM_SAMPLE_IS_DECODABLE_LEADING : ISOM_SAMPLE_IS_UNDECODABLE_LEADING; else { if( au->number < hevc_imp->num_undecodable ) - buffered_sample->prop.leading = ISOM_SAMPLE_IS_UNDECODABLE_LEADING; + sample->prop.leading = ISOM_SAMPLE_IS_UNDECODABLE_LEADING; else { - if( picture->independent || buffered_sample->cts >= hevc_imp->last_intra_cts ) - buffered_sample->prop.leading = ISOM_SAMPLE_IS_NOT_LEADING; + if( picture->independent || sample->cts >= hevc_imp->last_intra_cts ) + sample->prop.leading = ISOM_SAMPLE_IS_NOT_LEADING; else - buffered_sample->prop.leading = ISOM_SAMPLE_IS_UNDECODABLE_LEADING; + sample->prop.leading = ISOM_SAMPLE_IS_UNDECODABLE_LEADING; } } if( picture->independent ) - hevc_imp->last_intra_cts = buffered_sample->cts; + hevc_imp->last_intra_cts = sample->cts; /* Set property of independence. */ - buffered_sample->prop.independent = picture->independent ? ISOM_SAMPLE_IS_INDEPENDENT : ISOM_SAMPLE_IS_NOT_INDEPENDENT; - buffered_sample->prop.redundant = ISOM_SAMPLE_HAS_NO_REDUNDANCY; - buffered_sample->prop.post_roll.identifier = picture->poc; + sample->prop.independent = picture->independent ? ISOM_SAMPLE_IS_INDEPENDENT : ISOM_SAMPLE_IS_NOT_INDEPENDENT; + sample->prop.redundant = ISOM_SAMPLE_HAS_NO_REDUNDANCY; + sample->prop.post_roll.identifier = picture->poc; if( picture->random_accessible ) { if( picture->irap ) { - buffered_sample->prop.ra_flags = ISOM_SAMPLE_RANDOM_ACCESS_FLAG_SYNC; + sample->prop.ra_flags = ISOM_SAMPLE_RANDOM_ACCESS_FLAG_SYNC; if( picture->closed_rap ) - buffered_sample->prop.ra_flags |= ISOM_SAMPLE_RANDOM_ACCESS_FLAG_CLOSED_RAP; + sample->prop.ra_flags |= ISOM_SAMPLE_RANDOM_ACCESS_FLAG_CLOSED_RAP; else - buffered_sample->prop.ra_flags |= ISOM_SAMPLE_RANDOM_ACCESS_FLAG_RAP; + sample->prop.ra_flags |= ISOM_SAMPLE_RANDOM_ACCESS_FLAG_RAP; } else if( picture->recovery_poc_cnt ) { - buffered_sample->prop.ra_flags = ISOM_SAMPLE_RANDOM_ACCESS_FLAG_POST_ROLL_START; - buffered_sample->prop.post_roll.complete = picture->poc + picture->recovery_poc_cnt; + sample->prop.ra_flags = ISOM_SAMPLE_RANDOM_ACCESS_FLAG_POST_ROLL_START; + sample->prop.post_roll.complete = picture->poc + picture->recovery_poc_cnt; } else - buffered_sample->prop.ra_flags = ISOM_SAMPLE_RANDOM_ACCESS_FLAG_RAP; + sample->prop.ra_flags = ISOM_SAMPLE_RANDOM_ACCESS_FLAG_RAP; } - buffered_sample->length = au->length; - memcpy( buffered_sample->data, au->data, au->length ); + sample->length = au->length; + memcpy( sample->data, au->data, au->length ); return current_status; } diff --git a/cli/vc1_imp.c b/cli/vc1_imp.c index deadd72..d69e32b 100644 --- a/cli/vc1_imp.c +++ b/cli/vc1_imp.c @@ -266,7 +266,7 @@ static inline void vc1_importer_check_eof( importer_t *importer, vc1_access_unit importer->status = IMPORTER_OK; } -static int vc1_importer_get_accessunit( importer_t *importer, uint32_t track_number, lsmash_sample_t *buffered_sample ) +static int vc1_importer_get_accessunit( importer_t *importer, uint32_t track_number, lsmash_sample_t **p_sample ) { if( !importer->info ) return LSMASH_ERR_NAMELESS; @@ -275,39 +275,40 @@ static int vc1_importer_get_accessunit( importer_t *importer, uint32_t track_num vc1_importer_t *vc1_imp = (vc1_importer_t *)importer->info; vc1_info_t *info = &vc1_imp->info; importer_status current_status = importer->status; - if( current_status == IMPORTER_ERROR || buffered_sample->length < vc1_imp->max_au_length ) + if( current_status == IMPORTER_ERROR ) return LSMASH_ERR_NAMELESS; if( current_status == IMPORTER_EOF ) - { - buffered_sample->length = 0; - return 0; - } + return IMPORTER_EOF; int err = vc1_importer_get_access_unit_internal( importer, 0 ); if( err < 0 ) { importer->status = IMPORTER_ERROR; return err; } + lsmash_sample_t *sample = lsmash_create_sample( vc1_imp->max_au_length ); + if( !sample ) + return LSMASH_ERR_MEMORY_ALLOC; + *p_sample = sample; vc1_access_unit_t *access_unit = &info->access_unit; vc1_importer_check_eof( importer, access_unit ); - buffered_sample->dts = vc1_imp->ts_list.timestamp[ access_unit->number - 1 ].dts; - buffered_sample->cts = vc1_imp->ts_list.timestamp[ access_unit->number - 1 ].cts; - buffered_sample->prop.leading = access_unit->independent + sample->dts = vc1_imp->ts_list.timestamp[ access_unit->number - 1 ].dts; + sample->cts = vc1_imp->ts_list.timestamp[ access_unit->number - 1 ].cts; + sample->prop.leading = access_unit->independent || access_unit->non_bipredictive - || buffered_sample->cts >= vc1_imp->last_ref_intra_cts + || sample->cts >= vc1_imp->last_ref_intra_cts ? ISOM_SAMPLE_IS_NOT_LEADING : ISOM_SAMPLE_IS_UNDECODABLE_LEADING; if( access_unit->independent && !access_unit->disposable ) - vc1_imp->last_ref_intra_cts = buffered_sample->cts; + vc1_imp->last_ref_intra_cts = sample->cts; if( vc1_imp->composition_reordering_present && !access_unit->disposable && !access_unit->closed_gop ) - buffered_sample->prop.allow_earlier = QT_SAMPLE_EARLIER_PTS_ALLOWED; - buffered_sample->prop.independent = access_unit->independent ? ISOM_SAMPLE_IS_INDEPENDENT : ISOM_SAMPLE_IS_NOT_INDEPENDENT; - buffered_sample->prop.disposable = access_unit->disposable ? ISOM_SAMPLE_IS_DISPOSABLE : ISOM_SAMPLE_IS_NOT_DISPOSABLE; - buffered_sample->prop.redundant = ISOM_SAMPLE_HAS_NO_REDUNDANCY; + sample->prop.allow_earlier = QT_SAMPLE_EARLIER_PTS_ALLOWED; + sample->prop.independent = access_unit->independent ? ISOM_SAMPLE_IS_INDEPENDENT : ISOM_SAMPLE_IS_NOT_INDEPENDENT; + sample->prop.disposable = access_unit->disposable ? ISOM_SAMPLE_IS_DISPOSABLE : ISOM_SAMPLE_IS_NOT_DISPOSABLE; + sample->prop.redundant = ISOM_SAMPLE_HAS_NO_REDUNDANCY; if( access_unit->random_accessible ) /* All random access point is a sync sample even if it's an open RAP. */ - buffered_sample->prop.ra_flags = ISOM_SAMPLE_RANDOM_ACCESS_FLAG_SYNC; - buffered_sample->length = access_unit->data_length; - memcpy( buffered_sample->data, access_unit->data, access_unit->data_length ); + sample->prop.ra_flags = ISOM_SAMPLE_RANDOM_ACCESS_FLAG_SYNC; + sample->length = access_unit->data_length; + memcpy( sample->data, access_unit->data, access_unit->data_length ); return current_status; } diff --git a/cli/wave_imp.c b/cli/wave_imp.c index 5a58988..0a776f6 100644 --- a/cli/wave_imp.c +++ b/cli/wave_imp.c @@ -104,7 +104,7 @@ static void wave_importer_cleanup( importer_t *importer ) remove_wave_importer( importer->info ); } -static int wave_importer_get_accessunit( importer_t *importer, uint32_t track_number, lsmash_sample_t *buffered_sample ) +static int wave_importer_get_accessunit( importer_t *importer, uint32_t track_number, lsmash_sample_t **p_sample ) { if( !importer->info ) return LSMASH_ERR_NAMELESS; @@ -115,13 +115,10 @@ static int wave_importer_get_accessunit( importer_t *importer, uint32_t track_nu return LSMASH_ERR_NAMELESS; wave_importer_t *wave_imp = (wave_importer_t *)importer->info; importer_status current_status = importer->status; - if( current_status == IMPORTER_ERROR || buffered_sample->length < wave_imp->au_length ) + if( current_status == IMPORTER_ERROR ) return LSMASH_ERR_NAMELESS; if( current_status == IMPORTER_EOF ) - { - buffered_sample->length = 0; - return 0; - } + return IMPORTER_EOF; if( wave_imp->number_of_samples / summary->samples_in_frame > wave_imp->au_number ) wave_imp->au_length = summary->bytes_per_frame; else @@ -129,20 +126,21 @@ static int wave_importer_get_accessunit( importer_t *importer, uint32_t track_nu wave_imp->au_length = wave_imp->fmt.wfx.nBlockAlign * (wave_imp->number_of_samples % summary->samples_in_frame); importer->status = IMPORTER_EOF; if( wave_imp->au_length == 0 ) - { - buffered_sample->length = 0; - return 0; - } + return IMPORTER_EOF; } - if( lsmash_bs_get_bytes_ex( importer->bs, wave_imp->au_length, buffered_sample->data ) != wave_imp->au_length ) + lsmash_sample_t *sample = lsmash_create_sample( wave_imp->au_length ); + if( !sample ) + return LSMASH_ERR_MEMORY_ALLOC; + *p_sample = sample; + if( lsmash_bs_get_bytes_ex( importer->bs, wave_imp->au_length, sample->data ) != wave_imp->au_length ) { importer->status = IMPORTER_ERROR; return LSMASH_ERR_INVALID_DATA; } - buffered_sample->length = wave_imp->au_length; - buffered_sample->dts = wave_imp->au_number ++ * summary->samples_in_frame; - buffered_sample->cts = buffered_sample->dts; - buffered_sample->prop.ra_flags = ISOM_SAMPLE_RANDOM_ACCESS_FLAG_SYNC; + sample->length = wave_imp->au_length; + sample->dts = wave_imp->au_number ++ * summary->samples_in_frame; + sample->cts = sample->dts; + sample->prop.ra_flags = ISOM_SAMPLE_RANDOM_ACCESS_FLAG_SYNC; return current_status; } -- 2.11.4.GIT