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 namespace dcpomatic;
39 Piece::Piece (shared_ptr<Content> c, shared_ptr<Decoder> d, FrameRateChange f)
45 for (auto j: content->audio->streams()) {
46 _stream_last_push_end[j] = content->position();
54 Piece::update_pull_to (DCPTime& pull_to) const
60 for (auto const& i: _stream_last_push_end) {
61 pull_to = std::min(pull_to, i.second);
67 Piece::set_last_push_end (AudioStreamPtr stream, DCPTime end)
69 DCPOMATIC_ASSERT (_stream_last_push_end.find(stream) != _stream_last_push_end.end());
70 _stream_last_push_end[stream] = end;
75 Piece::content_video_to_dcp (Frame f) const
77 /* See comment in resampled_audio_to_dcp */
78 auto const d = DCPTime::from_frames(f * frc.factor(), frc.dcp) - DCPTime(content->trim_start(), frc);
79 return d + content->position();
84 Piece::resampled_audio_to_dcp (Frame f, shared_ptr<const Film> film) const
86 /* It might seem more logical here to convert s to a ContentTime (using the FrameRateChange)
87 then convert that ContentTime to frames at the content's rate. However this fails for
88 situations like content at 29.9978733fps, DCP at 30fps. The accuracy of the Time type is not
89 enough to distinguish between the two with low values of time (e.g. 3200 in Time units).
91 Instead we convert the DCPTime using the DCP video rate then account for any skip/repeat.
93 return DCPTime::from_frames(f, film->audio_frame_rate())
94 - DCPTime(content->trim_start(), frc)
95 + content->position();
100 Piece::dcp_to_content_time (DCPTime t, shared_ptr<const Film> film) const
102 auto s = t - content->position ();
103 s = min (content->length_after_trim(film), s);
104 return max (ContentTime(), ContentTime(s, frc) + content->trim_start());
109 Piece::content_time_to_dcp (ContentTime t) const
111 return max (DCPTime(), DCPTime(t - content->trim_start(), frc) + content->position());
116 Piece::use_video () const
118 return content->video && content->video->use();
123 Piece::video_frame_type () const
125 DCPOMATIC_ASSERT (content->video);
126 return content->video->frame_type ();
131 Piece::position () const
133 return content->position ();
138 Piece::end (shared_ptr<const Film> film) const
140 return content->end (film);
144 shared_ptr<PlayerVideo>
145 Piece::player_video (ContentVideo video, shared_ptr<const Film> film, dcp::Size container_size) const
147 return std::make_shared<PlayerVideo>(
149 content->video->crop (),
150 content->video->fade (film, video.frame),
151 scale_for_display(content->video->scaled_size(film->frame_size()), container_size, film->frame_size()),
155 content->video->colour_conversion(),
156 content->video->range(),
165 Piece::resampled_audio_frame_rate (shared_ptr<const Film> film) const
167 DCPOMATIC_ASSERT (content->audio);
168 return content->audio->resampled_frame_rate (film);
173 Piece::audio_gain () const
175 DCPOMATIC_ASSERT (content->audio);
176 return content->audio->gain();
181 Piece::decoder_for (shared_ptr<Content> content_) const
183 if (content_ == content) {
192 Piece::decoder_position () const
194 return content_time_to_dcp(std::max(decoder->position(), content->trim_start()));
201 LOG_DEBUG_PLAYER ("Calling pass() on %1", content->path(0));
202 done = decoder->pass();
207 Piece::reference_dcp_audio () const
209 auto dcp = dynamic_pointer_cast<DCPContent>(content);
210 return dcp && dcp->reference_audio();