Commit 271ddb11 authored by Nicolas George's avatar Nicolas George

lavfi: use min_perms and rej_perms for out pads.

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.
parent 67a804b9
...@@ -159,6 +159,7 @@ static int default_filter_samples(AVFilterLink *link, ...@@ -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) ...@@ -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 { ...@@ -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) ...@@ -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) ...@@ -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 */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment