Browse code

lavfi: add error handling to end_frame().

Anton Khirnov authored on 2012/07/14 16:25:33
Showing 26 changed files
... ...
@@ -287,8 +287,10 @@ struct AVFilterPad {
287 287
      * in the link structure during start_frame().
288 288
      *
289 289
      * Input video pads only.
290
+     *
291
+     * @return >= 0 on success, a negative AVERROR on error.
290 292
      */
291
-    void (*end_frame)(AVFilterLink *link);
293
+    int (*end_frame)(AVFilterLink *link);
292 294
 
293 295
     /**
294 296
      * Slice drawing callback. This is where a filter receives video data
... ...
@@ -98,7 +98,10 @@ static void queue_pop(FifoContext *s)
98 98
     s->root.next = tmp;
99 99
 }
100 100
 
101
-static void end_frame(AVFilterLink *inlink) { }
101
+static int end_frame(AVFilterLink *inlink)
102
+{
103
+    return 0;
104
+}
102 105
 
103 106
 static int draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
104 107
 {
... ...
@@ -98,8 +98,10 @@ struct AVFilterPad {
98 98
      * in the link structure during start_frame().
99 99
      *
100 100
      * Input video pads only.
101
+     *
102
+     * @return >= 0 on success, a negative AVERROR on error.
101 103
      */
102
-    void (*end_frame)(AVFilterLink *link);
104
+    int (*end_frame)(AVFilterLink *link);
103 105
 
104 106
     /**
105 107
      * Slice drawing callback. This is where a filter receives video data
... ...
@@ -90,13 +90,17 @@ static int draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
90 90
     return ret;
91 91
 }
92 92
 
93
-static void end_frame(AVFilterLink *inlink)
93
+static int end_frame(AVFilterLink *inlink)
94 94
 {
95 95
     AVFilterContext *ctx = inlink->dst;
96
-    int i;
96
+    int i, ret = 0;
97 97
 
98
-    for (i = 0; i < ctx->nb_outputs; i++)
99
-        ff_end_frame(ctx->outputs[i]);
98
+    for (i = 0; i < ctx->nb_outputs; i++) {
99
+        ret = ff_end_frame(ctx->outputs[i]);
100
+        if (ret < 0)
101
+            break;
102
+    }
103
+    return ret;
100 104
 }
101 105
 
102 106
 AVFilter avfilter_vf_split = {
... ...
@@ -91,7 +91,7 @@ static int draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
91 91
     return ff_draw_slice(ctx->outputs[0], y, h, slice_dir);
92 92
 }
93 93
 
94
-static void end_frame(AVFilterLink *inlink)
94
+static int end_frame(AVFilterLink *inlink)
95 95
 {
96 96
     AVFilterContext *ctx = inlink->dst;
97 97
     BlackFrameContext *blackframe = ctx->priv;
... ...
@@ -106,7 +106,7 @@ static void end_frame(AVFilterLink *inlink)
106 106
 
107 107
     blackframe->frame++;
108 108
     blackframe->nblack = 0;
109
-    ff_end_frame(inlink->dst->outputs[0]);
109
+    return ff_end_frame(inlink->dst->outputs[0]);
110 110
 }
111 111
 
112 112
 AVFilter avfilter_vf_blackframe = {
... ...
@@ -315,12 +315,12 @@ static int draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
315 315
     return ff_draw_slice(ctx->outputs[0], y - crop->y, h, slice_dir);
316 316
 }
317 317
 
318
-static void end_frame(AVFilterLink *link)
318
+static int end_frame(AVFilterLink *link)
319 319
 {
320 320
     CropContext *crop = link->dst->priv;
321 321
 
322 322
     crop->var_values[VAR_N] += 1.0;
323
-    ff_end_frame(link->dst->outputs[0]);
323
+    return ff_end_frame(link->dst->outputs[0]);
324 324
 }
325 325
 
326 326
 AVFilter avfilter_vf_crop = {
... ...
@@ -114,7 +114,7 @@ static int config_input(AVFilterLink *inlink)
114 114
     return 0;
115 115
 }
116 116
 
117
-static void end_frame(AVFilterLink *inlink)
117
+static int end_frame(AVFilterLink *inlink)
118 118
 {
119 119
     AVFilterContext *ctx = inlink->dst;
120 120
     CropDetectContext *cd = ctx->priv;
... ...
@@ -191,7 +191,7 @@ static void end_frame(AVFilterLink *inlink)
191 191
                w, h, x, y);
192 192
     }
193 193
 
194
-    ff_end_frame(inlink->dst->outputs[0]);
194
+    return ff_end_frame(inlink->dst->outputs[0]);
195 195
 }
196 196
 
197 197
 AVFilter avfilter_vf_cropdetect = {
... ...
@@ -250,7 +250,7 @@ static int null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
250 250
     return 0;
251 251
 }
252 252
 
253
-static void end_frame(AVFilterLink *inlink)
253
+static int end_frame(AVFilterLink *inlink)
254 254
 {
255 255
     DelogoContext *delogo = inlink->dst->priv;
256 256
     AVFilterLink *outlink = inlink->dst->outputs[0];
... ...
@@ -260,6 +260,7 @@ static void end_frame(AVFilterLink *inlink)
260 260
     int hsub0 = av_pix_fmt_descriptors[inlink->format].log2_chroma_w;
261 261
     int vsub0 = av_pix_fmt_descriptors[inlink->format].log2_chroma_h;
262 262
     int plane;
263
+    int ret;
263 264
 
264 265
     for (plane = 0; plane < 4 && inpicref->data[plane]; plane++) {
265 266
         int hsub = plane == 1 || plane == 2 ? hsub0 : 0;
... ...
@@ -274,8 +275,10 @@ static void end_frame(AVFilterLink *inlink)
274 274
                      delogo->show, direct);
275 275
     }
276 276
 
277
-    ff_draw_slice(outlink, 0, inlink->h, 1);
278
-    ff_end_frame(outlink);
277
+    if ((ret = ff_draw_slice(outlink, 0, inlink->h, 1)) < 0 ||
278
+        (ret = ff_end_frame(outlink)) < 0)
279
+        return ret;
280
+    return 0;
279 281
 }
280 282
 
281 283
 AVFilter avfilter_vf_delogo = {
... ...
@@ -860,19 +860,22 @@ static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
860 860
     return ff_start_frame(inlink->dst->outputs[0], buf_out);
861 861
 }
862 862
 
863
-static void end_frame(AVFilterLink *inlink)
863
+static int end_frame(AVFilterLink *inlink)
864 864
 {
865 865
     AVFilterLink *outlink = inlink->dst->outputs[0];
866 866
     AVFilterBufferRef *picref = inlink->cur_buf;
867 867
     DrawTextContext *dtext = inlink->dst->priv;
868
+    int ret;
868 869
 
869 870
     if (dtext->draw)
870 871
         draw_text(inlink->dst, picref, picref->video->w, picref->video->h);
871 872
 
872 873
     dtext->var_values[VAR_N] += 1.0;
873 874
 
874
-    ff_draw_slice(outlink, 0, picref->video->h, 1);
875
-    ff_end_frame(outlink);
875
+    if ((ret = ff_draw_slice(outlink, 0, picref->video->h, 1)) < 0 ||
876
+        (ret = ff_end_frame(outlink)) < 0)
877
+        return ret;
878
+    return 0;
876 879
 }
877 880
 
878 881
 AVFilter avfilter_vf_drawtext = {
... ...
@@ -137,17 +137,20 @@ static int draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
137 137
     return ff_draw_slice(inlink->dst->outputs[0], y, h, slice_dir);
138 138
 }
139 139
 
140
-static void end_frame(AVFilterLink *inlink)
140
+static int end_frame(AVFilterLink *inlink)
141 141
 {
142 142
     FadeContext *fade = inlink->dst->priv;
143
+    int ret;
143 144
 
144
-    ff_end_frame(inlink->dst->outputs[0]);
145
+    ret = ff_end_frame(inlink->dst->outputs[0]);
145 146
 
146 147
     if (fade->frame_index >= fade->start_frame &&
147 148
         fade->frame_index <= fade->stop_frame)
148 149
         fade->factor += fade->fade_per_frame;
149 150
     fade->factor = av_clip_uint16(fade->factor);
150 151
     fade->frame_index++;
152
+
153
+    return ret;
151 154
 }
152 155
 
153 156
 AVFilter avfilter_vf_fade = {
... ...
@@ -163,7 +163,7 @@ static int draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
163 163
     return 0;
164 164
 }
165 165
 
166
-static void end_frame(AVFilterLink *inlink)
166
+static int end_frame(AVFilterLink *inlink)
167 167
 {
168 168
     AVFilterContext   *ctx        = inlink->dst;
169 169
     FieldOrderContext *fieldorder = ctx->priv;
... ...
@@ -227,7 +227,7 @@ static void end_frame(AVFilterLink *inlink)
227 227
                 "not interlaced or field order already correct\n");
228 228
     }
229 229
 
230
-    ff_end_frame(outlink);
230
+    return ff_end_frame(outlink);
231 231
 }
232 232
 
233 233
 AVFilter avfilter_vf_fieldorder = {
... ...
@@ -166,14 +166,14 @@ static int write_to_fifo(AVFifoBuffer *fifo, AVFilterBufferRef *buf)
166 166
     return 0;
167 167
 }
168 168
 
169
-static void end_frame(AVFilterLink *inlink)
169
+static int end_frame(AVFilterLink *inlink)
170 170
 {
171 171
     AVFilterContext    *ctx = inlink->dst;
172 172
     FPSContext           *s = ctx->priv;
173 173
     AVFilterLink   *outlink = ctx->outputs[0];
174 174
     AVFilterBufferRef  *buf = inlink->cur_buf;
175 175
     int64_t delta;
176
-    int i;
176
+    int i, ret;
177 177
 
178 178
     inlink->cur_buf = NULL;
179 179
     s->frames_in++;
... ...
@@ -188,13 +188,12 @@ static void end_frame(AVFilterLink *inlink)
188 188
             avfilter_unref_buffer(buf);
189 189
             s->drop++;
190 190
         }
191
-        return;
191
+        return 0;
192 192
     }
193 193
 
194 194
     /* now wait for the next timestamp */
195 195
     if (buf->pts == AV_NOPTS_VALUE) {
196
-        write_to_fifo(s->fifo, buf);
197
-        return;
196
+        return write_to_fifo(s->fifo, buf);
198 197
     }
199 198
 
200 199
     /* number of output frames */
... ...
@@ -211,10 +210,10 @@ static void end_frame(AVFilterLink *inlink)
211 211
 
212 212
         av_fifo_generic_read(s->fifo, &tmp, sizeof(tmp), NULL);
213 213
         flush_fifo(s->fifo);
214
-        write_to_fifo(s->fifo, tmp);
214
+        ret = write_to_fifo(s->fifo, tmp);
215 215
 
216 216
         avfilter_unref_buffer(buf);
217
-        return;
217
+        return ret;
218 218
     }
