Various attempted fixes to audio sync.
[dcpomatic.git] / src / lib / player.cc
index 263998693e7887188eaf1f4d3b87f3cefa935ab6..3db2fe6c9eb19074be6f265f7fd4ffe6918ca61d 100644 (file)
@@ -119,10 +119,10 @@ Player::pass ()
                                break;
                        }
 
-                       dec->set_dcp_times ((*i)->frc.speed_up, offset);
+                       dec->set_dcp_times (_film->video_frame_rate(), _film->audio_frame_rate(), (*i)->frc, offset);
                        DCPTime const t = dec->dcp_time - offset;
-                       if (t >= (*i)->content->full_length() - (*i)->content->trim_end ()) {
-                               /* In the end-trimmed part; decoder has nothing eles to give us */
+                       if (t >= ((*i)->content->full_length() - (*i)->content->trim_end ())) {
+                               /* In the end-trimmed part; decoder has nothing else to give us */
                                dec.reset ();
                                done = true;
                        } else if (t >= (*i)->content->trim_start ()) {
@@ -172,11 +172,6 @@ Player::pass ()
        /* Will be set to false if we shouldn't consume the peeked DecodedThing */
        bool consume = true;
 
-       /* This is the margin either side of _{video,audio}_position that we will accept
-          as a starting point for a frame consecutive to the previous.
-       */
-       DCPTime const margin = TIME_HZ / (2 * _film->video_frame_rate ());
-       
        if (dv && _video) {
 
                if (_just_did_inaccurate_seek) {
@@ -185,7 +180,7 @@ Player::pass ()
                        emit_video (earliest_piece, dv);
                        step_video_position (dv);
                        
-               } else if (dv->dcp_time - _video_position > margin) {
+               } else if (dv->dcp_time > _video_position) {
 
                        /* Too far ahead */
 
@@ -197,36 +192,43 @@ Player::pass ()
                        if (i == _pieces.end() || !_last_incoming_video.video || !_have_valid_pieces) {
                                /* We're outside all video content */
                                emit_black ();
+                               _statistics.video.black++;
                        } else {
                                /* We're inside some video; repeat the frame */
                                _last_incoming_video.video->dcp_time = _video_position;
                                emit_video (_last_incoming_video.weak_piece, _last_incoming_video.video);
                                step_video_position (_last_incoming_video.video);
+                               _statistics.video.repeat++;
                        }
 
                        consume = false;
 
-               } else if (abs (dv->dcp_time - _video_position) < margin) {
+               } else if (dv->dcp_time == _video_position) {
                        /* We're ok */
                        emit_video (earliest_piece, dv);
                        step_video_position (dv);
+                       _statistics.video.good++;
                } else {
                        /* Too far behind: skip */
+                       _statistics.video.skip++;
                }
 
                _just_did_inaccurate_seek = false;
 
        } else if (da && _audio) {
 
-               if (da->dcp_time - _audio_position > margin) {
+               if (da->dcp_time > _audio_position) {
                        /* Too far ahead */
                        emit_silence (da->dcp_time - _audio_position);
                        consume = false;
-               } else if (abs (da->dcp_time - _audio_position) < margin) {
+                       _statistics.audio.silence += (da->dcp_time - _audio_position);
+               } else if (da->dcp_time == _audio_position) {
                        /* We're ok */
                        emit_audio (earliest_piece, da);
+                       _statistics.audio.good += da->data->frames();
                } else {
                        /* Too far behind: skip */
+                       _statistics.audio.skip += da->data->frames();
                }
                
        } else if (ds && _video) {
@@ -715,3 +717,15 @@ PlayerImage::image (AVPixelFormat format, bool aligned)
        return out;
 }
 
+void
+PlayerStatistics::dump (shared_ptr<Log> log) const
+{
+       log->log (String::compose ("Video: %1 good %2 skipped %3 black %4 repeat", video.good, video.skip, video.black, video.repeat));
+       log->log (String::compose ("Audio: %1 good %2 skipped %3 silence", audio.good, audio.skip, audio.silence));
+}
+
+PlayerStatistics const &
+Player::statistics () const
+{
+       return _statistics;
+}