@@ -180,6 +180,7 @@ class AV_State {
180180 std::mutex &get_tox_loop_lock () { return tox_loop_lock_; }
181181 bool in_call () const { return in_call_.load (); }
182182 uint32_t get_call_state () const { return call_state_.load (); }
183+ void hangup () {hangup_.store (true );}
183184 void stop_threads () {
184185 if (stop_threads_.exchange (true )) {
185186 // already stopped
@@ -201,7 +202,6 @@ class AV_State {
201202
202203 static constexpr uint32_t TEST_A_BITRATE = 48 ; // In kbit/s
203204 static constexpr uint32_t TEST_V_BITRATE = 4000 ; // In kbit/s
204- static constexpr std::chrono::duration<double > AUTO_HANGUP_TIME = std::chrono::seconds(2 );
205205
206206 private:
207207 enum class Iteration_Type {
@@ -225,10 +225,9 @@ class AV_State {
225225 ck_assert (state != TOXAV_FRIEND_CALL_STATE_ERROR);
226226 std::cout << " [" << me->name_ << " ] State changed to: " << std::to_string (state) << std::endl;
227227 me->call_state_ .store (state);
228- Time_Point tp = me->call_start_ .load ();
229228
230- if (state != TOXAV_FRIEND_CALL_STATE_NONE && tp == Time_Point ()) {
231- me->call_start_ . store ( Clock::now () );
229+ if (state != TOXAV_FRIEND_CALL_STATE_NONE && me-> call_start_ == Time_Point ()) {
230+ me->call_start_ = Clock::now ();
232231 me->in_call_ .store (true );
233232 }
234233 }
@@ -292,14 +291,13 @@ class AV_State {
292291
293292 if (in_call_.load ()) {
294293 uint32_t state = call_state_.load ();
295- Time_Point tp = call_start_.load ();
296- std::chrono::duration<double > call_time = Clock::now () - tp;
294+ std::chrono::duration<double > call_time = Clock::now () - call_start_;
297295
298296 if (state == TOXAV_FRIEND_CALL_STATE_FINISHED) {
299297 std::cout << " [" << name_ << " ] Call ended by other side after: " << call_time.count ()
300298 << " s" << std::endl;
301299 in_call_.store (false );
302- } else if (tp > Time_Point () && call_time > AV_State::AUTO_HANGUP_TIME ) {
300+ } else if (hangup_. exchange ( false ) ) {
303301 std::cout << " [" << name_ << " ] Ending call after: " << call_time.count () << " s"
304302 << std::endl;
305303 Toxav_Err_Call_Control cc_err;
@@ -361,9 +359,10 @@ class AV_State {
361359
362360 std::atomic_bool stop_threads_;
363361 std::atomic_bool incomming_;
362+ std::atomic_bool hangup_;
364363 std::atomic_uint32_t call_state_;
365364
366- std::atomic< Time_Point> call_start_{ Time_Point ()} ;
365+ Time_Point call_start_;
367366 std::atomic_bool in_call_;
368367
369368 std::atomic_bool video_received_;
@@ -389,7 +388,6 @@ struct DUMMY_VIDEO {
389388};
390389
391390// FIXME: once we upgrade to C++17, remove these, reason: https://stackoverflow.com/a/28846608
392- constexpr std::chrono::duration<double > AV_State::AUTO_HANGUP_TIME;
393391constexpr int16_t DUMMY_PCM::pcm[];
394392constexpr uint8_t DUMMY_VIDEO::y[];
395393constexpr uint8_t DUMMY_VIDEO::u[];
@@ -455,6 +453,18 @@ static void test_av(bool combined_av) {
455453 DUMMY_VIDEO::u, DUMMY_VIDEO::v, error);
456454 };
457455
456+ auto poll_av_received = [](AV_State &av, uint32_t max_tries, uint32_t delay_ms) -> bool {
457+ for (uint32_t i = 0 ; i < max_tries; ++i) {
458+ if (av.did_receive_audio () && av.did_receive_video ()) {
459+ return true ;
460+ }
461+
462+ std::this_thread::sleep_for (std::chrono::milliseconds (delay_ms));
463+ }
464+
465+ return false ;
466+ };
467+
458468 // Send frames from alice to bob
459469 {
460470 std::lock_guard<std::mutex>(alice.get_tox_loop_lock ());
@@ -466,6 +476,9 @@ static void test_av(bool combined_av) {
466476 ck_assert (err == TOXAV_ERR_SEND_FRAME_OK);
467477 }
468478
479+ // Give up to 1s for frames to arrive
480+ ck_assert (poll_av_received (bob, 10 , 100 ));
481+
469482 // Send frames from bob to alice
470483 {
471484 std::lock_guard<std::mutex>(bob.get_tox_loop_lock ());
@@ -477,8 +490,14 @@ static void test_av(bool combined_av) {
477490 ck_assert (err == TOXAV_ERR_SEND_FRAME_OK);
478491 }
479492
480- // auto hangup after 2s, wait 3s for this
481- ck_assert (poll_state (alice, TOXAV_FRIEND_CALL_STATE_FINISHED, 30 , 100 ));
493+ // Give up to 1s for frames to arrive
494+ ck_assert (poll_av_received (alice, 10 , 100 ));
495+
496+ // Let bob hangup, no locking needed since we use atomics
497+ bob.hangup ();
498+
499+ // wait 1s for hangup confirmed
500+ ck_assert (poll_state (alice, TOXAV_FRIEND_CALL_STATE_FINISHED, 10 , 100 ));
482501
483502 // TODO: why is Bobs call state not updated?
484503 // ck_assert(poll_state(bob, TOXAV_FRIEND_CALL_STATE_FINISHED, 30, 100)); fails
@@ -490,11 +509,6 @@ static void test_av(bool combined_av) {
490509
491510 alice.stop_threads ();
492511 bob.stop_threads ();
493-
494- ck_assert (alice.did_receive_audio ());
495- ck_assert (alice.did_receive_video ());
496- ck_assert (bob.did_receive_audio ());
497- ck_assert (bob.did_receive_video ());
498512}
499513
500514} // namespace
0 commit comments