Mostly based on libavcodec's
Showing the changes to libavfilter/avfiltergraph.c (1 of 11 files). Show all
Unified · Split
| @@ -20,6 +20,8 @@ · 19 unmodified lines | ||
| 20 | 20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 21 | 21 | */ |
| 22 | 22 | |
| 23 | +#include "config.h" | |
| 24 | + | |
| 23 | 25 | #include <string.h> |
| 24 | 26 | |
| 25 | 27 | #include "libavutil/avassert.h" |
| @@ -27,22 +29,59 @@ · 1 unmodified line | ||
| 27 | 29 | #include "libavutil/channel_layout.h" |
| 28 | 30 | #include "libavutil/common.h" |
| 29 | 31 | #include "libavutil/log.h" |
| 32 | +#include "libavutil/opt.h" | |
| 33 | + | |
| 30 | 34 | #include "avfilter.h" |
| 31 | 35 | #include "formats.h" |
| 32 | 36 | #include "internal.h" |
| 37 | +#include "thread.h" | |
| 38 | + | |
| 39 | +#define OFFSET(x) offsetof(AVFilterGraph, x) | |
| 40 | +#define FLAGS AV_OPT_FLAG_VIDEO_PARAM | |
| 41 | +static const AVOption filtergraph_options[] = { | |
| 42 | + { "thread_type", "Allowed thread types", OFFSET(thread_type), AV_OPT_TYPE_FLAGS, | |
| 43 | + { .i64 = AVFILTER_THREAD_SLICE }, 0, INT_MAX, FLAGS, "thread_type" }, | |
| 44 | + { "slice", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AVFILTER_THREAD_SLICE }, .flags = FLAGS, .unit = "thread_type" }, | |
| 45 | + { "threads", "Maximum number of threads", OFFSET(nb_threads), | |
| 46 | + AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FLAGS }, | |
| 47 | + { NULL }, | |
| 48 | +}; | |
| 33 | 49 | |
| 34 | 50 | static const AVClass filtergraph_class = { |
| 35 | 51 | .class_name = "AVFilterGraph", |
| 36 | 52 | .item_name = av_default_item_name, |
| 37 | 53 | .version = LIBAVUTIL_VERSION_INT, |
| 54 | + .option = filtergraph_options, | |
| 38 | 55 | }; |
| 39 | 56 | |
| 57 | +#if !HAVE_THREADS | |
| 58 | +void ff_graph_thread_free(AVFilterGraph *graph) | |
| 59 | +{ | |
| 60 | +} | |
| 61 | + | |
| 62 | +int ff_graph_thread_init(AVFilterGraph *graph) | |
| 63 | +{ | |
| 64 | + graph->thread_type = 0; | |
| 65 | + graph->nb_threads = 1; | |
| 66 | + return 0; | |
| 67 | +} | |
| 68 | +#endif | |
| 69 | + | |
| 40 | 70 | AVFilterGraph *avfilter_graph_alloc(void) |
| 41 | 71 | { |
| 42 | 72 | AVFilterGraph *ret = av_mallocz(sizeof(*ret)); |
| 43 | 73 | if (!ret) |
| 44 | 74 | return NULL; |
| 75 | + | |
| 76 | + ret->internal = av_mallocz(sizeof(*ret->internal)); | |
| 77 | + if (!ret->internal) { | |
| 78 | + av_freep(&ret); | |
| 79 | + return NULL; | |
| 80 | + } | |
| 81 | + | |
| 45 | 82 | ret->av_class = &filtergraph_class; |
| 83 | + av_opt_set_defaults(ret); | |
| 84 | + | |
| 46 | 85 | return ret; |
| 47 | 86 | } |
| 48 | 87 | |
| @@ -67,9 +106,12 @@ void avfilter_graph_free(AVFilterGraph **graph) · 18 unmodified lines | ||
| 67 | 106 | while ((*graph)->nb_filters) |
| 68 | 107 | avfilter_free((*graph)->filters[0]); |
| 69 | 108 | |
| 109 | + ff_graph_thread_free(*graph); | |
| 110 | + | |
| 70 | 111 | av_freep(&(*graph)->scale_sws_opts); |
| 71 | 112 | av_freep(&(*graph)->resample_lavr_opts); |
| 72 | 113 | av_freep(&(*graph)->filters); |
| 114 | + av_freep(&(*graph)->internal); | |
| 73 | 115 | av_freep(graph); |
| 74 | 116 | } |
| 75 | 117 | |
| @@ -123,6 +165,14 @@ AVFilterContext *avfilter_graph_alloc_filter(AVFilterGraph *graph, · 47 unmodified lines | ||
| 123 | 165 | { |
| 124 | 166 | AVFilterContext **filters, *s; |
| 125 | 167 | |
| 168 | + if (graph->thread_type && !graph->internal->thread) { | |
| 169 | + int ret = ff_graph_thread_init(graph); | |
| 170 | + if (ret < 0) { | |
| 171 | + av_log(graph, AV_LOG_ERROR, "Error initializing threading.\n"); | |
| 172 | + return NULL; | |
| 173 | + } | |
| 174 | + } | |
| 175 | + | |
| 126 | 176 | s = ff_filter_alloc(filter, name); |
| 127 | 177 | if (!s) |
| 128 | 178 | return NULL; |