summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2013-04-16 11:43:29 +0100
committerCarl Hetherington <cth@carlh.net>2013-04-16 11:43:29 +0100
commit147cca5876dfbdf56e21289c3a36bec4b4850191 (patch)
tree09a59d9e91c7e5ec68b8fb55d1a7b1fcc23c7519 /src/lib
parent50dd871c5a924660499b3fd599f1c68af5e3dbc1 (diff)
parentbe5dfa3ed0459392cc65d21f563f136b97a295ba (diff)
Merge master.
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/film.cc64
-rw-r--r--src/lib/film.h21
-rw-r--r--src/lib/po/sv_SE.po8
-rw-r--r--src/lib/trimmer.cc100
-rw-r--r--src/lib/trimmer.h39
-rw-r--r--src/lib/writer.cc31
-rw-r--r--src/lib/wscript1
7 files changed, 243 insertions, 21 deletions
diff --git a/src/lib/film.cc b/src/lib/film.cc
index 67605ffca..c8aee7a0a 100644
--- a/src/lib/film.cc
+++ b/src/lib/film.cc
@@ -98,6 +98,7 @@ Film::Film (string d, bool must_exist)
, _scaler (Scaler::from_id ("bicubic"))
, _trim_start (0)
, _trim_end (0)
+ , _trim_type (CPL)
, _ab (false)
, _audio_gain (0)
, _audio_delay (0)
@@ -165,6 +166,7 @@ Film::Film (Film const & o)
, _scaler (o._scaler)
, _trim_start (o._trim_start)
, _trim_end (o._trim_end)
+ , _trim_type (o._trim_type)
, _ab (o._ab)
, _audio_gain (o._audio_gain)
, _audio_delay (o._audio_delay)
@@ -223,19 +225,47 @@ Film::info_dir () const
}
string
-Film::video_mxf_dir () const
+Film::internal_video_mxf_dir () const
{
boost::filesystem::path p;
return dir ("video");
}
string
-Film::video_mxf_filename () const
+Film::internal_video_mxf_filename () const
{
return video_state_identifier() + ".mxf";
}
string
+Film::dcp_video_mxf_filename () const
+{
+ return filename_safe_name() + "_video.mxf";
+}
+
+string
+Film::dcp_audio_mxf_filename () const
+{
+ return filename_safe_name() + "_audio.mxf";
+}
+
+string
+Film::filename_safe_name () const
+{
+ string const n = name ();
+ string o;
+ for (size_t i = 0; i < n.length(); ++i) {
+ if (isalnum (n[i])) {
+ o += n[i];
+ } else {
+ o += "_";
+ }
+ }
+
+ return o;
+}
+
+string
Film::audio_analysis_path () const
{
boost::filesystem::path p;
@@ -385,12 +415,23 @@ Film::write_metadata () const
root->add_child("Name")->add_child_text (_name);
root->add_child("UseDCIName")->add_child_text (_use_dci_name ? "1" : "0");
root->add_child("TrustContentHeaders")->add_child_text (_trust_content_headers ? "1" : "0");
+
if (_dcp_content_type) {
root->add_child("DCPContentType")->add_child_text (_dcp_content_type->dci_name ());
}
+
if (_format) {
root->add_child("Format")->add_child_text (_format->id ());
}
+
+ switch (_trim_type) {
+ case CPL:
+ root->add_child("TrimType")->add_child_text ("CPL");
+ break;
+ case ENCODE:
+ root->add_child("TrimType")->add_child_text ("Encode");
+ }
+
root->add_child("LeftCrop")->add_child_text (boost::lexical_cast<string> (_crop.left));
root->add_child("RightCrop")->add_child_text (boost::lexical_cast<string> (_crop.right));
root->add_child("TopCrop")->add_child_text (boost::lexical_cast<string> (_crop.top));
@@ -455,6 +496,15 @@ Film::read_metadata ()
}
}
+ {
+ optional<string> c = f.optional_string_child ("TrimType");
+ if (!c || c.get() == "CPL") {
+ _trim_type = CPL;
+ } else if (c && c.get() == "Encode") {
+ _trim_type = ENCODE;
+ }
+ }
+
_crop.left = f.number_child<int> ("LeftCrop");
_crop.right = f.number_child<int> ("RightCrop");
_crop.top = f.number_child<int> ("TopCrop");
@@ -848,6 +898,16 @@ Film::set_trim_end (int t)
}
void
+Film::set_trim_type (TrimType t)
+{
+ {
+ boost::mutex::scoped_lock lm (_state_mutex);
+ _trim_type = t;
+ }
+ signal_changed (TRIM_TYPE);
+}
+
+void
Film::set_ab (bool a)
{
{
diff --git a/src/lib/film.h b/src/lib/film.h
index ffa5d0690..071f474ac 100644
--- a/src/lib/film.h
+++ b/src/lib/film.h
@@ -63,11 +63,14 @@ public:
std::string info_dir () const;
std::string j2c_path (int f, bool t) const;
std::string info_path (int f) const;
- std::string video_mxf_dir () const;
- std::string video_mxf_filename () const;
+ std::string internal_video_mxf_dir () const;
+ std::string internal_video_mxf_filename () const;
std::string audio_analysis_path () const;
void examine_content (boost::shared_ptr<Content>);
+ std::string dcp_video_mxf_filename () const;
+ std::string dcp_audio_mxf_filename () const;
+
void analyse_audio ();
void send_dcp_to_tms ();
void make_dcp ();
@@ -120,6 +123,11 @@ public:
void set_ffmpeg_subtitle_stream (FFmpegSubtitleStream);
void set_ffmpeg_audio_stream (FFmpegAudioStream);
+ enum TrimType {
+ CPL,
+ ENCODE
+ };
+
/** Identifiers for the parts of our state;
used for signalling changes.
*/
@@ -138,6 +146,7 @@ public:
TRIM_START,
TRIM_END,
AB,
+ TRIM_TYPE,
AUDIO_GAIN,
AUDIO_DELAY,
WITH_SUBTITLES,
@@ -213,6 +222,11 @@ public:
return _trim_end;
}
+ TrimType trim_type () const {
+ boost::mutex::scoped_lock lm (_state_mutex);
+ return _trim_type;
+ }
+
bool ab () const {
boost::mutex::scoped_lock lm (_state_mutex);
return _ab;
@@ -290,6 +304,7 @@ public:
void set_trim_start (int);
void set_trim_end (int);
void set_ab (bool);
+ void set_trim_type (TrimType);
void set_audio_gain (float);
void set_audio_delay (int);
void set_with_subtitles (bool);
@@ -322,6 +337,7 @@ private:
void content_changed (boost::weak_ptr<Content>, int);
boost::shared_ptr<FFmpegContent> ffmpeg () const;
void setup_default_audio_mapping ();
+ std::string filename_safe_name () const;
/** Log to write to */
boost::shared_ptr<Log> _log;
@@ -356,6 +372,7 @@ private:
int _trim_start;
/** Frames to trim off the end of the DCP */
int _trim_end;
+ TrimType _trim_type;
/** true to create an A/B comparison DCP, where the left half of the image
is the video without any filters or post-processing, and the right half
has the specified filters and post-processing.
diff --git a/src/lib/po/sv_SE.po b/src/lib/po/sv_SE.po
index c8695ce4d..f89874e35 100644
--- a/src/lib/po/sv_SE.po
+++ b/src/lib/po/sv_SE.po
@@ -8,10 +8,9 @@ msgstr ""
"Project-Id-Version: DCP-o-matic\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-04-09 11:14+0100\n"
-"PO-Revision-Date: 2013-04-09 10:13+0100\n"
+"PO-Revision-Date: 2013-04-10 15:35+0100\n"
"Last-Translator: Adam Klotblixt <adam.klotblixt@gmail.com>\n"
"Language-Team: \n"
-"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@@ -50,9 +49,8 @@ msgid "16:9 within Flat"
msgstr "16:9 innanför Flat"
#: src/lib/format.cc:115
-#, fuzzy
msgid "16:9 within Scope"
-msgstr "16:9 innanför Flat"
+msgstr "16:9 innanför Scope"
#: src/lib/filter.cc:88
msgid "3D denoiser"
@@ -76,7 +74,7 @@ msgstr "Reklam"
#: src/lib/job.cc:72
msgid "An error occurred whilst handling the file %1."
-msgstr "Ett fel inträffade vid hantering av filen (%1)"
+msgstr "Ett fel inträffade vid hantering av filen %1"
#: src/lib/analyse_audio_job.cc:49
msgid "Analyse audio of %1"
diff --git a/src/lib/trimmer.cc b/src/lib/trimmer.cc
new file mode 100644
index 000000000..68364e50a
--- /dev/null
+++ b/src/lib/trimmer.cc
@@ -0,0 +1,100 @@
+/*
+ Copyright (C) 2013 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
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <boost/shared_ptr.hpp>
+#include "trimmer.h"
+
+using std::cout;
+using std::max;
+using boost::shared_ptr;
+
+/** @param audio_sample_rate Audio sampling rate, or 0 if there is no audio */
+Trimmer::Trimmer (
+ shared_ptr<Log> log,
+ int video_trim_start,
+ int video_trim_end, int video_length,
+ int audio_sample_rate,
+ float frames_per_second,
+ int dcp_frames_per_second
+ )
+ : AudioVideoProcessor (log)
+ , _video_start (video_trim_start)
+ , _video_end (video_length - video_trim_end)
+ , _video_in (0)
+ , _audio_in (0)
+{
+ FrameRateConversion frc (frames_per_second, dcp_frames_per_second);
+
+ if (frc.skip) {
+ _video_start /= 2;
+ _video_end /= 2;
+ } else if (frc.repeat) {
+ _video_start *= 2;
+ _video_end *= 2;
+ }
+
+ if (audio_sample_rate) {
+ _audio_start = video_frames_to_audio_frames (_video_start, audio_sample_rate, frames_per_second);
+ _audio_end = video_frames_to_audio_frames (_video_end, audio_sample_rate, frames_per_second);
+ }
+}
+
+void
+Trimmer::process_video (shared_ptr<Image> image, bool same, shared_ptr<Subtitle> sub)
+{
+ if (_video_in >= _video_start && _video_in <= _video_end) {
+ Video (image, same, sub);
+ }
+
+ ++_video_in;
+}
+
+void
+Trimmer::process_audio (shared_ptr<AudioBuffers> audio)
+{
+ int64_t offset = _audio_start - _audio_in;
+ if (offset > audio->frames()) {
+ _audio_in += audio->frames ();
+ return;
+ }
+
+ if (offset < 0) {
+ offset = 0;
+ }
+
+ int64_t length = _audio_end - max (_audio_in, _audio_start);
+ if (length < 0) {
+ _audio_in += audio->frames ();
+ return;
+ }
+
+ if (length > (audio->frames() - offset)) {
+ length = audio->frames () - offset;
+ }
+
+ _audio_in += audio->frames ();
+
+ if (offset != 0 || length != audio->frames ()) {
+ audio->move (offset, 0, length);
+ audio->set_frames (length);
+ }
+
+ Audio (audio);
+}
+
diff --git a/src/lib/trimmer.h b/src/lib/trimmer.h
new file mode 100644
index 000000000..ff7e9514d
--- /dev/null
+++ b/src/lib/trimmer.h
@@ -0,0 +1,39 @@
+/*
+ Copyright (C) 2013 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
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "processor.h"
+
+class Trimmer : public AudioVideoProcessor
+{
+public:
+ Trimmer (boost::shared_ptr<Log>, int, int, int, int, float, int);
+
+ void process_video (boost::shared_ptr<Image> i, bool, boost::shared_ptr<Subtitle> s);
+ void process_audio (boost::shared_ptr<AudioBuffers>);
+
+private:
+ friend class trimmer_test;
+
+ int _video_start;
+ int _video_end;
+ int _video_in;
+ int64_t _audio_start;
+ int64_t _audio_end;
+ int64_t _audio_in;
+};
diff --git a/src/lib/writer.cc b/src/lib/writer.cc
index 7258826ba..8e771a5e2 100644
--- a/src/lib/writer.cc
+++ b/src/lib/writer.cc
@@ -69,8 +69,8 @@ Writer::Writer (shared_ptr<Film> f)
_picture_asset.reset (
new libdcp::MonoPictureAsset (
- _film->video_mxf_dir (),
- _film->video_mxf_filename (),
+ _film->internal_video_mxf_dir (),
+ _film->internal_video_mxf_filename (),
_film->dcp_frame_rate (),
_film->format()->dcp_size ()
)
@@ -82,7 +82,7 @@ Writer::Writer (shared_ptr<Film> f)
_sound_asset.reset (
new libdcp::SoundAsset (
_film->dir (_film->dcp_name()),
- N_("audio.mxf"),
+ _film->dcp_audio_mxf_filename (),
_film->dcp_frame_rate (),
_film->audio_mapping().dcp_channels (),
dcp_audio_sample_rate (_film->audio_frame_rate())
@@ -261,20 +261,25 @@ Writer::finish ()
}
int const frames = _last_written_frame + 1;
- int const duration = frames - _film->trim_start() - _film->trim_end();
+ int duration = 0;
+ if (_film->trim_type() == Film::CPL) {
+ duration = frames - _film->trim_start() - _film->trim_end();
+ _picture_asset->set_entry_point (_film->trim_start ());
+ } else {
+ duration = frames;
+ }
- _picture_asset->set_entry_point (_film->trim_start ());
_picture_asset->set_duration (duration);
/* Hard-link the video MXF into the DCP */
boost::filesystem::path from;
- from /= _film->video_mxf_dir();
- from /= _film->video_mxf_filename();
+ from /= _film->internal_video_mxf_dir();
+ from /= _film->internal_video_mxf_filename();
boost::filesystem::path to;
to /= _film->dir (_film->dcp_name());
- to /= N_("video.mxf");
+ to /= _film->dcp_video_mxf_filename ();
boost::system::error_code ec;
boost::filesystem::create_hard_link (from, to, ec);
@@ -287,10 +292,12 @@ Writer::finish ()
/* And update the asset */
_picture_asset->set_directory (_film->dir (_film->dcp_name ()));
- _picture_asset->set_file_name (N_("video.mxf"));
+ _picture_asset->set_file_name (_film->dcp_video_mxf_filename ());
if (_sound_asset) {
- _sound_asset->set_entry_point (_film->trim_start ());
+ if (_film->trim_type() == Film::CPL) {
+ _sound_asset->set_entry_point (_film->trim_start ());
+ }
_sound_asset->set_duration (duration);
}
@@ -341,8 +348,8 @@ Writer::check_existing_picture_mxf ()
{
/* Try to open the existing MXF */
boost::filesystem::path p;
- p /= _film->video_mxf_dir ();
- p /= _film->video_mxf_filename ();
+ p /= _film->internal_video_mxf_dir ();
+ p /= _film->internal_video_mxf_filename ();
FILE* mxf = fopen (p.string().c_str(), N_("rb"));
if (!mxf) {
return;
diff --git a/src/lib/wscript b/src/lib/wscript
index fddebe8e6..e53ac5a84 100644
--- a/src/lib/wscript
+++ b/src/lib/wscript
@@ -52,6 +52,7 @@ sources = """
transcode_job.cc
transcoder.cc
types.cc
+ trimmer.cc
ui_signaller.cc
util.cc
video_content.cc