Add more video properties to content properties dialog.
authorCarl Hetherington <cth@carlh.net>
Sun, 21 Jun 2015 18:12:44 +0000 (19:12 +0100)
committerCarl Hetherington <cth@carlh.net>
Sun, 21 Jun 2015 18:12:44 +0000 (19:12 +0100)
Also implement the whole properties thing more neatly.

14 files changed:
ChangeLog
src/lib/content.cc
src/lib/content.h
src/lib/dcp_content.cc
src/lib/dcp_content.h
src/lib/ffmpeg_content.cc
src/lib/ffmpeg_content.h
src/lib/ffmpeg_examiner.h
src/lib/single_stream_audio_content.cc
src/lib/single_stream_audio_content.h
src/lib/video_content.cc
src/lib/video_content.h
src/wx/content_properties_dialog.cc
src/wx/content_properties_dialog.h

index 4203e9f7e758a72d277baca850ff04d05d46d01e..85c61c9282ae08569d5a3b367afcd1f4c4161131 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
 2015-06-21  Carl Hetherington  <cth@carlh.net>
 
+       * Add some more video properties to the content properties
+       dialogue.
+
        * Version 2.1.7 released.
 
 2015-06-21  Carl Hetherington  <cth@carlh.net>
index aa382d68b9e5f53fa233e70a6d4925ae65a73b9e..2b4f02b903c90d8027d48c1f0fe1fbb36ac49380 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2013-2014 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2013-2015 Carl Hetherington <cth@carlh.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -40,6 +40,7 @@ using std::list;
 using std::cout;
 using std::vector;
 using std::max;
+using std::pair;
 using boost::shared_ptr;
 
 int const ContentProperty::PATH = 400;
@@ -273,3 +274,14 @@ Content::path_summary () const
 
        return s;
 }
+
+/** @return a list of properties that might be interesting to the user; first string is the property name,
+ *  second is the value.
+ */
+list<pair<string, string> >
+Content::properties () const
+{
+       list<pair<string, string> > p;
+       add_properties (p);
+       return p;
+}
index 6ee9e59dd289fd15c0eff15258d15a9916bdc9f2..2deee9763b70f3bc9c37edd901fcb93858de02c3 100644 (file)
@@ -84,6 +84,8 @@ public:
        virtual DCPTime full_length () const = 0;
        virtual std::string identifier () const;
 
+       std::list<std::pair<std::string, std::string> > properties () const;
+
        boost::shared_ptr<Content> clone () const;
 
        void set_path (boost::filesystem::path);
@@ -159,6 +161,7 @@ public:
 
 protected:
        void signal_changed (int);
+       virtual void add_properties (std::list<std::pair<std::string, std::string> > &) const {}
 
        boost::weak_ptr<const Film> _film;
 
index 880a543e7430dc9b7123f9bce275f2bc246ee8df..b1c9e3815fd916b8edb57ee7e9bad8576052a3c6 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2014 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2014-2015 Carl Hetherington <cth@carlh.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -32,6 +32,8 @@
 using std::string;
 using std::cout;
 using std::distance;
+using std::pair;
+using std::list;
 using boost::shared_ptr;
 using boost::optional;
 
@@ -181,3 +183,9 @@ DCPContent::directory () const
 
        return dir;
 }
+
+void
+DCPContent::add_properties (list<pair<string, string> >& p) const
+{
+       SingleStreamAudioContent::add_properties (p);
+}
index 2d0aaacde10620de23ecf7a6f8a158c618736c12..d7a29c6ed97c49f89ea0207730c92c10d2d59a8f 100644 (file)
@@ -84,6 +84,9 @@ public:
 
        bool can_be_played () const;
 
+protected:
+       void add_properties (std::list<std::pair<std::string, std::string> >& p) const;
+
 private:
        void read_directory (boost::filesystem::path);
 
index 8feb7df5728e6bff53b2f23dbfeed4d1aabcc5c8..ba0b4cc52c7348de052a5df9917018af99ad4098 100644 (file)
@@ -34,6 +34,7 @@
 #include <libcxml/cxml.h>
 extern "C" {
 #include <libavformat/avformat.h>
+#include <libavutil/pixdesc.h>
 }
 #include <boost/foreach.hpp>
 