219 219
 
220 220
     /* can output >= 1 frames */
... ...
@@ -239,8 +238,10 @@ static void end_frame(AVFilterLink *inlink)
239 239
     }
240 240
     flush_fifo(s->fifo);
241 241
 
242
-    write_to_fifo(s->fifo, buf);
242
+    ret = write_to_fifo(s->fifo, buf);
243 243
     s->pts = s->first_pts + av_rescale_q(s->frames_out, outlink->time_base, inlink->time_base);
244
+
245
+    return ret;
244 246
 }
245 247
 
246 248
 static int null_start_frame(AVFilterLink *link, AVFilterBufferRef *buf)
... ...
@@ -345,18 +345,21 @@ static int null_draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
345 345
     return 0;
346 346
 }
347 347
 
348
-static void end_frame(AVFilterLink *inlink)
348
+static int end_frame(AVFilterLink *inlink)
349 349
 {
350 350
     Frei0rContext *frei0r = inlink->dst->priv;
351 351
     AVFilterLink *outlink = inlink->dst->outputs[0];
352 352
     AVFilterBufferRef  *inpicref =  inlink->cur_buf;
353 353
     AVFilterBufferRef *outpicref = outlink->out_buf;
354
+    int ret;
354 355
 
355 356
     frei0r->update(frei0r->instance, inpicref->pts * av_q2d(inlink->time_base) * 1000,
356 357
                    (const uint32_t *)inpicref->data[0],
357 358
                    (uint32_t *)outpicref->data[0]);
358
-    ff_draw_slice(outlink, 0, outlink->h, 1);
359
-    ff_end_frame(outlink);
359
+    if ((ret = ff_draw_slice(outlink, 0, outlink->h, 1)) ||
360
+        (ret = ff_end_frame(outlink)) < 0)
361
+        return ret;
362
+    return 0;
360 363
 }
