Move some methods into Piece.
authorCarl Hetherington <cth@carlh.net>
Sun, 21 Jun 2020 23:34:26 +0000 (01:34 +0200)
committerCarl Hetherington <cth@carlh.net>
Sun, 21 Jun 2020 23:34:26 +0000 (01:34 +0200)
src/lib/piece.h
src/lib/player.cc
src/lib/player.h
test/time_calculation_test.cc

index 1b2889e5dec47a4bde352f355f66e217a18b795d..d1437ddfc6a044d4ac812c1b4d505e49903376d1 100644 (file)
@@ -47,6 +47,24 @@ public:
                return content->end (film);
        }
 
+       dcpomatic::DCPTime content_video_to_dcp (Frame f) const
+       {
+               /* It might seem more logical here to convert s to a ContentTime (using the FrameRateChange)
+                  then convert that ContentTime to frames at the content's rate.  However this fails for
+                  situations like content at 29.9978733fps, DCP at 30fps.  The accuracy of the Time type is not
+                  enough to distinguish between the two with low values of time (e.g. 3200 in Time units).
+
+                  Instead we convert the DCPTime using the DCP video rate then account for any skip/repeat.
+                  */
+               dcpomatic::DCPTime const d = dcpomatic::DCPTime::from_frames(f * frc.factor(), frc.dcp) - dcpomatic::DCPTime(content->trim_start(), frc);
+               return d + position();
+       }
+
+       dcpomatic::DCPTime content_time_to_dcp (dcpomatic::ContentTime t) const
+       {
+               return max (dcpomatic::DCPTime(), dcpomatic::DCPTime(t - content->trim_start(), frc) + position());
+       }
+
        boost::shared_ptr<Content> content;
        boost::shared_ptr<Decoder> decoder;
        FrameRateChange frc;
index 3d9c3efc76c8cdca4405d545103f2b49000119b8..216e68abd8cae901be7d9ff411614a5799d34543 100644 (file)
@@ -379,21 +379,6 @@ Player::black_player_video_frame (Eyes eyes) const
 }
 
 
-DCPTime
-Player::content_video_to_dcp (shared_ptr<const Piece> piece, Frame f) const
-{
-       /* It might seem more logical here to convert s to a ContentTime (using the FrameRateChange)
-          then convert that ContentTime to frames at the content's rate.  However this fails for
-          situations like content at 29.9978733fps, DCP at 30fps.  The accuracy of the Time type is not
-          enough to distinguish between the two with low values of time (e.g. 3200 in Time units).
-
-          Instead we convert the DCPTime using the DCP video rate then account for any skip/repeat.
-       */
-       DCPTime const d = DCPTime::from_frames (f * piece->frc.factor(), piece->frc.dcp) - DCPTime(piece->content->trim_start(), piece->frc);
-       return d + piece->position();
-}
-
-
 DCPTime
 Player::resampled_audio_to_dcp (shared_ptr<const Piece> piece, Frame f) const
 {
@@ -411,12 +396,6 @@ Player::dcp_to_content_time (shared_ptr<const Piece> piece, DCPTime t) const
        return max (ContentTime (), ContentTime (s, piece->frc) + piece->content->trim_start());
 }
 
-DCPTime
-Player::content_time_to_dcp (shared_ptr<const Piece> piece, ContentTime t) const
-{
-       return max (DCPTime (), DCPTime (t - piece->content->trim_start(), piece->frc) + piece->position());
-}
-
 list<shared_ptr<Font> >
 Player::get_subtitle_fonts ()
 {
@@ -596,7 +575,7 @@ Player::pass ()
                        continue;
                }
 
-               DCPTime const t = content_time_to_dcp (i, max(i->decoder->position(), i->content->trim_start()));
+               DCPTime const t = i->content_time_to_dcp (max(i->decoder->position(), i->content->trim_start()));
                if (t > i->end(_film)) {
                        i->done = true;
                } else {
@@ -789,7 +768,7 @@ Player::video (weak_ptr<Piece> wp, ContentVideo video)
        }
 
        /* Time of the first frame we will emit */
