Merge.
[dcpomatic.git] / doc / design / content.tex
1 \documentclass{article}
2 \begin{document}
3
4 \section{Status quo}
5
6 As at 0.78 there is an unfortunate mish-mash of code to handle the
7 input `content' the goes into a DCP.
8
9 The Film has a `content' file name.  This is guessed to be either a
10 movie (for FFmpeg) or a still-image (for ImageMagick) based on its
11 extension.  We also have `external audio', which is a set of WAV files
12 for libsndfile, and a flag to enable that.
13
14 The `content' file is badly named and limiting.  We can't have
15 multiple content files, and it's not really the `content' as such (it
16 used to be, but increasingly it's only a part of the content, on equal
17 footing with `external' audio).
18
19 The choice of sources for sound is expressed clumsily by the
20 AudioStream class hierarchy.
21
22
23 \section{Targets}
24
25 We want to be able to implement the following:
26
27 \begin{itemize}
28 \item Immediately:
29 \begin{itemize}
30 \item Multiple still images, each with their own duration, made into a `slide-show'
31 \item Lack of bugs in adding WAV-file audio to still images.
32 \item External subtitle files (either XML or SRT) to be converted to XML subtitles in the DCP.
33 \end{itemize}
34
35 \item In the future:
36 \begin{itemize}
37 \item Playlist-style multiple video / audio (perhaps).
38 \end{itemize}
39 \end{itemize}
40
41
42 \section{Content hierarchy}
43
44 One idea is to have a hierarchy of Content classes (\texttt{Content},
45 \texttt{\{Video/Audio\}Content}, \texttt{FFmpegContent}, \texttt{ImageMagickContent},
46 \texttt{SndfileContent}).
47
48 Then the Film has a list of these, and decides what to put into the
49 DCP based on some rules.  These rules would probably be fixed (for
50 now), with the possibility to expand later into some kind of playlist.
51
52
53 \section{Immediate questions}
54
55 \subsection{What Film attributes are video-content specific, and which are general?}
56
57 Questionable attributes:
58
59 \begin{itemize}
60 \item Trust content header
61 \item Crop
62 \item Filters
63
64 Post-processing (held as part of the filters description) is done in
65 the encoder, by which time all knowledge of the source is lost.
66
67 \item Scaler
68 \item Trim start/end
69
70 Messily tied in with the encoding side.  We want to implement this
71 using start/end point specifications in the DCP reel, otherwise
72 modifying the trim points requires a complete re-encode.
73
74 \item Audio gain
75 \item Audio delay
76 \item With subtitles
77 \item Subtitle offset/scale
78 \item Colour LUT
79 \end{itemize}
80
81 Attributes that I think must remain in Film:
82 \begin{itemize}
83 \item DCP content type
84 \item Format
85 \item A/B
86 \item J2K bandwidth
87 \end{itemize}
88
89 Part of the consideration here is that per-content attributes need to
90 be represented in the GUI differently to how things are represented
91 now.
92
93 Bear in mind also that, as it stands, the only options for video are:
94
95 \begin{enumerate}
96 \item An FFmpeg video
97 \item A set of stills
98 \end{enumerate}
99
100 and so the need for multiple scalers, crop and filters is
101 questionable.  Also, there is one set of audio (either from WAVs or
102 from the FFMpeg file), so per-content audio gain/delay is also
103 questionable.  Trust content header is only applicable for FFmpeg
104 content, really.  Similarly trim, with-subtitles, subtitle details,
105 colour LUT; basically none of it is really important right now.
106
107 Hence it may be sensible to keep everything in Film and move it later
108 along YAGNI lines.
109
110
111 \subsection{Who answers questions like: ``what is the length of video?''?}
112
113 If we have FFmpeg video, the question is easy to answer.  For a set of
114 stills, it is less easy.  Who knows that we are sticking them all
115 together end-to-end, with different durations for each?
116
117 If we have one-content-object equalling one file, the content objects
118 will presumably know how long their file should be displayed for.
119 There would appear to be two options following this:
120
121 \begin{enumerate}
122 \item There is one \texttt{ImageMagickDecoder} which is fed all the
123   files, and outputs them in order.  The magic knowledge is then
124   within this class, really.
125 \item There are multiple \texttt{ImageMagickDecoder} classes, one per
126   \texttt{..Content}, and some controlling (`playlist') class to manage
127   them.  The `playlist' is then itself a
128   \texttt{\{Video/Audio\}Source}, and has the magic knowledge.
129 \end{enumerate}
130
131
132 \section{Playlist approach}
133
134 Let's try the playlist approach.  We define a hierarchy of content classes:
135
136 \begin{verbatim}
137
138 class Content
139 {
140 public:
141   boost::filesystem::path file () const;
142 };
143
144 class VideoContent : virtual public Content
145 {
146 public:
147   VideoContentFrame video_length () const;
148   float video_frame_rate () const;
149   libdcp::Size size () const;
150
151 };
152
153 class AudioContent : virtual public Content
154 {
155
156 };
157
158 class FFmpegContent : public VideoContent, public AudioContent
159 {
160 public:
161   .. stream stuff ..
162 };
163
164 class ImageMagickContent : public VideoContent
165 {
166
167 };
168
169 class SndfileContent : public AudioContent
170 {
171 public:
172   .. channel allocation for this file ..
173 };
174 \end{verbatim}
175
176 Then Film has a \texttt{Playlist} which has a
177 \texttt{vector<shared\_ptr<Content> >}.  It can answer questions
178 about audio/video length, frame rate, audio channels and so on.
179
180 \texttt{Playlist} can also be a source of video and audio, so clients can do:
181
182 \begin{verbatim}
183 shared_ptr<Playlist> p = film->playlist ();
184 p->Video.connect (foo);
185 p->Audio.connect (foo);
186 while (!p->pass ()) {
187   /* carry on */
188 }
189 \end{verbatim}
190
191 Playlist could be created on-demand for all the difference it would
192 make.  And perhaps it should, since it will hold Decoders which are
193 probably run-once.
194
195 \end{document}