Example #1
0
lwlibav_audio_output_handler_t *lwlibav_audio_alloc_output_handler
(
    void
)
{
    return (lwlibav_audio_output_handler_t *)lw_malloc_zero( sizeof(lwlibav_audio_output_handler_t) );
}
libavsmash_video_output_handler_t *libavsmash_video_alloc_output_handler
(
    void
)
{
    return (libavsmash_video_output_handler_t *)lw_malloc_zero( sizeof(libavsmash_video_output_handler_t) );
}
LSMASHVideoSource::LSMASHVideoSource
(
    const char         *source,
    uint32_t            track_number,
    int                 threads,
    int                 seek_mode,
    uint32_t            forward_seek_threshold,
    int                 direct_rendering,
    int                 stacked_format,
    enum AVPixelFormat  pixel_format,
    IScriptEnvironment *env
)
{
    memset( &vi,  0, sizeof(VideoInfo) );
    memset( &vdh, 0, sizeof(libavsmash_video_decode_handler_t) );
    memset( &voh, 0, sizeof(libavsmash_video_output_handler_t) );
    format_ctx                 = NULL;
    vdh.seek_mode              = seek_mode;
    vdh.forward_seek_threshold = forward_seek_threshold;
    as_video_output_handler_t *as_vohp = (as_video_output_handler_t *)lw_malloc_zero( sizeof(as_video_output_handler_t) );
    if( !as_vohp )
        env->ThrowError( "LSMASHVideoSource: failed to allocate the AviSynth video output handler." );
    as_vohp->vi  = &vi;
    as_vohp->env = env;
    voh.private_handler      = as_vohp;
    voh.free_private_handler = as_free_video_output_handler;
    get_video_track( source, track_number, threads, env );
    lsmash_discard_boxes( vdh.root );
    prepare_video_decoding( direct_rendering, stacked_format, pixel_format, env );
}
Example #4
0
static int get_first_video_track( lsmash_handler_t *h, video_option_t *opt )
{
    if( h->audio_pcm_sample_count == 0 || h->audio_format.Format.nSamplesPerSec == 0 )
        return -1;  /* Only available if audio stream is present. */
    if( opt->dummy.framerate_den == 0 )
        return -1;
    h->framerate_num = opt->dummy.framerate_num;
    h->framerate_den = opt->dummy.framerate_den;
    h->video_sample_count = ((uint64_t)h->framerate_num * h->audio_pcm_sample_count - 1)
                            / ((uint64_t)h->framerate_den * h->audio_format.Format.nSamplesPerSec) + 1;
    static const struct
    {
        int                   pixel_size;
        output_colorspace_tag compression;
    } colorspace_table[3] =
    {
        { YUY2_SIZE,  OUTPUT_TAG_YUY2 },
        { RGB24_SIZE, OUTPUT_TAG_RGB  },
        { YC48_SIZE,  OUTPUT_TAG_YC48 }
    };
    int linesize = MAKE_AVIUTL_PITCH( opt->dummy.width * (colorspace_table[ opt->dummy.colorspace ].pixel_size << 3) );
    dummy_handler_t *hp = (dummy_handler_t *)h->video_private;
    hp->dummy_size = linesize * opt->dummy.height;
    if( hp->dummy_size <= 0 )
        return -1;
    hp->dummy_data = lw_malloc_zero( hp->dummy_size );
    if( !hp->dummy_data )
        return -1;
    uint8_t *pic = hp->dummy_data;
    switch( colorspace_table[ opt->dummy.colorspace ].compression )
    {
    case OUTPUT_TAG_YC48 :
    case OUTPUT_TAG_RGB :
        break;
    case OUTPUT_TAG_YUY2 :
        for( int i = 0; i < opt->dummy.height; i++ )
        {
            for( int j = 0; j < linesize; j += 2 )
            {
                pic[j    ] = 0;
                pic[j + 1] = 128;
            }
            pic += linesize;
        }
        break;
    default :
        lw_freep( &hp->dummy_data );
        return -1;
    }
    /* BITMAPINFOHEADER */
    h->video_format.biSize        = sizeof( BITMAPINFOHEADER );
    h->video_format.biWidth       = opt->dummy.width;
    h->video_format.biHeight      = opt->dummy.height;
    h->video_format.biBitCount    = colorspace_table[ opt->dummy.colorspace ].pixel_size << 3;
    h->video_format.biCompression = colorspace_table[ opt->dummy.colorspace ].compression;
    return 0;
}
Example #5
0
vs_video_output_handler_t *vs_allocate_video_output_handler
(
    lw_video_output_handler_t *vohp
)
{
    vs_video_output_handler_t *vs_vohp = lw_malloc_zero( sizeof(vs_video_output_handler_t) );
    if( !vs_vohp )
        return NULL;
    vohp->private_handler      = vs_vohp;
    vohp->free_private_handler = vs_free_video_output_handler;
    return vs_vohp;
}
/*****************************************************************************
 * Allocators / Deallocators
 *****************************************************************************/
