Пример #1
0
static int isom_read_minimum_chapter( FILE *chapter, isom_chapter_entry_t *data )
{
    char buff[CHAPTER_BUFSIZE];
    if( isom_lumber_line( buff, CHAPTER_BUFSIZE, chapter ) < 0 )    /* read newline */
        return LSMASH_ERR_NAMELESS;
    char *p_buff = &buff[ !memcmp( buff, UTF8_BOM, UTF8_BOM_LENGTH ) ? UTF8_BOM_LENGTH : 0 ];   /* BOM detection */
    if( isom_get_start_time( p_buff, data ) < 0 )   /* get start_time */
        return LSMASH_ERR_INVALID_DATA;
    /* get chapter_name */
    char *chapter_name = strchr( buff, ' ' );   /* find separator */
    if( !chapter_name++ )
        return LSMASH_ERR_INVALID_DATA;
    int len = LSMASH_MIN( 255, strlen( chapter_name ) );    /* We support length of chapter_name up to 255 */
    data->chapter_name = (char *)lsmash_malloc( len + 1 );
    if( !data->chapter_name )
        return LSMASH_ERR_MEMORY_ALLOC;
    memcpy( data->chapter_name, chapter_name, len );
    data->chapter_name[len] = '\0';
    return 0;
}
Пример #2
0
static int isom_read_minimum_chapter( FILE *chapter, isom_chapter_entry_t *data )
{
    char buff[CHAPTER_BUFSIZE];
    int len;

    if( isom_lumber_line( buff, CHAPTER_BUFSIZE, chapter ) ) /* read newline */
        return -1;
    char *p_buff = !memcmp( buff, UTF8_BOM, UTF8_BOM_LENGTH ) ? &buff[UTF8_BOM_LENGTH] : &buff[0]; /* BOM detection */
    if( isom_get_start_time( p_buff, data ) ) /* get start_time */
        return -1;
    /* get chapter_name */
    char *chapter_name = strchr( buff, ' ' );   /* find separator */
    if( !chapter_name++ )
        return -1;
    len = LSMASH_MIN( 255, strlen( chapter_name ) );  /* We support length of chapter_name up to 255 */
    data->chapter_name = (char *)malloc( len + 1 );
    if( !data->chapter_name )
        return -1;
    memcpy( data->chapter_name, chapter_name, len );
    data->chapter_name[len] = '\0';
    return 0;
}
Пример #3
0
static int isom_read_simple_chapter( FILE *chapter, isom_chapter_entry_t *data )
{
    char buff[CHAPTER_BUFSIZE];
    /* get start_time */
    if( isom_lumber_line( buff, CHAPTER_BUFSIZE, chapter ) < 0 )
        return LSMASH_ERR_NAMELESS;
    char *chapter_time = strchr( buff, '=' );   /* find separator */
    if( !chapter_time++ )
        return LSMASH_ERR_INVALID_DATA;
    if( isom_get_start_time( chapter_time, data ) < 0 )
        return LSMASH_ERR_INVALID_DATA;
    if( isom_lumber_line( buff, CHAPTER_BUFSIZE, chapter ) < 0 )    /* get chapter_name */
        return LSMASH_ERR_NAMELESS;
    char *chapter_name = strchr( buff, '=' );   /* find separator */
    if( !chapter_name++ )
        return LSMASH_ERR_INVALID_DATA;
    int len = LSMASH_MIN( 255, strlen( chapter_name ) );    /* We support length of chapter_name up to 255 */
    data->chapter_name = (char *)lsmash_malloc( len + 1 );
    if( !data->chapter_name )
        return LSMASH_ERR_MEMORY_ALLOC;
    memcpy( data->chapter_name, chapter_name, len );
    data->chapter_name[len] = '\0';
    return 0;
}
Пример #4
0
static int isom_read_simple_chapter( FILE *chapter, isom_chapter_entry_t *data )
{
    char buff[CHAPTER_BUFSIZE];
    int len;

    /* get start_time */
    if( isom_lumber_line( buff, CHAPTER_BUFSIZE, chapter ) )
        return -1;
    char *chapter_time = strchr( buff, '=' );   /* find separator */
    if( !chapter_time++
        || isom_get_start_time( chapter_time, data )
        || isom_lumber_line( buff, CHAPTER_BUFSIZE, chapter ) ) /* get chapter_name */
        return -1;
    char *chapter_name = strchr( buff, '=' );   /* find separator */
    if( !chapter_name++ )
        return -1;
    len = LSMASH_MIN( 255, strlen( chapter_name ) );  /* We support length of chapter_name up to 255 */
    data->chapter_name = (char *)malloc( len + 1 );
    if( !data->chapter_name )
        return -1;
    memcpy( data->chapter_name, chapter_name, len );
    data->chapter_name[len] = '\0';
    return 0;
}
Пример #5
0
int isom_check_compatibility
(
    lsmash_file_t *file
)
{
    if( !file )
        return LSMASH_ERR_FUNCTION_PARAM;
    isom_clear_compat_flags( file );
    /* Get the brand container. */
    isom_ftyp_t *ftyp = file->ftyp ? file->ftyp : (isom_ftyp_t *)lsmash_get_entry_data( &file->styp_list, 1 );
    /* Check brand to decide mandatory boxes. */
    if( !ftyp )
    {
        /* No brand declaration means this file is a MP4 version 1 or QuickTime file format. */
        if( file->moov
         && file->moov->iods )
        {
            file->mp4_version1    = 1;
            file->isom_compatible = 1;
        }
        else
        {
            file->qt_compatible    = 1;
            file->undefined_64_ver = 1;
        }
        return 0;
    }
    for( uint32_t i = 0; i <= ftyp->brand_count; i++ )
    {
        uint32_t brand = (i == ftyp->brand_count ? ftyp->major_brand : ftyp->compatible_brands[i]);
        switch( brand )
        {
            case ISOM_BRAND_TYPE_QT :
                file->qt_compatible = 1;
                break;
            case ISOM_BRAND_TYPE_MP41 :
                file->mp4_version1 = 1;
                break;
            case ISOM_BRAND_TYPE_MP42 :
                file->mp4_version2 = 1;
                break;
            case ISOM_BRAND_TYPE_AVC1 :
            case ISOM_BRAND_TYPE_ISOM :
                file->max_isom_version = LSMASH_MAX( file->max_isom_version, 1 );
                file->min_isom_version = LSMASH_MIN( file->min_isom_version, 1 );
                break;
            case ISOM_BRAND_TYPE_ISO2 :
                file->max_isom_version = LSMASH_MAX( file->max_isom_version, 2 );
                file->min_isom_version = LSMASH_MIN( file->min_isom_version, 2 );
                break;
            case ISOM_BRAND_TYPE_ISO3 :
                file->max_isom_version = LSMASH_MAX( file->max_isom_version, 3 );
                file->min_isom_version = LSMASH_MIN( file->min_isom_version, 3 );
                break;
            case ISOM_BRAND_TYPE_ISO4 :
                file->max_isom_version = LSMASH_MAX( file->max_isom_version, 4 );
                file->min_isom_version = LSMASH_MIN( file->min_isom_version, 4 );
                break;
            case ISOM_BRAND_TYPE_ISO5 :
                file->max_isom_version = LSMASH_MAX( file->max_isom_version, 5 );
                file->min_isom_version = LSMASH_MIN( file->min_isom_version, 5 );
                break;
            case ISOM_BRAND_TYPE_ISO6 :
                file->max_isom_version = LSMASH_MAX( file->max_isom_version, 6 );
                file->min_isom_version = LSMASH_MIN( file->min_isom_version, 6 );
                break;
            case ISOM_BRAND_TYPE_ISO7 :
                file->max_isom_version = LSMASH_MAX( file->max_isom_version, 7 );
                file->min_isom_version = LSMASH_MIN( file->min_isom_version, 7 );
                break;
            case ISOM_BRAND_TYPE_M4A :
            case ISOM_BRAND_TYPE_M4B :
            case ISOM_BRAND_TYPE_M4P :
            case ISOM_BRAND_TYPE_M4V :
                file->itunes_movie = 1;
                break;
            case ISOM_BRAND_TYPE_3GP4 :
                file->max_3gpp_version = LSMASH_MAX( file->max_3gpp_version, 4 );
                break;
            case ISOM_BRAND_TYPE_3GP5 :
                file->max_3gpp_version = LSMASH_MAX( file->max_3gpp_version, 5 );
                break;
            case ISOM_BRAND_TYPE_3GE6 :
            case ISOM_BRAND_TYPE_3GG6 :
            case ISOM_BRAND_TYPE_3GP6 :
            case ISOM_BRAND_TYPE_3GR6 :
            case ISOM_BRAND_TYPE_3GS6 :
                file->max_3gpp_version = LSMASH_MAX( file->max_3gpp_version, 6 );
                break;
            case ISOM_BRAND_TYPE_3GP7 :
                file->max_3gpp_version = LSMASH_MAX( file->max_3gpp_version, 7 );
                break;
            case ISOM_BRAND_TYPE_3GP8 :
                file->max_3gpp_version = LSMASH_MAX( file->max_3gpp_version, 8 );
                break;
            case ISOM_BRAND_TYPE_3GE9 :
            case ISOM_BRAND_TYPE_3GF9 :
            case ISOM_BRAND_TYPE_3GG9 :
            case ISOM_BRAND_TYPE_3GH9 :
            case ISOM_BRAND_TYPE_3GM9 :
            case ISOM_BRAND_TYPE_3GP9 :
            case ISOM_BRAND_TYPE_3GR9 :
            case ISOM_BRAND_TYPE_3GS9 :
            case ISOM_BRAND_TYPE_3GT9 :
                file->max_3gpp_version = LSMASH_MAX( file->max_3gpp_version, 9 );
                break;
            default :
                break;
        }
        switch( brand )
        {
            case ISOM_BRAND_TYPE_AVC1 :
            case ISOM_BRAND_TYPE_ISO2 :
            case ISOM_BRAND_TYPE_ISO3 :
            case ISOM_BRAND_TYPE_ISO4 :
            case ISOM_BRAND_TYPE_ISO5 :
            case ISOM_BRAND_TYPE_ISO6 :
                file->avc_extensions = 1;
                break;
            case ISOM_BRAND_TYPE_3GP4 :
            case ISOM_BRAND_TYPE_3GP5 :
            case ISOM_BRAND_TYPE_3GP6 :
            case ISOM_BRAND_TYPE_3GP7 :
            case ISOM_BRAND_TYPE_3GP8 :
            case ISOM_BRAND_TYPE_3GP9 :
                file->forbid_tref = 1;
                break;
            case ISOM_BRAND_TYPE_3GH9 :
            case ISOM_BRAND_TYPE_3GM9 :
            case ISOM_BRAND_TYPE_DASH :
            case ISOM_BRAND_TYPE_DSMS :
            case ISOM_BRAND_TYPE_LMSG :
            case ISOM_BRAND_TYPE_MSDH :
            case ISOM_BRAND_TYPE_MSIX :
            case ISOM_BRAND_TYPE_SIMS :
                file->media_segment = 1;
                break;
            default :
                break;
        }
    }
    file->isom_compatible = !file->qt_compatible
                          || file->mp4_version1
                          || file->mp4_version2
                          || file->itunes_movie
                          || file->max_3gpp_version;
    file->undefined_64_ver = file->qt_compatible || file->itunes_movie;
    if( file->flags & LSMASH_FILE_MODE_WRITE )
    {
        /* Media Segment is incompatible with ISO Base Media File Format version 4 or former must be compatible with
         * version 6 or later since it requires default-base-is-moof and Track Fragment Base Media Decode Time Box. */
        if( file->media_segment && (file->min_isom_version < 5 || (file->max_isom_version && file->max_isom_version < 6)) )
            return LSMASH_ERR_INVALID_DATA;
        file->allow_moof_base = (file->max_isom_version >= 5 && file->min_isom_version >= 5)
                             || (file->max_isom_version == 0 && file->min_isom_version == UINT8_MAX && file->media_segment);
    }
    return 0;
}
Пример #6
0
static int dts_importer_get_next_accessunit_internal( importer_t *importer )
{
    int au_completed = 0;
    dts_importer_t *dts_imp = (dts_importer_t *)importer->info;
    dts_info_t     *info    = &dts_imp->info;
    lsmash_bs_t    *bs      = info->bits->bs;
    while( !au_completed )
    {
        /* Read data from the stream if needed. */
        dts_imp->next_frame_pos += info->frame_size;
        lsmash_bs_read_seek( bs, dts_imp->next_frame_pos, SEEK_SET );
        uint64_t remain_size = lsmash_bs_get_remaining_buffer_size( bs );
        if( remain_size < DTS_MAX_EXSS_SIZE )
        {
            int err = lsmash_bs_read( bs, bs->buffer.max_size );
            if( err < 0 )
            {
                lsmash_log( importer, LSMASH_LOG_ERROR, "failed to read data from the stream.\n" );
                return err;
            }
            remain_size = lsmash_bs_get_remaining_buffer_size( bs );
        }
        memcpy( dts_imp->buffer, lsmash_bs_get_buffer_data( bs ), LSMASH_MIN( remain_size, DTS_MAX_EXSS_SIZE ) );
        /* Check the remainder length of the buffer.
         * If there is enough length, then parse the frame in it.
         * The length 10 is the required byte length to get frame size. */
        if( bs->eob || (bs->eof && remain_size < 10) )
        {
            /* Reached the end of stream. */
            importer->status = IMPORTER_EOF;
            au_completed = !!dts_imp->incomplete_au_length;
            if( !au_completed )
            {
                /* No more access units in the stream. */
                if( lsmash_bs_get_remaining_buffer_size( bs ) )
                {
                    lsmash_log( importer, LSMASH_LOG_WARNING, "the stream is truncated at the end.\n" );
                    return LSMASH_ERR_INVALID_DATA;
                }
                return 0;
            }
            if( !info->ddts_param_initialized )
                dts_update_specific_param( info );
        }
        else
        {
            /* Parse substream frame. */
            dts_substream_type prev_substream_type = info->substream_type;
            info->substream_type = dts_get_substream_type( info );
            int err;
            int (*dts_parse_frame)( dts_info_t * ) = NULL;
            switch( info->substream_type )
            {
                /* Decide substream frame parser and check if this frame and the previous frame belong to the same AU. */
                case DTS_SUBSTREAM_TYPE_CORE :
                    if( prev_substream_type != DTS_SUBSTREAM_TYPE_NONE )
                        au_completed = 1;
                    dts_parse_frame = dts_parse_core_substream;
                    break;
                case DTS_SUBSTREAM_TYPE_EXTENSION :
                {
                    uint8_t prev_exss_index = info->exss_index;
                    if( (err = dts_get_exss_index( info, &info->exss_index )) < 0 )
                    {
                        lsmash_log( importer, LSMASH_LOG_ERROR, "failed to get the index of an extension substream.\n" );
                        return err;
                    }
                    if( prev_substream_type == DTS_SUBSTREAM_TYPE_EXTENSION
                     && info->exss_index <= prev_exss_index )
                        au_completed = 1;
                    dts_parse_frame = dts_parse_extension_substream;
                    break;
                }
                default :
                    lsmash_log( importer, LSMASH_LOG_ERROR, "unknown substream type is detected.\n" );
                    return LSMASH_ERR_NAMELESS;
            }
            if( !info->ddts_param_initialized && au_completed )
                dts_update_specific_param( info );
            info->frame_size = 0;
            if( (err = dts_parse_frame( info )) < 0 )
            {
                lsmash_log( importer, LSMASH_LOG_ERROR, "failed to parse a frame.\n" );
                return err;
            }
        }
        if( au_completed )
        {
            memcpy( dts_imp->au, dts_imp->incomplete_au, dts_imp->incomplete_au_length );
            dts_imp->au_length            = dts_imp->incomplete_au_length;
            dts_imp->incomplete_au_length = 0;
            info->exss_count = (info->substream_type == DTS_SUBSTREAM_TYPE_EXTENSION);
            if( importer->status == IMPORTER_EOF )
                break;
        }
        /* Increase buffer size to store AU if short. */
        if( dts_imp->incomplete_au_length + info->frame_size > dts_imp->au_buffers->buffer_size )
        {
            lsmash_multiple_buffers_t *temp = lsmash_resize_multiple_buffers( dts_imp->au_buffers,
                                                                              dts_imp->au_buffers->buffer_size + DTS_MAX_EXSS_SIZE );
            if( !temp )
                return LSMASH_ERR_MEMORY_ALLOC;
            dts_imp->au_buffers    = temp;
            dts_imp->au            = lsmash_withdraw_buffer( dts_imp->au_buffers, 1 );
            dts_imp->incomplete_au = lsmash_withdraw_buffer( dts_imp->au_buffers, 2 );
        }
        /* Append frame data. */
        memcpy( dts_imp->incomplete_au + dts_imp->incomplete_au_length, dts_imp->buffer, info->frame_size );
        dts_imp->incomplete_au_length += info->frame_size;
    }
    return bs->error ? LSMASH_ERR_NAMELESS : 0;
}