You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-08-15 14:13:16 +02:00
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.
This commit is contained in:
45
ffmpeg.c
45
ffmpeg.c
@@ -2047,8 +2047,12 @@ static int poll_filters(void)
|
|||||||
{
|
{
|
||||||
AVFilterBufferRef *picref;
|
AVFilterBufferRef *picref;
|
||||||
AVFrame *filtered_frame = NULL;
|
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++) {
|
for (i = 0; i < nb_output_streams; i++) {
|
||||||
OutputStream *ost = output_streams[i];
|
OutputStream *ost = output_streams[i];
|
||||||
OutputFile *of = output_files[ost->file_index];
|
OutputFile *of = output_files[ost->file_index];
|
||||||
@@ -2062,13 +2066,18 @@ static int poll_filters(void)
|
|||||||
avcodec_get_frame_defaults(ost->filtered_frame);
|
avcodec_get_frame_defaults(ost->filtered_frame);
|
||||||
filtered_frame = 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;
|
AVRational ist_pts_tb = ost->filter->filter->inputs[0]->time_base;
|
||||||
if ((ret = av_buffersink_get_buffer_ref(ost->filter->filter,
|
ret = av_buffersink_get_buffer_ref(ost->filter->filter, &picref,
|
||||||
&picref,
|
AV_BUFFERSINK_FLAG_NO_REQUEST);
|
||||||
0)) < 0) {
|
if (ret < 0) {
|
||||||
av_log(NULL, AV_LOG_WARNING, "AV Filter told us it has a frame available but failed to output one\n");
|
if (ret != AVERROR(EAGAIN)) {
|
||||||
return ret;
|
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);
|
filtered_frame->pts = av_rescale_q(picref->pts, ist_pts_tb, AV_TIME_BASE_Q);
|
||||||
// if (ost->source_index >= 0)
|
// if (ost->source_index >= 0)
|
||||||
@@ -2095,7 +2104,27 @@ static int poll_filters(void)
|
|||||||
avfilter_unref_buffer(picref);
|
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)
|
static void print_report(int is_last_report, int64_t timer_start, int64_t cur_time)
|
||||||
|
Reference in New Issue
Block a user