, _full_written (0)
, _fake_written (0)
, _repeat_written (0)
+ , _ref_written (0)
, _pushed_to_disk (0)
{
/* Remove any old DCP */
terminate_thread (false);
}
+/** @param frame Frame within the DCP */
void
-Writer::write (Data encoded, int frame, Eyes eyes)
+Writer::write (Data encoded, Frame frame, Eyes eyes)
{
boost::mutex::scoped_lock lock (_state_mutex);
}
void
-Writer::repeat (int frame, Eyes eyes)
+Writer::repeat (Frame frame, Eyes eyes)
{
boost::mutex::scoped_lock lock (_state_mutex);
}
void
-Writer::fake_write (int frame, Eyes eyes)
+Writer::fake_write (Frame frame, Eyes eyes)
{
boost::mutex::scoped_lock lock (_state_mutex);
_empty_condition.notify_all ();
}
-/** This method is not thread safe */
+void
+Writer::ref_write (Frame frame)
+{
+ boost::mutex::scoped_lock lock (_state_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::REF;
+ qi.frame = frame;
+ qi.eyes = EYES_BOTH;
+ _queue.push_back (qi);
+
+ /* Now there's something to do: wake anything wait()ing on _empty_condition */
+ _empty_condition.notify_all ();
+}
+
+/** Write one video frame's worth of audio frames to the DCP.
+ * This method is not thread safe.
+ */
void
Writer::write (shared_ptr<const AudioBuffers> audio)
{
return;
}
- _audio_reel->sound_asset_writer->write (audio->data(), audio->frames());
+ if (audio) {
+ _audio_reel->sound_asset_writer->write (audio->data(), audio->frames());
+ }
+
+ ++_audio_reel->written;
+
+ cout << "(written " << _audio_reel->written << "); period is " << _audio_reel->period.duration() << "\n";
- /* SoundAsset's `frames' are video frames, not audio frames */
- if (_audio_reel->sound_asset_writer->frames_written() >= _audio_reel->period.duration().frames_round (_film->video_frame_rate())) {
+ /* written is in video frames, not audio frames */
+ if (_audio_reel->written >= _audio_reel->period.duration().frames_round (_film->video_frame_rate())) {
+ cout << "NEXT AUDIO REEL!\n";
++_audio_reel;
}
}
case QueueItem::FAKE:
LOG_DEBUG_ENCODE (N_("Writer FAKE-writes %1"), qi.frame);
reel.picture_asset_writer->fake_write (qi.size);
- _last_written[qi.eyes].reset ();
++_fake_written;
break;
case QueueItem::REPEAT:
+ {
LOG_DEBUG_ENCODE (N_("Writer REPEAT-writes %1"), qi.frame);
dcp::FrameInfo fin = reel.picture_asset_writer->write (
_last_written[qi.eyes]->data().get(),
++_repeat_written;
break;
}
+ case QueueItem::REF:
+ LOG_DEBUG_ENCODE (N_("Writer REF-writes %1"), qi.frame);
+ ++_ref_written;
+ break;
+ }
lock.lock ();
total *= 2;
}
if (total) {
- job->set_progress (float (_full_written + _fake_written + _repeat_written) / total);
+ job->set_progress (float (_full_written + _fake_written + _repeat_written + _ref_written) / total);
}
}
BOOST_FOREACH (Reel& i, _reels) {
if (!i.picture_asset_writer->finalize ()) {
- /* Nothing was written to the picture asset */
+ /* Nothing was written to the picture asset */
i.picture_asset.reset ();
}
if (i.sound_asset_writer && !i.sound_asset_writer->finalize ()) {
/* Nothing was written to the sound asset */
+ cout << "nothing written to reel @ " << i.period << "\n";
i.sound_asset.reset ();
+ } else {
+ cout << "something written to reel @ " << i.period << "\n";
}
/* Hard-link any video asset file into the DCP */
dcp.write_xml (_film->interop () ? dcp::INTEROP : dcp::SMPTE, meta, signer);
LOG_GENERAL (
- N_("Wrote %1 FULL, %2 FAKE, %3 REPEAT, %4 pushed to disk"), _full_written, _fake_written, _repeat_written, _pushed_to_disk
+ N_("Wrote %1 FULL, %2 FAKE, %3 REPEAT, %4 REF, %5 pushed to disk"), _full_written, _fake_written, _repeat_written, _ref_written, _pushed_to_disk
);
}
fclose (info_file);
}
-/** @param frame Frame index.
+/** @param frame Frame index within the whole DCP.
* @return true if we can fake-write this frame.
*/
bool
-Writer::can_fake_write (int frame) const
+Writer::can_fake_write (Frame frame) const
{
/* We have to do a proper write of the first frame so that we can set up the JPEG2000
parameters in the asset writer.
*/
- /* XXX: need to correct frame to be relative to the reel, perhaps?
- and clarify whether first_nonexistant_frame is relative to the start
- of the DCP or of the reel.
- */
+ Reel const & reel = video_reel (frame);
- return (frame != 0 && frame < video_reel(frame).first_nonexistant_frame);
+ /* Make frame relative to the start of the reel */
+ frame -= reel.period.from.frames_floor (_film->video_frame_rate());
+ return (frame != 0 && frame < reel.first_nonexistant_frame);
}
void