675fcae5cc1b6a3d927e926f8037885610cb0ca4
[dcpomatic.git] / src / lib / player.cc
1 /* -*- c-basic-offset: 8; default-tab-width: 8; -*- */
2
3 /*
4     Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
5
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
20 */
21
22 #include "player.h"
23 #include "film.h"
24 #include "ffmpeg_decoder.h"
25 #include "ffmpeg_content.h"
26 #include "imagemagick_decoder.h"
27 #include "imagemagick_content.h"
28 #include "sndfile_decoder.h"
29 #include "sndfile_content.h"
30 #include "playlist.h"
31 #include "job.h"
32 #include "image.h"
33
34 using std::list;
35 using std::cout;
36 using std::min;
37 using std::vector;
38 using boost::shared_ptr;
39 using boost::weak_ptr;
40 using boost::dynamic_pointer_cast;
41
42 Player::Player (shared_ptr<const Film> f, shared_ptr<const Playlist> p)
43         : _film (f)
44         , _playlist (p)
45         , _video (true)
46         , _audio (true)
47         , _subtitles (true)
48         , _have_valid_decoders (false)
49         , _position (0)
50         , _audio_buffers (MAX_AUDIO_CHANNELS, 0)
51         , _last_video (0)
52         , _last_was_black (false)
53         , _last_audio (0)
54 {
55         _playlist->Changed.connect (bind (&Player::playlist_changed, this));
56         _playlist->ContentChanged.connect (bind (&Player::content_changed, this, _1, _2));
57 }
58
59 void
60 Player::disable_video ()
61 {
62         _video = false;
63 }
64
65 void
66 Player::disable_audio ()
67 {
68         _audio = false;
69 }
70
71 void
72 Player::disable_subtitles ()
73 {
74         _subtitles = false;
75 }
76
77 bool
78 Player::pass ()
79 {
80         if (!_have_valid_decoders) {
81                 setup_decoders ();
82                 _have_valid_decoders = true;
83         }
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                 return true;
118         }
119
120         return false;
121 }
122
123 void
124 Player::process_video (shared_ptr<RegionDecoder> rd, shared_ptr<const Image> image, bool same, shared_ptr<Subtitle> sub, Time time)
125 {
126         shared_ptr<VideoDecoder> vd = dynamic_pointer_cast<VideoDecoder> (rd->decoder);
127         
128         Time const global_time = rd->region->time + time;
129         while ((global_time - _last_video) > 1) {
130                 /* Fill in with black */
131                 emit_black_frame ();
132         }
133
134         Video (image, same, sub, global_time);
135         rd->last = time;
136         _last_video = global_time;
137         _last_was_black = false;
138 }
139
140 void
141 Player::process_audio (shared_ptr<RegionDecoder> rd, shared_ptr<const AudioBuffers> audio, Time time)
142 {
143         /* XXX: mapping */
144
145         /* The time of this audio may indicate that some of our buffered audio is not going to
146            be added to any more, so it can be emitted.
147         */
148
149         if (time > _last_audio) {
150                 /* We can emit some audio from our buffers */
151                 OutputAudioFrame const N = min (_film->time_to_audio_frames (time - _last_audio), static_cast<OutputAudioFrame> (_audio_buffers.frames()));
152                 shared_ptr<AudioBuffers> emit (new AudioBuffers (_audio_buffers.channels(), N));
153                 emit->copy_from (&_audio_buffers, N, 0, 0);
154                 Audio (emit, _last_audio);
155                 _last_audio += _film->audio_frames_to_time (N);
156
157                 /* And remove it from our buffers */
158                 if (_audio_buffers.frames() > N) {
159                         _audio_buffers.move (N, 0, _audio_buffers.frames() - N);
160                 }
161                 _audio_buffers.set_frames (_audio_buffers.frames() - N);
162         }
163
164         /* Now accumulate the new audio into our buffers */
165
166         if (_audio_buffers.frames() == 0) {
167                 /* We have no remaining data.  Emit silence up to the start of this new data */
168                 if ((time - _last_audio) > 0) {
169                         emit_silence (time - _last_audio);
170                 }
171         }
172
173         _audio_buffers.ensure_size (time - _last_audio + audio->frames());
174         _audio_buffers.accumulate (audio.get(), 0, _film->time_to_audio_frames (time - _last_audio));
175         rd->last = time + _film->audio_frames_to_time (audio->frames ());
176 }
177
178 /** @return true on error */
179 bool
180 Player::seek (Time t)
181 {
182         if (!_have_valid_decoders) {
183                 setup_decoders ();
184                 _have_valid_decoders = true;
185         }
186
187         if (_decoders.empty ()) {
188                 return true;
189         }
190
191         /* XXX */
192
193         /* XXX: don't seek audio because we don't need to... */
194
195         return false;
196 }
197
198
199 void
200 Player::seek_back ()
201 {
202         /* XXX */
203 }
204
205 void
206 Player::seek_forward ()
207 {
208         /* XXX */
209 }
210
211
212 void
213 Player::setup_decoders ()
214 {
215         list<shared_ptr<RegionDecoder> > old_decoders = _decoders;
216
217         _decoders.clear ();
218
219         Playlist::RegionList regions = _playlist->regions ();
220         for (Playlist::RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
221
222                 shared_ptr<RegionDecoder> rd (new RegionDecoder);
223                 rd->region = *i;
224                 
225                 /* XXX: into content? */
226
227                 shared_ptr<const FFmpegContent> fc = dynamic_pointer_cast<const FFmpegContent> ((*i)->content);
228                 if (fc) {
229                         shared_ptr<FFmpegDecoder> fd (new FFmpegDecoder (_film, fc, _video, _audio, _subtitles));
230                         
231                         fd->Video.connect (bind (&Player::process_video, this, rd, _1, _2, _3, _4));
232                         fd->Audio.connect (bind (&Player::process_audio, this, rd, _1, _2));
233
234                         rd->decoder = fd;
235                 }
236                 
237                 shared_ptr<const ImageMagickContent> ic = dynamic_pointer_cast<const ImageMagickContent> ((*i)->content);
238                 if (ic) {
239                         shared_ptr<ImageMagickDecoder> id;
240                         
241                         /* See if we can re-use an old ImageMagickDecoder */
242                         for (list<shared_ptr<RegionDecoder> >::const_iterator i = old_decoders.begin(); i != old_decoders.end(); ++i) {
243                                 shared_ptr<ImageMagickDecoder> imd = dynamic_pointer_cast<ImageMagickDecoder> ((*i)->decoder);
244                                 if (imd && imd->content() == ic) {
245                                         id = imd;
246                                 }
247                         }
248
249                         if (!id) {
250                                 id.reset (new ImageMagickDecoder (_film, ic));
251                                 id->Video.connect (bind (&Player::process_video, this, rd, _1, _2, _3, _4));
252                         }
253
254                         rd->decoder = id;
255                 }
256
257                 shared_ptr<const SndfileContent> sc = dynamic_pointer_cast<const SndfileContent> ((*i)->content);
258                 if (sc) {
259                         shared_ptr<AudioDecoder> sd (new SndfileDecoder (_film, sc));
260                         sd->Audio.connect (bind (&Player::process_audio, this, rd, _1, _2));
261
262                         rd->decoder = sd;
263                 }
264
265                 _decoders.push_back (rd);
266         }
267
268         _position = 0;
269 }
270
271 void
272 Player::content_changed (weak_ptr<Content> w, int p)
273 {
274         shared_ptr<Content> c = w.lock ();
275         if (!c) {
276                 return;
277         }
278
279         if (p == VideoContentProperty::VIDEO_LENGTH) {
280                 _have_valid_decoders = false;
281         }
282 }
283
284 void
285 Player::playlist_changed ()
286 {
287         _have_valid_decoders = false;
288 }
289
290 void
291 Player::emit_black_frame ()
292 {
293         shared_ptr<SimpleImage> image (new SimpleImage (AV_PIX_FMT_RGB24, libdcp::Size (128, 128), true));
294         Video (image, _last_was_black, shared_ptr<Subtitle> (), _last_video);
295         _last_video += _film->video_frames_to_time (1);
296 }
297
298 void
299 Player::emit_silence (Time t)
300 {
301         OutputAudioFrame frames = _film->time_to_audio_frames (t);
302         while (frames) {
303                 /* Do this in half-second chunks so we don't overwhelm anybody */
304                 OutputAudioFrame this_time = min (_film->dcp_audio_frame_rate() / 2, frames);
305                 shared_ptr<AudioBuffers> silence (new AudioBuffers (MAX_AUDIO_CHANNELS, this_time));
306                 silence->make_silent ();
307                 Audio (silence, _last_audio);
308                 _last_audio += _film->audio_frames_to_time (this_time);
309                 frames -= this_time;
310         }
311 }