... | ... |
@@ -258,8 +258,11 @@ struct AVFilterPad { |
258 | 258 |
* picture inside the link structure. |
259 | 259 |
* |
260 | 260 |
* Input video pads only. |
261 |
+ * |
|
262 |
+ * @return >= 0 on success, a negative AVERROR on error. picref will be |
|
263 |
+ * unreferenced by the caller in case of error. |
|
261 | 264 |
*/ |
262 |
- void (*start_frame)(AVFilterLink *link, AVFilterBufferRef *picref); |
|
265 |
+ int (*start_frame)(AVFilterLink *link, AVFilterBufferRef *picref); |
|
263 | 266 |
|
264 | 267 |
/** |
265 | 268 |
* Callback function to get a video buffer. If NULL, the filter system will |
... | ... |
@@ -47,20 +47,16 @@ static av_cold void uninit(AVFilterContext *ctx) |
47 | 47 |
av_audio_fifo_free(sink->audio_fifo); |
48 | 48 |
} |
49 | 49 |
|
50 |
-static void start_frame(AVFilterLink *link, AVFilterBufferRef *buf) |
|
50 |
+static int start_frame(AVFilterLink *link, AVFilterBufferRef *buf) |
|
51 | 51 |
{ |
52 | 52 |
BufferSinkContext *s = link->dst->priv; |
53 | 53 |
|
54 | 54 |
av_assert0(!s->cur_buf); |
55 | 55 |
s->cur_buf = buf; |
56 | 56 |
link->cur_buf = NULL; |
57 |
-}; |
|
58 | 57 |
|
59 |
-static int filter_samples(AVFilterLink *link, AVFilterBufferRef *buf) |
|
60 |
-{ |
|
61 |
- start_frame(link, buf); |
|
62 | 58 |
return 0; |
63 |
-} |
|
59 |
+}; |
|
64 | 60 |
|
65 | 61 |
int av_buffersink_read(AVFilterContext *ctx, AVFilterBufferRef **buf) |
66 | 62 |
{ |
... | ... |
@@ -166,7 +162,7 @@ AVFilter avfilter_asink_abuffer = { |
166 | 166 |
|
167 | 167 |
.inputs = (const AVFilterPad[]) {{ .name = "default", |
168 | 168 |
.type = AVMEDIA_TYPE_AUDIO, |
169 |
- .filter_samples = filter_samples, |
|
169 |
+ .filter_samples = start_frame, |
|
170 | 170 |
.min_perms = AV_PERM_READ, |
171 | 171 |
.needs_fifo = 1 }, |
172 | 172 |
{ .name = NULL }}, |
... | ... |
@@ -76,6 +76,7 @@ static int add_to_queue(AVFilterLink *inlink, AVFilterBufferRef *buf) |
76 | 76 |
{ |
77 | 77 |
FifoContext *fifo = inlink->dst->priv; |
78 | 78 |
|
79 |
+ inlink->cur_buf = NULL; |
|
79 | 80 |
fifo->last->next = av_mallocz(sizeof(Buf)); |
80 | 81 |
if (!fifo->last->next) { |
81 | 82 |
avfilter_unref_buffer(buf); |
... | ... |
@@ -88,12 +89,6 @@ static int add_to_queue(AVFilterLink *inlink, AVFilterBufferRef *buf) |
88 | 88 |
return 0; |
89 | 89 |
} |
90 | 90 |
|
91 |
-static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *buf) |
|
92 |
-{ |
|
93 |
- add_to_queue(inlink, buf); |
|
94 |
- inlink->cur_buf = NULL; |
|
95 |
-} |
|
96 |
- |
|
97 | 91 |
static void queue_pop(FifoContext *s) |
98 | 92 |
{ |
99 | 93 |
Buf *tmp = s->root.next->next; |
... | ... |
@@ -272,7 +267,7 @@ AVFilter avfilter_vf_fifo = { |
272 | 272 |
.inputs = (const AVFilterPad[]) {{ .name = "default", |
273 | 273 |
.type = AVMEDIA_TYPE_VIDEO, |
274 | 274 |
.get_video_buffer= ff_null_get_video_buffer, |
275 |
- .start_frame = start_frame, |
|
275 |
+ .start_frame = add_to_queue, |
|
276 | 276 |
.draw_slice = draw_slice, |
277 | 277 |
.end_frame = end_frame, |
278 | 278 |
.rej_perms = AV_PERM_REUSE2, }, |
... | ... |
@@ -69,6 +69,9 @@ struct AVFilterPad { |
69 | 69 |
* picture inside the link structure. |
70 | 70 |
* |
71 | 71 |
* Input video pads only. |
72 |
+ * |
|
73 |
+ * @return >= 0 on success, a negative AVERROR on error. picref will be |
|
74 |
+ * unreferenced by the caller in case of error. |
|
72 | 75 |
*/ |
73 | 76 |
void (*start_frame)(AVFilterLink *link, AVFilterBufferRef *picref); |
74 | 77 |
|
... | ... |
@@ -63,14 +63,18 @@ static void split_uninit(AVFilterContext *ctx) |
63 | 63 |
av_freep(&ctx->output_pads[i].name); |
64 | 64 |
} |
65 | 65 |
|
66 |
-static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) |
|
66 |
+static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) |
|
67 | 67 |
{ |
68 | 68 |
AVFilterContext *ctx = inlink->dst; |
69 |
- int i; |
|
69 |
+ int i, ret = 0; |
|
70 | 70 |
|
71 |
- for (i = 0; i < ctx->nb_outputs; i++) |
|
72 |
- ff_start_frame(ctx->outputs[i], |
|
73 |
- avfilter_ref_buffer(picref, ~AV_PERM_WRITE)); |
|
71 |
+ for (i = 0; i < ctx->nb_outputs; i++) { |
|
72 |
+ ret = ff_start_frame(ctx->outputs[i], |
|
73 |
+ avfilter_ref_buffer(picref, ~AV_PERM_WRITE)); |
|
74 |
+ if (ret < 0) |
|
75 |
+ break; |
|
76 |
+ } |
|
77 |
+ return ret; |
|
74 | 78 |
} |
75 | 79 |
|
76 | 80 |
static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) |
... | ... |
@@ -64,13 +64,13 @@ static av_cold int init(AVFilterContext *ctx, const char *args) |
64 | 64 |
return 0; |
65 | 65 |
} |
66 | 66 |
|
67 |
-static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) |
|
67 |
+static int start_frame(AVFilterLink *link, AVFilterBufferRef *picref) |
|
68 | 68 |
{ |
69 | 69 |
AspectContext *aspect = link->dst->priv; |
70 | 70 |
|
71 | 71 |
picref->video->pixel_aspect = aspect->aspect; |
72 | 72 |
link->cur_buf = NULL; |
73 |
- ff_start_frame(link->dst->outputs[0], picref); |
|
73 |
+ return ff_start_frame(link->dst->outputs[0], picref); |
|
74 | 74 |
} |
75 | 75 |
|
76 | 76 |
#if CONFIG_SETDAR_FILTER |
... | ... |
@@ -240,7 +240,7 @@ static int config_output(AVFilterLink *link) |
240 | 240 |
return 0; |
241 | 241 |
} |
242 | 242 |
|
243 |
-static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) |
|
243 |
+static int start_frame(AVFilterLink *link, AVFilterBufferRef *picref) |
|
244 | 244 |
{ |
245 | 245 |
AVFilterContext *ctx = link->dst; |
246 | 246 |
CropContext *crop = ctx->priv; |
... | ... |
@@ -248,6 +248,9 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) |
248 | 248 |
int i; |
249 | 249 |
|
250 | 250 |
ref2 = avfilter_ref_buffer(picref, ~0); |
251 |
+ if (!ref2) |
|
252 |
+ return AVERROR(ENOMEM); |
|
253 |
+ |
|
251 | 254 |
ref2->video->w = crop->w; |
252 | 255 |
ref2->video->h = crop->h; |
253 | 256 |
|
... | ... |
@@ -291,7 +294,7 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) |
291 | 291 |
ref2->data[3] += crop->x * crop->max_step[3]; |
292 | 292 |
} |
293 | 293 |
|
294 |
- ff_start_frame(link->dst->outputs[0], ref2); |
|
294 |
+ return ff_start_frame(link->dst->outputs[0], ref2); |
|
295 | 295 |
} |
296 | 296 |
|
297 | 297 |
static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir) |
... | ... |
@@ -214,22 +214,35 @@ static av_cold int init(AVFilterContext *ctx, const char *args) |
214 | 214 |
return 0; |
215 | 215 |
} |
216 | 216 |
|
217 |
-static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) |
|
217 |
+static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) |
|
218 | 218 |
{ |
219 | 219 |
AVFilterLink *outlink = inlink->dst->outputs[0]; |
220 |
- AVFilterBufferRef *outpicref; |
|
220 |
+ AVFilterBufferRef *outpicref = NULL; |
|
221 |
+ int ret = 0; |
|
221 | 222 |
|
222 | 223 |
if (inpicref->perms & AV_PERM_PRESERVE) { |
223 | 224 |
outpicref = ff_get_video_buffer(outlink, AV_PERM_WRITE, |
224 | 225 |
outlink->w, outlink->h); |
226 |
+ if (!outpicref) |
|
227 |
+ return AVERROR(ENOMEM); |
|
228 |
+ |
|
225 | 229 |
avfilter_copy_buffer_ref_props(outpicref, inpicref); |
226 | 230 |
outpicref->video->w = outlink->w; |
227 | 231 |
outpicref->video->h = outlink->h; |
228 |
- } else |
|
232 |
+ } else { |
|
229 | 233 |
outpicref = avfilter_ref_buffer(inpicref, ~0); |
234 |
+ if (!outpicref) |
|
235 |
+ return AVERROR(ENOMEM); |
|
236 |
+ } |
|
237 |
+ |
|
238 |
+ ret = ff_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0)); |
|
239 |
+ if (ret < 0) { |
|
240 |
+ avfilter_unref_bufferp(&outpicref); |
|
241 |
+ return ret; |
|
242 |
+ } |
|
230 | 243 |
|
231 | 244 |
outlink->out_buf = outpicref; |
232 |
- ff_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0)); |
|
245 |
+ return 0; |
|
233 | 246 |
} |
234 | 247 |
|
235 | 248 |
static void null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { } |
... | ... |
@@ -808,16 +808,16 @@ static inline int normalize_double(int *n, double d) |
808 | 808 |
return ret; |
809 | 809 |
} |
810 | 810 |
|
811 |
-static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) |
|
811 |
+static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) |
|
812 | 812 |
{ |
813 | 813 |
AVFilterContext *ctx = inlink->dst; |
814 | 814 |
DrawTextContext *dtext = ctx->priv; |
815 | 815 |
AVFilterBufferRef *buf_out; |
816 |
- int fail = 0; |
|
816 |
+ int ret = 0; |
|
817 | 817 |
|
818 |
- if (dtext_prepare_text(ctx) < 0) { |
|
818 |
+ if ((ret = dtext_prepare_text(ctx)) < 0) { |
|
819 | 819 |
av_log(ctx, AV_LOG_ERROR, "Can't draw text\n"); |
820 |
- fail = 1; |
|
820 |
+ return ret; |
|
821 | 821 |
} |
822 | 822 |
|
823 | 823 |
dtext->var_values[VAR_T] = inpicref->pts == AV_NOPTS_VALUE ? |
... | ... |
@@ -829,8 +829,7 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) |
829 | 829 |
dtext->var_values[VAR_X] = |
830 | 830 |
av_expr_eval(dtext->x_pexpr, dtext->var_values, &dtext->prng); |
831 | 831 |
|
832 |
- dtext->draw = fail ? 0 : |
|
833 |
- av_expr_eval(dtext->d_pexpr, dtext->var_values, &dtext->prng); |
|
832 |
+ dtext->draw = av_expr_eval(dtext->d_pexpr, dtext->var_values, &dtext->prng); |
|
834 | 833 |
|
835 | 834 |
normalize_double(&dtext->x, dtext->var_values[VAR_X]); |
836 | 835 |
normalize_double(&dtext->y, dtext->var_values[VAR_Y]); |
... | ... |
@@ -852,7 +851,10 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) |
852 | 852 |
dtext->x, dtext->y, dtext->x+dtext->w, dtext->y+dtext->h); |
853 | 853 |
|
854 | 854 |
buf_out = avfilter_ref_buffer(inpicref, ~0); |
855 |
- ff_start_frame(inlink->dst->outputs[0], buf_out); |
|
855 |
+ if (!buf_out) |
|
856 |
+ return AVERROR(ENOMEM); |
|
857 |
+ |
|
858 |
+ return ff_start_frame(inlink->dst->outputs[0], buf_out); |
|
856 | 859 |
} |
857 | 860 |
|
858 | 861 |
static void end_frame(AVFilterLink *inlink) |
... | ... |
@@ -116,18 +116,32 @@ static AVFilterBufferRef *get_video_buffer(AVFilterLink *inlink, int perms, int |
116 | 116 |
return ff_get_video_buffer(outlink, perms, w, h); |
117 | 117 |
} |
118 | 118 |
|
119 |
-static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) |
|
119 |
+static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) |
|
120 | 120 |
{ |
121 | 121 |
AVFilterContext *ctx = inlink->dst; |
122 | 122 |
AVFilterLink *outlink = ctx->outputs[0]; |
123 | 123 |
|
124 | 124 |
AVFilterBufferRef *outpicref, *for_next_filter; |
125 |
+ int ret = 0; |
|
125 | 126 |
|
126 | 127 |
outpicref = avfilter_ref_buffer(inpicref, ~0); |
127 |
- outlink->out_buf = outpicref; |
|
128 |
+ if (!outpicref) |
|
129 |
+ return AVERROR(ENOMEM); |
|
128 | 130 |
|
129 | 131 |
for_next_filter = avfilter_ref_buffer(outpicref, ~0); |
130 |
- ff_start_frame(outlink, for_next_filter); |
|
132 |
+ if (!for_next_filter) { |
|
133 |
+ avfilter_unref_bufferp(&outpicref); |
|
134 |
+ return AVERROR(ENOMEM); |
|
135 |
+ } |
|
136 |
+ |
|
137 |
+ ret = ff_start_frame(outlink, for_next_filter); |
|
138 |
+ if (ret < 0) { |
|
139 |
+ avfilter_unref_bufferp(&outpicref); |
|
140 |
+ return ret; |
|
141 |
+ } |
|
142 |
+ |
|
143 |
+ outlink->out_buf = outpicref; |
|
144 |
+ return 0; |
|
131 | 145 |
} |
132 | 146 |
|
133 | 147 |
static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) |
... | ... |
@@ -243,8 +243,9 @@ static void end_frame(AVFilterLink *inlink) |
243 | 243 |
s->pts = s->first_pts + av_rescale_q(s->frames_out, outlink->time_base, inlink->time_base); |
244 | 244 |
} |
245 | 245 |
|
246 |
-static void null_start_frame(AVFilterLink *link, AVFilterBufferRef *buf) |
|
246 |
+static int null_start_frame(AVFilterLink *link, AVFilterBufferRef *buf) |
|
247 | 247 |
{ |
248 |
+ return 0; |
|
248 | 249 |
} |
249 | 250 |
|
250 | 251 |
static void null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) |
... | ... |
@@ -180,21 +180,34 @@ static int config_input(AVFilterLink *inlink) |
180 | 180 |
return 0; |
181 | 181 |
} |
182 | 182 |
|
183 |
-static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) |
|
183 |
+static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) |
|
184 | 184 |
{ |
185 | 185 |
AVFilterLink *outlink = inlink->dst->outputs[0]; |
186 |
- AVFilterBufferRef *outpicref; |
|
186 |
+ AVFilterBufferRef *outpicref = NULL; |
|
187 |
+ int ret = 0; |
|
187 | 188 |
|
188 | 189 |
if (inpicref->perms & AV_PERM_PRESERVE) { |
189 | 190 |
outpicref = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h); |
191 |
+ if (!outpicref) |
|
192 |
+ return AVERROR(ENOMEM); |
|
193 |
+ |
|
190 | 194 |
avfilter_copy_buffer_ref_props(outpicref, inpicref); |
191 | 195 |
outpicref->video->w = outlink->w; |
192 | 196 |
outpicref->video->h = outlink->h; |
193 |
- } else |
|
197 |
+ } else { |
|
194 | 198 |
outpicref = avfilter_ref_buffer(inpicref, ~0); |
199 |
+ if (!outpicref) |
|
200 |
+ return AVERROR(ENOMEM); |
|
201 |
+ } |
|
202 |
+ |
|
203 |
+ ret = ff_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0)); |
|
204 |
+ if (ret < 0) { |
|
205 |
+ avfilter_unref_bufferp(&outpicref); |
|
206 |
+ return ret; |
|
207 |
+ } |
|
195 | 208 |
|
196 | 209 |
outlink->out_buf = outpicref; |
197 |
- ff_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0)); |
|
210 |
+ return 0; |
|
198 | 211 |
} |
199 | 212 |
|
200 | 213 |
static void null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { } |
... | ... |
@@ -208,7 +208,7 @@ static AVFilterBufferRef *get_video_buffer(AVFilterLink *link, int perms, int w, |
208 | 208 |
return ff_get_video_buffer(link->dst->outputs[0], perms, w, h); |
209 | 209 |
} |
210 | 210 |
|
211 |
-static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) |
|
211 |
+static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) |
|
212 | 212 |
{ |
213 | 213 |
AVFilterBufferRef *outpicref = avfilter_ref_buffer(inpicref, ~0); |
214 | 214 |
AVFilterContext *ctx = inlink->dst; |
... | ... |
@@ -228,10 +228,10 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) |
228 | 228 |
over->overpicref = old; |
229 | 229 |
} |
230 | 230 |
|
231 |
- ff_start_frame(inlink->dst->outputs[0], outpicref); |
|
231 |
+ return ff_start_frame(inlink->dst->outputs[0], outpicref); |
|
232 | 232 |
} |
233 | 233 |
|
234 |
-static void start_frame_overlay(AVFilterLink *inlink, AVFilterBufferRef *inpicref) |
|
234 |
+static int start_frame_overlay(AVFilterLink *inlink, AVFilterBufferRef *inpicref) |
|
235 | 235 |
{ |
236 | 236 |
AVFilterContext *ctx = inlink->dst; |
237 | 237 |
OverlayContext *over = ctx->priv; |
... | ... |
@@ -239,6 +239,7 @@ static void start_frame_overlay(AVFilterLink *inlink, AVFilterBufferRef *inpicre |
239 | 239 |
over->overpicref = inpicref; |
240 | 240 |
over->overpicref->pts = av_rescale_q(inpicref->pts, ctx->inputs[OVERLAY]->time_base, |
241 | 241 |
ctx->outputs[0]->time_base); |
242 |
+ return 0; |
|
242 | 243 |
} |
243 | 244 |
|
244 | 245 |
static void blend_slice(AVFilterContext *ctx, |
... | ... |
@@ -299,12 +299,15 @@ static int does_clip(PadContext *pad, AVFilterBufferRef *outpicref, int plane, i |
299 | 299 |
return 0; |
300 | 300 |
} |
301 | 301 |
|
302 |
-static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) |
|
302 |
+static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) |
|
303 | 303 |
{ |
304 | 304 |
PadContext *pad = inlink->dst->priv; |
305 | 305 |
AVFilterBufferRef *outpicref = avfilter_ref_buffer(inpicref, ~0); |
306 | 306 |
AVFilterBufferRef *for_next_filter; |
307 |
- int plane; |
|
307 |
+ int plane, ret = 0; |
|
308 |
+ |
|
309 |
+ if (!outpicref) |
|
310 |
+ return AVERROR(ENOMEM); |
|
308 | 311 |
|
309 | 312 |
for (plane = 0; plane < 4 && outpicref->data[plane]; plane++) { |
310 | 313 |
int hsub = (plane == 1 || plane == 2) ? pad->hsub : 0; |
... | ... |
@@ -332,16 +335,31 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) |
332 | 332 |
outpicref = ff_get_video_buffer(inlink->dst->outputs[0], AV_PERM_WRITE | AV_PERM_NEG_LINESIZES, |
333 | 333 |
FFMAX(inlink->w, pad->w), |
334 | 334 |
FFMAX(inlink->h, pad->h)); |
335 |
+ if (!outpicref) |
|
336 |
+ return AVERROR(ENOMEM); |
|
337 |
+ |
|
335 | 338 |
avfilter_copy_buffer_ref_props(outpicref, inpicref); |
336 | 339 |
} |
337 | 340 |
|
338 |
- inlink->dst->outputs[0]->out_buf = outpicref; |
|
339 |
- |
|
340 | 341 |
outpicref->video->w = pad->w; |
341 | 342 |
outpicref->video->h = pad->h; |
342 | 343 |
|
343 | 344 |
for_next_filter = avfilter_ref_buffer(outpicref, ~0); |
344 |
- ff_start_frame(inlink->dst->outputs[0], for_next_filter); |
|
345 |
+ if (!for_next_filter) { |
|
346 |
+ ret = AVERROR(ENOMEM); |
|
347 |
+ goto fail; |
|
348 |
+ } |
|
349 |
+ |
|
350 |
+ ret = ff_start_frame(inlink->dst->outputs[0], for_next_filter); |
|
351 |
+ if (ret < 0) |
|
352 |
+ goto fail; |
|
353 |
+ |
|
354 |
+ inlink->dst->outputs[0]->out_buf = outpicref; |
|
355 |
+ return 0; |
|
356 |
+ |
|
357 |
+fail: |
|
358 |
+ avfilter_unref_bufferp(&outpicref); |
|
359 |
+ return ret; |
|
345 | 360 |
} |
346 | 361 |
|
347 | 362 |
static void end_frame(AVFilterLink *link) |
... | ... |
@@ -51,16 +51,18 @@ static int config_props(AVFilterLink *inlink) |
51 | 51 |
return 0; |
52 | 52 |
} |
53 | 53 |
|
54 |
-static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) |
|
54 |
+static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) |
|
55 | 55 |
{ |
56 | 56 |
PixdescTestContext *priv = inlink->dst->priv; |
57 | 57 |
AVFilterLink *outlink = inlink->dst->outputs[0]; |
58 | 58 |
AVFilterBufferRef *outpicref; |
59 |
- int i; |
|
59 |
+ int i, ret = 0; |
|
60 |
+ |
|
61 |
+ outpicref = ff_get_video_buffer(outlink, AV_PERM_WRITE, |
|
62 |
+ outlink->w, outlink->h); |
|
63 |
+ if (!outpicref) |
|
64 |
+ return AVERROR(ENOMEM); |
|
60 | 65 |
|
61 |
- outlink->out_buf = ff_get_video_buffer(outlink, AV_PERM_WRITE, |
|
62 |
- outlink->w, outlink->h); |
|
63 |
- outpicref = outlink->out_buf; |
|
64 | 66 |
avfilter_copy_buffer_ref_props(outpicref, picref); |
65 | 67 |
|
66 | 68 |
for (i = 0; i < 4; i++) { |
... | ... |
@@ -78,7 +80,14 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) |
78 | 78 |
priv->pix_desc->flags & PIX_FMT_PSEUDOPAL) |
79 | 79 |
memcpy(outpicref->data[1], outpicref->data[1], 256*4); |
80 | 80 |
|
81 |
- ff_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0)); |
|
81 |
+ ret = ff_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0)); |
|
82 |
+ if (ret < 0) { |
|
83 |
+ avfilter_unref_bufferp(&outpicref); |
|
84 |
+ return ret; |
|
85 |
+ } |
|
86 |
+ |
|
87 |
+ outlink->out_buf = outpicref; |
|
88 |
+ return 0; |
|
82 | 89 |
} |
83 | 90 |
|
84 | 91 |
static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) |
... | ... |
@@ -252,26 +252,28 @@ fail: |
252 | 252 |
return ret; |
253 | 253 |
} |
254 | 254 |
|
255 |
-static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) |
|
255 |
+static int start_frame(AVFilterLink *link, AVFilterBufferRef *picref) |
|
256 | 256 |
{ |
257 | 257 |
ScaleContext *scale = link->dst->priv; |
258 | 258 |
AVFilterLink *outlink = link->dst->outputs[0]; |
259 | 259 |
AVFilterBufferRef *outpicref; |
260 |
+ int ret = 0; |
|
260 | 261 |
|
261 | 262 |
if (!scale->sws) { |
262 |
- ff_start_frame(outlink, avfilter_ref_buffer(picref, ~0)); |
|
263 |
- return; |
|
263 |
+ return ff_start_frame(outlink, avfilter_ref_buffer(picref, ~0)); |
|
264 | 264 |
} |
265 | 265 |
|
266 | 266 |
scale->hsub = av_pix_fmt_descriptors[link->format].log2_chroma_w; |
267 | 267 |
scale->vsub = av_pix_fmt_descriptors[link->format].log2_chroma_h; |
268 | 268 |
|
269 | 269 |
outpicref = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h); |
270 |
+ if (!outpicref) |
|
271 |
+ return AVERROR(ENOMEM); |
|
272 |
+ |
|
270 | 273 |
avfilter_copy_buffer_ref_props(outpicref, picref); |
271 | 274 |
outpicref->video->w = outlink->w; |
272 | 275 |
outpicref->video->h = outlink->h; |
273 | 276 |
|
274 |
- outlink->out_buf = outpicref; |
|
275 | 277 |
|
276 | 278 |
av_reduce(&outpicref->video->pixel_aspect.num, &outpicref->video->pixel_aspect.den, |
277 | 279 |
(int64_t)picref->video->pixel_aspect.num * outlink->h * link->w, |
... | ... |
@@ -279,7 +281,14 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) |
279 | 279 |
INT_MAX); |
280 | 280 |
|
281 | 281 |
scale->slice_y = 0; |
282 |
- ff_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0)); |
|
282 |
+ ret = ff_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0)); |
|
283 |
+ if (ret < 0) { |
|
284 |
+ avfilter_unref_bufferp(&outpicref); |
|
285 |
+ return ret; |
|
286 |
+ } |
|
287 |
+ |
|
288 |
+ outlink->out_buf = outpicref; |
|
289 |
+ return 0; |
|
283 | 290 |
} |
284 | 291 |
|
285 | 292 |
static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir) |
... | ... |
@@ -227,7 +227,7 @@ static int select_frame(AVFilterContext *ctx, AVFilterBufferRef *picref) |
227 | 227 |
return res; |
228 | 228 |
} |
229 | 229 |
|
230 |
-static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) |
|
230 |
+static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) |
|
231 | 231 |
{ |
232 | 232 |
SelectContext *select = inlink->dst->priv; |
233 | 233 |
|
... | ... |
@@ -241,10 +241,12 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) |
241 | 241 |
else |
242 | 242 |
av_fifo_generic_write(select->pending_frames, &picref, |
243 | 243 |
sizeof(picref), NULL); |
244 |
- return; |
|
244 |
+ return 0; |
|
245 | 245 |
} |
246 |
- ff_start_frame(inlink->dst->outputs[0], avfilter_ref_buffer(picref, ~0)); |
|
246 |
+ return ff_start_frame(inlink->dst->outputs[0], avfilter_ref_buffer(picref, ~0)); |
|
247 | 247 |
} |
248 |
+ |
|
249 |
+ return 0; |
|
248 | 250 |
} |
249 | 251 |
|
250 | 252 |
static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) |
... | ... |
@@ -101,12 +101,15 @@ static int config_input(AVFilterLink *inlink) |
101 | 101 |
#define D2TS(d) (isnan(d) ? AV_NOPTS_VALUE : (int64_t)(d)) |
102 | 102 |
#define TS2D(ts) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts)) |
103 | 103 |
|
104 |
-static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) |
|
104 |
+static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) |
|
105 | 105 |
{ |
106 | 106 |
SetPTSContext *setpts = inlink->dst->priv; |
107 | 107 |
double d; |
108 | 108 |
AVFilterBufferRef *outpicref = avfilter_ref_buffer(inpicref, ~0); |
109 | 109 |
|
110 |
+ if (!outpicref) |
|
111 |
+ return AVERROR(ENOMEM); |
|
112 |
+ |
|
110 | 113 |
if (isnan(setpts->var_values[VAR_STARTPTS])) |
111 | 114 |
setpts->var_values[VAR_STARTPTS] = TS2D(inpicref->pts); |
112 | 115 |
|
... | ... |
@@ -130,7 +133,7 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) |
130 | 130 |
setpts->var_values[VAR_N] += 1.0; |
131 | 131 |
setpts->var_values[VAR_PREV_INPTS ] = TS2D(inpicref ->pts); |
132 | 132 |
setpts->var_values[VAR_PREV_OUTPTS] = TS2D(outpicref->pts); |
133 |
- ff_start_frame(inlink->dst->outputs[0], outpicref); |
|
133 |
+ return ff_start_frame(inlink->dst->outputs[0], outpicref); |
|
134 | 134 |
} |
135 | 135 |
|
136 | 136 |
static av_cold void uninit(AVFilterContext *ctx) |
... | ... |
@@ -104,7 +104,7 @@ static int config_output_props(AVFilterLink *outlink) |
104 | 104 |
return 0; |
105 | 105 |
} |
106 | 106 |
|
107 |
-static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) |
|
107 |
+static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) |
|
108 | 108 |
{ |
109 | 109 |
AVFilterContext *ctx = inlink->dst; |
110 | 110 |
AVFilterLink *outlink = ctx->outputs[0]; |
... | ... |
@@ -118,7 +118,7 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) |
118 | 118 |
} |
119 | 119 |
inlink->cur_buf = NULL; |
120 | 120 |
|
121 |
- ff_start_frame(outlink, picref); |
|
121 |
+ return ff_start_frame(outlink, picref); |
|
122 | 122 |
} |
123 | 123 |
|
124 | 124 |
AVFilter avfilter_vf_settb = { |
... | ... |
@@ -59,7 +59,7 @@ static int config_props(AVFilterLink *link) |
59 | 59 |
return 0; |
60 | 60 |
} |
61 | 61 |
|
62 |
-static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) |
|
62 |
+static int start_frame(AVFilterLink *link, AVFilterBufferRef *picref) |
|
63 | 63 |
{ |
64 | 64 |
SliceContext *slice = link->dst->priv; |
65 | 65 |
|
... | ... |
@@ -75,7 +75,7 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) |
75 | 75 |
av_log(link->dst, AV_LOG_DEBUG, "h:%d\n", slice->h); |
76 | 76 |
link->cur_buf = NULL; |
77 | 77 |
|
78 |
- ff_start_frame(link->dst->outputs[0], picref); |
|
78 |
+ return ff_start_frame(link->dst->outputs[0], picref); |
|
79 | 79 |
} |
80 | 80 |
|
81 | 81 |
static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir) |
... | ... |
@@ -117,12 +117,15 @@ static int config_props_output(AVFilterLink *outlink) |
117 | 117 |
return 0; |
118 | 118 |
} |
119 | 119 |
|
120 |
-static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) |
|
120 |
+static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) |
|
121 | 121 |
{ |
122 | 122 |
AVFilterLink *outlink = inlink->dst->outputs[0]; |
123 | 123 |
|
124 | 124 |
outlink->out_buf = ff_get_video_buffer(outlink, AV_PERM_WRITE, |
125 | 125 |
outlink->w, outlink->h); |
126 |
+ if (!outlink->out_buf) |
|
127 |
+ return AVERROR(ENOMEM); |
|
128 |
+ |
|
126 | 129 |
outlink->out_buf->pts = picref->pts; |
127 | 130 |
|
128 | 131 |
if (picref->video->pixel_aspect.num == 0) { |
... | ... |
@@ -132,7 +135,7 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) |
132 | 132 |
outlink->out_buf->video->pixel_aspect.den = picref->video->pixel_aspect.num; |
133 | 133 |
} |
134 | 134 |
|
135 |
- ff_start_frame(outlink, avfilter_ref_buffer(outlink->out_buf, ~0)); |
|
135 |
+ return ff_start_frame(outlink, avfilter_ref_buffer(outlink->out_buf, ~0)); |
|
136 | 136 |
} |
137 | 137 |
|
138 | 138 |
static void end_frame(AVFilterLink *inlink) |
... | ... |
@@ -64,7 +64,7 @@ static AVFilterBufferRef *get_video_buffer(AVFilterLink *link, int perms, |
64 | 64 |
return picref; |
65 | 65 |
} |
66 | 66 |
|
67 |
-static void start_frame(AVFilterLink *link, AVFilterBufferRef *inpicref) |
|
67 |
+static int start_frame(AVFilterLink *link, AVFilterBufferRef *inpicref) |
|
68 | 68 |
{ |
69 | 69 |
FlipContext *flip = link->dst->priv; |
70 | 70 |
AVFilterBufferRef *outpicref = avfilter_ref_buffer(inpicref, ~0); |
... | ... |
@@ -79,7 +79,7 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *inpicref) |
79 | 79 |
} |
80 | 80 |
} |
81 | 81 |
|
82 |
- ff_start_frame(link->dst->outputs[0], outpicref); |
|
82 |
+ return ff_start_frame(link->dst->outputs[0], outpicref); |
|
83 | 83 |
} |
84 | 84 |
|
85 | 85 |
static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir) |
... | ... |
@@ -201,7 +201,7 @@ static void return_frame(AVFilterContext *ctx, int is_second) |
201 | 201 |
yadif->frame_pending = (yadif->mode&1) && !is_second; |
202 | 202 |
} |
203 | 203 |
|
204 |
-static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) |
|
204 |
+static int start_frame(AVFilterLink *link, AVFilterBufferRef *picref) |
|
205 | 205 |
{ |
206 | 206 |
AVFilterContext *ctx = link->dst; |
207 | 207 |
YADIFContext *yadif = ctx->priv; |
... | ... |
@@ -216,7 +216,7 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) |
216 | 216 |
yadif->next = picref; |
217 | 217 |
|
218 | 218 |
if (!yadif->cur) |
219 |
- return; |
|
219 |
+ return 0; |
|
220 | 220 |
|
221 | 221 |
if (yadif->auto_enable && !yadif->cur->video->interlaced) { |
222 | 222 |
yadif->out = avfilter_ref_buffer(yadif->cur, AV_PERM_READ); |
... | ... |
@@ -224,8 +224,7 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) |
224 | 224 |
yadif->prev = NULL; |
225 | 225 |
if (yadif->out->pts != AV_NOPTS_VALUE) |
226 | 226 |
yadif->out->pts *= 2; |
227 |
- ff_start_frame(ctx->outputs[0], yadif->out); |
|
228 |
- return; |
|
227 |
+ return ff_start_frame(ctx->outputs[0], yadif->out); |
|
229 | 228 |
} |
230 | 229 |
|
231 | 230 |
if (!yadif->prev) |
... | ... |
@@ -238,7 +237,7 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) |
238 | 238 |
yadif->out->video->interlaced = 0; |
239 | 239 |
if (yadif->out->pts != AV_NOPTS_VALUE) |
240 | 240 |
yadif->out->pts *= 2; |
241 |
- ff_start_frame(ctx->outputs[0], yadif->out); |
|
241 |
+ return ff_start_frame(ctx->outputs[0], yadif->out); |
|
242 | 242 |
} |
243 | 243 |
|
244 | 244 |
static void end_frame(AVFilterLink *link) |
... | ... |
@@ -160,13 +160,15 @@ AVFilterBufferRef *ff_get_video_buffer(AVFilterLink *link, int perms, int w, int |
160 | 160 |
return ret; |
161 | 161 |
} |
162 | 162 |
|
163 |
-void ff_null_start_frame(AVFilterLink *link, AVFilterBufferRef *picref) |
|
163 |
+int ff_null_start_frame(AVFilterLink *link, AVFilterBufferRef *picref) |
|
164 | 164 |
{ |
165 | 165 |
AVFilterBufferRef *buf_out = avfilter_ref_buffer(picref, ~0); |
166 |
- ff_start_frame(link->dst->outputs[0], buf_out); |
|
166 |
+ if (!buf_out) |
|
167 |
+ return AVERROR(ENOMEM); |
|
168 |
+ return ff_start_frame(link->dst->outputs[0], buf_out); |
|
167 | 169 |
} |
168 | 170 |
|
169 |
-static void default_start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) |
|
171 |
+static int default_start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) |
|
170 | 172 |
{ |
171 | 173 |
AVFilterLink *outlink = NULL; |
172 | 174 |
|
... | ... |
@@ -175,18 +177,29 @@ static void default_start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) |
175 | 175 |
|
176 | 176 |
if (outlink) { |
177 | 177 |
outlink->out_buf = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h); |
178 |
+ if (!outlink->out_buf) |
|
179 |
+ return AVERROR(ENOMEM); |
|
180 |
+ |
|
178 | 181 |
avfilter_copy_buffer_ref_props(outlink->out_buf, picref); |
179 |
- ff_start_frame(outlink, avfilter_ref_buffer(outlink->out_buf, ~0)); |
|
182 |
+ return ff_start_frame(outlink, avfilter_ref_buffer(outlink->out_buf, ~0)); |
|
180 | 183 |
} |
184 |
+ return 0; |
|
185 |
+} |
|
186 |
+ |
|
187 |
+static void clear_link(AVFilterLink *link) |
|
188 |
+{ |
|
189 |
+ avfilter_unref_bufferp(&link->cur_buf); |
|
190 |
+ avfilter_unref_bufferp(&link->src_buf); |
|
191 |
+ avfilter_unref_bufferp(&link->out_buf); |
|
181 | 192 |
} |
182 | 193 |
|
183 | 194 |
/* XXX: should we do the duplicating of the picture ref here, instead of |
184 | 195 |
* forcing the source filter to do it? */ |
185 |
-void ff_start_frame(AVFilterLink *link, AVFilterBufferRef *picref) |
|
196 |
+int ff_start_frame(AVFilterLink *link, AVFilterBufferRef *picref) |
|
186 | 197 |
{ |
187 |
- void (*start_frame)(AVFilterLink *, AVFilterBufferRef *); |
|
198 |
+ int (*start_frame)(AVFilterLink *, AVFilterBufferRef *); |
|
188 | 199 |
AVFilterPad *dst = link->dstpad; |
189 |
- int perms = picref->perms; |
|
200 |
+ int ret, perms = picref->perms; |
|
190 | 201 |
|
191 | 202 |
FF_DPRINTF_START(NULL, start_frame); ff_dlog_link(NULL, link, 0); av_dlog(NULL, " "); ff_dlog_ref(NULL, picref, 1); |
192 | 203 |
|
... | ... |
@@ -203,13 +216,22 @@ void ff_start_frame(AVFilterLink *link, AVFilterBufferRef *picref) |
203 | 203 |
link->dstpad->min_perms, link->dstpad->rej_perms); |
204 | 204 |
|
205 | 205 |
link->cur_buf = ff_get_video_buffer(link, dst->min_perms, link->w, link->h); |
206 |
+ if (!link->cur_buf) { |
|
207 |
+ avfilter_unref_bufferp(&picref); |
|
208 |
+ return AVERROR(ENOMEM); |
|
209 |
+ } |
|
210 |
+ |
|
206 | 211 |
link->src_buf = picref; |
207 | 212 |
avfilter_copy_buffer_ref_props(link->cur_buf, link->src_buf); |
208 | 213 |
} |
209 | 214 |
else |
210 | 215 |
link->cur_buf = picref; |
211 | 216 |
|
212 |
- start_frame(link, link->cur_buf); |
|
217 |
+ ret = start_frame(link, link->cur_buf); |
|
218 |
+ if (ret < 0) |
|
219 |
+ clear_link(link); |
|
220 |
+ |
|
221 |
+ return ret; |
|
213 | 222 |
} |
214 | 223 |
|
215 | 224 |
void ff_null_end_frame(AVFilterLink *link) |
... | ... |
@@ -238,14 +260,7 @@ void ff_end_frame(AVFilterLink *link) |
238 | 238 |
|
239 | 239 |
end_frame(link); |
240 | 240 |
|
241 |
- /* unreference the source picture if we're feeding the destination filter |
|
242 |
- * a copied version dues to permission issues */ |
|
243 |
- if (link->src_buf) { |
|
244 |
- avfilter_unref_buffer(link->src_buf); |
|
245 |
- link->src_buf = NULL; |
|
246 |
- } |
|
247 |
- avfilter_unref_bufferp(&link->cur_buf); |
|
248 |
- avfilter_unref_bufferp(&link->out_buf); |
|
241 |
+ clear_link(link); |
|
249 | 242 |
} |
250 | 243 |
|
251 | 244 |
void ff_null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) |
... | ... |
@@ -39,7 +39,7 @@ AVFilterBufferRef *ff_null_get_video_buffer(AVFilterLink *link, int perms, int w |
39 | 39 |
AVFilterBufferRef *ff_get_video_buffer(AVFilterLink *link, int perms, |
40 | 40 |
int w, int h); |
41 | 41 |
|
42 |
-void ff_null_start_frame(AVFilterLink *link, AVFilterBufferRef *picref); |
|
42 |
+int ff_null_start_frame(AVFilterLink *link, AVFilterBufferRef *picref); |
|
43 | 43 |
void ff_null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir); |
44 | 44 |
void ff_null_end_frame(AVFilterLink *link); |
45 | 45 |
|
... | ... |
@@ -51,8 +51,11 @@ void ff_null_end_frame(AVFilterLink *link); |
51 | 51 |
* frame need only be valid once draw_slice() is called for that |
52 | 52 |
* portion. The receiving filter will free this reference when |
53 | 53 |
* it no longer needs it. |
54 |
+ * |
|
55 |
+ * @return >= 0 on success, a negative AVERROR on error. This function will |
|
56 |
+ * unreference picref in case of error. |
|
54 | 57 |
*/ |
55 |
-void ff_start_frame(AVFilterLink *link, AVFilterBufferRef *picref); |
|
58 |
+int ff_start_frame(AVFilterLink *link, AVFilterBufferRef *picref); |
|
56 | 59 |
|
57 | 60 |
/** |
58 | 61 |
* Notify the next filter that the current frame has finished. |
... | ... |
@@ -19,8 +19,9 @@ |
19 | 19 |
#include "avfilter.h" |
20 | 20 |
#include "internal.h" |
21 | 21 |
|
22 |
-static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) |
|
22 |
+static int start_frame(AVFilterLink *link, AVFilterBufferRef *picref) |
|
23 | 23 |
{ |
24 |
+ return 0; |
|
24 | 25 |
} |
25 | 26 |
|
26 | 27 |
static void end_frame(AVFilterLink *link) |