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