[FFmpeg-cvslog] ffmpeg: directly request frames from filters.

Nicolas George git at videolan.org
Mon Apr 23 14:30:40 CEST 2012


ffmpeg | branch: master | Nicolas George <nicolas.george at normalesup.org> | Thu Apr 19 18:44:55 2012 +0200| [99f29108d31b9e6fc9687a7401446097b31e9131] | committer: Nicolas George

ffmpeg: directly request frames from filters.

It allows ffmpeg filtering logic to work with filters
that do not implement the poll_frame method,
such as split or tile.

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=99f29108d31b9e6fc9687a7401446097b31e9131
---

 ffmpeg.c |   45 +++++++++++++++++++++++++++++++++++++--------
 1 files changed, 37 insertions(+), 8 deletions(-)

diff --git a/ffmpeg.c b/ffmpeg.c
index d22378f..d1ed3c6 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -2047,8 +2047,12 @@ static int poll_filters(void)
 {
     AVFilterBufferRef *picref;
     AVFrame *filtered_frame = NULL;
-    int i, ret;
+    int i, ret, ret_all;
+    unsigned nb_success, nb_eof;
 
+    while (1) {
+        /* Reap all buffers present in the buffer sinks */
+        /* TODO reindent */
     for (i = 0; i < nb_output_streams; i++) {
         OutputStream *ost = output_streams[i];
         OutputFile    *of = output_files[ost->file_index];
@@ -2062,13 +2066,18 @@ static int poll_filters(void)
             avcodec_get_frame_defaults(ost->filtered_frame);
         filtered_frame = ost->filtered_frame;
 
-        while (avfilter_poll_frame(ost->filter->filter->inputs[0])) {
+        while (1) {
             AVRational ist_pts_tb = ost->filter->filter->inputs[0]->time_base;
-            if ((ret = av_buffersink_get_buffer_ref(ost->filter->filter,
-                                                            &picref,
-                                                            0)) < 0) {
-                av_log(NULL, AV_LOG_WARNING, "AV Filter told us it has a frame available but failed to output one\n");
-                return ret;
+            ret = av_buffersink_get_buffer_ref(ost->filter->filter, &picref,
+                                               AV_BUFFERSINK_FLAG_NO_REQUEST);
+            if (ret < 0) {
+                if (ret != AVERROR(EAGAIN)) {
+                    char buf[256];
+                    av_strerror(ret, buf, sizeof(buf));
+                    av_log(NULL, AV_LOG_WARNING,
+                           "Error in av_buffersink_get_buffer_ref(): %s\n", buf);
+                }
+                break;
             }
             filtered_frame->pts = av_rescale_q(picref->pts, ist_pts_tb, AV_TIME_BASE_Q);
 //             if (ost->source_index >= 0)
@@ -2095,7 +2104,27 @@ static int poll_filters(void)
             avfilter_unref_buffer(picref);
         }
     }
-    return 0;
+        /* Request frames through all the graphs */
+        ret_all = nb_success = nb_eof = 0;
+        for (i = 0; i < nb_filtergraphs; i++) {
+            ret = avfilter_graph_request_oldest(filtergraphs[i]->graph);
+            if (!ret) {
+                nb_success++;
+            } else if (ret == AVERROR_EOF) {
+                nb_eof++;
+            } else if (ret != AVERROR(EAGAIN)) {
+                char buf[256];
+                av_strerror(ret, buf, sizeof(buf));
+                av_log(NULL, AV_LOG_WARNING,
+                       "Error in request_frame(): %s\n", buf);
+                ret_all = ret;
+            }
+        }
+        if (!nb_success)
+            break;
+        /* Try again if anything succeeded */
+    }
+    return nb_eof == nb_filtergraphs ? AVERROR_EOF : ret_all;
 }
 
 static void print_report(int is_last_report, int64_t timer_start, int64_t cur_time)



More information about the ffmpeg-cvslog mailing list