]> git.sesse.net Git - vlc/commitdiff
* include/vlc_es.h: added b_packetized field to es_format_t to tell a decoder if...
authorGildas Bazin <gbazin@videolan.org>
Sun, 7 Mar 2004 22:34:22 +0000 (22:34 +0000)
committerGildas Bazin <gbazin@videolan.org>
Sun, 7 Mar 2004 22:34:22 +0000 (22:34 +0000)
* 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.

include/vlc_codec.h
include/vlc_es.h
modules/codec/faad.c
modules/codec/ffmpeg/ffmpeg.c
modules/demux/ps.h
modules/demux/ts.c
src/input/es_out.c
src/input/input_dec.c
src/input/input_programs.c

index f62e99ce77de3c8262de8dc2d3edcf9e7fb93001..c0b7617aa957cc25ca355d99e25f59d5da9691a6 100644 (file)
@@ -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;
 
index 7e78bd1869c300854840eece1140f41ca997bba9..6cb50c37066c811c6927be9cf9fcd5a76bb28942 100644 (file)
@@ -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
     {
index 35c8c6791a65010fd8e92b0424763047becc320b..e5a71f762b8d2125621b678d61bb840abc850ab8 100644 (file)
@@ -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;
 }
 
index fee83e9e002d50edfea2322c41ee7d669946e212..739c4ab7fa21f6cec04374f11d39b1bb9f4f2350 100644 (file)
@@ -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 );
index ed81a7996095c892b0f3a26457fd3d660a81491f..4671d5e8d4cf94506ceae5c519043678ddf75bec 100644 (file)
@@ -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;
 }
 
index d82b7b3185ebcd41dc99c29f2c316941a7889f4d..0f3a13e79d39dffd8eba53818d51076060411721 100644 (file)
@@ -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 ;
 }
 
index c7e925ff1f92c92349bf7dc760422d5308fdb762..a1df9b93937db57fd3bf6d582810e6d08e3597ab 100644 (file)
@@ -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 );
index c09c4a8bb8b2622cb8bd1db6c9c49707133bf417..0df4b453d601934596b8e090c2498dce240aedbe 100644 (file)
@@ -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 );
 }
index 33e7d60ca44aa2d5106773b22c44f630cdd672b8..f5b08b1011ba782004b8c001c5f62032c16b4128 100644 (file)
@@ -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 )
     {