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 "lib/decoder_factory.h"
23 #include "lib/image_content.h"
24 #include "lib/piece.h"
25 #include "lib/piece_video.h"
26 #include "lib/shuffler.h"
28 #include <boost/test/unit_test.hpp>
32 using std::make_shared;
33 using std::shared_ptr;
35 using boost::optional;
36 #if BOOST_VERSION >= 106100
37 using namespace boost::placeholders;
42 push (Shuffler& s, shared_ptr<Film> film, shared_ptr<Content> content, shared_ptr<Decoder> decoder, int frame, Eyes eyes)
44 auto piece = make_shared<Piece>(film, content, decoder, FrameRateChange(24, 24), false);
51 list<PieceVideo> pending_cv;
54 receive (weak_ptr<Piece>, PieceVideo cv)
56 pending_cv.push_back (cv);
60 check (int frame, Eyes eyes, int line)
62 BOOST_REQUIRE_MESSAGE (!pending_cv.empty(), "Check at " << line << " failed.");
63 BOOST_CHECK_MESSAGE (pending_cv.front().frame == frame, "Check at " << line << " failed.");
64 BOOST_CHECK_MESSAGE (pending_cv.front().eyes == eyes, "Check at " << line << " failed.");
65 pending_cv.pop_front();
68 /** A perfect sequence */
69 BOOST_AUTO_TEST_CASE (shuffler_test1)
72 s.Video.connect (boost::bind (&receive, _1, _2));
74 auto film = new_test_film2 ("shuffler_test1");
75 auto content = make_shared<ImageContent>("test/data/flat_red.png");
76 auto decoder = decoder_factory (film, content, true, {});
77 BOOST_REQUIRE (decoder);
79 for (int i = 0; i < 10; ++i) {
80 push (s, film, content, decoder, i, Eyes::LEFT);
81 push (s, film, content, decoder, i, Eyes::RIGHT);
82 check (i, Eyes::LEFT, __LINE__);
83 check (i, Eyes::RIGHT, __LINE__);
87 /** Everything present but some simple shuffling needed */
88 BOOST_AUTO_TEST_CASE (shuffler_test2)
91 s.Video.connect (boost::bind (&receive, _1, _2));
93 auto film = new_test_film2 ("shuffler_test2");
94 auto content = make_shared<ImageContent>("test/data/flat_red.png");
95 auto decoder = decoder_factory (film, content, true, {});
97 for (int i = 0; i < 10; i += 2) {
98 push (s, film, content, decoder, i, Eyes::LEFT);
99 push (s, film, content, decoder, i + 1, Eyes::LEFT);
100 push (s, film, content, decoder, i, Eyes::RIGHT);
101 push (s, film, content, decoder, i + 1, Eyes::RIGHT);
102 check (i, Eyes::LEFT, __LINE__);
103 check (i, Eyes::RIGHT, __LINE__);
104 check (i + 1, Eyes::LEFT, __LINE__);
105 check (i + 1, Eyes::RIGHT, __LINE__);
109 /** One missing left eye image */
110 BOOST_AUTO_TEST_CASE (shuffler_test3)
113 s.Video.connect (boost::bind (&receive, _1, _2));
115 auto film = new_test_film2 ("shuffler_test3");
116 auto content = make_shared<ImageContent>("test/data/flat_red.png");
117 auto decoder = decoder_factory (film, content, true, {});
119 push (s, film, content, decoder, 0, Eyes::LEFT);
120 check (0, Eyes::LEFT, __LINE__);
121 push (s, film, content, decoder, 0, Eyes::RIGHT);
122 check (0, Eyes::RIGHT, __LINE__);
123 push (s, film, content, decoder, 1, Eyes::LEFT);
124 check (1, Eyes::LEFT, __LINE__);
125 push (s, film, content, decoder, 1, Eyes::RIGHT);
126 check (1, Eyes::RIGHT, __LINE__);
127 push (s, film, content, decoder, 2, Eyes::RIGHT);
128 push (s, film, content, decoder, 3, Eyes::LEFT);
129 push (s, film, content, decoder, 3, Eyes::RIGHT);
130 push (s, film, content, decoder, 4, Eyes::LEFT);
131 push (s, film, content, decoder, 4, Eyes::RIGHT);
133 check (2, Eyes::RIGHT, __LINE__);
134 check (3, Eyes::LEFT, __LINE__);
135 check (3, Eyes::RIGHT, __LINE__);
136 check (4, Eyes::LEFT, __LINE__);
137 check (4, Eyes::RIGHT, __LINE__);
140 /** One missing right eye image */
141 BOOST_AUTO_TEST_CASE (shuffler_test4)
144 s.Video.connect (boost::bind (&receive, _1, _2));
146 auto film = new_test_film2 ("shuffler_test3");
147 auto content = make_shared<ImageContent>("test/data/flat_red.png");
148 auto decoder = decoder_factory (film, content, true, {});
150 push (s, film, content, decoder, 0, Eyes::LEFT);
151 check (0, Eyes::LEFT, __LINE__);
152 push (s, film, content, decoder, 0, Eyes::RIGHT);
153 check (0, Eyes::RIGHT, __LINE__);
154 push (s, film, content, decoder, 1, Eyes::LEFT);
155 check (1, Eyes::LEFT, __LINE__);
156 push (s, film, content, decoder, 1, Eyes::RIGHT);
157 check (1, Eyes::RIGHT, __LINE__);
158 push (s, film, content, decoder, 2, Eyes::LEFT);
159 push (s, film, content, decoder, 3, Eyes::LEFT);
160 push (s, film, content, decoder, 3, Eyes::RIGHT);
161 push (s, film, content, decoder, 4, Eyes::LEFT);
162 push (s, film, content, decoder, 4, Eyes::RIGHT);
164 check (2, Eyes::LEFT, __LINE__);
165 check (3, Eyes::LEFT, __LINE__);
166 check (3, Eyes::RIGHT, __LINE__);
167 check (4, Eyes::LEFT, __LINE__);
168 check (4, Eyes::RIGHT, __LINE__);
172 BOOST_AUTO_TEST_CASE (shuffler_test5)
175 s.Video.connect (boost::bind (&receive, _1, _2));
177 auto film = new_test_film2 ("shuffler_test3");
178 auto content = make_shared<ImageContent>("test/data/flat_red.png");
179 auto decoder = decoder_factory (film, content, true, {});
181 /* One left should come out straight away */
182 push (s, film, content, decoder, 0, Eyes::LEFT);
183 check (0, Eyes::LEFT, __LINE__);
185 /* More lefts should be kept in the shuffler in the hope that some rights arrive */
186 for (int i = 0; i < s._max_size; ++i) {
187 push (s, film, content, decoder, i + 1, Eyes::LEFT);
189 BOOST_CHECK (pending_cv.empty ());
191 /* If enough lefts come the shuffler should conclude that there's no rights and start
192 giving out the lefts.
194 push (s, film, content, decoder, s._max_size + 1, Eyes::LEFT);
195 check (1, Eyes::LEFT, __LINE__);
198 /** One complete frame (L+R) missing.
199 Shuffler should carry on, skipping this frame, as the player will cope with it.
201 BOOST_AUTO_TEST_CASE (shuffler_test6)
204 s.Video.connect (boost::bind (&receive, _1, _2));
206 auto film = new_test_film2 ("shuffler_test3");
207 auto content = make_shared<ImageContent>("test/data/flat_red.png");
208 auto decoder = decoder_factory (film, content, true, {});
210 push (s, film, content, decoder, 0, Eyes::LEFT);
211 check (0, Eyes::LEFT, __LINE__);
212 push (s, film, content, decoder, 0, Eyes::RIGHT);
213 check (0, Eyes::RIGHT, __LINE__);
215 push (s, film, content, decoder, 2, Eyes::LEFT);
216 push (s, film, content, decoder, 2, Eyes::RIGHT);
217 check (2, Eyes::LEFT, __LINE__);
218 check (2, Eyes::RIGHT, __LINE__);
220 push (s, film, content, decoder, 3, Eyes::LEFT);
221 check (3, Eyes::LEFT, __LINE__);
222 push (s, film, content, decoder, 3, Eyes::RIGHT);
223 check (3, Eyes::RIGHT, __LINE__);