2 Copyright (C) 2013-2021 Carl Hetherington <cth@carlh.net>
4 This file is part of DCP-o-matic.
6 DCP-o-matic is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 DCP-o-matic is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
22 #include "audio_content.h"
24 #include "dcp_content.h"
25 #include "dcpomatic_log.h"
29 #include "player_video.h"
30 #include "video_content.h"
33 using std::dynamic_pointer_cast;
34 using std::make_shared;
35 using std::shared_ptr;
36 using boost::optional;
37 using namespace dcpomatic;
40 Piece::Piece (shared_ptr<Content> c, shared_ptr<Decoder> d, FrameRateChange f)
45 if (_content->audio) {
46 for (auto j: _content->audio->streams()) {
47 _stream_last_push_end[j] = _content->position();
55 Piece::update_pull_to (DCPTime& pull_to) const
61 for (auto const& i: _stream_last_push_end) {
62 pull_to = std::min(pull_to, i.second);
68 Piece::set_last_push_end (AudioStreamPtr stream, DCPTime end)
70 DCPOMATIC_ASSERT (_stream_last_push_end.find(stream) != _stream_last_push_end.end());
71 _stream_last_push_end[stream] = end;
76 Piece::content_video_to_dcp (Frame f) const
78 /* See comment in resampled_audio_to_dcp */
79 auto const d = DCPTime::from_frames(f * _frc.factor(), _frc.dcp) - DCPTime(_content->trim_start(), _frc);
80 return d + _content->position();
85 Piece::resampled_audio_to_dcp (Frame f, shared_ptr<const Film> film) const
87 /* It might seem more logical here to convert s to a ContentTime (using the FrameRateChange)
88 then convert that ContentTime to frames at the content's rate. However this fails for
89 situations like content at 29.9978733fps, DCP at 30fps. The accuracy of the Time type is not
90 enough to distinguish between the two with low values of time (e.g. 3200 in Time units).
92 Instead we convert the DCPTime using the DCP video rate then account for any skip/repeat.
94 return DCPTime::from_frames(f, film->audio_frame_rate())
95 - DCPTime(_content->trim_start(), _frc)
96 + _content->position();
101 Piece::dcp_to_content_time (DCPTime t, shared_ptr<const Film> film) const
103 auto s = t - _content->position ();
104 s = min (_content->length_after_trim(film), s);
105 return max (ContentTime(), ContentTime(s, _frc) + _content->trim_start());
110 Piece::content_time_to_dcp (shared_ptr<const Content> content, ContentTime t) const
112 if (_content != content) {
116 return max (DCPTime(), DCPTime(t - _content->trim_start(), _frc) + _content->position());
121 Piece::use_video () const
123 return _content->video && _content->video->use();
128 Piece::video_frame_type () const
130 DCPOMATIC_ASSERT (_content->video);
131 return _content->video->frame_type ();
136 Piece::position () const
138 return _content->position ();
143 Piece::end (shared_ptr<const Film> film) const
145 return _content->end (film);
149 shared_ptr<PlayerVideo>
150 Piece::player_video (ContentVideo video, shared_ptr<const Film> film, dcp::Size container_size) const
152 return std::make_shared<PlayerVideo>(
154 _content->video->crop (),
155 _content->video->fade (film, video.frame),
156 scale_for_display(_content->video->scaled_size(film->frame_size()), container_size, film->frame_size()),
160 _content->video->colour_conversion(),
161 _content->video->range(),
170 Piece::resampled_audio_frame_rate (shared_ptr<const Film> film) const
172 DCPOMATIC_ASSERT (_content->audio);
173 return _content->audio->resampled_frame_rate (film);
178 Piece::audio_gain () const
180 DCPOMATIC_ASSERT (_content->audio);
181 return _content->audio->gain();
186 Piece::decoder_for (shared_ptr<Content> content) const
188 if (content == _content) {
197 Piece::decoder_position () const
199 auto t = content_time_to_dcp(_content, std::max(decoder->position(), _content->trim_start()));
200 DCPOMATIC_ASSERT (t);
208 LOG_DEBUG_PLAYER ("Calling pass() on %1", _content->path(0));
209 done = decoder->pass();
214 Piece::reference_dcp_audio () const
216 auto dcp = dynamic_pointer_cast<DCPContent>(_content);
217 return dcp && dcp->reference_audio();
222 Piece::has_text () const
224 return !decoder->text.empty();