Allow specification of video bit rate separately for J2K and MPEG2.
authorCarl Hetherington <cth@carlh.net>
Fri, 5 Apr 2024 21:17:03 +0000 (23:17 +0200)
committerCarl Hetherington <cth@carlh.net>
Mon, 22 Apr 2024 11:03:04 +0000 (13:03 +0200)
22 files changed:
src/lib/config.cc
src/lib/config.h
src/lib/create_cli.cc
src/lib/dcp_film_encoder.cc
src/lib/film.cc
src/lib/film.h
src/lib/grok/context.h
src/lib/hints.cc
src/lib/j2k_encoder.cc
src/lib/make_dcp.cc
src/lib/mpeg2_encoder.cc
src/lib/video_encoding.cc
src/lib/video_encoding.h
src/tools/dcpomatic_cli.cc
src/wx/dcp_panel.cc
src/wx/full_config_dialog.cc
test/data
test/film_metadata_test.cc
test/j2k_video_bit_rate_test.cc
test/reels_test.cc
test/required_disk_space_test.cc
test/test.cc

index 1400b93098f53a78538b352e3bcc680919422a6f..33b1a865659063042ca06d770b5dfca7d24290a1 100644 (file)
@@ -108,7 +108,8 @@ Config::set_defaults ()
        _default_still_length = 10;
        _default_dcp_content_type = DCPContentType::from_isdcf_name ("FTR");
        _default_dcp_audio_channels = 8;
-       _default_video_bit_rate = 150000000;
+       _default_video_bit_rate[VideoEncoding::JPEG2000] = 150000000;
+       _default_video_bit_rate[VideoEncoding::MPEG2] = 5000000;
        _default_audio_delay = 0;
        _default_interop = false;
        _default_metadata.clear ();
@@ -127,7 +128,8 @@ Config::set_defaults ()
        _notification_bcc = "";
        _check_for_updates = false;
        _check_for_test_updates = false;
-       _maximum_video_bit_rate = 250000000;
+       _maximum_video_bit_rate[VideoEncoding::JPEG2000] = 250000000;
+       _maximum_video_bit_rate[VideoEncoding::MPEG2] = 50000000;
        _log_types = LogEntry::TYPE_GENERAL | LogEntry::TYPE_WARNING | LogEntry::TYPE_ERROR | LogEntry::TYPE_DISK;
        _analyse_ebur128 = true;
        _automatic_audio_analysis = false;
@@ -376,10 +378,11 @@ try
 
        _default_still_length = f.optional_number_child<int>("DefaultStillLength").get_value_or (10);
        if (auto j2k = f.optional_number_child<int>("DefaultJ2KBandwidth")) {
-               _default_video_bit_rate = *j2k;
+               _default_video_bit_rate[VideoEncoding::JPEG2000] = *j2k;
        } else {
-               _default_video_bit_rate = f.optional_number_child<int64_t>("DefaultVideoBitRate").get_value_or(200000000);
+               _default_video_bit_rate[VideoEncoding::JPEG2000] = f.optional_number_child<int64_t>("DefaultJ2KVideoBitRate").get_value_or(200000000);
        }
+       _default_video_bit_rate[VideoEncoding::MPEG2] = f.optional_number_child<int64_t>("DefaultMPEG2VideoBitRate").get_value_or(5000000);
        _default_audio_delay = f.optional_number_child<int>("DefaultAudioDelay").get_value_or (0);
        _default_interop = f.optional_bool_child("DefaultInterop").get_value_or (false);
 
@@ -455,10 +458,11 @@ try
        _check_for_test_updates = f.optional_bool_child("CheckForTestUpdates").get_value_or (false);
 
        if (auto j2k = f.optional_number_child<int>("MaximumJ2KBandwidth")) {
-               _maximum_video_bit_rate = *j2k;
+               _maximum_video_bit_rate[VideoEncoding::JPEG2000] = *j2k;
        } else {
-               _maximum_video_bit_rate = f.optional_number_child<int64_t>("MaximumVideoBitRate").get_value_or(250000000);
+               _maximum_video_bit_rate[VideoEncoding::JPEG2000] = f.optional_number_child<int64_t>("MaximumJ2KVideoBitRate").get_value_or(250000000);
        }
+       _maximum_video_bit_rate[VideoEncoding::MPEG2] = f.optional_number_child<int64_t>("MaximumMPEG2VideoBitRate").get_value_or(50000000);
        _allow_any_dcp_frame_rate = f.optional_bool_child ("AllowAnyDCPFrameRate").get_value_or (false);
        _allow_any_container = f.optional_bool_child ("AllowAnyContainer").get_value_or (false);
        _allow_96khz_audio = f.optional_bool_child("Allow96kHzAudio").get_value_or(false);
@@ -815,8 +819,10 @@ Config::write_config () const
 
        /* [XML] DefaultStillLength Default length (in seconds) for still images in new films. */
        cxml::add_text_child(root, "DefaultStillLength", raw_convert<string>(_default_still_length));
