Merge master.
authorCarl Hetherington <cth@carlh.net>
Sat, 23 Aug 2014 21:50:40 +0000 (22:50 +0100)
committerCarl Hetherington <cth@carlh.net>
Sat, 23 Aug 2014 21:50:40 +0000 (22:50 +0100)
39 files changed:
ChangeLog
debian/changelog
src/lib/analyse_audio_job.cc
src/lib/compose.hpp
src/lib/config.cc
src/lib/content.cc
src/lib/dcp_video.cc
src/lib/ffmpeg_content.cc
src/lib/ffmpeg_decoder.cc
src/lib/ffmpeg_examiner.cc
src/lib/film.cc
src/lib/filter_graph.cc
src/lib/image_content.cc
src/lib/internet.cc
src/lib/job.cc
src/lib/kdm.cc
src/lib/log.cc
src/lib/md5_digester.cc
src/lib/safe_stringstream.cc [new file with mode: 0644]
src/lib/safe_stringstream.h [new file with mode: 0644]
src/lib/server.cc
src/lib/server_finder.cc
src/lib/sndfile_content.cc
src/lib/stack.cpp
src/lib/transcode_job.cc
src/lib/update.cc
src/lib/util.cc
src/lib/video_content.cc
src/lib/wscript
src/tools/dcpomatic.cc
src/tools/dcpomatic_kdm.cc
src/tools/dcpomatic_server_cli.cc
src/wx/about_dialog.cc
src/wx/colour_conversion_editor.cc
src/wx/film_editor.cc
src/wx/job_wrapper.cc
src/wx/properties_dialog.cc
src/wx/timing_panel.cc
test/film_metadata_test.cc

index 23ccae1902d6f8189f305fa33f221f08f27353ae..e100fd23e466e0c395a50fe5168e4ada053915d3 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
 
        * Add subtitle view.
 
+2014-08-23  Carl Hetherington  <cth@carlh.net>
+
+       * Version 1.72.12 released.
+
+2014-08-23  Carl Hetherington  <cth@carlh.net>
+
+       * Revert previous use of AVFormatContext::start_time when
+       computing the length of video.  I think this is wrong, and
+       causes bits to be missed off the end of videos (and other
+       problems).
+
+2014-08-20  Carl Hetherington  <cth@carlh.net>
+
+       * Version 1.72.11 released.
+
+2014-08-19  Carl Hetherington  <cth@carlh.net>
+
+       * Attempt to fix random crashes on OS X (especially during encodes)
+       thought to be caused by multiple threads using (different) stringstreams
+       at the same time; see src/lib/safe_stringstream.
+>>>>>>> origin/master
+
 2014-08-09  Carl Hetherington  <cth@carlh.net>
 
        * Version 1.72.10 released.
index 1da8a1f91707c709a48beaa08630d3c38924a409..09d40178298a9256211e2b1504703a01fb37445c 100644 (file)
@@ -171,15 +171,8 @@ dcpomatic (2.0.1-1) UNRELEASED; urgency=low
   * New upstream release.
   * New upstream release.
   * New upstream release.
-<<<<<<< HEAD
 
  -- Carl Hetherington <carl@dalglish>  Wed, 06 Aug 2014 18:59:35 +0100
-=======
-  * New upstream release.
-  * New upstream release.
-
- -- Carl Hetherington <carl@d1stkfactory>  Sat, 09 Aug 2014 12:38:18 +0100
->>>>>>> origin/master
 
 dcpomatic (0.87-1) UNRELEASED; urgency=low
 
