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;
}
int
cmd_set_window_option_exec(struct cmd *self, struct cmd_ctx *ctx)
{
	struct cmd_option_data		*data = self->data;
	struct winlink			*wl;
	struct client			*c;
	struct options			*oo;
	const struct set_option_entry   *entry;
	u_int				 i;

	if (data->flags & CMD_GFLAG)
		oo = &global_window_options;
	else {
		if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
			return (-1);
		oo = &wl->window->options;
	}

	if (*data->option == '\0') {
		ctx->error(ctx, "invalid option");
		return (-1);
	}

	entry = NULL;
	for (i = 0; i < NSETWINDOWOPTION; i++) {
		if (strncmp(set_window_option_table[i].name,
		    data->option, strlen(data->option)) != 0)
			continue;
		if (entry != NULL) {
			ctx->error(ctx, "ambiguous option: %s", data->option);
			return (-1);
		}
		entry = &set_window_option_table[i];

		/* Bail now if an exact match. */
		if (strcmp(entry->name, data->option) == 0)
			break;
	}
	if (entry == NULL) {
		ctx->error(ctx, "unknown option: %s", data->option);
		return (-1);
	}

	if (data->flags & CMD_UFLAG) {
		if (data->flags & CMD_GFLAG) {
			ctx->error(ctx,
			    "can't unset global option: %s", entry->name);
			return (-1);
		}
		if (data->value != NULL) {
			ctx->error(ctx,
			    "value passed to unset option: %s", entry->name);
			return (-1);
		}

		options_remove(oo, entry->name);
		ctx->info(ctx, "unset option: %s", entry->name);
	} else {
		switch (entry->type) {
		case SET_OPTION_STRING:
			set_option_string(ctx, oo, entry, data->value);
			break;
		case SET_OPTION_NUMBER:
			set_option_number(ctx, oo, entry, data->value);
			break;
		case SET_OPTION_KEY:
			set_option_key(ctx, oo, entry, data->value);
			break;
		case SET_OPTION_COLOUR:
			set_option_colour(ctx, oo, entry, data->value);
			break;
		case SET_OPTION_ATTRIBUTES:
			set_option_attributes(ctx, oo, entry, data->value);
			break;
		case SET_OPTION_FLAG:
			set_option_flag(ctx, oo, entry, data->value);
			break;
		case SET_OPTION_CHOICE:
			set_option_choice(ctx, oo, entry, data->value);
			break;
		}
	}

	recalculate_sizes();
	for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
		c = ARRAY_ITEM(&clients, i);
		if (c != NULL && c->session != NULL)
			server_redraw_client(c);
	}

	return (0);
}
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;
}