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