summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
Diffstat (limited to 'examples')
-rw-r--r--examples/make_dcp.cc140
-rw-r--r--examples/read_dcp.cc90
-rw-r--r--examples/wscript12
3 files changed, 163 insertions, 79 deletions
diff --git a/examples/make_dcp.cc b/examples/make_dcp.cc
index 6aa4268b..d86cd30a 100644
--- a/examples/make_dcp.cc
+++ b/examples/make_dcp.cc
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2012 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2012-2014 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
@@ -18,7 +18,7 @@
*/
/** @file examples/make_dcp.cc
- * @brief Shows how to make a DCP from some JPEG2000 and WAV files.
+ * @brief Shows how to make a DCP from some JPEG2000 and audio data.
*/
#include <vector>
@@ -33,94 +33,80 @@
#include "dcp.h"
#include "cpl.h"
-#include "mono_picture_asset.h"
-#include "sound_asset.h"
+#include "mono_picture_mxf.h"
+#include "mono_picture_mxf_writer.h"
+#include "sound_mxf.h"
+#include "sound_mxf_writer.h"
#include "reel.h"
-
-/* This method returns the filename of the JPEG2000 file to use for a given frame.
- In this example, we are using the same file for each frame, so we don't bother
- looking at the frame parameter, but it will called with frame=0, frame=1, ...
-*/
-std::string
-video_frame (int /* frame */)
-{
- return "examples/help.j2c";
-}
+#include "file.h"
+#include "reel_mono_picture_asset.h"
+#include "reel_sound_asset.h"
int
main ()
{
- /* Make a DCP object. "My Film DCP" is the directory name for the DCP */
- libdcp::DCP dcp ("My Film DCP");
+ /* Create a directory to put the DCP in */
+ boost::filesystem::create_directory ("DCP");
- /* Now make a CPL object.
-
- "My Film" is the title that will be shown on the projector / TMS when the DCP is ingested.
- FEATURE is the type that the projector will list the DCP as.
- 24 is the frame rate, and the DCP will be 48 frames long (ie 2 seconds at 24 fps).
- */
- boost::shared_ptr<libdcp::CPL> cpl (new libdcp::CPL ("My Film DCP", "My Film", libdcp::FEATURE, 24, 48));
-
- /* And add the CPL to the DCP */
- dcp.add_cpl (cpl);
-
- /* Now make a `picture asset'. This is a collection of the JPEG2000 files that make up the picture; one per frame.
- First, create the object.
+ /* Make a picture MXF. This is a file which combines JPEG2000 files together to make
+ up the video of the DCP. First, create the object, specifying a frame rate of 24 frames
+ per second.
*/
- boost::shared_ptr<libdcp::MonoPictureAsset> picture_asset (
- new libdcp::MonoPictureAsset ("My Film DCP", "video.mxf")
- );
+ boost::shared_ptr<dcp::MonoPictureMXF> picture_mxf (new dcp::MonoPictureMXF (dcp::Fraction (24, 1)));
- /* Now set up its parameters; we have the frame rate, the
- number of frames and the resolution of the frames;
- 1998x1080 is the DCI Flat specification for 2K projectors.
- */
-
- picture_asset->set_edit_rate (24);
- picture_asset->set_intrinsic_duration (24);
- picture_asset->set_size (libdcp::Size (1998, 1080));
-
- /* Now we can create the asset itself. Here using a function (video_frame) to obtain the name of the JPEG2000 file for each frame.
- The result will be an MXF file written to the directory "My Film DCP" (which should be the same as the DCP's
- directory above) called "video.mxf".
- */
+ /* Start off a write to it */
+ boost::shared_ptr<dcp::PictureMXFWriter> picture_writer = picture_mxf->start_write ("DCP/picture.mxf", dcp::SMPTE, false);
- picture_asset->create (video_frame);
+ /* Write 24 frames of the same JPEG2000 file */
+ dcp::File picture ("examples/help.j2c");
+ for (int i = 0; i < 24; ++i) {
+ picture_writer->write (picture.data(), picture.size());
+ }
- /* Now we will create a `sound asset', which is made up of a WAV file for each channel of audio. Here we're using
- stereo, so we add two WAV files to a vector.
+ /* And finish off */
+ picture_writer->finalize ();
- We could add more files here to use more channels; the file order is:
- Left
- Right
- Centre
- LFE (sub)
- Left surround
- Right surround
+ /* Now create a sound MXF. As before, create an object and a writer.
+ When creating the object we specify the sampling rate (48kHz) and the number of channels (2).
*/
- std::vector<boost::filesystem::path> sound_files;
- sound_files.push_back ("examples/sine_440_-12dB.wav");
- sound_files.push_back ("examples/sine_880_-12dB.wav");
-
- /* Now we can create the sound asset using these files */
- boost::shared_ptr<libdcp::SoundAsset> sound_asset (new libdcp::SoundAsset ("My Film DCP", "audio.mxf"));
- sound_asset->set_edit_rate (24);
- sound_asset->set_intrinsic_duration (48);
- sound_asset->create (sound_files);
-
- /* Now that we have the assets, we can create a Reel to put them in and add it to the CPL */
- cpl->add_reel (
- boost::shared_ptr<libdcp::Reel> (
- new libdcp::Reel (picture_asset, sound_asset, boost::shared_ptr<libdcp::SubtitleAsset> ())
- )
- );
-
- /* Finally, we call this to write the XML description files to the DCP. After this, the DCP
- is ready to ingest and play.
+ boost::shared_ptr<dcp::SoundMXF> sound_mxf (new dcp::SoundMXF (dcp::Fraction (24, 1), 48000, 2));
+ boost::shared_ptr<dcp::SoundMXFWriter> sound_writer = sound_mxf->start_write ("DCP/sound.mxf", dcp::SMPTE);
+
+ /* Write some sine waves */
+ float* audio[2];
+ audio[0] = new float[48000];
+ audio[1] = new float[48000];
+ for (int i = 0; i < 48000; ++i) {
+ audio[0][i] = sin (2 * M_PI * i * 440 / 48000) * 0.25;
+ audio[1][i] = sin (2 * M_PI * i * 880 / 48000) * 0.25;
+ }
+ sound_writer->write (audio, 48000);
+
+ /* And tidy up */
+ delete[] audio[0];
+ delete[] audio[1];
+ sound_writer->finalize ();
+
+ /* Now create a reel */
+ boost::shared_ptr<dcp::Reel> reel (new dcp::Reel ());
+
+ /* Add picture and sound to it. The zeros are the `entry points', i.e. the first
+ (video) frame from the MXFs that the reel should play.
*/
- libdcp::XMLMetadata metadata;
- dcp.write_xml (false, metadata);
-
+ reel->add (boost::shared_ptr<dcp::ReelPictureAsset> (new dcp::ReelMonoPictureAsset (picture_mxf, 0)));
+ reel->add (boost::shared_ptr<dcp::ReelSoundAsset> (new dcp::ReelSoundAsset (sound_mxf, 0)));
+
+ /* Make a CPL with this reel */
+ boost::shared_ptr<dcp::CPL> cpl (new dcp::CPL ("My film", dcp::FEATURE));
+ cpl->add (reel);
+
+ /* Write the DCP */
+ dcp::DCP dcp ("DCP");
+ dcp.add (cpl);
+ dcp.add (picture_mxf);
+ dcp.add (sound_mxf);
+ dcp.write_xml (dcp::SMPTE);
+
return 0;
}
diff --git a/examples/read_dcp.cc b/examples/read_dcp.cc
new file mode 100644
index 00000000..f3c47a3c
--- /dev/null
+++ b/examples/read_dcp.cc
@@ -0,0 +1,90 @@
+/*
+ Copyright (C) 2012-2014 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.
+
+*/
+
+/* If you are using an installed libdcp, these #includes would need to be changed to
+#include <libdcp/dcp.h>
+#include <libdcp/picture_mxf.h>
+... etc. ...
+*/
+
+#include "dcp.h"
+#include "cpl.h"
+#include "reel.h"
+#include "reel_picture_asset.h"
+#include "mono_picture_frame.h"
+#include "mono_picture_mxf.h"
+#include "stereo_picture_mxf.h"
+#include "sound_mxf.h"
+#include "subtitle_content.h"
+#include "argb_frame.h"
+#include <Magick++.h>
+
+/** @file examples/read_dcp.cc
+ * @brief Shows how to read a DCP.
+ */
+
+int
+main ()
+{
+ /* Create a DCP, specifying where our existing data is */
+ dcp::DCP dcp ("/home/carl/diagonal.com/APPASSIONATA_TLR_F_UK-DEFR_CH_51_2K_LOK_20121115_DGL_OV");
+ /* Read the DCP to find out about it */
+ dcp.read ();
+
+ if (dcp.encrypted ()) {
+ std::cout << "DCP is encrypted.\n";
+ } else {
+ std::cout << "DCP is not encrypted.\n";
+ }
+
+ std::cout << "DCP has " << dcp.cpls().size() << " CPLs.\n";
+ std::list<boost::shared_ptr<dcp::Asset> > assets = dcp.assets ();
+ std::cout << "DCP has " << assets.size() << " assets.\n";
+ for (std::list<boost::shared_ptr<dcp::Asset> >::const_iterator i = assets.begin(); i != assets.end(); ++i) {
+ if (boost::dynamic_pointer_cast<dcp::MonoPictureMXF> (*i)) {
+ std::cout << "2D picture\n";
+ } else if (boost::dynamic_pointer_cast<dcp::StereoPictureMXF> (*i)) {
+ std::cout << "3D picture\n";
+ } else if (boost::dynamic_pointer_cast<dcp::SoundMXF> (*i)) {
+ std::cout << "Sound\n";
+ } else if (boost::dynamic_pointer_cast<dcp::SubtitleContent> (*i)) {
+ std::cout << "Subtitle\n";
+ } else if (boost::dynamic_pointer_cast<dcp::CPL> (*i)) {
+ std::cout << "CPL\n";
+ }
+ std::cout << "\t" << (*i)->file().leaf().string() << "\n";
+ }
+
+ /* Take the first CPL */
+ boost::shared_ptr<dcp::CPL> cpl = dcp.cpls().front ();
+
+ /* Get the MXF of the picture asset in the first reel */
+ boost::shared_ptr<dcp::MonoPictureMXF> picture_mxf = boost::dynamic_pointer_cast<dcp::MonoPictureMXF> (cpl->reels().front()->main_picture()->mxf ());
+
+ /* Get the 1000th frame of it */
+ boost::shared_ptr<const dcp::MonoPictureFrame> picture_frame_j2k = picture_mxf->get_frame(999);
+
+ /* Get a ARGB copy of it */
+ boost::shared_ptr<dcp::ARGBFrame> picture_frame_rgb = picture_frame_j2k->argb_frame ();
+
+ Magick::Image image (picture_frame_rgb->size().width, picture_frame_rgb->size().height, "BGRA", Magick::CharPixel, picture_frame_rgb->data ());
+ image.write ("frame.png");
+
+ return 0;
+}
diff --git a/examples/wscript b/examples/wscript
index 05cca98f..abb0885c 100644
--- a/examples/wscript
+++ b/examples/wscript
@@ -1,8 +1,16 @@
def build(bld):
obj = bld(features = 'cxx cxxprogram')
- obj.name = 'examples'
- obj.use = 'libdcp'
+ obj.name = 'make_dcp'
+ obj.use = 'libdcp%s' % bld.env.API_VERSION
obj.uselib = 'OPENJPEG CXML'
obj.source = 'make_dcp.cc'
obj.target = 'make_dcp'
obj.install_path = ''
+
+ obj = bld(features = 'cxx cxxprogram')
+ obj.name = 'read_dcp'
+ obj.use = 'libdcp%s' % bld.env.API_VERSION
+ obj.uselib = 'OPENJPEG CXML MAGICK'
+ obj.source = 'read_dcp.cc'
+ obj.target = 'read_dcp'
+ obj.install_path = ''