Merge remote-tracking branch 'origin/main' into v2.17.x
[dcpomatic.git] / src / lib / ffmpeg_content.cc
index 515b58cd0fbaa82eac39ec95d2194525b2f39406..c80bdec69fef072cc2aa07f48e88a48aec73004b 100644 (file)
 
 */
 
-#include "ffmpeg_content.h"
-#include "video_content.h"
 #include "audio_content.h"
-#include "ffmpeg_examiner.h"
-#include "ffmpeg_subtitle_stream.h"
-#include "ffmpeg_audio_stream.h"
 #include "compose.hpp"
-#include "job.h"
-#include "util.h"
-#include "filter.h"
-#include "film.h"
-#include "log.h"
 #include "config.h"
+#include "constants.h"
 #include "exceptions.h"
+#include "ffmpeg_audio_stream.h"
+#include "ffmpeg_content.h"
+#include "ffmpeg_examiner.h"
+#include "ffmpeg_subtitle_stream.h"
+#include "film.h"
+#include "filter.h"
 #include "frame_rate_change.h"
+#include "job.h"
+#include "log.h"
 #include "text_content.h"
+#include "video_content.h"
 #include <dcp/raw_convert.h>
 #include <libcxml/cxml.h>
 extern "C" {
@@ -115,9 +115,8 @@ FFmpegContent::FFmpegContent (cxml::ConstNodePtr node, int version, list<string>
        }
 
        for (auto i: node->node_children("Filter")) {
-               Filter const * f = Filter::from_id(i->content());
-               if (f) {
-                       _filters.push_back (f);
+               if (auto filter = Filter::from_id(i->content())) {
+                       _filters.push_back(*filter);
                } else {
                        notes.push_back (String::compose (_("DCP-o-matic no longer supports the `%1' filter, so it has been turned off."), i->content()));
                }
@@ -198,61 +197,61 @@ FFmpegContent::FFmpegContent (vector<shared_ptr<Content>> c)
 
 
 void
-FFmpegContent::as_xml (xmlpp::Node* node, bool with_paths) const
+FFmpegContent::as_xml(xmlpp::Element* element, bool with_paths) const
 {
-       node->add_child("Type")->add_child_text("FFmpeg");
-       Content::as_xml (node, with_paths);
+       cxml::add_text_child(element, "Type", "FFmpeg");
+       Content::as_xml(element, with_paths);
 
        if (video) {
-               video->as_xml (node);
+               video->as_xml(element);
        }
 
        if (audio) {
-               audio->as_xml (node);
+               audio->as_xml(element);
 
                for (auto i: audio->streams()) {
                        auto f = dynamic_pointer_cast<FFmpegAudioStream> (i);
                        DCPOMATIC_ASSERT (f);
-                       f->as_xml (node->add_child("AudioStream"));
+                       f->as_xml(cxml::add_child(element, "AudioStream"));
                }
        }
 
        if (only_text()) {
-               only_text()->as_xml (node);
+               only_text()->as_xml(element);
        }
 
        boost::mutex::scoped_lock lm (_mutex);
 
        for (auto i: _subtitle_streams) {
-               auto t = node->add_child("SubtitleStream");
+               auto t = cxml::add_child(element, "SubtitleStream");
                if (_subtitle_stream && i == _subtitle_stream) {
-                       t->add_child("Selected")->add_child_text("1");
+                       cxml::add_text_child(t, "Selected", "1");
                }
                i->as_xml (t);
        }
 
        for (auto i: _filters) {
-               node->add_child("Filter")->add_child_text(i->id());
+               cxml::add_text_child(element, "Filter", i.id());
        }
 
        if (_first_video) {
-               node->add_child("FirstVideo")->add_child_text(raw_convert<string>(_first_video.get().get()));
+               cxml::add_text_child(element, "FirstVideo", raw_convert<string>(_first_video.get().get()));
        }
 
        if (_color_range) {
-               node->add_child("ColorRange")->add_child_text(raw_convert<string>(static_cast<int>(*_color_range)));
+               cxml::add_text_child(element, "ColorRange", raw_convert<string>(static_cast<int>(*_color_range)));
        }
        if (_color_primaries) {
-               node->add_child("ColorPrimaries")->add_child_text(raw_convert<string>(static_cast<int>(*_color_primaries)));
+               cxml::add_text_child(element, "ColorPrimaries", raw_convert<string>(static_cast<int>(*_color_primaries)));
        }
        if (_color_trc) {
-               node->add_child("ColorTransferCharacteristic")->add_child_text(raw_convert<string>(static_cast<int>(*_color_trc)));
+               cxml::add_text_child(element, "ColorTransferCharacteristic", raw_convert<string>(static_cast<int>(*_color_trc)));
        }
        if (_colorspace) {
-               node->add_child("Colorspace")->add_child_text(raw_convert<string>(static_cast<int>(*_colorspace)));
+               cxml::add_text_child(element, "Colorspace", raw_convert<string>(static_cast<int>(*_colorspace)));
        }
        if (_bits_per_pixel) {
-               node->add_child("BitsPerPixel")->add_child_text(raw_convert<string>(*_bits_per_pixel));
+               cxml::add_text_child(element, "BitsPerPixel", raw_convert<string>(*_bits_per_pixel));
        }
 }
 
@@ -292,14 +291,19 @@ FFmpegContent::examine (shared_ptr<const Film> film, shared_ptr<Job> job)
                        if (examiner->rotation()) {
                                auto rot = *examiner->rotation ();
                                if (fabs (rot - 180) < 1.0) {
-                                       _filters.push_back (Filter::from_id ("vflip"));
-                                       _filters.push_back (Filter::from_id ("hflip"));
+                                       _filters.push_back(*Filter::from_id("vflip"));
+                                       _filters.push_back(*Filter::from_id("hflip"));
                                } else if (fabs (rot - 90) < 1.0) {
-                                       _filters.push_back (Filter::from_id ("90clock"));
+                                       _filters.push_back(*Filter::from_id("90clock"));
+                                       video->rotate_size();
                                } else if (fabs (rot - 270) < 1.0) {
-                                       _filters.push_back (Filter::from_id ("90anticlock"));
+                                       _filters.push_back(*Filter::from_id("90anticlock"));
+                                       video->rotate_size();
                                }
                        }
+                       if (examiner->has_alpha()) {
+                               _filters.push_back(*Filter::from_id("premultiply"));
+                       }
                }
 
                if (!examiner->audio_streams().empty()) {
@@ -455,7 +459,7 @@ FFmpegContent::approximate_length () const
 
 
 void
-FFmpegContent::set_filters (vector<Filter const *> const & filters)
+FFmpegContent::set_filters(vector<Filter> const& filters)
 {
        ContentChangeSignaller cc (this, FFmpegContentProperty::FILTERS);
 
@@ -486,7 +490,7 @@ FFmpegContent::identifier () const
        }
 
        for (auto i: _filters) {
-               s += "_" + i->id();
+               s += "_" + i.id();
        }
 
        return s;
@@ -519,7 +523,7 @@ FFmpegContent::set_default_colour_conversion ()
                video->set_colour_conversion (PresetColourConversion::from_id ("rec2020").conversion);
                break;
        default:
-               if (s.width < 1080) {
+               if (s && s->width < 1080) {
                        video->set_colour_conversion (PresetColourConversion::from_id ("rec601").conversion);
                } else {
                        video->set_colour_conversion (PresetColourConversion::from_id ("rec709").conversion);