[Libav-user] How to get the last frame from a filter graph?
Tobias Rapp
t.rapp at noa-archive.com
Tue Jan 23 10:48:16 EET 2018
On 23.01.2018 09:12, Corey Taylor wrote:
> On Tue, Jan 23, 2018 at 2:04 AM, Tobias Rapp <t.rapp at noa-archive.com> wrote:
>> Hi,
>>
>> in my application I have problems getting the last frame out of a filter
>> graph when the filter chain includes the yadif filter. The application is
>> based on the filtering_video.c example and I can reproduce it when adding
>> the yadif filter there (see attached file).
>>
>> How can I make sure to always get all the frames out of a filter graph?
>
>
> You can call av_buffersrc_add_frame_flags with NULL for the frame
> which will signal the end of stream.
>
> Then you can loop through av_buffersink_get_frame until it returns
> AVERROR_EOF (or any error).
>
> The loop would typically be:
>
> 1. Call av_buffersink_get_frame
> 2. If no error, process frame
> 3. if AVERROR_EOF, end your stream
I added a loop to drain the filtergraph (see attached diff) and indeed
it worked. Maybe I will post a patch to update the upstream example.
> avcodec_send_frame will do the same with a NULL for the frame to
> trigger flushing the codec the same as the filter graph.
Good to know. Thanks a lot for the help!
Regards,
Tobias
-------------- next part --------------
diff --git a/doc/examples/filtering_video.c b/doc/examples/filtering_video.c
index 3fd6d5b..4f43ecd 100644
--- a/doc/examples/filtering_video.c
+++ b/doc/examples/filtering_video.c
@@ -278,6 +278,25 @@ int main(int argc, char **argv)
}
av_packet_unref(&packet);
}
+ if (ret == AVERROR_EOF) {
+ /* signal EOF to the filtergraph */
+ if (av_buffersrc_add_frame_flags(buffersrc_ctx, NULL, AV_BUFFERSRC_FLAG_KEEP_REF) < 0) {
+ av_log(NULL, AV_LOG_ERROR, "Error while feeding the filtergraph\n");
+ goto end;
+ }
+
+ /* pull remaining frames from the filtergraph */
+ while (1) {
+ ret = av_buffersink_get_frame(buffersink_ctx, filt_frame);
+ if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
+ break;
+ if (ret < 0)
+ goto end;
+ display_frame(filt_frame, buffersink_ctx->inputs[0]->time_base);
+ frame_count++;
+ av_frame_unref(filt_frame);
+ }
+ }
av_log(NULL, AV_LOG_INFO, "Processed %d frames\n", frame_count);
end:
More information about the Libav-user
mailing list