}
}
+/** Called in order, so each time this is called the supplied frame is the one
+ * after the previous one.
+ */
void
-Encoder::enqueue (shared_ptr<PlayerVideo> pvf)
+Encoder::enqueue (shared_ptr<PlayerVideo> pv)
{
_waker.nudge ();
rethrow ();
if (_writer->can_fake_write (_video_frames_out)) {
- _writer->fake_write (_video_frames_out, pvf->eyes ());
+ /* We can fake-write this frame */
+ _writer->fake_write (_video_frames_out, pv->eyes ());
frame_done ();
- } else if (pvf->has_j2k ()) {
- _writer->write (pvf->j2k(), _video_frames_out, pvf->eyes ());
+ } else if (pv->has_j2k ()) {
+ /* This frame already has JPEG2000 data, so just write it */
+ _writer->write (pv->j2k(), _video_frames_out, pv->eyes ());
} else {
/* Queue this new frame for encoding */
LOG_TIMING ("adding to queue of %1", _queue.size ());
_queue.push_back (shared_ptr<DCPVideo> (
new DCPVideo (
- pvf,
+ pv,
_video_frames_out,
_film->video_frame_rate(),
_film->j2k_bandwidth(),
_empty_condition.notify_all ();
}
- if (pvf->eyes() != EYES_LEFT) {
+ if (pv->eyes() != EYES_LEFT) {
++_video_frames_out;
}
}
encodings.
*/
int remote_backoff = 0;
+ shared_ptr<DCPVideo> last_dcp_video;
+ shared_ptr<EncodedData> last_encoded;
while (true) {
shared_ptr<EncodedData> encoded;
- if (server) {
- try {
- encoded = vf->encode_remotely (server.get ());
-
- if (remote_backoff > 0) {
- LOG_GENERAL ("%1 was lost, but now she is found; removing backoff", server->host_name ());
+ if (last_dcp_video && vf->same (last_dcp_video)) {
+ /* We already have encoded data for the same input as this one, so take a short-cut */
+ encoded = last_encoded;
+ } else {
+ /* We need to encode this input */
+ if (server) {
+ try {
+ encoded = vf->encode_remotely (server.get ());
+
+ if (remote_backoff > 0) {
+ LOG_GENERAL ("%1 was lost, but now she is found; removing backoff", server->host_name ());
+ }
+
+ /* This job succeeded, so remove any backoff */
+ remote_backoff = 0;
+
+ } catch (std::exception& e) {
+ if (remote_backoff < 60) {
+ /* back off more */
+ remote_backoff += 10;
+ }
+ LOG_ERROR (
+ N_("Remote encode of %1 on %2 failed (%3); thread sleeping for %4s"),
+ vf->index(), server->host_name(), e.what(), remote_backoff
+ );
}
- /* This job succeeded, so remove any backoff */
- remote_backoff = 0;
-
- } catch (std::exception& e) {
- if (remote_backoff < 60) {
- /* back off more */
- remote_backoff += 10;
+ } else {
+ try {
+ LOG_TIMING ("[%1] encoder thread begins local encode of %2", boost::this_thread::get_id(), vf->index());
+ encoded = vf->encode_locally ();
+ LOG_TIMING ("[%1] encoder thread finishes local encode of %2", boost::this_thread::get_id(), vf->index());
+ } catch (std::exception& e) {
+ LOG_ERROR (N_("Local encode failed (%1)"), e.what ());
}
- LOG_ERROR (
- N_("Remote encode of %1 on %2 failed (%3); thread sleeping for %4s"),
- vf->index(), server->host_name(), e.what(), remote_backoff
- );
- }
-
- } else {
- try {
- LOG_TIMING ("[%1] encoder thread begins local encode of %2", boost::this_thread::get_id(), vf->index());
- encoded = vf->encode_locally ();
- LOG_TIMING ("[%1] encoder thread finishes local encode of %2", boost::this_thread::get_id(), vf->index());
- } catch (std::exception& e) {
- LOG_ERROR (N_("Local encode failed (%1)"), e.what ());
}
}
+ last_dcp_video = vf;
+ last_encoded = encoded;
+
if (encoded) {
_writer->write (encoded, vf->index (), vf->eyes ());
frame_done ();