361 364
 
362 365
 AVFilter avfilter_vf_frei0r = {
... ...
@@ -215,13 +215,13 @@ static int null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
215 215
     return 0;
216 216
 }
217 217
 
218
-static void end_frame(AVFilterLink *inlink)
218
+static int end_frame(AVFilterLink *inlink)
219 219
 {
220 220
     GradFunContext *gf = inlink->dst->priv;
221 221
     AVFilterBufferRef *inpic = inlink->cur_buf;
222 222
     AVFilterLink *outlink = inlink->dst->outputs[0];
223 223
     AVFilterBufferRef *outpic = outlink->out_buf;
224
-    int p;
224
+    int p, ret;
225 225
 
226 226
     for (p = 0; p < 4 && inpic->data[p]; p++) {
227 227
         int w = inlink->w;
... ...
@@ -239,8 +239,10 @@ static void end_frame(AVFilterLink *inlink)
239 239
             av_image_copy_plane(outpic->data[p], outpic->linesize[p], inpic->data[p], inpic->linesize[p], w, h);
240 240
     }
241 241
 
242
-    ff_draw_slice(outlink, 0, inlink->h, 1);
243
-    ff_end_frame(outlink);
242
+    if ((ret = ff_draw_slice(outlink, 0, inlink->h, 1)) < 0 ||
243
+        (ret = ff_end_frame(outlink)) < 0)
244
+        return ret;
245
+    return 0;
244 246
 }
