/* Deallocate the handler of this plugin. */ static void free_handler ( lsmas_handler_t **hpp ) { if( !hpp || !*hpp ) return; lsmas_handler_t *hp = *hpp; lsmash_root_t *root = libavsmash_video_get_root( hp->vdhp ); lw_free( libavsmash_video_get_preferred_decoder_names( hp->vdhp ) ); libavsmash_video_free_decode_handler( hp->vdhp ); libavsmash_video_free_output_handler( hp->vohp ); avformat_close_input( &hp->format_ctx ); lsmash_close_file( &hp->file_param ); lsmash_destroy_root( root ); lw_free( hp ); }
/***************************************************************************** * Others *****************************************************************************/ int libavsmash_video_get_track ( libavsmash_video_decode_handler_t *vdhp, uint32_t track_number ) { lw_log_handler_t *lhp = libavsmash_video_get_log_handler( vdhp ); uint32_t track_id = libavsmash_get_track_by_media_type ( libavsmash_video_get_root( vdhp ), ISOM_MEDIA_HANDLER_TYPE_VIDEO_TRACK, track_number, lhp ); if( track_id == 0 ) return -1; libavsmash_video_set_track_id( vdhp, track_id ); (void)libavsmash_video_fetch_sample_count ( vdhp ); (void)libavsmash_video_fetch_media_duration ( vdhp ); (void)libavsmash_video_fetch_media_timescale( vdhp ); return 0; }
void VS_CC vs_libavsmashsource_create( const VSMap *in, VSMap *out, void *user_data, VSCore *core, const VSAPI *vsapi ) { /* Get file name. */ const char *file_name = vsapi->propGetData( in, "source", 0, NULL ); if( !file_name ) { vsapi->setError( out, "lsmas: failed to get source file name." ); return; } /* Allocate the handler of this plugin. */ lsmas_handler_t *hp = alloc_handler(); if( !hp ) { vsapi->setError( out, "lsmas: failed to allocate the handler." ); return; } libavsmash_video_decode_handler_t *vdhp = hp->vdhp; libavsmash_video_output_handler_t *vohp = hp->vohp; vs_video_output_handler_t *vs_vohp = vs_allocate_video_output_handler( vohp ); if( !vs_vohp ) { free_handler( &hp ); vsapi->setError( out, "lsmas: failed to allocate the VapourSynth video output handler." ); return; } vohp->private_handler = vs_vohp; vohp->free_private_handler = lw_free; /* Set up VapourSynth error handler. */ vs_basic_handler_t vsbh = { 0 }; vsbh.out = out; vsbh.frame_ctx = NULL; vsbh.vsapi = vsapi; /* Set up log handler. */ lw_log_handler_t lh = { 0 }; lh.level = LW_LOG_FATAL; lh.priv = &vsbh; lh.show_log = set_error; /* Open source file. */ uint32_t number_of_tracks = open_file( hp, file_name, &lh ); if( number_of_tracks == 0 ) { vs_filter_free( hp, core, vsapi ); return; } /* Get options. */ int64_t track_number; int64_t threads; int64_t seek_mode; int64_t seek_threshold; int64_t variable_info; int64_t direct_rendering; int64_t fps_num; int64_t fps_den; const char *format; const char *preferred_decoder_names; set_option_int64 ( &track_number, 0, "track", in, vsapi ); set_option_int64 ( &threads, 0, "threads", in, vsapi ); set_option_int64 ( &seek_mode, 0, "seek_mode", in, vsapi ); set_option_int64 ( &seek_threshold, 10, "seek_threshold", in, vsapi ); set_option_int64 ( &variable_info, 0, "variable", in, vsapi ); set_option_int64 ( &direct_rendering, 0, "dr", in, vsapi ); set_option_int64 ( &fps_num, 0, "fpsnum", in, vsapi ); set_option_int64 ( &fps_den, 1, "fpsden", in, vsapi ); set_option_string( &format, NULL, "format", in, vsapi ); set_option_string( &preferred_decoder_names, NULL, "decoder", in, vsapi ); set_preferred_decoder_names_on_buf( hp->preferred_decoder_names_buf, preferred_decoder_names ); libavsmash_video_set_seek_mode ( vdhp, CLIP_VALUE( seek_mode, 0, 2 ) ); libavsmash_video_set_forward_seek_threshold ( vdhp, CLIP_VALUE( seek_threshold, 1, 999 ) ); libavsmash_video_set_preferred_decoder_names( vdhp, tokenize_preferred_decoder_names( hp->preferred_decoder_names_buf ) ); vohp->vfr2cfr = (fps_num > 0 && fps_den > 0); vohp->cfr_num = (uint32_t)fps_num; vohp->cfr_den = (uint32_t)fps_den; vs_vohp->variable_info = CLIP_VALUE( variable_info, 0, 1 ); vs_vohp->direct_rendering = CLIP_VALUE( direct_rendering, 0, 1 ) && !format; vs_vohp->vs_output_pixel_format = vs_vohp->variable_info ? pfNone : get_vs_output_pixel_format( format ); if( track_number && track_number > number_of_tracks ) { vs_filter_free( hp, core, vsapi ); set_error_on_init( out, vsapi, "lsmas: the number of tracks equals %"PRIu32".", number_of_tracks ); return; } libavsmash_video_set_log_handler( vdhp, &lh ); /* Get video track. */ if( libavsmash_video_get_track( vdhp, track_number ) < 0 ) { vs_filter_free( hp, core, vsapi ); return; } /* Set up decoders for this track. */ threads = threads >= 0 ? threads : 0; if( prepare_video_decoding( hp, threads, out, core, vsapi ) < 0 ) { vs_filter_free( hp, core, vsapi ); return; } lsmash_discard_boxes( libavsmash_video_get_root( vdhp ) ); vsapi->createFilter( in, out, "LibavSMASHSource", vs_filter_init, vs_filter_get_frame, vs_filter_free, fmUnordered, nfMakeLinear, hp, core ); return; }