From 837bace2d4794976b004325983ca6f425cfdba41 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 23 Jun 2020 23:03:08 +0200 Subject: [PATCH] Oops: commit piece.cc. --- src/lib/piece.cc | 169 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 src/lib/piece.cc diff --git a/src/lib/piece.cc b/src/lib/piece.cc new file mode 100644 index 000000000..a34b39901 --- /dev/null +++ b/src/lib/piece.cc @@ -0,0 +1,169 @@ +/* + Copyright (C) 2013-2020 Carl Hetherington + + This file is part of DCP-o-matic. + + DCP-o-matic is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + DCP-o-matic is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with DCP-o-matic. If not, see . + +*/ + + +#include "audio_stream.h" +#include "content.h" +#include "piece.h" +#include + + +using std::copy; +using std::list; +using boost::shared_ptr; + + +Piece::Piece (shared_ptr c, shared_ptr d, FrameRateChange f) + : _frc (f) + , _done (false) +{ + _content.push_back (c); + _decoder.push_back (d); + + if (c->audio) { + BOOST_FOREACH (AudioStreamPtr i, c->audio->streams()) { + _stream_last_push_end[i] = c->position(); + } + } +} + + +void +Piece::update_pull_to (DCPTime& pull_to) const +{ + if (_done) { + return; + } + + for (map::const_iterator i = _stream_last_push_end.begin(); i != _stream_last_push_end.end(); ++i) { + if (i->second < pull_to) { + pull_to = i->second; + } + } +} + + +void +Piece::set_last_push_end (AudioStreamPtr stream, DCPTime end) +{ + DCPOMATIC_ASSERT (_stream_last_push_end.find(stream) != _stream_last_push_end.end()); + _stream_last_push_end[stream] = end; +} + + +DCPTime +Piece::position () const +{ + return _content[0]->position(); +} + + +DCPTime +Piece::end (shared_ptr film) const +{ + return _content[0]->end(film); +} + + +DCPTime +Piece::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. + */ + + DCPTime const d = DCPTime::from_frames(f * _frc.factor(), _frc.dcp) - DCPTime(_content[0]->trim_start(), _frc); + return d + position(); +} + + +DCPTime +Piece::resampled_audio_to_dcp (shared_ptr film, Frame f) const +{ + /* See comment in dcp_to_content_video */ + return DCPTime::from_frames(f, film->audio_frame_rate()) - DCPTime(_content[0]->trim_start(), frc) + position(); +} + + +ContentTime +Piece::dcp_to_content_time (shared_ptr film, DCPTime t) const +{ + DCPTime s = t - position(); + s = min (_content[0]->length_after_trim(_film), s); + return max (ContentTime(), ContentTime(s, _frc) + _content[0]->trim_start()); +} + + +DCPTime +Piece::content_time_to_dcp (ContentTime t) const +{ + return max (DCPTime(), DCPTime(t - _content[0]->trim_start(), _frc) + position()); +} + + +void +Piece::add_fonts (list >& fonts) const +{ + BOOST_FOREACH (shared_ptr i, _content) { + BOOST_FOREACH (shared_ptr j, i->text) { + /* XXX: things may go wrong if there are duplicate font IDs + with different font files. + */ + list > f = j->fonts (); + copy (f.begin(), f.end(), back_inserter(fonts)); + } + } +} + + +optional +Piece::position (shared_ptr film) +{ + if (_done) { + return optional(); + } + + DCPTime const t = content_time_to_dcp (max(_decoder[0]->position(), _content[0]->trim_start())); + if (t > end(film)) { + _done = true; + return optional(); + } + + return t; +} + + +bool +Piece::has_text () const +{ + return !_decoder[0].text.empty(); +} + + +void +Piece::pass () const +{ + _done = _decoder[0]->pass(); +} + -- 2.30.2