Commit 779340cf authored by Gildas Bazin's avatar Gildas Bazin

* include/vlc_es.h: added b_packetized field to es_format_t to tell a decoder...

* include/vlc_es.h: added b_packetized field to es_format_t to tell a decoder if the input elementary stream will be fed in complete frames.
* include/vlc_codec.h: added a b_need_packetized field to decoder_t that is used by a decoder to tell if it wants to be fed complete frames.
* modules/demux/ts.c, modules/demux/ps.h, src/input/input_programs.c: b_packetized = VLC_FALSE.
* modules/codec/ffmpeg/ffmpeg.c, modules/codec/faad.c: b_need_packetized = VLC_TRUE;
* src/input/input_dec.c: if (b_need_packetized & !b_packetized) then kick off a packetizer that we'll use to feed the decoder.
* src/input/es_out.c: removed useless stuff.
parent 5c5ee979
......@@ -2,7 +2,7 @@
* vlc_codec.h: codec related structures
*****************************************************************************
* Copyright (C) 1999-2003 VideoLAN
* $Id: vlc_codec.h,v 1.8 2004/02/20 18:34:28 massiot Exp $
* $Id$
*
* Authors: Gildas Bazin <gbazin@netcourrier.com>
*
......@@ -53,6 +53,9 @@ struct decoder_t
void ( * pf_decode_sub) ( decoder_t *, block_t ** );
block_t * ( * pf_packetize ) ( decoder_t *, block_t ** );
/* Some decoders only accept packetized data (ie. not truncated) */
vlc_bool_t b_need_packetized;
/* Input format ie from demuxer (XXX: a lot of field could be invalid) */
es_format_t fmt_in;
......
......@@ -2,7 +2,7 @@
* vlc_es.h: Elementary stream formats descriptions
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
* $Id: vlc_es.h,v 1.10 2004/02/07 00:33:08 gbazin Exp $
* $Id$
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
......@@ -142,8 +142,10 @@ struct es_format_t
video_format_t video;
subs_format_t subs;
int i_bitrate;
int i_bitrate;
vlc_bool_t b_packetized; /* wether the data is packetized
(ie. not truncated) */
int i_extra;
void *p_extra;
......@@ -171,6 +173,7 @@ static inline void es_format_Init( es_format_t *fmt,
memset( &fmt->video, 0, sizeof(video_format_t) );
memset( &fmt->subs, 0, sizeof(subs_format_t) );
fmt->b_packetized = VLC_TRUE;
fmt->i_bitrate = 0;
fmt->i_extra = 0;
fmt->p_extra = NULL;
......@@ -185,9 +188,9 @@ static inline void es_format_Copy( es_format_t *dst, es_format_t *src )
dst->psz_description = strdup( src->psz_description );
if( src->i_extra > 0 )
{
dst->i_extra = src->i_extra;
dst->p_extra = malloc( src->i_extra );
memcpy( dst->p_extra, src->p_extra,
src->i_extra );
memcpy( dst->p_extra, src->p_extra, src->i_extra );
}
else
{
......
......@@ -2,7 +2,7 @@
* decoder.c: AAC decoder using libfaad2
*****************************************************************************
* Copyright (C) 2001, 2003 VideoLAN
* $Id: faad.c,v 1.14 2004/02/25 17:48:52 fenrir Exp $
* $Id$
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Gildas Bazin <gbazin@netcourrier.com>
......@@ -161,6 +161,9 @@ static int Open( vlc_object_t *p_this )
p_sys->i_buffer = p_sys->i_buffer_size = 0;
p_sys->p_buffer = 0;
/* Faad2 can't deal with truncated data (eg. from MPEG TS) */
p_dec->b_need_packetized = VLC_TRUE;
return VLC_SUCCESS;
}
......
......@@ -2,7 +2,7 @@
* ffmpeg.c: video decoder using ffmpeg library
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
* $Id: ffmpeg.c,v 1.80 2004/01/26 18:57:18 gbazin Exp $
* $Id$
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Gildas Bazin <gbazin@netcourrier.com>
......@@ -180,6 +180,7 @@ static int OpenDecoder( vlc_object_t *p_this )
switch( i_cat )
{
case VIDEO_ES:
p_dec->b_need_packetized = VLC_TRUE;
p_dec->pf_decode_video = E_(DecodeVideo);
i_result = E_( InitVideoDec )( p_dec, p_context, p_codec,
i_codec_id, psz_namecodec );
......
......@@ -2,7 +2,7 @@
* ps.h: Program Stream demuxer helper
*****************************************************************************
* Copyright (C) 2004 VideoLAN
* $Id: ps.h,v 1.5 2004/01/30 01:09:24 fenrir Exp $
* $Id$
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
......@@ -101,6 +101,10 @@ static inline int ps_track_fill( ps_track_t *tk, int i_id )
return VLC_EGENERIC;
}
}
/* PES packets usually contain truncated frames */
tk->fmt.b_packetized = VLC_FALSE;
return VLC_SUCCESS;
}
......
......@@ -2,7 +2,7 @@
* ts.c: Transport Stream input module for VLC.
*****************************************************************************
* Copyright (C) 2004 VideoLAN
* $Id: ts.c,v 1.13 2004/03/03 01:26:49 fenrir Exp $
* $Id$
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
......@@ -1148,6 +1148,9 @@ static int PIDFillFormat( ts_pid_t *pid, int i_stream_type )
break;
}
/* PES packets usually contain truncated frames */
fmt->b_packetized = VLC_FALSE;
return fmt->i_cat == UNKNOWN_ES ? VLC_EGENERIC : VLC_SUCCESS ;
}
......
......@@ -2,7 +2,7 @@
* es_out.c: Es Out handler for input.
*****************************************************************************
* Copyright (C) 2003-2004 VideoLAN
* $Id: es_out.c,v 1.25 2004/01/31 20:21:47 fenrir Exp $
* $Id$
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
......@@ -331,54 +331,15 @@ static es_out_id_t *EsOutAdd( es_out_t *out, es_format_t *fmt )
switch( fmt->i_cat )
{
case AUDIO_ES:
{
WAVEFORMATEX *p_wf =
malloc( sizeof( WAVEFORMATEX ) + fmt->i_extra);
p_wf->wFormatTag = WAVE_FORMAT_UNKNOWN;
p_wf->nChannels = fmt->audio.i_channels;
p_wf->nSamplesPerSec = fmt->audio.i_rate;
p_wf->nAvgBytesPerSec = fmt->i_bitrate / 8;
p_wf->nBlockAlign = fmt->audio.i_blockalign;
p_wf->wBitsPerSample = fmt->audio.i_bitspersample;
p_wf->cbSize = fmt->i_extra;
if( fmt->i_extra > 0 )
{
memcpy( &p_wf[1], fmt->p_extra, fmt->i_extra );
}
es->p_es->p_waveformatex = p_wf;
es->i_channel = p_sys->i_audio;
break;
}
case VIDEO_ES:
{
BITMAPINFOHEADER *p_bih = malloc( sizeof( BITMAPINFOHEADER ) +
fmt->i_extra );
p_bih->biSize = sizeof(BITMAPINFOHEADER) + fmt->i_extra;
p_bih->biWidth = fmt->video.i_width;
p_bih->biHeight = fmt->video.i_height;
p_bih->biPlanes = 1;
p_bih->biBitCount = 24;
p_bih->biCompression = fmt->i_codec;
p_bih->biSizeImage = fmt->video.i_width *
fmt->video.i_height;
p_bih->biXPelsPerMeter = 0;
p_bih->biYPelsPerMeter = 0;
p_bih->biClrUsed = 0;
p_bih->biClrImportant = 0;
case AUDIO_ES:
es->i_channel = p_sys->i_audio;
break;
if( fmt->i_extra > 0 )
{
memcpy( &p_bih[1], fmt->p_extra, fmt->i_extra );
}
es->p_es->p_bitmapinfoheader = p_bih;
case VIDEO_ES:
es->i_channel = p_sys->i_video;
break;
es->i_channel = p_sys->i_video;
break;
}
case SPU_ES:
case SPU_ES:
{
subtitle_data_t *p_sub = malloc( sizeof( subtitle_data_t ) );
memset( p_sub, 0, sizeof( subtitle_data_t ) );
......@@ -396,9 +357,9 @@ static es_out_id_t *EsOutAdd( es_out_t *out, es_format_t *fmt )
break;
}
default:
es->i_channel = 0;
break;
default:
es->i_channel = 0;
break;
}
sprintf( psz_cat, _("Stream %d"), out->p_sys->i_id - 1 );
......
......@@ -71,6 +71,9 @@ struct decoder_owner_sys_t
sout_instance_t *p_sout;
sout_packetizer_input_t *p_sout_input;
/* Some decoders require already packetized data (ie. not truncated) */
decoder_t *p_packetizer;
/* Current format in use by the output */
video_format_t video;
audio_format_t audio;
......@@ -94,8 +97,8 @@ struct decoder_owner_sys_t
*/
decoder_t * input_RunDecoder( input_thread_t * p_input, es_descriptor_t * p_es )
{
decoder_t *p_dec = NULL;
vlc_value_t val;
decoder_t *p_dec = NULL;
vlc_value_t val;
/* If we are in sout mode, search for packetizer module */
if( !p_es->b_force_decoder && p_input->stream.p_sout )
......@@ -107,8 +110,6 @@ decoder_t * input_RunDecoder( input_thread_t * p_input, es_descriptor_t * p_es )
msg_Err( p_input, "could not create packetizer" );
return NULL;
}
p_dec->p_module = module_Need( p_dec, "packetizer", "$packetizer", 0 );
}
else
{
......@@ -119,9 +120,6 @@ decoder_t * input_RunDecoder( input_thread_t * p_input, es_descriptor_t * p_es )
msg_Err( p_input, "could not create decoder" );
return NULL;
}
/* default Get a suitable decoder module */
p_dec->p_module = module_Need( p_dec, "decoder", "$codec", 0 );
}
if( !p_dec->p_module )
......@@ -163,6 +161,12 @@ decoder_t * input_RunDecoder( input_thread_t * p_input, es_descriptor_t * p_es )
}
}
/* Select a new ES */
INSERT_ELEM( p_input->stream.pp_selected_es,
p_input->stream.i_selected_es_number,
p_input->stream.i_selected_es_number,
p_es );
p_input->stream.b_changed = 1;
return p_dec;
......@@ -398,16 +402,10 @@ static decoder_t * CreateDecoder( input_thread_t * p_input,
p_dec->pf_decode_sub = 0;
p_dec->pf_packetize = 0;
/* Select a new ES */
INSERT_ELEM( p_input->stream.pp_selected_es,
p_input->stream.i_selected_es_number,
p_input->stream.i_selected_es_number,
p_es );
/* Initialize the decoder fifo */
p_dec->p_module = NULL;
p_dec->fmt_in = p_es->fmt;
es_format_Copy( &p_dec->fmt_in, &p_es->fmt );
if( p_es->p_waveformatex )
{
......@@ -480,6 +478,7 @@ static decoder_t * CreateDecoder( input_thread_t * p_input,
p_dec->p_owner->p_vout = NULL;
p_dec->p_owner->p_sout = p_input->stream.p_sout;
p_dec->p_owner->p_sout_input = NULL;
p_dec->p_owner->p_packetizer = NULL;
p_dec->p_owner->p_es_descriptor = p_es;
......@@ -501,6 +500,40 @@ static decoder_t * CreateDecoder( input_thread_t * p_input,
vlc_object_attach( p_dec, p_input );
/* Find a suitable decoder/packetizer module */
if( i_object_type == VLC_OBJECT_DECODER )
p_dec->p_module = module_Need( p_dec, "decoder", "$codec", 0 );
else
p_dec->p_module = module_Need( p_dec, "packetizer", "$packetizer", 0 );
/* Check if decoder requires already packetized data */
if( i_object_type == VLC_OBJECT_DECODER &&
p_dec->b_need_packetized && !p_dec->fmt_in.b_packetized )
{
p_dec->p_owner->p_packetizer =
vlc_object_create( p_input, VLC_OBJECT_PACKETIZER );
if( p_dec->p_owner->p_packetizer )
{
p_dec->p_owner->p_packetizer->fmt_in = null_es_format;
p_dec->p_owner->p_packetizer->fmt_out = null_es_format;
es_format_Copy( &p_dec->p_owner->p_packetizer->fmt_in,
&p_dec->fmt_in );
vlc_object_attach( p_dec->p_owner->p_packetizer, p_input );
p_dec->p_owner->p_packetizer->p_module =
module_Need( p_dec->p_owner->p_packetizer,
"packetizer", "$packetizer", 0 );
if( !p_dec->p_owner->p_packetizer->p_module )
{
es_format_Clean( &p_dec->p_owner->p_packetizer->fmt_in );
vlc_object_detach( p_dec->p_owner->p_packetizer );
vlc_object_destroy( p_dec->p_owner->p_packetizer );
}
}
}
return p_dec;
}
......@@ -580,14 +613,17 @@ static int DecoderDecode( decoder_t *p_dec, block_t *p_block )
p_dec->p_owner->sout.i_group =
p_dec->p_owner->p_es_descriptor->p_pgrm->i_number;
}
p_dec->p_owner->sout.i_id = p_dec->p_owner->p_es_descriptor->i_id - 1;
p_dec->p_owner->sout.i_id =
p_dec->p_owner->p_es_descriptor->i_id - 1;
if( p_dec->fmt_in.psz_language )
{
p_dec->p_owner->sout.psz_language = strdup( p_dec->fmt_in.psz_language );
p_dec->p_owner->sout.psz_language =
strdup( p_dec->fmt_in.psz_language );
}
p_dec->p_owner->p_sout_input =
sout_InputNew( p_dec->p_owner->p_sout, &p_dec->p_owner->sout );
sout_InputNew( p_dec->p_owner->p_sout,
&p_dec->p_owner->sout );
if( p_dec->p_owner->p_sout_input == NULL )
{
......@@ -596,7 +632,7 @@ static int DecoderDecode( decoder_t *p_dec, block_t *p_block )
while( p_sout_block )
{
block_t *p_next = p_sout_block->p_next;
block_t *p_next = p_sout_block->p_next;
block_Release( p_sout_block );
p_sout_block = p_next;
}
......@@ -625,12 +661,13 @@ static int DecoderDecode( decoder_t *p_dec, block_t *p_block )
p_sout_buffer->i_dts = p_sout_block->i_dts;
p_sout_buffer->i_length = p_sout_block->i_length;
p_sout_buffer->i_flags =
(p_sout_block->i_flags << SOUT_BUFFER_FLAGS_BLOCK_SHIFT)
& SOUT_BUFFER_FLAGS_BLOCK_MASK;
( p_sout_block->i_flags << SOUT_BUFFER_FLAGS_BLOCK_SHIFT )
& SOUT_BUFFER_FLAGS_BLOCK_MASK;
block_Release( p_sout_block );
sout_InputSendBuffer( p_dec->p_owner->p_sout_input, p_sout_buffer );
sout_InputSendBuffer( p_dec->p_owner->p_sout_input,
p_sout_buffer );
p_sout_block = p_next;
}
......@@ -654,7 +691,23 @@ static int DecoderDecode( decoder_t *p_dec, block_t *p_block )
{
aout_buffer_t *p_aout_buf;
while( (p_aout_buf = p_dec->pf_decode_audio( p_dec, &p_block )) )
if( p_dec->p_owner->p_packetizer )
{
block_t *p_packetized_block;
decoder_t *p_packetizer = p_dec->p_owner->p_packetizer;
while( (p_packetized_block =
p_packetizer->pf_packetize( p_packetizer, &p_block )) )
{
while( (p_aout_buf =
p_dec->pf_decode_audio( p_dec, &p_packetized_block )) )
{
aout_DecPlay( p_dec->p_owner->p_aout,
p_dec->p_owner->p_aout_input, p_aout_buf );
}
}
}
else while( (p_aout_buf = p_dec->pf_decode_audio( p_dec, &p_block )) )
{
aout_DecPlay( p_dec->p_owner->p_aout,
p_dec->p_owner->p_aout_input, p_aout_buf );
......@@ -664,7 +717,24 @@ static int DecoderDecode( decoder_t *p_dec, block_t *p_block )
{
picture_t *p_pic;
while( (p_pic = p_dec->pf_decode_video( p_dec, &p_block )) )
if( p_dec->p_owner->p_packetizer )
{
block_t *p_packetized_block;
decoder_t *p_packetizer = p_dec->p_owner->p_packetizer;
while( (p_packetized_block =
p_packetizer->pf_packetize( p_packetizer, &p_block )) )
{
while( (p_pic =
p_dec->pf_decode_video( p_dec, &p_packetized_block )) )
{
vout_DatePicture( p_dec->p_owner->p_vout, p_pic,
p_pic->date );
vout_DisplayPicture( p_dec->p_owner->p_vout, p_pic );
}
}
}
else while( (p_pic = p_dec->pf_decode_video( p_dec, &p_block )) )
{
vout_DatePicture( p_dec->p_owner->p_vout, p_pic, p_pic->date );
vout_DisplayPicture( p_dec->p_owner->p_vout, p_pic );
......@@ -693,8 +763,7 @@ static void DeleteDecoder( decoder_t * p_dec )
{
vlc_object_detach( p_dec );
msg_Dbg( p_dec,
"killing decoder fourcc `%4.4s', %d PES in FIFO",
msg_Dbg( p_dec, "killing decoder fourcc `%4.4s', %d PES in FIFO",
(char*)&p_dec->fmt_in.i_codec,
p_dec->p_owner->p_fifo->i_depth );
......@@ -729,11 +798,21 @@ static void DeleteDecoder( decoder_t * p_dec )
if( p_dec->p_owner->p_sout_input )
{
sout_InputDelete( p_dec->p_owner->p_sout_input );
if( p_dec->p_owner->sout.i_extra ) free(p_dec->p_owner->sout.p_extra);
es_format_Clean( &p_dec->p_owner->sout );
}
if( p_dec->fmt_in.i_extra ) free( p_dec->fmt_in.p_extra );
if( p_dec->fmt_out.i_extra ) free( p_dec->fmt_out.p_extra );
es_format_Clean( &p_dec->fmt_in );
es_format_Clean( &p_dec->fmt_out );
if( p_dec->p_owner->p_packetizer )
{
module_Unneed( p_dec->p_owner->p_packetizer,
p_dec->p_owner->p_packetizer->p_module );
es_format_Clean( &p_dec->p_owner->p_packetizer->fmt_in );
es_format_Clean( &p_dec->p_owner->p_packetizer->fmt_out );
vlc_object_detach( p_dec->p_owner->p_packetizer );
vlc_object_destroy( p_dec->p_owner->p_packetizer );
}
free( p_dec->p_owner );
}
......
......@@ -2,7 +2,7 @@
* input_programs.c: es_descriptor_t, pgrm_descriptor_t management
*****************************************************************************
* Copyright (C) 1999-2004 VideoLAN
* $Id: input_programs.c,v 1.133 2004/02/25 12:38:33 fenrir Exp $
* $Id$
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
......@@ -624,6 +624,7 @@ es_descriptor_t * input_AddES( input_thread_t * p_input,
p_es->c_invalid_packets = 0;
p_es->b_force_decoder = VLC_FALSE;
es_format_Init( &p_es->fmt, UNKNOWN_ES, 0 );
p_es->fmt.b_packetized = VLC_FALSE; /* Only there for old mpeg demuxers */
if( i_data_len )
{
......
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