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 ); }
static int get_video_track( lsmash_handler_t *h, video_option_t *opt ) { avs_handler_t *hp = (avs_handler_t *)h->video_private; if( hp->vi->num_frames <= 0 || hp->vi->width <= 0 || hp->vi->height <= 0 ) return -1; hp->av_frame = av_frame_alloc(); if( !hp->av_frame ) return -1; hp->bit_depth = opt->avs.bit_depth; return prepare_video_decoding( h, opt ); }
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; }
void VS_CC vs_lwlibavsource_create( const VSMap *in, VSMap *out, void *user_data, VSCore *core, const VSAPI *vsapi ) { /* Get file path. */ const char *file_path = vsapi->propGetData( in, "source", 0, NULL ); if( !file_path ) { vsapi->setError( out, "lsmas: failed to get source file name." ); return; } /* Allocate the handler of this filter function. */ lwlibav_handler_t *hp = alloc_handler(); if( !hp ) { vsapi->setError( out, "lsmas: failed to allocate the LW-Libav handler." ); return; } lwlibav_file_handler_t *lwhp = &hp->lwh; lwlibav_video_decode_handler_t *vdhp = hp->vdhp; lwlibav_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; /* Get options. */ int64_t stream_index; int64_t threads; int64_t cache_index; int64_t seek_mode; int64_t seek_threshold; int64_t variable_info; int64_t direct_rendering; int64_t fps_num; int64_t fps_den; int64_t apply_repeat_flag; int64_t field_dominance; const char *format; const char *preferred_decoder_names; set_option_int64 ( &stream_index, -1, "stream_index", in, vsapi ); set_option_int64 ( &threads, 0, "threads", in, vsapi ); set_option_int64 ( &cache_index, 1, "cache", 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_int64 ( &apply_repeat_flag, 0, "repeat", in, vsapi ); set_option_int64 ( &field_dominance, 0, "dominance", 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 ); /* Set options. */ lwlibav_option_t opt; opt.file_path = file_path; opt.threads = threads >= 0 ? threads : 0; opt.av_sync = 0; opt.no_create_index = !cache_index; opt.force_video = (stream_index >= 0); opt.force_video_index = stream_index >= 0 ? stream_index : -1; opt.force_audio = 0; opt.force_audio_index = -1; opt.apply_repeat_flag = apply_repeat_flag; opt.field_dominance = CLIP_VALUE( field_dominance, 0, 2 ); /* 0: Obey source flags, 1: TFF, 2: BFF */ opt.vfr2cfr.active = fps_num > 0 && fps_den > 0 ? 1 : 0; opt.vfr2cfr.fps_num = fps_num; opt.vfr2cfr.fps_den = fps_den; lwlibav_video_set_seek_mode ( vdhp, CLIP_VALUE( seek_mode, 0, 2 ) ); lwlibav_video_set_forward_seek_threshold ( vdhp, CLIP_VALUE( seek_threshold, 1, 999 ) ); lwlibav_video_set_preferred_decoder_names( vdhp, tokenize_preferred_decoder_names( hp->preferred_decoder_names_buf ) ); 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 ); /* Set up progress indicator. */ progress_indicator_t indicator; indicator.open = NULL; indicator.update = NULL; indicator.close = NULL; /* Construct index. */ int ret = lwlibav_construct_index( lwhp, vdhp, vohp, hp->adhp, hp->aohp, &lh, &opt, &indicator, NULL ); lwlibav_audio_free_decode_handler_ptr( &hp->adhp ); lwlibav_audio_free_output_handler_ptr( &hp->aohp ); if( ret < 0 ) { vs_filter_free( hp, core, vsapi ); set_error_on_init( out, vsapi, "lsmas: failed to construct index." ); return; } /* Get the desired video track. */ lwlibav_video_set_log_handler( vdhp, &lh ); if( lwlibav_video_get_desired_track( lwhp->file_path, vdhp, lwhp->threads ) < 0 ) { vs_filter_free( hp, core, vsapi ); return; } /* Set average framerate. */ hp->vi.numFrames = vohp->frame_count; hp->vi.fpsNum = 25; hp->vi.fpsDen = 1; lwlibav_video_setup_timestamp_info( lwhp, vdhp, vohp, &hp->vi.fpsNum, &hp->vi.fpsDen ); /* Set up decoders for this stream. */ if( prepare_video_decoding( hp, out, core, vsapi ) < 0 ) { vs_filter_free( hp, core, vsapi ); return; } vsapi->createFilter( in, out, "LWLibavSource", vs_filter_init, vs_filter_get_frame, vs_filter_free, fmUnordered, nfMakeLinear, hp, core ); return; }