@@ -46,6 +47,7 @@ using std::vector;
 using std::list;
 using std::cout;
 using std::pair;
+using std::make_pair;
 using boost::shared_ptr;
 using boost::dynamic_pointer_cast;
 
@@ -96,6 +98,15 @@ FFmpegContent::FFmpegContent (shared_ptr<const Film> film, cxml::ConstNodePtr no
        }
 
        _first_video = node->optional_number_child<double> ("FirstVideo");
+
+
+       _color_range = static_cast<AVColorRange> (node->optional_number_child<int>("ColorRange").get_value_or (AVCOL_RANGE_UNSPECIFIED));
+       _color_primaries = static_cast<AVColorPrimaries> (node->optional_number_child<int>("ColorPrimaries").get_value_or (AVCOL_PRI_UNSPECIFIED));
+       _color_trc = static_cast<AVColorTransferCharacteristic> (
+               node->optional_number_child<int>("ColorTransferCharacteristic").get_value_or (AVCOL_TRC_UNSPECIFIED)
+               );
+       _colorspace = static_cast<AVColorSpace> (node->optional_number_child<int>("Colorspace").get_value_or (AVCOL_SPC_UNSPECIFIED));
+
 }
 
 FFmpegContent::FFmpegContent (shared_ptr<const Film> film, vector<boost::shared_ptr<Content> > c)
@@ -150,6 +161,11 @@ FFmpegContent::as_xml (xmlpp::Node* node) const
        if (_first_video) {
                node->add_child("FirstVideo")->add_child_text (raw_convert<string> (_first_video.get().get()));
        }
+
+       node->add_child("ColorRange")->add_child_text (raw_convert<string> (_color_range));
+       node->add_child("ColorPrimaries")->add_child_text (raw_convert<string> (_color_primaries));
+       node->add_child("ColorTransferCharacteristic")->add_child_text (raw_convert<string> (_color_trc));
+       node->add_child("Colorspace")->add_child_text (raw_convert<string> (_colorspace));
 }
 
 void
@@ -182,6 +198,11 @@ FFmpegContent::examine (shared_ptr<Job> job)
                }
 
                _first_video = examiner->first_video ();
+
+               _color_range = examiner->color_range ();
+               _color_primaries = examiner->color_primaries ();
+               _color_trc = examiner->color_trc ();
+               _colorspace = examiner->colorspace ();
        }
 
        signal_changed (FFmpegContentProperty::SUBTITLE_STREAMS);
@@ -332,3 +353,77 @@ FFmpegContent::audio_streams () const
        copy (_audio_streams.begin(), _audio_streams.end(), back_inserter (s));
        return s;
 }
+
+void
+FFmpegContent::add_properties (list<pair<string, string> >& p) const
+{
+       VideoContent::add_properties (p);
+
+       /* I tried av_*_name for these but they are not the most
+          nicely formatted.
+       */
+
+       char const * ranges[] = {
+               _("Unspecified"),
+               _("MPEG (0-219 or equivalent)"),
+               _("JPEG (0-255 or equivalent)")
+       };
+
+       DCPOMATIC_ASSERT (AVCOL_RANGE_NB == 3);
+       p.push_back (make_pair (_("Colour range"), ranges[_color_range]));
+
+       char const * primaries[] = {
+               _("Unspecified"),
+               _("BT709"),
+               _("Unspecified"),
+               _("Unspecified"),
+               _("BT470M"),
+               _("BT470BG"),
+               _("SMPTE 170M (BT601)"),
+               _("SMPTE 240M"),
+               _("Film"),
+               _("BT2020")
+       };
+
+       DCPOMATIC_ASSERT (AVCOL_PRI_NB == 10);
+       p.push_back (make_pair (_("Color primaries"), primaries[_color_primaries]));
+
+       char const * transfers[] = {
+               _("Unspecified"),
+               _("BT709"),
+               _("Unspecified"),
+               _("Unspecified"),
+               _("Gamma 22 (BT470M)"),
+               _("Gamma 28 (BT470BG)"),
+               _("SMPTE 170M (BT601)"),
+               _("SMPTE 240M"),
+               _("Linear"),
+               _("Logarithmic (100:1 range)"),
+               _("Logarithmic (316:1 range)"),
+               _("IEC61966-2-4"),
+               _("BT1361 extended colour gamut"),
+               _("IEC61966-2-1 (sRGB or sYCC)"),
+               _("BT2020 for a 10-bit system"),
+               _("BT2020 for a 12-bit system")
+       };
+
+       DCPOMATIC_ASSERT (AVCOL_TRC_NB == 16);
+       p.push_back (make_pair (_("Colour transfer characteristic"), transfers[_color_trc]));
+
+       char const * spaces[] = {
+               _("RGB / sRGB (IEC61966-2-1)"),
+               _("BT709"),
+               _("Unspecified"),
+               _("Unspecified"),
+               _("FCC"),
+               _("BT470BG (BT601-6)"),
+               _("SMPTE 170M (BT601-6)"),
+               _("SMPTE 240M"),
+               _("YCOCG"),
+               _("BT2020 non-constant luminance"),
+               _("BT2020 constant luminance"),
+       };
+
+       DCPOMATIC_ASSERT (AVCOL_SPC_NB == 11);
+       p.push_back (make_pair (_("Colourspace"), spaces[_colorspace]));
+}
index c5797d5d1b63761d6409fe055ed69692e8db6518..05f6cebb6ff2f168f5cbfb30e6e7fee242f02974 100644 (file)
@@ -104,6 +104,9 @@ public:
 
        std::list<ContentTimePeriod> subtitles_during (ContentTimePeriod, bool starting) const;
 
