summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2013-07-23 11:14:44 +0100
committerCarl Hetherington <cth@carlh.net>2013-07-23 11:14:44 +0100
commit4eb77be6999a3758998bfe37b28d4bb1cd55d51e (patch)
tree9e2882f27751ee6badb1ee9b333bf1d012bd083b /src/lib
parentfa4bac5dd1b8d0e09bd4a4eb20c83c0564858649 (diff)
Various 3D fixes.
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/dcp_video_frame.cc14
-rw-r--r--src/lib/encoder.cc8
-rw-r--r--src/lib/player.cc3
-rw-r--r--src/lib/writer.cc81
4 files changed, 76 insertions, 30 deletions
diff --git a/src/lib/dcp_video_frame.cc b/src/lib/dcp_video_frame.cc
index 10f1e4ad1..4f6ff9987 100644
--- a/src/lib/dcp_video_frame.cc
+++ b/src/lib/dcp_video_frame.cc
@@ -185,7 +185,19 @@ DCPVideoFrame::encode_locally ()
throw EncodeError (N_("JPEG2000 encoding failed"));
}
- _log->log (String::compose (N_("Finished locally-encoded frame %1"), _frame));
+ switch (_eyes) {
+ case EYES_BOTH:
+ _log->log (String::compose (N_("Finished locally-encoded frame %1 for mono"), _frame));
+ break;
+ case EYES_LEFT:
+ _log->log (String::compose (N_("Finished locally-encoded frame %1 for L"), _frame));
+ break;
+ case EYES_RIGHT:
+ _log->log (String::compose (N_("Finished locally-encoded frame %1 for R"), _frame));
+ break;
+ default:
+ break;
+ }
shared_ptr<EncodedData> enc (new LocallyEncodedData (cio->buffer, cio_tell (cio)));
diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc
index 8e61a0d60..7959fda6f 100644
--- a/src/lib/encoder.cc
+++ b/src/lib/encoder.cc
@@ -175,6 +175,8 @@ Encoder::process_video (shared_ptr<const Image> image, Eyes eyes, bool same)
{
boost::mutex::scoped_lock lock (_mutex);
+ /* XXX: discard 3D here if required */
+
/* Wait until the queue has gone down a bit */
while (_queue.size() >= _threads.size() * 2 && !_terminate) {
TIMING ("decoder sleeps with queue of %1", _queue.size());
@@ -212,7 +214,9 @@ Encoder::process_video (shared_ptr<const Image> image, Eyes eyes, bool same)
_have_a_real_frame[eyes] = true;
}
- ++_video_frames_out;
+ if (eyes != EYES_LEFT) {
+ ++_video_frames_out;
+ }
}
void
@@ -262,7 +266,7 @@ Encoder::encoder_thread (ServerDescription* server)
TIMING ("encoder thread %1 wakes with queue of %2", boost::this_thread::get_id(), _queue.size());
shared_ptr<DCPVideoFrame> vf = _queue.front ();
- _film->log()->log (String::compose (N_("Encoder thread %1 pops frame %2 from queue"), boost::this_thread::get_id(), vf->frame()), Log::VERBOSE);
+ _film->log()->log (String::compose (N_("Encoder thread %1 pops frame %2 (%3) from queue"), boost::this_thread::get_id(), vf->frame(), vf->eyes ()));
_queue.pop_front ();
lock.unlock ();
diff --git a/src/lib/player.cc b/src/lib/player.cc
index 20beda945..e1173a36b 100644
--- a/src/lib/player.cc
+++ b/src/lib/player.cc
@@ -32,6 +32,7 @@
#include "image.h"
#include "ratio.h"
#include "resampler.h"
+#include "log.h"
#include "scaler.h"
using std::list;
@@ -240,7 +241,7 @@ Player::process_video (weak_ptr<Piece> weak_piece, shared_ptr<const Image> image
#ifdef DCPOMATIC_DEBUG
_last_video = piece->content;
-#endif
+#endif
Video (work_image, eyes, same, time);
time += TIME_HZ / _film->dcp_video_frame_rate();
diff --git a/src/lib/writer.cc b/src/lib/writer.cc
index 90e1bd554..b9c1ce2e1 100644
--- a/src/lib/writer.cc
+++ b/src/lib/writer.cc
@@ -57,6 +57,7 @@ Writer::Writer (shared_ptr<const Film> f, shared_ptr<Job> j)
, _finish (false)
, _queued_full_in_memory (0)
, _last_written_frame (-1)
+ , _last_written_eyes (EYES_RIGHT)
, _full_written (0)
, _fake_written (0)
, _repeat_written (0)
@@ -127,10 +128,21 @@ Writer::write (shared_ptr<const EncodedData> encoded, int frame, Eyes eyes)
qi.type = QueueItem::FULL;
qi.encoded = encoded;
qi.frame = frame;
- qi.eyes = eyes;
- _queue.push_back (qi);
- ++_queued_full_in_memory;
+ if (_film->dcp_3d() && eyes == EYES_BOTH) {
+ /* 2D material in a 3D DCP; fake the 3D */
+ qi.eyes = EYES_LEFT;
+ _queue.push_back (qi);
+ ++_queued_full_in_memory;
+ qi.eyes = EYES_RIGHT;
+ _queue.push_back (qi);
+ ++_queued_full_in_memory;
+ } else {
+ qi.eyes = eyes;
+ _queue.push_back (qi);
+ ++_queued_full_in_memory;
+ }
+
_condition.notify_all ();
}
@@ -159,7 +171,9 @@ Writer::write (shared_ptr<const AudioBuffers> audio)
_sound_asset_writer->write (audio->data(), audio->frames());
}
-/** This must be called from Writer::thread() with an appropriate lock held */
+/** This must be called from Writer::thread() with an appropriate lock held,
+ * and with _queue sorted.
+ */
bool
Writer::have_sequenced_image_at_queue_head () const
{
@@ -167,13 +181,24 @@ Writer::have_sequenced_image_at_queue_head () const
return false;
}
- /* We assume that we will get either all 2D frames or all 3D frames, not a mixture */
-
- bool const eyes_ok = (_queue.front().eyes == EYES_BOTH) ||
- (_queue.front().eyes == EYES_LEFT && _last_written_eyes == EYES_RIGHT) ||
- (_queue.front().eyes == EYES_RIGHT && _last_written_eyes == EYES_LEFT);
-
- return _queue.front().frame == (_last_written_frame + 1) && eyes_ok;
+ /* The queue should contain only EYES_LEFT/EYES_RIGHT pairs or EYES_BOTH */
+
+ if (_queue.front().eyes == EYES_BOTH) {
+ /* 2D */
+ return _queue.front().frame == (_last_written_frame + 1);
+ }
+
+ /* 3D */
+
+ if (_last_written_eyes == EYES_LEFT && _queue.front().frame == _last_written_frame && _queue.front().eyes == EYES_RIGHT) {
+ return true;
+ }
+
+ if (_last_written_eyes == EYES_RIGHT && _queue.front().frame == (_last_written_frame + 1) && _queue.front().eyes == EYES_LEFT) {
+ return true;
+ }
+
+ return false;
}
void
@@ -191,7 +216,7 @@ try
if (_finish || _queued_full_in_memory > _maximum_frames_in_memory || have_sequenced_image_at_queue_head ()) {
break;
}
-
+
TIMING (N_("writer sleeps with a queue of %1"), _queue.size());
_condition.wait (lock);
TIMING (N_("writer wakes with a queue of %1"), _queue.size());
@@ -245,25 +270,21 @@ try
if (_mono_picture_asset_writer) {
libdcp::FrameInfo fin = _mono_picture_asset_writer->write (
- _last_written[EYES_BOTH]->data(),
- _last_written[EYES_BOTH]->size()
+ _last_written[qi.eyes]->data(),
+ _last_written[qi.eyes]->size()
);
- _last_written[EYES_BOTH]->write_info (_film, qi.frame, qi.eyes, fin);
+ _last_written[qi.eyes]->write_info (_film, qi.frame, qi.eyes, fin);
} else {
libdcp::FrameInfo fin = _stereo_picture_asset_writer->write (
- _last_written[EYES_LEFT]->data(), _last_written[EYES_LEFT]->size(), libdcp::EYE_LEFT
+ _last_written[qi.eyes]->data(),
+ _last_written[qi.eyes]->size(),
+ qi.eyes == EYES_LEFT ? libdcp::EYE_LEFT : libdcp::EYE_RIGHT
);
- _last_written[EYES_LEFT]->write_info (_film, qi.frame, qi.eyes, fin);
-
- fin = _stereo_picture_asset_writer->write (
- _last_written[EYES_RIGHT]->data(), _last_written[EYES_RIGHT]->size(), libdcp::EYE_RIGHT
- );
-
- _last_written[EYES_RIGHT]->write_info (_film, qi.frame, qi.eyes, fin);
+ _last_written[qi.eyes]->write_info (_film, qi.frame, qi.eyes, fin);
}
++_repeat_written;
@@ -271,14 +292,15 @@ try
}
}
lock.lock ();
+
+ _last_written_frame = qi.frame;
+ _last_written_eyes = qi.eyes;
if (_film->length()) {
_job->set_progress (
float (_full_written + _fake_written + _repeat_written) / _film->time_to_video_frames (_film->length())
);
}
-
- ++_last_written_frame;
}
while (_queued_full_in_memory > _maximum_frames_in_memory) {
@@ -298,7 +320,14 @@ try
++_pushed_to_disk;
lock.unlock ();
- _film->log()->log (String::compose (N_("Writer full (awaiting %1); pushes %2 to disk"), _last_written_frame + 1, qi.frame));
+
+ _film->log()->log (
+ String::compose (
+ "Writer full (awaiting %1 [last eye was %2]); pushes %3 to disk",
+ _last_written_frame + 1,
+ _last_written_eyes, qi.frame)
+ );
+
qi.encoded->write (_film, qi.frame, qi.eyes);
lock.lock ();
qi.encoded.reset ();