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 | int ff_filter_samples_framed(AVFilterLink *link, AVFilterBufferRef *samplesref) | 159 | int ff_filter_samples_framed(AVFilterLink *link, AVFilterBufferRef *samplesref) |
| 160 | { | 160 | { |
| 161 | int (*filter_samples)(AVFilterLink *, AVFilterBufferRef *); | 161 | int (*filter_samples)(AVFilterLink *, AVFilterBufferRef *); |
| 162 | AVFilterPad *src = link->srcpad; | ||
| 162 | AVFilterPad *dst = link->dstpad; | 163 | AVFilterPad *dst = link->dstpad; |
| 163 | int64_t pts; | 164 | int64_t pts; |
| 164 | AVFilterBufferRef *buf_out; | 165 | AVFilterBufferRef *buf_out; |
| @@ -169,6 +170,9 @@ int ff_filter_samples_framed(AVFilterLink *link, AVFilterBufferRef *samplesref) · 4 unmodified lines | |||
| 169 | if (!(filter_samples = dst->filter_samples)) | 170 | if (!(filter_samples = dst->filter_samples)) |
| 170 | filter_samples = default_filter_samples; | 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 | /* prepare to copy the samples if the buffer has insufficient permissions */ | 176 | /* prepare to copy the samples if the buffer has insufficient permissions */ |
| 173 | if ((dst->min_perms & samplesref->perms) != dst->min_perms || | 177 | if ((dst->min_perms & samplesref->perms) != dst->min_perms || |
| 174 | dst->rej_perms & samplesref->perms) { | 178 | dst->rej_perms & samplesref->perms) { |
| @@ -240,22 +240,29 @@ struct AVFilterPad { · 239 unmodified lines | |||
| 240 | enum AVMediaType type; | 240 | enum AVMediaType type; |
| 241 | 241 | ||
| 242 | /** | 242 | /** |
| 243 | * Input pads: | ||
| 243 | * Minimum required permissions on incoming buffers. Any buffer with | 244 | * Minimum required permissions on incoming buffers. Any buffer with |
| 244 | * insufficient permissions will be automatically copied by the filter | 245 | * insufficient permissions will be automatically copied by the filter |
| 245 | * system to a new buffer which provides the needed access permissions. | 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 | int min_perms; | 253 | int min_perms; |
| 250 | 254 | ||
| 251 | /** | 255 | /** |
| 256 | * Input pads: | ||
| 252 | * Permissions which are not accepted on incoming buffers. Any buffer | 257 | * Permissions which are not accepted on incoming buffers. Any buffer |
| 253 | * which has any of these permissions set will be automatically copied | 258 | * which has any of these permissions set will be automatically copied |
| 254 | * by the filter system to a new buffer which does not have those | 259 | * by the filter system to a new buffer which does not have those |
| 255 | * permissions. This can be used to easily disallow buffers with | 260 | * permissions. This can be used to easily disallow buffers with |
| 256 | * AV_PERM_REUSE. | 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 | int rej_perms; | 267 | int rej_perms; |
| 261 | 268 | ||
| @@ -232,8 +232,9 @@ static void clear_link(AVFilterLink *link) · 231 unmodified lines | |||
| 232 | int ff_start_frame(AVFilterLink *link, AVFilterBufferRef *picref) | 232 | int ff_start_frame(AVFilterLink *link, AVFilterBufferRef *picref) |
| 233 | { | 233 | { |
| 234 | int (*start_frame)(AVFilterLink *, AVFilterBufferRef *); | 234 | int (*start_frame)(AVFilterLink *, AVFilterBufferRef *); |
| 235 | AVFilterPad *src = link->srcpad; | ||
| 235 | AVFilterPad *dst = link->dstpad; | 236 | AVFilterPad *dst = link->dstpad; |
| 236 | int ret, perms = picref->perms; | 237 | int ret, perms; |
| 237 | AVFilterCommand *cmd= link->dst->command_queue; | 238 | AVFilterCommand *cmd= link->dst->command_queue; |
| 238 | int64_t pts; | 239 | int64_t pts; |
| 239 | 240 | ||
| @@ -242,6 +243,10 @@ int ff_start_frame(AVFilterLink *link, AVFilterBufferRef *picref) · 2 unmodified lines | |||
| 242 | if (!(start_frame = dst->start_frame)) | 243 | if (!(start_frame = dst->start_frame)) |
| 243 | start_frame = default_start_frame; | 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 | if (picref->linesize[0] < 0) | 250 | if (picref->linesize[0] < 0) |
| 246 | perms |= AV_PERM_NEG_LINESIZES; | 251 | perms |= AV_PERM_NEG_LINESIZES; |
| 247 | /* prepare to copy the picture if it has insufficient permissions */ | 252 | /* prepare to copy the picture if it has insufficient permissions */ |