From a0d1dd5d91c81ec9907cbc7b890905c463c18f62 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 28 Jul 2015 17:53:27 +0100 Subject: [PATCH] Replace Time::frames with Time::frames_round and Time::frames_floor. I believe both are necessary; doing floor instead of round caused #648. --- src/lib/analyse_audio_job.cc | 2 +- src/lib/audio_decoder_stream.cc | 4 ++-- src/lib/dcp_decoder.cc | 4 ++-- src/lib/dcpomatic_time.h | 9 +++++++-- src/lib/ffmpeg_examiner.cc | 2 +- src/lib/image_decoder.cc | 2 +- src/lib/player.cc | 14 +++++++++----- src/lib/sndfile_decoder.cc | 2 +- src/lib/transcode_job.cc | 2 +- src/lib/video_decoder.cc | 2 +- src/lib/writer.cc | 2 +- src/wx/timing_panel.cc | 2 +- src/wx/video_panel.cc | 4 ++-- test/audio_decoder_test.cc | 2 +- test/dcpomatic_time_test.cc | 3 +-- test/seek_zero_test.cc | 2 +- 16 files changed, 33 insertions(+), 25 deletions(-) diff --git a/src/lib/analyse_audio_job.cc b/src/lib/analyse_audio_job.cc index 2f48d12a9..e997c03c5 100644 --- a/src/lib/analyse_audio_job.cc +++ b/src/lib/analyse_audio_job.cc @@ -66,7 +66,7 @@ AnalyseAudioJob::run () shared_ptr player (new Player (_film, _playlist)); player->set_ignore_video (); - int64_t const len = _playlist->length().frames (_film->audio_frame_rate()); + int64_t const len = _playlist->length().frames_round (_film->audio_frame_rate()); _samples_per_point = max (int64_t (1), len / _num_points); _current.resize (_film->audio_channels ()); diff --git a/src/lib/audio_decoder_stream.cc b/src/lib/audio_decoder_stream.cc index fdcebbc9f..36274b502 100644 --- a/src/lib/audio_decoder_stream.cc +++ b/src/lib/audio_decoder_stream.cc @@ -145,7 +145,7 @@ AudioDecoderStream::audio (shared_ptr data, ContentTime time if (_seek_reference) { /* We've had an accurate seek and now we're seeing some data */ ContentTime const delta = time - _seek_reference.get (); - Frame const delta_frames = delta.frames (frame_rate); + Frame const delta_frames = delta.frames_round (frame_rate); if (delta_frames > 0) { /* This data comes after the seek time. Pad the data with some silence. */ shared_ptr padded (new AudioBuffers (data->channels(), data->frames() + delta_frames)); @@ -172,7 +172,7 @@ AudioDecoderStream::audio (shared_ptr data, ContentTime time } if (!_position) { - _position = time.frames (frame_rate); + _position = time.frames_round (frame_rate); } DCPOMATIC_ASSERT (_position.get() >= (_decoded.frame + _decoded.audio->frames())); diff --git a/src/lib/dcp_decoder.cc b/src/lib/dcp_decoder.cc index 44450f7d9..053ff4f68 100644 --- a/src/lib/dcp_decoder.cc +++ b/src/lib/dcp_decoder.cc @@ -64,7 +64,7 @@ DCPDecoder::pass () } double const vfr = _dcp_content->video_frame_rate (); - int64_t const frame = _next.frames (vfr); + int64_t const frame = _next.frames_round (vfr); if ((*_reel)->main_picture ()) { shared_ptr asset = (*_reel)->main_picture()->asset (); @@ -127,7 +127,7 @@ DCPDecoder::pass () _next += ContentTime::from_frames (1, vfr); if ((*_reel)->main_picture ()) { - if (_next.frames (vfr) >= (*_reel)->main_picture()->duration()) { + if (_next.frames_round (vfr) >= (*_reel)->main_picture()->duration()) { ++_reel; } } diff --git a/src/lib/dcpomatic_time.h b/src/lib/dcpomatic_time.h index 41339d128..c1d27407a 100644 --- a/src/lib/dcpomatic_time.h +++ b/src/lib/dcpomatic_time.h @@ -132,7 +132,12 @@ public: } template - int64_t frames (T r) const { + int64_t frames_round (T r) const { + return llrint (_t * r / HZ); + } + + template + int64_t frames_floor (T r) const { return floor (_t * r / HZ); } @@ -143,7 +148,7 @@ public: /* Do this calculation with frames so that we can round to a frame boundary at the start rather than the end. */ - int64_t ff = frames (r); + int64_t ff = frames_round (r); h = ff / (3600 * r); ff -= h * 3600 * r; diff --git a/src/lib/ffmpeg_examiner.cc b/src/lib/ffmpeg_examiner.cc index bcc5a86a6..78d97d21e 100644 --- a/src/lib/ffmpeg_examiner.cc +++ b/src/lib/ffmpeg_examiner.cc @@ -139,7 +139,7 @@ FFmpegExaminer::video_packet (AVCodecContext* context) if (_need_video_length) { _video_length = frame_time ( _format_context->streams[_video_stream] - ).get_value_or (ContentTime ()).frames (video_frame_rate().get ()); + ).get_value_or (ContentTime ()).frames_round (video_frame_rate().get ()); } } } diff --git a/src/lib/image_decoder.cc b/src/lib/image_decoder.cc index 3d543eaf2..db7c5401f 100644 --- a/src/lib/image_decoder.cc +++ b/src/lib/image_decoder.cc @@ -71,5 +71,5 @@ void ImageDecoder::seek (ContentTime time, bool accurate) { VideoDecoder::seek (time, accurate); - _video_position = time.frames (_image_content->video_frame_rate ()); + _video_position = time.frames_round (_image_content->video_frame_rate ()); } diff --git a/src/lib/player.cc b/src/lib/player.cc index e73481107..147f08ae8 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -431,7 +431,7 @@ Player::get_audio (DCPTime time, DCPTime length, bool accurate) setup_pieces (); } - Frame const length_frames = length.frames (_film->audio_frame_rate ()); + Frame const length_frames = length.frames_round (_film->audio_frame_rate ()); shared_ptr audio (new AudioBuffers (_film->audio_channels(), length_frames)); audio->make_silent (); @@ -457,7 +457,7 @@ Player::get_audio (DCPTime time, DCPTime length, bool accurate) the stuff we get back. */ offset = -request; - request_frames += request.frames (_film->audio_frame_rate ()); + request_frames += request.frames_round (_film->audio_frame_rate ()); if (request_frames < 0) { request_frames = 0; } @@ -509,7 +509,7 @@ Player::get_audio (DCPTime time, DCPTime length, bool accurate) audio->accumulate_frames ( all.audio.get(), content_frame - all.frame, - offset.frames (_film->audio_frame_rate()), + offset.frames_round (_film->audio_frame_rate()), min (Frame (all.audio->frames()), request_frames) ); } @@ -524,7 +524,10 @@ 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); - return max (ContentTime (), ContentTime (s, piece->frc) + piece->content->trim_start ()).frames (vc->video_frame_rate ()); + /* 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 + */ + return max (ContentTime (), ContentTime (s, piece->frc) + piece->content->trim_start ()).frames_floor (vc->video_frame_rate ()); } DCPTime @@ -540,7 +543,8 @@ Player::dcp_to_resampled_audio (shared_ptr piece, DCPTime t) const { DCPTime s = t - piece->content->position (); s = min (piece->content->length_after_trim(), s); - return max (DCPTime (), DCPTime (piece->content->trim_start (), piece->frc) + s).frames (_film->audio_frame_rate ()); + /* See notes in dcp_to_content_video */ + return max (DCPTime (), DCPTime (piece->content->trim_start (), piece->frc) + s).frames_floor (_film->audio_frame_rate ()); } ContentTime diff --git a/src/lib/sndfile_decoder.cc b/src/lib/sndfile_decoder.cc index 2fa9ae2a3..b2d35f302 100644 --- a/src/lib/sndfile_decoder.cc +++ b/src/lib/sndfile_decoder.cc @@ -98,6 +98,6 @@ SndfileDecoder::seek (ContentTime t, bool accurate) { AudioDecoder::seek (t, accurate); - _done = t.frames (_info.samplerate); + _done = t.frames_round (_info.samplerate); _remaining = _info.frames - _done; } diff --git a/src/lib/transcode_job.cc b/src/lib/transcode_job.cc index 4a2d768f4..122f7f799 100644 --- a/src/lib/transcode_job.cc +++ b/src/lib/transcode_job.cc @@ -123,5 +123,5 @@ TranscodeJob::remaining_time () const } /* Compute approximate proposed length here, as it's only here that we need it */ - return (_film->length().frames (_film->video_frame_rate ()) - t->video_frames_out()) / fps; + return (_film->length().frames_round (_film->video_frame_rate ()) - t->video_frames_out()) / fps; } diff --git a/src/lib/video_decoder.cc b/src/lib/video_decoder.cc index 944b1b695..2b9b13689 100644 --- a/src/lib/video_decoder.cc +++ b/src/lib/video_decoder.cc @@ -278,7 +278,7 @@ VideoDecoder::video (shared_ptr image, Frame frame) boost::optional to; if (_decoded_video.empty() && _last_seek_time && _last_seek_accurate) { - from = _last_seek_time->frames (_video_content->video_frame_rate ()); + from = _last_seek_time->frames_round (_video_content->video_frame_rate ()); to = to_push.front().frame; } else if (!_decoded_video.empty ()) { from = _decoded_video.back().frame + 1; diff --git a/src/lib/writer.cc b/src/lib/writer.cc index ff6e4f63c..863b49959 100644 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@ -396,7 +396,7 @@ try shared_ptr job = _job.lock (); DCPOMATIC_ASSERT (job); - int64_t total = _film->length().frames (_film->video_frame_rate ()); + int64_t total = _film->length().frames_round (_film->video_frame_rate ()); if (_film->three_d ()) { /* _full_written and so on are incremented for each eye, so we need to double the total frames to get the correct progress. diff --git a/src/wx/timing_panel.cc b/src/wx/timing_panel.cc index f92505c33..53e109224 100644 --- a/src/wx/timing_panel.cc +++ b/src/wx/timing_panel.cc @@ -296,7 +296,7 @@ TimingPanel::full_length_changed () shared_ptr ic = dynamic_pointer_cast (*i); if (ic && ic->still ()) { int const vfr = _parent->film()->video_frame_rate (); - ic->set_video_length (_full_length->get (vfr).frames (vfr)); + ic->set_video_length (_full_length->get (vfr).frames_round (vfr)); } } } diff --git a/src/wx/video_panel.cc b/src/wx/video_panel.cc index aa8e946da..68ff7c369 100644 --- a/src/wx/video_panel.cc +++ b/src/wx/video_panel.cc @@ -426,7 +426,7 @@ VideoPanel::fade_in_changed () VideoContentList vc = _parent->selected_video (); for (VideoContentList::const_iterator i = vc.begin(); i != vc.end(); ++i) { int const vfr = _parent->film()->video_frame_rate (); - (*i)->set_fade_in (_fade_in->get (vfr).frames (vfr)); + (*i)->set_fade_in (_fade_in->get (vfr).frames_round (vfr)); } } @@ -436,6 +436,6 @@ VideoPanel::fade_out_changed () VideoContentList vc = _parent->selected_video (); for (VideoContentList::const_iterator i = vc.begin(); i != vc.end(); ++i) { int const vfr = _parent->film()->video_frame_rate (); - (*i)->set_fade_out (_fade_out->get (vfr).frames (vfr)); + (*i)->set_fade_out (_fade_out->get (vfr).frames_round (vfr)); } } diff --git a/test/audio_decoder_test.cc b/test/audio_decoder_test.cc index 6816c1fbb..8af5dfb11 100644 --- a/test/audio_decoder_test.cc +++ b/test/audio_decoder_test.cc @@ -87,7 +87,7 @@ public: void seek (ContentTime t, bool accurate) { AudioDecoder::seek (t, accurate); - _position = t.frames (_test_audio_content->resampled_audio_frame_rate ()); + _position = t.frames_round (_test_audio_content->resampled_audio_frame_rate ()); } private: diff --git a/test/dcpomatic_time_test.cc b/test/dcpomatic_time_test.cc index 4462ae870..2b42d22b8 100644 --- a/test/dcpomatic_time_test.cc +++ b/test/dcpomatic_time_test.cc @@ -28,8 +28,7 @@ BOOST_AUTO_TEST_CASE (dcpomatic_time_test) for (int64_t i = 0; i < 62000; i += 2000) { DCPTime d (i); ContentTime c (d, frc); - std::cout << i << " " << d << " " << c << " " << c.frames (24.0) << " " << j << "\n"; - BOOST_CHECK_EQUAL (c.frames (24.0), j); + BOOST_CHECK_EQUAL (c.frames_floor (24.0), j); ++k; if (k == 2) { ++j; diff --git a/test/seek_zero_test.cc b/test/seek_zero_test.cc index 7f661b21c..5f870ba41 100644 --- a/test/seek_zero_test.cc +++ b/test/seek_zero_test.cc @@ -57,7 +57,7 @@ BOOST_AUTO_TEST_CASE (seek_zero_test) video_delay = ContentTime (); } - Frame const first_frame = video_delay.round_up (content->video_frame_rate ()).frames (content->video_frame_rate ()); + Frame const first_frame = video_delay.round_up (content->video_frame_rate ()).frames_round (content->video_frame_rate ()); FFmpegDecoder decoder (content, film->log()); list a = decoder.get_video (first_frame, true); -- 2.30.2