diff options
author | Nicolas George <nicolas.george@normalesup.org> | 2012-04-19 18:44:55 +0200 |
---|---|---|
committer | Nicolas George <nicolas.george@normalesup.org> | 2012-04-23 14:14:25 +0200 |
commit | 99f29108d31b9e6fc9687a7401446097b31e9131 (patch) | |
tree | 4d44fd269a353a04614809fc47439fb87996e937 | |
parent | e11110dee40837b766921855221968e1541230d3 (diff) | |
download | ffmpeg-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.c | 45 |
1 files changed, 37 insertions, 8 deletions
@@ -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) |