+static size_t block_ChainExtract( block_t *p_list, void *p_data, size_t i_max )
+{
+ size_t i_total = 0;
+ uint8_t *p = (uint8_t*)p_data;
+
+ while( p_list && i_max )
+ {
+ size_t i_copy = __MIN( i_max, p_list->i_buffer );
+ memcpy( p, p_list->p_buffer, i_copy );
+ i_max -= i_copy;
+ i_total += i_copy;
+ p += i_copy;
+
+ p_list = p_list->p_next;
+ }
+ return i_total;
+}
+
+static inline block_t *block_ChainGather( block_t *p_list )
+{
+ size_t i_total = 0;
+ mtime_t i_length = 0;
+ block_t *b, *g;
+
+ if( p_list->p_next == NULL )
+ return p_list; /* Already gathered */
+
+ for( b = p_list; b != NULL; b = b->p_next )
+ {
+ i_total += b->i_buffer;
+ i_length += b->i_length;
+ }
+
+ g = block_Alloc( i_total );
+ block_ChainExtract( p_list, g->p_buffer, g->i_buffer );
+
+ g->i_flags = p_list->i_flags;
+ g->i_pts = p_list->i_pts;
+ g->i_dts = p_list->i_dts;
+ g->i_length = i_length;
+
+ /* free p_list */
+ block_ChainRelease( p_list );
+ return g;
+}
+
+
+/****************************************************************************
+ * Fifos of blocks.
+ ****************************************************************************
+ * - block_FifoNew : create and init a new fifo
+ * - block_FifoRelease : destroy a fifo and free all blocks in it.
+ * - block_FifoEmpty : free all blocks in a fifo
+ * - block_FifoPut : put a block
+ * - block_FifoGet : get a packet from the fifo (and wait if it is empty)
+ * - block_FifoShow : show the first packet of the fifo (and wait if
+ * needed), be carefull, you can use it ONLY if you are sure to be the
+ * only one getting data from the fifo.
+ * - block_FifoCount : how many packets are waiting in the fifo
+ * - block_FifoSize : how many cumulated bytes are waiting in the fifo
+ * - block_FifoWake : wake ups a thread with block_FifoGet() = NULL
+ * (this is used to wakeup a thread when there is no data to queue)
+ ****************************************************************************/