Try to fix up paths for video MXFs, hashes and temporarily-stored frames.
[dcpomatic.git] / src / lib / dcp_video_frame.cc
index 996aff33f7016d7c86f7e2a75ac537185543faab..5df2d7a46b61b8219467c933671e505f138cd51d 100644 (file)
 using std::string;
 using std::stringstream;
 using std::ofstream;
+using std::cout;
 using boost::shared_ptr;
+using libdcp::Size;
 
 /** Construct a DCP video frame.
  *  @param input Input image.
  *  @param out Required size of output, in pixels (including any padding).
  *  @param s Scaler to use.
  *  @param p Number of pixels of padding either side of the image.
- *  @param f Index of the frame within the Film.
- *  @param fps Frames per second of the Film.
+ *  @param f Index of the frame within the DCP's intrinsic duration.
+ *  @param fps Frames per second of the Film's source.
  *  @param pp FFmpeg post-processing string to use.
  *  @param clut Colour look-up table to use (see Config::colour_lut_index ())
  *  @param bw J2K bandwidth to use (see Config::j2k_bandwidth ())
@@ -76,7 +78,7 @@ using boost::shared_ptr;
 DCPVideoFrame::DCPVideoFrame (
        shared_ptr<const Image> yuv, shared_ptr<Subtitle> sub,
        Size out, int p, int subtitle_offset, float subtitle_scale,
-       Scaler const * s, SourceFrame f, float fps, string pp, int clut, int bw, Log* l
+       Scaler const * s, int f, float fps, string pp, int clut, int bw, Log* l
        )
        : _input (yuv)
        , _subtitle (sub)
@@ -86,9 +88,9 @@ DCPVideoFrame::DCPVideoFrame (
        , _subtitle_scale (subtitle_scale)
        , _scaler (s)
        , _frame (f)
-       , _frames_per_second (dcp_frame_rate(fps).frames_per_second)
+       , _frames_per_second (DCPFrameRate(fps).frames_per_second)
        , _post_process (pp)
-       , _colour_lut_index (clut)
+       , _colour_lut (clut)
        , _j2k_bandwidth (bw)
        , _log (l)
        , _image (0)
@@ -154,10 +156,10 @@ shared_ptr<EncodedData>
 DCPVideoFrame::encode_locally ()
 {
        if (!_post_process.empty ()) {
-               _input = _input->post_process (_post_process);
+               _input = _input->post_process (_post_process, true);
        }
        
-       shared_ptr<Image> prepared = _input->scale_and_convert_to_rgb (_out_size, _padding, _scaler);
+       shared_ptr<Image> prepared = _input->scale_and_convert_to_rgb (_out_size, _padding, _scaler, true);
 
        if (_subtitle) {
                Rect tx = subtitle_transformed_area (
@@ -166,7 +168,7 @@ DCPVideoFrame::encode_locally ()
                        _subtitle->area(), _subtitle_offset, _subtitle_scale
                        );
 
-               shared_ptr<Image> im = _subtitle->image()->scale (tx.size(), _scaler);
+               shared_ptr<Image> im = _subtitle->image()->scale (tx.size(), _scaler, true);
                prepared->alpha_blend (im, tx.position());
        }
 
@@ -188,22 +190,22 @@ DCPVideoFrame::encode_locally ()
                for (int x = 0; x < _out_size.width; ++x) {
 
                        /* In gamma LUT (converting 8-bit input to 12-bit) */
-                       s.r = lut_in[_colour_lut_index][*p++ << 4];
-                       s.g = lut_in[_colour_lut_index][*p++ << 4];
-                       s.b = lut_in[_colour_lut_index][*p++ << 4];
+                       s.r = lut_in[_colour_lut][*p++ << 4];
+                       s.g = lut_in[_colour_lut][*p++ << 4];
+                       s.b = lut_in[_colour_lut][*p++ << 4];
                        
                        /* RGB to XYZ Matrix */
-                       d.x = ((s.r * color_matrix[_colour_lut_index][0][0]) +
-                              (s.g * color_matrix[_colour_lut_index][0][1]) +
-                              (s.b * color_matrix[_colour_lut_index][0][2]));
+                       d.x = ((s.r * color_matrix[_colour_lut][0][0]) +
+                              (s.g * color_matrix[_colour_lut][0][1]) +
+                              (s.b * color_matrix[_colour_lut][0][2]));
                        
