Various bits.
[dcpomatic.git] / src / lib / writer.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 #include <list>
21 #include <boost/shared_ptr.hpp>
22 #include <boost/thread.hpp>
23 #include <boost/thread/condition.hpp>
24 #include "exceptions.h"
25
26 class Film;
27 class EncodedData;
28 class AudioBuffers;
29
30 namespace libdcp {
31         class MonoPictureAsset;
32         class MonoPictureAssetWriter;
33         class SoundAsset;
34         class SoundAssetWriter;
35 }
36
37 struct QueueItem
38 {
39 public:
40         enum Type {
41                 /** a normal frame with some JPEG200 data */
42                 FULL,
43                 /** a frame whose data already exists in the MXF,
44                     and we fake-write it; i.e. we update the writer's
45                     state but we use the data that is already on disk.
46                 */
47                 FAKE,
48                 /** this is a repeat of the last frame to be written */
49                 REPEAT
50         } type;
51
52         /** encoded data for FULL */
53         boost::shared_ptr<const EncodedData> encoded;
54         /** size of data for FAKE */
55         int size;
56         /** frame index */
57         int frame;
58 };
59
60 bool operator< (QueueItem const & a, QueueItem const & b);
61 bool operator== (QueueItem const & a, QueueItem const & b);
62
63 class Writer : public ExceptionStore
64 {
65 public:
66         Writer (boost::shared_ptr<Film>);
67
68         bool can_fake_write (int) const;
69         
70         void write (boost::shared_ptr<const EncodedData>, int);
71         void fake_write (int);
72         void write (boost::shared_ptr<const AudioBuffers>);
73         void repeat (int f);
74         void finish ();
75
76 private:
77
78         void thread ();
79         void check_existing_picture_mxf ();
80
81         /** our Film */
82         boost::shared_ptr<Film> _film;
83         /** the first frame index that does not already exist in our MXF */
84         int _first_nonexistant_frame;
85
86         /** our thread, or 0 */
87         boost::thread* _thread;
88         /** true if our thread should finish */
89         bool _finish;
90         /** queue of things to write to disk */
91         std::list<QueueItem> _queue;
92         /** number of FULL frames whose JPEG200 data is currently held in RAM */
93         int _queued_full_in_memory;
94         /** mutex for thread state */
95         mutable boost::mutex _mutex;
96         /** condition to manage thread wakeups */
97         boost::condition _condition;
98         /** the data of the last written frame, or 0 if there isn't one */
99         boost::shared_ptr<const EncodedData> _last_written;
100         /** the index of the last written frame */
101         int _last_written_frame;
102         /** maximum number of frames to hold in memory, for when we are managing
103             ordering
104         */
105         static const int _maximum_frames_in_memory;
106
107         /** number of FULL written frames */
108         int _full_written;
109         /** number of FAKE written frames */
110         int _fake_written;
111         /** number of REPEAT written frames */
112         int _repeat_written;
113         /** number of frames pushed to disk and then recovered
114             due to the limit of frames to be held in memory.
115         */
116         int _pushed_to_disk;
117         
118         boost::shared_ptr<libdcp::MonoPictureAsset> _picture_asset;
119         boost::shared_ptr<libdcp::MonoPictureAssetWriter> _picture_asset_writer;
120         boost::shared_ptr<libdcp::SoundAsset> _sound_asset;
121         boost::shared_ptr<libdcp::SoundAssetWriter> _sound_asset_writer;
122 };