Missed update to private test repo version.
[dcpomatic.git] / src / lib / decoder.cc
1 /*
2     Copyright (C) 2012-2021 Carl Hetherington <cth@carlh.net>
3
4     This file is part of DCP-o-matic.
5
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.
10
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.
15
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/>.
18
19 */
20
21
22 #include "decoder.h"
23 #include "video_decoder.h"
24 #include "audio_decoder.h"
25 #include "text_decoder.h"
26 #include <boost/optional.hpp>
27 #include <iostream>
28
29
30 using std::cout;
31 using boost::optional;
32 using std::shared_ptr;
33 using std::weak_ptr;
34 using namespace dcpomatic;
35
36
37 Decoder::Decoder (weak_ptr<const Film> film)
38         : WeakConstFilm (film)
39 {
40
41 }
42
43
44 /** @return Earliest time of content that the next pass() will emit */
45 ContentTime
46 Decoder::position () const
47 {
48         optional<ContentTime> pos;
49         auto f = film();
50
51         if (video && !video->ignore() && (!pos || video->position(f).get_value_or(ContentTime()) < *pos)) {
52                 pos = video->position(f);
53         }
54
55         if (audio && !audio->ignore() && (!pos || audio->position(f).get_value_or(ContentTime()) < *pos)) {
56                 pos = audio->position(f);
57         }
58
59         /* Only decide position based on subtitle sources if there is nothing else
60            to go on.  Otherwise we can have problems with muxed sources which have
61            (for example) video, audio and a subtitle.  If the subtitle data runs out
62            before the video/audio the position() call will return the position of the
63            end of the subs.  This causes this file to be pass()ed in favour of others,
64            which can cause bugs like #1581.
65         */
66         if (!pos) {
67                 for (auto i: text) {
68                         if (!i->ignore() && (!pos || i->position(f) < *pos)) {
69                                 pos = i->position(f);
70                         }
71                 }
72         }
73
74         return pos.get_value_or(ContentTime());
75 }
76
77
78 void
79 Decoder::seek (ContentTime, bool)
80 {
81         if (video) {
82                 video->seek ();
83         }
84         if (audio) {
85                 audio->seek ();
86         }
87         for (auto i: text) {
88                 i->seek ();
89         }
90 }
91
92
93 shared_ptr<TextDecoder>
94 Decoder::only_text () const
95 {
96         DCPOMATIC_ASSERT (text.size() < 2);
97         if (text.empty()) {
98                 return {};
99         }
100         return text.front();
101 }