aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVitor Sessak <vitor1001@gmail.com>2008-02-15 21:38:06 +0000
committerVitor Sessak <vitor1001@gmail.com>2008-02-15 21:38:06 +0000
commita4af86c878102f4e85043552c053ce38c0717424 (patch)
tree5160b38077451208ef16887d8476095a8dd5c3c1
parentc949d867638b057ecd772a83ee83c89737a5a06f (diff)
downloadffmpeg-a4af86c878102f4e85043552c053ce38c0717424.tar.gz
Track the permissions that have been given out to each picture.
This should make it easier to know what can be done to a buffer once it's been passed to your filter without falling back to copying it "just to be safe". Commited in SoC by Bobby Bingham on 2007-08-17 18:21:07 Originally committed as revision 12009 to svn://svn.ffmpeg.org/ffmpeg/trunk
-rw-r--r--libavfilter/avfilter.c59
1 files changed, 54 insertions, 5 deletions
diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c
index f6695997cb..9d53f8d138 100644
--- a/libavfilter/avfilter.c
+++ b/libavfilter/avfilter.c
@@ -35,19 +35,67 @@ static AVFilter **filters = NULL;
#define link_dpad(link) link->dst-> input_pads[link->dstpad]
#define link_spad(link) link->src->output_pads[link->srcpad]
-AVFilterPicRef *avfilter_ref_pic(AVFilterPicRef *ref, int pmask)
+/**
+ * helper function to get a pointer to the structure telling the permissions
+ * the filter has on the given picture, or to create the structure if it
+ * does not yet exist.
+ */
+static AVFilterPicPerms *get_perms(AVFilterPic *pic, AVFilterContext *filter)
+{
+ AVFilterPicPerms *ret;
+
+ for(ret = pic->perms; ret; ret = ret->next)
+ if(ret->filter == filter)
+ return ret;
+
+ ret = av_malloc(sizeof(AVFilterPicPerms));
+ ret->filter = filter;
+ ret->perms = 0;
+ ret->next = pic->perms;
+ pic->perms = ret;
+
+ return ret;
+}
+
+int avfilter_get_pic_perms(AVFilterPicRef *pic, AVFilterContext *filter)
+{
+ return get_perms(pic->pic, filter)->perms;
+}
+
+void avfilter_add_pic_perms(AVFilterPicRef *pic, AVFilterContext *filter,
+ int perms)
{
+ get_perms(pic->pic, filter)->perms |= perms;
+}
+
+AVFilterPicRef *avfilter_ref_pic(AVFilterPicRef *ref, AVFilterContext *filter,
+ int pmask)
+{
+ AVFilterPicPerms *pic_perms;
AVFilterPicRef *ret = av_malloc(sizeof(AVFilterPicRef));
memcpy(ret, ref, sizeof(AVFilterPicRef));
ret->perms &= pmask;
ret->pic->refcount ++;
+
+ if(filter) {
+ pic_perms = get_perms(ref->pic, filter);
+ pic_perms->perms |= ret->perms;
+ }
+
return ret;
}
void avfilter_unref_pic(AVFilterPicRef *ref)
{
- if(-- ref->pic->refcount == 0)
+ AVFilterPicPerms *perms;
+
+ if(-- ref->pic->refcount == 0) {
+ for(; ref->pic->perms; ref->pic->perms = perms) {
+ perms = ref->pic->perms->next;
+ av_free(ref->pic->perms);
+ }
ref->pic->free(ref->pic);
+ }
av_free(ref);
}
@@ -160,6 +208,7 @@ int avfilter_request_frame(AVFilterLink *link)
* forcing the source filter to do it? */
void avfilter_start_frame(AVFilterLink *link, AVFilterPicRef *picref)
{
+ int perms = get_perms(picref->pic, link->dst)->perms;
void (*start_frame)(AVFilterLink *, AVFilterPicRef *);
start_frame = link_dpad(link).start_frame;
@@ -167,11 +216,11 @@ void avfilter_start_frame(AVFilterLink *link, AVFilterPicRef *picref)
start_frame = avfilter_default_start_frame;
/* prepare to copy the picture if it has insufficient permissions */
- if((link_dpad(link).min_perms & picref->perms) != link_dpad(link).min_perms ||
- link_dpad(link).rej_perms & picref->perms) {
+ if((link_dpad(link).min_perms & perms) != link_dpad(link).min_perms ||
+ link_dpad(link).rej_perms & perms) {
av_log(link->dst, AV_LOG_INFO,
"frame copy needed (have perms %x, need %x, reject %x)\n",
- picref->perms,
+ perms,
link_dpad(link).min_perms, link_dpad(link).rej_perms);
link->cur_pic = avfilter_default_get_video_buffer(link, link_dpad(link).min_perms);