Another try at sorting out the thorny question of timing.
[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 <stdint.h>
21 #include "player.h"
22 #include "film.h"
23 #include "ffmpeg_decoder.h"
24 #include "ffmpeg_content.h"
25 #include "imagemagick_decoder.h"
26 #include "imagemagick_content.h"
27 #include "sndfile_decoder.h"
28 #include "sndfile_content.h"
29 #include "playlist.h"
30 #include "job.h"
31 #include "image.h"
32 #include "ratio.h"
33 #include "resampler.h"
34
35 using std::list;
36 using std::cout;
37 using std::min;
38 using std::max;
39 using std::vector;
40 using std::pair;
41 using std::map;
42 using boost::shared_ptr;
43 using boost::weak_ptr;
44 using boost::dynamic_pointer_cast;
45
46 #define DEBUG_PLAYER 1
47
48 class Piece
49 {
50 public:
51         Piece (shared_ptr<Content> c)
52                 : content (c)
53                 , video_position (c->start ())
54                 , audio_position (c->start ())
55         {}
56         
57         Piece (shared_ptr<Content> c, shared_ptr<Decoder> d)
58                 : content (c)
59                 , decoder (d)
60                 , video_position (c->start ())
61                 , audio_position (c->start ())
62         {}
63         
64         shared_ptr<Content> content;
65         shared_ptr<Decoder> decoder;
66         Time video_position;
67         Time audio_position;
68 };
69
70 #ifdef DEBUG_PLAYER
71 std::ostream& operator<<(std::ostream& s, Piece const & p)
72 {
73         if (dynamic_pointer_cast<FFmpegContent> (p.content)) {
74                 s << "\tffmpeg     ";
75         } else if (dynamic_pointer_cast<ImageMagickContent> (p.content)) {
76                 s << "\timagemagick";
77         } else if (dynamic_pointer_cast<SndfileContent> (p.content)) {
78                 s << "\tsndfile    ";
79         }
80         
81         s << " at " << p.content->start() << " until " << p.content->end();
82         
83         return s;
84 }
85 #endif  
86
87 Player::Player (shared_ptr<const Film> f, shared_ptr<const Playlist> p)
88         : _film (f)
89         , _playlist (p)
90         , _video (true)
91         , _audio (true)
92         , _have_valid_pieces (false)
93         , _video_position (0)
94         , _audio_position (0)
95         , _audio_buffers (f->dcp_audio_channels(), 0)
96 {
97         _playlist->Changed.connect (bind (&Player::playlist_changed, this));
98         _playlist->ContentChanged.connect (bind (&Player::content_changed, this, _1, _2));
99         set_video_container_size (_film->container()->size (_film->full_frame ()));
100 }
101
102 void
103 Player::disable_video ()
104 {
105         _video = false;
106 }
107
108 void
109 Player::disable_audio ()
110 {
111         _audio = false;
112 }
113
114 bool
115 Player::pass ()
116 {
117         if (!_have_valid_pieces) {
118                 setup_pieces ();
119                 _have_valid_pieces = true;
120         }
121
122 #ifdef DEBUG_PLAYER
123         cout << "= PASS\n";
124 #endif  
125
126         Time earliest_t = TIME_MAX;
127         shared_ptr<Piece> earliest;
128         enum {
129                 VIDEO,
130                 AUDIO
131         } type = VIDEO;
132
133         for (list<shared_ptr<Piece> >::iterator i = _pieces.begin(); i != _pieces.end(); ++i) {
134                 if ((*i)->decoder->done ()) {
135                         continue;
136                 }
137
138                 if (dynamic_pointer_cast<VideoDecoder> ((*i)->decoder)) {
139                         if ((*i)->video_position < earliest_t) {
140                                 earliest_t = (*i)->video_position;
141                                 earliest = *i;
142                                 type = VIDEO;
143                         }
144                 }
145
146                 if (dynamic_pointer_cast<AudioDecoder> ((*i)->decoder)) {
147                         if ((*i)->audio_position < earliest_t) {
148                                 earliest_t = (*i)->audio_position;
149                                 earliest = *i;
150                                 type = AUDIO;
151                         }
152                 }
153         }
154
155         if (!earliest) {
156 #ifdef DEBUG_PLAYER
157                 cout << "no earliest piece.\n";
158 #endif          
159                 
160                 flush ();
161                 return true;
162         }
163
164         switch (type) {
165         case VIDEO:
166                 if (earliest_t > _video_position) {
167 #ifdef DEBUG_PLAYER
168                         cout << "no video here; emitting black frame.\n";
169 #endif
170                         emit_black ();
171                 } else {
172 #ifdef DEBUG_PLAYER
173                         cout << "Pass " << *earliest << "\n";
174 #endif                  
175                         earliest->decoder->pass ();
176                 }
177                 break;
178
179         case AUDIO:
180                 if (earliest_t > _audio_position) {
181 #ifdef DEBUG_PLAYER
182                         cout << "no audio here; emitting silence.\n";
183 #endif
184                         emit_silence (_film->time_to_audio_frames (earliest_t - _audio_position));
185                 } else {
186 #ifdef DEBUG_PLAYER
187                         cout << "Pass " << *earliest << "\n";
188 #endif                  
189                         earliest->decoder->pass ();
190                 }
191                 break;
192         }
193
194 #ifdef DEBUG_PLAYER
195         cout << "\tpost pass " << _video_position << " " << _audio_position << "\n";
196 #endif  
197
198         return false;
199 }
200
201 void
202 Player::process_video (weak_ptr<Piece> weak_piece, shared_ptr<const Image> image, bool same, VideoContent::Frame frame)
203 {
204         shared_ptr<Piece> piece = weak_piece.lock ();
205         if (!piece) {
206                 return;
207         }
208
209         shared_ptr<VideoContent> content = dynamic_pointer_cast<VideoContent> (piece->content);
210         assert (content);
211
212         FrameRateConversion frc (content->video_frame_rate(), _film->dcp_video_frame_rate());
213         if (frc.skip && (frame % 2) == 1) {
214                 return;
215         }
216
217         image = image->crop (content->crop(), true);
218
219         libdcp::Size const image_size = content->ratio()->size (_video_container_size);
220         
221         image = image->scale_and_convert_to_rgb (image_size, _film->scaler(), true);
222
223 #if 0   
224         if (film->with_subtitles ()) {
225                 shared_ptr<Subtitle> sub;
226                 if (_timed_subtitle && _timed_subtitle->displayed_at (t)) {
227                         sub = _timed_subtitle->subtitle ();
228                 }
229                 
230                 if (sub) {
231                         dcpomatic::Rect const tx = subtitle_transformed_area (
232                                 float (image_size.width) / content->video_size().width,
233                                 float (image_size.height) / content->video_size().height,
234                                 sub->area(), film->subtitle_offset(), film->subtitle_scale()
235                                 );
236                         
237                         shared_ptr<Image> im = sub->image()->scale (tx.size(), film->scaler(), true);
238                         image->alpha_blend (im, tx.position());
239                 }
240         }
241 #endif  
242
243         if (image_size != _video_container_size) {
244                 assert (image_size.width <= _video_container_size.width);
245                 assert (image_size.height <= _video_container_size.height);
246                 shared_ptr<Image> im (new SimpleImage (PIX_FMT_RGB24, _video_container_size, true));
247                 im->make_black ();
248                 im->copy (image, Position ((_video_container_size.width - image_size.width) / 2, (_video_container_size.height - image_size.height) / 2));
249                 image = im;
250         }
251
252         Time time = content->start() + (frame * frc.factor() * TIME_HZ / _film->dcp_video_frame_rate());
253         
254         Video (image, same, time);
255         time += TIME_HZ / _film->dcp_video_frame_rate();
256
257         if (frc.repeat) {
258                 Video (image, true, time);
259                 time += TIME_HZ / _film->dcp_video_frame_rate();
260         }
261
262         _video_position = piece->video_position = time;
263 }
264
265 void
266 Player::process_audio (weak_ptr<Piece> weak_piece, shared_ptr<const AudioBuffers> audio, AudioContent::Frame frame)
267 {
268         shared_ptr<Piece> piece = weak_piece.lock ();
269         if (!piece) {
270                 return;
271         }
272
273         shared_ptr<AudioContent> content = dynamic_pointer_cast<AudioContent> (piece->content);
274         assert (content);
275
276         if (content->content_audio_frame_rate() != content->output_audio_frame_rate()) {
277                 audio = resampler(content)->run (audio);
278         }
279
280         /* Remap channels */
281         shared_ptr<AudioBuffers> dcp_mapped (new AudioBuffers (_film->dcp_audio_channels(), audio->frames()));
282         dcp_mapped->make_silent ();
283         list<pair<int, libdcp::Channel> > map = content->audio_mapping().content_to_dcp ();
284         for (list<pair<int, libdcp::Channel> >::iterator i = map.begin(); i != map.end(); ++i) {
285                 dcp_mapped->accumulate_channel (audio.get(), i->first, i->second);
286         }
287
288         /* The time of this audio may indicate that some of our buffered audio is not going to
289            be added to any more, so it can be emitted.
290         */
291
292         Time const time = content->start() + (frame * TIME_HZ / _film->dcp_audio_frame_rate());
293
294         if (time > _audio_position) {
295                 /* We can emit some audio from our buffers */
296                 OutputAudioFrame const N = _film->time_to_audio_frames (time - _audio_position);
297                 assert (N <= _audio_buffers.frames());
298                 shared_ptr<AudioBuffers> emit (new AudioBuffers (_audio_buffers.channels(), N));
299                 emit->copy_from (&_audio_buffers, N, 0, 0);
300                 Audio (emit, _audio_position);
301                 _audio_position = piece->audio_position = time + _film->audio_frames_to_time (N);
302
303                 /* And remove it from our buffers */
304                 if (_audio_buffers.frames() > N) {
305                         _audio_buffers.move (N, 0, _audio_buffers.frames() - N);
306                 }
307                 _audio_buffers.set_frames (_audio_buffers.frames() - N);
308         }
309
310         /* Now accumulate the new audio into our buffers */
311         _audio_buffers.ensure_size (_audio_buffers.frames() + audio->frames());
312         _audio_buffers.accumulate_frames (audio.get(), 0, 0, audio->frames ());
313         _audio_buffers.set_frames (_audio_buffers.frames() + audio->frames());
314 }
315
316 void
317 Player::flush ()
318 {
319         if (_audio_buffers.frames() > 0) {
320                 shared_ptr<AudioBuffers> emit (new AudioBuffers (_audio_buffers.channels(), _audio_buffers.frames()));
321                 emit->copy_from (&_audio_buffers, _audio_buffers.frames(), 0, 0);
322                 Audio (emit, _audio_position);
323                 _audio_position += _film->audio_frames_to_time (_audio_buffers.frames ());
324                 _audio_buffers.set_frames (0);
325         }
326
327         while (_video_position < _audio_position) {
328                 emit_black ();
329         }
330
331         while (_audio_position < _video_position) {
332                 emit_silence (_film->time_to_audio_frames (_video_position - _audio_position));
333         }
334         
335 }
336
337 /** @return true on error */
338 void
339 Player::seek (Time t)
340 {
341         if (!_have_valid_pieces) {
342                 setup_pieces ();
343                 _have_valid_pieces = true;
344         }
345
346         if (_pieces.empty ()) {
347                 return;
348         }
349
350         for (list<shared_ptr<Piece> >::iterator i = _pieces.begin(); i != _pieces.end(); ++i) {
351                 shared_ptr<VideoContent> vc = dynamic_pointer_cast<VideoContent> ((*i)->content);
352                 if (!vc) {
353                         continue;
354                 }
355                 
356                 Time s = t - vc->start ();
357                 s = max (static_cast<Time> (0), s);
358                 s = min (vc->length(), s);
359
360                 FrameRateConversion frc (vc->video_frame_rate(), _film->dcp_video_frame_rate());
361                 VideoContent::Frame f = s * _film->dcp_video_frame_rate() / (frc.factor() * TIME_HZ);
362                 dynamic_pointer_cast<VideoDecoder>((*i)->decoder)->seek (f);
363         }
364
365         /* XXX: don't seek audio because we don't need to... */
366 }
367
368
369 void
370 Player::seek_back ()
371 {
372
373 }
374
375 void
376 Player::setup_pieces ()
377 {
378         list<shared_ptr<Piece> > old_pieces = _pieces;
379
380         _pieces.clear ();
381
382         Playlist::ContentList content = _playlist->content ();
383         sort (content.begin(), content.end(), ContentSorter ());
384         
385         for (Playlist::ContentList::iterator i = content.begin(); i != content.end(); ++i) {
386
387                 shared_ptr<Piece> piece (new Piece (*i));
388
389                 /* XXX: into content? */
390
391                 shared_ptr<const FFmpegContent> fc = dynamic_pointer_cast<const FFmpegContent> (*i);
392                 if (fc) {
393                         shared_ptr<FFmpegDecoder> fd (new FFmpegDecoder (_film, fc, _video, _audio));
394                         
395                         fd->Video.connect (bind (&Player::process_video, this, piece, _1, _2, _3));
396                         fd->Audio.connect (bind (&Player::process_audio, this, piece, _1, _2));
397
398                         piece->decoder = fd;
399                 }
400                 
401                 shared_ptr<const ImageMagickContent> ic = dynamic_pointer_cast<const ImageMagickContent> (*i);
402                 if (ic) {
403                         shared_ptr<ImageMagickDecoder> id;
404                         
405                         /* See if we can re-use an old ImageMagickDecoder */
406                         for (list<shared_ptr<Piece> >::const_iterator j = old_pieces.begin(); j != old_pieces.end(); ++j) {
407                                 shared_ptr<ImageMagickDecoder> imd = dynamic_pointer_cast<ImageMagickDecoder> ((*j)->decoder);
408                                 if (imd && imd->content() == ic) {
409                                         id = imd;
410                                 }
411                         }
412
413                         if (!id) {
414                                 id.reset (new ImageMagickDecoder (_film, ic));
415                                 id->Video.connect (bind (&Player::process_video, this, piece, _1, _2, _3));
416                         }
417
418                         piece->decoder = id;
419                 }
420
421                 shared_ptr<const SndfileContent> sc = dynamic_pointer_cast<const SndfileContent> (*i);
422                 if (sc) {
423                         shared_ptr<AudioDecoder> sd (new SndfileDecoder (_film, sc));
424                         sd->Audio.connect (bind (&Player::process_audio, this, piece, _1, _2));
425
426                         piece->decoder = sd;
427                 }
428
429                 _pieces.push_back (piece);
430         }
431
432 #ifdef DEBUG_PLAYER
433         cout << "=== Player setup:\n";
434         for (list<shared_ptr<Piece> >::iterator i = _pieces.begin(); i != _pieces.end(); ++i) {
435                 cout << *(i->get()) << "\n";
436         }
437 #endif  
438 }
439
440 void
441 Player::content_changed (weak_ptr<Content> w, int p)
442 {
443         shared_ptr<Content> c = w.lock ();
444         if (!c) {
445                 return;
446         }
447
448         if (p == ContentProperty::START || p == ContentProperty::LENGTH) {
449                 _have_valid_pieces = false;
450         }
451 }
452
453 void
454 Player::playlist_changed ()
455 {
456         _have_valid_pieces = false;
457 }
458
459 void
460 Player::set_video_container_size (libdcp::Size s)
461 {
462         _video_container_size = s;
463         _black_frame.reset (new SimpleImage (PIX_FMT_RGB24, _video_container_size, true));
464         _black_frame->make_black ();
465 }
466
467 shared_ptr<Resampler>
468 Player::resampler (shared_ptr<AudioContent> c)
469 {
470         map<shared_ptr<AudioContent>, shared_ptr<Resampler> >::iterator i = _resamplers.find (c);
471         if (i != _resamplers.end ()) {
472                 return i->second;
473         }
474         
475         shared_ptr<Resampler> r (new Resampler (c->content_audio_frame_rate(), c->output_audio_frame_rate(), c->audio_channels()));
476         _resamplers[c] = r;
477         return r;
478 }
479
480 void
481 Player::emit_black ()
482 {
483         /* XXX: use same here */
484         Video (_black_frame, false, _video_position);
485         _video_position += _film->video_frames_to_time (1);
486 }
487
488 void
489 Player::emit_silence (OutputAudioFrame most)
490 {
491         OutputAudioFrame N = min (most, _film->dcp_audio_frame_rate() / 2);
492         shared_ptr<AudioBuffers> silence (new AudioBuffers (_film->dcp_audio_channels(), N));
493         silence->make_silent ();
494         Audio (silence, _audio_position);
495         _audio_position += _film->audio_frames_to_time (N);
496 }
497
498         
499