2 Copyright (C) 2012 Carl Hetherington <cth@carlh.net>
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 /** @file src/make_mxf_job.cc
21 * @brief A job that creates a MXF file from some data.
25 #include <boost/filesystem.hpp>
27 #include "KM_fileio.h"
28 #include "make_mxf_job.h"
30 #include "film_state.h"
32 #include "exceptions.h"
35 using namespace boost;
38 * @brief A job that creates a MXF file from some data.
41 MakeMXFJob::MakeMXFJob (shared_ptr<const FilmState> s, shared_ptr<const Options> o, Log* l, Type t)
49 MakeMXFJob::name () const
54 s << "Make video MXF for " << _fs->name;
57 s << "Make audio MXF for " << _fs->name;
69 set_progress_unknown ();
71 /* We round for DCP: not sure if this is right */
72 float fps = rintf (_fs->frames_per_second);
75 c << "opendcp_mxf -r " << fps << " -i ";
78 c << "\"" << _opt->frame_out_path () << "\" -o \"" << _fs->file ("video.mxf") << "\"";
81 c << "\"" << _opt->multichannel_audio_out_path () << "/*\" -o \"" << _fs->file ("audio.mxf") << "\"";
98 dir = _opt->frame_out_path ();
101 dir = _opt->multichannel_audio_out_path ();
106 for (filesystem::directory_iterator i = filesystem::directory_iterator (dir); i != filesystem::directory_iterator(); ++i) {
107 files.push_back (filesystem::path (*i).string());
110 if (files.empty ()) {
111 throw EncodeError ("no input files found for MXF");
116 ASDCP::EssenceType_t essence_type;
117 if (ASDCP_FAILURE (ASDCP::RawEssenceType (files.front().c_str(), essence_type))) {
118 throw EncodeError ("could not work out type for MXF");
121 switch (essence_type) {
122 case ASDCP::ESS_JPEG_2000:
123 j2k (files, _fs->file ("video.mxf"));
125 case ASDCP::ESS_PCM_24b_48k:
126 case ASDCP::ESS_PCM_24b_96k:
127 wav (files, _fs->file ("audio.mxf"));
130 throw EncodeError ("unknown essence type");
137 MakeMXFJob::wav (list<string> const & files, string const & mxf)
143 MakeMXFJob::j2k (list<string> const & files, string const & mxf)
145 /* Arbitrarily assume that the J2K MXF will take 90% of the time */
148 ASDCP::JP2K::CodestreamParser j2k_parser;
149 ASDCP::JP2K::FrameBuffer frame_buffer (4 * Kumu::Megabyte);
150 if (ASDCP_FAILURE (j2k_parser.OpenReadFrame (files.front().c_str(), frame_buffer))) {
151 throw EncodeError ("could not open J2K file for reading");
154 ASDCP::JP2K::PictureDescriptor picture_desc;
155 j2k_parser.FillPictureDescriptor (picture_desc);
156 /* XXX: we round for DCP: not sure if this is right */
157 picture_desc.EditRate = ASDCP::Rational (rintf (_fs->frames_per_second), 1);
159 ASDCP::WriterInfo writer_info;
160 fill_writer_info (&writer_info);
162 ASDCP::JP2K::MXFWriter mxf_writer;
163 if (ASDCP_FAILURE (mxf_writer.OpenWrite (mxf.c_str(), writer_info, picture_desc))) {
164 throw EncodeError ("could not open MXF for writing");
168 for (list<string>::const_iterator i = files.begin(); i != files.end(); ++i) {
169 if (ASDCP_FAILURE (j2k_parser.OpenReadFrame (i->c_str(), frame_buffer))) {
170 throw EncodeError ("could not open J2K file for reading");
173 /* XXX: passing 0 to WriteFrame ok? */
174 if (ASDCP_FAILURE (mxf_writer.WriteFrame (frame_buffer, 0, 0))) {
175 throw EncodeError ("error in writing video MXF");
179 set_progress (float (j) / files.size ());
182 if (ASDCP_FAILURE (mxf_writer.Finalize())) {
183 throw EncodeError ("error in finalising video MXF");
190 MakeMXFJob::fill_writer_info (ASDCP::WriterInfo* writer_info)
192 writer_info->ProductVersion = DVDOMATIC_VERSION;
193 writer_info->CompanyName = "dvd-o-matic";
194 writer_info->ProductName = "dvd-o-matic";
196 /* set the label type */
197 writer_info->LabelSetType = ASDCP::LS_MXF_INTEROP;
199 /* generate a random UUID for this essence */
200 Kumu::GenRandomUUID (writer_info->AssetUUID);