X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Flib%2Fvideo_filter_graph.cc;h=89467ae94e50746dccd5704f8be099bc78b9e9a2;hb=9063624bd62c8fb513b51077300a74c7e46a56d9;hp=a61da6773bbb8517330895aa2a8b01eae3e39c76;hpb=1516214cdc7970797b79bca06b46a2eed16a1da3;p=dcpomatic.git diff --git a/src/lib/video_filter_graph.cc b/src/lib/video_filter_graph.cc index a61da6773..89467ae94 100644 --- a/src/lib/video_filter_graph.cc +++ b/src/lib/video_filter_graph.cc @@ -20,9 +20,11 @@ #include "compose.hpp" +#include "dcpomatic_assert.h" +#include "exceptions.h" #include "image.h" +#include "scope_guard.h" #include "video_filter_graph.h" -#include "warnings.h" extern "C" { #include #include @@ -38,7 +40,6 @@ using std::make_shared; using std::pair; using std::shared_ptr; using std::string; -using std::vector; VideoFilterGraph::VideoFilterGraph (dcp::Size s, AVPixelFormat p, dcp::Fraction r) @@ -50,16 +51,59 @@ 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), frame->best_effort_timestamp)); + images.push_back (make_pair(make_shared(frame, Image::Alignment::PADDED), frame->best_effort_timestamp)); } else { int r = av_buffersrc_write_frame (_buffer_src_context, frame); if (r < 0) { @@ -71,7 +115,7 @@ VideoFilterGraph::process (AVFrame* frame) break; } - images.push_back (make_pair(make_shared(_frame), frame->best_effort_timestamp)); + images.push_back (make_pair(make_shared(_frame, Image::Alignment::PADDED), frame->best_effort_timestamp)); av_frame_unref (_frame); } }