+ return track->mf.out == track->mf.in ?
+ NULL : track->mf.fifo[track->mf.out & (track->mf.flen - 1)];
+}
+
+static void MoveToInternalFifos( int tk, hb_mux_t *mux, hb_buffer_t * buf )
+{
+ // move all the buffers on the track's fifo to our internal
+ // fifo so that (a) we don't deadlock in the reader and
+ // (b) we can control how data from multiple tracks is
+ // interleaved in the output file.
+ mf_push( mux, tk, buf );
+ if ( buf->stop >= mux->pts )
+ {
+ // buffer is past our next interleave point so
+ // note that this track is ready to be output.
+ mux->rdy |= ( 1 << tk );
+ }
+}
+
+static void OutputTrackChunk( hb_mux_t *mux, hb_track_t *track, hb_mux_object_t *m )
+{
+ hb_buffer_t *buf;
+
+ while ( ( buf = mf_peek( track ) ) != NULL && buf->start < mux->pts )
+ {
+ buf = mf_pull( track );
+ track->frames += 1;
+ track->bytes += buf->size;
+ m->mux( m, track->mux_data, buf );
+ }
+}
+
+static int muxWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
+ hb_buffer_t ** buf_out )
+{
+ hb_work_private_t * pv = w->private_data;
+ hb_job_t * job = pv->job;
+ hb_mux_t * mux = pv->mux;
+ hb_track_t * track;
+ int i;
+ hb_buffer_t * buf = *buf_in;
+
+ hb_lock( mux->mutex );
+ if ( mux->done )
+ {
+ hb_unlock( mux->mutex );
+ return HB_WORK_DONE;
+ }
+
+ if ( buf->size <= 0 )
+ {
+ // EOF - mark this track as done
+ hb_buffer_close( &buf );
+ mux->eof |= ( 1 << pv->track );
+ mux->rdy |= ( 1 << pv->track );
+ }
+ else if ( ( job->pass != 0 && job->pass != 2 ) ||
+ ( mux->eof & (1 << pv->track) ) )
+ {
+ hb_buffer_close( &buf );
+ }
+ else
+ {
+ MoveToInternalFifos( pv->track, mux, buf );
+ }
+ *buf_in = NULL;
+
+ if ( ( mux->rdy & mux->allRdy ) != mux->allRdy )
+ {
+ hb_unlock( mux->mutex );
+ return HB_WORK_OK;
+ }