Merge master; fix crash on new film.
[dcpomatic.git] / src / lib / player.cc
1 /*
2     Copyright (C) 2013 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 "player.h"
21 #include "film.h"
22 #include "ffmpeg_decoder.h"
23 #include "ffmpeg_content.h"
24 #include "imagemagick_decoder.h"
25 #include "imagemagick_content.h"
26 #include "sndfile_decoder.h"
27 #include "sndfile_content.h"
28 #include "playlist.h"
29 #include "job.h"
30
31 using std::list;
32 using std::cout;
33 using std::vector;
34 using boost::shared_ptr;
35 using boost::weak_ptr;
36 using boost::dynamic_pointer_cast;
37
38 Player::Player (shared_ptr<const Film> f, shared_ptr<const Playlist> p)
39         : _film (f)
40         , _playlist (p)
41         , _video (true)
42         , _audio (true)
43         , _subtitles (true)
44         , _have_valid_decoders (false)
45 {
46         _playlist->Changed.connect (bind (&Player::playlist_changed, this));
47         _playlist->ContentChanged.connect (bind (&Player::content_changed, this, _1, _2));
48 }
49
50 void
51 Player::disable_video ()
52 {
53         _video = false;
54 }
55
56 void
57 Player::disable_audio ()
58 {
59         _audio = false;
60 }
61
62 void
63 Player::disable_subtitles ()
64 {
65         _subtitles = false;
66 }
67
68 bool
69 Player::pass ()
70 {
71         if (!_have_valid_decoders) {
72                 setup_decoders ();
73                 _have_valid_decoders = true;
74         }
75         
76         bool done = true;
77         
78         if (_video && _video_decoder < _video_decoders.size ()) {
79
80                 /* Run video decoder; this may also produce audio */
81                 
82                 if (_video_decoders[_video_decoder]->pass ()) {
83                         _video_decoder++;
84                 }
85                 
86                 if (_video_decoder < _video_decoders.size ()) {
87                         done = false;
88                 }
89                 
90         }
91
92         if (!_video && _audio && _playlist->audio_from() == Playlist::AUDIO_FFMPEG && _sequential_audio_decoder < _audio_decoders.size ()) {
93
94                 /* We're not producing video, so we may need to run FFmpeg content to get the audio */
95                 
96                 if (_audio_decoders[_sequential_audio_decoder]->pass ()) {
97                         _sequential_audio_decoder++;
98                 }
99                 
100                 if (_sequential_audio_decoder < _audio_decoders.size ()) {
101                         done = false;
102                 }
103                 
104         }
105
106         if (_audio && _playlist->audio_from() == Playlist::AUDIO_SNDFILE) {
107                 
108                 /* We're getting audio from SndfileContent */
109                 
110                 for (vector<shared_ptr<AudioDecoder> >::iterator i = _audio_decoders.begin(); i != _audio_decoders.end(); ++i) {
111                         if (!(*i)->pass ()) {
112                                 done = false;
113                         }
114                 }
115
116                 Audio (_audio_buffers, _audio_time.get());
117                 _audio_buffers.reset ();
118                 _audio_time = boost::none;
119         }
120
121         return done;
122 }
123
124 void
125 Player::set_progress (shared_ptr<Job> job)
126 {
127         /* Assume progress can be divined from how far through the video we are */
128
129         if (_video_decoder >= _video_decoders.size() || !_playlist->video_length()) {
130                 return;
131         }
132
133         job->set_progress ((_video_start[_video_decoder] + _video_decoders[_video_decoder]->video_frame()) / _playlist->video_length ());
134 }
135
136 void
137 Player::process_video (shared_ptr<const Image> i, bool same, shared_ptr<Subtitle> s, double t)
138 {
139         Video (i, same, s, _video_start[_video_decoder] + t);
140 }
141
142 void
143 Player::process_audio (weak_ptr<const AudioContent> c, shared_ptr<const AudioBuffers> b, double t)
144 {
145         AudioMapping mapping = _film->audio_mapping ();
146         if (!_audio_buffers) {
147                 _audio_buffers.reset (new AudioBuffers (mapping.dcp_channels(), b->frames ()));
148                 _audio_buffers->make_silent ();
149                 _audio_time = t;
150                 if (_playlist->audio_from() == Playlist::AUDIO_FFMPEG) {
151                         _audio_time = _audio_time.get() + _audio_start[_sequential_audio_decoder];
152                 }
153         }
154
155         for (int i = 0; i < b->channels(); ++i) {
156                 list<libdcp::Channel> dcp = mapping.content_to_dcp (AudioMapping::Channel (c, i));
157                 for (list<libdcp::Channel>::iterator j = dcp.begin(); j != dcp.end(); ++j) {
158                         _audio_buffers->accumulate (b, i, static_cast<int> (*j));
159                 }
160         }
161
162         if (_playlist->audio_from() == Playlist::AUDIO_FFMPEG) {
163                 /* We can just emit this audio now as it will all be here */
164                 Audio (_audio_buffers, t);
165                 _audio_buffers.reset ();
166                 _audio_time = boost::none;
167         }
168 }
169
170 /** @return true on error */
171 bool
172 Player::seek (double t)
173 {
174         if (!_have_valid_decoders) {
175                 setup_decoders ();
176                 _have_valid_decoders = true;
177         }
178
179         if (_video_decoders.empty ()) {
180                 return true;
181         }
182
183         /* Find the decoder that contains this position */
184         _video_decoder = 0;
185         while (1) {
186                 ++_video_decoder;
187                 if (_video_decoder >= _video_decoders.size () || t < _video_start[_video_decoder]) {
188                         --_video_decoder;
189                         t -= _video_start[_video_decoder];
190                         break;
191                 }
192         }
193
194         if (_video_decoder < _video_decoders.size()) {
195                 _video_decoders[_video_decoder]->seek (t);
196         } else {
197                 return true;
198         }
199
200         /* XXX: don't seek audio because we don't need to... */
201
202         return false;
203 }
204
205
206 void
207 Player::seek_back ()
208 {
209         /* XXX */
210 }
211
212 void
213 Player::seek_forward ()
214 {
215         /* XXX */
216 }
217
218
219 void
220 Player::setup_decoders ()
221 {
222         _video_decoders.clear ();
223         _video_decoder = 0;
224         _audio_decoders.clear ();
225         _sequential_audio_decoder = 0;
226
227         _video_start.clear();
228         _audio_start.clear();
229
230         double video_so_far = 0;
231         double audio_so_far = 0;
232         
233         list<shared_ptr<const VideoContent> > vc = _playlist->video ();
234         for (list<shared_ptr<const VideoContent> >::iterator i = vc.begin(); i != vc.end(); ++i) {
235                 
236                 shared_ptr<const VideoContent> video_content;
237                 shared_ptr<const AudioContent> audio_content;
238                 shared_ptr<VideoDecoder> video_decoder;
239                 shared_ptr<AudioDecoder> audio_decoder;
240                 
241                 /* XXX: into content? */
242                 
243                 shared_ptr<const FFmpegContent> fc = dynamic_pointer_cast<const FFmpegContent> (*i);
244                 if (fc) {
245                         shared_ptr<FFmpegDecoder> fd (
246                                 new FFmpegDecoder (
247                                         _film, fc, _video,
248                                         _audio && _playlist->audio_from() == Playlist::AUDIO_FFMPEG,
249                                         _subtitles
250                                         )
251                                 );
252                         
253                         video_content = fc;
254                         audio_content = fc;
255                         video_decoder = fd;
256                         audio_decoder = fd;
257                 }
258                 
259                 shared_ptr<const ImageMagickContent> ic = dynamic_pointer_cast<const ImageMagickContent> (*i);
260                 if (ic) {
261                         video_content = ic;
262                         video_decoder.reset (new ImageMagickDecoder (_film, ic));
263                 }
264                 
265                 video_decoder->connect_video (shared_from_this ());
266                 _video_decoders.push_back (video_decoder);
267                 _video_start.push_back (video_so_far);
268                 video_so_far += video_content->video_length() / video_content->video_frame_rate();
269
270                 if (audio_decoder && _playlist->audio_from() == Playlist::AUDIO_FFMPEG) {
271                         audio_decoder->Audio.connect (bind (&Player::process_audio, this, audio_content, _1, _2));
272                         _audio_decoders.push_back (audio_decoder);
273                         _audio_start.push_back (audio_so_far);
274                         audio_so_far += double(audio_content->audio_length()) / audio_content->audio_frame_rate();
275                 }
276         }
277         
278         _video_decoder = 0;
279         _sequential_audio_decoder = 0;
280
281         if (_playlist->audio_from() == Playlist::AUDIO_SNDFILE) {
282                 
283                 list<shared_ptr<const AudioContent> > ac = _playlist->audio ();
284                 for (list<shared_ptr<const AudioContent> >::iterator i = ac.begin(); i != ac.end(); ++i) {
285                         
286                         shared_ptr<const SndfileContent> sc = dynamic_pointer_cast<const SndfileContent> (*i);
287                         assert (sc);
288                         
289                         shared_ptr<AudioDecoder> d (new SndfileDecoder (_film, sc));
290                         d->Audio.connect (bind (&Player::process_audio, this, sc, _1, _2));
291                         _audio_decoders.push_back (d);
292                         _audio_start.push_back (audio_so_far);
293                 }
294         }
295 }
296
297 double
298 Player::last_video_time () const
299 {
300         return _video_start[_video_decoder] + _video_decoders[_video_decoder]->last_content_time ();
301 }
302
303 void
304 Player::content_changed (weak_ptr<Content> w, int p)
305 {
306         shared_ptr<Content> c = w.lock ();
307         if (!c) {
308                 return;
309         }
310
311         if (p == VideoContentProperty::VIDEO_LENGTH) {
312                 if (dynamic_pointer_cast<FFmpegContent> (c)) {
313                         /* FFmpeg content length changes are serious; we need new decoders */
314                         _have_valid_decoders = false;
315                 }
316         }
317 }
318
319 void
320 Player::playlist_changed ()
321 {
322         _have_valid_decoders = false;
323 }