-       /* [XML] DefaultVideoBitRate Default bitrate (in bits per second) for JPEG2000 or MPEG2 data in new films. */
-       cxml::add_text_child(root, "DefaultVideoBitRate", raw_convert<string>(_default_video_bit_rate));
+       /* [XML] DefaultJ2KVideoBitRate Default bitrate (in bits per second) for JPEG2000 data in new films. */
+       cxml::add_text_child(root, "DefaultJ2KVideoBitRate", raw_convert<string>(_default_video_bit_rate[VideoEncoding::JPEG2000]));
+       /* [XML] DefaultMPEG2VideoBitRate Default bitrate (in bits per second) for MPEG2 data in new films. */
+       cxml::add_text_child(root, "DefaultMPEG2VideoBitRate", raw_convert<string>(_default_video_bit_rate[VideoEncoding::MPEG2]));
        /* [XML] DefaultAudioDelay Default delay to apply to audio (positive moves audio later) in milliseconds. */
        cxml::add_text_child(root, "DefaultAudioDelay", raw_convert<string>(_default_audio_delay));
        /* [XML] DefaultInterop 1 to default new films to Interop, 0 for SMPTE. */
@@ -896,8 +902,10 @@ Config::write_config () const
        /* [XML] CheckForUpdates 1 to check dcpomatic.com for new text versions, 0 to check only on request. */
        cxml::add_text_child(root, "CheckForTestUpdates", _check_for_test_updates ? "1" : "0");
 
-       /* [XML] MaximumVideoBitRate Maximum video bit rate (in bits per second) that can be specified in the GUI. */
-       cxml::add_text_child(root, "MaximumVideoBitRate", raw_convert<string>(_maximum_video_bit_rate));
+       /* [XML] MaximumJ2KVideoBitRate Maximum video bit rate (in bits per second) that can be specified in the GUI for JPEG2000 encodes. */
+       cxml::add_text_child(root, "MaximumJ2KVideoBitRate", raw_convert<string>(_maximum_video_bit_rate[VideoEncoding::JPEG2000]));
+       /* [XML] MaximumMPEG2VideoBitRate Maximum video bit rate (in bits per second) that can be specified in the GUI for MPEG2 encodes. */
+       cxml::add_text_child(root, "MaximumMPEG2VideoBitRate", raw_convert<string>(_maximum_video_bit_rate[VideoEncoding::MPEG2]));
        /* [XML] AllowAnyDCPFrameRate 1 to allow users to specify any frame rate when creating DCPs, 0 to limit the GUI to standard rates. */
        cxml::add_text_child(root, "AllowAnyDCPFrameRate", _allow_any_dcp_frame_rate ? "1" : "0");
        /* [XML] AllowAnyContainer 1 to allow users to user any container ratio for their DCP, 0 to limit the GUI to DCI Flat/Scope */
index ff71f8a388e9a4927455d2bbe69a955745cf47c3..a7b238c04099c0c5dec736cb3d298325254350ec 100644 (file)
 
 
 #include "audio_mapping.h"
+#include "enum_indexed_vector.h"
 #include "export_config.h"
 #include "rough_duration.h"
 #include "state.h"
+#include "video_encoding.h"
 #include <dcp/name_format.h>
 #include <dcp/certificate_chain.h>
 #include <dcp/encrypted_kdm.h>
@@ -233,8 +235,8 @@ public:
                return _dcp_j2k_comment;
        }
 
-       int64_t default_video_bit_rate() const {
-               return _default_video_bit_rate;
+       int64_t default_video_bit_rate(VideoEncoding encoding) const {
+               return _default_video_bit_rate[encoding];
        }
 
        int default_audio_delay () const {
@@ -349,8 +351,8 @@ public:
                return _check_for_test_updates;
        }
 
-       int64_t maximum_video_bit_rate() const {
-               return _maximum_video_bit_rate;
+       int64_t maximum_video_bit_rate(VideoEncoding encoding) const {
+               return _maximum_video_bit_rate[encoding];
        }
 
        int log_types () const {
@@ -811,8 +813,8 @@ public:
                maybe_set (_dcp_j2k_comment, c);
        }
 
-       void set_default_video_bit_rate(int64_t b) {
-               maybe_set(_default_video_bit_rate, b);
+       void set_default_video_bit_rate(VideoEncoding encoding, int64_t b) {
+               maybe_set(_default_video_bit_rate[encoding], b);
        }
 
        void set_default_audio_delay (int d) {
@@ -934,8 +936,8 @@ public:
                maybe_set (_check_for_test_updates, c);
        }
 
-       void set_maximum_video_bit_rate(int64_t b) {
-               maybe_set(_maximum_video_bit_rate, b);
+       void set_maximum_video_bit_rate(VideoEncoding encoding, int64_t b) {
+               maybe_set(_maximum_video_bit_rate[encoding], b);
        }
 
        void set_log_types (int t) {
@@ -1381,7 +1383,7 @@ private:
        std::string _dcp_product_name;
        std::string _dcp_product_version;
        std::string _dcp_j2k_comment;
-       int64_t _default_video_bit_rate;
+       EnumIndexedVector<int64_t, VideoEncoding> _default_video_bit_rate;
        int _default_audio_delay;
        bool _default_interop;
        boost::optional<dcp::LanguageTag> _default_audio_language;
@@ -1419,7 +1421,7 @@ private:
        bool _check_for_updates;
        bool _check_for_test_updates;
        /** maximum allowed video bit rate in bits per second */
-       int64_t _maximum_video_bit_rate;
+       EnumIndexedVector<int64_t, VideoEncoding> _maximum_video_bit_rate;
        int _log_types;
        bool _analyse_ebur128;
        bool _automatic_audio_analysis;
index b33537974bae5adea41081fa7777439b7ee50b75..8fe5a2a143f834c47a72d2eb906cf1fcfbd2b511 100644 (file)
@@ -320,8 +320,8 @@ CreateCLI::CreateCLI (int argc, char* argv[])
                _name = content[0].path.filename().string();
        }
 
-       if (_video_bit_rate && (*_video_bit_rate < 10000000 || *_video_bit_rate > Config::instance()->maximum_video_bit_rate())) {
-               error = String::compose("%1: video-bit-rate must be between 10 and %2 Mbit/s", argv[0], (Config::instance()->maximum_video_bit_rate() / 1000000));
+       if (_video_bit_rate && (*_video_bit_rate < 10000000 || *_video_bit_rate > Config::instance()->maximum_video_bit_rate(VideoEncoding::JPEG2000))) {
+               error = String::compose("%1: video-bit-rate must be between 10 and %2 Mbit/s", argv[0], (Config::instance()->maximum_video_bit_rate(VideoEncoding::JPEG2000) / 1000000));
                return;
        }
 }
@@ -373,7 +373,7 @@ CreateCLI::make_film() const
                film->set_resolution(Resolution::FOUR_K);
        }
        if (_video_bit_rate) {
-               film->set_video_bit_rate(*_video_bit_rate);
+               film->set_video_bit_rate(VideoEncoding::JPEG2000, *_video_bit_rate);
        }
 
        int channels = 6;
index 17f5316931a3a66bfd37d3b68c54bd9d25d0d3dc..bdcd17f387954023c6d1a1300f3de8a5291af0d0 100644 (file)
@@ -78,6 +78,8 @@ DCPFilmEncoder::DCPFilmEncoder(shared_ptr<const Film> film, weak_ptr<Job> job)
        case VideoEncoding::MPEG2:
                _encoder.reset(new MPEG2Encoder(film, _writer));
                break;
+       case VideoEncoding::COUNT:
+               DCPOMATIC_ASSERT(false);
        }
 
        _player_video_connection = _player.Video.connect(bind(&DCPFilmEncoder::video, this, _1, _2));
index 6dc1b6b6c65b9d0bfd8d4908671f250252848815..a3e78e8773e557cbb00b345d33c469b910537af0 100644 (file)
@@ -163,7 +163,6 @@ Film::Film (optional<boost::filesystem::path> dir)
        , _resolution (Resolution::TWO_K)
        , _encrypted (false)
        , _context_id (dcp::make_uuid ())
-       , _video_bit_rate(Config::instance()->default_video_bit_rate())
        , _video_frame_rate (24)
        , _audio_channels (Config::instance()->default_dcp_audio_channels ())
        , _three_d (false)
@@ -203,6 +202,10 @@ Film::Film (optional<boost::filesystem::path> dir)
                _studio = metadata["studio"];
        }
 
+       for (auto encoding: {VideoEncoding::JPEG2000, VideoEncoding::MPEG2}) {
+               _video_bit_rate[encoding] = Config::instance()->default_video_bit_rate(encoding);
+       }
+
        _playlist_change_connection = _playlist->Change.connect (bind (&Film::playlist_change, this, _1));
        _playlist_order_changed_connection = _playlist->OrderChange.connect (bind (&Film::playlist_order_changed, this));
        _playlist_content_change_connection = _playlist->ContentChange.connect (bind (&Film::playlist_content_change, this, _1, _2, _3, _4));
@@ -241,7 +244,7 @@ Film::video_identifier () const
                + "_" + resolution_to_string (_resolution)
                + "_" + _playlist->video_identifier()
                + "_" + raw_convert<string>(_video_frame_rate)
-               + "_" + raw_convert<string>(video_bit_rate());
+               + "_" + raw_convert<string>(video_bit_rate(video_encoding()));
 
        if (encrypted ()) {
                /* This is insecure but hey, the key is in plaintext in metadata.xml */
@@ -401,7 +404,8 @@ Film::metadata (bool with_content_paths) const
        }
 
        cxml::add_text_child(root, "Resolution", resolution_to_string(_resolution));
-       cxml::add_text_child(root, "VideoBitRate", raw_convert<string>(_video_bit_rate));
+       cxml::add_text_child(root, "J2KVideoBitRate", raw_convert<string>(_video_bit_rate[VideoEncoding::JPEG2000]));
+       cxml::add_text_child(root, "MPEG2VideoBitRate", raw_convert<string>(_video_bit_rate[VideoEncoding::MPEG2]));
        cxml::add_text_child(root, "VideoFrameRate", raw_convert<string>(_video_frame_rate));
        cxml::add_text_child(root, "AudioFrameRate", raw_convert<string>(_audio_frame_rate));
        cxml::add_text_child(root, "ISDCFDate", boost::gregorian::to_iso_string(_isdcf_date));
@@ -575,10 +579,11 @@ Film::read_metadata (optional<boost::filesystem::path> path)
 
        _resolution = string_to_resolution (f.string_child ("Resolution"));
        if (auto j2k = f.optional_number_child<int>("J2KBandwidth")) {
-               _video_bit_rate = *j2k;
+               _video_bit_rate[VideoEncoding::JPEG2000] = *j2k;
        } else {
-               _video_bit_rate = f.number_child<int64_t>("VideoBitRate");
+               _video_bit_rate[VideoEncoding::JPEG2000] = f.number_child<int64_t>("J2KVideoBitRate");
        }
+       _video_bit_rate[VideoEncoding::MPEG2] = f.optional_number_child<int64_t>("MPEG2VideoBitRate").get_value_or(Config::instance()->default_video_bit_rate(VideoEncoding::MPEG2));
        _video_frame_rate = f.number_child<int> ("VideoFrameRate");
        _audio_frame_rate = f.optional_number_child<int>("AudioFrameRate").get_value_or(48000);
        _encrypted = f.bool_child ("Encrypted");
@@ -1181,10 +1186,10 @@ Film::set_resolution (Resolution r, bool explicit_user)
 
 
 void
-Film::set_video_bit_rate(int64_t bit_rate)
+Film::set_video_bit_rate(VideoEncoding encoding, int64_t bit_rate)
 {
        FilmChangeSignaller ch(this, FilmProperty::VIDEO_BIT_RATE);
-       _video_bit_rate = bit_rate;
+       _video_bit_rate[encoding] = bit_rate;
 }
 
 /** @param f New frame rate.
@@ -1802,7 +1807,7 @@ Film::make_kdm(boost::filesystem::path cpl_file, dcp::LocalTime from, dcp::Local
 uint64_t
 Film::required_disk_space () const
 {
-       return _playlist->required_disk_space (shared_from_this(), video_bit_rate(), audio_channels(), audio_frame_rate());
+       return _playlist->required_disk_space (shared_from_this(), video_bit_rate(video_encoding()), audio_channels(), audio_frame_rate());
 }
 
 /** This method checks the disk that the Film is on and tries to decide whether or not
@@ -1934,7 +1939,7 @@ Film::reels () const
                /* Integer-divide reel length by the size of one frame to give the number of frames per reel,
                 * making sure we don't go less than 1s long.
                 */
-               Frame const reel_in_frames = max(_reel_length / ((video_bit_rate() / video_frame_rate()) / 8), static_cast<Frame>(video_frame_rate()));
+               Frame const reel_in_frames = max(_reel_length / ((video_bit_rate(video_encoding()) / video_frame_rate()) / 8), static_cast<Frame>(video_frame_rate()));
                while (current < len) {
                        DCPTime end = min (len, current + DCPTime::from_frames (reel_in_frames, video_frame_rate ()));
                        periods.emplace_back(current, end);
@@ -1978,7 +1983,9 @@ Film::use_template (string name)
        _dcp_content_type = _template_film->_dcp_content_type;
        _container = _template_film->_container;
        _resolution = _template_film->_resolution;
-       _video_bit_rate = _template_film->_video_bit_rate;
+       for (auto encoding: { VideoEncoding::JPEG2000, VideoEncoding::MPEG2 }) {
+               _video_bit_rate[encoding] = _template_film->_video_bit_rate[encoding];
+       }
        _video_frame_rate = _template_film->_video_frame_rate;
        _encrypted = _template_film->_encrypted;
        _audio_channels = _template_film->_audio_channels;
index ff3dee6fcf62d81d05242d93bac28a845271429a..e2e88e2c9fe294569c40b165e88f51e7e68a68dd 100644 (file)
@@ -32,6 +32,7 @@
 #include "change_signaller.h"
 #include "dcp_text_track.h"
 #include "dcpomatic_time.h"
+#include "enum_indexed_vector.h"
 #include "film_property.h"
 #include "frame_rate_change.h"
 #include "named_channel.h"
@@ -251,8 +252,8 @@ public:
                return _key;
        }
 
-       int video_bit_rate() const {
-               return _video_bit_rate;
+       int video_bit_rate(VideoEncoding encoding) const {
+               return _video_bit_rate[encoding];
        }
 
        /** @return The frame rate of the DCP */
@@ -406,7 +407,7 @@ public:
        void set_container (Ratio const *, bool user_explicit = true);
        void set_resolution (Resolution, bool user_explicit = true);
        void set_encrypted (bool);
-       void set_video_bit_rate(int64_t);
+       void set_video_bit_rate(VideoEncoding encoding, int64_t);
        void set_video_frame_rate (int rate, bool user_explicit = false);
        void set_audio_channels (int);
        void set_three_d (bool);
@@ -521,8 +522,8 @@ private:
         *  re-start picture MXF encodes.
         */
        std::string _context_id;
-       /** bit rate for encoding video using J2K or MPEG2 in bits per second */
-       int64_t _video_bit_rate;
+       /** bit rate for encoding video using in bits per second */
+       EnumIndexedVector<int64_t, VideoEncoding> _video_bit_rate;
        /** Frames per second to run our DCP at */
        int _video_frame_rate;
        /** The date that we should use in a ISDCF name */
index fc9b74a579628c1db21d69405917c92379dacea9..81622ad9d8e1d1e303078731a76c2c6b7a53a33f 100644 (file)
@@ -226,7 +226,7 @@ public:
                                        device,
                                        _dcpomatic_context->film->resolution() == Resolution::FOUR_K,
                                        _dcpomatic_context->film->video_frame_rate(),
-                                       _dcpomatic_context->film->video_bit_rate(),
+                                       _dcpomatic_context->film->video_bit_rate(VideoEncoding::JPEG2000),
                                        grok.licence_server,
                                        grok.licence_port,
                                        grok.licence)) {
index fc59fa703a6252e9c08d2483cfd13afa2117f8b8..8e678fdf15987916c48f48593d9a9b1680d28c0a 100644 (file)
@@ -175,7 +175,7 @@ Hints::check_unusual_container ()
 void
 Hints::check_high_video_bit_rate()
 {
-       if (film()->video_bit_rate() >= 245000000) {
+       if (film()->video_encoding() == VideoEncoding::JPEG2000 && film()->video_bit_rate(VideoEncoding::JPEG2000) >= 245000000) {
                hint (_("A few projectors have problems playing back very high bit-rate DCPs.  It is a good idea to drop the video bit rate down to about 200Mbit/s; this is unlikely to have any visible effect on the image."));
        }
 }
index d5c7b3eed635a63334ebe5c806e10782baefa25d..094e104ef7b2937b7adeeaf2deef4fdf94c9ff3f 100644 (file)
@@ -310,7 +310,7 @@ J2KEncoder::encode (shared_ptr<PlayerVideo> pv, DCPTime time)
                                pv,
                                position,
                                _film->video_frame_rate(),
-                               _film->video_bit_rate(),
+                               _film->video_bit_rate(VideoEncoding::JPEG2000),
                                _film->resolution()
                                );
                _queue.push_back (dcpv);
index e4707721c374b9fadd5d67f7abc005c00c0e801c..b7275619410defdbf4730f033c92c34dc3c20418 100644 (file)
@@ -91,7 +91,7 @@ make_dcp (shared_ptr<Film> film, TranscodeJob::ChangedBehaviour behaviour)
                LOG_GENERAL ("Content: %1", content->technical_summary());
        }
        LOG_GENERAL ("DCP video rate %1 fps", film->video_frame_rate());
-       LOG_GENERAL("Video bit rate %1", film->video_bit_rate());
+       LOG_GENERAL("Video bit rate %1", film->video_bit_rate(film->video_encoding()));
 
        auto tj = make_shared<DCPTranscodeJob>(film, behaviour);
        tj->set_encoder(make_shared<DCPFilmEncoder>(film, tj));
index 49bff19d4ec8944ad89ae5debb24b6224269ecdf..9b9cdfd091cefa2e83e1d14c6bd78901ae97bc14 100644 (file)
@@ -32,7 +32,7 @@ using std::shared_ptr;
 
 MPEG2Encoder::MPEG2Encoder(shared_ptr<const Film> film, Writer& writer)
        : VideoEncoder(film, writer)
-       , _transcoder(film->frame_size(), film->video_frame_rate(), film->video_bit_rate())
+       , _transcoder(film->frame_size(), film->video_frame_rate(), film->video_bit_rate(VideoEncoding::MPEG2))
 {
 
 }
index ead1a2eaf076177f5eda9142f0026f01f3dedd66..de68c6ae9dccc87fb9a4a783a300fee5ffea2aa5 100644 (file)
@@ -34,6 +34,8 @@ video_encoding_to_string(VideoEncoding encoding)
                return "jpeg2000";
        case VideoEncoding::MPEG2:
                return "mpeg2";
+       case VideoEncoding::COUNT:
+               DCPOMATIC_ASSERT(false);
        }
 
        DCPOMATIC_ASSERT(false);
index 45ee0b21eb0e8694ff069a9a76e93d7169c2df70..7c240f06f68d0996c913a7436152506dfefe7e9c 100644 (file)
 */
 
 
+#ifndef DCPOMATIC_VIDEO_ENCODING_H
+#define DCPOMATIC_VIDEO_ENCODING_H
+
+
 #include <string>
 
 
 enum class VideoEncoding
 {
        JPEG2000,
-       MPEG2
+       MPEG2,
+       COUNT
 };
 
 
 std::string video_encoding_to_string(VideoEncoding encoding);
 VideoEncoding video_encoding_from_string(std::string const& encoding);
 
+
+#endif
+
index b593489089edef9abab3a6f9df5cf41e67bd6c5a..49caf5cb2d359f59c3d5fd91b061fcf5b86bb000 100644 (file)
@@ -94,7 +94,7 @@ print_dump (shared_ptr<Film> film)
 {
        cout << film->dcp_name (true) << "\n"
             << film->container()->container_nickname() << " at " << ((film->resolution() == Resolution::TWO_K) ? "2K" : "4K") << "\n"
-            << (film->video_bit_rate() / 1000000) << "Mbit/s" << "\n"
+            << (film->video_bit_rate(film->video_encoding()) / 1000000) << "Mbit/s" << "\n"
             << "Duration " << (film->length().timecode(film->video_frame_rate())) << "\n"
             << "Output " << film->video_frame_rate() << "fps " << (film->three_d() ? "3D" : "2D") << " " << (film->audio_frame_rate() / 1000) << "kHz\n"
             << (film->interop() ? "Inter-Op" : "SMPTE") << " " << (film->encrypted() ? "encrypted" : "unencrypted") << "\n";
index 8ee95df18f65a7823dbb920233a7b93b4fb4a16b..bc8ac859c5ab9841233d221beee5db55da37bdf1 100644 (file)
@@ -270,7 +270,7 @@ DCPPanel::video_bit_rate_changed()
                return;
        }
 
-       _film->set_video_bit_rate(_video_bit_rate->GetValue() * 1000000);
+       _film->set_video_bit_rate(_film->video_encoding(), _video_bit_rate->GetValue() * 1000000);
 }
 
 
@@ -397,7 +397,7 @@ DCPPanel::film_changed(FilmProperty p)
                setup_dcp_name ();
                break;
        case FilmProperty::VIDEO_BIT_RATE:
-               checked_set(_video_bit_rate, _film->video_bit_rate() / 1000000);
+               checked_set(_video_bit_rate, _film->video_bit_rate(_film->video_encoding()) / 1000000);
                break;
        case FilmProperty::USE_ISDCF_NAME:
        {
@@ -460,6 +460,7 @@ DCPPanel::film_changed(FilmProperty p)
                set_standard();
                setup_container();
                setup_sensitivity();
+               film_changed(FilmProperty::VIDEO_BIT_RATE);
                break;
        case FilmProperty::LIMIT_TO_SMPTE_BV20:
                set_standard();
@@ -754,7 +755,8 @@ DCPPanel::reencode_j2k_changed ()
 void
 DCPPanel::config_changed (Config::Property p)
 {
-       _video_bit_rate->SetRange(1, Config::instance()->maximum_video_bit_rate() / 1000000);
+       VideoEncoding const encoding = _film ? _film->video_encoding() : VideoEncoding::JPEG2000;
+       _video_bit_rate->SetRange(1, Config::instance()->maximum_video_bit_rate(encoding) / 1000000);
        setup_frame_rate_widget ();
 
        if (p == Config::SHOW_EXPERIMENTAL_AUDIO_PROCESSORS) {
@@ -836,7 +838,8 @@ DCPPanel::make_video_panel ()
                _frame_rate_choice->add_entry(boost::lexical_cast<string>(i));
        }
 
-       _video_bit_rate->SetRange(1, Config::instance()->maximum_video_bit_rate() / 1000000);
+       VideoEncoding const encoding = _film ? _film->video_encoding() : VideoEncoding::JPEG2000;
+       _video_bit_rate->SetRange(1, Config::instance()->maximum_video_bit_rate(encoding) / 1000000);
        _frame_rate_spin->SetRange (1, 480);
 
        _resolution->add_entry(_("2K"));
index 092c9ab26821d2468363776986a0dc9cc323bb54..00e5575b180c156ba83b3f344cdcc7ef8b58e3b1 100644 (file)
@@ -320,10 +320,19 @@ private:
                table->Add (_dcp_audio_channels);
 
                {
-                       add_label_to_sizer (table, _panel, _("Default JPEG2000 bandwidth"), true, 0, wxLEFT | wxRIGHT | wxALIGN_CENTRE_VERTICAL);
+                       add_label_to_sizer(table, _panel, _("Default JPEG2000 bit rate"), true, 0, wxLEFT | wxRIGHT | wxALIGN_CENTRE_VERTICAL);
                        auto s = new wxBoxSizer (wxHORIZONTAL);
-                       _video_bit_rate = new wxSpinCtrl(_panel);
-                       s->Add(_video_bit_rate);
+                       _j2k_video_bit_rate = new wxSpinCtrl(_panel);
+                       s->Add(_j2k_video_bit_rate);
+                       add_label_to_sizer (s, _panel, _("Mbit/s"), false, 0, wxLEFT | wxRIGHT | wxALIGN_CENTRE_VERTICAL);
+                       table->Add (s, 1);
+               }
+
+               {
+                       add_label_to_sizer(table, _panel, _("Default MPEG2 bit rate"), true, 0, wxLEFT | wxRIGHT | wxALIGN_CENTRE_VERTICAL);
+                       auto s = new wxBoxSizer (wxHORIZONTAL);
+                       _mpeg2_video_bit_rate = new wxSpinCtrl(_panel);
+                       s->Add(_mpeg2_video_bit_rate);
                        add_label_to_sizer (s, _panel, _("Mbit/s"), false, 0, wxLEFT | wxRIGHT | wxALIGN_CENTRE_VERTICAL);
                        table->Add (s, 1);
                }
@@ -410,8 +419,10 @@ private:
                _dcp_content_type->Bind (wxEVT_CHOICE, boost::bind (&DefaultsPage::dcp_content_type_changed, this));
                _dcp_audio_channels->Bind (wxEVT_CHOICE, boost::bind (&DefaultsPage::dcp_audio_channels_changed, this));
 
-               _video_bit_rate->SetRange(50, 250);
-               _video_bit_rate->Bind(wxEVT_SPINCTRL, boost::bind(&DefaultsPage::video_bit_rate_changed, this));
+               _j2k_video_bit_rate->SetRange(50, 250);
+               _j2k_video_bit_rate->Bind(wxEVT_SPINCTRL, boost::bind(&DefaultsPage::j2k_video_bit_rate_changed, this));
+               _mpeg2_video_bit_rate->SetRange(1, 50);
+               _mpeg2_video_bit_rate->Bind(wxEVT_SPINCTRL, boost::bind(&DefaultsPage::mpeg2_video_bit_rate_changed, this));
 
                _audio_delay->SetRange (-1000, 1000);
                _audio_delay->Bind (wxEVT_SPINCTRL, boost::bind (&DefaultsPage::audio_delay_changed, this));
@@ -451,8 +462,10 @@ private:
                _kdm_directory->SetPath (std_to_wx (config->default_kdm_directory_or (wx_to_std (wxStandardPaths::Get().GetDocumentsDir())).string ()));
                _kdm_type->set (config->default_kdm_type());
                checked_set (_use_isdcf_name_by_default, config->use_isdcf_name_by_default());
-               checked_set(_video_bit_rate, config->default_video_bit_rate() / 1000000);
-               _video_bit_rate->SetRange(50, config->maximum_video_bit_rate() / 1000000);
+               checked_set(_j2k_video_bit_rate, config->default_video_bit_rate(VideoEncoding::JPEG2000) / 1000000);
+               _j2k_video_bit_rate->SetRange(50, config->maximum_video_bit_rate(VideoEncoding::JPEG2000) / 1000000);
+               checked_set(_mpeg2_video_bit_rate, config->default_video_bit_rate(VideoEncoding::MPEG2) / 1000000);
+               _mpeg2_video_bit_rate->SetRange(1, config->maximum_video_bit_rate(VideoEncoding::MPEG2) / 1000000);
                checked_set (_dcp_audio_channels, locale_convert<string> (config->default_dcp_audio_channels()));
                checked_set (_audio_delay, config->default_audio_delay ());
                checked_set (_standard, config->default_interop() ? 1 : 0);
@@ -527,9 +540,14 @@ private:
                config->set_default_kdm_duration (RoughDuration(duration, unit));
        }
 
-       void video_bit_rate_changed()
+       void j2k_video_bit_rate_changed()
+       {
+               Config::instance()->set_default_video_bit_rate(VideoEncoding::JPEG2000, _j2k_video_bit_rate->GetValue() * 1000000);
+       }
+
+       void mpeg2_video_bit_rate_changed()
        {
-               Config::instance()->set_default_video_bit_rate(_video_bit_rate->GetValue() * 1000000);
+               Config::instance()->set_default_video_bit_rate(VideoEncoding::MPEG2, _mpeg2_video_bit_rate->GetValue() * 1000000);
        }
 
        void audio_delay_changed ()
@@ -634,7 +652,8 @@ private:
                }
        }
 
-       wxSpinCtrl* _video_bit_rate;
+       wxSpinCtrl* _j2k_video_bit_rate;
+       wxSpinCtrl* _mpeg2_video_bit_rate;
        wxSpinCtrl* _audio_delay;
        wxSpinCtrl* _still_length;
 #ifdef DCPOMATIC_USE_OWN_PICKER
@@ -1541,10 +1560,19 @@ private:
                _panel->GetSizer()->Add(table, 1, wxALL | wxEXPAND, _border);
 
                {
-                       add_label_to_sizer(table, _panel, _("Maximum JPEG2000 bandwidth"), true, 0, wxLEFT | wxRIGHT | wxALIGN_CENTRE_VERTICAL);
+                       add_label_to_sizer(table, _panel, _("Maximum JPEG2000 bit rate"), true, 0, wxLEFT | wxRIGHT | wxALIGN_CENTRE_VERTICAL);
                        auto s = new wxBoxSizer(wxHORIZONTAL);
-                       _maximum_video_bit_rate = new wxSpinCtrl(_panel);
-                       s->Add(_maximum_video_bit_rate, 1);
+                       _maximum_j2k_video_bit_rate = new wxSpinCtrl(_panel);
+                       s->Add(_maximum_j2k_video_bit_rate, 1);
+                       add_label_to_sizer(s, _panel, _("Mbit/s"), false, 0, wxLEFT | wxALIGN_CENTRE_VERTICAL);
+                       table->Add(s, 1);
+               }
+
+               {
+                       add_label_to_sizer(table, _panel, _("Maximum MPEG2 bit rate"), true, 0, wxLEFT | wxRIGHT | wxALIGN_CENTRE_VERTICAL);
+                       auto s = new wxBoxSizer(wxHORIZONTAL);
+                       _maximum_mpeg2_video_bit_rate = new wxSpinCtrl(_panel);
+                       s->Add(_maximum_mpeg2_video_bit_rate, 1);
                        add_label_to_sizer(s, _panel, _("Mbit/s"), false, 0, wxLEFT | wxALIGN_CENTRE_VERTICAL);
                        table->Add(s, 1);
                }
@@ -1573,8 +1601,10 @@ private:
                        table->Add(s, 1);
                }
 
-               _maximum_video_bit_rate->SetRange(1, 1000);
-               _maximum_video_bit_rate->Bind(wxEVT_SPINCTRL, boost::bind(&NonStandardPage::maximum_video_bit_rate_changed, this));
+               _maximum_j2k_video_bit_rate->SetRange(1, 1000);
+               _maximum_j2k_video_bit_rate->Bind(wxEVT_SPINCTRL, boost::bind(&NonStandardPage::maximum_j2k_video_bit_rate_changed, this));
+               _maximum_mpeg2_video_bit_rate->SetRange(1, 100);
+               _maximum_mpeg2_video_bit_rate->Bind(wxEVT_SPINCTRL, boost::bind(&NonStandardPage::maximum_mpeg2_video_bit_rate_changed, this));
                _allow_any_dcp_frame_rate->bind(&NonStandardPage::allow_any_dcp_frame_rate_changed, this);
                _allow_any_container->bind(&NonStandardPage::allow_any_container_changed, this);
                _allow_96khz_audio->bind(&NonStandardPage::allow_96khz_audio_changed, this);
@@ -1588,7 +1618,8 @@ private:
        {
                auto config = Config::instance();
 
-               checked_set(_maximum_video_bit_rate, config->maximum_video_bit_rate() / 1000000);
+               checked_set(_maximum_j2k_video_bit_rate, config->maximum_video_bit_rate(VideoEncoding::JPEG2000) / 1000000);
+               checked_set(_maximum_mpeg2_video_bit_rate, config->maximum_video_bit_rate(VideoEncoding::MPEG2) / 1000000);
                checked_set(_allow_any_dcp_frame_rate, config->allow_any_dcp_frame_rate());
                checked_set(_allow_any_container, config->allow_any_container());
                checked_set(_allow_96khz_audio, config->allow_96khz_audio());
@@ -1597,9 +1628,14 @@ private:
                checked_set(_isdcf_name_part_length, config->isdcf_name_part_length());
        }
 
-       void maximum_video_bit_rate_changed()
+       void maximum_j2k_video_bit_rate_changed()
+       {
+               Config::instance()->set_maximum_video_bit_rate(VideoEncoding::JPEG2000, _maximum_j2k_video_bit_rate->GetValue() * 1000000);
+       }
+
+       void maximum_mpeg2_video_bit_rate_changed()
        {
-               Config::instance()->set_maximum_video_bit_rate(_maximum_video_bit_rate->GetValue() * 1000000);
+               Config::instance()->set_maximum_video_bit_rate(VideoEncoding::MPEG2, _maximum_mpeg2_video_bit_rate->GetValue() * 1000000);
        }
 
        void allow_any_dcp_frame_rate_changed()
