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