summaryrefslogtreecommitdiff
path: root/doc/mainpage.txt
blob: f43949268eefefd7dcecb107f8d1a36954c5d595 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/*!

@mainpage libdcp

libdcp is a small library to create and read Digital Cinema Packages (DCPs) from JPEG2000 and WAV files.

Most of the hard work is done by a (slightly patched) version of asdcplib (http://www.cinecert.com/asdcplib/)
which is included in the source distribution for libdcp.

libdcp is distributed under the GNU GPL.

Creating DCPs
--

Typical use for creating DCPs might be:
@code
#include <libdcp/dcp.h>
using namespace std;

libdcp::DCP dcp ("My Film DCP", "My Film", libdcp::DCP::FEATURE, 24, 50000);

vector<string> j2k_files;
j2k_files.push_back ("1.j2c");
...
j2k_files.push_back ("50000.j2c");

// These images are 1998x1080 pixels (DCI Flat)
dcp.add_picture_asset (j2k_files, 1998, 1080);

vector<string> wav_files;
wav_files.push_back ("L.wav");
wav_files.push_back ("R.wav");
wav_files.push_back ("C.wav");
wav_files.push_back ("Lfe.wav");
wav_files.push_back ("Ls.wav");
wav_files.push_back ("Rs.wav");
dcp.add_sound_asset (wav_files);

dcp.write_xml ();

@endcode

This will create a DCP at 24 frames per second with 50000 frames, writing
data to a directory "My Film DCP", naming the DCP "My Film" and marking
as a Feature.  We then add the picture and sound files (which creates
MXF files inside the DCP directory) and then write the required XML files.

If you want to report progress for long jobs (add_picture_asset() can
take a long time, in particular, as it must do a lot of disk I/O for
large DCPs), connect to the libdcp::DCP::Progress signal and report its parameter
to the user (it will range between 0 for 0% and 1 for 100%) using something like

@code
void
report (float p)
{
   cout << "We are " << int (p * 100) << "% done.\n";
}

dcp.Progress.connect (sigc::ptr_fun (&report));
@endcode

If you can generate content paths algorithmically, you may prefer to do something
like this:

@code

string
j2k_path (int frame)
{
	stringstream s;
	s << "my_j2ks/" << frame << ".j2c"
	return s.str ();
}

string
wav_path (libdcp::Channel channel)
{
	switch (channel) {
	case LEFT:
		return "left.wav";
	case RIGHT:
		return "right.wav";
	}

	return "";
}

...

// Our images are 1998x1080 (DCI Flat)
dcp.add_picture_asset (sigc::ptr_fun (&j2k_path), 1998, 1080);
// We have two sound channels
dcp.add_sound_asset (sigc::ptr_fun (&wav_path), 2);

...

@endcode

Reading existing DCPs
--

Alternatively libdcp can be used to read existing DCPs and examine their content.  You
might do

@code
#include <libdcp/dcp.h>
using namespace std;

libdcp::DCP dcp ("some-DCP-directory");
@endcode

libdcp will look at the XML files that make up the DCP and find its assets.  You can then
do things like

@code
boost::shared_ptr<libdcp::PictureAsset> p = dcp.picture_asset ();
boost::shared_ptr<libdcp::RGBAFrame> f = p->get_frame(42)->rgba_frame ();
uint8_t* data = f->data ();
int size = f->size ();
@endcode

This will extract the image of frame 42 from the DCP and make its RGBA data available
for examination.

Audio data is accessed in chunks equal in length to the duration of a video frame.  To
get the audio that accompanies frame 66, you can do

@code
boost::shared_ptr<libdcp::SoundAsset> s = dcp.sound_asset ();
cout << "Sound has " << s->channels() << " channels at " << s->sampling_rate() << "Hz\n";
boost::shared_ptr<libdcp::SoundFrame> f = s->get_frame(66);
uint8_t* data = f->data ();
int size = f->size ();
@endcode

The returned data is interleaved 24-bit samples, so that

@code
int left = data[0] | (data[1] << 8) | (data[2] << 16);
data += 3;
int right = data[0] | (data[1] << 8) | (data[2] << 16);
data += 3;
int centre = data[0] | (data[1] << 8) | (data[2] << 16);
data += 3;
int lfe = data[0] | (data[1] << 8) | (data[2] << 16);
data += 3;
int ls = data[0] | (data[1] << 8) | (data[2] << 16);
data += 3;
int rs = data[0] | (data[1] << 8) | (data[2] << 16);
data += 3;
@endcode

would obtain the first sample from each of the 6 channels for that frame.

Subtitles can be read using code like

@code
boost::shared_ptr<SubtitleAsset> s = dcp.subtitle_asset ();
list<boost::shared_ptr<libdcp::Text> > texts = s->subtitles_at (libdcp::Time (0, 3, 2, 5));
@endcode

This returns the subtitles that should be shown at 3 minutes, 2
seconds, 5 ticks (where 1 tick is 4ms) into the DCP.

*/