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.tags/n1.0
| @@ -159,6 +159,7 @@ static int default_filter_samples(AVFilterLink *link, | |||||
| int ff_filter_samples_framed(AVFilterLink *link, AVFilterBufferRef *samplesref) | int ff_filter_samples_framed(AVFilterLink *link, AVFilterBufferRef *samplesref) | ||||
| { | { | ||||
| int (*filter_samples)(AVFilterLink *, AVFilterBufferRef *); | int (*filter_samples)(AVFilterLink *, AVFilterBufferRef *); | ||||
| AVFilterPad *src = link->srcpad; | |||||
| AVFilterPad *dst = link->dstpad; | AVFilterPad *dst = link->dstpad; | ||||
| int64_t pts; | int64_t pts; | ||||
| AVFilterBufferRef *buf_out; | AVFilterBufferRef *buf_out; | ||||
| @@ -169,6 +170,9 @@ int ff_filter_samples_framed(AVFilterLink *link, AVFilterBufferRef *samplesref) | |||||
| if (!(filter_samples = dst->filter_samples)) | if (!(filter_samples = dst->filter_samples)) | ||||
| filter_samples = default_filter_samples; | filter_samples = default_filter_samples; | ||||
| av_assert1((samplesref->perms & src->min_perms) == src->min_perms); | |||||
| samplesref->perms &= ~ src->rej_perms; | |||||
| /* prepare to copy the samples if the buffer has insufficient permissions */ | /* prepare to copy the samples if the buffer has insufficient permissions */ | ||||
| if ((dst->min_perms & samplesref->perms) != dst->min_perms || | if ((dst->min_perms & samplesref->perms) != dst->min_perms || | ||||
| dst->rej_perms & samplesref->perms) { | dst->rej_perms & samplesref->perms) { | ||||
| @@ -240,22 +240,29 @@ struct AVFilterPad { | |||||
| enum AVMediaType type; | enum AVMediaType type; | ||||
| /** | /** | ||||
| * Input pads: | |||||
| * Minimum required permissions on incoming buffers. Any buffer with | * Minimum required permissions on incoming buffers. Any buffer with | ||||
| * insufficient permissions will be automatically copied by the filter | * insufficient permissions will be automatically copied by the filter | ||||
| * system to a new buffer which provides the needed access permissions. | * system to a new buffer which provides the needed access permissions. | ||||
| * | * | ||||
| * Input pads only. | |||||
| * Output pads: | |||||
| * Guaranteed permissions on outgoing buffers. Any buffer pushed on the | |||||
| * link must have at least these permissions; this fact is checked by | |||||
| * asserts. It can be used to optimize buffer allocation. | |||||
| */ | */ | ||||
| int min_perms; | int min_perms; | ||||
| /** | /** | ||||
| * Input pads: | |||||
| * Permissions which are not accepted on incoming buffers. Any buffer | * Permissions which are not accepted on incoming buffers. Any buffer | ||||
| * which has any of these permissions set will be automatically copied | * which has any of these permissions set will be automatically copied | ||||
| * by the filter system to a new buffer which does not have those | * by the filter system to a new buffer which does not have those | ||||
| * permissions. This can be used to easily disallow buffers with | * permissions. This can be used to easily disallow buffers with | ||||
| * AV_PERM_REUSE. | * AV_PERM_REUSE. | ||||
| * | * | ||||
| * Input pads only. | |||||
| * Output pads: | |||||
| * Permissions which are automatically removed on outgoing buffers. It | |||||
| * can be used to optimize buffer allocation. | |||||
| */ | */ | ||||
| int rej_perms; | int rej_perms; | ||||
| @@ -232,8 +232,9 @@ static void clear_link(AVFilterLink *link) | |||||
| int ff_start_frame(AVFilterLink *link, AVFilterBufferRef *picref) | int ff_start_frame(AVFilterLink *link, AVFilterBufferRef *picref) | ||||
| { | { | ||||
| int (*start_frame)(AVFilterLink *, AVFilterBufferRef *); | int (*start_frame)(AVFilterLink *, AVFilterBufferRef *); | ||||
| AVFilterPad *src = link->srcpad; | |||||
| AVFilterPad *dst = link->dstpad; | AVFilterPad *dst = link->dstpad; | ||||
| int ret, perms = picref->perms; | |||||
| int ret, perms; | |||||
| AVFilterCommand *cmd= link->dst->command_queue; | AVFilterCommand *cmd= link->dst->command_queue; | ||||
| int64_t pts; | int64_t pts; | ||||
| @@ -242,6 +243,10 @@ int ff_start_frame(AVFilterLink *link, AVFilterBufferRef *picref) | |||||
| if (!(start_frame = dst->start_frame)) | if (!(start_frame = dst->start_frame)) | ||||
| start_frame = default_start_frame; | start_frame = default_start_frame; | ||||
| av_assert1((picref->perms & src->min_perms) == src->min_perms); | |||||
| picref->perms &= ~ src->rej_perms; | |||||
| perms = picref->perms; | |||||
| if (picref->linesize[0] < 0) | if (picref->linesize[0] < 0) | ||||
| perms |= AV_PERM_NEG_LINESIZES; | perms |= AV_PERM_NEG_LINESIZES; | ||||
| /* prepare to copy the picture if it has insufficient permissions */ | /* prepare to copy the picture if it has insufficient permissions */ | ||||