diff options
| author | Carl Hetherington <cth@carlh.net> | 2013-07-23 11:14:44 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2013-07-23 11:14:44 +0100 |
| commit | 4eb77be6999a3758998bfe37b28d4bb1cd55d51e (patch) | |
| tree | 9e2882f27751ee6badb1ee9b333bf1d012bd083b /src/lib | |
| parent | fa4bac5dd1b8d0e09bd4a4eb20c83c0564858649 (diff) | |
Various 3D fixes.
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/dcp_video_frame.cc | 14 | ||||
| -rw-r--r-- | src/lib/encoder.cc | 8 | ||||
| -rw-r--r-- | src/lib/player.cc | 3 | ||||
| -rw-r--r-- | src/lib/writer.cc | 81 |
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 (); |