245 247
 
246 248
 AVFilter avfilter_vf_gradfun = {
... ...
@@ -295,7 +295,7 @@ static int null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
295 295
     return 0;
296 296
 }
297 297
 
298
-static void end_frame(AVFilterLink *inlink)
298
+static int end_frame(AVFilterLink *inlink)
299 299
 {
300 300
     HQDN3DContext *hqdn3d = inlink->dst->priv;
301 301
     AVFilterLink *outlink = inlink->dst->outputs[0];
... ...
@@ -303,6 +303,7 @@ static void end_frame(AVFilterLink *inlink)
303 303
     AVFilterBufferRef *outpic = outlink->out_buf;
304 304
     int cw = inpic->video->w >> hqdn3d->hsub;
305 305
     int ch = inpic->video->h >> hqdn3d->vsub;
306
+    int ret;
306 307
 
307 308
     deNoise(inpic->data[0], outpic->data[0],
308 309
             hqdn3d->Line, &hqdn3d->Frame[0], inpic->video->w, inpic->video->h,
... ...
@@ -323,8 +324,10 @@ static void end_frame(AVFilterLink *inlink)
323 323
             hqdn3d->Coefs[2],
324 324
             hqdn3d->Coefs[3]);
325 325
 
326
-    ff_draw_slice(outlink, 0, inpic->video->h, 1);
327
-    ff_end_frame(outlink);
326
+    if ((ret = ff_draw_slice(outlink, 0, inpic->video->h, 1)) < 0 ||
327
+        (ret = ff_end_frame(outlink)) < 0)
328
+        return ret;
329
+    return 0;
328 330
 }
329 331
 
