+static hb_buffer_t *mf_peek( hb_track_t *track )
+{
+ 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 )