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