wip. 1771-resample-glitches-take2
authorCarl Hetherington <cth@carlh.net>
Tue, 23 Jun 2020 20:04:04 +0000 (22:04 +0200)
committerCarl Hetherington <cth@carlh.net>
Tue, 23 Jun 2020 20:04:04 +0000 (22:04 +0200)
src/lib/piece.cc
src/lib/piece.h
src/lib/player.cc

index 84d0968c24185c7ee5050adc93f6bebaf02824fc..3fd7444939131e2f40795bed59ee570173fb6498 100644 (file)
 #include "audio_content.h"
 #include "film.h"
 #include "piece.h"
+#include "text_content.h"
 
 
+using std::list;
+using std::vector;
 using boost::optional;
 using boost::shared_ptr;
 using namespace dcpomatic;
@@ -32,14 +35,14 @@ using namespace dcpomatic;
 DCPTime
 Piece::position () const
 {
-       return content->position ();
+       return _content->position ();
 }
 
 
 DCPTime
 Piece::end (shared_ptr<const Film> film) const
 {
-       return content->end (film);
+       return _content->end (film);
 }
 
 
@@ -53,7 +56,7 @@ Piece::content_video_to_dcp (Frame f) const
 
           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->trim_start(), frc);
+       DCPTime const d = DCPTime::from_frames(f * frc.factor(), frc.dcp) - DCPTime(_content->trim_start(), frc);
        return d + position();
 }
 
@@ -61,14 +64,50 @@ Piece::content_video_to_dcp (Frame f) const
 DCPTime
 Piece::content_time_to_dcp (ContentTime t) const
 {
-       return max (DCPTime(), DCPTime(t - content->trim_start(), frc) + position());
+       return max (DCPTime(), DCPTime(t - _content->trim_start(), frc) + position());
+}
+
+
+optional<DCPTime>
+Piece::content_time_to_dcp (shared_ptr<const Content> c, ContentTime t) const
+{
+       BOOST_FOREACH (shared_ptr<Content> i, _content) {
+               if (i == c) {
+                       return i->content_time_to_dcp (t);
+               }
+       }
+
+       return optional<DCPTime>();
+}
+
+
+ContentTime
+Piece::trim_start () const
+{
+       return _content[0]->trim_start ();
+}
+
+
+list<shared_ptr<Font> >
+Piece::fonts () const
+{
+       list<shared_ptr<Font> > fonts;
+       BOOST_FOREACH (shared_ptr<Content> i, _content) {
+               BOOST_FOREACH (shared_ptr<TextContent> j, i->text) {
+                       /* XXX: things may go wrong if there are duplicate font IDs
+                          with different font files.
+                       */
+                       list<shared_ptr<Font> > f = j->fonts ();
+                       copy (f.begin(), f.end(), back_inserter (fonts));
+               }
+       }
 }
 
 
 Crop
 Piece::video_crop () const
 {
-       return content->video->crop ();
+       return _content->video->crop ();
 }
 
 
@@ -77,7 +116,7 @@ Piece::resampled_audio_to_dcp (shared_ptr<const Film> film, Frame f) const
 {
        /* See notes in content_video_to_dcp */
        return DCPTime::from_frames(f, film->audio_frame_rate())
-               - DCPTime(content->trim_start(), frc)
+               - DCPTime(_content->trim_start(), frc)
                + position();
 }
 
