X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Flib%2Fffmpeg_image_proxy.cc;h=2fcd486dfafc72daa641f0a7c50e6c891c8c9d01;hb=cb330f076f72000d028b11e88702addb0a2ab480;hp=54fb1c46837012485d3a93dbdd37ae3e71ceeecc;hpb=5523c5b7c0572616d9d76786d0140e6f7f3e7174;p=dcpomatic.git diff --git a/src/lib/ffmpeg_image_proxy.cc b/src/lib/ffmpeg_image_proxy.cc index 54fb1c468..2fcd486df 100644 --- a/src/lib/ffmpeg_image_proxy.cc +++ b/src/lib/ffmpeg_image_proxy.cc @@ -21,21 +21,23 @@ #include "compose.hpp" #include "cross.h" +#include "dcpomatic_assert.h" #include "dcpomatic_socket.h" #include "exceptions.h" #include "ffmpeg_image_proxy.h" #include "image.h" -#include "util.h" -#include "warnings.h" +#include "memory_util.h" +#include "video_filter_graph.h" #include -DCPOMATIC_DISABLE_WARNINGS +#include +LIBDCP_DISABLE_WARNINGS extern "C" { #include #include #include } #include -DCPOMATIC_ENABLE_WARNINGS +LIBDCP_ENABLE_WARNINGS #include #include "i18n.h" @@ -122,7 +124,7 @@ FFmpegImageProxy::avio_seek (int64_t const pos, int whence) ImageProxy::Result -FFmpegImageProxy::image (optional) const +FFmpegImageProxy::image (Image::Alignment alignment, optional) const { auto constexpr name_for_errors = "FFmpegImageProxy::image"; @@ -133,11 +135,11 @@ FFmpegImageProxy::image (optional) const } uint8_t* avio_buffer = static_cast (wrapped_av_malloc(4096)); - AVIOContext* avio_context = avio_alloc_context (avio_buffer, 4096, 0, const_cast(this), avio_read_wrapper, 0, avio_seek_wrapper); + auto avio_context = avio_alloc_context (avio_buffer, 4096, 0, const_cast(this), avio_read_wrapper, 0, avio_seek_wrapper); AVFormatContext* format_context = avformat_alloc_context (); format_context->pb = avio_context; - AVDictionary* options = 0; + AVDictionary* options = nullptr; /* These durations are in microseconds, and represent how far into the content file we will look for streams. */ @@ -150,7 +152,7 @@ FFmpegImageProxy::image (optional) const directly from the file). This code just does enough to allow the probe code to take a hint from "foo.tga" and so try targa format. */ - AVInputFormat* f = av_find_input_format ("image2"); + auto f = av_find_input_format ("image2"); format_context = avformat_alloc_context (); format_context->pb = avio_context; format_context->iformat = f; @@ -171,7 +173,7 @@ FFmpegImageProxy::image (optional) const DCPOMATIC_ASSERT (format_context->nb_streams == 1); - AVFrame* frame = av_frame_alloc (); + auto frame = av_frame_alloc (); if (!frame) { std::bad_alloc (); } @@ -205,7 +207,20 @@ FFmpegImageProxy::image (optional) const throw DecodeError (N_("avcodec_receive_frame"), name_for_errors, r, *_path); } - _image = make_shared(frame); + if (av_pix_fmt_desc_get(context->pix_fmt)->flags & AV_PIX_FMT_FLAG_ALPHA) { + /* XXX: this repeated setup of a the filter graph could be really slow + * (haven't measured it though). + */ + VideoFilterGraph graph(dcp::Size(frame->width, frame->height), context->pix_fmt, dcp::Fraction(24, 1)); + auto filter = Filter::from_id("premultiply"); + DCPOMATIC_ASSERT(filter); + graph.setup({*filter}); + auto images = graph.process(frame); + DCPOMATIC_ASSERT(images.size() == 1); + _image = images.front().first; + } else { + _image = make_shared(frame, alignment); + } av_packet_unref (&packet); av_frame_free (&frame);