aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolas George <nicolas.george@normalesup.org>2012-04-19 18:44:55 +0200
committerNicolas George <nicolas.george@normalesup.org>2012-04-23 14:14:25 +0200
commit99f29108d31b9e6fc9687a7401446097b31e9131 (patch)
tree4d44fd269a353a04614809fc47439fb87996e937
parente11110dee40837b766921855221968e1541230d3 (diff)
downloadffmpeg-99f29108d31b9e6fc9687a7401446097b31e9131.tar.gz
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.
-rw-r--r--ffmpeg.c45
1 files changed, 37 insertions, 8 deletions
diff --git a/ffmpeg.c b/ffmpeg.c
index d22378f354..d1ed3c67de 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)