Merge master.
[dcpomatic.git] / src / lib / matcher.cc
index f6eff168b69ed47fc46d13b76d62ff9cbe016e63..77ed9b6515bbb3e40add4a89e3b4d6d6d81a0d52 100644 (file)
@@ -1,10 +1,32 @@
+/*
+    Copyright (C) 2012 Carl Hetherington <cth@carlh.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
 #include "matcher.h"
 #include "image.h"
 #include "log.h"
 
+#include "i18n.h"
+
+using std::min;
 using boost::shared_ptr;
 
-Matcher::Matcher (Log* log, int sample_rate, float frames_per_second)
+Matcher::Matcher (shared_ptr<Log> log, int sample_rate, float frames_per_second)
        : AudioVideoProcessor (log)
        , _sample_rate (sample_rate)
        , _frames_per_second (frames_per_second)
@@ -15,9 +37,9 @@ Matcher::Matcher (Log* log, int sample_rate, float frames_per_second)
 }
 
 void
-Matcher::process_video (boost::shared_ptr<Image> i, boost::shared_ptr<Subtitle> s)
+Matcher::process_video (shared_ptr<Image> i, bool same, shared_ptr<Subtitle> s)
 {
-       Video (i, s);
+       Video (i, same, s);
        _video_frames++;
 
        _pixel_format = i->pixel_format ();
@@ -25,7 +47,7 @@ Matcher::process_video (boost::shared_ptr<Image> i, boost::shared_ptr<Subtitle>
 }
 
 void
-Matcher::process_audio (boost::shared_ptr<AudioBuffers> b)
+Matcher::process_audio (shared_ptr<AudioBuffers> b)
 {
        Audio (b);
        _audio_frames += b->frames ();
@@ -45,7 +67,7 @@ Matcher::process_end ()
 
        _log->log (
                String::compose (
-                       "Matching processor has seen %1 video frames (which equals %2 audio frames) and %3 audio frames",
+                       N_("Matching processor has seen %1 video frames (which equals %2 audio frames) and %3 audio frames"),
                        _video_frames,
                        video_frames_to_audio_frames (_video_frames, _sample_rate, _frames_per_second),
                        _audio_frames
@@ -54,17 +76,17 @@ Matcher::process_end ()
        
        if (audio_short_by_frames < 0) {
                
-               _log->log (String::compose ("%1 too many audio frames", -audio_short_by_frames));
+               _log->log (String::compose (N_("%1 too many audio frames"), -audio_short_by_frames));
                
                /* We have seen more audio than video.  Emit enough black video frames so that we reverse this */
                int const black_video_frames = ceil (-audio_short_by_frames * _frames_per_second / _sample_rate);
                
-               _log->log (String::compose ("Emitting %1 frames of black video", black_video_frames));
+               _log->log (String::compose (N_("Emitting %1 frames of black video"), black_video_frames));
 
-               shared_ptr<Image> black (new CompactImage (_pixel_format.get(), _size.get()));
+               shared_ptr<Image> black (new SimpleImage (_pixel_format.get(), _size.get(), true));
                black->make_black ();
                for (int i = 0; i < black_video_frames; ++i) {
-                       Video (black, shared_ptr<Subtitle>());
+                       Video (black, i != 0, shared_ptr<Subtitle>());
                }
                
                /* Now recompute our check value */
@@ -72,10 +94,22 @@ Matcher::process_end ()
        }
        
        if (audio_short_by_frames > 0) {
-               _log->log (String::compose ("Emitted %1 too few audio frames", audio_short_by_frames));
-               shared_ptr<AudioBuffers> b (new AudioBuffers (_channels.get(), audio_short_by_frames));
+               _log->log (String::compose (N_("Emitted %1 too few audio frames"), audio_short_by_frames));
+
+               /* Do things in half second blocks as I think there may be limits
+                  to what FFmpeg (and in particular the resampler) can cope with.
+               */
+               int64_t const block = _sample_rate / 2;
+               shared_ptr<AudioBuffers> b (new AudioBuffers (_channels.get(), block));
                b->make_silent ();
-               Audio (b);
-               _audio_frames += b->frames ();
+               
+               int64_t to_do = audio_short_by_frames;
+               while (to_do > 0) {
+                       int64_t const this_time = min (to_do, block);
+                       b->set_frames (this_time);
+                       Audio (b);
+                       _audio_frames += b->frames ();
+                       to_do -= this_time;
+               }
        }
 }