summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2024-03-26 22:43:10 +0100
committerCarl Hetherington <cth@carlh.net>2024-04-21 23:18:23 +0200
commitf7518583f90a866a07d8069a78bebcea82b2b248 (patch)
tree92af4f01ff048248fcf7eeb6e65d7d8408d89807
parentfa15dc1a375e13d2047a857e5aef202179eec0d4 (diff)
Extract frame info read/write to new class.
-rw-r--r--src/lib/frame_info.cc84
-rw-r--r--src/lib/frame_info.h45
-rw-r--r--src/lib/reel_writer.cc65
-rw-r--r--src/lib/reel_writer.h6
-rw-r--r--src/lib/writer.cc7
-rw-r--r--src/lib/wscript1
-rw-r--r--test/reel_writer_test.cc39
7 files changed, 160 insertions, 87 deletions
diff --git a/src/lib/frame_info.cc b/src/lib/frame_info.cc
new file mode 100644
index 000000000..f348bca6a
--- /dev/null
+++ b/src/lib/frame_info.cc
@@ -0,0 +1,84 @@
+/*
+ Copyright (C) 2024 Carl Hetherington <cth@carlh.net>
+
+ 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.
+
+ 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 DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+
+#include "frame_info.h"
+#include <string>
+
+
+using std::shared_ptr;
+using std::string;
+
+
+J2KFrameInfo::J2KFrameInfo(uint64_t offset_, uint64_t size_, string hash_)
+ : dcp::J2KFrameInfo(offset_, size_, hash_)
+{
+
+}
+
+
+J2KFrameInfo::J2KFrameInfo(dcp::J2KFrameInfo const& info)
+ : dcp::J2KFrameInfo(info)
+{
+
+}
+
+
+J2KFrameInfo::J2KFrameInfo(shared_ptr<InfoFileHandle> info_file, Frame frame, Eyes eyes)
+{
+ info_file->get().seek(position(frame, eyes), SEEK_SET);
+ info_file->get().checked_read(&offset, sizeof(offset));
+ info_file->get().checked_read(&size, sizeof(size));
+
+ char hash_buffer[33];
+ info_file->get().checked_read(hash_buffer, 32);
+ hash_buffer[32] = '\0';
+ hash = hash_buffer;
+}
+
+
+long
+J2KFrameInfo::position(Frame frame, Eyes eyes) const
+{
+ switch (eyes) {
+ case Eyes::BOTH:
+ return frame * _size_on_disk;
+ case Eyes::LEFT:
+ return frame * _size_on_disk * 2;
+ case Eyes::RIGHT:
+ return frame * _size_on_disk * 2 + _size_on_disk;
+ default:
+ DCPOMATIC_ASSERT(false);
+ }
+
+ DCPOMATIC_ASSERT(false);
+}
+
+
+/** @param frame reel-relative frame */
+void
+J2KFrameInfo::write(shared_ptr<InfoFileHandle> info_file, Frame frame, Eyes eyes) const
+{
+ info_file->get().seek(position(frame, eyes), SEEK_SET);
+ info_file->get().checked_write(&offset, sizeof(offset));
+ info_file->get().checked_write(&size, sizeof(size));
+ info_file->get().checked_write(hash.c_str(), hash.size());
+}
+
diff --git a/src/lib/frame_info.h b/src/lib/frame_info.h
new file mode 100644
index 000000000..a5a22bd9e
--- /dev/null
+++ b/src/lib/frame_info.h
@@ -0,0 +1,45 @@
+/*
+ Copyright (C) 2024 Carl Hetherington <cth@carlh.net>
+
+ 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.
+
+ 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 DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+
+#include "film.h"
+#include <dcp/frame_info.h>
+#include <memory>
+
+
+class J2KFrameInfo : public dcp::J2KFrameInfo
+{
+public:
+ J2KFrameInfo(dcp::J2KFrameInfo const& info);
+ J2KFrameInfo(uint64_t offset_, uint64_t size_, std::string hash_);
+ J2KFrameInfo(std::shared_ptr<InfoFileHandle> info_file, Frame frame, Eyes eyes);
+
+ void write(std::shared_ptr<InfoFileHandle> info_file, Frame frame, Eyes eyes) const;
+
+ static int size_on_disk() {
+ return _size_on_disk;
+ }
+
+private:
+ long position(Frame frame, Eyes eyes) const;
+
+ static constexpr auto _size_on_disk = 32 + sizeof(dcp::J2KFrameInfo::offset) + sizeof(dcp::J2KFrameInfo::size);
+};
+
diff --git a/src/lib/reel_writer.cc b/src/lib/reel_writer.cc
index 1cca3fd17..201c23e71 100644
--- a/src/lib/reel_writer.cc
+++ b/src/lib/reel_writer.cc
@@ -28,6 +28,7 @@
#include "digester.h"
#include "film.h"
#include "film_util.h"
+#include "frame_info.h"
#include "image.h"
#include "image_png.h"
#include "job.h"
@@ -81,9 +82,6 @@ using dcp::raw_convert;
using namespace dcpomatic;
-int const ReelWriter::_info_size = 48;
-
-
static dcp::MXFMetadata
mxf_metadata ()
{
@@ -215,53 +213,6 @@ ReelWriter::ReelWriter (
}
-/** @param frame reel-relative frame */
-void
-ReelWriter::write_frame_info (Frame frame, Eyes eyes, dcp::FrameInfo info) const
-{
- auto handle = film()->info_file_handle(_period, false);
- handle->get().seek(frame_info_position(frame, eyes), SEEK_SET);
- handle->get().checked_write(&info.offset, sizeof(info.offset));
- handle->get().checked_write(&info.size, sizeof(info.size));
- handle->get().checked_write(info.hash.c_str(), info.hash.size());
-}
-
-
-dcp::FrameInfo
-ReelWriter::read_frame_info (shared_ptr<InfoFileHandle> info, Frame frame, Eyes eyes) const
-{
- dcp::FrameInfo frame_info;
- info->get().seek(frame_info_position(frame, eyes), SEEK_SET);
- info->get().checked_read(&frame_info.offset, sizeof(frame_info.offset));
- info->get().checked_read(&frame_info.size, sizeof(frame_info.size));
-
- char hash_buffer[33];
- info->get().checked_read(hash_buffer, 32);
- hash_buffer[32] = '\0';
- frame_info.hash = hash_buffer;
-
- return frame_info;
-}
-
-
-long
-ReelWriter::frame_info_position (Frame frame, Eyes eyes) const
-{
- switch (eyes) {
- case Eyes::BOTH:
- return frame * _info_size;
- case Eyes::LEFT:
- return frame * _info_size * 2;
- case Eyes::RIGHT:
- return frame * _info_size * 2 + _info_size;
- default:
- DCPOMATIC_ASSERT (false);
- }
-
- DCPOMATIC_ASSERT (false);
-}
-
-
Frame
ReelWriter::check_existing_picture_asset (boost::filesystem::path asset)
{
@@ -290,8 +241,8 @@ ReelWriter::check_existing_picture_asset (boost::filesystem::path asset)
}
/* Offset of the last dcp::FrameInfo in the info file */
- int const n = (dcp::filesystem::file_size(info_file->get().path()) / _info_size) - 1;
- LOG_GENERAL ("The last FI is %1; info file is %2, info size %3", n, dcp::filesystem::file_size(info_file->get().path()), _info_size);
+ int const n = (dcp::filesystem::file_size(info_file->get().path()) / J2KFrameInfo::size_on_disk()) - 1;
+ LOG_GENERAL("The last FI is %1; info file is %2, info size %3", n, dcp::filesystem::file_size(info_file->get().path()), J2KFrameInfo::size_on_disk())
Frame first_nonexistent_frame;
if (film()->three_d()) {
@@ -326,8 +277,8 @@ ReelWriter::write (shared_ptr<const Data> encoded, Frame frame, Eyes eyes)
return;
}
- auto fin = _picture_asset_writer->write (encoded->data(), encoded->size());
- write_frame_info (frame, eyes, fin);
+ auto fin = J2KFrameInfo(_j2k_picture_asset_writer->write(encoded->data(), encoded->size()));
+ fin.write(film()->info_file_handle(_period, false), frame, eyes);
_last_written[eyes] = encoded;
}
@@ -368,8 +319,8 @@ ReelWriter::repeat_write (Frame frame, Eyes eyes)
return;
}
- auto fin = _picture_asset_writer->write(_last_written[eyes]->data(), _last_written[eyes]->size());
- write_frame_info (frame, eyes, fin);
+ auto fin = J2KFrameInfo(_j2k_picture_asset_writer->write(_last_written[eyes]->data(), _last_written[eyes]->size()));
+ fin.write(film()->info_file_handle(_period, false), frame, eyes);
}
@@ -1012,7 +963,7 @@ ReelWriter::existing_picture_frame_ok (dcp::File& asset_file, shared_ptr<InfoFil
/* Read the data from the info file; for 3D we just check the left
frames until we find a good one.
*/
- auto const info = read_frame_info (info_file, frame, film()->three_d() ? Eyes::LEFT : Eyes::BOTH);
+ auto const info = J2KFrameInfo(info_file, frame, film()->three_d() ? Eyes::LEFT : Eyes::BOTH);
bool ok = true;
diff --git a/src/lib/reel_writer.h b/src/lib/reel_writer.h
index 6f47c6740..30abdd563 100644
--- a/src/lib/reel_writer.h
+++ b/src/lib/reel_writer.h
@@ -95,14 +95,10 @@ public:
return _first_nonexistent_frame;
}
- dcp::FrameInfo read_frame_info (std::shared_ptr<InfoFileHandle> info, Frame frame, Eyes eyes) const;
-
private:
friend struct ::write_frame_info_test;
- void write_frame_info (Frame frame, Eyes eyes, dcp::FrameInfo info) const;
- long frame_info_position (Frame frame, Eyes eyes) const;
Frame check_existing_picture_asset (boost::filesystem::path asset);
bool existing_picture_frame_ok (dcp::File& asset_file, std::shared_ptr<InfoFileHandle> info_file, Frame frame) const;
std::shared_ptr<dcp::SubtitleAsset> empty_text_asset (TextType type, boost::optional<DCPTextTrack> track, bool with_dummy) const;
@@ -146,6 +142,4 @@ private:
std::shared_ptr<dcp::AtmosAssetWriter> _atmos_asset_writer;
mutable FontMetrics _font_metrics;
-
- static int const _info_size;
};
diff --git a/src/lib/writer.cc b/src/lib/writer.cc
index fbe2d248d..1c04f4065 100644
--- a/src/lib/writer.cc
+++ b/src/lib/writer.cc
@@ -30,6 +30,7 @@
#include "dcpomatic_log.h"
#include "film.h"
#include "film_util.h"
+#include "frame_info.h"
#include "job.h"
#include "log.h"
#include "ratio.h"
@@ -229,11 +230,7 @@ Writer::fake_write (Frame frame, Eyes eyes)
QueueItem qi;
qi.type = QueueItem::Type::FAKE;
-
- {
- shared_ptr<InfoFileHandle> info_file = film()->info_file_handle(_reels[reel].period(), true);
- qi.size = _reels[reel].read_frame_info(info_file, frame_in_reel, eyes).size;
- }
+ qi.size = J2KFrameInfo(film()->info_file_handle(_reels[reel].period(), true), frame_in_reel, eyes).size;
DCPOMATIC_ASSERT((film()->three_d() && eyes != Eyes::BOTH) || (!film()->three_d() && eyes == Eyes::BOTH));
diff --git a/src/lib/wscript b/src/lib/wscript
index 152d3abaf..8e839cb49 100644
--- a/src/lib/wscript
+++ b/src/lib/wscript
@@ -98,6 +98,7 @@ sources = """
examine_ffmpeg_subtitles_job.cc
exceptions.cc
export_config.cc
+ frame_info.cc
file_group.cc
file_log.cc
filter_graph.cc
diff --git a/test/reel_writer_test.cc b/test/reel_writer_test.cc
index ec2469898..f81e8e333 100644
--- a/test/reel_writer_test.cc
+++ b/test/reel_writer_test.cc
@@ -30,6 +30,7 @@
#include "lib/content_factory.h"
#include "lib/cross.h"
#include "lib/film.h"
+#include "lib/frame_info.h"
#include "lib/reel_writer.h"
#include "lib/video_content.h"
#include "test.h"
@@ -46,9 +47,9 @@ using std::string;
using boost::optional;
-static bool equal (dcp::FrameInfo a, ReelWriter const & writer, shared_ptr<InfoFileHandle> file, Frame frame, Eyes eyes)
+static bool equal(J2KFrameInfo a, shared_ptr<InfoFileHandle> file, Frame frame, Eyes eyes)
{
- auto b = writer.read_frame_info(file, frame, eyes);
+ auto b = J2KFrameInfo(file, frame, eyes);
return a.offset == b.offset && a.size == b.size && a.hash == b.hash;
}
@@ -61,44 +62,44 @@ BOOST_AUTO_TEST_CASE (write_frame_info_test)
/* Write the first one */
- dcp::FrameInfo info1(0, 123, "12345678901234567890123456789012");
- writer.write_frame_info (0, Eyes::LEFT, info1);
+ J2KFrameInfo info1(0, 123, "12345678901234567890123456789012");
+ info1.write(film->info_file_handle(period, false), 0, Eyes::LEFT);
{
auto file = film->info_file_handle(period, true);
- BOOST_CHECK (equal(info1, writer, file, 0, Eyes::LEFT));
+ BOOST_CHECK(equal(info1, file, 0, Eyes::LEFT));
}
/* Write some more */
- dcp::FrameInfo info2(596, 14921, "123acb789f1234ae782012n456339522");
- writer.write_frame_info (5, Eyes::RIGHT, info2);
+ J2KFrameInfo info2(596, 14921, "123acb789f1234ae782012n456339522");
+ info2.write(film->info_file_handle(period, false), 5, Eyes::RIGHT);
{
auto file = film->info_file_handle(period, true);
- BOOST_CHECK (equal(info1, writer, file, 0, Eyes::LEFT));
- BOOST_CHECK (equal(info2, writer, file, 5, Eyes::RIGHT));
+ BOOST_CHECK(equal(info1, file, 0, Eyes::LEFT));
+ BOOST_CHECK(equal(info2, file, 5, Eyes::RIGHT));
}
- dcp::FrameInfo info3(12494, 99157123, "xxxxyyyyabc12356ffsfdsf456339522");
- writer.write_frame_info (10, Eyes::LEFT, info3);
+ J2KFrameInfo info3(12494, 99157123, "xxxxyyyyabc12356ffsfdsf456339522");
+ info3.write(film->info_file_handle(period, false), 10, Eyes::LEFT);
{
auto file = film->info_file_handle(period, true);
- BOOST_CHECK (equal(info1, writer, file, 0, Eyes::LEFT));
- BOOST_CHECK (equal(info2, writer, file, 5, Eyes::RIGHT));
- BOOST_CHECK (equal(info3, writer, file, 10, Eyes::LEFT));
+ BOOST_CHECK(equal(info1, file, 0, Eyes::LEFT));
+ BOOST_CHECK(equal(info2, file, 5, Eyes::RIGHT));
+ BOOST_CHECK(equal(info3, file, 10, Eyes::LEFT));
}
/* Overwrite one */
- dcp::FrameInfo info4(55512494, 123599157123, "ABCDEFGyabc12356ffsfdsf4563395ZZ");
- writer.write_frame_info (5, Eyes::RIGHT, info4);
+ J2KFrameInfo info4(55512494, 123599157123, "ABCDEFGyabc12356ffsfdsf4563395ZZ");
+ info4.write(film->info_file_handle(period, false), 5, Eyes::RIGHT);
{
auto file = film->info_file_handle(period, true);
- BOOST_CHECK (equal(info1, writer, file, 0, Eyes::LEFT));
- BOOST_CHECK (equal(info4, writer, file, 5, Eyes::RIGHT));
- BOOST_CHECK (equal(info3, writer, file, 10, Eyes::LEFT));
+ BOOST_CHECK(equal(info1, file, 0, Eyes::LEFT));
+ BOOST_CHECK(equal(info4, file, 5, Eyes::RIGHT));
+ BOOST_CHECK(equal(info3, file, 10, Eyes::LEFT));
}
}