330 332
 AVFilter avfilter_vf_hqdn3d = {
... ...
@@ -354,7 +354,7 @@ static av_cold void uninit(AVFilterContext *ctx)
354 354
     memset(ocv, 0, sizeof(*ocv));
355 355
 }
356 356
 
357
-static void end_frame(AVFilterLink *inlink)
357
+static int end_frame(AVFilterLink *inlink)
358 358
 {
359 359
     AVFilterContext *ctx = inlink->dst;
360 360
     OCVContext *ocv = ctx->priv;
... ...
@@ -362,14 +362,17 @@ static void end_frame(AVFilterLink *inlink)
362 362
     AVFilterBufferRef *inpicref  = inlink ->cur_buf;
363 363
     AVFilterBufferRef *outpicref = outlink->out_buf;
364 364
     IplImage inimg, outimg;
365
+    int ret;
365 366
 
366 367
     fill_iplimage_from_picref(&inimg , inpicref , inlink->format);
367 368
     fill_iplimage_from_picref(&outimg, outpicref, inlink->format);
368 369
     ocv->end_frame_filter(ctx, &inimg, &outimg);
369 370
     fill_picref_from_iplimage(outpicref, &outimg, inlink->format);
370 371
 
371
-    ff_draw_slice(outlink, 0, outlink->h, 1);
372
-    ff_end_frame(outlink);
372
+    if ((ret = ff_draw_slice(outlink, 0, outlink->h, 1)) < 0 ||
373
+        (ret = ff_end_frame(outlink)) < 0)
374
+        return ret;
375
+    return 0;
373 376
 }
374 377
 
375 378
 AVFilter avfilter_vf_ocv = {
... ...
@@ -337,9 +337,9 @@ static int draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
337 337
     return ff_draw_slice(outlink, y, h, slice_dir);
338 338
 }
339 339
 
340
-static void end_frame(AVFilterLink *inlink)
340
+static int end_frame(AVFilterLink *inlink)
341 341
 {
342
-    ff_end_frame(inlink->dst->outputs[0]);
342
+    return ff_end_frame(inlink->dst->outputs[0]);
343 343
 }
344 344
 
345 345
 static int null_draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
... ...
@@ -347,7 +347,10 @@ static int null_draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
347 347
     return 0;
348 348
 }
349 349
 
350
-static void null_end_frame(AVFilterLink *inlink) { }
350
+static int null_end_frame(AVFilterLink *inlink)
351
+{
352
+    return 0;
353
+}
351 354
 
352 355
 static int poll_frame(AVFilterLink *link)
353 356
 {
... ...
@@ -362,9 +362,9 @@ fail:
362 362
     return ret;
363 363
 }
364 364
 
365
-static void end_frame(AVFilterLink *link)
365
+static int end_frame(AVFilterLink *link)
366 366
 {
367
-    ff_end_frame(link->dst->outputs[0]);
367
+    return ff_end_frame(link->dst->outputs[0]);
368 368
 }
369 369
 
370 370
 static int draw_send_bar_slice(AVFilterLink *link, int y, int h, int slice_dir, int before_slice)
... ...
@@ -258,15 +258,16 @@ static int draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
258 258
     return 0;
259 259
 }
260 260
 
261
-static void end_frame(AVFilterLink *inlink)
261
+static int end_frame(AVFilterLink *inlink)
262 262
 {
263 263
     SelectContext *select = inlink->dst->priv;
264 264
 
265 265
     if (select->select) {
266 266
         if (select->cache_frames)
267
-            return;
268
-        ff_end_frame(inlink->dst->outputs[0]);
267
+            return 0;
268
+        return ff_end_frame(inlink->dst->outputs[0]);
269 269
     }
270
+    return 0;
270 271
 }
271 272
 
272 273
 static int request_frame(AVFilterLink *outlink)
... ...
@@ -40,7 +40,7 @@ static av_cold int init(AVFilterContext *ctx, const char *args)
40 40
     return 0;
41 41
 }
42 42
 
