Commit a558a9bb authored by Christophe Massiot's avatar Christophe Massiot

* Changed default values :

INPUT_PTS_DELAY down to 200 ms ;
video heap down from 10 to 5 pictures ;
decoder fifo size from 1023 to 511 PES ;
* Fixed various bugs in 32 bit-versions of input_ext-dec.h ;
* Fixed a bug in GetChunk() ;
* Renamed GetByte, GetWord, ShowWord to _GetByte, _GetWord, _ShowWord ;
* Moved decoder_fifo-specific code from programs.c to dec.c ;
* Fixed bugs in program.c that prevented vlc to close all decoders ;
* Gave sam a lesson for the use of the bitstream in spu_decoder.c :ppp ;
* Made the video parser unlock the reference pictures before quitting
(still one left, yaknow why ?)
parent ebfaed9b
......@@ -113,7 +113,7 @@
*/
/* Size of the FIFO. FIFO_SIZE+1 must be a power of 2 */
#define FIFO_SIZE 1023
#define FIFO_SIZE 511
/*
* Paths
......@@ -207,9 +207,9 @@
* server */
#define INPUT_VLAN_CHANGE_DELAY (5*CLOCK_FREQ)
/* Duration between the time we receive the TS packet, and the time we will
/* Duration between the time we receive the data packet, and the time we will
* mark it to be presented */
#define DEFAULT_PTS_DELAY (.5*CLOCK_FREQ)
#define DEFAULT_PTS_DELAY (.2*CLOCK_FREQ)
#define INPUT_DVD_AUDIO_VAR "vlc_dvd_audio"
#define INPUT_DVD_CHANNEL_VAR "vlc_dvd_channel"
......@@ -301,10 +301,10 @@
/* Video heap size - remember that a decompressed picture is big
* (~1 Mbyte) before using huge values */
#define VOUT_MAX_PICTURES 10
#define VOUT_MAX_PICTURES 5
/* Number of simultaneous subpictures */
#define VOUT_MAX_SUBPICTURES 10
#define VOUT_MAX_SUBPICTURES 5
/* Maximum number of active areas in a rendering buffer. Active areas are areas
* of the picture which need to be cleared before re-using the buffer. If a
......
......@@ -2,7 +2,7 @@
* input_ext-dec.h: structures exported to the VideoLAN decoders
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: input_ext-dec.h,v 1.12 2001/01/12 11:36:49 massiot Exp $
* $Id: input_ext-dec.h,v 1.13 2001/01/12 17:33:18 massiot Exp $
*
* Authors:
*
......@@ -178,9 +178,9 @@ typedef struct bit_stream_s
*/
/*****************************************************************************
* GetByte : reads the next byte in the input stream
* GetByte : reads the next byte in the input stream (PRIVATE)
*****************************************************************************/
static __inline__ byte_t GetByte( bit_stream_t * p_bit_stream )
static __inline__ byte_t _GetByte( bit_stream_t * p_bit_stream )
{
/* Are there some bytes left in the current data packet ? */
/* could change this test to have a if (! (bytes--)) instead */
......@@ -209,7 +209,7 @@ static __inline__ void NeedBits( bit_stream_t * p_bit_stream, int i_bits )
{
while ( p_bit_stream->fifo.i_available < i_bits )
{
p_bit_stream->fifo.buffer |= ((WORD_TYPE)GetByte( p_bit_stream ))
p_bit_stream->fifo.buffer |= ((WORD_TYPE)_GetByte( p_bit_stream ))
<< (sizeof(WORD_TYPE) - 8
- p_bit_stream->fifo.i_available);
p_bit_stream->fifo.i_available += 8;
......@@ -245,7 +245,7 @@ static __inline__ void DumpBits( bit_stream_t * p_bit_stream, int i_bits )
/*****************************************************************************
* ShowBits : return i_bits bits from the bit stream
*****************************************************************************/
static __inline__ WORD_TYPE ShowWord( bit_stream_t * p_bit_stream )
static __inline__ WORD_TYPE _ShowWord( bit_stream_t * p_bit_stream )
{
if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
{
......@@ -264,14 +264,14 @@ static __inline__ WORD_TYPE ShowBits( bit_stream_t * p_bit_stream, int i_bits )
}
return( (p_bit_stream->fifo.buffer |
(ShowWord( p_bit_stream ) >> p_bit_stream->fifo.i_available))
(_ShowWord( p_bit_stream ) >> p_bit_stream->fifo.i_available))
>> (8 * sizeof(WORD_TYPE) - i_bits) );
}
/*****************************************************************************
* GetWord : returns the next word to be read
* GetWord : returns the next word to be read (PRIVATE)
*****************************************************************************/
static __inline__ WORD_TYPE GetWord( bit_stream_t * p_bit_stream )
static __inline__ WORD_TYPE _GetWord( bit_stream_t * p_bit_stream )
{
if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
{
......@@ -297,7 +297,7 @@ static __inline__ void RemoveBits( bit_stream_t * p_bit_stream, int i_bits )
p_bit_stream->fifo.buffer <<= i_bits;
return;
}
p_bit_stream->fifo.buffer = GetWord( p_bit_stream )
p_bit_stream->fifo.buffer = _GetWord( p_bit_stream )
<< ( -p_bit_stream->fifo.i_available );
p_bit_stream->fifo.i_available += sizeof(WORD_TYPE) * 8;
}
......@@ -310,12 +310,12 @@ static __inline__ void RemoveBits32( bit_stream_t * p_bit_stream )
{
if( p_bit_stream->fifo.i_available )
{
p_bit_stream->fifo.buffer = GetWord( p_bit_stream )
p_bit_stream->fifo.buffer = _GetWord( p_bit_stream )
<< (32 - p_bit_stream->fifo.i_available);
}
else
{
p_bit_stream->fifo.buffer = GetWord( p_bit_stream );
_GetWord( p_bit_stream );
}
}
......@@ -336,7 +336,7 @@ static __inline__ WORD_TYPE GetBits( bit_stream_t * p_bit_stream, int i_bits )
}
i_result = p_bit_stream->fifo.buffer >> (8 * sizeof(WORD_TYPE) - i_bits);
p_bit_stream->fifo.buffer = GetWord( p_bit_stream );
p_bit_stream->fifo.buffer = _GetWord( p_bit_stream );
i_result |= p_bit_stream->fifo.buffer
>> (8 * sizeof(WORD_TYPE)
+ p_bit_stream->fifo.i_available);
......@@ -353,18 +353,21 @@ static __inline__ WORD_TYPE GetBits32( bit_stream_t * p_bit_stream )
{
WORD_TYPE i_result;
i_result = p_bit_stream->fifo.buffer;
p_bit_stream->fifo.buffer = GetWord( p_bit_stream );
i_result |= p_bit_stream->fifo.buffer
>> (p_bit_stream->fifo.i_available);
if( p_bit_stream->fifo.i_available )
{
i_result = p_bit_stream->fifo.buffer;
p_bit_stream->fifo.buffer = _GetWord( p_bit_stream );
i_result |= p_bit_stream->fifo.buffer
>> (p_bit_stream->fifo.i_available);
p_bit_stream->fifo.buffer <<= (8 * sizeof(WORD_TYPE)
- p_bit_stream->fifo.i_available);
return( i_result );
}
else
{
return( _GetWord( p_bit_stream ) );
}
return( i_result );
}
/*****************************************************************************
......@@ -411,7 +414,7 @@ static __inline__ void GetChunk( bit_stream_t * p_bit_stream,
p_bit_stream->pf_next_data_packet( p_bit_stream );
}
while( (i_available = p_bit_stream->p_end - p_bit_stream->p_byte)
<= i_buf_len );
<= i_buf_len && !p_bit_stream->p_decoder_fifo->b_die );
if( i_buf_len )
{
......
......@@ -2,7 +2,7 @@
* input_dec.c: Functions for the management of decoders
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: input_dec.c,v 1.5 2001/01/12 14:49:55 sam Exp $
* $Id: input_dec.c,v 1.6 2001/01/12 17:33:18 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
......@@ -26,6 +26,7 @@
*****************************************************************************/
#include "defs.h"
#include <stdlib.h>
#include "config.h"
#include "common.h"
#include "threads.h"
......@@ -72,6 +73,13 @@ void input_EndDecoder( input_thread_t * p_input, es_descriptor_t * p_es )
DECODER_FIFO_START( *p_es->p_decoder_fifo ) );
DECODER_FIFO_INCSTART( *p_es->p_decoder_fifo );
}
/* Destroy the lock and cond */
vlc_cond_destroy( &p_es->p_decoder_fifo->data_wait );
vlc_mutex_destroy( &p_es->p_decoder_fifo->data_lock );
free( p_es->p_decoder_fifo );
p_es->p_decoder_fifo = NULL;
}
/*****************************************************************************
......
......@@ -2,7 +2,7 @@
* input_programs.c: es_descriptor_t, pgrm_descriptor_t management
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: input_programs.c,v 1.24 2001/01/12 14:49:55 sam Exp $
* $Id: input_programs.c,v 1.25 2001/01/12 17:33:18 massiot Exp $
*
* Authors:
*
......@@ -75,19 +75,15 @@ void input_InitStream( input_thread_t * p_input, size_t i_data_len )
*****************************************************************************/
void input_EndStream( input_thread_t * p_input )
{
int i;
/* Free all programs and associated ES, and associated decoders. */
for( i = 0; i < p_input->stream.i_pgrm_number; i++ )
while( p_input->stream.i_pgrm_number )
{
/* Don't put i instead of 0 !! */
input_DelProgram( p_input, p_input->stream.pp_programs[0] );
}
/* Free standalone ES */
for( i = 0; i < p_input->stream.i_es_number; i++ )
while( p_input->stream.i_es_number )
{
/* Don't put i instead of 0 !! */
input_DelES( p_input, p_input->stream.pp_es[0] );
}
}
......@@ -187,16 +183,15 @@ pgrm_descriptor_t * input_AddProgram( input_thread_t * p_input,
*****************************************************************************/
void input_DelProgram( input_thread_t * p_input, pgrm_descriptor_t * p_pgrm )
{
int i_index, i_pgrm_index;
int i_pgrm_index;
ASSERT( p_pgrm );
intf_DbgMsg("Deleting description for pgrm %d", p_pgrm->i_number);
/* Free the structures that describe the es that belongs to that program */
for( i_index = 0; i_index < p_pgrm->i_es_number; i_index++ )
while( p_pgrm->i_es_number )
{
/* Don't put i_index instead of 0 !! */
input_DelES( p_input, p_pgrm->pp_es[0] );
}
......@@ -342,12 +337,6 @@ void input_DelES( input_thread_t * p_input, es_descriptor_t * p_es )
if( p_es->p_decoder_fifo != NULL )
{
input_EndDecoder( p_input, p_es );
/* Destroy the lock and cond */
vlc_cond_destroy( &p_es->p_decoder_fifo->data_wait );
vlc_mutex_destroy( &p_es->p_decoder_fifo->data_lock );
free( p_es->p_decoder_fifo );
}
/* Remove this ES from the description of the program if it is associated to
......
......@@ -144,174 +144,159 @@ static void RunThread( spudec_thread_t *p_spudec )
boolean_t b_valid;
subpicture_t * p_spu = NULL;
while( !DECODER_FIFO_ISEMPTY(*p_spudec->p_fifo) )
/* wait for the next SPU ID.
* XXX: We trash 0xff bytes since they probably come from
* an incomplete previous packet */
do
{
/* wait for the next SPU ID.
* XXX: We trash 0xff bytes since they probably come from
* an incomplete previous packet */
do
{
i_packet_size = GetByte( &p_spudec->bit_stream );
}
while( i_packet_size == 0xff );
i_packet_size = GetBits( &p_spudec->bit_stream, 8 );
}
while( i_packet_size == 0xff );
if( p_spudec->p_fifo->b_die )
{
break;
}
/* the total size - should equal the sum of the
* PES packet size that form the SPU packet */
i_packet_size = i_packet_size << 8
| GetBits( &p_spudec->bit_stream, 8 );
/* the RLE stuff size */
i_rle_size = GetBits( &p_spudec->bit_stream, 16 );
/* if the values we got aren't too strange, decode the data */
if( i_rle_size < i_packet_size )
{
/* allocate the subpicture.
* FIXME: we should check if the allocation failed */
p_spu = vout_CreateSubPicture( p_spudec->p_vout,
DVD_SUBPICTURE, i_rle_size );
/* get display time */
p_spu->begin_date = p_spu->end_date
= DECODER_FIFO_START(*p_spudec->p_fifo)->i_pts;
/* get RLE data, skip 4 bytes for the first two read offsets */
GetChunk( &p_spudec->bit_stream, p_spu->p_data,
i_rle_size - 4 );
if( p_spudec->p_fifo->b_die )
{
goto bad_packet;
break;
}
/* the total size - should equal the sum of the
* PES packet size that form the SPU packet */
i_packet_size = i_packet_size << 8
| GetByte( &p_spudec->bit_stream );
/* continue parsing after the RLE part */
i_index = i_rle_size;
/* the RLE stuff size */
i_rle_size = GetByte( &p_spudec->bit_stream ) << 8
| GetByte( &p_spudec->bit_stream );
/* assume packet is valid */
b_valid = 1;
/* if the values we got aren't too strange, decode the data */
if( i_rle_size < i_packet_size )
/* getting the control part */
do
{
/* allocate the subpicture.
* FIXME: we should check if the allocation failed */
p_spu = vout_CreateSubPicture( p_spudec->p_vout,
DVD_SUBPICTURE, i_rle_size );
/* get display time */
p_spu->begin_date = p_spu->end_date
= DECODER_FIFO_START(*p_spudec->p_fifo)->i_pts;
/* get RLE data, skip 4 bytes for the first two read offsets */
GetChunk( &p_spudec->bit_stream, p_spu->p_data,
i_rle_size - 4 );
if( p_spudec->p_fifo->b_die )
{
goto bad_packet;
}
unsigned char i_cmd;
u16 i_date;
/* continue parsing after the RLE part */
i_index = i_rle_size;
/* Get the sequence date */
i_date = GetBits( &p_spudec->bit_stream, 16 );
/* assume packet is valid */
b_valid = 1;
/* Next offset */
i_next = GetBits( &p_spudec->bit_stream, 16 );
i_index += 4;
/* getting the control part */
do
{
unsigned char i_cmd;
unsigned int i_word, i_date;
/* Get the sequence date */
i_date = GetByte( &p_spudec->bit_stream ) << 8
| GetByte( &p_spudec->bit_stream );
/* Next offset */
i_next = GetByte( &p_spudec->bit_stream ) << 8
| GetByte( &p_spudec->bit_stream );
i_index += 4;
i_cmd = GetBits( &p_spudec->bit_stream, 8 );
i_index++;
do
switch( i_cmd )
{
i_cmd = GetByte( &p_spudec->bit_stream );
i_index++;
switch( i_cmd )
{
case SPU_CMD_FORCE_DISPLAY:
/* 00 (force displaying) */
break;
/* FIXME: here we have to calculate dates. It's
* around i_date * 12000 but I don't know
* how much exactly.
*/
case SPU_CMD_START_DISPLAY:
/* 01 (start displaying) */
p_spu->begin_date += ( i_date * 12000 );
break;
case SPU_CMD_STOP_DISPLAY:
/* 02 (stop displaying) */
p_spu->end_date += ( i_date * 12000 );
break;
case SPU_CMD_SET_PALETTE:
/* 03xxxx (palette) */
i_word = GetByte( &p_spudec->bit_stream ) << 8
| GetByte( &p_spudec->bit_stream );
i_index += 2;
break;
case SPU_CMD_SET_ALPHACHANNEL:
/* 04xxxx (alpha channel) */
i_word = GetByte( &p_spudec->bit_stream ) << 8
| GetByte( &p_spudec->bit_stream );
i_index += 2;
break;
case SPU_CMD_SET_COORDINATES:
/* 05xxxyyyxxxyyy (coordinates) */
i_word = GetByte( &p_spudec->bit_stream );
p_spu->i_x = (i_word << 4)
| GetBits( &p_spudec->bit_stream, 4 );
i_word = GetBits( &p_spudec->bit_stream, 4 );
p_spu->i_width = p_spu->i_x - ( (i_word << 8)
| GetBits( &p_spudec->bit_stream, 8 ) ) + 1;
i_word = GetBits( &p_spudec->bit_stream, 8 );
p_spu->i_y = (i_word << 4)
| GetBits( &p_spudec->bit_stream, 4 );
i_word = GetBits( &p_spudec->bit_stream, 4 );
p_spu->i_height = p_spu->i_y - ( (i_word << 8)
| GetByte( &p_spudec->bit_stream ) ) + 1;
i_index += 6;
break;
case SPU_CMD_SET_OFFSETS:
/* 06xxxxyyyy (byte offsets) */
p_spu->type.spu.i_offset[0] =
( GetByte( &p_spudec->bit_stream ) << 8
| GetByte( &p_spudec->bit_stream ) ) - 4;
p_spu->type.spu.i_offset[1] =
( GetByte( &p_spudec->bit_stream ) << 8
| GetByte( &p_spudec->bit_stream ) ) - 4;
i_index += 4;
break;
case SPU_CMD_END:
/* ff (end) */
break;
default:
/* ?? (unknown command) */
intf_ErrMsg( "spudec: unknown command 0x%.2x",
i_cmd );
b_valid = 0;
break;
}
case SPU_CMD_FORCE_DISPLAY:
/* 00 (force displaying) */
break;
/* FIXME: here we have to calculate dates. It's
* around i_date * 12000 but I don't know
* how much exactly.
*/
case SPU_CMD_START_DISPLAY:
/* 01 (start displaying) */
p_spu->begin_date += ( i_date * 12000 );
break;
case SPU_CMD_STOP_DISPLAY:
/* 02 (stop displaying) */
p_spu->end_date += ( i_date * 12000 );
break;
case SPU_CMD_SET_PALETTE:
/* 03xxxx (palette) - trashed */
RemoveBits( &p_spudec->bit_stream, 16 );
i_index += 2;
break;
case SPU_CMD_SET_ALPHACHANNEL:
/* 04xxxx (alpha channel) - trashed */
RemoveBits( &p_spudec->bit_stream, 16 );
i_index += 2;
break;
case SPU_CMD_SET_COORDINATES:
/* 05xxxyyyxxxyyy (coordinates) */
p_spu->i_x =
GetBits( &p_spudec->bit_stream, 12 );
p_spu->i_width = p_spu->i_x -
GetBits( &p_spudec->bit_stream, 12 ) + 1;
p_spu->i_y =
GetBits( &p_spudec->bit_stream, 12 );
p_spu->i_height = p_spu->i_y -
GetBits( &p_spudec->bit_stream, 12 ) + 1;
i_index += 6;
break;
case SPU_CMD_SET_OFFSETS:
/* 06xxxxyyyy (byte offsets) */
p_spu->type.spu.i_offset[0] =
GetBits( &p_spudec->bit_stream, 16 ) - 4;
p_spu->type.spu.i_offset[1] =
GetBits( &p_spudec->bit_stream, 16 ) - 4;
i_index += 4;
break;
case SPU_CMD_END:
/* ff (end) */
break;
default:
/* ?? (unknown command) */
intf_ErrMsg( "spudec: unknown command 0x%.2x",
i_cmd );
b_valid = 0;
break;
}
while( b_valid && ( i_cmd != SPU_CMD_END ) );
}
while( b_valid && ( i_index == i_next ) );
while( b_valid && ( i_cmd != SPU_CMD_END ) );
}
while( b_valid && ( i_index == i_next ) );
if( b_valid )
{
/* SPU is finished - we can tell the video output
* to display it */
vout_DisplaySubPicture( p_spudec->p_vout, p_spu );
}
else
{
vout_DestroySubPicture( p_spudec->p_vout, p_spu );
}
if( b_valid )
{
/* SPU is finished - we can tell the video output
* to display it */
vout_DisplaySubPicture( p_spudec->p_vout, p_spu );
}
else
else
{
/* Unexpected PES packet - trash it */
intf_ErrMsg( "spudec: trying to recover from bad packet" );
vlc_mutex_lock( &p_spudec->p_fifo->data_lock );
p_spudec->p_fifo->pf_delete_pes( p_spudec->p_fifo->p_packets_mgt,
DECODER_FIFO_START(*p_spudec->p_fifo) );
DECODER_FIFO_INCSTART( *p_spudec->p_fifo );
vlc_mutex_unlock( &p_spudec->p_fifo->data_lock );
vout_DestroySubPicture( p_spudec->p_vout, p_spu );
}
bad_packet:
}
else
{
/* Unexpected PES packet - trash it */
intf_ErrMsg( "spudec: trying to recover from bad packet" );
vlc_mutex_lock( &p_spudec->p_fifo->data_lock );
p_spudec->p_fifo->pf_delete_pes( p_spudec->p_fifo->p_packets_mgt,
DECODER_FIFO_START(*p_spudec->p_fifo) );
DECODER_FIFO_INCSTART( *p_spudec->p_fifo );
vlc_mutex_unlock( &p_spudec->p_fifo->data_lock );
}
}
......
......@@ -2,7 +2,7 @@
* video_parser.c : video parser thread
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: video_parser.c,v 1.64 2001/01/10 19:22:11 massiot Exp $
* $Id: video_parser.c,v 1.65 2001/01/12 17:33:18 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Samuel Hocevar <sam@via.ecp.fr>
......@@ -308,6 +308,18 @@ static void EndThread( vpar_thread_t *p_vpar )
intf_DbgMsg("vpar debug: destroying video parser thread %p", p_vpar);
/* Release used video buffers. */
if( p_vpar->sequence.p_forward != NULL )
{
vout_UnlinkPicture( p_vpar->p_vout, p_vpar->sequence.p_forward );
}
if( p_vpar->sequence.p_backward != NULL )
{
vout_DatePicture( p_vpar->p_vout, p_vpar->sequence.p_backward,
vpar_SynchroDate( p_vpar ) );
vout_UnlinkPicture( p_vpar->p_vout, p_vpar->sequence.p_backward );
}
#ifdef STATS
intf_Msg("vpar stats: %d loops among %d sequence(s)",
p_vpar->c_loops, p_vpar->c_sequences);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment