#include "dcp_content_type.h"
#include "ratio.h"
#include "cross.h"
-#include "safe_stringstream.h"
#include "environment_info.h"
-#include "raw_convert.h"
#include "audio_processor.h"
#include "digester.h"
#include "compose.hpp"
#include <dcp/util.h>
#include <dcp/local_time.h>
#include <dcp/decrypted_kdm.h>
+#include <dcp/raw_convert.h>
#include <libxml++/libxml++.h>
#include <boost/filesystem.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/foreach.hpp>
+#include <boost/regex.hpp>
#include <unistd.h>
#include <stdexcept>
#include <iostream>
using boost::dynamic_pointer_cast;
using boost::optional;
using boost::is_any_of;
+using dcp::raw_convert;
#define LOG_GENERAL(...) log()->log (String::compose (__VA_ARGS__), LogEntry::TYPE_GENERAL);
#define LOG_GENERAL_NC(...) log()->log (__VA_ARGS__, LogEntry::TYPE_GENERAL);
* 33 -> 34
* Content only contains audio/subtitle-related tags if those things
* are present.
+ * 34 -> 35
+ * VideoFrameType in VideoContent is a string rather than an integer.
+ * 35 -> 36
+ * EffectColour rather than OutlineColour in Subtitle.
*/
-int const Film::current_state_version = 34;
+int const Film::current_state_version = 36;
/** Construct a Film object in a given directory.
*
, _j2k_bandwidth (Config::instance()->default_j2k_bandwidth ())
, _isdcf_metadata (Config::instance()->default_isdcf_metadata ())
, _video_frame_rate (24)
- , _audio_channels (6)
+ , _audio_channels (Config::instance()->default_dcp_audio_channels ())
, _three_d (false)
, _sequence (true)
, _interop (Config::instance()->default_interop ())
{
DCPOMATIC_ASSERT (container ());
- SafeStringStream s;
- s.imbue (std::locale::classic ());
-
- s << container()->id()
- << "_" << resolution_to_string (_resolution)
- << "_" << _playlist->video_identifier()
- << "_" << _video_frame_rate
- << "_" << j2k_bandwidth();
+ string s = container()->id()
+ + "_" + resolution_to_string (_resolution)
+ + "_" + _playlist->video_identifier()
+ + "_" + raw_convert<string>(_video_frame_rate)
+ + "_" + raw_convert<string>(j2k_bandwidth());
if (encrypted ()) {
- s << "_E";
+ s += "_E";
} else {
- s << "_P";
+ s += "_P";
}
if (_interop) {
- s << "_I";
+ s += "_I";
} else {
- s << "_S";
+ s += "_S";
}
if (_three_d) {
- s << "_3D";
+ s += "_3D";
}
- return s.str ();
+ return s;
}
/** @return The file to write video frame info to */
if (_audio_processor) {
root->add_child("AudioProcessor")->add_child_text (_audio_processor->id ());
}
- root->add_child("ReelType")->add_child_text (raw_convert<string> (_reel_type));
+ root->add_child("ReelType")->add_child_text (raw_convert<string> (static_cast<int> (_reel_type)));
root->add_child("ReelLength")->add_child_text (raw_convert<string> (_reel_length));
root->add_child("UploadAfterMakeDCP")->add_child_text (_upload_after_make_dcp ? "1" : "0");
_playlist->as_xml (root->add_child ("Playlist"));
string
Film::isdcf_name (bool if_created_now) const
{
- SafeStringStream d;
+ string d;
string raw_name = name ();
fixed_name = fixed_name.substr (0, 14);
}
- d << fixed_name;
+ d += fixed_name;
if (dcp_content_type()) {
- d << "_" << dcp_content_type()->isdcf_name();
- d << "-" << isdcf_metadata().content_version;
+ d += "_" + dcp_content_type()->isdcf_name();
+ d += "-" + raw_convert<string>(isdcf_metadata().content_version);
}
ISDCFMetadata const dm = isdcf_metadata ();
if (dm.temp_version) {
- d << "-Temp";
+ d += "-Temp";
}
if (dm.pre_release) {
- d << "-Pre";
+ d += "-Pre";
}
if (dm.red_band) {
- d << "-RedBand";
+ d += "-RedBand";
}
if (!dm.chain.empty ()) {
- d << "-" << dm.chain;
+ d += "-" + dm.chain;
}
if (three_d ()) {
- d << "-3D";
+ d += "-3D";
}
if (dm.two_d_version_of_three_d) {
- d << "-2D";
+ d += "-2D";
}
if (!dm.mastered_luminance.empty ()) {
- d << "-" << dm.mastered_luminance;
+ d += "-" + dm.mastered_luminance;
}
if (video_frame_rate() != 24) {
- d << "-" << video_frame_rate();
+ d += "-" + raw_convert<string>(video_frame_rate());
}
if (container()) {
- d << "_" << container()->isdcf_name();
+ d += "_" + container()->isdcf_name();
}
/* XXX: this uses the first bit of content only */
}
if (content_ratio && content_ratio != container()) {
- d << "-" << content_ratio->isdcf_name();
+ d += "-" + content_ratio->isdcf_name();
}
}
if (!dm.audio_language.empty ()) {
- d << "_" << dm.audio_language;
+ d += "_" + dm.audio_language;
if (!dm.subtitle_language.empty()) {
bool burnt_in = true;
transform (language.begin(), language.end(), language.begin(), ::toupper);
}
- d << "-" << language;
+ d += "-" + language;
} else {
- d << "-XX";
+ d += "-XX";
}
}
if (!dm.territory.empty ()) {
- d << "_" << dm.territory;
+ d += "_" + dm.territory;
if (dm.rating.empty ()) {
- d << "-NR";
+ d += "-NR";
} else {
- d << "-" << dm.rating;
+ d += "-" + dm.rating;
}
}
}
if (non_lfe) {
- d << "_" << non_lfe << lfe;
+ d += String::compose("_%1%2", non_lfe, lfe);
}
/* XXX: HI/VI */
- d << "_" << resolution_to_string (_resolution);
+ d += "_" + resolution_to_string (_resolution);
if (!dm.studio.empty ()) {
- d << "_" << dm.studio;
+ d += "_" + dm.studio;
}
if (if_created_now) {
- d << "_" << boost::gregorian::to_iso_string (boost::gregorian::day_clock::local_day ());
+ d += "_" + boost::gregorian::to_iso_string (boost::gregorian::day_clock::local_day ());
} else {
- d << "_" << boost::gregorian::to_iso_string (_isdcf_date);
+ d += "_" + boost::gregorian::to_iso_string (_isdcf_date);
}
if (!dm.facility.empty ()) {
- d << "_" << dm.facility;
+ d += "_" + dm.facility;
}
if (_interop) {
- d << "_IOP";
+ d += "_IOP";
} else {
- d << "_SMPTE";
+ d += "_SMPTE";
}
if (three_d ()) {
- d << "-3D";
+ d += "-3D";
}
bool vf = false;
}
if (vf) {
- d << "_VF";
+ d += "_VF";
} else {
- d << "_OV";
+ d += "_OV";
}
- return d.str ();
+ return d;
}
/** @return name to give the DCP */
p /= "j2c";
p /= video_identifier ();
- SafeStringStream s;
- s.width (8);
- s << setfill('0') << reel << "_" << frame;
+ char buffer[256];
+ snprintf(buffer, sizeof(buffer), "%08d_%08" PRId64, reel, frame);
+ string s (buffer);
if (eyes == EYES_LEFT) {
- s << ".L";
+ s += ".L";
} else if (eyes == EYES_RIGHT) {
- s << ".R";
+ s += ".R";
}
- s << ".j2c";
+ s += ".j2c";
if (tmp) {
- s << ".tmp";
+ s += ".tmp";
}
- p /= s.str();
+ p /= s;
return file (p);
}
/** Change the gains of the supplied AudioMapping to make it a default
* for this film. The defaults are guessed based on what processor (if any)
- * is in use and the number of input channels.
+ * is in use, the number of input channels and any filename supplied.
*/
void
-Film::make_audio_mapping_default (AudioMapping& mapping) const
+Film::make_audio_mapping_default (AudioMapping& mapping, optional<boost::filesystem::path> filename) const
{
+ static string const regex[] = {
+ ".*[\\._-]L[\\._-].*",
+ ".*[\\._-]R[\\._-].*",
+ ".*[\\._-]C[\\._-].*",
+ ".*[\\._-]Lfe[\\._-].*",
+ ".*[\\._-]Ls[\\._-].*",
+ ".*[\\._-]Rs[\\._-].*"
+ };
+
+ static int const regexes = sizeof(regex) / sizeof(*regex);
+
if (audio_processor ()) {
audio_processor()->make_audio_mapping_default (mapping);
} else {
mapping.make_zero ();
if (mapping.input_channels() == 1) {
- /* Mono -> Centre */
- mapping.set (0, static_cast<int> (dcp::CENTRE), 1);
+ bool guessed = false;
+
+ /* See if we can guess where this stream should go */
+ if (filename) {
+ for (int i = 0; i < regexes; ++i) {
+ boost::regex e (regex[i], boost::regex::icase);
+ if (boost::regex_match (filename->string(), e) && i < mapping.output_channels()) {
+ mapping.set (0, i, 1);
+ guessed = true;
+ }
+ }
+ }
+
+ if (!guessed) {
+ /* If we have no idea, just put it on centre */
+ mapping.set (0, static_cast<int> (dcp::CENTRE), 1);
+ }
} else {
/* 1:1 mapping */
for (int i = 0; i < min (mapping.input_channels(), mapping.output_channels()); ++i) {
{
optional<DCPTime> last_split;
shared_ptr<Content> last_video;
- ContentList cl = content ();
BOOST_FOREACH (shared_ptr<Content> c, content ()) {
if (c->video) {
BOOST_FOREACH (DCPTime t, c->reel_split_points()) {
return p;
}
+
+string
+Film::content_summary (DCPTimePeriod period) const
+{
+ return _playlist->content_summary (period);
+}