X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Flib%2Fplayer.cc;h=79db7cc2c76d1695ac3201a09a1a470ecc360b30;hb=444e1d4e0062677220d32b78b97a4b730156b514;hp=6f0cfd1af7e9490f216b2d243742b86d081badb5;hpb=26c62598730d1d32333bfab0d5f463b90d26ee4d;p=dcpomatic.git diff --git a/src/lib/player.cc b/src/lib/player.cc index 6f0cfd1af..79db7cc2c 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2013-2018 Carl Hetherington + Copyright (C) 2013-2019 Carl Hetherington This file is part of DCP-o-matic. @@ -48,6 +48,7 @@ #include "image_decoder.h" #include "compose.hpp" #include "shuffler.h" +#include "timer.h" #include #include #include @@ -92,6 +93,7 @@ Player::Player (shared_ptr film, shared_ptr playlist , _ignore_text (false) , _always_burn_open_subtitles (false) , _fast (false) + , _tolerant (film->tolerant()) , _play_referenced (false) , _audio_merger (_film->audio_frame_rate()) , _shuffler (0) @@ -137,6 +139,7 @@ have_audio (shared_ptr piece) void Player::setup_pieces_unlocked () { + list > old_pieces = _pieces; _pieces.clear (); delete _shuffler; @@ -154,7 +157,15 @@ Player::setup_pieces_unlocked () continue; } - shared_ptr decoder = decoder_factory (_film, i, _fast); + shared_ptr old_decoder; + BOOST_FOREACH (shared_ptr j, old_pieces) { + if (j->content == i) { + old_decoder = j->decoder; + break; + } + } + + shared_ptr decoder = decoder_factory (_film, i, _fast, _tolerant, old_decoder); FrameRateChange frc (_film, i); if (!decoder) { @@ -493,7 +504,7 @@ Player::get_reel_assets () scoped_ptr decoder; try { - decoder.reset (new DCPDecoder (_film, j, false)); + decoder.reset (new DCPDecoder (_film, j, false, false, shared_ptr())); } catch (...) { return a; } @@ -603,12 +614,12 @@ Player::pass () which = CONTENT; } - if (!_black.done() && (!earliest_time || _black.position() < *earliest_time)) { + if (!_black.done() && !_ignore_video && (!earliest_time || _black.position() < *earliest_time)) { earliest_time = _black.position (); which = BLACK; } - if (!_silent.done() && (!earliest_time || _silent.position() < *earliest_time)) { + if (!_silent.done() && !_ignore_audio && (!earliest_time || _silent.position() < *earliest_time)) { earliest_time = _silent.position (); which = SILENT; } @@ -637,8 +648,16 @@ Player::pass () if (_last_audio_time) { /* Sometimes the thing that happened last finishes fractionally before or after this silence. Bodge the start time of the silence to fix it. + I think this is nothing to worry about since we will just add or + remove a little silence at the end of some content. */ - DCPOMATIC_ASSERT (labs(period.from.get() - _last_audio_time->get()) < 2); + int64_t const error = labs(period.from.get() - _last_audio_time->get()); + /* Let's not worry about less than a frame at 24fps */ + int64_t const too_much_error = DCPTime::from_frames(1, 24).get(); + if (error >= too_much_error) { + _film->log()->log(String::compose("Silence starting before or after last audio by %1", error), LogEntry::TYPE_ERROR); + } + DCPOMATIC_ASSERT (error < too_much_error); period.from = *_last_audio_time; } if (period.duration() > one_video_frame()) { @@ -1044,8 +1063,12 @@ Player::seek (DCPTime time, bool accurate) BOOST_FOREACH (shared_ptr i, _pieces) { if (time < i->content->position()) { - /* Before; seek to the start of the content */ - i->decoder->seek (dcp_to_content_time (i, i->content->position()), accurate); + /* Before; seek to the start of the content. Even if this request is for an inaccurate seek + we must seek this (following) content accurately, otherwise when we come to the end of the current + content we may not start right at the beginning of the next, causing a gap (if the next content has + been trimmed to a point between keyframes, or something). + */ + i->decoder->seek (dcp_to_content_time (i, i->content->position()), true); i->done = false; } else if (i->content->position() <= time && time < i->content->end(_film)) { /* During; seek to position */