-                       d.y = ((s.r * color_matrix[_colour_lut_index][1][0]) +
-                              (s.g * color_matrix[_colour_lut_index][1][1]) +
-                              (s.b * color_matrix[_colour_lut_index][1][2]));
+                       d.y = ((s.r * color_matrix[_colour_lut][1][0]) +
+                              (s.g * color_matrix[_colour_lut][1][1]) +
+                              (s.b * color_matrix[_colour_lut][1][2]));
                        
-                       d.z = ((s.r * color_matrix[_colour_lut_index][2][0]) +
-                              (s.g * color_matrix[_colour_lut_index][2][1]) +
-                              (s.b * color_matrix[_colour_lut_index][2][2]));
+                       d.z = ((s.r * color_matrix[_colour_lut][2][0]) +
+                              (s.g * color_matrix[_colour_lut][2][1]) +
+                              (s.b * color_matrix[_colour_lut][2][2]));
                        
                        /* DCI companding */
                        d.x = d.x * DCI_COEFFICENT * (DCI_LUT_SIZE - 1);
@@ -334,8 +336,8 @@ DCPVideoFrame::encode_remotely (ServerDescription const * serv)
                s << "post_process " << _post_process << "\n";
        }
        
-       s << "colour_lut " << Config::instance()->colour_lut_index () << "\n"
-         << "j2k_bandwidth " << Config::instance()->j2k_bandwidth () << "\n";
+       s << "colour_lut " << _colour_lut << "\n"
+         << "j2k_bandwidth " << _j2k_bandwidth << "\n";
 
        if (_subtitle) {
                s << "subtitle_x " << _subtitle->position().x << "\n"
@@ -371,34 +373,63 @@ DCPVideoFrame::encode_remotely (ServerDescription const * serv)
        return e;
 }
 
+EncodedData::EncodedData (int s)
+       : _data (new uint8_t[s])
+       , _size (s)
+{
+
+}
+
+EncodedData::EncodedData (string file)
+{
+       _size = boost::filesystem::file_size (file);
+       _data = new uint8_t[_size];
+
+       FILE* f = fopen (file.c_str(), "rb");
+       if (!f) {
+               throw FileError ("could not open file for reading", file);
+       }
+       
+       fread (_data, 1, _size, f);
+       fclose (f);
+}
+
+
+EncodedData::~EncodedData ()
+{
+       delete[] _data;
+}
+
 /** Write this data to a J2K file.
- *  @param opt Options.
- *  @param frame Frame index.
+ *  @param Film Film.
+ *  @param frame DCP frame index.
  */
 void
-EncodedData::write (shared_ptr<const EncodeOptions> opt, SourceFrame frame)
+EncodedData::write (shared_ptr<const Film> film, int frame) const
 {
-       string const tmp_j2k = opt->frame_out_path (frame, true);
+       string const tmp_j2c = film->j2c_path (frame, true);
 
-       FILE* f = fopen (tmp_j2k.c_str (), "wb");
+       FILE* f = fopen (tmp_j2c.c_str (), "wb");
        
        if (!f) {
-               throw WriteFileError (tmp_j2k, errno);
+               throw WriteFileError (tmp_j2c, errno);
        }
 
        fwrite (_data, 1, _size, f);
        fclose (f);
 
-       string const real_j2k = opt->frame_out_path (frame, false);
+       string const real_j2c = film->j2c_path (frame, false);
 
        /* Rename the file from foo.j2c.tmp to foo.j2c now that it is complete */
-       boost::filesystem::rename (tmp_j2k, real_j2k);
+       boost::filesystem::rename (tmp_j2c, real_j2c);
+}
 
-       /* Write a file containing the hash */
-       string const hash = real_j2k + ".md5";
+void
+EncodedData::write_hash (shared_ptr<const Film> film, int frame) const
+{
+       string const hash = film->hash_path (frame);
        ofstream h (hash.c_str());
        h << md5_digest (_data, _size) << "\n";
-       h.close ();
 }
 
 /** Send this data to a socket.
@@ -413,14 +444,15 @@ EncodedData::send (shared_ptr<Socket> socket)
        socket->write (_data, _size, 30);
 }
 
-/** @param s Size of data in bytes */
-RemotelyEncodedData::RemotelyEncodedData (int s)
-       : EncodedData (new uint8_t[s], s)
+LocallyEncodedData::LocallyEncodedData (uint8_t* d, int s)
+       : EncodedData (s)
 {
-
+       memcpy (_data, d, s);
 }
 
-RemotelyEncodedData::~RemotelyEncodedData ()
+/** @param s Size of data in bytes */
+RemotelyEncodedData::RemotelyEncodedData (int s)
+       : EncodedData (s)
 {
-       delete[] _data;
+
 }