Browse code

lavfi: replace link.closed by link.status.

The status field can carry any error code instead of just EOF.
Also only update it through a wrapper function and provide a timestamp.
Update the few filters that used it directly.

Nicolas George authored on 2015/09/24 17:07:42
Showing 8 changed files
... ...
@@ -178,9 +178,20 @@ int avfilter_link_get_channels(AVFilterLink *link)
178 178
     return link->channels;
179 179
 }
180 180
 
181
+void ff_avfilter_link_set_in_status(AVFilterLink *link, int status, int64_t pts)
182
+{
183
+    ff_avfilter_link_set_out_status(link, status, pts);
184
+}
185
+
186
+void ff_avfilter_link_set_out_status(AVFilterLink *link, int status, int64_t pts)
187
+{
188
+    link->status = status;
189
+    ff_update_link_current_pts(link, pts);
190
+}
191
+
181 192
 void avfilter_link_set_closed(AVFilterLink *link, int closed)
182 193
 {
183
-    link->closed = closed;
194
+    ff_avfilter_link_set_out_status(link, closed ? AVERROR_EOF : 0, AV_NOPTS_VALUE);
184 195
 }
185 196
 
186 197
 int avfilter_insert_filter(AVFilterLink *link, AVFilterContext *filt,
... ...
@@ -346,8 +357,8 @@ int ff_request_frame(AVFilterLink *link)
346 346
     int ret = -1;
347 347
     FF_TPRINTF_START(NULL, request_frame); ff_tlog_link(NULL, link, 1);
348 348
 
349
-    if (link->closed)
350
-        return AVERROR_EOF;
349
+    if (link->status)
350
+        return link->status;
351 351
     if (link->srcpad->request_frame)
352 352
         ret = link->srcpad->request_frame(link);
353 353
     else if (link->src->inputs[0])
... ...
@@ -358,8 +369,8 @@ int ff_request_frame(AVFilterLink *link)
358 358
         ret = ff_filter_frame_framed(link, pbuf);
359 359
     }
360 360
     if (ret < 0) {
361
-        if (ret == AVERROR_EOF)
362
-            link->closed = 1;
361
+        if (ret != AVERROR(EAGAIN) && ret != link->status)
362
+            ff_avfilter_link_set_in_status(link, ret, AV_NOPTS_VALUE);
363 363
     }
364 364
     return ret;
365 365
 }
... ...
@@ -1005,9 +1016,9 @@ static int ff_filter_frame_framed(AVFilterLink *link, AVFrame *frame)
1005 1005
     AVFilterCommand *cmd= link->dst->command_queue;
1006 1006
     int64_t pts;
1007 1007
 
