Remove unused RGBPlusAlphaImage; merge Image/SimpleImage.
[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 Image (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         /* Resample */
264         if (content->content_audio_frame_rate() != content->output_audio_frame_rate()) {
265                 shared_ptr<Resampler> r = resampler (content);
266                 audio = r->run (audio);
267         }
268
269         /* Remap channels */
270         shared_ptr<AudioBuffers> dcp_mapped (new AudioBuffers (_film->dcp_audio_channels(), audio->frames()));
271         dcp_mapped->make_silent ();
272         list<pair<int, libdcp::Channel> > map = content->audio_mapping().content_to_dcp ();
273         for (list<pair<int, libdcp::Channel> >::iterator i = map.begin(); i != map.end(); ++i) {
274                 if (i->first < audio->channels() && i->second < dcp_mapped->channels()) {
275                         dcp_mapped->accumulate_channel (audio.get(), i->first, i->second);
276                 }
277         }
278
279         audio = dcp_mapped;
280
281         Time time = content->start() + (frame * TIME_HZ / _film->dcp_audio_frame_rate()) + (content->audio_delay() * TIME_HZ / 1000);
282
283         /* We must cut off anything that comes before the start of all time */
284         if (time < 0) {
285                 int const frames = - time * _film->dcp_audio_frame_rate() / TIME_HZ;
286                 if (frames >= audio->frames ()) {
287                         return;
288                 }
289
290                 shared_ptr<AudioBuffers> trimmed (new AudioBuffers (audio->channels(), audio->frames() - frames));
291                 trimmed->copy_from (audio.get(), audio->frames() - frames, frames, 0);
292
293                 audio = trimmed;
294                 time = 0;
295         }
296
297         /* The time of this audio may indicate that some of our buffered audio is not going to
298            be added to any more, so it can be emitted.
299         */
300
301         if (time > _audio_position) {
302                 /* We can emit some audio from our buffers */
303                 OutputAudioFrame const N = _film->time_to_audio_frames (time - _audio_position);
304                 if (N > _audio_buffers.frames()) {
305                         /* We need some extra silence before whatever is in the buffers */
306                         _audio_buffers.ensure_size (N);
307                         _audio_buffers.move (0, N - _audio_buffers.frames(), _audio_buffers.frames ());
308                         _audio_buffers.make_silent (0, _audio_buffers.frames());
309                         _audio_buffers.set_frames (N);
310                 }
311                         
312                 if (N > _audio_buffers.frames()) {
313                         cout << "N=" << N << ", ab=" << _audio_buffers.frames() << "\n";
314                 }
315                 assert (N <= _audio_buffers.frames());
316                 shared_ptr<AudioBuffers> emit (new AudioBuffers (_audio_buffers.channels(), N));
317                 emit->copy_from (&_audio_buffers, N, 0, 0);
318                 Audio (emit, _audio_position);
319                 _audio_position = piece->audio_position = time + _film->audio_frames_to_time (N);
320
321                 /* And remove it from our buffers */
322                 if (_audio_buffers.frames() > N) {
323                         _audio_buffers.move (N, 0, _audio_buffers.frames() - N);
324                 }
325                 _audio_buffers.set_frames (_audio_buffers.frames() - N);
326         }
327
328         /* Now accumulate the new audio into our buffers */
329         _audio_buffers.ensure_size (_audio_buffers.frames() + audio->frames());
330         _audio_buffers.accumulate_frames (audio.get(), 0, 0, audio->frames ());
331         _audio_buffers.set_frames (_audio_buffers.frames() + audio->frames());
332 }
333
334 void
335 Player::flush ()
336 {
337         if (_audio_buffers.frames() > 0) {
338                 shared_ptr<AudioBuffers> emit (new AudioBuffers (_audio_buffers.channels(), _audio_buffers.frames()));
339                 emit->copy_from (&_audio_buffers, _audio_buffers.frames(), 0, 0);
340                 Audio (emit, _audio_position);
341                 _audio_position += _film->audio_frames_to_time (_audio_buffers.frames ());
342                 _audio_buffers.set_frames (0);
343         }
344
345         while (_video_position < _audio_position) {
346                 emit_black ();
347         }
348
349         while (_audio_position < _video_position) {
350                 emit_silence (_film->time_to_audio_frames (_video_position - _audio_position));
351         }
352         
353 }
354
355 /** @return true on error */
356 void
357 Player::seek (Time t, bool accurate)
358 {
359         if (!_have_valid_pieces) {
360                 setup_pieces ();
361                 _have_valid_pieces = true;
362         }
363
364         if (_pieces.empty ()) {
365                 return;
366         }
367
368         for (list<shared_ptr<Piece> >::iterator i = _pieces.begin(); i != _pieces.end(); ++i) {
369                 shared_ptr<VideoContent> vc = dynamic_pointer_cast<VideoContent> ((*i)->content);
370                 if (!vc) {
371                         continue;
372                 }
373                 
374                 Time s = t - vc->start ();
375                 s = max (static_cast<Time> (0), s);
376                 s = min (vc->length(), s);
377
378                 FrameRateConversion frc (vc->video_frame_rate(), _film->dcp_video_frame_rate());
379                 VideoContent::Frame f = s * vc->video_frame_rate() / (frc.factor() * TIME_HZ);
380                 dynamic_pointer_cast<VideoDecoder>((*i)->decoder)->seek (f, accurate);
381         }
382
383         /* XXX: don't seek audio because we don't need to... */
384 }
385
386 void
387 Player::setup_pieces ()
388 {
389         list<shared_ptr<Piece> > old_pieces = _pieces;
390
391         _pieces.clear ();
392
393         Playlist::ContentList content = _playlist->content ();
394         sort (content.begin(), content.end(), ContentSorter ());
395
396         for (Playlist::ContentList::iterator i = content.begin(); i != content.end(); ++i) {
397
398                 shared_ptr<Piece> piece (new Piece (*i));
399
400                 /* XXX: into content? */
401
402                 shared_ptr<const FFmpegContent> fc = dynamic_pointer_cast<const FFmpegContent> (*i);
403                 if (fc) {
404                         shared_ptr<FFmpegDecoder> fd (new FFmpegDecoder (_film, fc, _video, _audio));
405                         
406                         fd->Video.connect (bind (&Player::process_video, this, piece, _1, _2, _3));
407                         fd->Audio.connect (bind (&Player::process_audio, this, piece, _1, _2));
408                         fd->Subtitle.connect (bind (&Player::process_subtitle, this, piece, _1, _2, _3, _4));
409
410                         piece->decoder = fd;
411                 }
412                 
413                 shared_ptr<const ImageMagickContent> ic = dynamic_pointer_cast<const ImageMagickContent> (*i);
414                 if (ic) {
415                         shared_ptr<ImageMagickDecoder> id;
416                         
417                         /* See if we can re-use an old ImageMagickDecoder */
418                         for (list<shared_ptr<Piece> >::const_iterator j = old_pieces.begin(); j != old_pieces.end(); ++j) {
419                                 shared_ptr<ImageMagickDecoder> imd = dynamic_pointer_cast<ImageMagickDecoder> ((*j)->decoder);
420                                 if (imd && imd->content() == ic) {
421                                         id = imd;
422                                 }
423                         }
424
425                         if (!id) {
426                                 id.reset (new ImageMagickDecoder (_film, ic));
427                                 id->Video.connect (bind (&Player::process_video, this, piece, _1, _2, _3));
428                         }
429
430                         piece->decoder = id;
431                 }
432
433                 shared_ptr<const SndfileContent> sc = dynamic_pointer_cast<const SndfileContent> (*i);
434                 if (sc) {
435                         shared_ptr<AudioDecoder> sd (new SndfileDecoder (_film, sc));
436                         sd->Audio.connect (bind (&Player::process_audio, this, piece, _1, _2));
437
438                         piece->decoder = sd;
439                 }
440
441                 _pieces.push_back (piece);
442         }
443
444 #ifdef DEBUG_PLAYER
445         cout << "=== Player setup:\n";
446         for (list<shared_ptr<Piece> >::iterator i = _pieces.begin(); i != _pieces.end(); ++i) {
447                 cout << *(i->get()) << "\n";
448         }
449 #endif  
450 }
451
452 void
453 Player::content_changed (weak_ptr<Content> w, int p)
454 {
455         shared_ptr<Content> c = w.lock ();
456         if (!c) {
457                 return;
458         }
459
460         if (
461                 p == ContentProperty::START || p == ContentProperty::LENGTH ||
462                 p == VideoContentProperty::VIDEO_CROP || p == VideoContentProperty::VIDEO_RATIO
463                 ) {
464                 
465                 _have_valid_pieces = false;
466                 Changed ();
467
468         } else if (p == SubtitleContentProperty::SUBTITLE_OFFSET || p == SubtitleContentProperty::SUBTITLE_SCALE) {
469                 update_subtitle ();
470                 Changed ();
471         }
472 }
473
474 void
475 Player::playlist_changed ()
476 {
477         _have_valid_pieces = false;
478         Changed ();
479 }
480
481 void
482 Player::set_video_container_size (libdcp::Size s)
483 {
484         _video_container_size = s;
485         _black_frame.reset (new Image (PIX_FMT_RGB24, _video_container_size, true));
486         _black_frame->make_black ();
487 }
488
489 shared_ptr<Resampler>
490 Player::resampler (shared_ptr<AudioContent> c)
491 {
492         map<shared_ptr<AudioContent>, shared_ptr<Resampler> >::iterator i = _resamplers.find (c);
493         if (i != _resamplers.end ()) {
494                 return i->second;
495         }
496         
497         shared_ptr<Resampler> r (new Resampler (c->content_audio_frame_rate(), c->output_audio_frame_rate(), c->audio_channels()));
498         _resamplers[c] = r;
499         return r;
500 }
501
502 void
503 Player::emit_black ()
504 {
505         /* XXX: use same here */
506         Video (_black_frame, false, _video_position);
507         _video_position += _film->video_frames_to_time (1);
508 }
509
510 void
511 Player::emit_silence (OutputAudioFrame most)
512 {
513         OutputAudioFrame N = min (most, _film->dcp_audio_frame_rate() / 2);
514         shared_ptr<AudioBuffers> silence (new AudioBuffers (_film->dcp_audio_channels(), N));
515         silence->make_silent ();
516         Audio (silence, _audio_position);
517         _audio_position += _film->audio_frames_to_time (N);
518 }
519
520 void
521 Player::film_changed (Film::Property p)
522 {
523         /* Here we should notice Film properties that affect our output, and
524            alert listeners that our output now would be different to how it was
525            last time we were run.
526         */
527
528         if (p == Film::SCALER || p == Film::WITH_SUBTITLES || p == Film::CONTAINER) {
529                 Changed ();
530         }
531 }
532
533 void
534 Player::process_subtitle (weak_ptr<Piece> weak_piece, shared_ptr<Image> image, dcpomatic::Rect<double> rect, Time from, Time to)
535 {
536         _in_subtitle.piece = weak_piece;
537         _in_subtitle.image = image;
538         _in_subtitle.rect = rect;
539         _in_subtitle.from = from;
540         _in_subtitle.to = to;
541
542         update_subtitle ();
543 }
544
545 void
546 Player::update_subtitle ()
547 {
548         shared_ptr<Piece> piece = _in_subtitle.piece.lock ();
549         if (!piece) {
550                 return;
551         }
552
553         if (!_in_subtitle.image) {
554                 _out_subtitle.image.reset ();
555                 return;
556         }
557
558         shared_ptr<SubtitleContent> sc = dynamic_pointer_cast<SubtitleContent> (piece->content);
559         assert (sc);
560
561         dcpomatic::Rect<double> in_rect = _in_subtitle.rect;
562         libdcp::Size scaled_size;
563
564         in_rect.y += sc->subtitle_offset ();
565
566         /* We will scale the subtitle up to fit _video_container_size, and also by the additional subtitle_scale */
567         scaled_size.width = in_rect.width * _video_container_size.width * sc->subtitle_scale ();
568         scaled_size.height = in_rect.height * _video_container_size.height * sc->subtitle_scale ();
569
570         /* Then we need a corrective translation, consisting of two parts:
571          *
572          * 1.  that which is the result of the scaling of the subtitle by _video_container_size; this will be
573          *     rect.x * _video_container_size.width and rect.y * _video_container_size.height.
574          *
575          * 2.  that to shift the origin of the scale by subtitle_scale to the centre of the subtitle; this will be
576          *     (width_before_subtitle_scale * (1 - subtitle_scale) / 2) and
577          *     (height_before_subtitle_scale * (1 - subtitle_scale) / 2).
578          *
579          * Combining these two translations gives these expressions.
580          */
581         
582         _out_subtitle.position.x = rint (_video_container_size.width * (in_rect.x + (in_rect.width * (1 - sc->subtitle_scale ()) / 2)));
583         _out_subtitle.position.y = rint (_video_container_size.height * (in_rect.y + (in_rect.height * (1 - sc->subtitle_scale ()) / 2)));
584         
585         _out_subtitle.image = _in_subtitle.image->scale (libdcp::Size (scaled_size.width, scaled_size.height), Scaler::from_id ("bicubic"), true);
586         _out_subtitle.from = _in_subtitle.from + piece->content->start ();
587         _out_subtitle.to = _in_subtitle.to + piece->content->start ();
588 }