Exemple #1
0
int lsmash_set_tyrant_chapter( lsmash_root_t *root, char *file_name, int add_bom )
{
    /* This function should be called after updating of the latest movie duration. */
    if( !root || !root->moov || !root->moov->mvhd || !root->moov->mvhd->timescale || !root->moov->mvhd->duration )
        goto error_message;
    /* check each line format */
    fn_get_chapter_data fnc = isom_check_chap_line( file_name );
    if( !fnc )
        goto error_message;
    FILE *chapter = fopen( file_name, "rb" );
    if( !chapter )
    {
        lsmash_log( LSMASH_LOG_ERROR, "failed to open the chapter file \"%s\".\n", file_name );
        goto error_message;
    }
    if( isom_add_udta( root, 0 ) || isom_add_chpl( root->moov ) )
        goto fail;
    isom_chapter_entry_t data = {0};
    while( !fnc( chapter, &data ) )
    {
        if( add_bom )
        {
            char *chapter_name_with_bom = (char *)malloc( strlen( data.chapter_name ) + 1 + UTF8_BOM_LENGTH );
            if( !chapter_name_with_bom )
                goto fail2;
            sprintf( chapter_name_with_bom, "%s%s", UTF8_BOM, data.chapter_name );
            free( data.chapter_name );
            data.chapter_name = chapter_name_with_bom;
        }
        data.start_time = (data.start_time + 50) / 100;    /* convert to 100ns unit */
        if( data.start_time / 1e7 > (double)root->moov->mvhd->duration / root->moov->mvhd->timescale )
        {
            lsmash_log( LSMASH_LOG_WARNING, "a chapter point exceeding the actual duration detected. This chapter point and the following ones (if any) will be cut off.\n" );
            free( data.chapter_name );
            break;
        }
        if( isom_add_chpl_entry( root->moov->udta->chpl, &data ) )
            goto fail2;
        free( data.chapter_name );
        data.chapter_name = NULL;
    }
    fclose( chapter );
    return 0;
fail2:
    if( data.chapter_name )
        free( data.chapter_name );
fail:
    fclose( chapter );
error_message:
    lsmash_log( LSMASH_LOG_ERROR, "failed to set chapter list.\n" );
    return -1;
}
Exemple #2
0
int lsmash_set_tyrant_chapter( lsmash_root_t *root, char *file_name, int add_bom )
{
    if( isom_check_initializer_present( root ) < 0 )
        goto error_message;
    /* This function should be called after updating of the latest movie duration. */
    lsmash_file_t *file = root->file;
    if( !file
     || !file->moov
     || !file->moov->mvhd
     ||  file->moov->mvhd->timescale == 0
     ||  file->moov->mvhd->duration  == 0 )
        goto error_message;
    /* check each line format */
    fn_get_chapter_data fnc = isom_check_chap_line( file_name );
    if( !fnc )
        goto error_message;
    FILE *chapter = lsmash_fopen( file_name, "rb" );
    if( !chapter )
    {
        lsmash_log( NULL, LSMASH_LOG_ERROR, "failed to open the chapter file \"%s\".\n", file_name );
        goto error_message;
    }
    if( (!file->moov->udta       && !isom_add_udta( file->moov ))
     || (!file->moov->udta->chpl && !isom_add_chpl( file->moov->udta )) )
        goto fail;
    file->moov->udta->chpl->version = 1;    /* version = 1 is popular. */
    isom_chapter_entry_t data = { 0 };
    while( !fnc( chapter, &data ) )
    {
        if( add_bom )
        {
            char *chapter_name_with_bom = (char *)lsmash_malloc( strlen( data.chapter_name ) + 1 + UTF8_BOM_LENGTH );
            if( !chapter_name_with_bom )
                goto fail2;
            sprintf( chapter_name_with_bom, "%s%s", UTF8_BOM, data.chapter_name );
            lsmash_free( data.chapter_name );
            data.chapter_name = chapter_name_with_bom;
        }
        data.start_time = (data.start_time + 50) / 100;    /* convert to 100ns unit */
        if( data.start_time / 1e7 > (double)file->moov->mvhd->duration / file->moov->mvhd->timescale )
        {
            lsmash_log( NULL, LSMASH_LOG_WARNING,
                        "a chapter point exceeding the actual duration detected."
                        "This chapter point and the following ones (if any) will be cut off.\n" );
            lsmash_free( data.chapter_name );
            break;
        }
        if( isom_add_chpl_entry( file->moov->udta->chpl, &data ) < 0 )
            goto fail2;
        lsmash_freep( &data.chapter_name );
    }
    fclose( chapter );
    return 0;
fail2:
    lsmash_free( data.chapter_name );
fail:
    fclose( chapter );
error_message:
    lsmash_log( NULL, LSMASH_LOG_ERROR, "failed to set chapter list.\n" );
    return LSMASH_ERR_NAMELESS;
}