]> git.sesse.net Git - vlc/blobdiff - modules/codec/flac.c
* block: added
[vlc] / modules / codec / flac.c
index afe6c68987a12d51c81c0cc8954d9c9af3e832d3..8c7b95faef637002ab70076037a6f1d01bbcb945 100644 (file)
@@ -142,6 +142,9 @@ static uint8_t flac_crc8( const uint8_t *data, unsigned len );
  *****************************************************************************/
 vlc_module_begin();
 
+    set_category( CAT_INPUT );
+    set_subcategory( SUBCAT_INPUT_ACODEC );
+
     set_description( _("Flac audio decoder") );
     set_capability( "decoder", 100 );
     set_callbacks( OpenDecoder, CloseDecoder );
@@ -215,30 +218,56 @@ static int OpenDecoder( vlc_object_t *p_this )
     p_dec->pf_decode_audio = DecodeBlock;
     p_dec->pf_packetize    = PacketizeBlock;
 
-    /* Decode STREAMINFO */
-    msg_Dbg( p_dec, "decode STREAMINFO" );
-    p_sys->p_block = block_New( p_dec, p_dec->fmt_in.i_extra );
-    memcpy( p_sys->p_block->p_buffer, p_dec->fmt_in.p_extra,
-            p_dec->fmt_in.i_extra );
-    FLAC__stream_decoder_process_until_end_of_metadata( p_sys->p_flac );
-    msg_Dbg( p_dec, "STREAMINFO decoded" );
-
     return VLC_SUCCESS;
 }
 
 static int OpenPacketizer( vlc_object_t *p_this )
 {
     decoder_t *p_dec = (decoder_t*)p_this;
+    int i_ret;
+
+    /* Hmmm, mem leak ?*/
+    es_format_Copy( &p_dec->fmt_out, &p_dec->fmt_in );
 
-    int i_ret = OpenDecoder( p_this );
+    i_ret = OpenDecoder( p_this );
 
-    if( i_ret != VLC_SUCCESS ) return i_ret;
+    /* Set output properties */
+    p_dec->fmt_out.i_codec = VLC_FOURCC('f','l','a','c');
 
-    es_format_Copy( &p_dec->fmt_out, &p_dec->fmt_in );
+    if( i_ret != VLC_SUCCESS ) return i_ret;
 
     return i_ret;
 }
 
+/*****************************************************************************
+ * ProcessHeader: processe Flac header.
+ *****************************************************************************/
+static void ProcessHeader( decoder_t *p_dec )
+{
+    decoder_sys_t *p_sys = p_dec->p_sys;
+
+    if( !p_dec->fmt_in.i_extra ) return;
+
+    /* Decode STREAMINFO */
+    msg_Dbg( p_dec, "decode STREAMINFO" );
+    p_sys->p_block = block_New( p_dec, p_dec->fmt_in.i_extra );
+    memcpy( p_sys->p_block->p_buffer, p_dec->fmt_in.p_extra,
+            p_dec->fmt_in.i_extra );
+    FLAC__stream_decoder_process_until_end_of_metadata( p_sys->p_flac );
+    msg_Dbg( p_dec, "STREAMINFO decoded" );
+
+    if( !p_sys->b_stream_info ) return;
+
+    if( p_dec->fmt_out.i_codec == VLC_FOURCC('f','l','a','c') )
+    {
+        p_dec->fmt_out.i_extra = p_dec->fmt_in.i_extra;
+        p_dec->fmt_out.p_extra =
+            realloc( p_dec->fmt_out.p_extra, p_dec->fmt_out.i_extra );
+        memcpy( p_dec->fmt_out.p_extra,
+                p_dec->fmt_in.p_extra, p_dec->fmt_out.i_extra );
+    }
+}
+
 /****************************************************************************
  * PacketizeBlock: the whole thing
  ****************************************************************************
@@ -252,14 +281,21 @@ static block_t *PacketizeBlock( decoder_t *p_dec, block_t **pp_block )
 
     if( !pp_block || !*pp_block ) return NULL;
 
+    if( !p_sys->b_stream_info ) ProcessHeader( p_dec );
+
     if( !aout_DateGet( &p_sys->end_date ) && !(*pp_block)->i_pts )
     {
         /* We've just started the stream, wait for the first PTS. */
         block_Release( *pp_block );
         return NULL;
     }
+    else if( !aout_DateGet( &p_sys->end_date ) )
+    {
+        /* The first PTS is as good as anything else. */
+        aout_DateSet( &p_sys->end_date, (*pp_block)->i_pts );
+    }
 
-    if( (*pp_block)->i_flags&BLOCK_FLAG_DISCONTINUITY )
+    if( (*pp_block)->i_flags&(BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
     {
         p_sys->i_state = STATE_NOSYNC;
     }
@@ -325,7 +361,6 @@ static block_t *PacketizeBlock( decoder_t *p_dec, block_t **pp_block )
             {
                 p_dec->fmt_out.audio.i_rate = p_sys->i_rate;
                 aout_DateInit( &p_sys->end_date, p_sys->i_rate );
-                p_dec->fmt_out.audio.i_rate = p_sys->i_rate;
             }
             p_sys->i_state = STATE_NEXT_SYNC;
             p_sys->i_frame_size = 1;
@@ -364,7 +399,6 @@ static block_t *PacketizeBlock( decoder_t *p_dec, block_t **pp_block )
                 /* Need more data */
                 return NULL;
             }
-            break;
 
         case STATE_SEND_DATA:
             p_sout_block = block_New( p_dec, p_sys->i_frame_size );