diff options
| author | Carl Hetherington <cth@carlh.net> | 2013-04-16 11:43:29 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2013-04-16 11:43:29 +0100 |
| commit | 147cca5876dfbdf56e21289c3a36bec4b4850191 (patch) | |
| tree | 09a59d9e91c7e5ec68b8fb55d1a7b1fcc23c7519 /src/lib | |
| parent | 50dd871c5a924660499b3fd599f1c68af5e3dbc1 (diff) | |
| parent | be5dfa3ed0459392cc65d21f563f136b97a295ba (diff) | |
Merge master.
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/film.cc | 64 | ||||
| -rw-r--r-- | src/lib/film.h | 21 | ||||
| -rw-r--r-- | src/lib/po/sv_SE.po | 8 | ||||
| -rw-r--r-- | src/lib/trimmer.cc | 100 | ||||
| -rw-r--r-- | src/lib/trimmer.h | 39 | ||||
| -rw-r--r-- | src/lib/writer.cc | 31 | ||||
| -rw-r--r-- | src/lib/wscript | 1 |
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 |
