Add PixelQuanta to VideoContent.
authorCarl Hetherington <cth@carlh.net>
Sun, 3 Oct 2021 00:02:12 +0000 (02:02 +0200)
committerCarl Hetherington <cth@carlh.net>
Sun, 3 Oct 2021 21:41:02 +0000 (23:41 +0200)
src/lib/dcp_examiner.h
src/lib/ffmpeg_examiner.cc
src/lib/ffmpeg_examiner.h
src/lib/image_examiner.h
src/lib/pixel_quanta.cc [new file with mode: 0644]
src/lib/pixel_quanta.h [new file with mode: 0644]
src/lib/video_content.cc
src/lib/video_content.h
src/lib/video_examiner.h
src/lib/video_mxf_examiner.h
src/lib/wscript

index 66f694f729c70aac2a92f66ed77c6dac2c3c0209..fd643a754ff78cfa2caaa7bf80a332173810360f 100644 (file)
@@ -62,6 +62,10 @@ public:
                return VideoRange::FULL;
        }
 
+       PixelQuanta pixel_quanta () const {
+               return {};
+       }
+
        std::string name () const {
                return _name;
        }
index 853db90be3e3ef1ec36cc834a51f0ff6754468e9..0a236d836be46b4f5baacdee175201e154de6cab 100644 (file)
@@ -480,3 +480,12 @@ FFmpegExaminer::range () const
                return VideoRange::FULL;
        }
 }
+
+
+PixelQuanta
+FFmpegExaminer::pixel_quanta () const
+{
+       auto const desc = av_pix_fmt_desc_get(video_codec_context()->pix_fmt);
+       return { 1 << desc->log2_chroma_w, 1 << desc->log2_chroma_h };
+}
+
index 793460f9b11b7dfc777e502914ee5f976c64f2cf..f978eb52bc00e63b55f3ab34034f57ea2893cdb8 100644 (file)
@@ -57,6 +57,8 @@ public:
 
        VideoRange range () const;
 
+       PixelQuanta pixel_quanta () const;
+
        AVColorRange color_range () const {
                return video_codec_context()->color_range;
        }
index cad8683a19b3e23148668f1a97b6eb5bf82ccaf6..0dcdebad0520986bce14a84363c82037149fb49d 100644 (file)
@@ -39,6 +39,10 @@ public:
        VideoRange range () const {
                return VideoRange::FULL;
        }
+       PixelQuanta pixel_quanta () const {
+               /* See ::yuv - we're assuming the image is not YUV and so not subsampled */
+               return {};
+       }
 
 private:
        std::weak_ptr<const Film> _film;
diff --git a/src/lib/pixel_quanta.cc b/src/lib/pixel_quanta.cc
new file mode 100644 (file)
index 0000000..12eea50
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+    Copyright (C) 2021 Carl Hetherington <cth@carlh.net>
+
+    This file is part of DCP-o-matic.
+
+    DCP-o-matic is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    DCP-o-matic is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with DCP-o-matic.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+
+#include "pixel_quanta.h"
+#include <dcp/raw_convert.h>
+
+
+PixelQuanta::PixelQuanta (cxml::ConstNodePtr node)
+       : x(node->number_child<int>("X"))
+       , y(node->number_child<int>("Y"))
+{
+
+}
+
+
+void
+PixelQuanta::as_xml (xmlpp::Element* node) const
+{
+       node->add_child("X")->add_child_text(dcp::raw_convert<std::string>(x));
+       node->add_child("Y")->add_child_text(dcp::raw_convert<std::string>(y));
+}
+
+
+PixelQuanta
+max (PixelQuanta const& a, PixelQuanta const& b)
+{
+       return { std::max(a.x, b.x), std::max(a.y, b.y) };
+}
+
diff --git a/src/lib/pixel_quanta.h b/src/lib/pixel_quanta.h
new file mode 100644 (file)
index 0000000..e4a03c9
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+    Copyright (C) 2021 Carl Hetherington <cth@carlh.net>
+
+    This file is part of DCP-o-matic.
+
+    DCP-o-matic is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    DCP-o-matic is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with DCP-o-matic.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+
+#ifndef DCPOMATIC_PIXEL_QUANTA_H
+#define DCPOMATIC_PIXEL_QUANTA_H
+
+
+#include "warnings.h"
+
+#include <libcxml/cxml.h>
+DCPOMATIC_DISABLE_WARNINGS
+#include <libxml++/libxml++.h>
+DCPOMATIC_ENABLE_WARNINGS
+
+
+class PixelQuanta
+{
+public:
+       PixelQuanta ()
+               : x(1)
+               , y(1)
+       {}
+
+       /** @param x number of pixels that must not be split in the x direction; e.g. if x=2 scale should
+        *  only happen to multiples of 2 width, and x crop should only happen at multiples of 2 position.
+        *  @param y similar value for y / height.
+        */
+       PixelQuanta (int x_, int y_)
+               : x(x_)
+               , y(y_)
+       {}
+
+       PixelQuanta (cxml::ConstNodePtr node);
+
+       void as_xml (xmlpp::Element* node) const;
+
+       int x;
+       int y;
+};
+
+
+PixelQuanta max (PixelQuanta const& a, PixelQuanta const& b);
+
+#endif
+
index 655b8baf6aa861af5c947eaed8b2e2ce6580c2ed..bffe2e3224cdfe8f0f9775f28ff2a7bac07b535d 100644 (file)
@@ -184,6 +184,10 @@ VideoContent::VideoContent (Content* parent, cxml::ConstNodePtr node, int versio
                _range = VideoRange::VIDEO;
        }
 
