X-Git-Url: http://git.cinelerra-gg.org/git/?p=goodguy%2Fhistory.git;a=blobdiff_plain;f=cinelerra-5.1%2Fcinelerra%2Fpluginfclient.C;h=c5d02db8ae36b69a7c11eb5f9a19fd056a31d4d6;hp=644bd52744b450c81f388ee53ccc6aa6a35dbdb7;hb=7e5a0760f40ff787cc3d93cb7768a901ebe52809;hpb=21c2e6b36d6a96c2f662a89459d607b5a387f4eb diff --git a/cinelerra-5.1/cinelerra/pluginfclient.C b/cinelerra-5.1/cinelerra/pluginfclient.C index 644bd527..c5d02db8 100644 --- a/cinelerra-5.1/cinelerra/pluginfclient.C +++ b/cinelerra-5.1/cinelerra/pluginfclient.C @@ -16,6 +16,9 @@ #include "vframe.h" #include "filexml.h" +#ifdef FFMPEG3 +#define av_filter_iterate(p) ((*(const AVFilter**)(p))=avfilter_next(*(const AVFilter **)(p))) +#endif static void ff_err(int ret, const char *fmt, ...) { @@ -101,6 +104,13 @@ void PluginFClientConfig::initialize(const char *name) append(fopt); } } + if( (ffilt->filter->flags & AVFILTER_FLAG_SLICE_THREADS) != 0 ) { + opt = av_opt_find(ffilt->fctx, "threads", NULL, 0, 0); + if( opt ) { + PluginFClient_Opt *fopt = new PluginFClient_Opt(this, opt); + append(fopt); + } + } } int PluginFClientConfig::update() @@ -217,12 +227,75 @@ PluginFClientApply:: int PluginFClientApply::handle_event() { - const char *text = fwin->text->get_text(); - if( text && fwin->selected ) { - fwin->selected->set(text); - fwin->selected->item_value->update(); - fwin->draw(); - fwin->ffmpeg->plugin->send_configure_change(); + return fwin->update(); +} + +PluginFClientPot::PluginFClientPot(PluginFClientWindow *fwin, int x, int y) + : BC_FPot(x, y, 0.f, 0.f, 0.f) +{ + this->fwin = fwin; +} + +int PluginFClient_Opt::get_range(float &fmn, float &fmx) +{ + switch( opt->type ) { + case AV_OPT_TYPE_INT: + case AV_OPT_TYPE_INT64: + case AV_OPT_TYPE_DOUBLE: + case AV_OPT_TYPE_FLOAT: break; + default: return 1; + } + const AVClass *filt_class = filter_class(); + if( !filt_class || !filt_class->option ) return 1; + AVOptionRanges *r = 0; + void *obj = &filt_class; + if( av_opt_query_ranges(&r, obj, opt->name, AV_OPT_SEARCH_FAKE_OBJ) < 0 ) return 1; + int ret = 1; + if( r->nb_ranges == 1 ) { + fmn = r->range[0]->value_min; + fmx = r->range[0]->value_max; + ret = 0; + } + av_opt_freep_ranges(&r); + return ret; +} + +float PluginFClient_Opt::get_float() +{ + char val[BCTEXTLEN]; val[0] = 0; + get(val, sizeof(val)); + return atof(val); +} + +void PluginFClient_Opt::set_float(float v) +{ + char val[BCTEXTLEN]; val[0] = 0; + sprintf(val, "%f", v); + set(val); +} + +int PluginFClientPot::handle_event() +{ + if( fwin->selected ) { + fwin->selected->set_float(get_value()); + fwin->update_selected(); + return fwin->update(); + } + return 1; +} + +PluginFClientSlider::PluginFClientSlider(PluginFClientWindow *fwin, int x, int y) + : BC_FSlider(x, y, 0, fwin->get_w()-x-20, fwin->get_w()-x-20, 0.f, 0.f, 0.f) +{ + this->fwin = fwin; +} + +int PluginFClientSlider::handle_event() +{ + if( fwin->selected ) { + fwin->selected->set_float(get_value()); + fwin->update_selected(); + return fwin->update(); } return 1; } @@ -285,9 +358,33 @@ void PluginFClientWindow::update(PluginFClient_Opt *opt) if( opt ) opt->get(val, sizeof(val)); text->update(val); + float v = 0, fmn = 0, fmx = 0; + if( opt && !opt->get_range(fmn, fmx) ) v = atof(val); + float p = (fmx-fmn) / slider->get_w(); + slider->set_precision(p); + slider->update(slider->get_w(), v, fmn, fmx); + pot->set_precision(p); + pot->update(v, fmn, fmx); panel->update(); } +int PluginFClientWindow::update() +{ + const char *txt = text->get_text(); + if( txt && selected ) { + selected->set(txt); + selected->item_value->update(); + draw(); + ffmpeg->plugin->send_configure_change(); + } + return 1; +} + +void PluginFClientWindow::update_selected() +{ + update(selected); +} + int PluginFClient_OptPanel::selection_changed() { PluginFClient_Opt *opt = 0; @@ -472,6 +569,10 @@ void PluginFClientWindow::create_objects() add_subwindow(apply = new PluginFClientApply(this, x1, y)); add_subwindow(text = new PluginFClientText(this, x0, y, x1-x0 - 8)); y += title->get_h() + 10; + add_subwindow(pot = new PluginFClientPot(this, x, y)); + x1 = x + pot->get_w() + 10; + add_subwindow(slider = new PluginFClientSlider(this, x1, y+10)); + y += pot->get_h() + 10; panel_x = x; panel_y = y; panel_w = get_w()-10 - panel_x; @@ -500,12 +601,17 @@ int PluginFClientWindow::resize_event(int w, int h) int x0 = units->get_x() + units->get_w() + 8; int y0 = units->get_y(); text->reposition_window(x0,y0, x1-x0-8); + x1 = pot->get_x() + pot->get_w() + 10; + int w1 = w - slider->get_x() - 20; + slider->set_pointer_motion_range(w1); + slider->reposition_window(x1, slider->get_y(), w1, slider->get_h()); panel_w = get_w()-10 - panel_x; panel_h = get_h()-10 - panel_y; panel->reposition_window(panel_x,panel_y, panel_w, panel_h); return 1; } + PluginFClient::PluginFClient(PluginClient *plugin, const char *name) { this->plugin = plugin; @@ -525,7 +631,7 @@ PluginFClient::~PluginFClient() delete ffilt; } -bool PluginFClient::is_audio(AVFilter *fp) +bool PluginFClient::is_audio(const AVFilter *fp) { if( !fp->outputs ) return 0; if( avfilter_pad_count(fp->outputs) > 1 ) return 0; @@ -537,7 +643,7 @@ bool PluginFClient::is_audio(AVFilter *fp) if( avfilter_pad_get_type(fp->inputs, 0) != AVMEDIA_TYPE_AUDIO ) return 0; return 1; } -bool PluginFClient::is_video(AVFilter *fp) +bool PluginFClient::is_video(const AVFilter *fp) { if( !fp->outputs ) return 0; if( avfilter_pad_count(fp->outputs) > 1 ) return 0; @@ -616,6 +722,13 @@ void PluginFClient::save_data(KeyFrame *keyframe) av_freep(&buf); } } + if( (config.ffilt->filter->flags & AVFILTER_FLAG_SLICE_THREADS) != 0 ) { + uint8_t *buf = 0; + if( av_opt_get(config.ffilt->fctx, "threads", 0, &buf) >= 0 && buf ) { + output.tag.set_property("threads", (const char *)buf); + av_freep(&buf); + } + } output.append_tag(); output.terminate_string(); @@ -624,7 +737,7 @@ void PluginFClient::save_data(KeyFrame *keyframe) void PluginFClient::read_data(KeyFrame *keyframe) { FileXML input; - char string[BCTEXTLEN], value[BCTEXTLEN]; + char string[BCTEXTLEN]; input.set_shared_input(keyframe->get_data(), strlen(keyframe->get_data())); while( !input.read_tag() ) { @@ -635,9 +748,12 @@ void PluginFClient::read_data(KeyFrame *keyframe) void *obj = config.filter_config(); const AVOption *opt = NULL; while( (opt=av_opt_next(obj, opt)) != 0 ) { - to_upper(string, opt->name); - if( !input.tag.get_property(string, value) ) continue; - av_opt_set(obj, opt->name, value, 0); + const char *v = input.tag.get_property(opt->name); + if( v ) av_opt_set(obj, opt->name, v, 0); + } + if( (config.ffilt->filter->flags & AVFILTER_FLAG_SLICE_THREADS) != 0 ) { + const char *v = input.tag.get_property("threads"); + if( v ) av_opt_set(config.ffilt->fctx, "threads", v, 0); } } } @@ -788,14 +904,14 @@ int PluginFAClient::get_inchannels() { AVFilterContext *fctx = ffilt->fctx; AVFilterLink **links = !fctx->nb_inputs ? 0 : fctx->inputs; - return !links ? 0 : avfilter_link_get_channels(links[0]); + return !links ? 0 : links[0]->channels; } int PluginFAClient::get_outchannels() { AVFilterContext *fctx = ffilt->fctx; AVFilterLink **links = !fctx->nb_outputs ? 0 : fctx->outputs; - return !links ? 0 : avfilter_link_get_channels(links[0]); + return !links ? 0 : links[0]->channels; } int PluginFAClient::process_buffer(int64_t size, Samples **buffer, int64_t start_position, int sample_rate) @@ -819,6 +935,11 @@ int PluginFAClient::process_buffer(int64_t size, Samples **buffer, int64_t start if( ret >= 0 ) { in_channels = get_inchannels(); out_channels = get_outchannels(); + frame->nb_samples = size; + frame->format = AV_SAMPLE_FMT_FLTP; + frame->channel_layout = (1<sample_rate = sample_rate; + frame->pts = local_to_edl(filter_position); } int retry = 10; @@ -829,11 +950,6 @@ int PluginFAClient::process_buffer(int64_t size, Samples **buffer, int64_t start for( int i=0; inb_samples = size; - frame->format = AV_SAMPLE_FMT_FLTP; - frame->channel_layout = (1<sample_rate = sample_rate; - frame->pts = local_to_edl(filter_position); ret = av_frame_get_buffer(frame, 0); if( ret < 0 ) break; float **in_buffers = (float **)&frame->extended_data[0]; @@ -922,14 +1038,14 @@ int PluginFVClient::process_buffer(VFrame **frames, int64_t position, double fra ret = av_buffersink_get_frame(fsink, frame); if( ret >= 0 || ret != AVERROR(EAGAIN) ) break; if( !fsrc ) { ret = AVERROR(EIO); break; } - read_frame(vframe, 0, filter_position++, frame_rate, get_use_opengl()); + read_frame(vframe, 0, filter_position++, frame_rate, 0); frame->format = pix_fmt; frame->width = width; frame->height = height; frame->pts = local_to_edl(position); ret = av_frame_get_buffer(frame, 32); if( ret < 0 ) break; - ret = transfer_pixfmt(vframe, frame, pix_fmt, width, height); + ret = transfer_pixfmt(vframe, frame); if( ret < 0 ) break; ret = av_buffersrc_add_frame_flags(fsrc, frame, 0); } @@ -938,7 +1054,7 @@ int PluginFVClient::process_buffer(VFrame **frames, int64_t position, double fra if( ret >= 0 ) { pix_fmt = (AVPixelFormat) frame->format; - ret = transfer_cmodel(vframe, frame, pix_fmt, width, height); + ret = transfer_cmodel(vframe, frame); } if( ret < 0 ) { ff_err(ret, "PluginFVClient::process_buffer() %s\n", plugin_title()); @@ -985,23 +1101,35 @@ PluginFClient_Opt::~PluginFClient_Opt() delete item_value; } -char *PluginFClient_Opt::get(char *vp, int sz) +const char *PluginFClientConfig::get(const char *name) { - char *ret = 0; - void *obj = filter_config(); uint8_t *bp = 0; - if( av_opt_get(obj, opt->name, 0, &bp) >= 0 && bp != 0 ) { - const char *val = (const char *)bp; - ret = sz >= 0 ? strncpy(vp,val,sz) : strcpy(vp, val); - if( sz > 0 ) vp[sz-1] = 0; - av_freep(&bp); + if( av_opt_get(filter_config(), name, 0, &bp) >= 0 || + av_opt_get(ffilt->fctx, name, 0, &bp) >= 0 ) + return (const char *)bp; + return 0; +} +char *PluginFClient_Opt::get(char *vp, int sz) +{ + const char *val = conf->get(opt->name); + if( val ) { + strncpy(vp, val, sz); + vp[sz-1] = 0; } - return ret; + else + vp = 0; + av_freep(&val); + return vp; +} + +void PluginFClientConfig::set(const char *name, const char *val) +{ + if( av_opt_set(filter_config(), name, val, 0) < 0 ) + av_opt_set(ffilt->fctx, name, val, 0); } void PluginFClient_Opt::set(const char *val) { - void *obj = filter_config(); - av_opt_set(obj , opt->name, val, 0); + conf->set(opt->name, val); } void PluginFFilter::uninit() @@ -1016,13 +1144,14 @@ static int get_defaults(const char *name, char *args) FILE *fp = fopen(defaults_path,"r"); if( !fp ) return 0; char ff_plugin[BCSTRLEN], ff_args[BCTEXTLEN], *ap = 0; - while( !ap && fgets(ff_args, sizeof(ff_args), fp) ) { - if( *(ap=ff_args) == ';' ) continue; - if( *(ap=ff_args) == '#' ) ++ap; + while( fgets(ff_args, sizeof(ff_args), fp) ) { + char *cp = ff_args; + if( *cp == ';' ) continue; + if( *cp == '#' ) ++cp; char *bp = ff_plugin, *ep = bp + sizeof(ff_plugin)-1; - while( bp < ep && *ap && *ap != '\n' && *ap != ' ' ) *bp++ = *ap++; + while( bp < ep && *cp && *cp != '\n' && *cp != ' ' ) *bp++ = *cp++; *bp = 0; - if( strcmp(ff_plugin, name) ) ap = 0; + if( !strcmp(ff_plugin, name) ) { ap = cp; break; } } fclose(fp); if( !ap ) return 0; @@ -1059,17 +1188,33 @@ int PluginFFilter::init(const char *name, PluginFClientConfig *conf) static int inst = 0; char inst_name[BCSTRLEN]; sprintf(inst_name,"%s_%d", name, ++inst); - graph->thread_type = 0; - graph->nb_threads = 1; + if( conf && (filter->flags & AVFILTER_FLAG_SLICE_THREADS) != 0 ) { + graph->thread_type = AVFILTER_THREAD_SLICE; + graph->nb_threads = atoi(conf->get("threads")); + } + else { + graph->thread_type = 0; + graph->nb_threads = 0; + } fctx = avfilter_graph_alloc_filter(graph, filter, inst_name); if( !fctx ) return AVERROR(ENOMEM); + fctx->thread_type = graph->thread_type; // bug in avfilter if( conf ) { AVDictionary *opts = 0; for( int i=0; isize(); ++i ) { PluginFClient_Opt *op = conf->get(i); const char *name = op->opt->name; char val[BCTEXTLEN], *vp = op->get(val, sizeof(val)); - if( vp ) av_dict_set(&opts, name, vp, 0); + if( !vp ) continue; + uint8_t *bp = 0; +// unspecified opts cause a special behavior in some filters (lut3d) +// so... if opt value is the default, skip it or no special behavior + if( av_opt_get(filter_config(), name, 0, &bp) >= 0 ) { + int result = strcmp((const char *)bp, vp); + av_freep(&bp); + if( !result ) continue; + } + av_dict_set(&opts, name, vp, 0); } ret = avfilter_init_dict(fctx, &opts); av_dict_free(&opts); @@ -1105,7 +1250,7 @@ PluginFFilter *PluginFFilter::new_ffilter(const char *name, PluginFClientConfig PluginClient *PluginServer::new_ffmpeg_plugin() { - AVFilter *filter = avfilter_get_by_name(ff_name); + const AVFilter *filter = avfilter_get_by_name(ff_name); if( !filter ) return 0; PluginFClient *ffmpeg = PluginFClient::is_audio(filter) ? @@ -1123,14 +1268,15 @@ PluginServer* MWindow::new_ffmpeg_server(MWindow *mwindow, const char *name) PluginFFilter *ffilt = PluginFFilter::new_ffilter(name); if( !ffilt ) return 0; delete ffilt; - return new PluginServer(mwindow, (char*)name, PLUGIN_TYPE_FFMPEG); + return new PluginServer(mwindow, name, PLUGIN_TYPE_FFMPEG); } void MWindow::init_ffmpeg_index(MWindow *mwindow, Preferences *preferences, FILE *fp) { PluginFLogLevel errs(AV_LOG_ERROR); - const AVFilter *filter = 0; - while( (filter=avfilter_next(filter)) != 0 ) { + const AVFilter *filter = 0; void *idx = 0; + while( (filter=av_filter_iterate(&idx)) != 0 ) { +//printf("%s\n",filter->name); PluginServer *server = new_ffmpeg_server(mwindow, filter->name); if( server ) { int result = server->open_plugin(1, preferences, 0, 0); @@ -1146,7 +1292,5 @@ void MWindow::init_ffmpeg_index(MWindow *mwindow, Preferences *preferences, FILE void MWindow::init_ffmpeg() { - av_register_all(); - avfilter_register_all(); }