X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Flib%2Fplayer.cc;h=caa2791b8d573c3c2ad32efae0e9cd4239b56eb9;hb=ffdb290bcba1cb9a3e2e6768ee254629d696dd36;hp=3ceaac8c1b667fe39781dc027f5b21a2289e128e;hpb=bd0fbdae25424a491b30427443a0ce2b338522b8;p=dcpomatic.git diff --git a/src/lib/player.cc b/src/lib/player.cc index 3ceaac8c1..caa2791b8 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -293,8 +293,8 @@ Player::transform_image_subtitles (list subs) const true ), Position ( - rint (_video_container_size.width * i->rectangle.x), - rint (_video_container_size.height * i->rectangle.y) + lrint (_video_container_size.width * i->rectangle.x), + lrint (_video_container_size.height * i->rectangle.y) ) ) ); @@ -524,18 +524,25 @@ Player::dcp_to_content_video (shared_ptr piece, DCPTime t) const shared_ptr vc = dynamic_pointer_cast (piece->content); DCPTime s = t - piece->content->position (); s = min (piece->content->length_after_trim(), s); - /* We're returning a frame index here so we need to floor() the conversion since we want to know the frame - that contains t, I think + s = max (DCPTime(), s + DCPTime (piece->content->trim_start(), piece->frc)); + + /* 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. */ - return max (ContentTime (), ContentTime (s, piece->frc) + piece->content->trim_start ()).frames_floor (vc->video_frame_rate ()); + return s.frames_floor (piece->frc.dcp) / piece->frc.factor (); } DCPTime Player::content_video_to_dcp (shared_ptr piece, Frame f) const { shared_ptr vc = dynamic_pointer_cast (piece->content); - ContentTime const c = ContentTime::from_frames (f, vc->video_frame_rate ()) - piece->content->trim_start (); - return max (DCPTime (), DCPTime (c, piece->frc) + piece->content->position ()); + /* See comment in dcp_to_content_video */ + DCPTime const d = DCPTime::from_frames (f * piece->frc.factor(), piece->frc.dcp) - DCPTime (piece->content->trim_start (), piece->frc); + return max (DCPTime (), d + piece->content->position ()); } Frame