+       if (auto pixel_quanta = node->optional_node_child("PixelQuanta")) {
+               _pixel_quanta = PixelQuanta(pixel_quanta);
+       }
+
        auto burnt = node->optional_string_child("BurntSubtitleLanguage");
        if (burnt) {
                _burnt_subtitle_language = dcp::LanguageTag (*burnt);
@@ -243,6 +247,8 @@ VideoContent::VideoContent (Content* parent, vector<shared_ptr<Content> > c)
                if (c[i]->video->yuv ()) {
                        _yuv = true;
                }
+
+               _pixel_quanta = max(_pixel_quanta, c[i]->video->_pixel_quanta);
        }
 
        _use = ref->use ();
@@ -285,6 +291,7 @@ VideoContent::as_xml (xmlpp::Node* node) const
        node->add_child("FadeIn")->add_child_text (raw_convert<string> (_fade_in));
        node->add_child("FadeOut")->add_child_text (raw_convert<string> (_fade_out));
        node->add_child("Range")->add_child_text(_range == VideoRange::FULL ? "full" : "video");
+       _pixel_quanta.as_xml(node->add_child("PixelQuanta"));
        if (_burnt_subtitle_language) {
                node->add_child("BurntSubtitleLanguage")->add_child_text(_burnt_subtitle_language->to_string());
        }
@@ -299,6 +306,7 @@ VideoContent::take_from_examiner (shared_ptr<VideoExaminer> d)
        auto const ar = d->sample_aspect_ratio ();
        auto const yuv = d->yuv ();
        auto const range = d->range ();
+       auto const pixel_quanta = d->pixel_quanta ();
 
        ContentChangeSignaller cc1 (_parent, VideoContentProperty::SIZE);
        ContentChangeSignaller cc2 (_parent, ContentProperty::LENGTH);
@@ -311,6 +319,7 @@ VideoContent::take_from_examiner (shared_ptr<VideoExaminer> d)
                _sample_aspect_ratio = ar;
                _yuv = yuv;
                _range = range;
+               _pixel_quanta = pixel_quanta;
        }
 
        LOG_GENERAL ("Video length obtained from header as %1 frames", _length);
index 0c46499547c3245b0ad410dd4a1ea2b0b16708c7..de151e1451d9f9583168a65a19687a045cc5a309 100644 (file)
@@ -26,6 +26,7 @@
 #include "colour_conversion.h"
 #include "content_part.h"
 #include "dcpomatic_time.h"
+#include "pixel_quanta.h"
 #include "types.h"
 #include "user_property.h"
 #include <dcp/language_tag.h>
@@ -245,6 +246,7 @@ private:
        /** fade out time in content frames */
        Frame _fade_out;
        VideoRange _range;
+       PixelQuanta _pixel_quanta;
        boost::optional<dcp::LanguageTag> _burnt_subtitle_language;
 };
 
index 4e5c6dc0a322c3fd57c024aa6611775178a68226..c56530448fce67e44b5e98d728e43e254dbdf5f8 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2013-2016 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2013-2021 Carl Hetherington <cth@carlh.net>
 
     This file is part of DCP-o-matic.
 
 
 */
 
+
 /** @file  src/lib/video_examiner.h
  *  @brief VideoExaminer class.
  */
 
+
+#include "pixel_quanta.h"
 #include "types.h"
 #include "video_content.h"
 #include <dcp/types.h>
 
+
 /** @class VideoExaminer
  *  @brief Parent for classes which examine video sources and obtain information about them.
  */
@@ -49,4 +53,5 @@ public:
        /** @return true if this video is in YUV; must not be called if has_video() == false */
        virtual bool yuv () const = 0;
        virtual VideoRange range () const = 0;
+       virtual PixelQuanta pixel_quanta () const = 0;
 };
index 37badafba4adc15f2a96b60986806d9255e993bd..3719d3efcf09f5d7a4326a5e07973c5f7adb340a 100644 (file)
@@ -42,6 +42,9 @@ public:
        VideoRange range () const {
                return VideoRange::FULL;
        }
+       PixelQuanta pixel_quanta () const {
+               return {};
+       }
 
 private:
        std::shared_ptr<dcp::PictureAsset> _asset;
index 06bb555b26f627b55ca927516fcb05ef0993ff87..fd243db689afb0fef910ea73e1d7a42f0803fb06 100644 (file)
@@ -133,6 +133,7 @@ sources = """
           log_entry.cc
           mid_side_decoder.cc
           overlaps.cc
+          pixel_quanta.cc
           player.cc
           player_text.cc
           player_video.cc