+protected:
+       void add_properties (std::list<std::pair<std::string, std::string> > &) const;
+
 private:
        friend struct ffmpeg_pts_offset_test;
        friend struct audio_sampling_rate_test;
@@ -114,6 +117,11 @@ private:
        boost::optional<ContentTime> _first_video;
        /** Video filters that should be used when generating DCPs */
        std::vector<Filter const *> _filters;
+
+       AVColorRange _color_range;
+       AVColorPrimaries _color_primaries;
+       AVColorTransferCharacteristic _color_trc;
+       AVColorSpace _colorspace;
 };
 
 #endif
index 7b64b508aff864661aa56b8cea8cd392a9f64c05..f2bdea0c29374495107a14103e10066c0defa64d 100644 (file)
@@ -46,6 +46,22 @@ public:
                return _first_video;
        }
 
+       AVColorRange color_range () const {
+               return video_codec_context()->color_range;
+       }
+
+       AVColorPrimaries color_primaries () const {
+               return video_codec_context()->color_primaries;
+       }
+
+       AVColorTransferCharacteristic color_trc () const {
+               return video_codec_context()->color_trc;
+       }
+
+       AVColorSpace colorspace () const {
+               return video_codec_context()->colorspace;
+       }
+
 private:
        void video_packet (AVCodecContext *);
        void audio_packet (AVCodecContext *, boost::shared_ptr<FFmpegAudioStream>);
index cf2dcc1bd6210a9e78d4b5ead98c8bbb968aeadf..38623422d15e8e18f3b58224bfb48a6ada0cdbf1 100644 (file)
 #include "film.h"
 #include "raw_convert.h"
 
+#include "i18n.h"
+
 using std::string;
 using std::cout;
 using std::vector;
+using std::list;
+using std::pair;
 using boost::shared_ptr;
 
 SingleStreamAudioContent::SingleStreamAudioContent (shared_ptr<const Film> film)
@@ -81,3 +85,10 @@ SingleStreamAudioContent::audio_streams () const
        s.push_back (_audio_stream);
        return s;
 }
+
+void
+SingleStreamAudioContent::add_properties (list<pair<string, string> >& p) const
+{
+       /* XXX: this could be better wrt audio streams */
+       p.push_back (make_pair (_("Audio channels"), raw_convert<string> (audio_stream()->channels ())));
+}
index 7ae6dbaa46c3538d6fb5a951e05ebd829a7031b4..ad4de46ea22d0f63fec6ec35eb84700c77a50a63 100644 (file)
@@ -49,6 +49,8 @@ public:
        void take_from_audio_examiner (boost::shared_ptr<AudioExaminer>);
 
 protected:
+       void add_properties (std::list<std::pair<std::string, std::string> > &) const;
+
        boost::shared_ptr<AudioStream> _audio_stream;
 };
 
