summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2021-10-02 10:21:52 +0200
committerCarl Hetherington <cth@carlh.net>2021-10-02 10:21:52 +0200
commitd8a20fef494065a9b3ccf2d93328861b1eea1d4f (patch)
treea5f9f76eb4b2a4dfd91c012923537286385af631
parent753b75171d1eb3f9e4fc7c2d12fd5b8de5669331 (diff)
Gather and store chroma subsampling information for video content.
-rw-r--r--src/lib/dcp_examiner.h8
-rw-r--r--src/lib/ffmpeg_examiner.cc15
-rw-r--r--src/lib/ffmpeg_examiner.h2
-rw-r--r--src/lib/image_examiner.cc16
-rw-r--r--src/lib/image_examiner.h2
-rw-r--r--src/lib/video_content.cc19
-rw-r--r--src/lib/video_content.h2
-rw-r--r--src/lib/video_examiner.h10
-rw-r--r--src/lib/video_mxf_examiner.h6
9 files changed, 79 insertions, 1 deletions
diff --git a/src/lib/dcp_examiner.h b/src/lib/dcp_examiner.h
index 66f694f72..4cc3e1240 100644
--- a/src/lib/dcp_examiner.h
+++ b/src/lib/dcp_examiner.h
@@ -58,6 +58,14 @@ public:
return false;
}
+ int log2_chroma_width () const {
+ return 0;
+ }
+
+ int log2_chroma_height () const {
+ return 0;
+ }
+
VideoRange range () const {
return VideoRange::FULL;
}
diff --git a/src/lib/ffmpeg_examiner.cc b/src/lib/ffmpeg_examiner.cc
index 853db90be..c63bca647 100644
--- a/src/lib/ffmpeg_examiner.cc
+++ b/src/lib/ffmpeg_examiner.cc
@@ -480,3 +480,18 @@ FFmpegExaminer::range () const
return VideoRange::FULL;
}
}
+
+
+int
+FFmpegExaminer::log2_chroma_width () const
+{
+ return av_pix_fmt_desc_get(video_codec_context()->pix_fmt)->log2_chroma_w;
+}
+
+
+int
+FFmpegExaminer::log2_chroma_height () const
+{
+ return av_pix_fmt_desc_get(video_codec_context()->pix_fmt)->log2_chroma_h;
+}
+
diff --git a/src/lib/ffmpeg_examiner.h b/src/lib/ffmpeg_examiner.h
index 793460f9b..21fbac92a 100644
--- a/src/lib/ffmpeg_examiner.h
+++ b/src/lib/ffmpeg_examiner.h
@@ -42,6 +42,8 @@ public:
Frame video_length () const;
boost::optional<double> sample_aspect_ratio () const;
bool yuv () const;
+ int log2_chroma_width () const;
+ int log2_chroma_height () const;
std::vector<std::shared_ptr<FFmpegSubtitleStream>> subtitle_streams () const {
return _subtitle_streams;
diff --git a/src/lib/image_examiner.cc b/src/lib/image_examiner.cc
index 89d1517ce..624b05e57 100644
--- a/src/lib/image_examiner.cc
+++ b/src/lib/image_examiner.cc
@@ -107,3 +107,19 @@ ImageExaminer::yuv () const
*/
return false;
}
+
+
+int
+ImageExaminer::log2_chroma_width () const
+{
+ /* See ::yuv() - we're assuming the image is not YUV and so not subsampled */
+ return 0;
+}
+
+
+int
+ImageExaminer::log2_chroma_height () const
+{
+ /* See ::yuv() - we're assuming the image is not YUV and so not subsampled */
+ return 0;
+}
diff --git a/src/lib/image_examiner.h b/src/lib/image_examiner.h
index cad8683a1..48d7770dc 100644
--- a/src/lib/image_examiner.h
+++ b/src/lib/image_examiner.h
@@ -39,6 +39,8 @@ public:
VideoRange range () const {
return VideoRange::FULL;
}
+ int log2_chroma_width () const;
+ int log2_chroma_height () const;
private:
std::weak_ptr<const Film> _film;
diff --git a/src/lib/video_content.cc b/src/lib/video_content.cc
index 655b8baf6..c3e28fe09 100644
--- a/src/lib/video_content.cc
+++ b/src/lib/video_content.cc
@@ -184,6 +184,14 @@ VideoContent::VideoContent (Content* parent, cxml::ConstNodePtr node, int versio
_range = VideoRange::VIDEO;
}
+ if (auto cw = node->optional_number_child<int>("Log2ChromaWidth")) {
+ _log2_chroma_width = *cw;
+ }
+
+ if (auto ch = node->optional_number_child<int>("Log2ChromaHeight")) {
+ _log2_chroma_height = *ch;
+ }
+
auto burnt = node->optional_string_child("BurntSubtitleLanguage");
if (burnt) {
_burnt_subtitle_language = dcp::LanguageTag (*burnt);
@@ -192,7 +200,7 @@ VideoContent::VideoContent (Content* parent, cxml::ConstNodePtr node, int versio
}
-VideoContent::VideoContent (Content* parent, vector<shared_ptr<Content> > c)
+VideoContent::VideoContent (Content* parent, vector<shared_ptr<Content>> c)
: ContentPart (parent)
, _length (0)
, _yuv (false)
@@ -243,6 +251,9 @@ VideoContent::VideoContent (Content* parent, vector<shared_ptr<Content> > c)
if (c[i]->video->yuv ()) {
_yuv = true;
}
+
+ _log2_chroma_width = std::max(_log2_chroma_width, c[i]->video->_log2_chroma_width);
+ _log2_chroma_height = std::max(_log2_chroma_height, c[i]->video->_log2_chroma_height);
}
_use = ref->use ();
@@ -285,6 +296,8 @@ 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");
+ node->add_child("Log2ChromaWidth")->add_child_text(raw_convert<string>(_log2_chroma_width));
+ node->add_child("Log2ChromaHeight")->add_child_text(raw_convert<string>(_log2_chroma_height));
if (_burnt_subtitle_language) {
node->add_child("BurntSubtitleLanguage")->add_child_text(_burnt_subtitle_language->to_string());
}
@@ -299,6 +312,8 @@ 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 cw = d->log2_chroma_width ();
+ auto const ch = d->log2_chroma_height ();
ContentChangeSignaller cc1 (_parent, VideoContentProperty::SIZE);
ContentChangeSignaller cc2 (_parent, ContentProperty::LENGTH);
@@ -311,6 +326,8 @@ VideoContent::take_from_examiner (shared_ptr<VideoExaminer> d)
_sample_aspect_ratio = ar;
_yuv = yuv;
_range = range;
+ _log2_chroma_width = cw;
+ _log2_chroma_height = ch;
}
LOG_GENERAL ("Video length obtained from header as %1 frames", _length);
diff --git a/src/lib/video_content.h b/src/lib/video_content.h
index 0c4649954..31346ffcd 100644
--- a/src/lib/video_content.h
+++ b/src/lib/video_content.h
@@ -240,6 +240,8 @@ private:
/** Sample aspect ratio obtained from the content file's header, if there is one */
boost::optional<double> _sample_aspect_ratio;
bool _yuv;
+ int _log2_chroma_width = 0;
+ int _log2_chroma_height = 0;
/** fade in time in content frames */
Frame _fade_in;
/** fade out time in content frames */
diff --git a/src/lib/video_examiner.h b/src/lib/video_examiner.h
index 4e5c6dc0a..e83eb1adf 100644
--- a/src/lib/video_examiner.h
+++ b/src/lib/video_examiner.h
@@ -49,4 +49,14 @@ 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;
+ /** @return Amount by which the luminance width must be shifted right to find the chroma width.
+ * e.g. for YUV420 or YUV422 this is 1, for YUV444 this is 0
+ * Must not be called if has_video() == false.
+ */
+ virtual int log2_chroma_width () const = 0;
+ /** @return Amount by which the luminance height must be shifted right to find the chroma height.
+ * e.g. for YUV420 this is 1, for YUV444 this is 0
+ * Must not be called if has_video() == false.
+ */
+ virtual int log2_chroma_height () const = 0;
};
diff --git a/src/lib/video_mxf_examiner.h b/src/lib/video_mxf_examiner.h
index 37badafba..508cc9875 100644
--- a/src/lib/video_mxf_examiner.h
+++ b/src/lib/video_mxf_examiner.h
@@ -42,6 +42,12 @@ public:
VideoRange range () const {
return VideoRange::FULL;
}
+ int log2_chroma_width () const {
+ return 0;
+ }
+ int log2_chroma_height () const {
+ return 0;
+ }
private:
std::shared_ptr<dcp::PictureAsset> _asset;