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