43
-static void end_frame(AVFilterLink *inlink)
43
+static int end_frame(AVFilterLink *inlink)
44 44
 {
45 45
     AVFilterContext *ctx = inlink->dst;
46 46
     ShowInfoContext *showinfo = ctx->priv;
... ...
@@ -76,7 +76,7 @@ static void end_frame(AVFilterLink *inlink)
76 76
            checksum, plane_checksum[0], plane_checksum[1], plane_checksum[2], plane_checksum[3]);
77 77
 
78 78
     showinfo->frame++;
79
-    ff_end_frame(inlink->dst->outputs[0]);
79
+    return ff_end_frame(inlink->dst->outputs[0]);
80 80
 }
81 81
 
82 82
 AVFilter avfilter_vf_showinfo = {
... ...
@@ -138,13 +138,13 @@ static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
138 138
     return ff_start_frame(outlink, avfilter_ref_buffer(outlink->out_buf, ~0));
139 139
 }
140 140
 
141
-static void end_frame(AVFilterLink *inlink)
141
+static int end_frame(AVFilterLink *inlink)
142 142
 {
143 143
     TransContext *trans = inlink->dst->priv;
144 144
     AVFilterBufferRef *inpic  = inlink->cur_buf;
145 145
     AVFilterBufferRef *outpic = inlink->dst->outputs[0]->out_buf;
146 146
     AVFilterLink *outlink = inlink->dst->outputs[0];
147
-    int plane;
147
+    int plane, ret;
148 148
 
149 149
     for (plane = 0; outpic->data[plane]; plane++) {
150 150
         int hsub = plane == 1 || plane == 2 ? trans->hsub : 0;
... ...
@@ -195,8 +195,10 @@ static void end_frame(AVFilterLink *inlink)
195 195
         }
196 196
     }
197 197
 
198
-    ff_draw_slice(outlink, 0, outpic->video->h, 1);
199
-    ff_end_frame(outlink);
198
+    if ((ret = ff_draw_slice(outlink, 0, outpic->video->h, 1)) < 0 ||
199
+        (ret = ff_end_frame(outlink)) < 0)
200
+        return ret;
201
+    return 0;
200 202
 }
201 203
 
202 204
 AVFilter avfilter_vf_transpose = {
... ...
@@ -213,20 +213,23 @@ static av_cold void uninit(AVFilterContext *ctx)
213 213
     free_filter_param(&unsharp->chroma);
214 214
 }
215 215
 
216
-static void end_frame(AVFilterLink *link)
216
+static int end_frame(AVFilterLink *link)
217 217
 {
218 218
     UnsharpContext *unsharp = link->dst->priv;
219 219
     AVFilterBufferRef *in  = link->cur_buf;
220 220
     AVFilterBufferRef *out = link->dst->outputs[0]->out_buf;
221 221
     int cw = SHIFTUP(link->w, unsharp->hsub);
222 222
     int ch = SHIFTUP(link->h, unsharp->vsub);
223
+    int ret;
223 224
 
224 225
     apply_unsharp(out->data[0], out->linesize[0], in->data[0], in->linesize[0], link->w, link->h, &unsharp->luma);
225 226
     apply_unsharp(out->data[1], out->linesize[1], in->data[1], in->linesize[1], cw,      ch,      &unsharp->chroma);
226 227
     apply_unsharp(out->data[2], out->linesize[2], in->data[2], in->linesize[2], cw,      ch,      &unsharp->chroma);
227 228
 
228
-    ff_draw_slice(link->dst->outputs[0], 0, link->h, 1);
229
-    ff_end_frame(link->dst->outputs[0]);
229
+    if ((ret = ff_draw_slice(link->dst->outputs[0], 0, link->h, 1)) < 0 ||
230
+        (ret = ff_end_frame(link->dst->outputs[0])) < 0)
231
+        return ret;
232
+    return 0;
230 233
 }
231 234
 
232 235
 static int draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
... ...
@@ -240,21 +240,23 @@ static int start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
240 240
     return ff_start_frame(ctx->outputs[0], yadif->out);
241 241
 }
242 242
 
