std::shared_ptr
[dcpomatic.git] / test / shuffler_test.cc
1 #include "lib/shuffler.h"
2 #include "lib/piece.h"
3 #include "lib/content_video.h"
4 #include <boost/test/unit_test.hpp>
5
6 using std::list;
7 using std::shared_ptr;
8 using std::weak_ptr;
9 using boost::optional;
10 #if BOOST_VERSION >= 106100
11 using namespace boost::placeholders;
12 #endif
13
14
15 static void
16 push (Shuffler& s, int frame, Eyes eyes)
17 {
18         shared_ptr<Piece> piece (new Piece (shared_ptr<Content>(), shared_ptr<Decoder>(), FrameRateChange(24, 24)));
19         ContentVideo cv;
20         cv.frame = frame;
21         cv.eyes = eyes;
22         s.video (piece, cv);
23 }
24
25 list<ContentVideo> pending_cv;
26
27 static void
28 receive (weak_ptr<Piece>, ContentVideo cv)
29 {
30         pending_cv.push_back (cv);
31 }
32
33 static void
34 check (int frame, Eyes eyes, int line)
35 {
36         BOOST_REQUIRE_MESSAGE (!pending_cv.empty(), "Check at " << line << " failed.");
37         BOOST_CHECK_MESSAGE (pending_cv.front().frame == frame, "Check at " << line << " failed.");
38         BOOST_CHECK_MESSAGE (pending_cv.front().eyes == eyes, "Check at " << line << " failed.");
39         pending_cv.pop_front();
40 }
41
42 /** A perfect sequence */
43 BOOST_AUTO_TEST_CASE (shuffler_test1)
44 {
45         Shuffler s;
46         s.Video.connect (boost::bind (&receive, _1, _2));
47
48         for (int i = 0; i < 10; ++i) {
49                 push (s, i, EYES_LEFT);
50                 push (s, i, EYES_RIGHT);
51                 check (i, EYES_LEFT, __LINE__);
52                 check (i, EYES_RIGHT, __LINE__);
53         }
54 }
55
56 /** Everything present but some simple shuffling needed */
57 BOOST_AUTO_TEST_CASE (shuffler_test2)
58 {
59         Shuffler s;
60         s.Video.connect (boost::bind (&receive, _1, _2));
61
62         for (int i = 0; i < 10; i += 2) {
63                 push (s, i, EYES_LEFT);
64                 push (s, i + 1, EYES_LEFT);
65                 push (s, i, EYES_RIGHT);
66                 push (s, i + 1, EYES_RIGHT);
67                 check (i, EYES_LEFT, __LINE__);
68                 check (i, EYES_RIGHT, __LINE__);
69                 check (i + 1, EYES_LEFT, __LINE__);
70                 check (i + 1, EYES_RIGHT, __LINE__);
71         }
72 }
73
74 /** One missing left eye image */
75 BOOST_AUTO_TEST_CASE (shuffler_test3)
76 {
77         Shuffler s;
78         s.Video.connect (boost::bind (&receive, _1, _2));
79
80         push (s, 0, EYES_LEFT);
81         check (0, EYES_LEFT, __LINE__);
82         push (s, 0, EYES_RIGHT);
83         check (0, EYES_RIGHT, __LINE__);
84         push (s, 1, EYES_LEFT);
85         check (1, EYES_LEFT, __LINE__);
86         push (s, 1, EYES_RIGHT);
87         check (1, EYES_RIGHT, __LINE__);
88         push (s, 2, EYES_RIGHT);
89         push (s, 3, EYES_LEFT);
90         push (s, 3, EYES_RIGHT);
91         push (s, 4, EYES_LEFT);
92         push (s, 4, EYES_RIGHT);
93         s.flush ();
94         check (2, EYES_RIGHT, __LINE__);
95         check (3, EYES_LEFT, __LINE__);
96         check (3, EYES_RIGHT, __LINE__);
97         check (4, EYES_LEFT, __LINE__);
98         check (4, EYES_RIGHT, __LINE__);
99 }
100
101 /** One missing right eye image */
102 BOOST_AUTO_TEST_CASE (shuffler_test4)
103 {
104         Shuffler s;
105         s.Video.connect (boost::bind (&receive, _1, _2));
106
107         push (s, 0, EYES_LEFT);
108         check (0, EYES_LEFT, __LINE__);
109         push (s, 0, EYES_RIGHT);
110         check (0, EYES_RIGHT, __LINE__);
111         push (s, 1, EYES_LEFT);
112         check (1, EYES_LEFT, __LINE__);
113         push (s, 1, EYES_RIGHT);
114         check (1, EYES_RIGHT, __LINE__);
115         push (s, 2, EYES_LEFT);
116         push (s, 3, EYES_LEFT);
117         push (s, 3, EYES_RIGHT);
118         push (s, 4, EYES_LEFT);
119         push (s, 4, EYES_RIGHT);
120         s.flush ();
121         check (2, EYES_LEFT, __LINE__);
122         check (3, EYES_LEFT, __LINE__);
123         check (3, EYES_RIGHT, __LINE__);
124         check (4, EYES_LEFT, __LINE__);
125         check (4, EYES_RIGHT, __LINE__);
126 }
127
128 /** Only one eye */
129 BOOST_AUTO_TEST_CASE (shuffler_test5)
130 {
131         Shuffler s;
132         s.Video.connect (boost::bind (&receive, _1, _2));
133
134         /* One left should come out straight away */
135         push (s, 0, EYES_LEFT);
136         check (0, EYES_LEFT, __LINE__);
137
138         /* More lefts should be kept in the shuffler in the hope that some rights arrive */
139         for (int i = 0; i < s._max_size; ++i) {
140                 push (s, i + 1, EYES_LEFT);
141         }
142         BOOST_CHECK (pending_cv.empty ());
143
144         /* If enough lefts come the shuffler should conclude that there's no rights and start
145            giving out the lefts.
146         */
147         push (s, s._max_size + 1, EYES_LEFT);
148         check (1, EYES_LEFT, __LINE__);
149 }
150
151 /** One complete frame (L+R) missing.
152     Shuffler should carry on, skipping this frame, as the player will cope with it.
153 */
154 BOOST_AUTO_TEST_CASE (shuffler_test6)
155 {
156         Shuffler s;
157         s.Video.connect (boost::bind (&receive, _1, _2));
158
159         push (s, 0, EYES_LEFT);
160         check (0, EYES_LEFT, __LINE__);
161         push (s, 0, EYES_RIGHT);
162         check (0, EYES_RIGHT, __LINE__);
163
164         push (s, 2, EYES_LEFT);
165         push (s, 2, EYES_RIGHT);
166         check (2, EYES_LEFT, __LINE__);
167         check (2, EYES_RIGHT, __LINE__);
168
169         push (s, 3, EYES_LEFT);
170         check (3, EYES_LEFT, __LINE__);
171         push (s, 3, EYES_RIGHT);
172         check (3, EYES_RIGHT, __LINE__);
173 }