@@ -86,56 +125,79 @@ ContentTime
 Piece::dcp_to_content_time (shared_ptr<const Film> film, DCPTime t) const
 {
        DCPTime s = t - position();
-       s = min(content->length_after_trim(film), s);
-       return max(ContentTime(), ContentTime(s, frc) + content->trim_start());
+       s = min(_content->length_after_trim(film), s);
+       return max(ContentTime(), ContentTime(s, frc) + _content->trim_start());
 }
 
 
 bool
 Piece::video_use () const
 {
-       return content->video->use();
+       return _content->video->use();
 }
 
 
 optional<double>
 Piece::video_fade (shared_ptr<const Film> film, Frame frame) const
 {
-       return content->video->fade (film, frame);
+       return _content->video->fade (film, frame);
 }
 
 
 dcp::Size
 Piece::video_scaled_size (dcp::Size container_size)
 {
-       return content->video->scaled_size(container_size);
+       return _content->video->scaled_size(container_size);
 }
 
 
 optional<ColourConversion>
 Piece::video_colour_conversion () const
 {
-       return content->video->colour_conversion();
+       return _content->video->colour_conversion();
 }
 
 
 VideoRange
 Piece::video_range () const
 {
-       return content->video->range();
+       return _content->video->range();
 }
 
 
 int
 Piece::audio_resampled_frame_rate (boost::shared_ptr<const Film> film) const
 {
-       return content->audio->resampled_frame_rate (film);
+       return _content->audio->resampled_frame_rate (film);
 }
 
 
 double
 Piece::audio_gain () const
 {
-       return content->audio->gain();
+       return _content->audio->gain();
+}
+
+
+vector<AudioStreamPtr>
+Piece::audio_streams () const
+{
+       vector<AudioStreamPtr> streams;
+       BOOST_FOREACH (shared_ptr<Content> i, _content) {
+               if (i->audio) {
+                       vector<AudioStreamPtr> s = i->audio->streams ();
+                       copy (s.begin(), s.end(), back_inserter(streams));
+               }
+       }
+
+       return streams;
+}
+
+
+bool
+Piece::referenced_audio () const
+{
+       shared_ptr<DCPContent> dcp = dynamic_pointer_cast<DCPContent>(_content[0]);
+       return dcp && dcp->reference_audio();
 }
 
index dd7867227dc4ef6ed403278e24ea67dc54ae01ab..df17feaa85a7a484b015c001aa267ede35c74743 100644 (file)
@@ -21,6 +21,7 @@
 #ifndef DCPOMATIC_PIECE_H
 #define DCPOMATIC_PIECE_H
 
+#include "audio_stream.h"
 #include "content.h"
 #include "dcpomatic_time.h"
 #include "frame_rate_change.h"
 
 class Content;
 class Decoder;
+namespace dcpomatic {
+       class Font;
+}
 
 class Piece
 {
 public:
        Piece (boost::shared_ptr<Content> c, boost::shared_ptr<Decoder> d, FrameRateChange f)
-               : content (c)
-               , decoder (d)
+               : decoder (d)
                , frc (f)
                , done (false)
+               , _content (c)
        {}
 
        dcpomatic::DCPTime position () const;
        dcpomatic::DCPTime end (boost::shared_ptr<const Film> film) const;
        dcpomatic::DCPTime content_video_to_dcp (Frame f) const;
        dcpomatic::DCPTime content_time_to_dcp (dcpomatic::ContentTime t) const;
+       boost::optional<dcpomatic::DCPTime> content_time_to_dcp (boost::shared_ptr<const Content> content, dcpomatic::ContentTime t);
        dcpomatic::DCPTime resampled_audio_to_dcp (boost::shared_ptr<const Film> film, Frame f) const;
        dcpomatic::ContentTime dcp_to_content_time (boost::shared_ptr<const Film> film, dcpomatic::DCPTime t) const;
 
+       dcpomatic::ContentTime trim_start () const;
+       std::list<boost::shared_ptr<dcpomatic::Font> > fonts () const;
+       bool referenced_audio () const;
+
        Crop video_crop () const;
        bool video_use () const;
        boost::optional<double> video_fade (boost::shared_ptr<const Film> film, Frame frame) const;
@@ -56,11 +65,14 @@ public:
 
        int audio_resampled_frame_rate (boost::shared_ptr<const Film> film) const;
        double audio_gain () const;
+       std::vector<AudioStreamPtr> audio_streams () const;
 
-       boost::shared_ptr<Content> content;
        boost::shared_ptr<Decoder> decoder;
        FrameRateChange frc;
        bool done;
+
+private:
+       boost::shared_ptr<Content> _content;
 };
 
 #endif
index fbf3c2674fce1581857b5f545723e8eb673599b3..9577f5afacae2168da99262c74105bd629739c57 100644 (file)
@@ -186,12 +186,14 @@ Player::setup_pieces_unlocked ()
                }
 
                shared_ptr<Decoder> old_decoder;