243
-static void end_frame(AVFilterLink *link)
243
+static int end_frame(AVFilterLink *link)
244 244
 {
245 245
     AVFilterContext *ctx = link->dst;
246 246
     YADIFContext *yadif = ctx->priv;
247 247
 
248 248
     if (!yadif->out)
249
-        return;
249
+        return 0;
250 250
 
251 251
     if (yadif->auto_enable && !yadif->cur->video->interlaced) {
252
-        ff_draw_slice(ctx->outputs[0], 0, link->h, 1);
253
-        ff_end_frame(ctx->outputs[0]);
254
-        return;
252
+        int ret = ff_draw_slice(ctx->outputs[0], 0, link->h, 1);
253
+        if (ret >= 0)
254
+            ret = ff_end_frame(ctx->outputs[0]);
255
+        return ret;
255 256
     }
256 257
 
257 258
     return_frame(ctx, 0);
259
+    return 0;
258 260
 }
259 261
 
260 262
 static int request_frame(AVFilterLink *link)
... ...
@@ -234,12 +234,12 @@ int ff_start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
234 234
     return ret;
235 235
 }
236 236
 
237
-void ff_null_end_frame(AVFilterLink *link)
237
+int ff_null_end_frame(AVFilterLink *link)
238 238
 {
239
-    ff_end_frame(link->dst->outputs[0]);
239
+    return ff_end_frame(link->dst->outputs[0]);
240 240
 }
241 241
 
242
-static void default_end_frame(AVFilterLink *inlink)
242
+static int default_end_frame(AVFilterLink *inlink)
243 243
 {
244 244
     AVFilterLink *outlink = NULL;
245 245
 
... ...
@@ -247,20 +247,24 @@ static void default_end_frame(AVFilterLink *inlink)
247 247
         outlink = inlink->dst->outputs[0];
248 248
 
249 249
     if (outlink) {
250
-        ff_end_frame(outlink);
250
+        return ff_end_frame(outlink);
251 251
     }
252
+    return 0;
252 253
 }
253 254
 
254
-void ff_end_frame(AVFilterLink *link)
255
+int ff_end_frame(AVFilterLink *link)
255 256
 {
256
-    void (*end_frame)(AVFilterLink *);
257
+    int (*end_frame)(AVFilterLink *);
258
+    int ret;
257 259
 
258 260
     if (!(end_frame = link->dstpad->end_frame))
259 261
         end_frame = default_end_frame;
260 262
 
261
-    end_frame(link);
263
+    ret = end_frame(link);
262 264
 
263 265
     clear_link(link);
266
+
267
+    return ret;
264 268
 }
265 269
 
266 270
 int ff_null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
... ...
@@ -41,7 +41,7 @@ AVFilterBufferRef *ff_get_video_buffer(AVFilterLink *link, int perms,
41 41
 
42 42
 int ff_null_start_frame(AVFilterLink *link, AVFilterBufferRef *picref);
43 43
 int ff_null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir);
44
-void ff_null_end_frame(AVFilterLink *link);
44
+int ff_null_end_frame(AVFilterLink *link);
45 45
 
46 46
 /**
47 47
  * Notify the next filter of the start of a frame.
... ...
@@ -61,8 +61,10 @@ int ff_start_frame(AVFilterLink *link, AVFilterBufferRef *picref);
61 61
  * Notify the next filter that the current frame has finished.
62 62
  *
63 63
  * @param link the output link the frame was sent over
64
+ *
65
+ * @return >= 0 on success, a negative AVERROR on error
64 66
  */
65
-void ff_end_frame(AVFilterLink *link);
67
+int ff_end_frame(AVFilterLink *link);
66 68
 
67 69
 /**
68 70
  * Send a slice to the next filter.
... ...
@@ -24,8 +24,9 @@ static int start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
24 24
     return 0;
25 25
 }
26 26
 
27
-static void end_frame(AVFilterLink *link)
27
+static int end_frame(AVFilterLink *link)
28 28
 {
29
+    return 0;
29 30
 }
30 31
 
31 32
 AVFilter avfilter_vsink_nullsink = {