* input_ext-dec.c: services to the decoders
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
+ * $Id: input_ext-dec.c,v 1.16 2001/05/08 00:43:57 sam Exp $
*
- * Authors:
+ * Authors: Christophe Massiot <massiot@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
*****************************************************************************/
#include "defs.h"
+#include <string.h> /* memcpy(), memset() */
+#include <sys/types.h> /* off_t */
+
#include "config.h"
#include "common.h"
#include "threads.h"
/*****************************************************************************
* InitBitstream: initialize a bit_stream_t structure
*****************************************************************************/
-void InitBitstream( bit_stream_t * p_bit_stream, decoder_fifo_t * p_fifo )
+void InitBitstream( bit_stream_t * p_bit_stream, decoder_fifo_t * p_fifo,
+ void (* pf_bitstream_callback)( struct bit_stream_s *,
+ boolean_t ),
+ void * p_callback_arg )
{
p_bit_stream->p_decoder_fifo = p_fifo;
p_bit_stream->pf_next_data_packet = NextDataPacket;
- p_bit_stream->pf_bitstream_callback = NULL;
- p_bit_stream->p_callback_arg = NULL;
+ p_bit_stream->pf_bitstream_callback = pf_bitstream_callback;
+ p_bit_stream->p_callback_arg = p_callback_arg;
/* Get the first data packet. */
vlc_mutex_lock( &p_fifo->data_lock );
p_bit_stream->fifo.buffer = 0;
p_bit_stream->fifo.i_available = 0;
vlc_mutex_unlock( &p_fifo->data_lock );
+
+ /* Call back the decoder. */
+ if( p_bit_stream->pf_bitstream_callback != NULL )
+ {
+ p_bit_stream->pf_bitstream_callback( p_bit_stream, 1 );
+ }
+
+ if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
+ {
+ /* Get aligned on a word boundary.
+ * 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 );
+ }
}
/*****************************************************************************
}
}
-void OldKludge( bit_stream_t * p_bit_stream )
-{
- WORD_TYPE buffer_left;
- ptrdiff_t i_bytes_left;
-
- /* Put the remaining bytes (not aligned on a word boundary) in a
- * temporary buffer. */
- i_bytes_left = p_bit_stream->p_end - p_bit_stream->p_byte;
- buffer_left = *((WORD_TYPE *)p_bit_stream->p_end - 1);
-
- p_bit_stream->pf_next_data_packet( p_bit_stream );
-
- /* Copy remaining bits of the previous packet */
- *((WORD_TYPE *)p_bit_stream->p_byte - 1) = buffer_left;
- p_bit_stream->p_byte -= i_bytes_left;
-}
-
/*****************************************************************************
* UnalignedShowBits : return i_bits bits from the bit stream, even when
* not aligned on a word boundary
else
{
p_bit_stream->pf_next_data_packet( p_bit_stream );
- p_bit_stream->fifo.buffer |= *(p_bit_stream->p_byte++)
- << (8 * sizeof(WORD_TYPE) - 8
- - p_bit_stream->fifo.i_available);
- p_bit_stream->fifo.i_available += 8;
+
+ if( (ptrdiff_t)p_bit_stream->p_byte & (sizeof(WORD_TYPE) - 1) )
+ {
+ /* We are not aligned anymore. */
+ if( ((ptrdiff_t)p_bit_stream->p_byte
+ & (sizeof(WORD_TYPE) - 1)) * 8
+ < p_bit_stream->fifo.i_available )
+ {
+ /* We are not aligned, and won't be. Copy the first word
+ * of the packet in a temporary buffer, and we'll see
+ * later. */
+ int i;
+
+ /* sizeof(WORD_TYPE) - number of bytes to trash
+ * from the last payload */
+ int j;
+
+ p_bit_stream->i_showbits_buffer = 0;
+
+ for( j = i = 0 ; i < sizeof(WORD_TYPE) ; i++ )
+ {
+ if( p_bit_stream->p_byte >= p_bit_stream->p_end )
+ {
+ j = i;
+ p_bit_stream->pf_next_data_packet( p_bit_stream );
+ }
+ ((byte_t *)&p_bit_stream->i_showbits_buffer)[i] =
+ * p_bit_stream->p_byte;
+ p_bit_stream->p_byte++;
+ }
+
+ /* This is kind of kludgy. */
+ p_bit_stream->p_data->p_payload_start +=
+ sizeof(WORD_TYPE) - j;
+ p_bit_stream->p_byte =
+ (byte_t *)&p_bit_stream->i_showbits_buffer;
+ p_bit_stream->p_end =
+ (byte_t *)&p_bit_stream->i_showbits_buffer
+ + sizeof(WORD_TYPE);
+ p_bit_stream->showbits_data.p_next = p_bit_stream->p_data;
+ p_bit_stream->p_data = &p_bit_stream->showbits_data;
+ }
+ else
+ {
+ /* We are not aligned, but we can be. */
+ AlignWord( p_bit_stream );
+ }
+ }
+
+ return( ShowBits( p_bit_stream, i_bits ) );
}
}
return( p_bit_stream->fifo.buffer >> (8 * sizeof(WORD_TYPE) - i_bits) );
i_result = p_bit_stream->fifo.buffer
>> (8 * sizeof(WORD_TYPE) - i_bits);
- i_bits -= p_bit_stream->fifo.i_available;
+ i_bits = -p_bit_stream->fifo.i_available;
/* Gather missing bytes. */
while( i_bits >= 8 )