X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Flib%2Fvideo_filter_graph.cc;h=89467ae94e50746dccd5704f8be099bc78b9e9a2;hb=9063624bd62c8fb513b51077300a74c7e46a56d9;hp=1cc1425202d190f6c5937a16fb4fd29d209bd7a1;hpb=3c29aa6531a4046a8db72dcac81189eb8893233c;p=dcpomatic.git diff --git a/src/lib/video_filter_graph.cc b/src/lib/video_filter_graph.cc index 1cc142520..89467ae94 100644 --- a/src/lib/video_filter_graph.cc +++ b/src/lib/video_filter_graph.cc @@ -20,7 +20,10 @@ #include "compose.hpp" +#include "dcpomatic_assert.h" +#include "exceptions.h" #include "image.h" +#include "scope_guard.h" #include "video_filter_graph.h" extern "C" { #include @@ -48,13 +51,56 @@ VideoFilterGraph::VideoFilterGraph (dcp::Size s, AVPixelFormat p, dcp::Fraction } +list> +VideoFilterGraph::process(shared_ptr image) +{ + if (_copy) { + return { image }; + } + + auto frame = av_frame_alloc(); + if (!frame) { + throw std::bad_alloc(); + } + + ScopeGuard sg = [&frame]() { av_frame_free(&frame); }; + + for (int i = 0; i < image->planes(); ++i) { + frame->data[i] = image->data()[i]; + frame->linesize[i] = image->stride()[i]; + } + + frame->width = image->size().width; + frame->height = image->size().height; + frame->format = image->pixel_format(); + + int r = av_buffersrc_write_frame(_buffer_src_context, frame); + if (r < 0) { + throw DecodeError(String::compose(N_("could not push buffer into filter chain (%1)."), r)); + } + + list> images; + + while (true) { + if (av_buffersink_get_frame(_buffer_sink_context, _frame) < 0) { + break; + } + + images.push_back(make_shared(_frame, Image::Alignment::PADDED)); + av_frame_unref (_frame); + } + + return images; +} + + /** Take an AVFrame and process it using our configured filters, returning a * set of Images. Caller handles memory management of the input frame. */ -list, int64_t>> +list, int64_t>> VideoFilterGraph::process (AVFrame* frame) { - list, int64_t>> images; + list, int64_t>> images; if (_copy) { images.push_back (make_pair(make_shared(frame, Image::Alignment::PADDED), frame->best_effort_timestamp));