libavsmash_video_decode_handler_t *libavsmash_video_alloc_decode_handler
(
    void
)
{
    libavsmash_video_decode_handler_t *vdhp = (libavsmash_video_decode_handler_t *)lw_malloc_zero( sizeof(libavsmash_video_decode_handler_t) );
    if( !vdhp )
        return NULL;
    vdhp->frame_buffer = av_frame_alloc();
    if( !vdhp->frame_buffer )
    {
        libavsmash_video_free_decode_handler( vdhp );
        return NULL;
    }
    return vdhp;
}
Example #7
0
/*****************************************************************************
 * Allocators / Deallocators
 *****************************************************************************/
lwlibav_audio_decode_handler_t *lwlibav_audio_alloc_decode_handler
(
    void
)
{
    lwlibav_audio_decode_handler_t *adhp = (lwlibav_audio_decode_handler_t *)lw_malloc_zero( sizeof(lwlibav_audio_decode_handler_t) );
    if( !adhp )
        return NULL;
    adhp->frame_buffer = av_frame_alloc();
    if( !adhp->frame_buffer )
    {
        lwlibav_audio_free_decode_handler( adhp );
        return NULL;
    }
    return adhp;
}
Example #8
0
/* Allocate the handler of this plugin. */
static lwlibav_handler_t *alloc_handler
(
    void
)
{
    lwlibav_handler_t *hp = lw_malloc_zero( sizeof(lwlibav_handler_t) );
    if( !hp )
        return NULL;
    if( !(hp->vdhp = lwlibav_video_alloc_decode_handler())
     || !(hp->vohp = lwlibav_video_alloc_output_handler())
     || !(hp->adhp = lwlibav_audio_alloc_decode_handler())
     || !(hp->aohp = lwlibav_audio_alloc_output_handler()) )
    {
        free_handler( &hp );
        return NULL;
    }
    return hp;
}
Example #9
0
static void *open_file( char *file_name, reader_option_t *opt )
{
    /* Check file extension. */
    if( lw_check_file_extension( file_name, "avs" ) < 0 )
        return NULL;
    /* Try to open the file as avisynth script. */
    avs_handler_t *hp = lw_malloc_zero( sizeof(avs_handler_t) );
    if( !hp )
        return NULL;
    AVS_Value res = initialize_avisynth( hp, file_name );
    if( !avs_is_clip( res ) )
    {
        if( hp->library )
            close_avisynth_dll( hp );
        lw_free( hp );
        return NULL;
    }
    hp->func.avs_release_value( res );
    return hp;
}
int libavsmash_video_create_keyframe_list
(
    libavsmash_video_decode_handler_t *vdhp
)
{
    vdhp->keyframe_list = (uint8_t *)lw_malloc_zero( (vdhp->sample_count + 1) * sizeof(uint8_t) );
    if( !vdhp->keyframe_list )
        return -1;
    for( uint32_t composition_sample_number = 1; composition_sample_number <= vdhp->sample_count; composition_sample_number++ )
    {
        uint32_t decoding_sample_number = get_decoding_sample_number( vdhp->order_converter, composition_sample_number );
        uint32_t rap_number;
        if( lsmash_get_closest_random_accessible_point_from_media_timeline( vdhp->root,
                                                                            vdhp->track_id,
                                                                            decoding_sample_number, &rap_number ) < 0 )
            continue;
        if( decoding_sample_number == rap_number )
            vdhp->keyframe_list[composition_sample_number] = 1;
    }
    return 0;
}
/* Allocate the handler of this plugin. */
static lsmas_handler_t *alloc_handler
(
    void
)
{
    lsmas_handler_t *hp = lw_malloc_zero( sizeof(lsmas_handler_t) );
    if( !hp )
        return NULL;
    hp->vdhp = libavsmash_video_alloc_decode_handler();
    if( !hp->vdhp )
    {
        free_handler( &hp );
        return NULL;
    }
    hp->vohp = libavsmash_video_alloc_output_handler();
    if( !hp->vohp )
    {
        free_handler( &hp );
        return NULL;
    }
    return hp;
}
Example #12
0
static void *open_file( char *file_path, reader_option_t *opt )
{
    libav_handler_t *hp = lw_malloc_zero( sizeof(libav_handler_t) );
    if( !hp )
        return NULL;
    /* Set up error handler. */
    lw_log_handler_t lh = { 0 };
    lh.level    = LW_LOG_FATAL;
    lh.priv     = &hp->uType;
    lh.show_log = NULL;
    hp->uType = MB_ICONERROR | MB_OK;
    /* Set options. */
    lwlibav_option_t lwlibav_opt;
    lwlibav_opt.file_path         = file_path;
    lwlibav_opt.threads           = opt->threads;
    lwlibav_opt.av_sync           = opt->av_sync;
    lwlibav_opt.no_create_index   = opt->no_create_index;
    lwlibav_opt.force_video       = opt->force_video;
    lwlibav_opt.force_video_index = opt->force_video_index;
    lwlibav_opt.force_audio       = opt->force_audio;
    lwlibav_opt.force_audio_index = opt->force_audio_index;
    lwlibav_opt.apply_repeat_flag = opt->video_opt.apply_repeat_flag;
    lwlibav_opt.field_dominance   = opt->video_opt.field_dominance;
    /* Set up progress indicator. */
    progress_indicator_t indicator;
    indicator.open   = open_indicator;
    indicator.update = update_indicator;
    indicator.close  = close_indicator;
    progress_handler_t ph = { { 0 } };
    ph.module_name = "lwinput.aui";
    ph.template_id = IDD_PROGRESS_ABORTABLE;
    /* Construct index. */
    if( lwlibav_construct_index( &hp->lwh, &hp->vdh, &hp->voh, &hp->adh, &hp->aoh, &lh, &lwlibav_opt, &indicator, &ph ) < 0 )
    {
        free( hp );
        return NULL;
    }
    return hp;
}
Example #13
0
static void *open_file
(
    char            *file_name,
    reader_option_t *opt
)
{
    /* Check file extension. */
    if( lw_check_file_extension( file_name, "vpy" ) < 0 )
        return NULL;
    /* Try to open the file as VapourSynth script. */
    vpy_handler_t *hp = lw_malloc_zero( sizeof(vpy_handler_t) );
    if( !hp )
        return NULL;
    if( load_vsscript_dll( hp ) < 0 )
    {
        free( hp );
        return NULL;
    }
    if( hp->vsscript.func.init() == 0 )
        goto fail;
    hp->vsapi = hp->vsscript.func.getVSApi();
    if( !hp->vsapi || hp->vsscript.func.evaluateFile( &hp->vsscript.handle, file_name, efSetWorkingDir ) )
        goto fail;
    hp->node = hp->vsscript.func.getOutput( hp->vsscript.handle, 0 );
    if( !hp->node )
        goto fail;
    hp->vi = hp->vsapi->getVideoInfo( hp->node );
    /* */
    hp->ctx = avcodec_alloc_context3( NULL );
    if( !hp->ctx )
        goto fail;
    return hp;
fail:
    if( hp->library )
        close_vsscript_dll( hp );
    free( hp );
    return NULL;
}
Example #14
0
static void *open_file( char *file_name, reader_option_t *opt )
{
    /* Check file extension. */
    int file_name_length = strlen( file_name );
    if( file_name_length < 5 )
        return NULL;
    char *ext = &file_name[file_name_length - 4];
    if( ext[0] != '.' || ext[1] != 'a' || ext[2] != 'v' || ext[3] != 's' )
        return NULL;
    /* Try to open the file as avisynth script. */
    avs_handler_t *hp = lw_malloc_zero( sizeof(avs_handler_t) );
    if( !hp )
        return NULL;
    AVS_Value res = initialize_avisynth( hp, file_name );
    if( !avs_is_clip( res ) )
    {
        if( hp->library )
            close_avisynth_dll( hp );
        free( hp );
        return NULL;
    }
    hp->func.avs_release_value( res );
    return hp;
}
int libavsmash_video_setup_timestamp_info
(
    libavsmash_video_decode_handler_t *vdhp,
    libavsmash_video_output_handler_t *vohp,
    int64_t                           *framerate_num,
    int64_t                           *framerate_den
)
{
    int err = -1;
    uint64_t media_timescale = lsmash_get_media_timescale( vdhp->root, vdhp->track_id );
    uint64_t media_duration  = lsmash_get_media_duration_from_media_timeline( vdhp->root, vdhp->track_id );
    if( media_duration == 0 )
        media_duration = INT32_MAX;
    if( vdhp->sample_count == 1 )
    {
        /* Calculate average framerate. */
        reduce_fraction( &media_timescale, &media_duration );
        *framerate_num = (int64_t)media_timescale;
        *framerate_den = (int64_t)media_duration;
        err = 0;
        goto setup_finish;
    }
    lw_log_handler_t *lhp = &vdhp->config.lh;
    lsmash_media_ts_list_t ts_list;
    if( lsmash_get_media_timestamps( vdhp->root, vdhp->track_id, &ts_list ) < 0 )
    {
        lw_log_show( lhp, LW_LOG_ERROR, "Failed to get timestamps." );
        goto setup_finish;
    }
    if( ts_list.sample_count != vdhp->sample_count )
    {
        lw_log_show( lhp, LW_LOG_ERROR, "Failed to count number of video samples." );
        goto setup_finish;
    }
    uint32_t composition_sample_delay;
    if( lsmash_get_max_sample_delay( &ts_list, &composition_sample_delay ) < 0 )
    {
        lsmash_delete_media_timestamps( &ts_list );
        lw_log_show( lhp, LW_LOG_ERROR, "Failed to get composition delay." );
        goto setup_finish;
    }
    if( composition_sample_delay )
    {
        /* Consider composition order for keyframe detection.
         * Note: sample number for L-SMASH is 1-origin. */
        vdhp->order_converter = (order_converter_t *)lw_malloc_zero( (ts_list.sample_count + 1) * sizeof(order_converter_t) );
        if( !vdhp->order_converter )
        {
            lsmash_delete_media_timestamps( &ts_list );
            lw_log_show( lhp, LW_LOG_ERROR, "Failed to allocate memory." );
            goto setup_finish;
        }
        for( uint32_t i = 0; i < ts_list.sample_count; i++ )
            ts_list.timestamp[i].dts = i + 1;
        lsmash_sort_timestamps_composition_order( &ts_list );
        for( uint32_t i = 0; i < ts_list.sample_count; i++ )
            vdhp->order_converter[i + 1].composition_to_decoding = (uint32_t)ts_list.timestamp[i].dts;
    }
    /* Calculate average framerate. */
    uint64_t largest_cts          = ts_list.timestamp[0].cts;
    uint64_t second_largest_cts   = 0;
    uint64_t first_duration       = ts_list.timestamp[1].cts - ts_list.timestamp[0].cts;
    uint64_t composition_timebase = first_duration;
    int      strict_cfr           = 1;
    for( uint32_t i = 1; i < ts_list.sample_count; i++ )
    {
        uint64_t duration = ts_list.timestamp[i].cts - ts_list.timestamp[i - 1].cts;
        if( duration == 0 )
        {
            lsmash_delete_media_timestamps( &ts_list );
            lw_log_show( lhp, LW_LOG_WARNING, "Detected CTS duplication at frame %" PRIu32, i );
            err = 0;
            goto setup_finish;
        }
        if( strict_cfr && duration != first_duration )
            strict_cfr = 0;
        composition_timebase = get_gcd( composition_timebase, duration );
        second_largest_cts   = largest_cts;
        largest_cts          = ts_list.timestamp[i].cts;
    }
    uint64_t reduce = reduce_fraction( &media_timescale, &composition_timebase );
    uint64_t composition_duration = ((largest_cts - ts_list.timestamp[0].cts) + (largest_cts - second_largest_cts)) / reduce;
    lsmash_delete_media_timestamps( &ts_list );
    double avg_frame_rate = (vdhp->sample_count * ((double)media_timescale / composition_duration));
    if( strict_cfr || !lw_try_rational_framerate( avg_frame_rate, framerate_num, framerate_den, composition_timebase ) )
    {
        uint64_t num = (uint64_t)(avg_frame_rate * composition_timebase + 0.5);
        uint64_t den = composition_timebase;
        if( num && den )
            reduce_fraction( &num, &den );
        else
        {
            num = 1;
            den = 1;
        }
        *framerate_num = (int64_t)num;
        *framerate_den = (int64_t)den;
    }
    err = 0;
setup_finish:;
    if( vohp->vfr2cfr )
    {
        /* Override average framerate by specified output constant framerate. */
        *framerate_num = (int64_t)vohp->cfr_num;
        *framerate_den = (int64_t)vohp->cfr_den;
        vohp->frame_count = ((double)vohp->cfr_num / vohp->cfr_den)
                          * ((double)media_duration / media_timescale)
                          + 0.5;
    }
    else
        vohp->frame_count = libavsmash_video_get_sample_count( vdhp );
    uint32_t min_cts_sample_number = get_decoding_sample_number( vdhp->order_converter, 1 );
    vdhp->config.error = lsmash_get_cts_from_media_timeline( vdhp->root, vdhp->track_id, min_cts_sample_number, &vdhp->min_cts );
    return err;
}
Example #16
0
INPUT_HANDLE func_open( LPSTR file )
{
    lsmash_handler_t *hp = (lsmash_handler_t *)lw_malloc_zero( sizeof(lsmash_handler_t) );
    if( !hp )
        return NULL;
    hp->video_reader = READER_NONE;
    hp->audio_reader = READER_NONE;
    get_settings();
    if( reader_opt.threads <= 0 )
        reader_opt.threads = get_auto_threads();
    extern lsmash_reader_t libavsmash_reader;
    extern lsmash_reader_t avs_reader;
    extern lsmash_reader_t vpy_reader;
    extern lsmash_reader_t libav_reader;
    extern lsmash_reader_t dummy_reader;
    static lsmash_reader_t *lsmash_reader_table[] =
    {
        &libavsmash_reader,
        &avs_reader,
        &vpy_reader,
        &libav_reader,
        &dummy_reader,
        NULL
    };
    for( int i = 0; lsmash_reader_table[i]; i++ )
    {
        if( reader_disabled[lsmash_reader_table[i]->type - 1] )
            continue;
        int video_none = 1;
        int audio_none = 1;
        lsmash_reader_t reader = *lsmash_reader_table[i];
        void *private_stuff = reader.open_file( file, &reader_opt );
        if( private_stuff )
        {
            if( !hp->video_private )
            {
                hp->video_private = private_stuff;
                if( reader.get_video_track
                 && reader.get_video_track( hp ) == 0 )
                {
                    hp->video_reader     = reader.type;
                    hp->read_video       = reader.read_video;
                    hp->is_keyframe      = reader.is_keyframe;
                    hp->video_cleanup    = reader.video_cleanup;
                    hp->close_video_file = reader.close_file;
                    video_none = 0;
                }
                else
                    hp->video_private = NULL;
            }
            if( !hp->audio_private )
            {
                hp->audio_private = private_stuff;
                if( reader.get_audio_track
                 && reader.get_audio_track( hp ) == 0 )
                {
                    hp->audio_reader     = reader.type;
                    hp->read_audio       = reader.read_audio;
                    hp->delay_audio      = reader.delay_audio;
                    hp->audio_cleanup    = reader.audio_cleanup;
                    hp->close_audio_file = reader.close_file;
                    audio_none = 0;
                }
                else
                    hp->audio_private = NULL;
            }
        }
        if( video_none && audio_none )
        {
            if( reader.close_file )
                reader.close_file( private_stuff );
        }
        else
        {
            if( reader.destroy_disposable )
                reader.destroy_disposable( private_stuff );
            if( !video_none
             && reader.prepare_video_decoding
             && reader.prepare_video_decoding( hp, video_opt ) )
            {
                if( hp->video_cleanup )
                {
                    hp->video_cleanup( hp );
                    hp->video_cleanup = NULL;
                }
                hp->video_private = NULL;
                hp->video_reader  = READER_NONE;
                video_none = 1;
            }
            if( !audio_none
             && reader.prepare_audio_decoding
             && reader.prepare_audio_decoding( hp, audio_opt ) )
            {
                if( hp->audio_cleanup )
                {
                    hp->audio_cleanup( hp );
                    hp->audio_cleanup = NULL;
                }
                hp->audio_private = NULL;
                hp->audio_reader  = READER_NONE;
                audio_none = 1;
            }
            if( video_none && audio_none && reader.close_file )
                reader.close_file( private_stuff );
        }
        /* Found both video and audio reader. */
        if( hp->video_reader != READER_NONE && hp->audio_reader != READER_NONE )
            break;
    }
    if( hp->video_reader == hp->audio_reader )
    {
        hp->global_private = hp->video_private;
        hp->close_file     = hp->close_video_file;
        hp->close_video_file = NULL;
        hp->close_audio_file = NULL;
    }
    if( hp->video_reader == READER_NONE && hp->audio_reader == READER_NONE )
    {
        DEBUG_MESSAGE_BOX_DESKTOP( MB_OK, "No readable video and/or audio stream" );
        func_close( hp );
        return NULL;
    }
    return hp;
}
Example #17
0
static void *open_file( char *file_name, reader_option_t *opt )
{
    return lw_malloc_zero( sizeof(dummy_handler_t) );
}