index 347cc0a0fb362f95b55686ad3fb76744e746ff8f..60b10e7b6e05ba69dc418894fa10b4ca8ef7781e 100644 (file)
@@ -87,7 +87,7 @@ AnalyseAudioJob::analyse (shared_ptr<const AudioBuffers> b)
                for (int j = 0; j < b->channels(); ++j) {
                        float s = b->data(j)[i];
                        if (fabsf (s) < 10e-7) {
-                               /* stringstream can't serialise and recover inf or -inf, so prevent such
+                               /* SafeStringStream can't serialise and recover inf or -inf, so prevent such
                                   values by replacing with this (140dB down) */
                                s = 10e-7;
                        }
index b3f410c8ea52345112dc911671fe6756cbde9554..aa67b5a1fd8bc9f1027ab272b20c93ff744d8732 100644 (file)
 #ifndef STRING_COMPOSE_H
 #define STRING_COMPOSE_H
 
-#include <sstream>
 #include <string>
 #include <list>
 #include <map>                 // for multimap
+#include "safe_stringstream.h"
 
 namespace StringPrivate
 {
@@ -56,7 +56,7 @@ namespace StringPrivate
     std::string str() const;
 
   private:
-    std::ostringstream os;
+    SafeStringStream os;
     int arg_no;
 
     // we store the output as a list - when the output string is requested, the
index 14539044d2eb53b11f2465ea4e753e75a0ab1f93..4f2a75574414bafa2b13129afe478f2df740edc9 100644 (file)
@@ -17,7 +17,6 @@
 
 */
 
-#include <sstream>
 #include <cstdlib>
 #include <fstream>
 #include <glib.h>
index bbbe9b6ce4bdd4dd5ff6b8dcf231c8d08126e253..21e49a2c955ae7e74091ec5c1a43f4e9e238b857 100644 (file)
 #include "ui_signaller.h"
 #include "exceptions.h"
 #include "film.h"
+#include "safe_stringstream.h"
 
 #include "i18n.h"
 
 using std::string;
-using std::stringstream;
 using std::set;
 using std::list;
 using std::cout;
@@ -225,7 +225,7 @@ Content::length_after_trim () const
 string
 Content::identifier () const
 {
-       stringstream s;
+       SafeStringStream s;
        
        s << Content::digest()
          << "_" << position().get()
index 9b1c8c33eae12cf36d214cbd81b84af99e9e7ae8..d849866512d4cdc0e983ca42201631fe3fe88d70 100644 (file)
@@ -34,7 +34,6 @@
 #include <stdexcept>
 #include <cstdio>
 #include <iomanip>
-#include <sstream>
 #include <iostream>
 #include <fstream>
 #include <unistd.h>
@@ -67,7 +66,6 @@
 #include "i18n.h"
 
 using std::string;
-using std::stringstream;
 using std::cout;
 using boost::shared_ptr;
 using boost::lexical_cast;
@@ -282,10 +280,9 @@ DCPVideo::encode_remotely (ServerDescription serv)
        LOG_GENERAL (N_("Sending frame %1 to remote"), _index);
        
        /* Send XML metadata */
-       stringstream xml;
-       doc.write_to_stream (xml, "UTF-8");
-       socket->write (xml.str().length() + 1);
-       socket->write ((uint8_t *) xml.str().c_str(), xml.str().length() + 1);
+       string xml = doc.write_to_string ("UTF-8");
+       socket->write (xml.length() + 1);
+       socket->write ((uint8_t *) xml.c_str(), xml.length() + 1);
 
        /* Send binary data */
        _frame->send_binary (socket, _burn_subtitles);
index 0af53d8830a52ab8ca8518b0bae5591be12c6127..bb4e022308dc9882dff57d5a0959d0a014cf9cab 100644 (file)
@@ -34,13 +34,13 @@ extern "C" {
 #include "log.h"
 #include "exceptions.h"
 #include "frame_rate_change.h"
+#include "safe_stringstream.h"
 
 #include "i18n.h"
 
 #define LOG_GENERAL(...) film->log()->log (String::compose (__VA_ARGS__), Log::TYPE_GENERAL);
 
 using std::string;
-using std::stringstream;
 using std::vector;
 using std::list;
 using std::cout;
@@ -235,7 +235,7 @@ FFmpegContent::information () const
                return "";
        }
        
-       stringstream s;
+       SafeStringStream s;
        
        s << String::compose (_("%1 frames; %2 frames per second"), video_length_after_3d_combine().frames (video_frame_rate()), video_frame_rate()) << "\n";
        s << VideoContent::information ();
@@ -352,7 +352,7 @@ FFmpegContent::set_audio_mapping (AudioMapping m)
 string
 FFmpegContent::identifier () const
 {
-       stringstream s;
+       SafeStringStream s;
 
        s << VideoContent::identifier();
 
index 4e5d9bb1ed271760e858b4a37d62fcde110fa1d4..15443c346b3d302cce263165588044e641879160 100644 (file)
@@ -23,7 +23,6 @@
 
 #include <stdexcept>
 #include <vector>
-#include <sstream>
 #include <iomanip>
 #include <iostream>
 #include <stdint.h>
index 62b909b1d65f3708293ca8dcbe91fe4a371d4608..48d85da6f11113cb6cabc83215505c8df766110a 100644 (file)
@@ -26,13 +26,13 @@ extern "C" {
 #include "ffmpeg_audio_stream.h"
 #include "ffmpeg_subtitle_stream.h"
 #include "util.h"
+#include "safe_stringstream.h"
 
 #include "i18n.h"
 
 using std::string;
 using std::cout;
 using std::max;
-using std::stringstream;
 using boost::shared_ptr;
 using boost::optional;
 
@@ -176,14 +176,14 @@ FFmpegExaminer::video_size () const
 ContentTime
 FFmpegExaminer::video_length () const
 {
-       ContentTime const length = ContentTime::from_seconds (double (_format_context->duration - _format_context->start_time) / AV_TIME_BASE);
+       ContentTime const length = ContentTime::from_seconds (double (_format_context->duration) / AV_TIME_BASE);
        return ContentTime (max (ContentTime::Type (1), length.get ()));
 }
 
 string
 FFmpegExaminer::audio_stream_name (AVStream* s) const
 {
-       stringstream n;
+       SafeStringStream n;
 
        n << stream_name (s);
 
@@ -199,7 +199,7 @@ FFmpegExaminer::audio_stream_name (AVStream* s) const
 string
 FFmpegExaminer::subtitle_stream_name (AVStream* s) const
 {
-       stringstream n;
+       SafeStringStream n;
 
        n << stream_name (s);
 
@@ -213,7 +213,7 @@ FFmpegExaminer::subtitle_stream_name (AVStream* s) const
 string
 FFmpegExaminer::stream_name (AVStream* s) const
 {
-       stringstream n;
+       SafeStringStream n;
 
        if (s->metadata) {
                AVDictionaryEntry const * lang = av_dict_get (s->metadata, "language", 0, 0);
index 0891838ff930674548ea90c23e7f117fcdc05905..577c29e3a55afeb8a7c85e29883c2bf7c30bcff6 100644 (file)
@@ -22,7 +22,6 @@
 #include <algorithm>
 #include <fstream>
 #include <cstdlib>
-#include <sstream>
 #include <iomanip>
 #include <unistd.h>
 #include <boost/filesystem.hpp>
 #include "ratio.h"
 #include "cross.h"
 #include "cinema.h"
+#include "safe_stringstream.h"
 
 #include "i18n.h"
 
 using std::string;
-using std::stringstream;
 using std::multimap;
 using std::pair;
 using std::map;
@@ -162,7 +161,7 @@ Film::video_identifier () const
 {
        assert (container ());
 
-       stringstream s;
+       SafeStringStream s;
        s.imbue (std::locale::classic ());
        
        s << container()->id()
@@ -504,7 +503,7 @@ Film::file (boost::filesystem::path f) const
 string
 Film::isdcf_name (bool if_created_now) const
 {
-       stringstream d;
+       SafeStringStream d;
 
        string raw_name = name ();
 
@@ -827,7 +826,7 @@ Film::info_path (int f, Eyes e) const
        boost::filesystem::path p;
        p /= info_dir ();
 
-       stringstream s;
+       SafeStringStream s;
        s.width (8);
        s << setfill('0') << f;
 
@@ -854,7 +853,7 @@ Film::j2c_path (int f, Eyes e, bool t) const
        p /= "j2c";
        p /= video_identifier ();
 
-       stringstream s;
+       SafeStringStream s;
        s.width (8);
        s << setfill('0') << f;
 
index f6a6c4529df2376bc08f81a2adaf721d5516459d..d2427c31faf35957b251320d1d091fce2e54b161 100644 (file)
@@ -34,10 +34,10 @@ extern "C" {
 #include "exceptions.h"
 #include "image.h"
 #include "ffmpeg_content.h"
+#include "safe_stringstream.h"
 
 #include "i18n.h"
 
-using std::stringstream;
 using std::string;
 using std::list;
 using std::pair;
@@ -83,7 +83,7 @@ FilterGraph::FilterGraph (shared_ptr<const FFmpegContent> content, dcp::Size s,
                throw DecodeError (N_("Could not create buffer sink filter"));
        }
 
-       stringstream a;
+       SafeStringStream a;
        a << "video_size=" << _size.width << "x" << _size.height << ":"
          << "pix_fmt=" << _pixel_format << ":"
          << "time_base=1/1:"
index 70d777bca11f6e52a466dbf44414b7a1ab048163..84b0b75c9732a4cd47dc30e1698ee1a82335c675 100644 (file)
 #include "job.h"
 #include "frame_rate_change.h"
 #include "exceptions.h"
+#include "safe_stringstream.h"
 
 #include "i18n.h"
 
 using std::string;
 using std::cout;
-using std::stringstream;
 using boost::shared_ptr;
 
 ImageContent::ImageContent (shared_ptr<const Film> f, boost::filesystem::path p)
@@ -134,7 +134,7 @@ ImageContent::full_length () const
 string
 ImageContent::identifier () const
 {
-       stringstream s;
+       SafeStringStream s;
        s << VideoContent::identifier ();
        s << "_" << video_length().get();
        return s.str ();
index 99ae5c2142ed255d3731e1a667591e811bc63bb9..c28e650fdd92f4514bb850dacd13c7869b040ad4 100644 (file)
 #include <curl/curl.h>
 #include <zip.h>
 #include "util.h"
+#include "safe_stringstream.h"
 
 #include "i18n.h"
 
 using std::string;
-using std::stringstream;
 using std::list;
 using boost::optional;
 using boost::function;
@@ -130,11 +130,10 @@ ftp_ls (string url)
                return list<string> ();
        }
 
-       stringstream s (ls_raw);
-       string line;
+       SafeStringStream s (ls_raw);
        list<string> ls;
        while (s.good ()) {
-               getline (s, line);
+               string const line = s.getline ();
                if (line.length() > 55) {
                        string const file = line.substr (55);
                        if (file != "." && file != "..") {
index 31a10a44bd6af2343ca4ddfa525ed3b4e35226ad..1d3cb73b6fcf39f276e9aefc3fbdd91841397051 100644 (file)
@@ -37,7 +37,6 @@
 using std::string;
 using std::list;
 using std::cout;
-using std::stringstream;
 using boost::shared_ptr;
 
 Job::Job (shared_ptr<const Film> f)
@@ -309,7 +308,7 @@ Job::status () const
                pc = 99;
        }
 
-       stringstream s;
+       SafeStringStream s;
        if (!finished ()) {
                s << pc << N_("%");
                if (p >= 0 && t > 10 && r > 0) {
index a2ed1be73498dd924752f998fa154e479ae18cb9..108860594e2592144760965a02aeb1220f8cf02c 100644 (file)
 #include "util.h"
 #include "film.h"
 #include "config.h"
+#include "safe_stringstream.h"
 
 using std::list;
 using std::string;
-using std::stringstream;
 using std::cout;
 using boost::shared_ptr;
 
@@ -234,9 +234,9 @@ email_kdms (
                
                quickmail_initialize ();
 
-               stringstream start;
+               SafeStringStream start;
                start << from.date() << " " << from.time_of_day();
-               stringstream end;
+               SafeStringStream end;
                end << to.date() << " " << to.time_of_day();
                
                string subject = Config::instance()->kdm_subject();
@@ -260,7 +260,7 @@ email_kdms (
                boost::algorithm::replace_all (body, "$END_TIME", end.str ());
                boost::algorithm::replace_all (body, "$CINEMA_NAME", i->cinema->name);
                
-               stringstream screens;
+               SafeStringStream screens;
                for (list<ScreenKDM>::const_iterator j = i->screen_kdms.begin(); j != i->screen_kdms.end(); ++j) {
                        screens << j->screen->name << ", ";
                }
index 4de6bd874e94c4c97feed165a210de7b10169936..5e8277a23c5da6a023212defe579f9c5270212a7 100644 (file)
@@ -26,6 +26,7 @@
 #include "log.h"
 #include "cross.h"
 #include "config.h"
+#include "safe_stringstream.h"
 
 #include "i18n.h"
 
@@ -63,7 +64,7 @@ Log::log (string message, int type)
        time (&t);
        string a = ctime (&t);
 
-       stringstream s;
+       SafeStringStream s;
        s << a.substr (0, a.length() - 1) << N_(": ");
 
        if (type & TYPE_ERROR) {
@@ -90,7 +91,7 @@ Log::microsecond_log (string m, int t)
        struct timeval tv;
        gettimeofday (&tv, 0);
 
-       stringstream s;
+       SafeStringStream s;
        s << tv.tv_sec << N_(":") << tv.tv_usec << N_(" ") << m;
        do_log (s.str ());
 }      
index 1244209bd62fc149aea62d4f1f41025ce400d916..1d4d1974ad88fc1295307948d443a5dd5373e3ba 100644 (file)
 */
 
 #include <iomanip>
-#include <sstream>
 #include <openssl/md5.h>
 #include "md5_digester.h"
+#include "safe_stringstream.h"
 
 using std::string;
-using std::stringstream;
 using std::hex;
 using std::setfill;
 using std::setw;
@@ -51,7 +50,7 @@ MD5Digester::get () const
                unsigned char digest[MD5_DIGEST_LENGTH];
                MD5_Final (digest, &_context);
                
-               stringstream s;
+               SafeStringStream s;
                for (int i = 0; i < MD5_DIGEST_LENGTH; ++i) {
                        s << hex << setfill('0') << setw(2) << ((int) digest[i]);
                }
diff --git a/src/lib/safe_stringstream.cc b/src/lib/safe_stringstream.cc
new file mode 100644 (file)
index 0000000..01d5450
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+    Copyright (C) 2014 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 <boost/thread/mutex.hpp>
+#include "safe_stringstream.h"
+
+boost::mutex SafeStringStream::_mutex;
diff --git a/src/lib/safe_stringstream.h b/src/lib/safe_stringstream.h
new file mode 100644 (file)
index 0000000..e455de9
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+    Copyright (C) 2014 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.
+
+*/
+
+#ifndef DCPOMATIC_SAFE_STRINGSTREAM_H
+#define DCPOMATIC_SAFE_STRINGSTREAM_H
+
+#include <boost/thread/mutex.hpp>
+
+/* I've not been able to reproduce it, but there have been reports that DCP-o-matic crashes
+ * on OS X with two simultaneous backtraces that look like this:
+ *
+ * 0 libSystem.B.dylib  0x00007fff84ebe264 __numeric_load_locale + 125
+ * 1 libSystem.B.dylib  0x00007fff84e2aac4 loadlocale + 323
+ * 2 libstdc++.6.dylib  0x00007fff8976ba69 std::__convert_from_v(int* const&, char*, int, char const*, ...) + 199
+ * 3 libstdc++.6.dylib  0x00007fff8974e99b std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char,
+std::char_traits<char> > >::_M_insert_float<double>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, char, double) const + 199
+ * 4 libstdc++.6.dylib  0x00007fff8974ebc0 std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> >
+>::do_put(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, double) const + 28
+ * 5 libstdc++.6.dylib  0x00007fff897566a2 std::ostream& std::ostream::_M_insert<double>(double) + 178
+ * 6 libdcpomatic.dylib 0x0000000100331e21 StringPrivate::Composition& StringPrivate::Composition::arg<float>(float const&) + 33
+ *
+ * in two different threads.  I'm assuming that for some bizarre reason it is unsafe to use two separate stringstream
+ * objects in different threads on OS X.  This is a hack to work around it.
+ */
+
+class SafeStringStream
+{
+public:
+       SafeStringStream ()
+       {}
+       
+       SafeStringStream (std::string s)
+               : _stream (s)
+       {}
+       
+       template <class T>
+       std::ostream& operator<< (T val)
+       {
+               boost::mutex::scoped_lock lm (_mutex);
+               _stream << val;
+               return _stream;
+       }
+
+       template <class T>
+       std::istream& operator>> (T& val)
+       {
+               boost::mutex::scoped_lock lm (_mutex);
+               _stream >> val;
+               return _stream;
+       }
+
+       std::string str () const {
+               return _stream.str ();
+       }
+
+       void str (std::string const & s) {
+               _stream.str (s);
+       }
+
+       void imbue (std::locale const & loc)
+       {
+               boost::mutex::scoped_lock lm (_mutex);
+               _stream.imbue (loc);
+       }
+
+       void width (int w)
+       {
+               _stream.width (w);
+       }
+
+       void precision (int p)
+       {
+               _stream.precision (p);
+       }
+
+       bool good () const
+       {
+               return _stream.good ();
+       }
+
+       std::string getline ()
+       {
+               boost::mutex::scoped_lock lm (_mutex);
+               std::string s;
+               std::getline (_stream, s);
+               return s;
+       }
+
+       void setf (std::ios_base::fmtflags flags, std::ios_base::fmtflags mask)
+       {
+               _stream.setf (flags, mask);
+       }
+
+private:
+       static boost::mutex _mutex;
+       std::stringstream _stream;
+};
+
+#endif
index 5598ef69f8388aae66098669ad9361e369691ab9..d2c573c1b404c2e37f07269897511be56f327851 100644 (file)
@@ -24,7 +24,6 @@
 
 #include <string>
 #include <vector>
-#include <sstream>
 #include <iostream>
 #include <boost/algorithm/string.hpp>
 #include <boost/scoped_array.hpp>
@@ -39,6 +38,7 @@
 #include "cross.h"
 #include "player_video.h"
 #include "encoded_data.h"
+#include "safe_stringstream.h"
 
 #include "i18n.h"
 
@@ -48,7 +48,6 @@
 #define LOG_ERROR_NC(...)   _log->log (__VA_ARGS__, Log::TYPE_ERROR);
 
 using std::string;
-using std::stringstream;
 using std::multimap;
 using std::vector;
 using std::list;
@@ -104,9 +103,9 @@ Server::process (shared_ptr<Socket> socket, struct timeval& after_read, struct t
        scoped_array<char> buffer (new char[length]);
        socket->read (reinterpret_cast<uint8_t*> (buffer.get()), length);
 
-       stringstream s (buffer.get());
+       string s (buffer.get());
        shared_ptr<cxml::Document> xml (new cxml::Document ("EncodingRequest"));
-       xml->read_stream (s);
+       xml->read_string (s);
        if (xml->number_child<int> ("Version") != SERVER_LINK_VERSION) {
                cerr << "Mismatched server/client versions\n";
                LOG_ERROR_NC ("Mismatched server/client versions");
@@ -180,7 +179,7 @@ Server::worker_thread ()
                        struct timeval end;
                        gettimeofday (&end, 0);
 
-                       stringstream message;
+                       SafeStringStream message;
                        message.precision (2);
                        message << fixed
                                << "Encoded frame " << frame << " from " << ip << ": "
@@ -251,14 +250,13 @@ Server::broadcast_received ()
                xmlpp::Document doc;
                xmlpp::Element* root = doc.create_root_node ("ServerAvailable");
                root->add_child("Threads")->add_child_text (raw_convert<string> (_worker_threads.size ()));
-               stringstream xml;
-               doc.write_to_stream (xml, "UTF-8");
+               string xml = doc.write_to_string ("UTF-8");
 
                shared_ptr<Socket> socket (new Socket);
                try {
                        socket->connect (boost::asio::ip::tcp::endpoint (_broadcast.send_endpoint.address(), Config::instance()->server_port_base() + 1));
-                       socket->write (xml.str().length() + 1);
-                       socket->write ((uint8_t *) xml.str().c_str(), xml.str().length() + 1);
+                       socket->write (xml.length() + 1);
+                       socket->write ((uint8_t *) xml.c_str(), xml.length() + 1);
                } catch (...) {
 
                }
index 9b0cd037679f9351c5a9112537dbef283235a4ed..14cb3af5999ac5ff7ccb434d39371addcbb18a6d 100644 (file)
@@ -27,7 +27,6 @@
 #include "ui_signaller.h"
 
 using std::string;
-using std::stringstream;
 using std::list;
 using std::vector;
 using std::cout;
@@ -116,9 +115,9 @@ try
                scoped_array<char> buffer (new char[length]);
                sock->read (reinterpret_cast<uint8_t*> (buffer.get()), length);
                
-               stringstream s (buffer.get());
+               string s (buffer.get());
                shared_ptr<cxml::Document> xml (new cxml::Document ("ServerAvailable"));
-               xml->read_stream (s);
+               xml->read_string (s);
 
                string const ip = sock->socket().remote_endpoint().address().to_string ();
                if (!server_found (ip)) {
index a573d43c407f8ac8a825190a1784600ba37ac873..1a17976657c42759a10566aaec00559de94e1ba9 100644 (file)
 #include "compose.hpp"
 #include "job.h"
 #include "util.h"
+#include "safe_stringstream.h"
 
 #include "i18n.h"
 
 using std::string;
-using std::stringstream;
 using std::cout;
 using boost::shared_ptr;
 using dcp::raw_convert;
@@ -79,7 +79,7 @@ SndfileContent::information () const
                return "";
        }
        
-       stringstream s;
+       SafeStringStream s;
 
        s << String::compose (
                _("%1 channels, %2kHz, %3 samples"),
index a8183d3444c7c426f47fcbcc3d60b70548039f47..167524017a0a2232eca56ff880d0b943e9091dde 100644 (file)
@@ -9,7 +9,6 @@
 #include <iomanip>
 #include <ostream>
 #include <stdexcept>
-#include <sstream>
 
 #include "stack.hpp"
 
index 1a162b6544ad1ba6442acbfbdcaab87d52b4bd95..23a46d06dddcb7875a9247911d387028a0da802e 100644 (file)
@@ -27,6 +27,7 @@
 #include "film.h"
 #include "transcoder.h"
 #include "log.h"
+#include "safe_stringstream.h"
 
 #include "i18n.h"
 
@@ -34,7 +35,6 @@
 #define LOG_ERROR_NC(...)   _film->log()->log (__VA_ARGS__, Log::TYPE_ERROR);
 
 using std::string;
-using std::stringstream;
 using std::fixed;
 using std::setprecision;
 using std::cout;
@@ -90,7 +90,7 @@ TranscodeJob::status () const
                return Job::status ();
        }
 
-       stringstream s;
+       SafeStringStream s;
 
        s << Job::status ();
 
index 44ecbb232c26b03214f23d3191c54fedd9a9071a..0146df48430deff9a410763e6a46bf7894b9af4d 100644 (file)
@@ -18,7 +18,6 @@
 */
 
 #include <string>
-#include <sstream>
 #include <boost/algorithm/string.hpp>
 #include <curl/curl.h>
 #include <libcxml/cxml.h>
@@ -26,6 +25,7 @@
 #include "update.h"
 #include "version.h"
 #include "ui_signaller.h"
+#include "safe_stringstream.h"
 
 #define BUFFER_SIZE 1024
 
@@ -113,10 +113,9 @@ UpdateChecker::thread ()
                        /* Parse the reply */
                        
                        _buffer[_offset] = '\0';
-                       stringstream s;
-                       s << _buffer;
+                       string s (_buffer);
                        cxml::Document doc ("Update");
-                       doc.read_stream (s);
+                       doc.read_string (s);
                        
                        {
                                boost::mutex::scoped_lock lm (_data_mutex);
index 60953b544d1a0c26b3816c674db3f9612b4ee181..c9685aa44ff3ee811e1f7e77e052b8047ca8ff1d 100644 (file)
@@ -22,7 +22,6 @@
  *  @brief Some utility functions and classes.
  */
 
-#include <sstream>
 #include <iomanip>
 #include <iostream>
 #include <fstream>
@@ -72,6 +71,7 @@ extern "C" {
 #include "rect.h"
 #include "md5_digester.h"
 #include "audio_processor.h"
+#include "safe_stringstream.h"
 #ifdef DCPOMATIC_WINDOWS
 #include "stack.hpp"
 #endif
@@ -79,7 +79,6 @@ extern "C" {
 #include "i18n.h"
 
 using std::string;
-using std::stringstream;
 using std::setfill;
 using std::ostream;
 using std::endl;
@@ -123,7 +122,7 @@ seconds_to_hms (int s)
        int h = m / 60;
        m -= (h * 60);
 
-       stringstream hms;
+       SafeStringStream hms;
        hms << h << N_(":");
        hms.width (2);
        hms << std::setfill ('0') << m << N_(":");
@@ -144,7 +143,7 @@ seconds_to_approximate_hms (int s)
        int h = m / 60;
        m -= (h * 60);
 
-       stringstream ap;
+       SafeStringStream ap;
 
        bool const hours = h > 0;
        bool const minutes = h < 10 && m > 0;
@@ -263,7 +262,7 @@ stacktrace (ostream& out, int levels)
 static string
 ffmpeg_version_to_string (int v)
 {
-       stringstream s;
+       SafeStringStream s;
        s << ((v & 0xff0000) >> 16) << N_(".") << ((v & 0xff00) >> 8) << N_(".") << (v & 0xff);
        return s.str ();
 }
@@ -889,7 +888,7 @@ divide_with_round (int64_t a, int64_t b)
 string
 dependency_version_summary ()
 {
-       stringstream s;
+       SafeStringStream s;
        s << N_("libopenjpeg ") << opj_version () << N_(", ")
          << N_("libavcodec ") << ffmpeg_version_to_string (avcodec_version()) << N_(", ")
          << N_("libavfilter ") << ffmpeg_version_to_string (avfilter_version()) << N_(", ")
index 0a3e378eecb1fda2f05ef3b6894659c6849386fe..796e6575a2e62f2088affaafea41a7240adb866b 100644 (file)
@@ -32,6 +32,7 @@
 #include "exceptions.h"
 #include "frame_rate_change.h"
 #include "log.h"
+#include "safe_stringstream.h"
 
 #include "i18n.h"
 
@@ -45,7 +46,6 @@ int const VideoContentProperty::VIDEO_SCALE     = 4;
 int const VideoContentProperty::COLOUR_CONVERSION = 5;
 
 using std::string;
-using std::stringstream;
 using std::setprecision;
 using std::cout;
 using std::vector;
@@ -217,7 +217,7 @@ VideoContent::information () const
                return "";
        }
        
-       stringstream s;
+       SafeStringStream s;
 
        s << String::compose (
                _("%1x%2 pixels (%3:1)"),
@@ -309,7 +309,7 @@ VideoContent::set_scale (VideoContentScale s)
 string
 VideoContent::identifier () const
 {
-       stringstream s;
+       SafeStringStream s;
        s << Content::identifier()
          << "_" << crop().left
          << "_" << crop().right
@@ -479,7 +479,7 @@ VideoContentScale::as_xml (xmlpp::Node* node) const
 string
 VideoContentScale::id () const
 {
-       stringstream s;
+       SafeStringStream s;
        
        if (_ratio) {
                s << _ratio->id () << "_";
index 15f26c34f2dcc91cfeef95d19a142301eebd5e38..2510ebe2a481b75d4d8b0c90f3916420f43350f7 100644 (file)
@@ -65,6 +65,7 @@ sources = """
           raw_image_proxy.cc
           render_subtitles.cc
           resampler.cc
+          safe_stringstream.cc
           scp_dcp_job.cc
           scaler.cc
           send_kdm_email_job.cc
index 8c7f09ae77de6fd4e8344ca12f3a528617991a6a..4246455378fb8c401aec5ac96206d54ff093ff0b 100644 (file)
@@ -65,7 +65,6 @@
 using std::cout;
 using std::string;
 using std::wstring;
-using std::stringstream;
 using std::map;
 using std::make_pair;
 using std::list;
index f9ed155445b5f1852c154b807195602c3d4567b6..6257d60af3f636e2a25eaf3464eebafa993c5ee3 100644 (file)
@@ -24,9 +24,9 @@
 #include "lib/kdm.h"
 #include "lib/config.h"
 #include "lib/exceptions.h"
+#include "lib/safe_stringstream.h"
 
 using std::string;
-using std::stringstream;
 using std::cout;
 using std::cerr;
 using std::list;
@@ -76,7 +76,7 @@ time_from_string (string t)
 static boost::posix_time::time_duration
 duration_from_string (string d)
 {
-       stringstream s (d);
+       SafeStringStream s (d);
        int N;
        string unit;
        s >> N >> unit;
index c74e258e8ff081680f3b799f354c5ee344ad937c..b816460a3376daadea18467caf49fb5e1a20ffd9 100644 (file)
@@ -20,7 +20,6 @@
 #include "lib/server.h"
 #include <iostream>
 #include <stdexcept>
-#include <sstream>
 #include <cstring>
 #include <vector>
 #include <unistd.h>
index 1d9b038997542374bd34f128921447cee8822671..5d1e546f7b92c78005e1df387344bd9c8d210c8d 100644 (file)
@@ -116,6 +116,7 @@ AboutDialog::AboutDialog (wxWindow* parent)
        wxArrayString supported_by;
        supported_by.Add (wxT ("Manual AC"));
        supported_by.Add (wxT ("Kambiz Afshar"));
+       supported_by.Add (wxT ("Alex Asp"));
        supported_by.Add (wxT ("Louis Belloisy"));
        supported_by.Add (wxT ("Mike Blakesley"));
        supported_by.Add (wxT ("Jeff Boot"));
index 6617b66d6ca44dbae258041628898663dda3c979..4a1e5074fa625073be95def3dcbc5b34fb39b5a6 100644 (file)
 #include <wx/spinctrl.h>
 #include <wx/gbsizer.h>
 #include "lib/colour_conversion.h"
+#include "lib/safe_stringstream.h"
 #include "wx_util.h"
 #include "colour_conversion_editor.h"
 
 using std::string;
 using std::cout;
-using std::stringstream;
 using boost::shared_ptr;
 using boost::lexical_cast;
 
@@ -110,7 +110,7 @@ ColourConversionEditor::set (ColourConversion conversion)
        _input_gamma_linearised->SetValue (conversion.input_gamma_linearised);
        for (int i = 0; i < 3; ++i) {
                for (int j = 0; j < 3; ++j) {
-                       stringstream s;
+                       SafeStringStream s;
                        s.setf (std::ios::fixed, std::ios::floatfield);
                        s.precision (7);
                        s << conversion.matrix (i, j);
index 37a8c880847391eb68d29bdbe7063c5940c4a7cc..1ce4695d6bf83c2e00c09df358667e5551374da1 100644 (file)
@@ -45,6 +45,7 @@
 #include "lib/content.h"
 #include "lib/content_factory.h"
 #include "lib/dcp_content.h"
+#include "lib/safe_stringstream.h"
 #include "timecode.h"
 #include "wx_util.h"
 #include "film_editor.h"
@@ -58,7 +59,6 @@
 
 using std::string;
 using std::cout;
-using std::stringstream;
 using std::pair;
 using std::fixed;
 using std::setprecision;
@@ -109,7 +109,6 @@ FilmEditor::film_changed (Film::Property p)
 
        _content_panel->film_changed (p);
        _dcp_panel->film_changed (p);
-
 }
 
 void
@@ -171,4 +170,3 @@ FilmEditor::active_jobs_changed (bool a)
 {
        set_general_sensitivity (!a);
 }
-
index df4aa7d2e78a740c786caffb1250a798c065a864..4c4ef049b8156ceda036ce3600235a0dc2ac2b5b 100644 (file)
@@ -17,7 +17,6 @@
 
 */
 
-#include <sstream>
 #include "lib/film.h"
 #include "lib/exceptions.h"
 #include "job_wrapper.h"
index 801996efa7bcb611111285a847c41848591f69b7..27fc75b1b39c649fd76b9890d1758e374f7af858 100644 (file)
 #include <boost/bind.hpp>
 #include "lib/film.h"
 #include "lib/config.h"
+#include "lib/safe_stringstream.h"
 #include "properties_dialog.h"
 #include "wx_util.h"
 
 using std::string;
-using std::stringstream;
 using std::fixed;
 using std::setprecision;
 using boost::shared_ptr;
@@ -47,7 +47,7 @@ PropertiesDialog::PropertiesDialog (wxWindow* parent, shared_ptr<Film> film)
        _encoded->Finished.connect (boost::bind (&PropertiesDialog::layout, this));
        _frames->SetLabel (std_to_wx (lexical_cast<string> (_film->length().frames (_film->video_frame_rate ()))));
        double const disk = double (_film->required_disk_space()) / 1073741824.0f;
-       stringstream s;
+       SafeStringStream s;
        s << fixed << setprecision (1) << disk << wx_to_std (_("Gb"));
        _disk->SetLabel (std_to_wx (s.str ()));
 
@@ -57,7 +57,7 @@ PropertiesDialog::PropertiesDialog (wxWindow* parent, shared_ptr<Film> film)
 string
 PropertiesDialog::frames_already_encoded () const
 {
-       stringstream u;
+       SafeStringStream u;
        try {
                u << _film->encoded_frames ();
        } catch (boost::thread_interrupted &) {
index a0e1f8f8a4845b8ebc9c852202d89818b55f8f01..27d5b9cd35f3f4e87bd771d3f76402c1f674592e 100644 (file)
@@ -166,9 +166,10 @@ TimingPanel::film_content_changed (int property)
                set<float> check;
                shared_ptr<VideoContent> vc;
                for (ContentList::const_iterator i = cl.begin (); i != cl.end(); ++i) {
-                       vc = dynamic_pointer_cast<VideoContent> (*i);
-                       if (vc) {
-                               check.insert (vc->video_frame_rate ());
+                       shared_ptr<VideoContent> t = dynamic_pointer_cast<VideoContent> (*i);
+                       if (t) {
+                               check.insert (t->video_frame_rate ());
+                               vc = t;
                        }
                }
                if (check.size() == 1) {
index f0a544e50a9f57ed178fb4705696fb14ca810d9f..01cff5b06c46fbb993eb397f68bdefc9a1329a0e 100644 (file)
@@ -21,7 +21,6 @@
  *  @brief Test some basic reading/writing of film metadata.
  */
 
-#include <sstream>
 #include <boost/test/unit_test.hpp>
 #include <boost/filesystem.hpp>
 #include <boost/date_time.hpp>