+               /* XXX
                BOOST_FOREACH (shared_ptr<Piece> j, old_pieces) {
                        if (j->content == i) {
                                old_decoder = j->decoder;
                                break;
                        }
                }
+               */
 
                shared_ptr<Decoder> decoder = decoder_factory (_film, i, _fast, _tolerant, old_decoder);
                DCPOMATIC_ASSERT (decoder);
@@ -259,10 +261,8 @@ Player::setup_pieces_unlocked ()
 
        _stream_states.clear ();
        BOOST_FOREACH (shared_ptr<Piece> i, _pieces) {
-               if (i->content->audio) {
-                       BOOST_FOREACH (AudioStreamPtr j, i->content->audio->streams()) {
-                               _stream_states[j] = StreamState (i, i->content->position ());
-                       }
+               BOOST_FOREACH (AudioStreamPtr j, i->audio_streams()) {
+                       _stream_states[j] = StreamState (i, i->content->position ());
                }
        }
 
@@ -386,13 +386,11 @@ Player::get_subtitle_fonts ()
 
        list<shared_ptr<Font> > fonts;
        BOOST_FOREACH (shared_ptr<Piece> i, _pieces) {
-               BOOST_FOREACH (shared_ptr<TextContent> j, i->content->text) {
-                       /* XXX: things may go wrong if there are duplicate font IDs
-                          with different font files.
-                       */
-                       list<shared_ptr<Font> > f = j->fonts ();
-                       copy (f.begin(), f.end(), back_inserter (fonts));
-               }
+               /* XXX: things may go wrong if there are duplicate font IDs
+                  with different font files.
+                  */
+               list<shared_ptr<Font> > f = i->fonts ();
+               copy (f.begin(), f.end(), back_inserter(fonts));
        }
 
        return fonts;
@@ -558,7 +556,7 @@ Player::pass ()
                        continue;
                }
 
-               DCPTime const t = i->content_time_to_dcp (max(i->decoder->position(), i->content->trim_start()));
+               DCPTime const t = i->content_time_to_dcp (max(i->decoder->position(), i->trim_start()));
                if (t > i->end(_film)) {
                        i->done = true;
                } else {
@@ -600,13 +598,12 @@ Player::pass ()
        case CONTENT:
        {
                earliest_content->done = earliest_content->decoder->pass ();
-               shared_ptr<DCPContent> dcp = dynamic_pointer_cast<DCPContent>(earliest_content->content);
-               if (dcp && !_play_referenced && dcp->reference_audio()) {
+               if (!_play_referenced && earliest_content->referenced_audio()) {
                        /* We are skipping some referenced DCP audio content, so we need to update _last_audio_time
                           to `hide' the fact that no audio was emitted during the referenced DCP (though
                           we need to behave as though it was).
                        */
-                       _last_audio_time = dcp->end (_film);
+                       _last_audio_time = earliest_content->end (_film);
                }
                break;
        }
@@ -1041,15 +1038,15 @@ Player::seek (DCPTime time, bool accurate)
        }
 
        BOOST_FOREACH (shared_ptr<Piece> i, _pieces) {
-               if (time < i->content->position()) {
+               if (time < i->position()) {
                        /* Before; seek to the start of the content.  Even if this request is for an inaccurate seek
                           we must seek this (following) content accurately, otherwise when we come to the end of the current
                           content we may not start right at the beginning of the next, causing a gap (if the next content has
                           been trimmed to a point between keyframes, or something).
                        */
-                       i->decoder->seek (i->dcp_to_content_time(_film, i->content->position()), true);
+                       i->decoder->seek (i->dcp_to_content_time(_film, i->position()), true);
                        i->done = false;
-               } else if (i->content->position() <= time && time < i->end(_film)) {
+               } else if (i->position() <= time && time < i->end(_film)) {
                        /* During; seek to position */
                        i->decoder->seek (i->dcp_to_content_time(_film, time), accurate);
                        i->done = false;
@@ -1196,8 +1193,9 @@ Player::content_time_to_dcp (shared_ptr<Content> content, ContentTime t)
        boost::mutex::scoped_lock lm (_mutex);
 
        BOOST_FOREACH (shared_ptr<Piece> i, _pieces) {
-               if (i->content == content) {
-                       return i->content_time_to_dcp (t);
+               optional<DCPTime> d = i->content_time_to_dcp (t);
+               if (d) {
+                       return d;
                }
        }