From: Gildas Bazin Date: Sun, 7 Mar 2004 22:34:22 +0000 (+0000) Subject: * include/vlc_es.h: added b_packetized field to es_format_t to tell a decoder if... X-Git-Tag: 0.7.2~739 X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=779340cfa2ce06d7226e037765807edd24942885;p=vlc * 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. --- diff --git a/include/vlc_codec.h b/include/vlc_codec.h index f62e99ce77..c0b7617aa9 100644 --- a/include/vlc_codec.h +++ b/include/vlc_codec.h @@ -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 * @@ -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; diff --git a/include/vlc_es.h b/include/vlc_es.h index 7e78bd1869..6cb50c3706 100644 --- a/include/vlc_es.h +++ b/include/vlc_es.h @@ -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 * @@ -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 { diff --git a/modules/codec/faad.c b/modules/codec/faad.c index 35c8c6791a..e5a71f762b 100644 --- a/modules/codec/faad.c +++ b/modules/codec/faad.c @@ -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 * Gildas Bazin @@ -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; } diff --git a/modules/codec/ffmpeg/ffmpeg.c b/modules/codec/ffmpeg/ffmpeg.c index fee83e9e00..739c4ab7fa 100644 --- a/modules/codec/ffmpeg/ffmpeg.c +++ b/modules/codec/ffmpeg/ffmpeg.c @@ -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 * Gildas Bazin @@ -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 ); diff --git a/modules/demux/ps.h b/modules/demux/ps.h index ed81a79960..4671d5e8d4 100644 --- a/modules/demux/ps.h +++ b/modules/demux/ps.h @@ -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 * @@ -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; } diff --git a/modules/demux/ts.c b/modules/demux/ts.c index d82b7b3185..0f3a13e79d 100644 --- a/modules/demux/ts.c +++ b/modules/demux/ts.c @@ -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 * @@ -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 ; } diff --git a/src/input/es_out.c b/src/input/es_out.c index c7e925ff1f..a1df9b9393 100644 --- a/src/input/es_out.c +++ b/src/input/es_out.c @@ -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 * @@ -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 ); diff --git a/src/input/input_dec.c b/src/input/input_dec.c index c09c4a8bb8..0df4b453d6 100644 --- a/src/input/input_dec.c +++ b/src/input/input_dec.c @@ -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 ); } diff --git a/src/input/input_programs.c b/src/input/input_programs.c index 33e7d60ca4..f5b08b1011 100644 --- a/src/input/input_programs.c +++ b/src/input/input_programs.c @@ -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 * @@ -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 ) {