-       DCPTime const time = content_video_to_dcp (piece, video.frame);
+       DCPTime const time = piece->content_video_to_dcp (video.frame);
 
        /* Discard if it's before the content's period or the last accurate seek.  We can't discard
           if it's after the content's period here as in that case we still need to fill any gap between
@@ -977,7 +956,7 @@ Player::bitmap_text_start (weak_ptr<Piece> wp, weak_ptr<const TextContent> wc, C
 
        dcp::Size scaled_size (width, height);
        ps.bitmap.push_back (BitmapText(image->scale(scaled_size, dcp::YUV_TO_RGB_REC601, image->pixel_format(), true, _fast), subtitle.sub.rectangle));
-       DCPTime from (content_time_to_dcp (piece, subtitle.from()));
+       DCPTime from (piece->content_time_to_dcp(subtitle.from()));
 
        _active_texts[text->type()].add_from (wc, ps, from);
 }
@@ -992,7 +971,7 @@ Player::plain_text_start (weak_ptr<Piece> wp, weak_ptr<const TextContent> wc, Co
        }
 
        PlayerText ps;
-       DCPTime const from (content_time_to_dcp (piece, subtitle.from()));
+       DCPTime const from (piece->content_time_to_dcp( subtitle.from()));
 
        if (from > piece->end(_film)) {
                return;
@@ -1043,7 +1022,7 @@ Player::subtitle_stop (weak_ptr<Piece> wp, weak_ptr<const TextContent> wc, Conte
                return;
        }
 
-       DCPTime const dcp_to = content_time_to_dcp (piece, to);
+       DCPTime const dcp_to = piece->content_time_to_dcp(to);
 
        if (dcp_to > piece->end(_film)) {
                return;
@@ -1239,7 +1218,7 @@ Player::content_time_to_dcp (shared_ptr<Content> content, ContentTime t)
 
        BOOST_FOREACH (shared_ptr<Piece> i, _pieces) {
                if (i->content == content) {
-                       return content_time_to_dcp (i, t);
+                       return i->content_time_to_dcp (t);
                }
        }
 
index f4bd26d9fb9416683e2b36c2da4b68c128b4fd91..871f589594881b51594fe78ec845a3477388178f 100644 (file)
@@ -126,10 +126,8 @@ private:
        void film_change (ChangeType, Film::Property);
        void playlist_change (ChangeType);
        void playlist_content_change (ChangeType, int, bool);
-       dcpomatic::DCPTime content_video_to_dcp (boost::shared_ptr<const Piece> piece, Frame f) const;
        dcpomatic::DCPTime resampled_audio_to_dcp (boost::shared_ptr<const Piece> piece, Frame f) const;
        dcpomatic::ContentTime dcp_to_content_time (boost::shared_ptr<const Piece> piece, dcpomatic::DCPTime t) const;
-       dcpomatic::DCPTime content_time_to_dcp (boost::shared_ptr<const Piece> piece, dcpomatic::ContentTime t) const;
        boost::shared_ptr<PlayerVideo> black_player_video_frame (Eyes eyes) const;
 
        void video (boost::weak_ptr<Piece>, ContentVideo);
index 5106dcdaf755a49873e001e6c0fc8f8a03a0ea57..cc008aa4873c2208ca2a935951bd2c7ae9bea7a2 100644 (file)
@@ -200,9 +200,9 @@ BOOST_AUTO_TEST_CASE (player_time_calculation_test2)
        player->setup_pieces ();
        BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
        shared_ptr<Piece> piece = player->_pieces.front ();
-       BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0).get(), 0);
-       BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 12).get(), DCPTime::from_seconds(0.5).get());
-       BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 72).get(), DCPTime::from_seconds(3.0).get());
+       BOOST_CHECK_EQUAL (piece->content_video_to_dcp(0).get(), 0);
+       BOOST_CHECK_EQUAL (piece->content_video_to_dcp(12).get(), DCPTime::from_seconds(0.5).get());
+       BOOST_CHECK_EQUAL (piece->content_video_to_dcp(72).get(), DCPTime::from_seconds(3.0).get());
 
        /* Position 3s, no trim, content rate = DCP rate */
        content->set_position (film, DCPTime::from_seconds(3));
@@ -212,9 +212,9 @@ BOOST_AUTO_TEST_CASE (player_time_calculation_test2)
        player->setup_pieces ();
        BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
        piece = player->_pieces.front ();