1008
-    if (link->closed) {
1008
+    if (link->status) {
1009 1009
         av_frame_free(&frame);
1010
-        return AVERROR_EOF;
1010
+        return link->status;
1011 1011
     }
1012 1012
 
1013 1013
     if (!(filter_frame = dst->filter_frame))
... ...
@@ -490,16 +490,16 @@ struct AVFilterLink {
490 490
     int max_samples;
491 491
 
492 492
     /**
493
-     * True if the link is closed.
494
-     * If set, all attempts of start_frame, filter_frame or request_frame
495
-     * will fail with AVERROR_EOF, and if necessary the reference will be
496
-     * destroyed.
497
-     * If request_frame returns AVERROR_EOF, this flag is set on the
493
+     * Link status.
494
+     * If not zero, all attempts of start_frame, filter_frame or request_frame
495
+     * will fail with the corresponding code, and if necessary the reference
496
+     * will be destroyed.
497
+     * If request_frame returns an error, the status is set on the
498 498
      * corresponding link.
499 499
      * It can be set also be set by either the source or the destination
500 500
      * filter.
501 501
      */
502
-    int closed;
502
+    int status;
503 503
 
504 504
     /**
505 505
      * Number of channels.
... ...
@@ -134,8 +134,8 @@ int attribute_align_arg av_buffersink_get_frame_flags(AVFilterContext *ctx, AVFr
134 134
 
135 135
     /* no picref available, fetch it from the filterchain */
136 136
     while (!av_fifo_size(buf->fifo)) {
137
-        if (inlink->closed)
138
-            return AVERROR_EOF;
137
+        if (inlink->status)
138
+            return inlink->status;
139 139
         if (flags & AV_BUFFERSINK_FLAG_NO_REQUEST)
140 140
             return AVERROR(EAGAIN);
141 141
         if ((ret = ff_request_frame(inlink)) < 0)
... ...
@@ -59,7 +59,7 @@ inline static int push_frame(AVFilterContext *ctx)
59 59
     for (i = 0; i < ctx->nb_inputs; i++) {
60 60
         struct FFBufQueue *q = &s->queues[i];
61 61
 
62
-        if (!q->available && !ctx->inputs[i]->closed)
62
+        if (!q->available && !ctx->inputs[i]->status)
63 63
             return 0;
64 64
         if (q->available) {
65 65
             frame = ff_bufqueue_peek(q, 0);
... ...
@@ -190,7 +190,7 @@ static int request_frame(AVFilterLink *outlink)
190 190
     int i, ret;
191 191
 
192 192
     for (i = 0; i < ctx->nb_inputs; i++) {
193
-        if (!s->queues[i].available && !ctx->inputs[i]->closed) {
193
+        if (!s->queues[i].available && !ctx->inputs[i]->status) {
194 194
             ret = ff_request_frame(ctx->inputs[i]);
195 195
             if (ret != AVERROR_EOF)
196 196
                 return ret;
... ...
@@ -226,6 +226,21 @@ int ff_parse_channel_layout(int64_t *ret, int *nret, const char *arg,
226 226
 
227 227
 void ff_update_link_current_pts(AVFilterLink *link, int64_t pts);
228 228
 
229
+/**
230
+ * Set the status field of a link from the source filter.
231
+ * The pts should reflect the timestamp of the status change,
232
+ * in link time base and relative to the frames timeline.
233
+ * In particular, for AVERROR_EOF, it should reflect the
234
+ * end time of the last frame.
235
+ */
236
+void ff_avfilter_link_set_in_status(AVFilterLink *link, int status, int64_t pts);
237
+
238
+/**
239
+ * Set the status field of a link from the destination filter.
240
+ * The pts should probably be left unset (AV_NOPTS_VALUE).
241
+ */
242
+void ff_avfilter_link_set_out_status(AVFilterLink *link, int status, int64_t pts);
243
+
229 244
 void ff_command_queue_pop(AVFilterContext *filter);
230 245
 
231 246
 /* misc trace functions */
... ...
@@ -77,7 +77,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
77 77
     for (i = 0; i < ctx->nb_outputs; i++) {
78 78
         AVFrame *buf_out;
79 79
 
80
-        if (ctx->outputs[i]->closed)
80
+        if (ctx->outputs[i]->status)
81 81
             continue;
82 82
         buf_out = av_frame_clone(frame);
83 83
         if (!buf_out) {
... ...
@@ -174,7 +174,8 @@ static int trim_filter_frame(AVFilterLink *inlink, AVFrame *frame)
174 174
             drop = 0;
175 175
 
176 176
         if (drop) {
177
-            s->eof = inlink->closed = 1;
177
+            s->eof = 1;
178
+            ff_avfilter_link_set_out_status(inlink, AVERROR_EOF, AV_NOPTS_VALUE);
178 179
             goto drop;
179 180
         }
180 181
     }
... ...
@@ -305,7 +306,8 @@ static int atrim_filter_frame(AVFilterLink *inlink, AVFrame *frame)
305 305
         }
306 306
 
307 307
         if (drop) {
308
-            s->eof = inlink->closed = 1;
308
+            s->eof = 1;
309
+            ff_avfilter_link_set_out_status(inlink, AVERROR_EOF, AV_NOPTS_VALUE);
309 310
             goto drop;
310 311
         }
311 312
     }
... ...
@@ -219,7 +219,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
219 219
         const int idx = s->map[i];
220 220
         AVFrame *out;
221 221
 
222
-        if (outlink->closed)
222
+        if (outlink->status)
223 223
             continue;
224 224
 
225 225
         out = ff_get_video_buffer(outlink, outlink->w, outlink->h);