X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Flib%2Fplayer.cc;h=b5a96163182b458acf00a58661be273251ceab60;hb=d324fc102df00d6dc62614938f78cf983a101dd4;hp=a235d16229bdd616303eb0df3ea02b07f34b1d65;hpb=e24d0def5b4e6c1825620b032af9f63c9eb78693;p=dcpomatic.git diff --git a/src/lib/player.cc b/src/lib/player.cc index a235d1622..b5a961631 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -55,6 +55,8 @@ public: : content (c) , video_position (c->position ()) , audio_position (c->position ()) + , repeat_to_do (0) + , repeat_done (0) {} Piece (shared_ptr c, shared_ptr d) @@ -63,11 +65,51 @@ public: , video_position (c->position ()) , audio_position (c->position ()) {} + + /** Set this piece to repeat a video frame a given number of times */ + void set_repeat (IncomingVideo video, int num) + { + repeat_video = video; + repeat_to_do = num; + repeat_done = 0; + } + + void reset_repeat () + { + repeat_video.image.reset (); + repeat_to_do = 0; + repeat_done = 0; + } + + bool repeating () const + { + return repeat_done != repeat_to_do; + } + + void repeat (Player* player) + { + player->process_video ( + repeat_video.weak_piece, + repeat_video.image, + repeat_video.eyes, + repeat_done > 0, + repeat_video.frame, + (repeat_done + 1) * (TIME_HZ / player->_film->video_frame_rate ()) + ); + + ++repeat_done; + } shared_ptr content; shared_ptr decoder; + /** Time of the last video we emitted relative to the start of the DCP */ Time video_position; + /** Time of the last audio we emitted relative to the start of the DCP */ Time audio_position; + + IncomingVideo repeat_video; + int repeat_to_do; + int repeat_done; }; Player::Player (shared_ptr f, shared_ptr p) @@ -119,7 +161,10 @@ Player::pass () continue; } - if (_video && dynamic_pointer_cast ((*i)->decoder)) { + shared_ptr vd = dynamic_pointer_cast ((*i)->decoder); + shared_ptr ad = dynamic_pointer_cast ((*i)->decoder); + + if (_video && vd) { if ((*i)->video_position < earliest_t) { earliest_t = (*i)->video_position; earliest = *i; @@ -127,7 +172,7 @@ Player::pass () } } - if (_audio && dynamic_pointer_cast ((*i)->decoder)) { + if (_audio && ad && ad->has_audio ()) { if ((*i)->audio_position < earliest_t) { earliest_t = (*i)->audio_position; earliest = *i; @@ -146,7 +191,11 @@ Player::pass () if (earliest_t > _video_position) { emit_black (); } else { - earliest->decoder->pass (); + if (earliest->repeating ()) { + earliest->repeat (this); + } else { + earliest->decoder->pass (); + } } break; @@ -172,30 +221,38 @@ Player::pass () } if (_audio) { - Time audio_done_up_to = TIME_MAX; + boost::optional