-       BOOST_CHECK_EQUAL (player->content_video_to_dcp(piece, 0).get(), DCPTime::from_seconds(3.00).get());
-       BOOST_CHECK_EQUAL (player->content_video_to_dcp(piece, 36).get(), DCPTime::from_seconds(4.50).get());
-       BOOST_CHECK_EQUAL (player->content_video_to_dcp(piece, 162).get(), DCPTime::from_seconds(9.75).get());
+       BOOST_CHECK_EQUAL (piece->content_video_to_dcp(0).get(), DCPTime::from_seconds(3.00).get());
+       BOOST_CHECK_EQUAL (piece->content_video_to_dcp(36).get(), DCPTime::from_seconds(4.50).get());
+       BOOST_CHECK_EQUAL (piece->content_video_to_dcp(162).get(), DCPTime::from_seconds(9.75).get());
 
        /* Position 3s, 1.5s trim, content rate = DCP rate */
        content->set_position (film, DCPTime::from_seconds(3));
@@ -224,10 +224,10 @@ BOOST_AUTO_TEST_CASE (player_time_calculation_test2)
        player->setup_pieces ();
        BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
        piece = player->_pieces.front ();
-       BOOST_CHECK_EQUAL (player->content_video_to_dcp(piece, 0).get(), DCPTime::from_seconds(1.50).get());
-       BOOST_CHECK_EQUAL (player->content_video_to_dcp(piece, 36).get(), DCPTime::from_seconds(3.00).get());
-       BOOST_CHECK_EQUAL (player->content_video_to_dcp(piece, 72).get(), DCPTime::from_seconds(4.50).get());
-       BOOST_CHECK_EQUAL (player->content_video_to_dcp(piece, 198).get(), DCPTime::from_seconds(9.75).get());
+       BOOST_CHECK_EQUAL (piece->content_video_to_dcp(0).get(), DCPTime::from_seconds(1.50).get());
+       BOOST_CHECK_EQUAL (piece->content_video_to_dcp(36).get(), DCPTime::from_seconds(3.00).get());
+       BOOST_CHECK_EQUAL (piece->content_video_to_dcp(72).get(), DCPTime::from_seconds(4.50).get());
+       BOOST_CHECK_EQUAL (piece->content_video_to_dcp(198).get(), DCPTime::from_seconds(9.75).get());
 
        /* Position 0, no trim, content rate 24, DCP rate 25.
           Now, for example, a DCPTime position of 3s means 3s at 25fps.  Since we run the video
@@ -240,9 +240,9 @@ BOOST_AUTO_TEST_CASE (player_time_calculation_test2)
        player->setup_pieces ();
        BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
        piece = player->_pieces.front ();
-       BOOST_CHECK_EQUAL (player->content_video_to_dcp(piece, 0).get(), 0);
-       BOOST_CHECK_EQUAL (player->content_video_to_dcp(piece, 15).get(), DCPTime::from_seconds(0.6).get());
-       BOOST_CHECK_EQUAL (player->content_video_to_dcp(piece, 75).get(), DCPTime::from_seconds(3.0).get());
+       BOOST_CHECK_EQUAL (piece->content_video_to_dcp(0).get(), 0);
+       BOOST_CHECK_EQUAL (piece->content_video_to_dcp(15).get(), DCPTime::from_seconds(0.6).get());
+       BOOST_CHECK_EQUAL (piece->content_video_to_dcp(75).get(), DCPTime::from_seconds(3.0).get());
 
        /* Position 3s, no trim, content rate 24, DCP rate 25 */
        content->set_position (film, DCPTime::from_seconds(3));
@@ -252,9 +252,9 @@ BOOST_AUTO_TEST_CASE (player_time_calculation_test2)
        player->setup_pieces ();
        BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
        piece = player->_pieces.front ();
-       BOOST_CHECK_EQUAL (player->content_video_to_dcp(piece, 0).get(), DCPTime::from_seconds(3.00).get());
-       BOOST_CHECK_EQUAL (player->content_video_to_dcp(piece, 40).get(), DCPTime::from_seconds(4.60).get());
-       BOOST_CHECK_EQUAL (player->content_video_to_dcp(piece, 169).get(), DCPTime::from_seconds(9.76).get());
+       BOOST_CHECK_EQUAL (piece->content_video_to_dcp(0).get(), DCPTime::from_seconds(3.00).get());
+       BOOST_CHECK_EQUAL (piece->content_video_to_dcp(40).get(), DCPTime::from_seconds(4.60).get());
+       BOOST_CHECK_EQUAL (piece->content_video_to_dcp(169).get(), DCPTime::from_seconds(9.76).get());
 
        /* Position 3s, 1.6s trim, content rate 24, DCP rate 25, so the 1.6s trim is at 24fps */
        content->set_position (film, DCPTime::from_seconds(3));
