/*
Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
- This program is free software; you can redistribute it and/or modify
+ This file is part of DCP-o-matic.
+
+ DCP-o-matic 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,
+ DCP-o-matic 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.
+ along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
*/
#include "cross.h"
#include "job.h"
#include "log.h"
-#include "md5_digester.h"
+#include "digester.h"
#include "font.h"
#include "compose.hpp"
#include "audio_buffers.h"
#include <dcp/interop_subtitle_asset.h>
#include <dcp/smpte_subtitle_asset.h>
#include <boost/foreach.hpp>
+#include <boost/make_shared.hpp>
#include "i18n.h"
using std::list;
using std::string;
+using std::cout;
using boost::shared_ptr;
+using boost::make_shared;
using boost::optional;
using boost::dynamic_pointer_cast;
using dcp::Data;
if (!asset_file) {
LOG_GENERAL ("Could not open existing asset at %1 (errno=%2)", _picture_asset->file().string(), errno);
return;
+ } else {
+ LOG_GENERAL ("Opened existing asset at %1", _picture_asset->file().string());
}
/* Offset of the last dcp::FrameInfo in the info file */
int const n = (boost::filesystem::file_size (_film->info_file(_period)) / _info_size) - 1;
+ LOG_GENERAL ("The last FI is %1; info file is %2, info size %3", n, boost::filesystem::file_size (_film->info_file(_period)), _info_size);
FILE* info_file = fopen_boost (_film->info_file(_period), "rb");
if (!info_file) {
_first_nonexistant_frame = n;
}
- bool ok = false;
-
- while (!ok) {
- /* Read the data from the info file; for 3D we just check the left
- frames until we find a good one.
- */
- dcp::FrameInfo info = read_frame_info (info_file, _first_nonexistant_frame, _film->three_d () ? EYES_LEFT : EYES_BOTH);
-
- ok = true;
-
- /* Read the data from the asset and hash it */
- dcpomatic_fseek (asset_file, info.offset, SEEK_SET);
- Data data (info.size);
- size_t const read = fread (data.data().get(), 1, data.size(), asset_file);
- if (read != static_cast<size_t> (data.size ())) {
- LOG_GENERAL ("Existing frame %1 is incomplete", _first_nonexistant_frame);
- ok = false;
- } else {
- MD5Digester digester;
- digester.add (data.data().get(), data.size());
- if (digester.get() != info.hash) {
- LOG_GENERAL ("Existing frame %1 failed hash check", _first_nonexistant_frame);
- ok = false;
- }
- }
-
- if (!ok) {
- --_first_nonexistant_frame;
- }
+ while (!existing_picture_frame_ok(asset_file, info_file) && _first_nonexistant_frame > 0) {
+ --_first_nonexistant_frame;
}
- if (!_film->three_d ()) {
+ if (!_film->three_d() && _first_nonexistant_frame > 0) {
/* If we are doing 3D we might have found a good L frame with no R, so only
do this if we're in 2D and we've just found a good B(oth) frame.
*/
++_first_nonexistant_frame;
}
+ LOG_GENERAL ("Proceeding with first nonexistant frame %1", _first_nonexistant_frame);
+
fclose (asset_file);
fclose (info_file);
}
shared_ptr<dcp::Reel>
ReelWriter::create_reel (list<ReferencedReelAsset> const & refs, list<shared_ptr<Font> > const & fonts)
{
- shared_ptr<dcp::Reel> reel (new dcp::Reel ());
+ shared_ptr<dcp::Reel> reel = make_shared<dcp::Reel> ();
shared_ptr<dcp::ReelPictureAsset> reel_picture_asset;
}
reel->add (reel_picture_asset);
+ /* If we have a hash for this asset in the CPL, assume that it is correct */
+ if (reel_picture_asset->hash()) {
+ reel_picture_asset->asset_ref()->set_hash (reel_picture_asset->hash().get());
+ }
if (_sound_asset) {
/* We have made a sound asset of our own. Put it into the reel */
- reel->add (shared_ptr<dcp::ReelSoundAsset> (new dcp::ReelSoundAsset (_sound_asset, 0)));
+ reel->add (make_shared<dcp::ReelSoundAsset> (_sound_asset, 0));
} else {
/* We don't have a sound asset of our own; hopefully we have one to reference */
BOOST_FOREACH (ReferencedReelAsset j, refs) {
shared_ptr<dcp::ReelSoundAsset> k = dynamic_pointer_cast<dcp::ReelSoundAsset> (j.asset);
if (k && j.period == _period) {
reel->add (k);
+ /* If we have a hash for this asset in the CPL, assume that it is correct */
+ if (k->hash()) {
+ k->asset_ref()->set_hash (k->hash().get());
+ }
}
}
}
shared_ptr<dcp::ReelSubtitleAsset> k = dynamic_pointer_cast<dcp::ReelSubtitleAsset> (j.asset);
if (k && j.period == _period) {
reel->add (k);
+ /* If we have a hash for this asset in the CPL, assume that it is correct */
+ if (k->hash()) {
+ k->asset_ref()->set_hash (k->hash().get());
+ }
}
}
}
lang = "Unknown";
}
if (_film->interop ()) {
- shared_ptr<dcp::InteropSubtitleAsset> s (new dcp::InteropSubtitleAsset ());
+ shared_ptr<dcp::InteropSubtitleAsset> s = make_shared<dcp::InteropSubtitleAsset> ();
s->set_movie_title (_film->name ());
s->set_language (lang);
s->set_reel_number ("1");
_subtitle_asset = s;
} else {
- shared_ptr<dcp::SMPTESubtitleAsset> s (new dcp::SMPTESubtitleAsset ());
+ shared_ptr<dcp::SMPTESubtitleAsset> s = make_shared<dcp::SMPTESubtitleAsset> ();
s->set_content_title_text (_film->name ());
s->set_language (lang);
s->set_edit_rate (dcp::Fraction (_film->video_frame_rate (), 1));
_subtitle_asset->add (i);
}
}
+
+bool
+ReelWriter::existing_picture_frame_ok (FILE* asset_file, FILE* info_file) const
+{
+ LOG_GENERAL ("Checking existing picture frame %1", _first_nonexistant_frame);
+
+ /* Read the data from the info file; for 3D we just check the left
+ frames until we find a good one.
+ */
+ dcp::FrameInfo const info = read_frame_info (info_file, _first_nonexistant_frame, _film->three_d () ? EYES_LEFT : EYES_BOTH);
+
+ bool ok = true;
+
+ /* Read the data from the asset and hash it */
+ dcpomatic_fseek (asset_file, info.offset, SEEK_SET);
+ Data data (info.size);
+ size_t const read = fread (data.data().get(), 1, data.size(), asset_file);
+ LOG_GENERAL ("Read %1 bytes of asset data; wanted %2", read, info.size);
+ if (read != static_cast<size_t> (data.size ())) {
+ LOG_GENERAL ("Existing frame %1 is incomplete", _first_nonexistant_frame);
+ ok = false;
+ } else {
+ Digester digester;
+ digester.add (data.data().get(), data.size());
+ LOG_GENERAL ("Hash %1 vs %2", digester.get(), info.hash);
+ if (digester.get() != info.hash) {
+ LOG_GENERAL ("Existing frame %1 failed hash check", _first_nonexistant_frame);
+ ok = false;
+ }
+ }
+
+ return ok;
+}