@@ -1632,7 +1668,8 @@ private:
                Config::instance()->set_isdcf_name_part_length(_isdcf_name_part_length->GetValue());
        }
 
-       wxSpinCtrl* _maximum_video_bit_rate = nullptr;
+       wxSpinCtrl* _maximum_j2k_video_bit_rate = nullptr;
+       wxSpinCtrl* _maximum_mpeg2_video_bit_rate = nullptr;
        CheckBox* _allow_any_dcp_frame_rate = nullptr;
        CheckBox* _allow_any_container = nullptr;
        CheckBox* _allow_96khz_audio = nullptr;
index 3ab3245220bd2a11cdf2e16a28221e4de063befc..06f2a187ab398bc2e26034d4e0b178610315b63e 160000 (submodule)
--- a/test/data
+++ b/test/data
@@ -1 +1 @@
-Subproject commit 3ab3245220bd2a11cdf2e16a28221e4de063befc
+Subproject commit 06f2a187ab398bc2e26034d4e0b178610315b63e
index 2f1346d1da5a6c032298d5531ebe06182169312b..c52df6d72b18d6c53699f88f2ceb2ab594517b44 100644 (file)
@@ -57,7 +57,7 @@ BOOST_AUTO_TEST_CASE (film_metadata_test)
        film->set_name ("fred");
        film->set_dcp_content_type (DCPContentType::from_isdcf_name ("SHR"));
        film->set_container (Ratio::from_id ("185"));
-       film->set_video_bit_rate(200000000);
+       film->set_video_bit_rate(VideoEncoding::JPEG2000, 200000000);
        film->set_interop (false);
        film->set_chain (string(""));
        film->set_distributor (string(""));
index 67579a3699c615dd5b66aca2929ca8a9f95b1c29..ab4c4271ede5074392776cbd26be1a8801a7253c 100644 (file)
@@ -47,7 +47,7 @@ check (int target_bits_per_second)
        auto film = new_test_film (name);
        film->set_name (name);
        film->set_dcp_content_type (DCPContentType::from_isdcf_name ("FTR"));
-       film->set_video_bit_rate(target_bits_per_second);
+       film->set_video_bit_rate(VideoEncoding::JPEG2000, target_bits_per_second);
        auto content = make_shared<ImageContent>(TestPaths::private_data() / "prophet_frame.tiff");
        film->examine_and_add_content (content);
        BOOST_REQUIRE (!wait_for_jobs());
index 5fcddfe781378ade48ce2ad86be6d5f4efeee13f..e6d8cf9c6168971c20eec267df91190c7584b553 100644 (file)
@@ -88,7 +88,7 @@ BOOST_AUTO_TEST_CASE (reels_test1)
        BOOST_CHECK_EQUAL (r.back().from.get(), 288000);
        BOOST_CHECK_EQUAL (r.back().to.get(), 288000 * 2);
 
-       film->set_video_bit_rate(100000000);
+       film->set_video_bit_rate(VideoEncoding::JPEG2000, 100000000);
        film->set_reel_type (ReelType::BY_LENGTH);
        /* This is just over 2.5s at 100Mbit/s; should correspond to 60 frames */
        film->set_reel_length (31253154);
@@ -310,7 +310,7 @@ BOOST_AUTO_TEST_CASE (reels_test6)
        auto A = make_shared<FFmpegContent>("test/data/test2.mp4");
        auto film = new_test_film2 ("reels_test6", {A});
 
-       film->set_video_bit_rate(100000000);
+       film->set_video_bit_rate(VideoEncoding::JPEG2000, 100000000);
        film->set_reel_type (ReelType::BY_LENGTH);
        /* This is just over 2.5s at 100Mbit/s; should correspond to 60 frames */
        film->set_reel_length (31253154);
index bd969bdb27a56d75a3c2f47558f39a55e4c67ab5..e26a091698be05469e9d44e65c44aa7c46a3fa28 100644 (file)
@@ -45,7 +45,7 @@ void check_within_n (int64_t a, int64_t b, int64_t n)
 BOOST_AUTO_TEST_CASE (required_disk_space_test)
 {
        auto film = new_test_film ("required_disk_space_test");
-       film->set_video_bit_rate(100000000);
+       film->set_video_bit_rate(VideoEncoding::JPEG2000, 100000000);
        film->set_audio_channels(8);
        film->set_reel_type (ReelType::BY_VIDEO_CONTENT);
        auto content_a = content_factory("test/data/flat_blue.png")[0];
index 1d5eb9083e92267db462b7de1cc777d9b2ab2253..ddd3d26f0ef60d76a2a61f603895433988155b42 100644 (file)
@@ -122,7 +122,7 @@ setup_test_config ()
        Config::instance()->set_server_port_base (61921);
        Config::instance()->set_default_dcp_content_type (static_cast<DCPContentType*> (0));
        Config::instance()->set_default_audio_delay (0);
-       Config::instance()->set_default_video_bit_rate(100000000);
+       Config::instance()->set_default_video_bit_rate(VideoEncoding::JPEG2000, 100000000);
        Config::instance()->set_default_interop (false);
        Config::instance()->set_default_still_length (10);
        Config::instance()->set_default_dcp_audio_channels(8);