Also add internal function ff_null_start_frame_keep_ref().
Fix crash when a following filter (e.g. settb) will unref the reference
passed by start_frame(), and then the reference is accessed in
end_frame() through inlink->cur_buf.
... | ... |
@@ -140,4 +140,13 @@ int ff_parse_channel_layout(int64_t *ret, const char *arg, void *log_ctx); |
140 | 140 |
*/ |
141 | 141 |
int ff_parse_packing_format(int *ret, const char *arg, void *log_ctx); |
142 | 142 |
|
143 |
+/** |
|
144 |
+ * Pass video frame along and keep an internal reference for later use. |
|
145 |
+ */ |
|
146 |
+static inline void ff_null_start_frame_keep_ref(AVFilterLink *inlink, |
|
147 |
+ AVFilterBufferRef *picref) |
|
148 |
+{ |
|
149 |
+ avfilter_start_frame(inlink->dst->outputs[0], avfilter_ref_buffer(picref, ~0)); |
|
150 |
+} |
|
151 |
+ |
|
143 | 152 |
#endif /* AVFILTER_INTERNAL_H */ |
... | ... |
@@ -27,6 +27,7 @@ |
27 | 27 |
#include "libavutil/timestamp.h" |
28 | 28 |
#include "avfilter.h" |
29 | 29 |
#include "bbox.h" |
30 |
+#include "internal.h" |
|
30 | 31 |
|
31 | 32 |
typedef struct { |
32 | 33 |
unsigned int frame; |
... | ... |
@@ -85,6 +86,7 @@ static void end_frame(AVFilterLink *inlink) |
85 | 85 |
av_log(ctx, AV_LOG_INFO, "\n"); |
86 | 86 |
|
87 | 87 |
bbox->frame++; |
88 |
+ avfilter_unref_buffer(picref); |
|
88 | 89 |
avfilter_end_frame(inlink->dst->outputs[0]); |
89 | 90 |
} |
90 | 91 |
|
... | ... |
@@ -99,7 +101,7 @@ AVFilter avfilter_vf_bbox = { |
99 | 99 |
{ .name = "default", |
100 | 100 |
.type = AVMEDIA_TYPE_VIDEO, |
101 | 101 |
.get_video_buffer = avfilter_null_get_video_buffer, |
102 |
- .start_frame = avfilter_null_start_frame, |
|
102 |
+ .start_frame = ff_null_start_frame_keep_ref, |
|
103 | 103 |
.end_frame = end_frame, |
104 | 104 |
.min_perms = AV_PERM_READ, }, |
105 | 105 |
{ .name = NULL } |
... | ... |
@@ -180,6 +180,7 @@ static void end_frame(AVFilterLink *inlink) |
180 | 180 |
|
181 | 181 |
blackdetect->frame_count++; |
182 | 182 |
blackdetect->nb_black_pixels = 0; |
183 |
+ avfilter_unref_buffer(picref); |
|
183 | 184 |
avfilter_end_frame(inlink->dst->outputs[0]); |
184 | 185 |
} |
185 | 186 |
|
... | ... |
@@ -196,7 +197,7 @@ AVFilter avfilter_vf_blackdetect = { |
196 | 196 |
.config_props = config_input, |
197 | 197 |
.draw_slice = draw_slice, |
198 | 198 |
.get_video_buffer = avfilter_null_get_video_buffer, |
199 |
- .start_frame = avfilter_null_start_frame, |
|
199 |
+ .start_frame = ff_null_start_frame_keep_ref, |
|
200 | 200 |
.end_frame = end_frame, }, |
201 | 201 |
{ .name = NULL } |
202 | 202 |
}, |
... | ... |
@@ -28,6 +28,7 @@ |
28 | 28 |
*/ |
29 | 29 |
|
30 | 30 |
#include "avfilter.h" |
31 |
+#include "internal.h" |
|
31 | 32 |
|
32 | 33 |
typedef struct { |
33 | 34 |
unsigned int bamount; ///< black amount |
... | ... |
@@ -110,6 +111,7 @@ static void end_frame(AVFilterLink *inlink) |
110 | 110 |
|
111 | 111 |
blackframe->frame++; |
112 | 112 |
blackframe->nblack = 0; |
113 |
+ avfilter_unref_buffer(picref); |
|
113 | 114 |
avfilter_end_frame(inlink->dst->outputs[0]); |
114 | 115 |
} |
115 | 116 |
|
... | ... |
@@ -126,7 +128,7 @@ AVFilter avfilter_vf_blackframe = { |
126 | 126 |
.type = AVMEDIA_TYPE_VIDEO, |
127 | 127 |
.draw_slice = draw_slice, |
128 | 128 |
.get_video_buffer = avfilter_null_get_video_buffer, |
129 |
- .start_frame = avfilter_null_start_frame, |
|
129 |
+ .start_frame = ff_null_start_frame_keep_ref, |
|
130 | 130 |
.end_frame = end_frame, }, |
131 | 131 |
{ .name = NULL}}, |
132 | 132 |
|
... | ... |
@@ -27,6 +27,7 @@ |
27 | 27 |
#include "libavutil/pixdesc.h" |
28 | 28 |
#include "libavutil/timestamp.h" |
29 | 29 |
#include "avfilter.h" |
30 |
+#include "internal.h" |
|
30 | 31 |
|
31 | 32 |
typedef struct { |
32 | 33 |
unsigned int frame; |
... | ... |
@@ -79,6 +80,7 @@ static void end_frame(AVFilterLink *inlink) |
79 | 79 |
av_log(ctx, AV_LOG_INFO, "]\n"); |
80 | 80 |
|
81 | 81 |
showinfo->frame++; |
82 |
+ avfilter_unref_buffer(picref); |
|
82 | 83 |
avfilter_end_frame(inlink->dst->outputs[0]); |
83 | 84 |
} |
84 | 85 |
|
... | ... |
@@ -92,7 +94,7 @@ AVFilter avfilter_vf_showinfo = { |
92 | 92 |
.inputs = (const AVFilterPad[]) {{ .name = "default", |
93 | 93 |
.type = AVMEDIA_TYPE_VIDEO, |
94 | 94 |
.get_video_buffer = avfilter_null_get_video_buffer, |
95 |
- .start_frame = avfilter_null_start_frame, |
|
95 |
+ .start_frame = ff_null_start_frame_keep_ref, |
|
96 | 96 |
.end_frame = end_frame, |
97 | 97 |
.min_perms = AV_PERM_READ, }, |
98 | 98 |
{ .name = NULL}}, |