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