Try to postpone linking of duplicate video frames to stop copies failing on Windows.
authorCarl Hetherington <cth@carlh.net>
Sun, 6 Jan 2013 23:43:40 +0000 (23:43 +0000)
committerCarl Hetherington <cth@carlh.net>
Sun, 6 Jan 2013 23:43:40 +0000 (23:43 +0000)
src/lib/encoder.cc
src/lib/encoder.h

index 6e1209d83512b82374010ecc71d704acf535ef54..693bd5bc8e5baecceb779189b4a1f7e339c1a3cb 100644 (file)
@@ -42,6 +42,7 @@ using std::stringstream;
 using std::vector;
 using std::list;
 using std::cout;
+using std::make_pair;
 using namespace boost;
 
 int const Encoder::_history_size = 25;
@@ -207,6 +208,12 @@ Encoder::process_end ()
                        _film->log()->log (String::compose ("Local encode failed (%1)", e.what ()));
                }
        }
+
+       /* Now do links (or copies on windows) to duplicate frames */
+       for (list<pair<int, int> >::iterator i = _links_required.begin(); i != _links_required.end(); ++i) {
+               link (_opt->frame_out_path (i->first, false), _opt->frame_out_path (i->second, false));
+               link (_opt->hash_out_path (i->first, false), _opt->hash_out_path (i->second, false));
+       }
 }      
 
 /** @return an estimate of the current number of frames we are encoding per second,
@@ -305,9 +312,11 @@ Encoder::process_video (shared_ptr<Image> image, bool same, boost::shared_ptr<Su
        }
 
        if (same && _last_real_frame) {
-               /* Use the last frame that we encoded */
-               link (_opt->frame_out_path (_last_real_frame.get(), false), _opt->frame_out_path (_video_frame, false));
-               link (_opt->hash_out_path (_last_real_frame.get(), false), _opt->hash_out_path (_video_frame, false));
+               /* Use the last frame that we encoded.  We need to postpone doing the actual link,
+                  as on windows the link is really a copy and the reference frame might not have
+                  finished encoding yet.
+               */
+               _links_required.push_back (make_pair (_last_real_frame.get(), _video_frame));
        } else {
                /* Queue this new frame for encoding */
                pair<string, string> const s = Filter::ffmpeg_strings (_film->filters());
index e5916ad3a022bc8f2f9c8c117e182f339d7f3def..52ccfc166833f60a2e0e9a6efe4583092f15ad54 100644 (file)
@@ -121,7 +121,13 @@ private:
 
 #if HAVE_SWRESAMPLE    
        SwrContext* _swr_context;
-#endif 
+#endif
+
+       /** List of links that we need to create when all frames have been processed;
+        *  such that we need to call link (first, second) for each member of this list.
+        *  In other words, `first' is a `real' frame and `second' should be a link to `first'.
+        */
+       std::list<std::pair<int, int> > _links_required;
 
        std::vector<SNDFILE*> _sound_files;
        int64_t _audio_frames_written;