index 8c6f6c7eb7ae11c39aada00f73ed0113c76febca..e2fba5829a6f489e6638b94d376f624371dc4f1e 100644 (file)
@@ -56,6 +56,8 @@ using std::max;
 using std::stringstream;
 using std::fixed;
 using std::setprecision;
+using std::list;
+using std::pair;
 using boost::shared_ptr;
 using boost::optional;
 using boost::dynamic_pointer_cast;
@@ -569,3 +571,11 @@ VideoContent::processing_description () const
 
        return d.str ();
 }
+
+void
+VideoContent::add_properties (list<pair<string, string> >& p) const
+{
+       p.push_back (make_pair (_("Video length"), raw_convert<string> (video_length ()) + " " + _("video frames")));
+       p.push_back (make_pair (_("Video size"), raw_convert<string> (video_size().width) + "x" + raw_convert<string> (video_size().height)));
+       p.push_back (make_pair (_("Video frame rate"), raw_convert<string> (video_frame_rate()) + " " + _("frames per second")));
+}
index 01e3cb2aab7e876a571bde5f02efa44c43dfc2e1..71c20e7373d772c822ef4b029b0a9dc612603379 100644 (file)
@@ -164,6 +164,7 @@ public:
 
 protected:
        void take_from_video_examiner (boost::shared_ptr<VideoExaminer>);
+       void add_properties (std::list<std::pair<std::string, std::string> > &) const;
 
        Frame _video_length;
        float _video_frame_rate;
index 7fb0cccbab2e42962a281c685148bcb851a8bfeb..4f92e53ce05aa925058bfbc88e62956e7869a196 100644 (file)
@@ -27,6 +27,8 @@
 #include <boost/algorithm/string.hpp>
 
 using std::string;
+using std::list;
+using std::pair;
 using boost::shared_ptr;
 using boost::dynamic_pointer_cast;
 
@@ -35,40 +37,14 @@ ContentPropertiesDialog::ContentPropertiesDialog (wxWindow* parent, shared_ptr<C
 {
        string n = content->path(0).string();
        boost::algorithm::replace_all (n, "&", "&&");
-       add_property (_("Filename"), std_to_wx (n));
+       add (_("Filename"), true);
+       add (new wxStaticText (this, wxID_ANY, std_to_wx (n)));
 
-       shared_ptr<VideoContent> video = dynamic_pointer_cast<VideoContent> (content);
-       if (video) {
-               add_property (
-                       _("Video length"),
-                       std_to_wx (raw_convert<string> (video->video_length ())) + " " + _("video frames")
-                       );
-               add_property (
-                       _("Video size"),
-                       std_to_wx (raw_convert<string> (video->video_size().width) + "x" + raw_convert<string> (video->video_size().height))
-                       );
-               add_property (
-                       _("Video frame rate"),
-                       std_to_wx (raw_convert<string> (video->video_frame_rate())) + " " + _("frames per second")
-                       );
-       }
-
-       /* XXX: this could be better wrt audio streams */
-
-       shared_ptr<SingleStreamAudioContent> single = dynamic_pointer_cast<SingleStreamAudioContent> (content);
-       if (single) {
-               add_property (
-                       _("Audio channels"),
-                       std_to_wx (raw_convert<string> (single->audio_stream()->channels ()))
-                       );
+       list<pair<string, string> > properties = content->properties ();
+       for (list<pair<string, string> >::const_iterator i = properties.begin(); i != properties.end(); ++i) {
+               add (std_to_wx (i->first), true);
+               add (new wxStaticText (this, wxID_ANY, std_to_wx (i->second)));
        }
 
        layout ();
 }
-
-void
-ContentPropertiesDialog::add_property (wxString k, wxString v)
-{
-       add (k, true);
-       add (new wxStaticText (this, wxID_ANY, v));
-}
index 5c5efa1e85ab4696b84c04d97759971459736c10..52cce7ec6683e2ad394ed64ca322d220d622a70c 100644 (file)
@@ -26,8 +26,4 @@ class ContentPropertiesDialog : public TableDialog
 {
 public:
        ContentPropertiesDialog (wxWindow* parent, boost::shared_ptr<Content> content);
-
-private:
-       void add_property (wxString k, wxString v);
 };
-