wip: Error when failing to read MXF frame.
[dcpomatic.git] / src / lib / player.cc
1 /*
2     Copyright (C) 2013-2021 Carl Hetherington <cth@carlh.net>
3
4     This file is part of DCP-o-matic.
5
6     DCP-o-matic is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     DCP-o-matic is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with DCP-o-matic.  If not, see <http://www.gnu.org/licenses/>.
18
19 */
20
21
22 #include "atmos_decoder.h"
23 #include "audio_buffers.h"
24 #include "audio_content.h"
25 #include "audio_decoder.h"
26 #include "audio_processor.h"
27 #include "compose.hpp"
28 #include "config.h"
29 #include "content_audio.h"
30 #include "content_video.h"
31 #include "dcp_content.h"
32 #include "dcp_decoder.h"
33 #include "dcpomatic_log.h"
34 #include "decoder.h"
35 #include "decoder_factory.h"
36 #include "ffmpeg_content.h"
37 #include "film.h"
38 #include "frame_rate_change.h"
39 #include "image.h"
40 #include "image_decoder.h"
41 #include "job.h"
42 #include "log.h"
43 #include "maths_util.h"
44 #include "piece.h"
45 #include "player.h"
46 #include "player_video.h"
47 #include "playlist.h"
48 #include "ratio.h"
49 #include "raw_image_proxy.h"
50 #include "render_text.h"
51 #include "shuffler.h"
52 #include "text_content.h"
53 #include "text_decoder.h"
54 #include "timer.h"
55 #include "video_decoder.h"
56 #include <dcp/reel.h>
57 #include <dcp/reel_closed_caption_asset.h>
58 #include <dcp/reel_picture_asset.h>
59 #include <dcp/reel_sound_asset.h>
60 #include <dcp/reel_subtitle_asset.h>
61 #include <algorithm>
62 #include <iostream>
63 #include <stdint.h>
64
65 #include "i18n.h"
66
67
68 using std::copy;
69 using std::cout;
70 using std::dynamic_pointer_cast;
71 using std::list;
72 using std::make_pair;
73 using std::make_shared;
74 using std::make_shared;
75 using std::max;
76 using std::min;
77 using std::min;
78 using std::pair;
79 using std::shared_ptr;
80 using std::vector;
81 using std::weak_ptr;
82 using boost::optional;
83 using boost::scoped_ptr;
84 #if BOOST_VERSION >= 106100
85 using namespace boost::placeholders;
86 #endif
87 using namespace dcpomatic;
88
89
90 int const PlayerProperty::VIDEO_CONTAINER_SIZE = 700;
91 int const PlayerProperty::PLAYLIST = 701;
92 int const PlayerProperty::FILM_CONTAINER = 702;
93 int const PlayerProperty::FILM_VIDEO_FRAME_RATE = 703;
94 int const PlayerProperty::DCP_DECODE_REDUCTION = 704;
95 int const PlayerProperty::PLAYBACK_LENGTH = 705;
96 int const PlayerProperty::IGNORE_VIDEO = 706;
97 int const PlayerProperty::IGNORE_AUDIO = 707;
98 int const PlayerProperty::IGNORE_TEXT = 708;
99 int const PlayerProperty::ALWAYS_BURN_OPEN_SUBTITLES = 709;
100 int const PlayerProperty::PLAY_REFERENCED = 710;
101
102
103 Player::Player (shared_ptr<const Film> film, Image::Alignment subtitle_alignment)
104         : _film (film)
105         , _suspended (0)
106         , _ignore_video(false)
107         , _ignore_audio(false)
108         , _ignore_text(false)
109         , _always_burn_open_subtitles(false)
110         , _fast(false)
111         , _tolerant (film->tolerant())
112         , _play_referenced(false)
113         , _audio_merger(film->audio_frame_rate())
114         , _subtitle_alignment (subtitle_alignment)
115 {
116         construct ();
117 }
118
119
120 Player::Player (shared_ptr<const Film> film, shared_ptr<const Playlist> playlist_)
121         : _film (film)
122         , _playlist (playlist_)
123         , _suspended (0)
124         , _ignore_video(false)
125         , _ignore_audio(false)
126         , _ignore_text(false)
127         , _always_burn_open_subtitles(false)
128         , _fast(false)
129         , _tolerant (film->tolerant())
130         , _play_referenced(false)
131         , _audio_merger(film->audio_frame_rate())
132 {
133         construct ();
134 }
135
136
137 void
138 Player::construct ()
139 {
140         auto film = _film.lock();
141         DCPOMATIC_ASSERT(film);
142
143         connect();
144         set_video_container_size(film->frame_size());
145
146         film_change (ChangeType::DONE, Film::Property::AUDIO_PROCESSOR);
147
148         setup_pieces ();
149         seek (DCPTime (), true);
150 }
151
152
153 void
154 Player::connect()
155 {
156         auto film = _film.lock();
157         DCPOMATIC_ASSERT(film);
158
159         _film_changed_connection = film->Change.connect(bind(&Player::film_change, this, _1, _2));
160         /* The butler must hear about this first, so since we are proxying this through to the butler we must
161            be first.
162         */
163         _playlist_change_connection = playlist()->Change.connect (bind (&Player::playlist_change, this, _1), boost::signals2::at_front);
164         _playlist_content_change_connection = playlist()->ContentChange.connect (bind(&Player::playlist_content_change, this, _1, _3, _4));
165 }
166
167
168 Player::Player(Player&& other)
169         : _film(other._film)
170         , _playlist(std::move(other._playlist))
171         , _suspended(other._suspended.load())
172         , _pieces(std::move(other._pieces))
173         , _video_container_size(other._video_container_size.load())
174         , _black_image(std::move(other._black_image))
175         , _ignore_video(other._ignore_video.load())
176         , _ignore_audio(other._ignore_audio.load())
177         , _ignore_text(other._ignore_text.load())
178         , _always_burn_open_subtitles(other._always_burn_open_subtitles.load())
179         , _fast(other._fast.load())
180         , _tolerant(other._tolerant)
181         , _play_referenced(other._play_referenced.load())
182         , _next_video_time(other._next_video_time)
183         , _next_audio_time(other._next_audio_time)
184         , _dcp_decode_reduction(other._dcp_decode_reduction.load())
185         , _last_video(std::move(other._last_video))
186         , _audio_merger(std::move(other._audio_merger))
187         , _shuffler(std::move(other._shuffler))
188         , _delay(std::move(other._delay))
189         , _stream_states(std::move(other._stream_states))
190         , _black(std::move(other._black))
191         , _silent(std::move(other._silent))
192         , _active_texts(std::move(other._active_texts))
193         , _audio_processor(std::move(other._audio_processor))
194         , _playback_length(other._playback_length.load())
195         , _subtitle_alignment(other._subtitle_alignment)
196 {
197         connect();
198 }
199
200
201 Player&
202 Player::operator=(Player&& other)
203 {
204         if (this == &other) {
205                 return *this;
206         }
207
208         _film = std::move(other._film);
209         _playlist = std::move(other._playlist);
210         _suspended = other._suspended.load();
211         _pieces = std::move(other._pieces);
212         _video_container_size = other._video_container_size.load();
213         _black_image = std::move(other._black_image);
214         _ignore_video = other._ignore_video.load();
215         _ignore_audio = other._ignore_audio.load();
216         _ignore_text = other._ignore_text.load();
217         _always_burn_open_subtitles = other._always_burn_open_subtitles.load();
218         _fast = other._fast.load();
219         _tolerant = other._tolerant;
220         _play_referenced = other._play_referenced.load();
221         _next_video_time = other._next_video_time;
222         _next_audio_time = other._next_audio_time;
223         _dcp_decode_reduction = other._dcp_decode_reduction.load();
224         _last_video = std::move(other._last_video);
225         _audio_merger = std::move(other._audio_merger);
226         _shuffler = std::move(other._shuffler);
227         _delay = std::move(other._delay);
228         _stream_states = std::move(other._stream_states);
229         _black = std::move(other._black);
230         _silent = std::move(other._silent);
231         _active_texts = std::move(other._active_texts);
232         _audio_processor = std::move(other._audio_processor);
233         _playback_length = other._playback_length.load();
234         _subtitle_alignment = other._subtitle_alignment;
235
236         connect();
237
238         return *this;
239 }
240
241
242 bool
243 have_video (shared_ptr<const Content> content)
244 {
245         return static_cast<bool>(content->video) && content->video->use() && content->can_be_played();
246 }
247
248
249 bool
250 have_audio (shared_ptr<const Content> content)
251 {
252         return static_cast<bool>(content->audio) && content->can_be_played();
253 }
254
255
256 void
257 Player::setup_pieces ()
258 {
259         boost::mutex::scoped_lock lm (_mutex);
260
261         auto old_pieces = _pieces;
262         _pieces.clear ();
263
264         auto film = _film.lock();
265         if (!film) {
266                 return;
267         }
268
269         _playback_length = _playlist ? _playlist->length(film) : film->length();
270
271         auto playlist_content = playlist()->content();
272         bool const have_threed = std::any_of(
273                 playlist_content.begin(),
274                 playlist_content.end(),
275                 [](shared_ptr<const Content> c) {
276                         return c->video && (c->video->frame_type() == VideoFrameType::THREE_D_LEFT || c->video->frame_type() == VideoFrameType::THREE_D_RIGHT);
277                 });
278
279
280         if (have_threed) {
281                 _shuffler.reset(new Shuffler());
282                 _shuffler->Video.connect(bind(&Player::video, this, _1, _2));
283         }
284
285         for (auto content: playlist()->content()) {
286
287                 if (!content->paths_valid()) {
288                         continue;
289                 }
290
291                 if (_ignore_video && _ignore_audio && content->text.empty()) {
292                         /* We're only interested in text and this content has none */
293                         continue;
294                 }
295
296                 shared_ptr<Decoder> old_decoder;
297                 for (auto j: old_pieces) {
298                         if (j->content == content) {
299                                 old_decoder = j->decoder;
300                                 break;
301                         }
302                 }
303
304                 auto decoder = decoder_factory(film, content, _fast, _tolerant, old_decoder);
305                 DCPOMATIC_ASSERT (decoder);
306
307                 FrameRateChange frc(film, content);
308
309                 if (decoder->video && _ignore_video) {
310                         decoder->video->set_ignore (true);
311                 }
312
313                 if (decoder->audio && _ignore_audio) {
314                         decoder->audio->set_ignore (true);
315                 }
316
317                 if (_ignore_text) {
318                         for (auto i: decoder->text) {
319                                 i->set_ignore (true);
320                         }
321                 }
322
323                 auto dcp = dynamic_pointer_cast<DCPDecoder> (decoder);
324                 if (dcp) {
325                         dcp->set_decode_referenced (_play_referenced);
326                         if (_play_referenced) {
327                                 dcp->set_forced_reduction (_dcp_decode_reduction);
328                         }
329                 }
330
331                 auto piece = make_shared<Piece>(content, decoder, frc);
332                 _pieces.push_back (piece);
333
334                 if (decoder->video) {
335                         if (have_threed) {
336                                 /* We need a Shuffler to cope with 3D L/R video data arriving out of sequence */
337                                 decoder->video->Data.connect (bind(&Shuffler::video, _shuffler.get(), weak_ptr<Piece>(piece), _1));
338                         } else {
339                                 decoder->video->Data.connect (bind(&Player::video, this, weak_ptr<Piece>(piece), _1));
340                         }
341                 }
342
343                 if (decoder->audio) {
344                         decoder->audio->Data.connect (bind (&Player::audio, this, weak_ptr<Piece> (piece), _1, _2));
345                 }
346
347                 auto j = decoder->text.begin();
348
349                 while (j != decoder->text.end()) {
350                         (*j)->BitmapStart.connect (
351                                 bind(&Player::bitmap_text_start, this, weak_ptr<Piece>(piece), weak_ptr<const TextContent>((*j)->content()), _1)
352                                 );
353                         (*j)->PlainStart.connect (
354                                 bind(&Player::plain_text_start, this, weak_ptr<Piece>(piece), weak_ptr<const TextContent>((*j)->content()), _1)
355                                 );
356                         (*j)->Stop.connect (
357                                 bind(&Player::subtitle_stop, this, weak_ptr<Piece>(piece), weak_ptr<const TextContent>((*j)->content()), _1)
358                                 );
359
360                         ++j;
361                 }
362
363                 if (decoder->atmos) {
364                         decoder->atmos->Data.connect (bind(&Player::atmos, this, weak_ptr<Piece>(piece), _1));
365                 }
366         }
367
368         _stream_states.clear ();
369         for (auto i: _pieces) {
370                 if (i->content->audio) {
371                         for (auto j: i->content->audio->streams()) {
372                                 _stream_states[j] = StreamState(i);
373                         }
374                 }
375         }
376
377         auto ignore_overlap = [](shared_ptr<VideoContent> v) {
378                 return v && v->use() && v->frame_type() != VideoFrameType::THREE_D_LEFT && v->frame_type() != VideoFrameType::THREE_D_RIGHT;
379         };
380
381         for (auto piece = _pieces.begin(); piece != _pieces.end(); ++piece) {
382                 if (ignore_overlap((*piece)->content->video)) {
383                         /* Look for content later in the content list with in-use video that overlaps this */
384                         auto const period = (*piece)->content->period(film);
385                         for (auto later_piece = std::next(piece); later_piece != _pieces.end(); ++later_piece) {
386                                 if (ignore_overlap((*later_piece)->content->video)) {
387                                         if (auto overlap = (*later_piece)->content->period(film).overlap(period)) {
388                                                 (*piece)->ignore_video.push_back(*overlap);
389                                         }
390                                 }
391                         }
392                 }
393         }
394
395         for (auto piece = _pieces.begin(); piece != _pieces.end(); ++piece) {
396                 if ((*piece)->content->atmos) {
397                         /* Look for content later in the content list with ATMOS that overlaps this */
398                         auto const period = (*piece)->content->period(film);
399                         for (auto later_piece = std::next(piece); later_piece != _pieces.end(); ++later_piece) {
400                                 if ((*later_piece)->content->atmos) {
401                                         if (auto overlap = (*later_piece)->content->period(film).overlap(period)) {
402                                                 (*piece)->ignore_atmos.push_back(*overlap);
403                                         }
404                                 }
405                         }
406                 }
407         }
408
409         _black = Empty(film, playlist(), bind(&have_video, _1), _playback_length);
410         _silent = Empty(film, playlist(), bind(&have_audio, _1), _playback_length);
411
412         _next_video_time = boost::none;
413         _next_video_eyes = Eyes::BOTH;
414         _next_audio_time = boost::none;
415 }
416
417
418 void
419 Player::playlist_content_change (ChangeType type, int property, bool frequent)
420 {
421         auto film = _film.lock();
422         if (!film) {
423                 return;
424         }
425
426         if (property == VideoContentProperty::CROP) {
427                 if (type == ChangeType::DONE) {
428                         boost::mutex::scoped_lock lm (_mutex);
429                         for (auto const& i: _delay) {
430                                 i.first->reset_metadata(film, _video_container_size);
431                         }
432                 }
433         } else {
434                 if (type == ChangeType::PENDING) {
435                         /* The player content is probably about to change, so we can't carry on
436                            until that has happened and we've rebuilt our pieces.  Stop pass()
437                            and seek() from working until then.
438                         */
439                         ++_suspended;
440                 } else if (type == ChangeType::DONE) {
441                         /* A change in our content has gone through.  Re-build our pieces. */
442                         setup_pieces ();
443                         --_suspended;
444                 } else if (type == ChangeType::CANCELLED) {
445                         --_suspended;
446                 }
447         }
448
449         Change (type, property, frequent);
450 }
451
452
453 void
454 Player::set_video_container_size (dcp::Size s)
455 {
456         ChangeSignaller<Player, int> cc(this, PlayerProperty::VIDEO_CONTAINER_SIZE);
457
458         if (s == _video_container_size) {
459                 cc.abort();
460                 return;
461         }
462
463         _video_container_size = s;
464
465         {
466                 boost::mutex::scoped_lock lm(_black_image_mutex);
467                 _black_image = make_shared<Image>(AV_PIX_FMT_RGB24, _video_container_size, Image::Alignment::PADDED);
468                 _black_image->make_black ();
469         }
470 }
471
472
473 void
474 Player::playlist_change (ChangeType type)
475 {
476         if (type == ChangeType::DONE) {
477                 setup_pieces ();
478         }
479         Change (type, PlayerProperty::PLAYLIST, false);
480 }
481
482
483 void
484 Player::film_change (ChangeType type, Film::Property p)
485 {
486         /* Here we should notice Film properties that affect our output, and
487            alert listeners that our output now would be different to how it was
488            last time we were run.
489         */
490
491         auto film = _film.lock();
492         if (!film) {
493                 return;
494         }
495
496         if (p == Film::Property::CONTAINER) {
497                 Change (type, PlayerProperty::FILM_CONTAINER, false);
498         } else if (p == Film::Property::VIDEO_FRAME_RATE) {
499                 /* Pieces contain a FrameRateChange which contains the DCP frame rate,
500                    so we need new pieces here.
501                 */
502                 if (type == ChangeType::DONE) {
503                         setup_pieces ();
504                 }
505                 Change (type, PlayerProperty::FILM_VIDEO_FRAME_RATE, false);
506         } else if (p == Film::Property::AUDIO_PROCESSOR) {
507                 if (type == ChangeType::DONE && film->audio_processor ()) {
508                         boost::mutex::scoped_lock lm (_mutex);
509                         _audio_processor = film->audio_processor()->clone(film->audio_frame_rate());
510                 }
511         } else if (p == Film::Property::AUDIO_CHANNELS) {
512                 if (type == ChangeType::DONE) {
513                         boost::mutex::scoped_lock lm (_mutex);
514                         _audio_merger.clear ();
515                 }
516         }
517 }
518
519
520 shared_ptr<PlayerVideo>
521 Player::black_player_video_frame (Eyes eyes) const
522 {
523         boost::mutex::scoped_lock lm(_black_image_mutex);
524
525         return std::make_shared<PlayerVideo> (
526                 std::make_shared<const RawImageProxy>(_black_image),
527                 Crop(),
528                 optional<double>(),
529                 _video_container_size,
530                 _video_container_size,
531                 eyes,
532                 Part::WHOLE,
533                 PresetColourConversion::all().front().conversion,
534                 VideoRange::FULL,
535                 std::weak_ptr<Content>(),
536                 boost::optional<Frame>(),
537                 false
538         );
539 }
540
541
542 Frame
543 Player::dcp_to_content_video (shared_ptr<const Piece> piece, DCPTime t) const
544 {
545         auto film = _film.lock();
546         DCPOMATIC_ASSERT(film);
547
548         auto s = t - piece->content->position ();
549         s = min (piece->content->length_after_trim(film), s);
550         s = max (DCPTime(), s + DCPTime (piece->content->trim_start(), piece->frc));
551
552         /* It might seem more logical here to convert s to a ContentTime (using the FrameRateChange)
553            then convert that ContentTime to frames at the content's rate.  However this fails for
554            situations like content at 29.9978733fps, DCP at 30fps.  The accuracy of the Time type is not
555            enough to distinguish between the two with low values of time (e.g. 3200 in Time units).
556
557            Instead we convert the DCPTime using the DCP video rate then account for any skip/repeat.
558         */
559         return s.frames_floor (piece->frc.dcp) / piece->frc.factor ();
560 }
561
562
563 DCPTime
564 Player::content_video_to_dcp (shared_ptr<const Piece> piece, Frame f) const
565 {
566         /* See comment in dcp_to_content_video */
567         auto const d = DCPTime::from_frames (f * piece->frc.factor(), piece->frc.dcp) - DCPTime(piece->content->trim_start(), piece->frc);
568         return d + piece->content->position();
569 }
570
571
572 Frame
573 Player::dcp_to_resampled_audio (shared_ptr<const Piece> piece, DCPTime t) const
574 {
575         auto film = _film.lock();
576         DCPOMATIC_ASSERT(film);
577
578         auto s = t - piece->content->position ();
579         s = min (piece->content->length_after_trim(film), s);
580         /* See notes in dcp_to_content_video */
581         return max (DCPTime(), DCPTime(piece->content->trim_start(), piece->frc) + s).frames_floor(film->audio_frame_rate());
582 }
583
584
585 DCPTime
586 Player::resampled_audio_to_dcp (shared_ptr<const Piece> piece, Frame f) const
587 {
588         auto film = _film.lock();
589         DCPOMATIC_ASSERT(film);
590
591         /* See comment in dcp_to_content_video */
592         return DCPTime::from_frames(f, film->audio_frame_rate())
593                 - DCPTime (piece->content->trim_start(), piece->frc)
594                 + piece->content->position();
595 }
596
597
598 ContentTime
599 Player::dcp_to_content_time (shared_ptr<const Piece> piece, DCPTime t) const
600 {
601         auto film = _film.lock();
602         DCPOMATIC_ASSERT(film);
603
604         auto s = t - piece->content->position ();
605         s = min (piece->content->length_after_trim(film), s);
606         return max (ContentTime (), ContentTime (s, piece->frc) + piece->content->trim_start());
607 }
608
609
610 DCPTime
611 Player::content_time_to_dcp (shared_ptr<const Piece> piece, ContentTime t) const
612 {
613         return max (DCPTime(), DCPTime(t - piece->content->trim_start(), piece->frc) + piece->content->position());
614 }
615
616
617 vector<shared_ptr<Font>>
618 Player::get_subtitle_fonts ()
619 {
620         boost::mutex::scoped_lock lm (_mutex);
621
622         vector<shared_ptr<Font>> fonts;
623         for (auto piece: _pieces) {
624                 for (auto text: piece->content->text) {
625                         auto text_fonts = text->fonts();
626                         copy (text_fonts.begin(), text_fonts.end(), back_inserter(fonts));
627                 }
628         }
629
630         return fonts;
631 }
632
633
634 /** Set this player never to produce any video data */
635 void
636 Player::set_ignore_video ()
637 {
638         ChangeSignaller<Player, int> cc(this, PlayerProperty::IGNORE_VIDEO);
639         _ignore_video = true;
640         setup_pieces();
641 }
642
643
644 void
645 Player::set_ignore_audio ()
646 {
647         ChangeSignaller<Player, int> cc(this, PlayerProperty::IGNORE_AUDIO);
648         _ignore_audio = true;
649         setup_pieces();
650 }
651
652
653 void
654 Player::set_ignore_text ()
655 {
656         ChangeSignaller<Player, int> cc(this, PlayerProperty::IGNORE_TEXT);
657         _ignore_text = true;
658         setup_pieces();
659 }
660
661
662 /** Set the player to always burn open texts into the image regardless of the content settings */
663 void
664 Player::set_always_burn_open_subtitles ()
665 {
666         ChangeSignaller<Player, int> cc(this, PlayerProperty::ALWAYS_BURN_OPEN_SUBTITLES);
667         _always_burn_open_subtitles = true;
668 }
669
670
671 /** Sets up the player to be faster, possibly at the expense of quality */
672 void
673 Player::set_fast ()
674 {
675         _fast = true;
676         setup_pieces();
677 }
678
679
680 void
681 Player::set_play_referenced ()
682 {
683         ChangeSignaller<Player, int> cc(this, PlayerProperty::PLAY_REFERENCED);
684         _play_referenced = true;
685         setup_pieces();
686 }
687
688
689 bool
690 Player::pass ()
691 {
692         boost::mutex::scoped_lock lm (_mutex);
693
694         if (_suspended) {
695                 /* We can't pass in this state */
696                 LOG_DEBUG_PLAYER_NC ("Player is suspended");
697                 return false;
698         }
699
700         auto film = _film.lock();
701
702         if (_playback_length.load() == DCPTime() || !film) {
703                 /* Special; just give one black frame */
704                 emit_video (black_player_video_frame(Eyes::BOTH), DCPTime());
705                 return true;
706         }
707
708         /* Find the decoder or empty which is farthest behind where we are and make it emit some data */
709
710         shared_ptr<Piece> earliest_content;
711         optional<DCPTime> earliest_time;
712
713         for (auto i: _pieces) {
714                 if (i->done) {
715                         continue;
716                 }
717
718                 auto const t = content_time_to_dcp (i, max(i->decoder->position(), i->content->trim_start()));
719                 if (t > i->content->end(film)) {
720                         i->done = true;
721                 } else {
722
723                         /* Given two choices at the same time, pick the one with texts so we see it before
724                            the video.
725                         */
726                         if (!earliest_time || t < *earliest_time || (t == *earliest_time && !i->decoder->text.empty())) {
727                                 earliest_time = t;
728                                 earliest_content = i;
729                         }
730                 }
731         }
732
733         bool done = false;
734
735         enum {
736                 NONE,
737                 CONTENT,
738                 BLACK,
739                 SILENT
740         } which = NONE;
741
742         if (earliest_content) {
743                 which = CONTENT;
744         }
745
746         if (!_black.done() && !_ignore_video && (!earliest_time || _black.position() < *earliest_time)) {
747                 earliest_time = _black.position ();
748                 which = BLACK;
749         }
750
751         if (!_silent.done() && !_ignore_audio && (!earliest_time || _silent.position() < *earliest_time)) {
752                 earliest_time = _silent.position ();
753                 which = SILENT;
754         }
755
756         switch (which) {
757         case CONTENT:
758         {
759                 LOG_DEBUG_PLAYER ("Calling pass() on %1", earliest_content->content->path(0));
760                 auto result = earliest_content->decoder->pass();
761                 earliest_content->done = result.is_finished();
762                 if (result.is_error()) {
763                         Error(result.error_message());
764                 }
765                 auto dcp = dynamic_pointer_cast<DCPContent>(earliest_content->content);
766                 if (dcp && !_play_referenced && dcp->reference_audio()) {
767                         /* We are skipping some referenced DCP audio content, so we need to update _next_audio_time
768                            to `hide' the fact that no audio was emitted during the referenced DCP (though
769                            we need to behave as though it was).
770                         */
771                         _next_audio_time = dcp->end(film);
772                 }
773                 break;
774         }
775         case BLACK:
776                 LOG_DEBUG_PLAYER ("Emit black for gap at %1", to_string(_black.position()));
777                 emit_video (black_player_video_frame(Eyes::BOTH), _black.position());
778                 _black.set_position (_black.position() + one_video_frame());
779                 break;
780         case SILENT:
781         {
782                 LOG_DEBUG_PLAYER ("Emit silence for gap at %1", to_string(_silent.position()));
783                 DCPTimePeriod period (_silent.period_at_position());
784                 if (_next_audio_time) {
785                         /* Sometimes the thing that happened last finishes fractionally before
786                            or after this silence.  Bodge the start time of the silence to fix it.
787                            I think this is nothing to worry about since we will just add or
788                            remove a little silence at the end of some content.
789                         */
790                         int64_t const error = labs(period.from.get() - _next_audio_time->get());
791                         /* Let's not worry about less than a frame at 24fps */
792                         int64_t const too_much_error = DCPTime::from_frames(1, 24).get();
793                         if (error >= too_much_error) {
794                                 film->log()->log(String::compose("Silence starting before or after last audio by %1", error), LogEntry::TYPE_ERROR);
795                         }
796                         DCPOMATIC_ASSERT (error < too_much_error);
797                         period.from = *_next_audio_time;
798                 }
799                 if (period.duration() > one_video_frame()) {
800                         period.to = period.from + one_video_frame();
801                 }
802                 fill_audio (period);
803                 _silent.set_position (period.to);
804                 break;
805         }
806         case NONE:
807                 done = true;
808                 break;
809         }
810
811         /* Emit any audio that is ready */
812
813         /* Work out the time before which the audio is definitely all here.  This is the earliest last_push_end of one
814            of our streams, or the position of the _silent.  First, though we choose only streams that are less than
815            ignore_streams_behind seconds behind the furthest ahead (we assume that if a stream has fallen that far
816            behind it has finished).  This is so that we don't withhold audio indefinitely awaiting data from a stream
817            that will never come, causing bugs like #2101.
818         */
819         constexpr int ignore_streams_behind = 5;
820
821         using state_pair = std::pair<AudioStreamPtr, StreamState>;
822
823         /* Find streams that have pushed */
824         std::vector<state_pair> have_pushed;
825         std::copy_if(_stream_states.begin(), _stream_states.end(), std::back_inserter(have_pushed), [](state_pair const& a) { return static_cast<bool>(a.second.last_push_end); });
826
827         /* Find the 'leading' stream (i.e. the one that pushed data most recently) */
828         auto latest_last_push_end = std::max_element(
829                 have_pushed.begin(),
830                 have_pushed.end(),
831                 [](state_pair const& a, state_pair const& b) { return a.second.last_push_end.get() < b.second.last_push_end.get(); }
832                 );
833
834         if (latest_last_push_end != have_pushed.end()) {
835                 LOG_DEBUG_PLAYER("Leading audio stream is in %1 at %2", latest_last_push_end->second.piece->content->path(0), to_string(latest_last_push_end->second.last_push_end.get()));
836         }
837
838         /* Now make a list of those streams that are less than ignore_streams_behind behind the leader */
839         std::map<AudioStreamPtr, StreamState> alive_stream_states;
840         for (auto const& i: _stream_states) {
841                 if (!i.second.last_push_end || (latest_last_push_end->second.last_push_end.get() - i.second.last_push_end.get()) < dcpomatic::DCPTime::from_seconds(ignore_streams_behind)) {
842                         alive_stream_states.insert(i);
843                 } else {
844                         LOG_DEBUG_PLAYER("Ignoring stream %1 because it is too far behind", i.second.piece->content->path(0));
845                 }
846         }
847
848         auto pull_to = _playback_length.load();
849         for (auto const& i: alive_stream_states) {
850                 auto position = i.second.last_push_end.get_value_or(i.second.piece->content->position());
851                 if (!i.second.piece->done && position < pull_to) {
852                         pull_to = position;
853                 }
854         }
855         if (!_silent.done() && _silent.position() < pull_to) {
856                 pull_to = _silent.position();
857         }
858
859         LOG_DEBUG_PLAYER("Emitting audio up to %1", to_string(pull_to));
860         auto audio = _audio_merger.pull (pull_to);
861         for (auto i = audio.begin(); i != audio.end(); ++i) {
862                 if (_next_audio_time && i->second < *_next_audio_time) {
863                         /* This new data comes before the last we emitted (or the last seek); discard it */
864                         auto cut = discard_audio (i->first, i->second, *_next_audio_time);
865                         if (!cut.first) {
866                                 continue;
867                         }
868                         *i = cut;
869                 } else if (_next_audio_time && i->second > *_next_audio_time) {
870                         /* There's a gap between this data and the last we emitted; fill with silence */
871                         fill_audio (DCPTimePeriod (*_next_audio_time, i->second));
872                 }
873
874                 emit_audio (i->first, i->second);
875         }
876
877         if (done) {
878                 if (_shuffler) {
879                         _shuffler->flush ();
880                 }
881                 for (auto const& i: _delay) {
882                         do_emit_video(i.first, i.second);
883                 }
884
885                 /* Perhaps we should have Empty entries for both eyes in the 3D case (somehow).
886                  * However, if we have L and R video files, and one is shorter than the other,
887                  * the fill code in ::video mostly takes care of filling in the gaps.
888                  * However, since it fills at the point when it knows there is more video coming
889                  * at time t (so it should fill any gap up to t) it can't do anything right at the
890                  * end.  This is particularly bad news if the last frame emitted is a LEFT
891                  * eye, as the MXF writer will complain about the 3D sequence being wrong.
892                  * Here's a hack to workaround that particular case.
893                  */
894                 if (_next_video_eyes && _next_video_time && *_next_video_eyes == Eyes::RIGHT) {
895                         do_emit_video (black_player_video_frame(Eyes::RIGHT), *_next_video_time);
896                 }
897         }
898
899         return done;
900 }
901
902
903 /** @return Open subtitles for the frame at the given time, converted to images */
904 optional<PositionImage>
905 Player::open_subtitles_for_frame (DCPTime time) const
906 {
907         auto film = _film.lock();
908         if (!film) {
909                 return {};
910         }
911
912         list<PositionImage> captions;
913         int const vfr = film->video_frame_rate();
914
915         for (
916                 auto j:
917                 _active_texts[TextType::OPEN_SUBTITLE].get_burnt(DCPTimePeriod(time, time + DCPTime::from_frames(1, vfr)), _always_burn_open_subtitles)
918                 ) {
919
920                 /* Bitmap subtitles */
921                 for (auto i: j.bitmap) {
922                         if (!i.image) {
923                                 continue;
924                         }
925
926                         /* i.image will already have been scaled to fit _video_container_size */
927                         dcp::Size scaled_size (i.rectangle.width * _video_container_size.load().width, i.rectangle.height * _video_container_size.load().height);
928
929                         captions.push_back (
930                                 PositionImage (
931                                         i.image,
932                                         Position<int> (
933                                                 lrint(_video_container_size.load().width * i.rectangle.x),
934                                                 lrint(_video_container_size.load().height * i.rectangle.y)
935                                                 )
936                                         )
937                                 );
938                 }
939
940                 /* String subtitles (rendered to an image) */
941                 if (!j.string.empty()) {
942                         auto s = render_text(j.string, _video_container_size, time, vfr);
943                         copy (s.begin(), s.end(), back_inserter (captions));
944                 }
945         }
946
947         if (captions.empty()) {
948                 return {};
949         }
950
951         return merge (captions, _subtitle_alignment);
952 }
953
954
955 static
956 Eyes
957 increment_eyes (Eyes e)
958 {
959         if (e == Eyes::LEFT) {
960                 return Eyes::RIGHT;
961         }
962
963         return Eyes::LEFT;
964 }
965
966
967 void
968 Player::video (weak_ptr<Piece> weak_piece, ContentVideo video)
969 {
970         if (_suspended) {
971                 return;
972         }
973
974         auto piece = weak_piece.lock ();
975         if (!piece) {
976                 return;
977         }
978
979         if (!piece->content->video->use()) {
980                 return;
981         }
982
983         auto film = _film.lock();
984         if (!film) {
985                 return;
986         }
987
988         FrameRateChange frc(film, piece->content);
989         if (frc.skip && (video.frame % 2) == 1) {
990                 return;
991         }
992
993         vector<Eyes> eyes_to_emit;
994
995         if (!film->three_d()) {
996                 if (video.eyes == Eyes::RIGHT) {
997                         /* 2D film, 3D content: discard right */
998                         return;
999                 } else if (video.eyes == Eyes::LEFT) {
1000                         /* 2D film, 3D content: emit left as "both" */
1001                         video.eyes = Eyes::BOTH;
1002                         eyes_to_emit = { Eyes::BOTH };
1003                 }
1004         } else {
1005                 if (video.eyes == Eyes::BOTH) {
1006                         /* 3D film, 2D content; emit "both" for left and right */
1007                         eyes_to_emit = { Eyes::LEFT, Eyes::RIGHT };
1008                 }
1009         }
1010
1011         if (eyes_to_emit.empty()) {
1012                 eyes_to_emit = { video.eyes };
1013         }
1014
1015         /* Time of the first frame we will emit */
1016         DCPTime const time = content_video_to_dcp (piece, video.frame);
1017         LOG_DEBUG_PLAYER("Received video frame %1 at %2", video.frame, to_string(time));
1018
1019         /* Discard if it's before the content's period or the last accurate seek.  We can't discard
1020            if it's after the content's period here as in that case we still need to fill any gap between
1021            `now' and the end of the content's period.
1022         */
1023         if (time < piece->content->position() || (_next_video_time && time < *_next_video_time)) {
1024                 return;
1025         }
1026
1027         auto ignore_video = std::find_if(
1028                 piece->ignore_video.begin(),
1029                 piece->ignore_video.end(),
1030                 [time](DCPTimePeriod period) { return period.contains(time); }
1031                 );
1032         if (ignore_video != piece->ignore_video.end()) {
1033                 return;
1034         }
1035
1036         /* Fill gaps that we discover now that we have some video which needs to be emitted.
1037            This is where we need to fill to.
1038         */
1039         DCPTime fill_to = min(time, piece->content->end(film));
1040
1041         if (_next_video_time) {
1042                 DCPTime fill_from = max (*_next_video_time, piece->content->position());
1043
1044                 /* Fill if we have more than half a frame to do */
1045                 if ((fill_to - fill_from) > one_video_frame() / 2) {
1046                         auto last = _last_video.find (weak_piece);
1047                         if (film->three_d()) {
1048                                 auto fill_to_eyes = eyes_to_emit[0];
1049                                 if (fill_to_eyes == Eyes::BOTH) {
1050                                         fill_to_eyes = Eyes::LEFT;
1051                                 }
1052                                 if (fill_to == piece->content->end(film)) {
1053                                         /* Don't fill after the end of the content */
1054                                         fill_to_eyes = Eyes::LEFT;
1055                                 }
1056                                 auto j = fill_from;
1057                                 auto eyes = _next_video_eyes.get_value_or(Eyes::LEFT);
1058                                 if (eyes == Eyes::BOTH) {
1059                                         eyes = Eyes::LEFT;
1060                                 }
1061                                 while (j < fill_to || eyes != fill_to_eyes) {
1062                                         if (last != _last_video.end()) {
1063                                                 LOG_DEBUG_PLAYER("Fill using last video at %1 in 3D mode", to_string(j));
1064                                                 auto copy = last->second->shallow_copy();
1065                                                 copy->set_eyes (eyes);
1066                                                 emit_video (copy, j);
1067                                         } else {
1068                                                 LOG_DEBUG_PLAYER("Fill using black at %1 in 3D mode", to_string(j));
1069                                                 emit_video (black_player_video_frame(eyes), j);
1070                                         }
1071                                         if (eyes == Eyes::RIGHT) {
1072                                                 j += one_video_frame();
1073                                         }
1074                                         eyes = increment_eyes (eyes);
1075                                 }
1076                         } else {
1077                                 for (DCPTime j = fill_from; j < fill_to; j += one_video_frame()) {
1078                                         if (last != _last_video.end()) {
1079                                                 emit_video (last->second, j);
1080                                         } else {
1081                                                 emit_video (black_player_video_frame(Eyes::BOTH), j);
1082                                         }
1083                                 }
1084                         }
1085                 }
1086         }
1087
1088         auto const content_video = piece->content->video;
1089
1090         for (auto eyes: eyes_to_emit) {
1091                 _last_video[weak_piece] = std::make_shared<PlayerVideo>(
1092                         video.image,
1093                         content_video->actual_crop(),
1094                         content_video->fade(film, video.frame),
1095                         scale_for_display(
1096                                 content_video->scaled_size(film->frame_size()),
1097                                 _video_container_size,
1098                                 film->frame_size(),
1099                                 content_video->pixel_quanta()
1100                                 ),
1101                         _video_container_size,
1102                         eyes,
1103                         video.part,
1104                         content_video->colour_conversion(),
1105                         content_video->range(),
1106                         piece->content,
1107                         video.frame,
1108                         false
1109                         );
1110
1111                 DCPTime t = time;
1112                 for (int i = 0; i < frc.repeat; ++i) {
1113                         if (t < piece->content->end(film)) {
1114                                 emit_video (_last_video[weak_piece], t);
1115                         }
1116                         t += one_video_frame ();
1117                 }
1118         }
1119 }
1120
1121
1122 void
1123 Player::audio (weak_ptr<Piece> weak_piece, AudioStreamPtr stream, ContentAudio content_audio)
1124 {
1125         if (_suspended) {
1126                 return;
1127         }
1128
1129         DCPOMATIC_ASSERT (content_audio.audio->frames() > 0);
1130
1131         auto piece = weak_piece.lock ();
1132         if (!piece) {
1133                 return;
1134         }
1135
1136         auto film = _film.lock();
1137         if (!film) {
1138                 return;
1139         }
1140
1141         auto content = piece->content->audio;
1142         DCPOMATIC_ASSERT (content);
1143
1144         int const rfr = content->resampled_frame_rate(film);
1145
1146         /* Compute time in the DCP */
1147         auto time = resampled_audio_to_dcp (piece, content_audio.frame);
1148
1149         /* And the end of this block in the DCP */
1150         auto end = time + DCPTime::from_frames(content_audio.audio->frames(), rfr);
1151         LOG_DEBUG_PLAYER("Received audio frame %1 covering %2 to %3 (%4)", content_audio.frame, to_string(time), to_string(end), piece->content->path(0).filename());
1152
1153         /* Remove anything that comes before the start or after the end of the content */
1154         if (time < piece->content->position()) {
1155                 auto cut = discard_audio (content_audio.audio, time, piece->content->position());
1156                 if (!cut.first) {
1157                         /* This audio is entirely discarded */
1158                         return;
1159                 }
1160                 content_audio.audio = cut.first;
1161                 time = cut.second;
1162         } else if (time > piece->content->end(film)) {
1163                 /* Discard it all */
1164                 return;
1165         } else if (end > piece->content->end(film)) {
1166                 Frame const remaining_frames = DCPTime(piece->content->end(film) - time).frames_round(rfr);
1167                 if (remaining_frames == 0) {
1168                         return;
1169                 }
1170                 content_audio.audio = make_shared<AudioBuffers>(content_audio.audio, remaining_frames, 0);
1171         }
1172
1173         DCPOMATIC_ASSERT (content_audio.audio->frames() > 0);
1174
1175         /* Gain and fade */
1176
1177         auto const fade_coeffs = content->fade (stream, content_audio.frame, content_audio.audio->frames(), rfr);
1178         if (content->gain() != 0 || !fade_coeffs.empty()) {
1179                 auto gain_buffers = make_shared<AudioBuffers>(content_audio.audio);
1180                 if (!fade_coeffs.empty()) {
1181                         /* Apply both fade and gain */
1182                         DCPOMATIC_ASSERT (fade_coeffs.size() == static_cast<size_t>(gain_buffers->frames()));
1183                         auto const channels = gain_buffers->channels();
1184                         auto const frames = fade_coeffs.size();
1185                         auto data = gain_buffers->data();
1186                         auto const gain = db_to_linear (content->gain());
1187                         for (auto channel = 0; channel < channels; ++channel) {
1188                                 for (auto frame = 0U; frame < frames; ++frame) {
1189                                         data[channel][frame] *= gain * fade_coeffs[frame];
1190                                 }
1191                         }
1192                 } else {
1193                         /* Just apply gain */
1194                         gain_buffers->apply_gain (content->gain());
1195                 }
1196                 content_audio.audio = gain_buffers;
1197         }
1198
1199         /* Remap */
1200
1201         content_audio.audio = remap(content_audio.audio, film->audio_channels(), stream->mapping());
1202
1203         /* Process */
1204
1205         if (_audio_processor) {
1206                 content_audio.audio = _audio_processor->run(content_audio.audio, film->audio_channels());
1207         }
1208
1209         /* Push */
1210
1211         _audio_merger.push (content_audio.audio, time);
1212         DCPOMATIC_ASSERT (_stream_states.find (stream) != _stream_states.end ());
1213         _stream_states[stream].last_push_end = time + DCPTime::from_frames(content_audio.audio->frames(), film->audio_frame_rate());
1214 }
1215
1216
1217 void
1218 Player::bitmap_text_start (weak_ptr<Piece> weak_piece, weak_ptr<const TextContent> weak_content, ContentBitmapText subtitle)
1219 {
1220         if (_suspended) {
1221                 return;
1222         }
1223
1224         auto piece = weak_piece.lock ();
1225         auto content = weak_content.lock ();
1226         if (!piece || !content) {
1227                 return;
1228         }
1229
1230         PlayerText ps;
1231         for (auto& sub: subtitle.subs)
1232         {
1233                 /* Apply content's subtitle offsets */
1234                 sub.rectangle.x += content->x_offset ();
1235                 sub.rectangle.y += content->y_offset ();
1236
1237                 /* Apply a corrective translation to keep the subtitle centred after the scale that is coming up */
1238                 sub.rectangle.x -= sub.rectangle.width * ((content->x_scale() - 1) / 2);
1239                 sub.rectangle.y -= sub.rectangle.height * ((content->y_scale() - 1) / 2);
1240
1241                 /* Apply content's subtitle scale */
1242                 sub.rectangle.width *= content->x_scale ();
1243                 sub.rectangle.height *= content->y_scale ();
1244
1245                 auto image = sub.image;
1246
1247                 /* We will scale the subtitle up to fit _video_container_size */
1248                 int const width = sub.rectangle.width * _video_container_size.load().width;
1249                 int const height = sub.rectangle.height * _video_container_size.load().height;
1250                 if (width == 0 || height == 0) {
1251                         return;
1252                 }
1253
1254                 dcp::Size scaled_size (width, height);
1255                 ps.bitmap.push_back (BitmapText(image->scale(scaled_size, dcp::YUVToRGB::REC601, image->pixel_format(), Image::Alignment::PADDED, _fast), sub.rectangle));
1256         }
1257
1258         DCPTime from(content_time_to_dcp(piece, subtitle.from()));
1259         _active_texts[content->type()].add_from(weak_content, ps, from);
1260 }
1261
1262
1263 void
1264 Player::plain_text_start (weak_ptr<Piece> weak_piece, weak_ptr<const TextContent> weak_content, ContentStringText subtitle)
1265 {
1266         if (_suspended) {
1267                 return;
1268         }
1269
1270         auto piece = weak_piece.lock ();
1271         auto content = weak_content.lock ();
1272         auto film = _film.lock();
1273         if (!piece || !content || !film) {
1274                 return;
1275         }
1276
1277         PlayerText ps;
1278         DCPTime const from (content_time_to_dcp (piece, subtitle.from()));
1279
1280         if (from > piece->content->end(film)) {
1281                 return;
1282         }
1283
1284         for (auto s: subtitle.subs) {
1285                 s.set_h_position (s.h_position() + content->x_offset());
1286                 s.set_v_position (s.v_position() + content->y_offset());
1287                 float const xs = content->x_scale();
1288                 float const ys = content->y_scale();
1289                 float size = s.size();
1290
1291                 /* Adjust size to express the common part of the scaling;
1292                    e.g. if xs = ys = 0.5 we scale size by 2.
1293                 */
1294                 if (xs > 1e-5 && ys > 1e-5) {
1295                         size *= 1 / min (1 / xs, 1 / ys);
1296                 }
1297                 s.set_size (size);
1298
1299                 /* Then express aspect ratio changes */
1300                 if (fabs (1.0 - xs / ys) > dcp::ASPECT_ADJUST_EPSILON) {
1301                         s.set_aspect_adjust (xs / ys);
1302                 }
1303
1304                 s.set_in (dcp::Time(from.seconds(), 1000));
1305                 ps.string.push_back (s);
1306         }
1307
1308         _active_texts[content->type()].add_from(weak_content, ps, from);
1309 }
1310
1311
1312 void
1313 Player::subtitle_stop (weak_ptr<Piece> weak_piece, weak_ptr<const TextContent> weak_content, ContentTime to)
1314 {
1315         if (_suspended) {
1316                 return;
1317         }
1318
1319         auto content = weak_content.lock ();
1320         if (!content) {
1321                 return;
1322         }
1323
1324         if (!_active_texts[content->type()].have(weak_content)) {
1325                 return;
1326         }
1327
1328         auto piece = weak_piece.lock ();
1329         auto film = _film.lock();
1330         if (!piece || !film) {
1331                 return;
1332         }
1333
1334         DCPTime const dcp_to = content_time_to_dcp (piece, to);
1335
1336         if (dcp_to > piece->content->end(film)) {
1337                 return;
1338         }
1339
1340         auto from = _active_texts[content->type()].add_to(weak_content, dcp_to);
1341
1342         bool const always = (content->type() == TextType::OPEN_SUBTITLE && _always_burn_open_subtitles);
1343         if (content->use() && !always && !content->burn()) {
1344                 Text (from.first, content->type(), content->dcp_track().get_value_or(DCPTextTrack()), DCPTimePeriod(from.second, dcp_to));
1345         }
1346 }
1347
1348
1349 void
1350 Player::seek (DCPTime time, bool accurate)
1351 {
1352         boost::mutex::scoped_lock lm (_mutex);
1353         LOG_DEBUG_PLAYER("Seek to %1 (%2accurate)", to_string(time), accurate ? "" : "in");
1354
1355         if (_suspended) {
1356                 /* We can't seek in this state */
1357                 return;
1358         }
1359
1360         auto film = _film.lock();
1361         if (!film) {
1362                 return;
1363         }
1364
1365         if (_shuffler) {
1366                 _shuffler->clear ();
1367         }
1368
1369         _delay.clear ();
1370
1371         if (_audio_processor) {
1372                 _audio_processor->flush ();
1373         }
1374
1375         _audio_merger.clear ();
1376         std::for_each(_active_texts.begin(), _active_texts.end(), [](ActiveText& a) { a.clear(); });
1377
1378         for (auto i: _pieces) {
1379                 if (time < i->content->position()) {
1380                         /* Before; seek to the start of the content.  Even if this request is for an inaccurate seek
1381                            we must seek this (following) content accurately, otherwise when we come to the end of the current
1382                            content we may not start right at the beginning of the next, causing a gap (if the next content has
1383                            been trimmed to a point between keyframes, or something).
1384                         */
1385                         i->decoder->seek (dcp_to_content_time (i, i->content->position()), true);
1386                         i->done = false;
1387                 } else if (i->content->position() <= time && time < i->content->end(film)) {
1388                         /* During; seek to position */
1389                         i->decoder->seek (dcp_to_content_time (i, time), accurate);
1390                         i->done = false;
1391                 } else {
1392                         /* After; this piece is done */
1393                         i->done = true;
1394                 }
1395         }
1396
1397         if (accurate) {
1398                 _next_video_time = time;
1399                 _next_video_eyes = Eyes::LEFT;
1400                 _next_audio_time = time;
1401         } else {
1402                 _next_video_time = boost::none;
1403                 _next_video_eyes = boost::none;
1404                 _next_audio_time = boost::none;
1405         }
1406
1407         _black.set_position (time);
1408         _silent.set_position (time);
1409
1410         _last_video.clear ();
1411
1412         for (auto& state: _stream_states) {
1413                 state.second.last_push_end = boost::none;
1414         }
1415 }
1416
1417
1418 void
1419 Player::emit_video (shared_ptr<PlayerVideo> pv, DCPTime time)
1420 {
1421         auto film = _film.lock();
1422         DCPOMATIC_ASSERT(film);
1423
1424         if (!film->three_d()) {
1425                 if (pv->eyes() == Eyes::LEFT) {
1426                         /* Use left-eye images for both eyes... */
1427                         pv->set_eyes (Eyes::BOTH);
1428                 } else if (pv->eyes() == Eyes::RIGHT) {
1429                         /* ...and discard the right */
1430                         return;
1431                 }
1432         }
1433
1434         /* We need a delay to give a little wiggle room to ensure that relevant subtitles arrive at the
1435            player before the video that requires them.
1436         */
1437         _delay.push_back (make_pair (pv, time));
1438
1439         if (pv->eyes() == Eyes::BOTH || pv->eyes() == Eyes::RIGHT) {
1440                 _next_video_time = time + one_video_frame();
1441         }
1442         _next_video_eyes = increment_eyes (pv->eyes());
1443
1444         if (_delay.size() < 3) {
1445                 return;
1446         }
1447
1448         auto to_do = _delay.front();
1449         _delay.pop_front();
1450         do_emit_video (to_do.first, to_do.second);
1451 }
1452
1453
1454 void
1455 Player::do_emit_video (shared_ptr<PlayerVideo> pv, DCPTime time)
1456 {
1457         if (pv->eyes() == Eyes::BOTH || pv->eyes() == Eyes::RIGHT) {
1458                 std::for_each(_active_texts.begin(), _active_texts.end(), [time](ActiveText& a) { a.clear_before(time); });
1459         }
1460
1461         auto subtitles = open_subtitles_for_frame (time);
1462         if (subtitles) {
1463                 pv->set_text (subtitles.get ());
1464         }
1465
1466         Video (pv, time);
1467 }
1468
1469
1470 void
1471 Player::emit_audio (shared_ptr<AudioBuffers> data, DCPTime time)
1472 {
1473         auto film = _film.lock();
1474         DCPOMATIC_ASSERT(film);
1475
1476         /* Log if the assert below is about to fail */
1477         if (_next_audio_time && labs(time.get() - _next_audio_time->get()) > 1) {
1478                 film->log()->log(String::compose("Out-of-sequence emit %1 vs %2", to_string(time), to_string(*_next_audio_time)), LogEntry::TYPE_WARNING);
1479         }
1480
1481         /* This audio must follow on from the previous, allowing for half a sample (at 48kHz) leeway */
1482         DCPOMATIC_ASSERT (!_next_audio_time || labs(time.get() - _next_audio_time->get()) < 2);
1483         Audio(data, time, film->audio_frame_rate());
1484         _next_audio_time = time + DCPTime::from_frames(data->frames(), film->audio_frame_rate());
1485 }
1486
1487
1488 void
1489 Player::fill_audio (DCPTimePeriod period)
1490 {
1491         auto film = _film.lock();
1492         DCPOMATIC_ASSERT(film);
1493
1494         if (period.from == period.to) {
1495                 return;
1496         }
1497
1498         DCPOMATIC_ASSERT (period.from < period.to);
1499
1500         DCPTime t = period.from;
1501         while (t < period.to) {
1502                 DCPTime block = min (DCPTime::from_seconds (0.5), period.to - t);
1503                 Frame const samples = block.frames_round(film->audio_frame_rate());
1504                 if (samples) {
1505                         auto silence = make_shared<AudioBuffers>(film->audio_channels(), samples);
1506                         silence->make_silent ();
1507                         emit_audio (silence, t);
1508                 }
1509                 t += block;
1510         }
1511 }
1512
1513
1514 DCPTime
1515 Player::one_video_frame () const
1516 {
1517         auto film = _film.lock();
1518         DCPOMATIC_ASSERT(film);
1519
1520         return DCPTime::from_frames(1, film->video_frame_rate ());
1521 }
1522
1523
1524 pair<shared_ptr<AudioBuffers>, DCPTime>
1525 Player::discard_audio (shared_ptr<const AudioBuffers> audio, DCPTime time, DCPTime discard_to) const
1526 {
1527         auto film = _film.lock();
1528         DCPOMATIC_ASSERT(film);
1529
1530         auto const discard_time = discard_to - time;
1531         auto const discard_frames = discard_time.frames_round(film->audio_frame_rate());
1532         auto remaining_frames = audio->frames() - discard_frames;
1533         if (remaining_frames <= 0) {
1534                 return make_pair(shared_ptr<AudioBuffers>(), DCPTime());
1535         }
1536         auto cut = make_shared<AudioBuffers>(audio, remaining_frames, discard_frames);
1537         return make_pair(cut, time + discard_time);
1538 }
1539
1540
1541 void
1542 Player::set_dcp_decode_reduction (optional<int> reduction)
1543 {
1544         ChangeSignaller<Player, int> cc(this, PlayerProperty::DCP_DECODE_REDUCTION);
1545
1546         if (reduction == _dcp_decode_reduction.load()) {
1547                 cc.abort();
1548                 return;
1549         }
1550
1551         _dcp_decode_reduction = reduction;
1552         setup_pieces();
1553 }
1554
1555
1556 optional<DCPTime>
1557 Player::content_time_to_dcp (shared_ptr<const Content> content, ContentTime t) const
1558 {
1559         boost::mutex::scoped_lock lm (_mutex);
1560
1561         for (auto i: _pieces) {
1562                 if (i->content == content) {
1563                         return content_time_to_dcp (i, t);
1564                 }
1565         }
1566
1567         /* We couldn't find this content; perhaps things are being changed over */
1568         return {};
1569 }
1570
1571
1572 optional<ContentTime>
1573 Player::dcp_to_content_time (shared_ptr<const Content> content, DCPTime t) const
1574 {
1575         boost::mutex::scoped_lock lm (_mutex);
1576
1577         for (auto i: _pieces) {
1578                 if (i->content == content) {
1579                         return dcp_to_content_time (i, t);
1580                 }
1581         }
1582
1583         /* We couldn't find this content; perhaps things are being changed over */
1584         return {};
1585 }
1586
1587
1588 shared_ptr<const Playlist>
1589 Player::playlist () const
1590 {
1591         auto film = _film.lock();
1592         if (!film) {
1593                 return {};
1594         }
1595
1596         return _playlist ? _playlist : film->playlist();
1597 }
1598
1599
1600 void
1601 Player::atmos (weak_ptr<Piece> weak_piece, ContentAtmos data)
1602 {
1603         if (_suspended) {
1604                 return;
1605         }
1606
1607         auto film = _film.lock();
1608         DCPOMATIC_ASSERT(film);
1609
1610         auto piece = weak_piece.lock ();
1611         DCPOMATIC_ASSERT (piece);
1612
1613         auto const vfr = film->video_frame_rate();
1614
1615         DCPTime const dcp_time = DCPTime::from_frames(data.frame, vfr) - DCPTime(piece->content->trim_start(), FrameRateChange(vfr, vfr));
1616         if (dcp_time < piece->content->position() || dcp_time >= (piece->content->end(film))) {
1617                 return;
1618         }
1619
1620         auto ignore_atmos = std::find_if(
1621                 piece->ignore_atmos.begin(),
1622                 piece->ignore_atmos.end(),
1623                 [dcp_time](DCPTimePeriod period) { return period.contains(dcp_time); }
1624                 );
1625         if (ignore_atmos != piece->ignore_atmos.end()) {
1626                 return;
1627         }
1628
1629         Atmos (data.data, dcp_time, data.metadata);
1630 }
1631
1632
1633 void
1634 Player::signal_change(ChangeType type, int property)
1635 {
1636         Change(type, property, false);
1637 }
1638