@@ -264,10 +264,10 @@ BOOST_AUTO_TEST_CASE (player_time_calculation_test2)
        player->setup_pieces ();
        BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
        piece = player->_pieces.front ();
-       BOOST_CHECK_EQUAL (player->content_video_to_dcp(piece, 0).get(), 142080);
-       BOOST_CHECK_EQUAL (player->content_video_to_dcp(piece, 40).get(), 295680);
-       BOOST_CHECK_EQUAL (player->content_video_to_dcp(piece, 80).get(), 449280);
-       BOOST_CHECK_EQUAL (player->content_video_to_dcp(piece, 209).get(), 944640);
+       BOOST_CHECK_EQUAL (piece->content_video_to_dcp(0).get(), 142080);
+       BOOST_CHECK_EQUAL (piece->content_video_to_dcp(40).get(), 295680);
+       BOOST_CHECK_EQUAL (piece->content_video_to_dcp(80).get(), 449280);
+       BOOST_CHECK_EQUAL (piece->content_video_to_dcp(209).get(), 944640);
 
        /* Position 0, no trim, content rate 24, DCP rate 48
           Now, for example, a DCPTime position of 3s means 3s at 48fps.  Since we run the video
@@ -282,9 +282,9 @@ BOOST_AUTO_TEST_CASE (player_time_calculation_test2)
        player->setup_pieces ();
        BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
        piece = player->_pieces.front ();
-       BOOST_CHECK_EQUAL (player->content_video_to_dcp(piece, 0).get(), 0);
-       BOOST_CHECK_EQUAL (player->content_video_to_dcp(piece, 12).get(), DCPTime::from_seconds(0.5).get());
-       BOOST_CHECK_EQUAL (player->content_video_to_dcp(piece, 72).get(), DCPTime::from_seconds(3.0).get());
+       BOOST_CHECK_EQUAL (piece->content_video_to_dcp(0).get(), 0);
+       BOOST_CHECK_EQUAL (piece->content_video_to_dcp(12).get(), DCPTime::from_seconds(0.5).get());
+       BOOST_CHECK_EQUAL (piece->content_video_to_dcp(72).get(), DCPTime::from_seconds(3.0).get());
 
        /* Position 3s, no trim, content rate 24, DCP rate 48 */
        content->set_position (film, DCPTime::from_seconds(3));
@@ -294,9 +294,9 @@ BOOST_AUTO_TEST_CASE (player_time_calculation_test2)
        player->setup_pieces ();
        BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
        piece = player->_pieces.front ();
-       BOOST_CHECK_EQUAL (player->content_video_to_dcp(piece, 0).get(), DCPTime::from_seconds(3.00).get());
-       BOOST_CHECK_EQUAL (player->content_video_to_dcp(piece, 36).get(), DCPTime::from_seconds(4.50).get());
-       BOOST_CHECK_EQUAL (player->content_video_to_dcp(piece, 162).get(), DCPTime::from_seconds(9.75).get());
+       BOOST_CHECK_EQUAL (piece->content_video_to_dcp(0).get(), DCPTime::from_seconds(3.00).get());
+       BOOST_CHECK_EQUAL (piece->content_video_to_dcp(36).get(), DCPTime::from_seconds(4.50).get());
+       BOOST_CHECK_EQUAL (piece->content_video_to_dcp(162).get(), DCPTime::from_seconds(9.75).get());
 
        /* Position 3s, 1.5s trim, content rate 24, DCP rate 48 */
        content->set_position (film, DCPTime::from_seconds(3));
@@ -306,10 +306,10 @@ BOOST_AUTO_TEST_CASE (player_time_calculation_test2)
        player->setup_pieces ();
        BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
        piece = player->_pieces.front ();
