#include "lib/exceptions.h"
#include "lib/ab_transcode_job.h"
#include "lib/thumbs_job.h"
-#include "lib/make_mxf_job.h"
#include "lib/job_manager.h"
#include "lib/filter.h"
#include "lib/screen.h"
vector<DCPContentType const *> DCPContentType::_dcp_content_types;
-DCPContentType::DCPContentType (string p, string d)
+DCPContentType::DCPContentType (string p, libdcp::DCP::ContentType c)
: _pretty_name (p)
- , _dcp_name (d)
+ , _libdcp_type (c)
{
}
void
DCPContentType::setup_dcp_content_types ()
{
- _dcp_content_types.push_back (new DCPContentType ("Feature", "feature"));
- _dcp_content_types.push_back (new DCPContentType ("Short", "short"));
- _dcp_content_types.push_back (new DCPContentType ("Trailer", "trailer"));
- _dcp_content_types.push_back (new DCPContentType ("Test", "test"));
- _dcp_content_types.push_back (new DCPContentType ("Transitional", "transitional"));
- _dcp_content_types.push_back (new DCPContentType ("Rating", "rating"));
- _dcp_content_types.push_back (new DCPContentType ("Teaser", "teaster"));
- _dcp_content_types.push_back (new DCPContentType ("Policy", "policy"));
- _dcp_content_types.push_back (new DCPContentType ("Public Service Announcement", "psa"));
- _dcp_content_types.push_back (new DCPContentType ("Advertisement", "advertisement"));
+ _dcp_content_types.push_back (new DCPContentType ("Feature", libdcp::DCP::FEATURE));
+ _dcp_content_types.push_back (new DCPContentType ("Short", libdcp::DCP::SHORT));
+ _dcp_content_types.push_back (new DCPContentType ("Trailer", libdcp::DCP::TRAILER));
+ _dcp_content_types.push_back (new DCPContentType ("Test", libdcp::DCP::TEST));
+ _dcp_content_types.push_back (new DCPContentType ("Transitional", libdcp::DCP::TRANSITIONAL));
+ _dcp_content_types.push_back (new DCPContentType ("Rating", libdcp::DCP::RATING));
+ _dcp_content_types.push_back (new DCPContentType ("Teaser", libdcp::DCP::TEASER));
+ _dcp_content_types.push_back (new DCPContentType ("Policy", libdcp::DCP::POLICY));
+ _dcp_content_types.push_back (new DCPContentType ("Public Service Announcement", libdcp::DCP::PUBLIC_SERVICE_ANNOUNCEMENT));
+ _dcp_content_types.push_back (new DCPContentType ("Advertisement", libdcp::DCP::ADVERTISEMENT));
}
DCPContentType const *
#include <string>
#include <vector>
+#include <libdcp/dcp.h>
/** @class DCPContentType
* @brief A description of the type of content for a DCP (e.g. feature, trailer etc.)
class DCPContentType
{
public:
- DCPContentType (std::string, std::string);
+ DCPContentType (std::string, libdcp::DCP::ContentType);
/** @return user-visible `pretty' name */
std::string pretty_name () const {
return _pretty_name;
}
- /** @return name as written to a DCP */
- std::string dcp_name () const {
- return _dcp_name;
+ libdcp::DCP::ContentType libdcp_type () const {
+ return _libdcp_type;
}
static DCPContentType const * from_pretty_name (std::string);
private:
std::string _pretty_name;
- std::string _dcp_name;
+ libdcp::DCP::ContentType _libdcp_type;
/** All available DCP content types */
static std::vector<DCPContentType const *> _dcp_content_types;
#include "job_manager.h"
#include "ab_transcode_job.h"
#include "transcode_job.h"
-#include "make_mxf_job.h"
#include "scp_dcp_job.h"
#include "copy_from_dvd_job.h"
#include "make_dcp_job.h"
}
}
- JobManager::instance()->add (shared_ptr<Job> (new MakeMXFJob (fs, o, log (), MakeMXFJob::VIDEO)));
- if (audio_channels() > 0) {
- JobManager::instance()->add (shared_ptr<Job> (new MakeMXFJob (fs, o, log (), MakeMXFJob::AUDIO)));
- }
JobManager::instance()->add (shared_ptr<Job> (new MakeDCPJob (fs, o, log ())));
}
*/
#include <boost/filesystem.hpp>
+#include <libdcp/dcp.h>
extern "C" {
#include <libavutil/pixdesc.h>
}
#include "film_state.h"
#include "dcp_content_type.h"
#include "exceptions.h"
+#include "options.h"
using namespace std;
using namespace boost;
void
MakeDCPJob::run ()
{
- set_progress_unknown ();
-
string const dcp_path = _fs->dir (_fs->name);
-
- /* Check that we have our prerequisites */
-
- if (!filesystem::exists (filesystem::path (_fs->file ("video.mxf")))) {
- throw EncodeError ("missing video.mxf");
- }
-
- bool const have_audio = filesystem::exists (filesystem::path (_fs->file ("audio.mxf")));
/* Remove any old DCP */
filesystem::remove_all (dcp_path);
- DCP dcp (_fs->dir (_fs->name()));
- dcp.add_asset (
- shared_ptr<MainPictureAsset> (new MainPictureAsset ("video.mxf", rint (_fs->frames_per_second), _fs->length, _opt->out_size))
- );
+ libdcp::DCP dcp (_fs->dir (_fs->name), _fs->name, _fs->dcp_content_type->libdcp_type (), rint (_fs->frames_per_second), _fs->length);
+ dcp.Progress.connect (sigc::mem_fun (*this, &MakeDCPJob::dcp_progress));
- if (filesystem::exists (filesystem::path (_fs->file ("audio.mxf")))) {
- dcp.add_asset (
- shared_ptr<MainSoundAsset> (new MainSoundAsset ("audio.mxf", rint (_fs->frames_per_second), _fs->length))
- );
+ list<string> j2cs;
+ int f = _fs->dcp_frames ? _fs->dcp_frames : _fs->length;
+ for (int i = 0; i < f; ++i) {
+ j2cs.push_back (_opt->frame_out_path (i, false));
}
-
- dcp.write_xml ();
-
- add_pkl ();
- add_cpl (pkl[0]);
+ descend (0.9);
+ dcp.add_picture_asset (j2cs, _opt->out_size.width, _opt->out_size.height);
+ ascend ();
- add_reel (pkl[0].cpl[0]);
+ list<string> wavs;
+ for (int i = 0; i < _fs->audio_channels; ++i) {
+ wavs.push_back (_opt->multichannel_audio_out_path (i, false));
+ }
- write_cpl ();
- write_pkl ();
- write_volindex ();
- write_assetmap ();
+ if (!wavs.empty ()) {
+ descend (0.1);
+ dcp.add_sound_asset (wavs);
+ ascend ();
+ }
+ dcp.write_xml ();
set_progress (1);
+ set_state (FINISHED_OK);
+}
+
+void
+MakeDCPJob::dcp_progress (float p)
+{
+ set_progress (p);
}
* @brief A job to create DCPs.
*/
-#include "shell_command_job.h"
+#include "job.h"
/** @class MakeDCPJob
* @brief A job to create DCPs
std::string name () const;
void run ();
+
+private:
+ void dcp_progress (float);
};
+++ /dev/null
-/*
- Copyright (C) 2012 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.
-
-*/
-
-/** @file src/make_mxf_job.cc
- * @brief A job that creates a MXF file from some data.
- */
-
-#include <iostream>
-#include <boost/filesystem.hpp>
-#include "AS_DCP.h"
-#include "KM_fileio.h"
-#include "make_mxf_job.h"
-#include "film.h"
-#include "film_state.h"
-#include "options.h"
-#include "exceptions.h"
-
-using namespace std;
-using namespace boost;
-
-/** @class MakeMXFJob
- * @brief A job that creates a MXF file from some data.
- */
-
-MakeMXFJob::MakeMXFJob (shared_ptr<const FilmState> s, shared_ptr<const Options> o, Log* l, Type t)
- : Job (s, o, l)
- , _type (t)
-{
-
-}
-
-string
-MakeMXFJob::name () const
-{
- stringstream s;
- switch (_type) {
- case VIDEO:
- s << "Make video MXF for " << _fs->name;
- break;
- case AUDIO:
- s << "Make audio MXF for " << _fs->name;
- break;
- }
-
- return s.str ();
-}
-
-void
-MakeMXFJob::run ()
-{
- set_progress (0);
-
- string dir;
- switch (_type) {
- case VIDEO:
- dir = _opt->frame_out_path ();
- break;
- case AUDIO:
- dir = _opt->multichannel_audio_out_path ();
- break;
- }
-
- list<string> files;
- for (filesystem::directory_iterator i = filesystem::directory_iterator (dir); i != filesystem::directory_iterator(); ++i) {
- files.push_back (filesystem::path (*i).string());
- }
-
- if (files.empty ()) {
- throw EncodeError ("no input files found for MXF");
- }
-
- files.sort ();
-
- switch (_type) {
- case VIDEO:
- j2k (files, _fs->file ("video.mxf"));
- break;
- case AUDIO:
- wav (files, _fs->file ("audio.mxf"));
- break;
- default:
- throw EncodeError ("unknown essence type");
- }
-
- set_progress (1);
-}
-
-void
-MakeMXFJob::wav (list<string> const & files, string const & mxf)
-{
- /* XXX: we round for DCP: not sure if this is right */
- ASDCP::Rational fps (rintf (_fs->frames_per_second), 1);
-
- ASDCP::PCM::WAVParser pcm_parser_channel[files.size()];
- if (pcm_parser_channel[0].OpenRead (files.front().c_str(), fps)) {
- throw EncodeError ("could not open WAV file for reading");
- }
-
- ASDCP::PCM::AudioDescriptor audio_desc;
- pcm_parser_channel[0].FillAudioDescriptor (audio_desc);
- audio_desc.ChannelCount = 0;
- audio_desc.BlockAlign = 0;
- audio_desc.EditRate = fps;
- audio_desc.AvgBps = audio_desc.AvgBps * files.size ();
-
- ASDCP::PCM::FrameBuffer frame_buffer_channel[files.size()];
- ASDCP::PCM::AudioDescriptor audio_desc_channel[files.size()];
-
- int j = 0;
- for (list<string>::const_iterator i = files.begin(); i != files.end(); ++i) {
-
- if (ASDCP_FAILURE (pcm_parser_channel[j].OpenRead (i->c_str(), fps))) {
- throw EncodeError ("could not open WAV file for reading");
- }
-
- pcm_parser_channel[j].FillAudioDescriptor (audio_desc_channel[j]);
- frame_buffer_channel[j].Capacity (ASDCP::PCM::CalcFrameBufferSize (audio_desc_channel[j]));
-
- audio_desc.ChannelCount += audio_desc_channel[j].ChannelCount;
- audio_desc.BlockAlign += audio_desc_channel[j].BlockAlign;
- ++j;
- }
-
- ASDCP::PCM::FrameBuffer frame_buffer;
- frame_buffer.Capacity (ASDCP::PCM::CalcFrameBufferSize (audio_desc));
- frame_buffer.Size (ASDCP::PCM::CalcFrameBufferSize (audio_desc));
-
- ASDCP::WriterInfo writer_info;
- fill_writer_info (&writer_info);
-
- ASDCP::PCM::MXFWriter mxf_writer;
- if (ASDCP_FAILURE (mxf_writer.OpenWrite (mxf.c_str(), writer_info, audio_desc))) {
- throw EncodeError ("could not open audio MXF for writing");
- }
-
- for (int i = 0; i < _fs->length; ++i) {
-
- byte_t *data_s = frame_buffer.Data();
- byte_t *data_e = data_s + frame_buffer.Capacity();
- byte_t sample_size = ASDCP::PCM::CalcSampleSize (audio_desc_channel[0]);
- int offset = 0;
-
- for (list<string>::size_type j = 0; j < files.size(); ++j) {
- memset (frame_buffer_channel[j].Data(), 0, frame_buffer_channel[j].Capacity());
- if (ASDCP_FAILURE (pcm_parser_channel[j].ReadFrame (frame_buffer_channel[j]))) {
- throw EncodeError ("could not read audio frame");
- }
-
- if (frame_buffer_channel[j].Size() != frame_buffer_channel[j].Capacity()) {
- throw EncodeError ("short audio frame");
- }
- }
-
- while (data_s < data_e) {
- for (list<string>::size_type j = 0; j < files.size(); ++j) {
- byte_t* frame = frame_buffer_channel[j].Data() + offset;
- memcpy (data_s, frame, sample_size);
- data_s += sample_size;
- }
- offset += sample_size;
- }
-
- if (ASDCP_FAILURE (mxf_writer.WriteFrame (frame_buffer, 0, 0))) {
- throw EncodeError ("could not write audio MXF frame");
- }
-
- set_progress (float (i) / _fs->length);
- }
-
- if (ASDCP_FAILURE (mxf_writer.Finalize())) {
- throw EncodeError ("could not finalise audio MXF");
- }
-
- set_progress (1);
- set_state (FINISHED_OK);
-}
-
-void
-MakeMXFJob::j2k (list<string> const & files, string const & mxf)
-{
- ASDCP::JP2K::CodestreamParser j2k_parser;
- ASDCP::JP2K::FrameBuffer frame_buffer (4 * Kumu::Megabyte);
- if (ASDCP_FAILURE (j2k_parser.OpenReadFrame (files.front().c_str(), frame_buffer))) {
- throw EncodeError ("could not open J2K file for reading");
- }
-
- ASDCP::JP2K::PictureDescriptor picture_desc;
- j2k_parser.FillPictureDescriptor (picture_desc);
- /* XXX: we round for DCP: not sure if this is right */
- picture_desc.EditRate = ASDCP::Rational (rintf (_fs->frames_per_second), 1);
-
- ASDCP::WriterInfo writer_info;
- fill_writer_info (&writer_info);
-
- ASDCP::JP2K::MXFWriter mxf_writer;
- if (ASDCP_FAILURE (mxf_writer.OpenWrite (mxf.c_str(), writer_info, picture_desc))) {
- throw EncodeError ("could not open MXF for writing");
- }
-
- int j = 0;
- for (list<string>::const_iterator i = files.begin(); i != files.end(); ++i) {
- if (ASDCP_FAILURE (j2k_parser.OpenReadFrame (i->c_str(), frame_buffer))) {
- throw EncodeError ("could not open J2K file for reading");
- }
-
- /* XXX: passing 0 to WriteFrame ok? */
- if (ASDCP_FAILURE (mxf_writer.WriteFrame (frame_buffer, 0, 0))) {
- throw EncodeError ("error in writing video MXF");
- }
-
- ++j;
- set_progress (float (j) / files.size ());
- }
-
- if (ASDCP_FAILURE (mxf_writer.Finalize())) {
- throw EncodeError ("error in finalising video MXF");
- }
-
- set_progress (1);
- set_state (FINISHED_OK);
-}
-
-void
-MakeMXFJob::fill_writer_info (ASDCP::WriterInfo* writer_info)
-{
- writer_info->ProductVersion = DVDOMATIC_VERSION;
- writer_info->CompanyName = "dvd-o-matic";
- writer_info->ProductName = "dvd-o-matic";
-
- /* set the label type */
- writer_info->LabelSetType = ASDCP::LS_MXF_SMPTE;
-
- /* generate a random UUID for this essence */
- Kumu::GenRandomUUID (writer_info->AssetUUID);
-}
+++ /dev/null
-/*
- Copyright (C) 2012 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.
-
-*/
-
-/** @file src/make_mxf_job.h
- * @brief A job that creates a MXF file from some data.
- */
-
-#include "shell_command_job.h"
-
-namespace ASDCP {
- class WriterInfo;
-}
-
-class FilmState;
-class Options;
-
-/** @class MakeMXFJob
- * @brief A job that creates a MXF file from some data.
- */
-class MakeMXFJob : public Job
-{
-public:
- enum Type {
- AUDIO,
- VIDEO
- };
-
- MakeMXFJob (boost::shared_ptr<const FilmState>, boost::shared_ptr<const Options>, Log *, Type);
-
- std::string name () const;
- void run ();
-
-private:
- void j2k (std::list<std::string> const &, std::string const &);
- void wav (std::list<std::string> const &, std::string const &);
- void fill_writer_info (ASDCP::WriterInfo *);
-
- Type _type;
-};
-
return AV_SAMPLE_FMT_NONE;
}
-/** @return Version of OpenDCP that is on the path (and hence that we will use) */
-static string
-opendcp_version ()
-{
- FILE* f = popen ("opendcp_xml", "r");
- if (f == 0) {
- throw EncodeError ("could not run opendcp_xml to check version");
- }
-
- string version = "unknown";
-
- while (!feof (f)) {
- char* buf = 0;
- size_t n = 0;
- ssize_t const r = getline (&buf, &n, f);
- if (r > 0) {
- string s (buf);
- vector<string> b;
- split (b, s, is_any_of (" "));
- if (b.size() >= 3 && b[0] == "OpenDCP" && b[1] == "version") {
- version = b[2];
- }
- free (buf);
- }
- }
-
- pclose (f);
-
- return version;
-}
-
/** @return Version of vobcopy that is on the path (and hence that we will use) */
static string
vobcopy_version ()
{
stringstream s;
s << "libopenjpeg " << opj_version () << ", "
- << "opendcp " << opendcp_version () << ", "
<< "vobcopy " << vobcopy_version() << ", "
<< "libswresample " << ffmpeg_version_to_string (swresample_version()) << ", "
<< "libavcodec " << ffmpeg_version_to_string (avcodec_version()) << ", "
obj = bld(features = 'cxx cxxshlib')
obj.name = 'libdvdomatic'
obj.export_includes = ['.']
- obj.uselib = 'AVCODEC AVUTIL AVFORMAT AVFILTER SWSCALE SWRESAMPLE SNDFILE BOOST_FILESYSTEM BOOST_THREAD OPENJPEG POSTPROC TIFF SIGC++ MAGICK SSH'
- obj.use = 'libasdcp-dvdomatic'
+ obj.uselib = 'AVCODEC AVUTIL AVFORMAT AVFILTER SWSCALE SWRESAMPLE SNDFILE BOOST_FILESYSTEM BOOST_THREAD OPENJPEG POSTPROC TIFF SIGC++ MAGICK SSH DCP'
if bld.env.DEBUG_HASH:
obj.uselib += ' MHASH'
obj.source = """
log.cc
lut.cc
make_dcp_job.cc
- make_mxf_job.cc
player.cc
player_manager.cc
scaler.cc
#include "film.h"
#include "filter.h"
#include "transcode_job.h"
-#include "make_mxf_job.h"
#include "make_dcp_job.h"
#include "job_manager.h"
#include "ab_transcode_job.h"
def configure(conf):
conf.recurse('lib')
- conf.recurse('asdcplib')
if not conf.env.DISABLE_GUI:
conf.recurse('gtk')
conf.check_cfg(package = 'libswresample', args = '--cflags --libs', uselib_store = 'SWRESAMPLE', mandatory = True)
conf.check_cfg(package = 'libpostproc', args = '--cflags --libs', uselib_store = 'POSTPROC', mandatory = True)
conf.check_cfg(package = 'sndfile', args = '--cflags --libs', uselib_store = 'SNDFILE', mandatory = True)
+ conf.check_cfg(package = 'libdcp', args = '--cflags --libs', uselib_store = 'DCP', mandatory = True)
conf.check_cfg(package = '', path = 'Magick++-config', args = '--cppflags --cxxflags --libs', uselib_store = 'MAGICK', mandatory = True)
conf.check_cc(msg = 'Checking for library libtiff', function_name = 'TIFFOpen', header_name = 'tiffio.h', lib = 'tiff', uselib_store = 'TIFF')
conf.check_cc(fragment = """