95036cfe0ae18f1ca24ffebea6a8f2a899eb61c6
[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::process_video (shared_ptr<const Image> i, bool same, shared_ptr<Subtitle> s, double t)
126 {
127         Video (i, same, s, _video_start[_video_decoder] + t);
128 }
129
130 void
131 Player::process_audio (weak_ptr<const AudioContent> c, shared_ptr<const AudioBuffers> b, double t)
132 {
133         AudioMapping mapping = _film->audio_mapping ();
134         if (!_audio_buffers) {
135                 _audio_buffers.reset (new AudioBuffers (mapping.dcp_channels(), b->frames ()));
136                 _audio_buffers->make_silent ();
137                 _audio_time = t;
138                 if (_playlist->audio_from() == Playlist::AUDIO_FFMPEG) {
139                         _audio_time = _audio_time.get() + _audio_start[_sequential_audio_decoder];
140                 }
141         }
142
143         for (int i = 0; i < b->channels(); ++i) {
144                 list<libdcp::Channel> dcp = mapping.content_to_dcp (AudioMapping::Channel (c, i));
145                 for (list<libdcp::Channel>::iterator j = dcp.begin(); j != dcp.end(); ++j) {
146                         _audio_buffers->accumulate (b, i, static_cast<int> (*j));
147                 }
148         }
149
150         if (_playlist->audio_from() == Playlist::AUDIO_FFMPEG) {
151                 /* We can just emit this audio now as it will all be here */
152                 Audio (_audio_buffers, t);
153                 _audio_buffers.reset ();
154                 _audio_time = boost::none;
155         }
156 }
157
158 /** @return true on error */
159 bool
160 Player::seek (double t)
161 {
162         if (!_have_valid_decoders) {
163                 setup_decoders ();
164                 _have_valid_decoders = true;
165         }
166
167         if (_video_decoders.empty ()) {
168                 return true;
169         }
170
171         /* Find the decoder that contains this position */
172         _video_decoder = 0;
173         while (1) {
174                 ++_video_decoder;
175                 if (_video_decoder >= _video_decoders.size () || t < _video_start[_video_decoder]) {
176                         --_video_decoder;
177                         t -= _video_start[_video_decoder];
178                         break;
179                 }
180         }
181
182         if (_video_decoder < _video_decoders.size()) {
183                 _video_decoders[_video_decoder]->seek (t);
184         } else {
185                 return true;
186         }
187
188         /* XXX: don't seek audio because we don't need to... */
189
190         return false;
191 }
192
193
194 void
195 Player::seek_back ()
196 {
197         /* XXX */
198 }
199
200 void
201 Player::seek_forward ()
202 {
203         /* XXX */
204 }
205
206
207 void
208 Player::setup_decoders ()
209 {
210         vector<shared_ptr<VideoDecoder> > old_video_decoders = _video_decoders;
211
212         _video_decoders.clear ();
213         _video_decoder = 0;
214         _audio_decoders.clear ();
215         _sequential_audio_decoder = 0;
216
217         _video_start.clear();
218         _audio_start.clear();
219
220         double video_so_far = 0;
221         double audio_so_far = 0;
222
223         for (int l = 0; l < _playlist->loop(); ++l) {
224                 list<shared_ptr<const VideoContent> > vc = _playlist->video ();
225                 for (list<shared_ptr<const VideoContent> >::iterator i = vc.begin(); i != vc.end(); ++i) {
226                         
227                         shared_ptr<const VideoContent> video_content;
228                         shared_ptr<const AudioContent> audio_content;
229                         shared_ptr<VideoDecoder> video_decoder;
230                         shared_ptr<AudioDecoder> audio_decoder;
231                         
232                         /* XXX: into content? */
233                         
234                         shared_ptr<const FFmpegContent> fc = dynamic_pointer_cast<const FFmpegContent> (*i);
235                         if (fc) {
236                                 shared_ptr<FFmpegDecoder> fd (
237                                         new FFmpegDecoder (
238                                                 _film, fc, _video,
239                                                 _audio && _playlist->audio_from() == Playlist::AUDIO_FFMPEG,
240                                                 _subtitles
241                                                 )
242                                         );
243                                 
244                                 video_content = fc;
245                                 audio_content = fc;
246                                 video_decoder = fd;
247                                 audio_decoder = fd;
248
249                                 video_decoder->connect_video (shared_from_this ());
250                         }
251                         
252                         shared_ptr<const ImageMagickContent> ic = dynamic_pointer_cast<const ImageMagickContent> (*i);
253                         if (ic) {
254                                 video_content = ic;
255
256                                 /* See if we can re-use an old ImageMagickDecoder */
257                                 for (vector<shared_ptr<VideoDecoder> >::const_iterator i = old_video_decoders.begin(); i != old_video_decoders.end(); ++i) {
258                                         shared_ptr<ImageMagickDecoder> imd = dynamic_pointer_cast<ImageMagickDecoder> (*i);
259                                         if (imd && imd->content() == ic) {
260                                                 video_decoder = *i;
261                                         }
262                                 }
263
264                                 if (!video_decoder) {
265                                         video_decoder.reset (new ImageMagickDecoder (_film, ic));
266                                         video_decoder->connect_video (shared_from_this ());
267                                 }
268                         }
269                         
270                         _video_decoders.push_back (video_decoder);
271                         _video_start.push_back (video_so_far);
272                         video_so_far += video_content->video_length() / video_content->video_frame_rate();
273                         
274                         if (audio_decoder && _playlist->audio_from() == Playlist::AUDIO_FFMPEG) {
275                                 audio_decoder->Audio.connect (bind (&Player::process_audio, this, audio_content, _1, _2));
276                                 _audio_decoders.push_back (audio_decoder);
277                                 _audio_start.push_back (audio_so_far);
278                                 audio_so_far += double(audio_content->audio_length()) / audio_content->audio_frame_rate();
279                         }
280                 }
281                 
282                 _video_decoder = 0;
283                 _sequential_audio_decoder = 0;
284                 
285                 if (_playlist->audio_from() == Playlist::AUDIO_SNDFILE) {
286                         
287                         list<shared_ptr<const AudioContent> > ac = _playlist->audio ();
288                         for (list<shared_ptr<const AudioContent> >::iterator i = ac.begin(); i != ac.end(); ++i) {
289                                 
290                                 shared_ptr<const SndfileContent> sc = dynamic_pointer_cast<const SndfileContent> (*i);
291                                 assert (sc);
292                                 
293                                 shared_ptr<AudioDecoder> d (new SndfileDecoder (_film, sc));
294                                 d->Audio.connect (bind (&Player::process_audio, this, sc, _1, _2));
295                                 _audio_decoders.push_back (d);
296                                 _audio_start.push_back (audio_so_far);
297                         }
298                 }
299         }
300 }
301
302 double
303 Player::last_video_time () const
304 {
305         if (_video_decoder >= _video_decoders.size ()) {
306                 return 0;
307         }
308         
309         return _video_start[_video_decoder] + _video_decoders[_video_decoder]->last_content_time ();
310 }
311
312 void
313 Player::content_changed (weak_ptr<Content> w, int p)
314 {
315         shared_ptr<Content> c = w.lock ();
316         if (!c) {
317                 return;
318         }
319
320         if (p == VideoContentProperty::VIDEO_LENGTH) {
321                 _have_valid_decoders = false;
322         }
323 }
324
325 void
326 Player::playlist_changed ()
327 {
328         _have_valid_decoders = false;
329 }