Tests pass.
[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         cout << "Player gets " << dcp_mapped->frames() << " @ " << time << " cf " << _audio_position << "\n";
295
296         if (time > _audio_position) {
297                 /* We can emit some audio from our buffers */
298                 OutputAudioFrame const N = _film->time_to_audio_frames (time - _audio_position);
299                 assert (N <= _audio_buffers.frames());
300                 shared_ptr<AudioBuffers> emit (new AudioBuffers (_audio_buffers.channels(), N));
301                 emit->copy_from (&_audio_buffers, N, 0, 0);
302                 Audio (emit, _audio_position);
303                 _audio_position = piece->audio_position = time + _film->audio_frames_to_time (N);
304
305                 /* And remove it from our buffers */
306                 if (_audio_buffers.frames() > N) {
307                         _audio_buffers.move (N, 0, _audio_buffers.frames() - N);
308                 }
309                 _audio_buffers.set_frames (_audio_buffers.frames() - N);
310         }
311
312         /* Now accumulate the new audio into our buffers */
313         _audio_buffers.ensure_size (_audio_buffers.frames() + audio->frames());
314         _audio_buffers.accumulate_frames (audio.get(), 0, 0, audio->frames ());
315         _audio_buffers.set_frames (_audio_buffers.frames() + audio->frames());
316 }
317
318 void
319 Player::flush ()
320 {
321         if (_audio_buffers.frames() > 0) {
322                 shared_ptr<AudioBuffers> emit (new AudioBuffers (_audio_buffers.channels(), _audio_buffers.frames()));
323                 emit->copy_from (&_audio_buffers, _audio_buffers.frames(), 0, 0);
324                 Audio (emit, _audio_position);
325                 _audio_position += _film->audio_frames_to_time (_audio_buffers.frames ());
326                 _audio_buffers.set_frames (0);
327         }
328
329         while (_video_position < _audio_position) {
330                 emit_black ();
331         }
332
333         while (_audio_position < _video_position) {
334                 emit_silence (_film->time_to_audio_frames (_video_position - _audio_position));
335         }
336         
337 }
338
339 /** @return true on error */
340 void
341 Player::seek (Time t)
342 {
343         if (!_have_valid_pieces) {
344                 setup_pieces ();
345                 _have_valid_pieces = true;
346         }
347
348         if (_pieces.empty ()) {
349                 return;
350         }
351
352         for (list<shared_ptr<Piece> >::iterator i = _pieces.begin(); i != _pieces.end(); ++i) {
353                 shared_ptr<VideoContent> vc = dynamic_pointer_cast<VideoContent> ((*i)->content);
354                 if (!vc) {
355                         continue;
356                 }
357                 
358                 Time s = t - vc->start ();
359                 s = max (static_cast<Time> (0), s);
360                 s = min (vc->length(), s);
361
362                 FrameRateConversion frc (vc->video_frame_rate(), _film->dcp_video_frame_rate());
363                 VideoContent::Frame f = s * _film->dcp_video_frame_rate() / (frc.factor() * TIME_HZ);
364                 dynamic_pointer_cast<VideoDecoder>((*i)->decoder)->seek (f);
365         }
366
367         /* XXX: don't seek audio because we don't need to... */
368 }
369
370
371 void
372 Player::seek_back ()
373 {
374
375 }
376
377 void
378 Player::setup_pieces ()
379 {
380         list<shared_ptr<Piece> > old_pieces = _pieces;
381
382         _pieces.clear ();
383
384         Playlist::ContentList content = _playlist->content ();
385         sort (content.begin(), content.end(), ContentSorter ());
386         
387         for (Playlist::ContentList::iterator i = content.begin(); i != content.end(); ++i) {
388
389                 shared_ptr<Piece> piece (new Piece (*i));
390
391                 /* XXX: into content? */
392
393                 shared_ptr<const FFmpegContent> fc = dynamic_pointer_cast<const FFmpegContent> (*i);
394                 if (fc) {
395                         shared_ptr<FFmpegDecoder> fd (new FFmpegDecoder (_film, fc, _video, _audio));
396                         
397                         fd->Video.connect (bind (&Player::process_video, this, piece, _1, _2, _3));
398                         fd->Audio.connect (bind (&Player::process_audio, this, piece, _1, _2));
399
400                         piece->decoder = fd;
401                 }
402                 
403                 shared_ptr<const ImageMagickContent> ic = dynamic_pointer_cast<const ImageMagickContent> (*i);
404                 if (ic) {
405                         shared_ptr<ImageMagickDecoder> id;
406                         
407                         /* See if we can re-use an old ImageMagickDecoder */
408                         for (list<shared_ptr<Piece> >::const_iterator j = old_pieces.begin(); j != old_pieces.end(); ++j) {
409                                 shared_ptr<ImageMagickDecoder> imd = dynamic_pointer_cast<ImageMagickDecoder> ((*j)->decoder);
410                                 if (imd && imd->content() == ic) {
411                                         id = imd;
412                                 }
413                         }
414
415                         if (!id) {
416                                 id.reset (new ImageMagickDecoder (_film, ic));
417                                 id->Video.connect (bind (&Player::process_video, this, piece, _1, _2, _3));
418                         }
419
420                         piece->decoder = id;
421                 }
422
423                 shared_ptr<const SndfileContent> sc = dynamic_pointer_cast<const SndfileContent> (*i);
424                 if (sc) {
425                         shared_ptr<AudioDecoder> sd (new SndfileDecoder (_film, sc));
426                         sd->Audio.connect (bind (&Player::process_audio, this, piece, _1, _2));
427
428                         piece->decoder = sd;
429                 }
430
431                 _pieces.push_back (piece);
432         }
433
434 #ifdef DEBUG_PLAYER
435         cout << "=== Player setup:\n";
436         for (list<shared_ptr<Piece> >::iterator i = _pieces.begin(); i != _pieces.end(); ++i) {
437                 cout << *(i->get()) << "\n";
438         }
439 #endif  
440 }
441
442 void
443 Player::content_changed (weak_ptr<Content> w, int p)
444 {
445         shared_ptr<Content> c = w.lock ();
446         if (!c) {
447                 return;
448         }
449
450         if (p == ContentProperty::START || p == ContentProperty::LENGTH) {
451                 _have_valid_pieces = false;
452         }
453 }
454
455 void
456 Player::playlist_changed ()
457 {
458         _have_valid_pieces = false;
459 }
460
461 void
462 Player::set_video_container_size (libdcp::Size s)
463 {
464         _video_container_size = s;
465         _black_frame.reset (new SimpleImage (PIX_FMT_RGB24, _video_container_size, true));
466         _black_frame->make_black ();
467 }
468
469 shared_ptr<Resampler>
470 Player::resampler (shared_ptr<AudioContent> c)
471 {
472         map<shared_ptr<AudioContent>, shared_ptr<Resampler> >::iterator i = _resamplers.find (c);
473         if (i != _resamplers.end ()) {
474                 return i->second;
475         }
476         
477         shared_ptr<Resampler> r (new Resampler (c->content_audio_frame_rate(), c->output_audio_frame_rate(), c->audio_channels()));
478         _resamplers[c] = r;
479         return r;
480 }
481
482 void
483 Player::emit_black ()
484 {
485         /* XXX: use same here */
486         Video (_black_frame, false, _video_position);
487         _video_position += _film->video_frames_to_time (1);
488 }
489
490 void
491 Player::emit_silence (OutputAudioFrame most)
492 {
493         OutputAudioFrame N = min (most, _film->dcp_audio_frame_rate() / 2);
494         shared_ptr<AudioBuffers> silence (new AudioBuffers (_film->dcp_audio_channels(), N));
495         silence->make_silent ();
496         Audio (silence, _audio_position);
497         _audio_position += _film->audio_frames_to_time (N);
498 }
499
500         
501