Compiles; strange hang on adding content to a 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 #include "image.h"
31
32 using std::list;
33 using std::cout;
34 using std::min;
35 using std::vector;
36 using boost::shared_ptr;
37 using boost::weak_ptr;
38 using boost::dynamic_pointer_cast;
39
40 Player::Player (shared_ptr<const Film> f, shared_ptr<const Playlist> p)
41         : _film (f)
42         , _playlist (p)
43         , _video (true)
44         , _audio (true)
45         , _subtitles (true)
46         , _have_valid_decoders (false)
47         , _position (0)
48         , _audio_buffers (MAX_AUDIO_CHANNELS, 0)
49         , _last_video (0)
50         , _last_was_black (false)
51         , _last_audio (0)
52 {
53         _playlist->Changed.connect (bind (&Player::playlist_changed, this));
54         _playlist->ContentChanged.connect (bind (&Player::content_changed, this, _1, _2));
55 }
56
57 void
58 Player::disable_video ()
59 {
60         _video = false;
61 }
62
63 void
64 Player::disable_audio ()
65 {
66         _audio = false;
67 }
68
69 void
70 Player::disable_subtitles ()
71 {
72         _subtitles = false;
73 }
74
75 bool
76 Player::pass ()
77 {
78         if (!_have_valid_decoders) {
79                 setup_decoders ();
80                 _have_valid_decoders = true;
81         }
82
83         cout << "-> Player::pass\n";
84         
85         /* Here we are just finding the active decoder with the earliest last emission time, then
86            calling pass on it.  If there is no decoder, we skip our position on until there is.
87            Hence this method will cause video and audio to be emitted, and it is up to the
88            process_{video,audio} methods to tidy it up.
89         */
90
91         Time earliest_pos = TIME_MAX;
92         shared_ptr<RegionDecoder> earliest;
93         Time next_wait = TIME_MAX;
94
95         for (list<shared_ptr<RegionDecoder> >::iterator i = _decoders.begin(); i != _decoders.end(); ++i) {
96                 Time const ts = (*i)->region.time;
97                 Time const te = (*i)->region.time + (*i)->region.content->length (_film);
98                 if (ts <= _position && te > _position) {
99                         Time const pos = ts + (*i)->last;
100                         if (pos < earliest_pos) {
101                                 earliest_pos = pos;
102                                 earliest = *i;
103                         }
104                 }
105
106                 if (ts > _position) {
107                         next_wait = min (next_wait, ts - _position);
108                 }
109         }
110
111         if (earliest) {
112                 earliest->decoder->pass ();
113                 _position = earliest->last;
114         } else if (next_wait < TIME_MAX) {
115                 _position += next_wait;
116         } else {
117                 cout << "<- Player::pass\n";
118                 return true;
119         }
120
121         cout << "<- Player::pass\n";
122         return false;
123 }
124
125 void
126 Player::process_video (shared_ptr<RegionDecoder> rd, shared_ptr<const Image> image, bool same, shared_ptr<Subtitle> sub, Time time)
127 {
128         shared_ptr<VideoDecoder> vd = dynamic_pointer_cast<VideoDecoder> (rd->decoder);
129         
130         Time const global_time = rd->region.time + time;
131         while ((global_time - _last_video) > 1) {
132                 /* Fill in with black */
133                 emit_black_frame ();
134         }
135
136         Video (image, same, sub, global_time);
137         rd->last = time;
138         _last_video = global_time;
139         _last_was_black = false;
140 }
141
142 void
143 Player::process_audio (shared_ptr<RegionDecoder> rd, shared_ptr<const AudioBuffers> audio, Time time)
144 {
145         /* XXX: mapping */
146
147         /* The time of this audio may indicate that some of our buffered audio is not going to
148            be added to any more, so it can be emitted.
149         */
150
151         if (time > _last_audio) {
152                 /* We can emit some audio from our buffers */
153                 OutputAudioFrame const N = min (_film->time_to_audio_frames (time - _last_audio), static_cast<OutputAudioFrame> (_audio_buffers.frames()));
154                 shared_ptr<AudioBuffers> emit (new AudioBuffers (_audio_buffers.channels(), N));
155                 emit->copy_from (&_audio_buffers, N, 0, 0);
156                 Audio (emit, _last_audio);
157                 _last_audio += _film->audio_frames_to_time (N);
158
159                 /* And remove it from our buffers */
160                 if (_audio_buffers.frames() > N) {
161                         _audio_buffers.move (N, 0, _audio_buffers.frames() - N);
162                 }
163                 _audio_buffers.set_frames (_audio_buffers.frames() - N);
164         }
165
166         /* Now accumulate the new audio into our buffers */
167
168         if (_audio_buffers.frames() == 0) {
169                 /* We have no remaining data.  Emit silence up to the start of this new data */
170                 if ((time - _last_audio) > 0) {
171                         emit_silence (time - _last_audio);
172                 }
173         }
174
175         _audio_buffers.ensure_size (time - _last_audio + audio->frames());
176         _audio_buffers.accumulate (audio.get(), 0, _film->time_to_audio_frames (time - _last_audio));
177         rd->last = time + _film->audio_frames_to_time (audio->frames ());
178 }
179
180 /** @return true on error */
181 bool
182 Player::seek (Time t)
183 {
184         if (!_have_valid_decoders) {
185                 setup_decoders ();
186                 _have_valid_decoders = true;
187         }
188
189         if (_decoders.empty ()) {
190                 return true;
191         }
192
193         /* XXX */
194
195         /* XXX: don't seek audio because we don't need to... */
196
197         return false;
198 }
199
200
201 void
202 Player::seek_back ()
203 {
204         /* XXX */
205 }
206
207 void
208 Player::seek_forward ()
209 {
210         /* XXX */
211 }
212
213
214 void
215 Player::setup_decoders ()
216 {
217         list<shared_ptr<RegionDecoder> > old_decoders = _decoders;
218
219         _decoders.clear ();
220
221         Playlist::RegionList regions = _playlist->regions ();
222         for (Playlist::RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
223
224                 shared_ptr<RegionDecoder> rd (new RegionDecoder);
225                 rd->region = *i;
226                 
227                 /* XXX: into content? */
228
229                 shared_ptr<const FFmpegContent> fc = dynamic_pointer_cast<const FFmpegContent> (i->content);
230                 if (fc) {
231                         shared_ptr<FFmpegDecoder> fd (new FFmpegDecoder (_film, fc, _video, _audio, _subtitles));
232                         
233                         fd->Video.connect (bind (&Player::process_video, this, rd, _1, _2, _3, _4));
234                         fd->Audio.connect (bind (&Player::process_audio, this, rd, _1, _2));
235
236                         rd->decoder = fd;
237                 }
238                 
239                 shared_ptr<const ImageMagickContent> ic = dynamic_pointer_cast<const ImageMagickContent> (i->content);
240                 if (ic) {
241                         shared_ptr<ImageMagickDecoder> id;
242                         
243                         /* See if we can re-use an old ImageMagickDecoder */
244                         for (list<shared_ptr<RegionDecoder> >::const_iterator i = old_decoders.begin(); i != old_decoders.end(); ++i) {
245                                 shared_ptr<ImageMagickDecoder> imd = dynamic_pointer_cast<ImageMagickDecoder> ((*i)->decoder);
246                                 if (imd && imd->content() == ic) {
247                                         id = imd;
248                                 }
249                         }
250
251                         if (!id) {
252                                 id.reset (new ImageMagickDecoder (_film, ic));
253                                 id->Video.connect (bind (&Player::process_video, this, rd, _1, _2, _3, _4));
254                         }
255
256                         rd->decoder = id;
257                 }
258
259                 shared_ptr<const SndfileContent> sc = dynamic_pointer_cast<const SndfileContent> (i->content);
260                 if (sc) {
261                         shared_ptr<AudioDecoder> sd (new SndfileDecoder (_film, sc));
262                         sd->Audio.connect (bind (&Player::process_audio, this, rd, _1, _2));
263
264                         rd->decoder = sd;
265                 }
266
267                 _decoders.push_back (rd);
268         }
269
270         _position = 0;
271 }
272
273 void
274 Player::content_changed (weak_ptr<Content> w, int p)
275 {
276         shared_ptr<Content> c = w.lock ();
277         if (!c) {
278                 return;
279         }
280
281         if (p == VideoContentProperty::VIDEO_LENGTH) {
282                 _have_valid_decoders = false;
283         }
284 }
285
286 void
287 Player::playlist_changed ()
288 {
289         _have_valid_decoders = false;
290 }
291
292 void
293 Player::emit_black_frame ()
294 {
295         shared_ptr<SimpleImage> image (new SimpleImage (AV_PIX_FMT_RGB24, libdcp::Size (128, 128), true));
296         Video (image, _last_was_black, shared_ptr<Subtitle> (), _last_video);
297         _last_video += _film->video_frames_to_time (1);
298 }
299
300 void
301 Player::emit_silence (Time t)
302 {
303         OutputAudioFrame frames = _film->time_to_audio_frames (t);
304         while (frames) {
305                 /* Do this in half-second chunks so we don't overwhelm anybody */
306                 OutputAudioFrame this_time = min (_film->dcp_audio_frame_rate() / 2, frames);
307                 shared_ptr<AudioBuffers> silence (new AudioBuffers (MAX_AUDIO_CHANNELS, this_time));
308                 silence->make_silent ();
309                 Audio (silence, _last_audio);
310                 _last_audio += _film->audio_frames_to_time (this_time);
311                 frames -= this_time;
312         }
313 }