summaryrefslogtreecommitdiff
path: root/src/lib/writer.cc
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2015-06-10 16:12:40 +0100
committerCarl Hetherington <cth@carlh.net>2015-06-10 16:12:40 +0100
commit7cd7b360169493d864206e2cdfb4f688cf5a12cf (patch)
tree4ee0d8d6bbdbd52631e874bf0a1a73ca209d8243 /src/lib/writer.cc
parent5e8f1fb8d6dac786983a8e96cc6ee119506c200a (diff)
Resurrect neater repeat-write handling.
Diffstat (limited to 'src/lib/writer.cc')
-rw-r--r--src/lib/writer.cc96
1 files changed, 89 insertions, 7 deletions
diff --git a/src/lib/writer.cc b/src/lib/writer.cc
index 527fb3701..5c711ef92 100644
--- a/src/lib/writer.cc
+++ b/src/lib/writer.cc
@@ -86,6 +86,7 @@ Writer::Writer (shared_ptr<const Film> f, weak_ptr<Job> j)
, _maximum_frames_in_memory (0)
, _full_written (0)
, _fake_written (0)
+ , _repeat_written (0)
, _pushed_to_disk (0)
{
/* Remove any old DCP */
@@ -191,6 +192,33 @@ Writer::write (Data encoded, int frame, Eyes eyes)
}
void
+Writer::repeat (int frame, Eyes eyes)
+{
+ boost::mutex::scoped_lock lock (_mutex);
+
+ while (_queued_full_in_memory > _maximum_frames_in_memory) {
+ /* The queue is too big; wait until that is sorted out */
+ _full_condition.wait (lock);
+ }
+
+ QueueItem qi;
+ qi.type = QueueItem::REPEAT;
+ qi.frame = frame;
+ if (_film->three_d() && eyes == EYES_BOTH) {
+ qi.eyes = EYES_LEFT;
+ _queue.push_back (qi);
+ qi.eyes = EYES_RIGHT;
+ _queue.push_back (qi);
+ } else {
+ qi.eyes = eyes;
+ _queue.push_back (qi);
+ }
+
+ /* Now there's something to do: wake anything wait()ing on _empty_condition */
+ _empty_condition.notify_all ();
+}
+
+void
Writer::fake_write (int frame, Eyes eyes)
{
boost::mutex::scoped_lock lock (_mutex);
@@ -265,6 +293,20 @@ Writer::have_sequenced_image_at_queue_head ()
}
void
+Writer::write_frame_info (int frame, Eyes eyes, dcp::FrameInfo info) const
+{
+ FILE* file = fopen_boost (_film->info_file(), "ab");
+ if (!file) {
+ throw OpenFileError (_film->info_file ());
+ }
+ dcpomatic_fseek (file, frame_info_position (frame, eyes), SEEK_SET);
+ fwrite (&info.offset, sizeof (info.offset), 1, file);
+ fwrite (&info.size, sizeof (info.size), 1, file);
+ fwrite (info.hash.c_str(), 1, info.hash.size(), file);
+ fclose (file);
+}
+
+void
Writer::thread ()
try
{
@@ -332,12 +374,7 @@ try
}
dcp::FrameInfo fin = _picture_asset_writer->write (qi.encoded->data().get (), qi.encoded->size());
- FILE* file = fopen_boost (_film->info_file(), "ab");
- if (!file) {
- throw OpenFileError (_film->info_file ());
- }
- write_frame_info (file, qi.frame, qi.eyes, fin);
- fclose (file);
+ write_frame_info (qi.frame, qi.eyes, fin);
_last_written[qi.eyes] = qi.encoded;
++_full_written;
break;
@@ -348,6 +385,15 @@ try
_last_written[qi.eyes].reset ();
++_fake_written;
break;
+ case QueueItem::REPEAT:
+ LOG_GENERAL (N_("Writer REPEAT-writes %1"), qi.frame);
+ dcp::FrameInfo fin = _picture_asset_writer->write (
+ _last_written[qi.eyes]->data().get(),
+ _last_written[qi.eyes]->size()
+ );
+ write_frame_info (qi.frame, qi.eyes, fin);
+ ++_repeat_written;
+ break;
}
lock.lock ();
@@ -578,7 +624,7 @@ Writer::finish ()
dcp.write_xml (_film->interop () ? dcp::INTEROP : dcp::SMPTE, meta, signer);
LOG_GENERAL (
- N_("Wrote %1 FULL, %2 FAKE, %3 pushed to disk"), _full_written, _fake_written, _pushed_to_disk
+ N_("Wrote %1 FULL, %2 FAKE, %3 REPEAT, %4 pushed to disk"), _full_written, _fake_written, _repeat_written, _pushed_to_disk
);
}
@@ -728,3 +774,39 @@ Writer::set_encoder_threads (int threads)
{
_maximum_frames_in_memory = rint (threads * 1.1);
}
+
+long
+Writer::frame_info_position (int frame, Eyes eyes) const
+{
+ static int const info_size = 48;
+
+ 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);
+}
+
+dcp::FrameInfo
+Writer::read_frame_info (FILE* file, int frame, Eyes eyes) const
+{
+ dcp::FrameInfo info;
+ dcpomatic_fseek (file, frame_info_position (frame, eyes), SEEK_SET);
+ fread (&info.offset, sizeof (info.offset), 1, file);
+ fread (&info.size, sizeof (info.size), 1, file);
+
+ char hash_buffer[33];
+ fread (hash_buffer, 1, 32, file);
+ hash_buffer[32] = '\0';
+ info.hash = hash_buffer;
+
+ return info;
+}