+ /* Gather missing bits. */
+ if( i_bits > 0 )
+ {
+ unsigned int i_tmp = 8 - i_bits;
+
+ if( p_bit_stream->p_byte < p_bit_stream->p_end )
+ {
+ i_result |= *p_bit_stream->p_byte >> i_tmp;
+ p_bit_stream->fifo.buffer = *(p_bit_stream->p_byte++)
+ << ( sizeof(WORD_TYPE) * 8 - i_tmp );
+ p_bit_stream->fifo.i_available = i_tmp;
+ }
+ else
+ {
+ _BitstreamNextDataPacket( p_bit_stream );
+ i_result |= *p_bit_stream->p_byte >> i_tmp;
+ p_bit_stream->fifo.buffer = *(p_bit_stream->p_byte++)
+ << ( sizeof(WORD_TYPE) * 8 - i_tmp );
+ p_bit_stream->fifo.i_available = i_tmp;
+ }
+ }
+ else
+ {
+ p_bit_stream->fifo.i_available = 0;
+ p_bit_stream->fifo.buffer = 0;
+ }
+
+ if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
+ {
+ /* Get aligned on a word boundary. Otherwise it is safer
+ * to do it the next time.
+ * NB : we _will_ get aligned, because we have at most
+ * sizeof(WORD_TYPE) - 1 bytes to store, and at least
+ * sizeof(WORD_TYPE) - 1 empty bytes in the bit buffer. */
+ AlignWord( p_bit_stream );
+ }
+
+ return( i_result );
+}
+
+/*****************************************************************************
+ * UnalignedRemoveBits : removes i_bits (== -i_available) from the bit
+ * buffer, even when the bit stream is not aligned on a word boundary
+ *****************************************************************************/
+void UnalignedRemoveBits( bit_stream_t * p_bit_stream )
+{
+ /* First remove all unnecessary bytes. */
+ while( p_bit_stream->fifo.i_available <= -8 )
+ {
+ if( p_bit_stream->p_byte < p_bit_stream->p_end )
+ {
+ p_bit_stream->p_byte++;
+ p_bit_stream->fifo.i_available += 8;
+ }
+ else
+ {
+ _BitstreamNextDataPacket( p_bit_stream );
+ p_bit_stream->p_byte++;
+ p_bit_stream->fifo.i_available += 8;
+ }
+ }
+
+ /* Remove unnecessary bits. */
+ if( p_bit_stream->fifo.i_available < 0 )
+ {
+ if( p_bit_stream->p_byte < p_bit_stream->p_end )
+ {
+ p_bit_stream->fifo.buffer = *(p_bit_stream->p_byte++)
+ << ( sizeof(WORD_TYPE) * 8 - 8
+ - p_bit_stream->fifo.i_available );
+ p_bit_stream->fifo.i_available += 8;
+ }
+ else
+ {
+ _BitstreamNextDataPacket( p_bit_stream );
+ p_bit_stream->fifo.buffer = *(p_bit_stream->p_byte++)
+ << ( sizeof(WORD_TYPE) * 8 - 8
+ - p_bit_stream->fifo.i_available );
+ p_bit_stream->fifo.i_available += 8;
+ }
+ }
+ else
+ {
+ p_bit_stream->fifo.buffer = 0;
+ }
+
+ if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
+ {
+ /* Get aligned on a word boundary. Otherwise it is safer
+ * to do it the next time.
+ * NB : we _will_ get aligned, because we have at most
+ * sizeof(WORD_TYPE) - 1 bytes to store, and at least
+ * sizeof(WORD_TYPE) - 1 empty bytes in the bit buffer. */
+ AlignWord( p_bit_stream );
+ }
+}
+
+/*****************************************************************************
+ * CurrentPTS: returns the current PTS and DTS
+ *****************************************************************************/
+void CurrentPTS( bit_stream_t * p_bit_stream, mtime_t * pi_pts,
+ mtime_t * pi_dts )
+{
+ /* Check if the current PTS is already valid (ie. if the first byte
+ * of the packet has already been used in the decoder). */
+ ptrdiff_t p_diff = p_bit_stream->p_pts_validity - p_bit_stream->p_byte;
+ if( p_diff < 0 || p_diff > 4 /* We are far away so it is valid */
+ || (p_diff * 8) >= p_bit_stream->fifo.i_available
+ /* We have buffered less bytes than actually read */ )
+ {
+ *pi_pts = p_bit_stream->i_pts;
+ if( pi_dts != NULL ) *pi_dts = p_bit_stream->i_dts;
+ p_bit_stream->i_pts = 0;
+ p_bit_stream->i_dts = 0;
+ }
+ else
+ {
+ *pi_pts = 0;
+ if( pi_dts != NULL) *pi_dts = 0;
+ }
+}
+
+/*****************************************************************************
+ * NextPTS: returns the PTS and DTS for the next starting byte
+ *****************************************************************************/
+void NextPTS( bit_stream_t * p_bit_stream, mtime_t * pi_pts,
+ mtime_t * pi_dts )
+{
+ /* Check if the current PTS is already valid (ie. if the first byte
+ * of the packet has already been used in the decoder). */
+ ptrdiff_t p_diff = p_bit_stream->p_pts_validity - p_bit_stream->p_byte - 1;
+ if( p_diff < 0 || p_diff > 4 /* We are far away so it is valid */
+ || (p_diff * 8) >= p_bit_stream->fifo.i_available
+ /* We have buffered less bytes than actually read */ )
+ {
+ *pi_pts = p_bit_stream->i_pts;
+ if( pi_dts != NULL ) *pi_dts = p_bit_stream->i_dts;
+ p_bit_stream->i_pts = 0;
+ p_bit_stream->i_dts = 0;
+ }
+ else
+ {
+ *pi_pts = 0;
+ if( pi_dts != NULL) *pi_dts = 0;
+ }
+}
+
+/****************************************************************************
+ * input_NextPES : extract a PES from the fifo. If pp_pes is NULL then this
+ * PES is deleted, else pp_pes will be set to this PES
+ ****************************************************************************/
+int input_NextPES( decoder_fifo_t *p_fifo, pes_packet_t **pp_pes )
+{
+ pes_packet_t *p_pes, *p_next;
+
+ vlc_mutex_lock( &p_fifo->data_lock );
+
+ /* if fifo is emty wait */
+ while( !p_fifo->p_first )
+ {
+ if( p_fifo->b_die )
+ {
+ vlc_mutex_unlock( &p_fifo->data_lock );
+ if( pp_pes )
+ {
+ *pp_pes = NULL;
+ }
+ return( -1 );
+ }
+ vlc_cond_signal( &p_fifo->data_wait );
+ vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
+ }
+ p_pes = p_fifo->p_first;
+
+ p_next = p_pes->p_next;
+ p_pes->p_next = NULL;
+
+
+ p_fifo->p_first = p_next;
+ p_fifo->i_depth--;