Browse code

ffmpeg: restructure sending EOF to filters

Be more careful when an input stream encounters EOF when its filtergraph
has not been configured yet. The current code would immediately mark the
corresponding output streams as finished, while there may still be
buffered frames waiting for frames to appear on other filtergraph
inputs.

This should fix the random FATE failures for complex filtergraph tests
after a3a0230a9870b9018dc7415ae5872784d524cfe5

This merges Libav commit 94ebf55. It was previously skipped.

This is the last filter init related Libav commit that was skipped, so
this also removes the commits from doc/libav-merge.txt.

Signed-off-by: wm4 <nfxjfg@googlemail.com>

Anton Khirnov authored on 2016/06/28 02:03:42
Showing 4 changed files
... ...
@@ -95,7 +95,6 @@ Stuff that didn't reach the codebase:
95 95
   - 0cef06df0 checkasm: add HEVC MC tests
96 96
   - e7078e842 hevcdsp: add x86 SIMD for MC
97 97
 - QSV scaling filter (62c58c5)
98
-- ffmpeg.c filter init decoupling (3e265ca,a3a0230,d2e56cf,94ebf55)
99 98
 
100 99
 Collateral damage that needs work locally:
101 100
 ------------------------------------------
... ...
@@ -2197,6 +2197,34 @@ static int ifilter_send_frame(InputFilter *ifilter, AVFrame *frame)
2197 2197
     return 0;
2198 2198
 }
2199 2199
 
2200
+static int ifilter_send_eof(InputFilter *ifilter)
2201
+{
2202
+    int i, j, ret;
2203
+
2204
+    ifilter->eof = 1;
2205
+
2206
+    if (ifilter->filter) {
2207
+        ret = av_buffersrc_add_frame_flags(ifilter->filter, NULL, AV_BUFFERSRC_FLAG_PUSH);
2208
+        if (ret < 0)
2209
+            return ret;
2210
+    } else {
2211
+        // the filtergraph was never configured
2212
+        FilterGraph *fg = ifilter->graph;
2213
+        for (i = 0; i < fg->nb_inputs; i++)
2214
+            if (!fg->inputs[i]->eof)
2215
+                break;
2216
+        if (i == fg->nb_inputs) {
2217
+            // All the input streams have finished without the filtergraph
2218
+            // ever being configured.
2219
+            // Mark the output streams as finished.
2220
+            for (j = 0; j < fg->nb_outputs; j++)
2221
+                finish_output_stream(fg->outputs[j]->ost);
2222
+        }
2223
+    }
2224
+
2225
+    return 0;
2226
+}
2227
+
2200 2228
 // This does not quite work like avcodec_decode_audio4/avcodec_decode_video2.
2201 2229
 // There is the following difference: if you got a frame, you must call
2202 2230
 // it again with pkt=NULL. pkt==NULL is treated differently from pkt.size==0
... ...
@@ -2498,18 +2526,11 @@ out:
2498 2498
 
2499 2499
 static int send_filter_eof(InputStream *ist)
2500 2500
 {
2501
-    int i, j, ret;
2501
+    int i, ret;
2502 2502
     for (i = 0; i < ist->nb_filters; i++) {
2503
-        if (ist->filters[i]->filter) {
2504
-            ret = av_buffersrc_add_frame(ist->filters[i]->filter, NULL);
2505
-            if (ret < 0)
2506
-                return ret;
2507
-        } else {
2508
-            // the filtergraph was never configured
2509
-            FilterGraph *fg = ist->filters[i]->graph;
2510
-            for (j = 0; j < fg->nb_outputs; j++)
2511
-                finish_output_stream(fg->outputs[j]->ost);
2512
-        }
2503
+        ret = ifilter_send_eof(ist->filters[i]);
2504
+        if (ret < 0)
2505
+            return ret;
2513 2506
     }
2514 2507
     return 0;
2515 2508
 }
... ...
@@ -248,6 +248,8 @@ typedef struct InputFilter {
248 248
     uint64_t channel_layout;
249 249
 
250 250
     AVBufferRef *hw_frames_ctx;
251
+
252
+    int eof;
251 253
 } InputFilter;
252 254
 
253 255
 typedef struct OutputFilter {
... ...
@@ -1128,6 +1128,15 @@ int configure_filtergraph(FilterGraph *fg)
1128 1128
         }
1129 1129
     }
1130 1130
 
1131
+    /* send the EOFs for the finished inputs */
1132
+    for (i = 0; i < fg->nb_inputs; i++) {
1133
+        if (fg->inputs[i]->eof) {
1134
+            ret = av_buffersrc_add_frame(fg->inputs[i]->filter, NULL);
1135
+            if (ret < 0)
1136
+                return ret;
1137
+        }
1138
+    }
1139
+
1131 1140
     return 0;
1132 1141
 }
1133 1142