*/
/** @file src/film.cc
- * @brief A representation of some audio and video content, and details of
+ * @brief A representation of some audio, video and subtitle content, and details of
* how they should be presented in a DCP.
*/
#include "job.h"
#include "util.h"
#include "job_manager.h"
+#include "dcp_encoder.h"
#include "transcode_job.h"
#include "upload_job.h"
#include "null_log.h"
#define LOG_GENERAL(...) log()->log (String::compose (__VA_ARGS__), LogEntry::TYPE_GENERAL);
#define LOG_GENERAL_NC(...) log()->log (__VA_ARGS__, LogEntry::TYPE_GENERAL);
+string const Film::metadata_file = "metadata.xml";
+
/* 5 -> 6
* AudioMapping XML changed.
* 6 -> 7
}
if (name().empty()) {
- throw MissingSettingError (_("name"));
+ set_name ("DCP");
}
BOOST_FOREACH (shared_ptr<const Content> i, content ()) {
}
LOG_GENERAL ("J2K bandwidth %1", j2k_bandwidth());
- JobManager::instance()->add (shared_ptr<Job> (new TranscodeJob (shared_from_this())));
+ shared_ptr<TranscodeJob> tj (new TranscodeJob (shared_from_this()));
+ tj->set_encoder (shared_ptr<Encoder> (new DCPEncoder (shared_from_this(), tj)));
+ JobManager::instance()->add (tj);
}
/** Start a job to send our DCP to the configured TMS */
DCPOMATIC_ASSERT (directory());
boost::filesystem::create_directories (directory().get());
shared_ptr<xmlpp::Document> doc = metadata ();
- doc->write_to_file_formatted (file("metadata.xml").string ());
+ doc->write_to_file_formatted (file(metadata_file).string ());
_dirty = false;
}
Film::read_metadata (optional<boost::filesystem::path> path)
{
if (!path) {
- if (boost::filesystem::exists (file ("metadata")) && !boost::filesystem::exists (file ("metadata.xml"))) {
+ if (boost::filesystem::exists (file ("metadata")) && !boost::filesystem::exists (file (metadata_file))) {
throw runtime_error (_("This film was created with an older version of DCP-o-matic, and unfortunately it cannot be loaded into this version. You will need to create a new Film, re-add your content and set it up again. Sorry!"));
}
- path = file ("metadata.xml");
+ path = file (metadata_file);
}
cxml::Document f ("Metadata");
}
/** Given a directory name, return its full path within the Film's directory.
- * @param d directory name within the Filn's directory.
+ * @param d directory name within the Film's directory.
* @param create true to create the directory (and its parents) if they do not exist.
*/
boost::filesystem::path
/* Count mapped audio channels */
- int non_lfe = 0;
- int lfe = 0;
-
- BOOST_FOREACH (int i, mapped_audio_channels ()) {
- if (i >= audio_channels()) {
- /* This channel is mapped but is not included in the DCP */
- continue;
- }
-
- if (static_cast<dcp::Channel> (i) == dcp::LFE) {
- ++lfe;
- } else {
- ++non_lfe;
- }
- }
-
- if (non_lfe) {
- d += String::compose("_%1%2", non_lfe, lfe);
+ pair<int, int> ch = audio_channel_types (mapped_audio_channels(), audio_channels());
+ if (ch.first) {
+ d += String::compose("_%1%2", ch.first, ch.second);
}
/* XXX: HI/VI */
return _playlist->content ();
}
+/** @param content Content to add.
+ * @param disable_audio_analysis true to never do automatic audio analysis, even if it is enabled in configuration.
+ */
void
-Film::examine_and_add_content (shared_ptr<Content> c)
+Film::examine_and_add_content (shared_ptr<Content> content, bool disable_audio_analysis)
{
- if (dynamic_pointer_cast<FFmpegContent> (c) && _directory) {
- run_ffprobe (c->path(0), file ("ffprobe.log"), _log);
+ if (dynamic_pointer_cast<FFmpegContent> (content) && _directory) {
+ run_ffprobe (content->path(0), file ("ffprobe.log"), _log);
}
- shared_ptr<Job> j (new ExamineContentJob (shared_from_this(), c));
+ shared_ptr<Job> j (new ExamineContentJob (shared_from_this(), content));
_job_connections.push_back (
- j->Finished.connect (bind (&Film::maybe_add_content, this, weak_ptr<Job> (j), weak_ptr<Content> (c)))
+ j->Finished.connect (bind (&Film::maybe_add_content, this, weak_ptr<Job>(j), weak_ptr<Content>(content), disable_audio_analysis))
);
JobManager::instance()->add (j);
}
void
-Film::maybe_add_content (weak_ptr<Job> j, weak_ptr<Content> c)
+Film::maybe_add_content (weak_ptr<Job> j, weak_ptr<Content> c, bool disable_audio_analysis)
{
shared_ptr<Job> job = j.lock ();
if (!job || !job->finished_ok ()) {
add_content (content);
- if (Config::instance()->automatic_audio_analysis() && content->audio) {
+ if (Config::instance()->automatic_audio_analysis() && content->audio && !disable_audio_analysis) {
shared_ptr<Playlist> playlist (new Playlist);
playlist->add (content);
boost::signals2::connection c;
DCPTime
Film::length () const
{
- return _playlist->length ();
+ return _playlist->length().ceil(video_frame_rate());
}
int
Film::reels () const
{
list<DCPTimePeriod> p;
- DCPTime const len = length().ceil (video_frame_rate ());
+ DCPTime const len = length();
switch (reel_type ()) {
case REELTYPE_SINGLE:
_reel_length = _template_film->_reel_length;
_upload_after_make_dcp = _template_film->_upload_after_make_dcp;
}
+
+pair<double, double>
+Film::speed_up_range (int dcp_frame_rate) const
+{
+ return _playlist->speed_up_range (dcp_frame_rate);
+}
+
+void
+Film::copy_from (shared_ptr<const Film> film)
+{
+ read_metadata (film->file (metadata_file));
+}