There are several reasons for doing that: 1. It documents the code for the reader and helps find inconsistencies and bugs. 2. For rej_perms, it guarantees the change will be done even if the output reference can be created by several code paths. 3. It can be used to predict cases where a copy will, or will not happen and optimize buffer allocation (for example not request a rare direct-rendering buffer from a device sink if it will be copied anyway). Note that a filter is still allowed to manage the permissions on its own without using these fields.
Unified · Split
| @@ -159,6 +159,7 @@ static int default_filter_samples(AVFilterLink *link, · 158 unmodified lines | ||
| 159 | 159 | int ff_filter_samples_framed(AVFilterLink *link, AVFilterBufferRef *samplesref) |
| 160 | 160 | { |
| 161 | 161 | int (*filter_samples)(AVFilterLink *, AVFilterBufferRef *); |
| 162 | + AVFilterPad *src = link->srcpad; | |
| 162 | 163 | AVFilterPad *dst = link->dstpad; |
| 163 | 164 | int64_t pts; |
| 164 | 165 | AVFilterBufferRef *buf_out; |
| @@ -169,6 +170,9 @@ int ff_filter_samples_framed(AVFilterLink *link, AVFilterBufferRef *samplesref) · 4 unmodified lines | ||
| 169 | 170 | if (!(filter_samples = dst->filter_samples)) |
| 170 | 171 | filter_samples = default_filter_samples; |
| 171 | 172 | |
| 173 | + av_assert1((samplesref->perms & src->min_perms) == src->min_perms); | |
| 174 | + samplesref->perms &= ~ src->rej_perms; | |
| 175 | + | |
| 172 | 176 | /* prepare to copy the samples if the buffer has insufficient permissions */ |
| 173 | 177 | if ((dst->min_perms & samplesref->perms) != dst->min_perms || |
| 174 | 178 | dst->rej_perms & samplesref->perms) { |
| @@ -240,22 +240,29 @@ struct AVFilterPad { · 239 unmodified lines | ||
| 240 | 240 | enum AVMediaType type; |
| 241 | 241 | |
| 242 | 242 | /** |
| 243 | + * Input pads: | |
| 243 | 244 | * Minimum required permissions on incoming buffers. Any buffer with |
| 244 | 245 | * insufficient permissions will be automatically copied by the filter |
| 245 | 246 | * system to a new buffer which provides the needed access permissions. |
| 246 | 247 | * |
| 247 | − * Input pads only. | |
| 248 | + * Output pads: | |
| 249 | + * Guaranteed permissions on outgoing buffers. Any buffer pushed on the | |
| 250 | + * link must have at least these permissions; this fact is checked by | |
| 251 | + * asserts. It can be used to optimize buffer allocation. | |
| 248 | 252 | */ |
| 249 | 253 | int min_perms; |
| 250 | 254 | |
| 251 | 255 | /** |
| 256 | + * Input pads: | |
| 252 | 257 | * Permissions which are not accepted on incoming buffers. Any buffer |
| 253 | 258 | * which has any of these permissions set will be automatically copied |
| 254 | 259 | * by the filter system to a new buffer which does not have those |
| 255 | 260 | * permissions. This can be used to easily disallow buffers with |
| 256 | 261 | * AV_PERM_REUSE. |
| 257 | 262 | * |
| 258 | − * Input pads only. | |
| 263 | + * Output pads: | |
| 264 | + * Permissions which are automatically removed on outgoing buffers. It | |
| 265 | + * can be used to optimize buffer allocation. | |
| 259 | 266 | */ |
| 260 | 267 | int rej_perms; |
| 261 | 268 | |
| @@ -232,8 +232,9 @@ static void clear_link(AVFilterLink *link) · 231 unmodified lines | ||
| 232 | 232 | int ff_start_frame(AVFilterLink *link, AVFilterBufferRef *picref) |
| 233 | 233 | { |
| 234 | 234 | int (*start_frame)(AVFilterLink *, AVFilterBufferRef *); |
| 235 | + AVFilterPad *src = link->srcpad; | |
| 235 | 236 | AVFilterPad *dst = link->dstpad; |
| 236 | − int ret, perms = picref->perms; | |
| 237 | + int ret, perms; | |
| 237 | 238 | AVFilterCommand *cmd= link->dst->command_queue; |
| 238 | 239 | int64_t pts; |
| 239 | 240 | |
| @@ -242,6 +243,10 @@ int ff_start_frame(AVFilterLink *link, AVFilterBufferRef *picref) · 2 unmodified lines | ||
| 242 | 243 | if (!(start_frame = dst->start_frame)) |
| 243 | 244 | start_frame = default_start_frame; |
| 244 | 245 | |
| 246 | + av_assert1((picref->perms & src->min_perms) == src->min_perms); | |
| 247 | + picref->perms &= ~ src->rej_perms; | |
| 248 | + perms = picref->perms; | |
| 249 | + | |
| 245 | 250 | if (picref->linesize[0] < 0) |
| 246 | 251 | perms |= AV_PERM_NEG_LINESIZES; |
| 247 | 252 | /* prepare to copy the picture if it has insufficient permissions */ |