Remove all use of stringstream in an attempt to fix
[dcpomatic.git] / src / lib / content.cc
index 7afbf924f63912c5631caf1a8b138583ad3ca616..9c7e790402c157aa7ffec1ad20a7b1e79e30948d 100644 (file)
@@ -27,7 +27,6 @@
 #include "content_factory.h"
 #include "exceptions.h"
 #include "film.h"
-#include "safe_stringstream.h"
 #include "job.h"
 #include "compose.hpp"
 #include "raw_convert.h"
@@ -95,6 +94,7 @@ Content::Content (shared_ptr<const Film> film, cxml::ConstNodePtr node)
        _position = DCPTime (node->number_child<DCPTime::Type> ("Position"));
        _trim_start = ContentTime (node->number_child<ContentTime::Type> ("TrimStart"));
        _trim_end = ContentTime (node->number_child<ContentTime::Type> ("TrimEnd"));
+       _video_frame_rate = node->optional_number_child<double> ("VideoFrameRate");
 }
 
 Content::Content (shared_ptr<const Film> film, vector<shared_ptr<Content> > c)
@@ -102,6 +102,7 @@ Content::Content (shared_ptr<const Film> film, vector<shared_ptr<Content> > c)
        , _position (c.front()->position ())
        , _trim_start (c.front()->trim_start ())
        , _trim_end (c.back()->trim_end ())
+       , _video_frame_rate (c.front()->video_frame_rate())
        , _change_signals_frequent (false)
 {
        for (size_t i = 0; i < c.size(); ++i) {
@@ -113,6 +114,17 @@ Content::Content (shared_ptr<const Film> film, vector<shared_ptr<Content> > c)
                        throw JoinError (_("Only the last piece of content to be joined can have an end trim."));
                }
 
+               if (
+                       (_video_frame_rate && !c[i]->_video_frame_rate) ||
+                       (!_video_frame_rate && c[i]->_video_frame_rate)
+                       ) {
+                       throw JoinError (_("Content to be joined must have the same video frame rate"));
+               }
+
+               if (_video_frame_rate && fabs (_video_frame_rate.get() - c[i]->_video_frame_rate.get()) > VIDEO_FRAME_RATE_EPSILON) {
+                       throw JoinError (_("Content to be joined must have the same video frame rate"));
+               }
+
                for (size_t j = 0; j < c[i]->number_of_paths(); ++j) {
                        _paths.push_back (c[i]->path (j));
                }
@@ -131,6 +143,9 @@ Content::as_xml (xmlpp::Node* node) const
        node->add_child("Position")->add_child_text (raw_convert<string> (_position.get ()));
        node->add_child("TrimStart")->add_child_text (raw_convert<string> (_trim_start.get ()));
        node->add_child("TrimEnd")->add_child_text (raw_convert<string> (_trim_end.get ()));
+       if (_video_frame_rate) {
+               node->add_child("VideoFrameRate")->add_child_text (raw_convert<string> (_video_frame_rate.get()));
+       }
 }
 
 void
@@ -145,10 +160,10 @@ Content::examine (shared_ptr<Job> job)
        lm.unlock ();
 
        /* Some content files are very big, so we use a poor man's
-          digest here: a MD5 of the first and last 1e6 bytes with the
+          digest here: a digest of the first and last 1e6 bytes with the
           size of the first file tacked on the end as a string.
        */
-       string const d = md5_digest_head_tail (p, 1000000) + raw_convert<string> (boost::filesystem::file_size (p.front ()));
+       string const d = digest_head_tail (p, 1000000) + raw_convert<string> (boost::filesystem::file_size (p.front ()));
 
        lm.lock ();
        _digest = d;
@@ -238,14 +253,12 @@ Content::length_after_trim () const
 string
 Content::identifier () const
 {
-       SafeStringStream s;
-
-       s << Content::digest()
-         << "_" << position().get()
-         << "_" << trim_start().get()
-         << "_" << trim_end().get();
-
-       return s.str ();
+       char buffer[256];
+       snprintf (
+               buffer, sizeof(buffer), "%s_%" PRId64 "_%" PRId64 "_%" PRId64,
+               Content::digest().c_str(), position().get(), trim_start().get(), trim_end().get()
+               );
+       return buffer;
 }
 
 bool
@@ -343,9 +356,27 @@ Content::active_video_frame_rate () const
 void
 Content::add_properties (list<UserProperty>& p) const
 {
-       p.push_back (UserProperty (_("General"), _("Filename"), path(0).string ()));
+       p.push_back (UserProperty (UserProperty::GENERAL, _("Filename"), path(0).string ()));
 
        if (_video_frame_rate) {
-               p.push_back (UserProperty (_("General"), _("Video frame rate"), raw_convert<string> (_video_frame_rate.get(), 5), _("frames per second")));
+               if (video) {
+                       p.push_back (
+                               UserProperty (
+                                       UserProperty::VIDEO,
+                                       _("Frame rate"),
+                                       raw_convert<string> (_video_frame_rate.get(), 5),
+                                       _("frames per second")
+                                       )
+                               );
+               } else {
+                       p.push_back (
+                               UserProperty (
+                                       UserProperty::GENERAL,
+                                       _("Prepared for video frame rate"),
+                                       raw_convert<string> (_video_frame_rate.get(), 5),
+                                       _("frames per second")
+                                       )
+                               );
+               }
        }
 }