... | ... |
@@ -662,6 +662,7 @@ afade=t=out:ss=875:d=25 |
662 | 662 |
@end example |
663 | 663 |
@end itemize |
664 | 664 |
|
665 |
+@anchor{aformat} |
|
665 | 666 |
@section aformat |
666 | 667 |
|
667 | 668 |
Set output format constraints for the input audio. The framework will |
... | ... |
@@ -3028,6 +3029,7 @@ framework. |
3028 | 3028 |
|
3029 | 3029 |
The filter does not take parameters. |
3030 | 3030 |
|
3031 |
+@anchor{format} |
|
3031 | 3032 |
@section format |
3032 | 3033 |
|
3033 | 3034 |
Convert the input video to one of the specified pixel formats. |
... | ... |
@@ -6085,6 +6087,43 @@ tools. |
6085 | 6085 |
|
6086 | 6086 |
Below is a description of the currently available multimedia filters. |
6087 | 6087 |
|
6088 |
+@section aperms, perms |
|
6089 |
+ |
|
6090 |
+Set read/write permissions for the output frames. |
|
6091 |
+ |
|
6092 |
+These filters are mainly aimed at developers to test direct path in the |
|
6093 |
+following filter in the filtergraph. |
|
6094 |
+ |
|
6095 |
+The filters accept parameters as a list of @var{key}=@var{value} pairs, |
|
6096 |
+separated by ":". If the key of the first options is omitted, the argument is |
|
6097 |
+assumed to be the @var{mode}. |
|
6098 |
+ |
|
6099 |
+A description of the accepted parameters follows. |
|
6100 |
+ |
|
6101 |
+@table @option |
|
6102 |
+@item mode |
|
6103 |
+Select the permissions mode. |
|
6104 |
+ |
|
6105 |
+It accepts the following values: |
|
6106 |
+@table @samp |
|
6107 |
+@item none |
|
6108 |
+Do nothing. This is the default. |
|
6109 |
+@item ro |
|
6110 |
+Set all the output frames read-only. |
|
6111 |
+@item rw |
|
6112 |
+Set all the output frames directly writable. |
|
6113 |
+@item toggle |
|
6114 |
+Make the frame read-only if writable, and writable if read-only. |
|
6115 |
+@item random |
|
6116 |
+Set each output frame read-only or writable randomly. |
|
6117 |
+@end table |
|
6118 |
+@end table |
|
6119 |
+ |
|
6120 |
+Note: in case of auto-inserted filter between the permission filter and the |
|
6121 |
+following one, the permission might not be received as expected in that |
|
6122 |
+following filter. Inserting a @ref{format} or @ref{aformat} filter before the |
|
6123 |
+perms/aperms filter can avoid this problem. |
|
6124 |
+ |
|
6088 | 6125 |
@section aselect, select |
6089 | 6126 |
Select frames to pass in output. |
6090 | 6127 |
|
... | ... |
@@ -56,6 +56,7 @@ OBJS-$(CONFIG_AMERGE_FILTER) += af_amerge.o |
56 | 56 |
OBJS-$(CONFIG_AMIX_FILTER) += af_amix.o |
57 | 57 |
OBJS-$(CONFIG_ANULL_FILTER) += af_anull.o |
58 | 58 |
OBJS-$(CONFIG_APAD_FILTER) += af_apad.o |
59 |
+OBJS-$(CONFIG_APERMS_FILTER) += f_perms.o |
|
59 | 60 |
OBJS-$(CONFIG_ARESAMPLE_FILTER) += af_aresample.o |
60 | 61 |
OBJS-$(CONFIG_ASELECT_FILTER) += f_select.o |
61 | 62 |
OBJS-$(CONFIG_ASENDCMD_FILTER) += f_sendcmd.o |
... | ... |
@@ -139,6 +140,7 @@ OBJS-$(CONFIG_NULL_FILTER) += vf_null.o |
139 | 139 |
OBJS-$(CONFIG_OCV_FILTER) += vf_libopencv.o |
140 | 140 |
OBJS-$(CONFIG_OVERLAY_FILTER) += vf_overlay.o |
141 | 141 |
OBJS-$(CONFIG_PAD_FILTER) += vf_pad.o |
142 |
+OBJS-$(CONFIG_PERMS_FILTER) += f_perms.o |
|
142 | 143 |
OBJS-$(CONFIG_PIXDESCTEST_FILTER) += vf_pixdesctest.o |
143 | 144 |
OBJS-$(CONFIG_PP_FILTER) += vf_pp.o |
144 | 145 |
OBJS-$(CONFIG_REMOVELOGO_FILTER) += bbox.o lswsutils.o lavfutils.o vf_removelogo.o |
... | ... |
@@ -52,6 +52,7 @@ void avfilter_register_all(void) |
52 | 52 |
REGISTER_FILTER(AMIX, amix, af); |
53 | 53 |
REGISTER_FILTER(ANULL, anull, af); |
54 | 54 |
REGISTER_FILTER(APAD, apad, af); |
55 |
+ REGISTER_FILTER(APERMS, aperms, af); |
|
55 | 56 |
REGISTER_FILTER(ARESAMPLE, aresample, af); |
56 | 57 |
REGISTER_FILTER(ASELECT, aselect, af); |
57 | 58 |
REGISTER_FILTER(ASENDCMD, asendcmd, af); |
... | ... |
@@ -135,6 +136,7 @@ void avfilter_register_all(void) |
135 | 135 |
REGISTER_FILTER(OCV, ocv, vf); |
136 | 136 |
REGISTER_FILTER(OVERLAY, overlay, vf); |
137 | 137 |
REGISTER_FILTER(PAD, pad, vf); |
138 |
+ REGISTER_FILTER(PERMS, perms, vf); |
|
138 | 139 |
REGISTER_FILTER(PIXDESCTEST, pixdesctest, vf); |
139 | 140 |
REGISTER_FILTER(PP, pp, vf); |
140 | 141 |
REGISTER_FILTER(REMOVELOGO, removelogo, vf); |
141 | 142 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,187 @@ |
0 |
+/* |
|
1 |
+ * This file is part of FFmpeg. |
|
2 |
+ * |
|
3 |
+ * FFmpeg is free software; you can redistribute it and/or |
|
4 |
+ * modify it under the terms of the GNU Lesser General Public |
|
5 |
+ * License as published by the Free Software Foundation; either |
|
6 |
+ * version 2.1 of the License, or (at your option) any later version. |
|
7 |
+ * |
|
8 |
+ * FFmpeg is distributed in the hope that it will be useful, |
|
9 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
10 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
11 |
+ * Lesser General Public License for more details. |
|
12 |
+ * |
|
13 |
+ * You should have received a copy of the GNU Lesser General Public |
|
14 |
+ * License along with FFmpeg; if not, write to the Free Software |
|
15 |
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
|
16 |
+ */ |
|
17 |
+ |
|
18 |
+#include "libavutil/lfg.h" |
|
19 |
+#include "libavutil/opt.h" |
|
20 |
+#include "libavutil/random_seed.h" |
|
21 |
+#include "audio.h" |
|
22 |
+#include "video.h" |
|
23 |
+ |
|
24 |
+enum mode { |
|
25 |
+ MODE_NONE, |
|
26 |
+ MODE_RO, |
|
27 |
+ MODE_RW, |
|
28 |
+ MODE_TOGGLE, |
|
29 |
+ MODE_RANDOM, |
|
30 |
+ NB_MODES |
|
31 |
+}; |
|
32 |
+ |
|
33 |
+typedef struct { |
|
34 |
+ const AVClass *class; |
|
35 |
+ AVLFG lfg; |
|
36 |
+ enum mode mode; |
|
37 |
+} PermsContext; |
|
38 |
+ |
|
39 |
+#define OFFSET(x) offsetof(PermsContext, x) |
|
40 |
+#define FLAGS AV_OPT_FLAG_FILTERING_PARAM |
|
41 |
+ |
|
42 |
+static const AVOption options[] = { |
|
43 |
+ { "mode", "select permissions mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64 = MODE_NONE}, MODE_NONE, NB_MODES-1, FLAGS, "mode" }, |
|
44 |
+ { "none", "do nothing", 0, AV_OPT_TYPE_CONST, {.i64 = MODE_NONE}, INT_MIN, INT_MAX, FLAGS, "mode" }, |
|
45 |
+ { "ro", "set all output frames read-only", 0, AV_OPT_TYPE_CONST, {.i64 = MODE_RO}, INT_MIN, INT_MAX, FLAGS, "mode" }, |
|
46 |
+ { "rw", "set all output frames writable", 0, AV_OPT_TYPE_CONST, {.i64 = MODE_RW}, INT_MIN, INT_MAX, FLAGS, "mode" }, |
|
47 |
+ { "toggle", "switch permissions", 0, AV_OPT_TYPE_CONST, {.i64 = MODE_TOGGLE}, INT_MIN, INT_MAX, FLAGS, "mode" }, |
|
48 |
+ { "random", "set permissions randomly", 0, AV_OPT_TYPE_CONST, {.i64 = MODE_RANDOM}, INT_MIN, INT_MAX, FLAGS, "mode" }, |
|
49 |
+ { NULL } |
|
50 |
+}; |
|
51 |
+ |
|
52 |
+static av_cold int init(AVFilterContext *ctx, const char *args, const AVClass *class) |
|
53 |
+{ |
|
54 |
+ int ret; |
|
55 |
+ PermsContext *perms = ctx->priv; |
|
56 |
+ static const char *shorthand[] = { "mode", NULL }; |
|
57 |
+ |
|
58 |
+ perms->class = class; |
|
59 |
+ av_opt_set_defaults(perms); |
|
60 |
+ |
|
61 |
+ if ((ret = av_opt_set_from_string(perms, args, shorthand, "=", ":")) < 0) |
|
62 |
+ return ret; |
|
63 |
+ |
|
64 |
+ // TODO: add a seed option |
|
65 |
+ if (perms->mode == MODE_RANDOM) |
|
66 |
+ av_lfg_init(&perms->lfg, av_get_random_seed()); |
|
67 |
+ |
|
68 |
+ av_opt_free(perms); |
|
69 |
+ return 0; |
|
70 |
+} |
|
71 |
+ |
|
72 |
+enum perm { RO, RW }; |
|
73 |
+static const char *perm_str[2] = { "RO", "RW" }; |
|
74 |
+ |
|
75 |
+static int filter_frame(AVFilterLink *inlink, AVFrame *frame) |
|
76 |
+{ |
|
77 |
+ int ret; |
|
78 |
+ AVFilterContext *ctx = inlink->dst; |
|
79 |
+ PermsContext *perms = ctx->priv; |
|
80 |
+ AVFrame *out = frame; |
|
81 |
+ enum perm in_perm = av_frame_is_writable(frame) ? RW : RO; |
|
82 |
+ enum perm out_perm; |
|
83 |
+ |
|
84 |
+ switch (perms->mode) { |
|
85 |
+ case MODE_TOGGLE: out_perm = in_perm == RO ? RW : RO; break; |
|
86 |
+ case MODE_RANDOM: out_perm = av_lfg_get(&perms->lfg) & 1 ? RW : RO; break; |
|
87 |
+ case MODE_RO: out_perm = RO; break; |
|
88 |
+ case MODE_RW: out_perm = RW; break; |
|
89 |
+ default: out_perm = in_perm; break; |
|
90 |
+ } |
|
91 |
+ |
|
92 |
+ av_log(ctx, AV_LOG_VERBOSE, "%s -> %s%s\n", |
|
93 |
+ perm_str[in_perm], perm_str[out_perm], |
|
94 |
+ in_perm == out_perm ? " (no-op)" : ""); |
|
95 |
+ |
|
96 |
+ if (in_perm == RO && out_perm == RW) { |
|
97 |
+ if ((ret = av_frame_make_writable(frame)) < 0) |
|
98 |
+ return ret; |
|
99 |
+ } else if (in_perm == RW && out_perm == RO) { |
|
100 |
+ out = av_frame_clone(frame); |
|
101 |
+ if (!out) |
|
102 |
+ return AVERROR(ENOMEM); |
|
103 |
+ } |
|
104 |
+ |
|
105 |
+ ret = ff_filter_frame(ctx->outputs[0], out); |
|
106 |
+ |
|
107 |
+ if (in_perm == RW && out_perm == RO) |
|
108 |
+ av_frame_free(&frame); |
|
109 |
+ return ret; |
|
110 |
+} |
|
111 |
+ |
|
112 |
+#if CONFIG_APERMS_FILTER |
|
113 |
+ |
|
114 |
+#define aperms_options options |
|
115 |
+AVFILTER_DEFINE_CLASS(aperms); |
|
116 |
+ |
|
117 |
+static av_cold int aperms_init(AVFilterContext *ctx, const char *args) |
|
118 |
+{ |
|
119 |
+ return init(ctx, args, &aperms_class); |
|
120 |
+} |
|
121 |
+ |
|
122 |
+static const AVFilterPad aperms_inputs[] = { |
|
123 |
+ { |
|
124 |
+ .name = "default", |
|
125 |
+ .type = AVMEDIA_TYPE_AUDIO, |
|
126 |
+ .filter_frame = filter_frame, |
|
127 |
+ }, |
|
128 |
+ { NULL } |
|
129 |
+}; |
|
130 |
+ |
|
131 |
+static const AVFilterPad aperms_outputs[] = { |
|
132 |
+ { |
|
133 |
+ .name = "default", |
|
134 |
+ .type = AVMEDIA_TYPE_AUDIO, |
|
135 |
+ }, |
|
136 |
+ { NULL } |
|
137 |
+}; |
|
138 |
+ |
|
139 |
+AVFilter avfilter_af_aperms = { |
|
140 |
+ .name = "aperms", |
|
141 |
+ .description = NULL_IF_CONFIG_SMALL("Set permissions for the output audio frame."), |
|
142 |
+ .init = aperms_init, |
|
143 |
+ .priv_size = sizeof(PermsContext), |
|
144 |
+ .inputs = aperms_inputs, |
|
145 |
+ .outputs = aperms_outputs, |
|
146 |
+ .priv_class = &aperms_class, |
|
147 |
+}; |
|
148 |
+#endif /* CONFIG_APERMS_FILTER */ |
|
149 |
+ |
|
150 |
+#if CONFIG_PERMS_FILTER |
|
151 |
+ |
|
152 |
+#define perms_options options |
|
153 |
+AVFILTER_DEFINE_CLASS(perms); |
|
154 |
+ |
|
155 |
+static av_cold int perms_init(AVFilterContext *ctx, const char *args) |
|
156 |
+{ |
|
157 |
+ return init(ctx, args, &perms_class); |
|
158 |
+} |
|
159 |
+ |
|
160 |
+static const AVFilterPad perms_inputs[] = { |
|
161 |
+ { |
|
162 |
+ .name = "default", |
|
163 |
+ .type = AVMEDIA_TYPE_VIDEO, |
|
164 |
+ .filter_frame = filter_frame, |
|
165 |
+ }, |
|
166 |
+ { NULL } |
|
167 |
+}; |
|
168 |
+ |
|
169 |
+static const AVFilterPad perms_outputs[] = { |
|
170 |
+ { |
|
171 |
+ .name = "default", |
|
172 |
+ .type = AVMEDIA_TYPE_VIDEO, |
|
173 |
+ }, |
|
174 |
+ { NULL } |
|
175 |
+}; |
|
176 |
+ |
|
177 |
+AVFilter avfilter_vf_perms = { |
|
178 |
+ .name = "perms", |
|
179 |
+ .description = NULL_IF_CONFIG_SMALL("Set permissions for the output video frame."), |
|
180 |
+ .init = perms_init, |
|
181 |
+ .priv_size = sizeof(PermsContext), |
|
182 |
+ .inputs = perms_inputs, |
|
183 |
+ .outputs = perms_outputs, |
|
184 |
+ .priv_class = &perms_class, |
|
185 |
+}; |
|
186 |
+#endif /* CONFIG_PERMS_FILTER */ |
... | ... |
@@ -29,8 +29,8 @@ |
29 | 29 |
#include "libavutil/avutil.h" |
30 | 30 |
|
31 | 31 |
#define LIBAVFILTER_VERSION_MAJOR 3 |
32 |
-#define LIBAVFILTER_VERSION_MINOR 45 |
|
33 |
-#define LIBAVFILTER_VERSION_MICRO 104 |
|
32 |
+#define LIBAVFILTER_VERSION_MINOR 46 |
|
33 |
+#define LIBAVFILTER_VERSION_MICRO 100 |
|
34 | 34 |
|
35 | 35 |
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ |
36 | 36 |
LIBAVFILTER_VERSION_MINOR, \ |