-       BOOST_CHECK_EQUAL (player->content_video_to_dcp(piece, 0).get(), DCPTime::from_seconds(1.50).get());
-       BOOST_CHECK_EQUAL (player->content_video_to_dcp(piece, 36).get(), DCPTime::from_seconds(3.00).get());
-       BOOST_CHECK_EQUAL (player->content_video_to_dcp(piece, 72).get(), DCPTime::from_seconds(4.50).get());
-       BOOST_CHECK_EQUAL (player->content_video_to_dcp(piece, 198).get(), DCPTime::from_seconds(9.75).get());
+       BOOST_CHECK_EQUAL (piece->content_video_to_dcp(0).get(), DCPTime::from_seconds(1.50).get());
+       BOOST_CHECK_EQUAL (piece->content_video_to_dcp(36).get(), DCPTime::from_seconds(3.00).get());
+       BOOST_CHECK_EQUAL (piece->content_video_to_dcp(72).get(), DCPTime::from_seconds(4.50).get());
+       BOOST_CHECK_EQUAL (piece->content_video_to_dcp(198).get(), DCPTime::from_seconds(9.75).get());
 
        /* Position 0, no trim, content rate 48, DCP rate 24
           Now, for example, a DCPTime position of 3s means 3s at 24fps.  Since we run the video
@@ -323,9 +323,9 @@ BOOST_AUTO_TEST_CASE (player_time_calculation_test2)
        player->setup_pieces ();
        BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
        piece = player->_pieces.front ();
-       BOOST_CHECK_EQUAL (player->content_video_to_dcp(piece, 0).get(), 0);
-       BOOST_CHECK_EQUAL (player->content_video_to_dcp(piece, 24).get(), DCPTime::from_seconds(0.5).get());
-       BOOST_CHECK_EQUAL (player->content_video_to_dcp(piece, 144).get(), DCPTime::from_seconds(3.0).get());
+       BOOST_CHECK_EQUAL (piece->content_video_to_dcp(0).get(), 0);
+       BOOST_CHECK_EQUAL (piece->content_video_to_dcp(24).get(), DCPTime::from_seconds(0.5).get());
+       BOOST_CHECK_EQUAL (piece->content_video_to_dcp(144).get(), DCPTime::from_seconds(3.0).get());
 
        /* Position 3s, no trim, content rate 24, DCP rate 48 */
        content->set_position (film, DCPTime::from_seconds(3));
@@ -335,9 +335,9 @@ BOOST_AUTO_TEST_CASE (player_time_calculation_test2)
        player->setup_pieces ();
        BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
        piece = player->_pieces.front ();
-       BOOST_CHECK_EQUAL (player->content_video_to_dcp(piece, 0).get(), DCPTime::from_seconds(3.00).get());
-       BOOST_CHECK_EQUAL (player->content_video_to_dcp(piece, 72).get(), DCPTime::from_seconds(4.50).get());
-       BOOST_CHECK_EQUAL (player->content_video_to_dcp(piece, 324).get(), DCPTime::from_seconds(9.75).get());
+       BOOST_CHECK_EQUAL (piece->content_video_to_dcp(0).get(), DCPTime::from_seconds(3.00).get());
+       BOOST_CHECK_EQUAL (piece->content_video_to_dcp(72).get(), DCPTime::from_seconds(4.50).get());
+       BOOST_CHECK_EQUAL (piece->content_video_to_dcp(324).get(), DCPTime::from_seconds(9.75).get());
 
        /* Position 3s, 1.5s trim, content rate 24, DCP rate 48 */
        content->set_position (film, DCPTime::from_seconds(3));
@@ -347,9 +347,9 @@ BOOST_AUTO_TEST_CASE (player_time_calculation_test2)
        player->setup_pieces ();
        BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
        piece = player->_pieces.front ();
-       BOOST_CHECK_EQUAL (player->content_video_to_dcp(piece, 0).get(), DCPTime::from_seconds(1.50).get());
-       BOOST_CHECK_EQUAL (player->content_video_to_dcp(piece, 72).get(), DCPTime::from_seconds(3.00).get());
-       BOOST_CHECK_EQUAL (player->content_video_to_dcp(piece, 144).get(), DCPTime::from_seconds(4.50).get());
-       BOOST_CHECK_EQUAL (player->content_video_to_dcp(piece, 396).get(), DCPTime::from_seconds(9.75).get());
+       BOOST_CHECK_EQUAL (piece->content_video_to_dcp(0).get(), DCPTime::from_seconds(1.50).get());
+       BOOST_CHECK_EQUAL (piece->content_video_to_dcp(72).get(), DCPTime::from_seconds(3.00).get());
+       BOOST_CHECK_EQUAL (piece->content_video_to_dcp(144).get(), DCPTime::from_seconds(4.50).get());
+       BOOST_CHECK_EQUAL (piece->content_video_to_dcp(396).get(), DCPTime::from_seconds(9.75).get());
 }