Merge branch 'master' of /home/carl/git/dvdomatic
[dcpomatic.git] / src / lib / film.h
1 /*
2     Copyright (C) 2012 Carl Hetherington <cth@carlh.net>
3
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.
8
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.
13
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.
17
18 */
19
20 /** @file  src/film.h
21  *  @brief A representation of a piece of video (with sound), including naming,
22  *  the source content file, and how it should be presented in a DCP.
23  */
24
25 #ifndef DVDOMATIC_FILM_H
26 #define DVDOMATIC_FILM_H
27
28 #include <string>
29 #include <vector>
30 #include <inttypes.h>
31 #include <boost/thread/mutex.hpp>
32 #include <boost/thread.hpp>
33 #include <boost/signals2.hpp>
34 #include <boost/enable_shared_from_this.hpp>
35 extern "C" {
36 #include <libavcodec/avcodec.h>
37 }
38 #include "dcp_content_type.h"
39 #include "util.h"
40 #include "stream.h"
41 #include "dci_metadata.h"
42
43 class Format;
44 class Job;
45 class Filter;
46 class Log;
47 class ExamineContentJob;
48 class ExternalAudioStream;
49
50 /** @class Film
51  *  @brief A representation of a video, maybe with sound.
52  *
53  *  A representation of a piece of video (maybe with sound), including naming,
54  *  the source content file, and how it should be presented in a DCP.
55  */
56 class Film : public boost::enable_shared_from_this<Film>
57 {
58 public:
59         Film (std::string d, bool must_exist = true);
60         Film (Film const &);
61         ~Film ();
62
63         std::string info_dir () const;
64         std::string j2c_path (int f, bool t) const;
65         std::string info_path (int f) const;
66         std::string video_mxf_dir () const;
67         std::string video_mxf_filename () const;
68
69         void examine_content ();
70         void send_dcp_to_tms ();
71
72         void make_dcp ();
73
74         /** @return Logger.
75          *  It is safe to call this from any thread.
76          */
77         Log* log () const {
78                 return _log;
79         }
80
81         int encoded_frames () const;
82         
83         std::string file (std::string f) const;
84         std::string dir (std::string d) const;
85
86         std::string content_path () const;
87         ContentType content_type () const;
88         
89         int target_audio_sample_rate () const;
90         
91         void write_metadata () const;
92         void read_metadata ();
93
94         libdcp::Size cropped_size (libdcp::Size) const;
95         std::string dci_name (bool if_created_now) const;
96         std::string dcp_name (bool if_created_now = false) const;
97
98         boost::optional<int> dcp_intrinsic_duration () const {
99                 return _dcp_intrinsic_duration;
100         }
101
102         /** @return true if our state has changed since we last saved it */
103         bool dirty () const {
104                 return _dirty;
105         }
106
107         int audio_channels () const;
108
109         void set_dci_date_today ();
110
111         bool have_dcp () const;
112
113         /** Identifiers for the parts of our state;
114             used for signalling changes.
115         */
116         enum Property {
117                 NONE,
118                 NAME,
119                 USE_DCI_NAME,
120                 CONTENT,
121                 TRUST_CONTENT_HEADER,
122                 DCP_CONTENT_TYPE,
123                 FORMAT,
124                 CROP,
125                 FILTERS,
126                 SCALER,
127                 TRIM_START,
128                 TRIM_END,
129                 DCP_AB,
130                 CONTENT_AUDIO_STREAM,
131                 EXTERNAL_AUDIO,
132                 USE_CONTENT_AUDIO,
133                 AUDIO_GAIN,
134                 AUDIO_DELAY,
135                 STILL_DURATION,
136                 SUBTITLE_STREAM,
137                 WITH_SUBTITLES,
138                 SUBTITLE_OFFSET,
139                 SUBTITLE_SCALE,
140                 COLOUR_LUT,
141                 J2K_BANDWIDTH,
142                 DCI_METADATA,
143                 SIZE,
144                 LENGTH,
145                 DCP_INTRINSIC_DURATION,
146                 CONTENT_AUDIO_STREAMS,
147                 SUBTITLE_STREAMS,
148                 FRAMES_PER_SECOND,
149         };
150
151
152         /* GET */
153
154         std::string directory () const {
155                 boost::mutex::scoped_lock lm (_directory_mutex);
156                 return _directory;
157         }
158
159         std::string name () const {
160                 boost::mutex::scoped_lock lm (_state_mutex);
161                 return _name;
162         }
163
164         bool use_dci_name () const {
165                 boost::mutex::scoped_lock lm (_state_mutex);
166                 return _use_dci_name;
167         }
168
169         std::string content () const {
170                 boost::mutex::scoped_lock lm (_state_mutex);
171                 return _content;
172         }
173
174         bool trust_content_header () const {
175                 boost::mutex::scoped_lock lm (_state_mutex);
176                 return _trust_content_header;
177         }
178
179         DCPContentType const * dcp_content_type () const {
180                 boost::mutex::scoped_lock lm (_state_mutex);
181                 return _dcp_content_type;
182         }
183
184         Format const * format () const {
185                 boost::mutex::scoped_lock lm (_state_mutex);
186                 return _format;
187         }
188
189         Crop crop () const {
190                 boost::mutex::scoped_lock lm (_state_mutex);
191                 return _crop;
192         }
193
194         std::vector<Filter const *> filters () const {
195                 boost::mutex::scoped_lock lm (_state_mutex);
196                 return _filters;
197         }
198
199         Scaler const * scaler () const {
200                 boost::mutex::scoped_lock lm (_state_mutex);
201                 return _scaler;
202         }
203
204         int trim_start () const {
205                 boost::mutex::scoped_lock lm (_state_mutex);
206                 return _trim_start;
207         }
208
209         int trim_end () const {
210                 boost::mutex::scoped_lock lm (_state_mutex);
211                 return _trim_end;
212         }
213
214         bool dcp_ab () const {
215                 boost::mutex::scoped_lock lm (_state_mutex);
216                 return _dcp_ab;
217         }
218
219         boost::shared_ptr<AudioStream> content_audio_stream () const {
220                 boost::mutex::scoped_lock lm (_state_mutex);
221                 return _content_audio_stream;
222         }
223
224         std::vector<std::string> external_audio () const {
225                 boost::mutex::scoped_lock lm (_state_mutex);
226                 return _external_audio;
227         }
228
229         bool use_content_audio () const {
230                 boost::mutex::scoped_lock lm (_state_mutex);
231                 return _use_content_audio;
232         }
233         
234         float audio_gain () const {
235                 boost::mutex::scoped_lock lm (_state_mutex);
236                 return _audio_gain;
237         }
238
239         int audio_delay () const {
240                 boost::mutex::scoped_lock lm (_state_mutex);
241                 return _audio_delay;
242         }
243
244         int still_duration () const {
245                 boost::mutex::scoped_lock lm (_state_mutex);
246                 return _still_duration;
247         }
248
249         int still_duration_in_frames () const;
250
251         boost::shared_ptr<SubtitleStream> subtitle_stream () const {
252                 boost::mutex::scoped_lock lm (_state_mutex);
253                 return _subtitle_stream;
254         }
255
256         bool with_subtitles () const {
257                 boost::mutex::scoped_lock lm (_state_mutex);
258                 return _with_subtitles;
259         }
260
261         int subtitle_offset () const {
262                 boost::mutex::scoped_lock lm (_state_mutex);
263                 return _subtitle_offset;
264         }
265
266         float subtitle_scale () const {
267                 boost::mutex::scoped_lock lm (_state_mutex);
268                 return _subtitle_scale;
269         }
270
271         int colour_lut () const {
272                 boost::mutex::scoped_lock lm (_state_mutex);
273                 return _colour_lut;
274         }
275
276         int j2k_bandwidth () const {
277                 boost::mutex::scoped_lock lm (_state_mutex);
278                 return _j2k_bandwidth;
279         }
280
281         DCIMetadata dci_metadata () const {
282                 boost::mutex::scoped_lock lm (_state_mutex);
283                 return _dci_metadata;
284         }
285         
286         libdcp::Size size () const {
287                 boost::mutex::scoped_lock lm (_state_mutex);
288                 return _size;
289         }
290
291         boost::optional<SourceFrame> length () const {
292                 boost::mutex::scoped_lock lm (_state_mutex);
293                 return _length;
294         }
295         
296         std::string content_digest () const {
297                 boost::mutex::scoped_lock lm (_state_mutex);
298                 return _content_digest;
299         }
300         
301         std::vector<boost::shared_ptr<AudioStream> > content_audio_streams () const {
302                 boost::mutex::scoped_lock lm (_state_mutex);
303                 return _content_audio_streams;
304         }
305
306         std::vector<boost::shared_ptr<SubtitleStream> > subtitle_streams () const {
307                 boost::mutex::scoped_lock lm (_state_mutex);
308                 return _subtitle_streams;
309         }
310         
311         float frames_per_second () const {
312                 boost::mutex::scoped_lock lm (_state_mutex);
313                 if (content_type() == STILL) {
314                         return 24;
315                 }
316                 
317                 return _frames_per_second;
318         }
319
320         boost::shared_ptr<AudioStream> audio_stream () const;
321
322         
323         /* SET */
324
325         void set_directory (std::string);
326         void set_name (std::string);
327         void set_use_dci_name (bool);
328         void set_content (std::string);
329         void set_trust_content_header (bool);
330         void set_dcp_content_type (DCPContentType const *);
331         void set_format (Format const *);
332         void set_crop (Crop);
333         void set_left_crop (int);
334         void set_right_crop (int);
335         void set_top_crop (int);
336         void set_bottom_crop (int);
337         void set_filters (std::vector<Filter const *>);
338         void set_scaler (Scaler const *);
339         void set_trim_start (int);
340         void set_trim_end (int);
341         void set_dcp_ab (bool);
342         void set_content_audio_stream (boost::shared_ptr<AudioStream>);
343         void set_external_audio (std::vector<std::string>);
344         void set_use_content_audio (bool);
345         void set_audio_gain (float);
346         void set_audio_delay (int);
347         void set_still_duration (int);
348         void set_subtitle_stream (boost::shared_ptr<SubtitleStream>);
349         void set_with_subtitles (bool);
350         void set_subtitle_offset (int);
351         void set_subtitle_scale (float);
352         void set_colour_lut (int);
353         void set_j2k_bandwidth (int);
354         void set_dci_metadata (DCIMetadata);
355         void set_size (libdcp::Size);
356         void set_length (SourceFrame);
357         void unset_length ();
358         void set_dcp_intrinsic_duration (int);
359         void set_content_digest (std::string);
360         void set_content_audio_streams (std::vector<boost::shared_ptr<AudioStream> >);
361         void set_subtitle_streams (std::vector<boost::shared_ptr<SubtitleStream> >);
362         void set_frames_per_second (float);
363
364         /** Emitted when some property has changed */
365         mutable boost::signals2::signal<void (Property)> Changed;
366
367         /** Current version number of the state file */
368         static int const state_version;
369
370 private:
371         
372         /** Log to write to */
373         Log* _log;
374
375         /** Any running ExamineContentJob, or 0 */
376         boost::shared_ptr<ExamineContentJob> _examine_content_job;
377
378         void signal_changed (Property);
379         void examine_content_finished ();
380         std::string video_state_identifier () const;
381
382         /** Complete path to directory containing the film metadata;
383          *  must not be relative.
384          */
385         std::string _directory;
386         /** Mutex for _directory */
387         mutable boost::mutex _directory_mutex;
388         
389         /** Name for DVD-o-matic */
390         std::string _name;
391         /** True if a auto-generated DCI-compliant name should be used for our DCP */
392         bool _use_dci_name;
393         /** File or directory containing content; may be relative to our directory
394          *  or an absolute path.
395          */
396         std::string _content;
397         /** If this is true, we will believe the length specified by the content
398          *  file's header; if false, we will run through the whole content file
399          *  the first time we see it in order to obtain the length.
400          */
401         bool _trust_content_header;
402         /** The type of content that this Film represents (feature, trailer etc.) */
403         DCPContentType const * _dcp_content_type;
404         /** The format to present this Film in (flat, scope, etc.) */
405         Format const * _format;
406         /** The crop to apply to the source */
407         Crop _crop;
408         /** Video filters that should be used when generating DCPs */
409         std::vector<Filter const *> _filters;
410         /** Scaler algorithm to use */
411         Scaler const * _scaler;
412         /** Frames to trim off the start of the DCP */
413         int _trim_start;
414         /** Frames to trim off the end of the DCP */
415         int _trim_end;
416         /** true to create an A/B comparison DCP, where the left half of the image
417             is the video without any filters or post-processing, and the right half
418             has the specified filters and post-processing.
419         */
420         bool _dcp_ab;
421         /** The audio stream to use from our content */
422         boost::shared_ptr<AudioStream> _content_audio_stream;
423         /** List of filenames of external audio files, in channel order
424             (L, R, C, Lfe, Ls, Rs)
425         */
426         std::vector<std::string> _external_audio;
427         /** true to use audio from our content file; false to use external audio */
428         bool _use_content_audio;
429         /** Gain to apply to audio in dB */
430         float _audio_gain;
431         /** Delay to apply to audio (positive moves audio later) in milliseconds */
432         int _audio_delay;
433         /** Duration to make still-sourced films (in seconds) */
434         int _still_duration;
435         boost::shared_ptr<SubtitleStream> _subtitle_stream;
436         /** True if subtitles should be shown for this film */
437         bool _with_subtitles;
438         /** y offset for placing subtitles, in source pixels; +ve is further down
439             the frame, -ve is further up.
440         */
441         int _subtitle_offset;
442         /** scale factor to apply to subtitles */
443         float _subtitle_scale;
444         /** index of colour LUT to use when converting RGB to XYZ.
445          *  0: sRGB
446          *  1: Rec 709
447          */
448         int _colour_lut;
449         /** bandwidth for J2K files in bits per second */
450         int _j2k_bandwidth;
451
452         /** DCI naming stuff */
453         DCIMetadata _dci_metadata;
454         /** The date that we should use in a DCI name */
455         boost::gregorian::date _dci_date;
456
457         /* Data which are cached to speed things up */
458
459         /** Size, in pixels, of the source (ignoring cropping) */
460         libdcp::Size _size;
461         /** The length of the source, in video frames (as far as we know) */
462         boost::optional<SourceFrame> _length;
463         boost::optional<int> _dcp_intrinsic_duration;
464         /** MD5 digest of our content file */
465         std::string _content_digest;
466         /** The audio streams in our content */
467         std::vector<boost::shared_ptr<AudioStream> > _content_audio_streams;
468         /** A stream to represent possible external audio (will always exist) */
469         boost::shared_ptr<AudioStream> _external_audio_stream;
470         /** the subtitle streams that we can use */
471         std::vector<boost::shared_ptr<SubtitleStream> > _subtitle_streams;
472         /** Frames per second of the source */
473         float _frames_per_second;
474
475         /** true if our state has changed since we last saved it */
476         mutable bool _dirty;
477
478         /** Mutex for all state except _directory */
479         mutable boost::mutex _state_mutex;
480
481         friend class paths_test;
482         friend class film_metadata_test;
483 };
484
485 #endif