]> git.sesse.net Git - vlc/commitdiff
Simplify FLAC extradata (streaminfo) parsing
authorRafaël Carré <funman@videolan.org>
Sun, 23 Jun 2013 21:15:55 +0000 (23:15 +0200)
committerRafaël Carré <funman@videolan.org>
Sun, 23 Jun 2013 21:16:35 +0000 (23:16 +0200)
Prefer the shorter version (avcodec/avformat support both)

modules/codec/avcodec/audio.c
modules/codec/avcodec/encoder.c
modules/codec/flac.c
modules/demux/avformat/mux.c
modules/demux/flac.c
modules/demux/mkv/matroska_segment_parse.cpp
modules/demux/ogg.c
modules/mux/ogg.c
modules/packetizer/flac.c

index 2dd3a7bb125985bfb1fc2f6aef9bdfc6535c7dad..b2f70ffe9341aea04db3a84a6563d867562de25a 100644 (file)
@@ -76,15 +76,11 @@ static void InitDecoderConfig( decoder_t *p_dec, AVCodecContext *p_context )
     if( p_dec->fmt_in.i_extra > 0 )
     {
         const uint8_t * const p_src = p_dec->fmt_in.p_extra;
-        int i_offset;
-        int i_size;
 
-        if( p_dec->fmt_in.i_codec == VLC_CODEC_FLAC )
-        {
-            i_offset = 8;
-            i_size = p_dec->fmt_in.i_extra - 8;
-        }
-        else if( p_dec->fmt_in.i_codec == VLC_CODEC_ALAC )
+        int i_offset = 0;
+        int i_size = p_dec->fmt_in.i_extra;
+
+        if( p_dec->fmt_in.i_codec == VLC_CODEC_ALAC )
         {
             static const uint8_t p_pattern[] = { 0, 0, 0, 36, 'a', 'l', 'a', 'c' };
             /* Find alac atom XXX it is a bit ugly */
@@ -97,11 +93,6 @@ static void InitDecoderConfig( decoder_t *p_dec, AVCodecContext *p_context )
             if( i_size < 36 )
                 i_size = 0;
         }
-        else
-        {
-            i_offset = 0;
-            i_size = p_dec->fmt_in.i_extra;
-        }
 
         if( i_size > 0 )
         {
index cbbe13a3a28b3fd39a95d39bca3fcc4d52b5d3f3..9717d099b8c3b14c2a4165b425b61b0caacfad53 100644 (file)
@@ -822,41 +822,16 @@ int OpenEncoder( vlc_object_t *p_this )
 
     av_dict_free(&options);
 
-    if( i_codec_id == AV_CODEC_ID_FLAC )
+    p_enc->fmt_out.i_extra = p_context->extradata_size;
+    if( p_enc->fmt_out.i_extra )
     {
-        p_enc->fmt_out.i_extra = 4 + 1 + 3 + p_context->extradata_size;
         p_enc->fmt_out.p_extra = malloc( p_enc->fmt_out.i_extra );
-        if( p_enc->fmt_out.p_extra )
+        if ( p_enc->fmt_out.p_extra == NULL )
         {
-            uint8_t *p = p_enc->fmt_out.p_extra;
-            p[0] = 0x66;    /* f */
-            p[1] = 0x4C;    /* L */
-            p[2] = 0x61;    /* a */
-            p[3] = 0x43;    /* C */
-            p[4] = 0x80;    /* streaminfo block, last block before audio */
-            p[5] = ( p_context->extradata_size >> 16 ) & 0xff;
-            p[6] = ( p_context->extradata_size >>  8 ) & 0xff;
-            p[7] = ( p_context->extradata_size       ) & 0xff;
-            memcpy( &p[8], p_context->extradata, p_context->extradata_size );
-        }
-        else
-        {
-            p_enc->fmt_out.i_extra = 0;
-        }
-    }
-    else
-    {
-        p_enc->fmt_out.i_extra = p_context->extradata_size;
-        if( p_enc->fmt_out.i_extra )
-        {
-            p_enc->fmt_out.p_extra = malloc( p_enc->fmt_out.i_extra );
-            if ( p_enc->fmt_out.p_extra == NULL )
-            {
-                goto error;
-            }
-            memcpy( p_enc->fmt_out.p_extra, p_context->extradata,
-                    p_enc->fmt_out.i_extra );
+            goto error;
         }
+        memcpy( p_enc->fmt_out.p_extra, p_context->extradata,
+                p_enc->fmt_out.i_extra );
     }
 
     p_context->flags &= ~CODEC_FLAG_GLOBAL_HEADER;
index 215de76d5f5324b2bc2d2e738ab2fa2b31c63026..5568fcf155d35d9521029e5e8457b5b92a3f2ff6 100644 (file)
@@ -386,7 +386,7 @@ static void ProcessHeader( decoder_t *p_dec )
         memcpy( p_sys->p_block->p_buffer + 8, p_dec->fmt_in.p_extra, i_extra );
         memcpy( p_sys->p_block->p_buffer, "fLaC", 4);
         uint8_t *p = p_sys->p_block->p_buffer;
-        p[4] = 0; /* STREAMINFO */
+        p[4] = 0x80 | 0; /* STREAMINFO faked as last block */
         p[5] = 0;
         p[6] = 0;
         p[7] = 34; /* block size */
@@ -396,7 +396,7 @@ static void ProcessHeader( decoder_t *p_dec )
         memcpy( p_sys->p_block->p_buffer, p_dec->fmt_in.p_extra, i_extra );
         break;
     default:
-        msg_Err(p_dec, "Invalid flac header size %zu\n", i_extra);
+        msg_Err(p_dec, "Invalid flac header size %zu", i_extra);
         return;
     }
     FLAC__stream_decoder_process_until_end_of_metadata( p_sys->p_flac );
@@ -547,7 +547,7 @@ struct encoder_sys_t
     mtime_t i_pts;
 };
 
-#define STREAMINFO_SIZE 38
+#define STREAMINFO_SIZE 34
 
 static block_t *Encode( encoder_t *, block_t * );
 
@@ -572,14 +572,9 @@ EncoderWriteCallback( const FLAC__StreamEncoder *encoder,
             msg_Dbg( p_enc, "Writing STREAMINFO: %zu", bytes );
 
             /* Backup the STREAMINFO metadata block */
-            p_enc->fmt_out.i_extra = STREAMINFO_SIZE + 4;
-            p_enc->fmt_out.p_extra = xmalloc( STREAMINFO_SIZE + 4 );
-            memcpy( p_enc->fmt_out.p_extra, "fLaC", 4 );
-            memcpy( ((uint8_t *)p_enc->fmt_out.p_extra) + 4, buffer,
-                    STREAMINFO_SIZE );
-
-            /* Fake this as the last metadata block */
-            ((uint8_t*)p_enc->fmt_out.p_extra)[4] |= 0x80;
+            p_enc->fmt_out.i_extra = STREAMINFO_SIZE;
+            p_enc->fmt_out.p_extra = xmalloc( STREAMINFO_SIZE );
+            memcpy(p_enc->fmt_out.p_extra, buffer + 4, STREAMINFO_SIZE );
         }
         p_sys->i_headers++;
         return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
index 58109f939be532258bc906e7cfd9c3d061c57c0c..5e2225fcfffe6c404e2ae73bc6f81f825d1684ea 100644 (file)
@@ -40,7 +40,7 @@
 #include "../../codec/avcodec/avcommon.h"
 
 
-//#define AVFORMAT_DEBUG 1
+#define AVFORMAT_DEBUG 1
 
 static const char *const ppsz_mux_options[] = {
     "mux", "options", NULL
index e6835e446ee9b8230e04511d3de4c73b61ff9cc4..28d58090fe58f8fa1c6d39ccca447acd636bca60 100644 (file)
@@ -91,7 +91,7 @@ struct demux_sys_t
     int                i_cover_score;
 };
 
-#define STREAMINFO_SIZE 38
+#define STREAMINFO_SIZE 34
 #define FLAC_PACKET_SIZE 16384
 
 /*****************************************************************************
@@ -146,7 +146,6 @@ static int Open( vlc_object_t * p_this )
 
     /* Load the FLAC packetizer */
     /* Store STREAMINFO for the decoder and packetizer */
-    p_streaminfo[4] |= 0x80; /* Fake this as the last metadata block */
     es_format_Init( &fmt, AUDIO_ES, VLC_CODEC_FLAC );
     fmt.i_extra = i_streaminfo;
     fmt.p_extra = p_streaminfo;
@@ -448,12 +447,11 @@ static int  ReadMeta( demux_t *p_demux, uint8_t **pp_streaminfo, int *pi_streami
     s->i_byte_offset = 0;
     TAB_APPEND( p_sys->i_seekpoint, p_sys->seekpoint, s );
 
-    static const uint8_t marker[4] = { 'f', 'L', 'a', 'C' };
     uint8_t header[4];
     if( stream_Read( p_demux->s, header, 4) < 4)
         return VLC_EGENERIC;
 
-    if (memcmp(header, marker, 4))
+    if (memcmp(header, "fLaC", 4))
         return VLC_EGENERIC;
 
     b_last = 0;
@@ -471,27 +469,25 @@ static int  ReadMeta( demux_t *p_demux, uint8_t **pp_streaminfo, int *pi_streami
 
         if( i_type == META_STREAMINFO && !*pp_streaminfo )
         {
-            if( i_len != (STREAMINFO_SIZE - 4) ) {
+            if( i_len != STREAMINFO_SIZE ) {
                 msg_Err( p_demux, "invalid size %d for a STREAMINFO metadata block", i_len );
                 return VLC_EGENERIC;
             }
-            i_peek = stream_Peek( p_demux->s, &p_peek, STREAMINFO_SIZE);
-            if( i_peek == STREAMINFO_SIZE)
 
-            *pi_streaminfo = STREAMINFO_SIZE + 4;
-            *pp_streaminfo = malloc( STREAMINFO_SIZE + 4 );
+            *pi_streaminfo = STREAMINFO_SIZE;
+            *pp_streaminfo = malloc( STREAMINFO_SIZE);
             if( *pp_streaminfo == NULL )
                 return VLC_EGENERIC;
 
-            if( stream_Read( p_demux->s, &(*pp_streaminfo)[4], STREAMINFO_SIZE ) != STREAMINFO_SIZE )
+            if( stream_Read( p_demux->s, NULL, 4) < 4)
+                return VLC_EGENERIC;
+            if( stream_Read( p_demux->s, *pp_streaminfo, STREAMINFO_SIZE ) != STREAMINFO_SIZE )
             {
                 msg_Err( p_demux, "failed to read STREAMINFO metadata block" );
                 free( *pp_streaminfo );
                 return VLC_EGENERIC;
             }
 
-            memcpy(*pp_streaminfo, marker, 4);
-
             /* */
             ParseStreamInfo( &i_sample_rate, &i_sample_count, *pp_streaminfo );
             if( i_sample_rate > 0 )
@@ -531,10 +527,8 @@ static int  ReadMeta( demux_t *p_demux, uint8_t **pp_streaminfo, int *pi_streami
 }
 static void ParseStreamInfo( int *pi_rate, int64_t *pi_count, uint8_t *p_data )
 {
-    const int i_skip = 4+4;
-
-    *pi_rate = GetDWBE(&p_data[i_skip+4+6]) >> 12;
-    *pi_count = GetQWBE(&p_data[i_skip+4+6]) &  ((INT64_C(1)<<36)-1);
+    *pi_rate = GetDWBE(&p_data[4+6]) >> 12;
+    *pi_count = GetQWBE(&p_data[4+6]) &  ((INT64_C(1)<<36)-1);
 }
 
 static void ParseSeekTable( demux_t *p_demux, const uint8_t *p_data, int i_data,
index f2f3c2f537eee74dbcba937bf73ceb1567f402d0..42019f3dd39d4b04b2441162bbcb5a64a77ed680 100644 (file)
@@ -1416,7 +1416,7 @@ int32_t matroska_segment_c::TrackInit( mkv_track_t * p_tk )
     else if( !strcmp( p_tk->psz_codec, "A_FLAC" ) )
     {
         p_tk->fmt.i_codec = VLC_CODEC_FLAC;
-        fill_extra_data( p_tk, 0 );
+        fill_extra_data( p_tk, 8 );
     }
     else if( !strcmp( p_tk->psz_codec, "A_VORBIS" ) )
     {
index b5750c3d1f536686101685945efadcc013901118..63f3d0dd878dba9377840943c6e7058d65ebcf63 100644 (file)
@@ -2068,30 +2068,28 @@ static void Ogg_ReadFlacHeader( demux_t *p_demux, logical_stream_t *p_stream,
     bs_init( &s, p_oggpacket->packet, p_oggpacket->bytes );
 
     bs_read( &s, 1 );
-    if( p_oggpacket->bytes > 0 && bs_read( &s, 7 ) == 0 )
+    if( p_oggpacket->bytes > 0 && bs_read( &s, 7 ) != 0 )
     {
-        if( bs_read( &s, 24 ) >= 34 /*size STREAMINFO*/ )
-        {
-            bs_skip( &s, 80 );
-            p_stream->f_rate = p_stream->fmt.audio.i_rate = bs_read( &s, 20 );
-            p_stream->fmt.audio.i_channels = bs_read( &s, 3 ) + 1;
+        msg_Dbg( p_demux, "Invalid FLAC STREAMINFO metadata" );
+        return;
+    }
 
-            msg_Dbg( p_demux, "FLAC header, channels: %i, rate: %i",
-                     p_stream->fmt.audio.i_channels, (int)p_stream->f_rate );
-        }
-        else
-        {
-            msg_Dbg( p_demux, "FLAC STREAMINFO metadata too short" );
-        }
+    if( bs_read( &s, 24 ) >= 34 /*size STREAMINFO*/ )
+    {
+        bs_skip( &s, 80 );
+        p_stream->f_rate = p_stream->fmt.audio.i_rate = bs_read( &s, 20 );
+        p_stream->fmt.audio.i_channels = bs_read( &s, 3 ) + 1;
 
-        /* Fake this as the last metadata block */
-        *((uint8_t*)p_oggpacket->packet) |= 0x80;
+        msg_Dbg( p_demux, "FLAC header, channels: %i, rate: %i",
+                 p_stream->fmt.audio.i_channels, (int)p_stream->f_rate );
     }
     else
     {
-        /* This ain't a STREAMINFO metadata */
-        msg_Dbg( p_demux, "Invalid FLAC STREAMINFO metadata" );
+        msg_Dbg( p_demux, "FLAC STREAMINFO metadata too short" );
     }
+
+    /* Fake this as the last metadata block */
+    *((uint8_t*)p_oggpacket->packet) |= 0x80;
 }
 
 static void Ogg_ReadKateHeader( logical_stream_t *p_stream,
index 85758a28bb1ded08bc403d553bcea8f5106b2287..8d5325b6d5818f51eb143717257dc3632f717ebd 100644 (file)
@@ -779,11 +779,24 @@ static block_t *OggCreateHeader( sout_mux_t *p_mux )
             msg_Dbg( p_mux, "writing extra data" );
             op.bytes  = p_input->p_fmt->i_extra;
             op.packet = p_input->p_fmt->p_extra;
+            uint8_t flac_streaminfo[34 + 4];
             if( p_stream->i_fourcc == VLC_CODEC_FLAC )
             {
-                /* Skip the flac stream marker */
-                op.bytes -= 4;
-                op.packet+= 4;
+                if (op.bytes == 42 && !memcmp(op.packet, "fLaC", 4)) {
+                    op.bytes -= 4;
+                    memcpy(flac_streaminfo, op.packet + 4, 38);
+                    op.packet = flac_streaminfo;
+                } else if (op.bytes == 34) {
+                    op.bytes += 4;
+                    memcpy(flac_streaminfo + 4, op.packet, 34);
+                    flac_streaminfo[0] = 0x80; /* last block, streaminfo */
+                    flac_streaminfo[1] = 0;
+                    flac_streaminfo[2] = 0;
+                    flac_streaminfo[3] = 34; /* block size */
+                    op.packet = flac_streaminfo;
+                } else {
+                    msg_Err(p_mux, "Invalid FLAC streaminfo (%d bytes)", op.bytes);
+                }
             }
             op.b_o_s  = 0;
             op.e_o_s  = 0;
index 19de0bfc364dac78c9280d3ba36e8f6d3d1e8523..090b60160eae10a9b4e68618f5e2d7aafb459b26 100644 (file)
@@ -170,11 +170,18 @@ static void ProcessHeader( decoder_t *p_dec )
     decoder_sys_t *p_sys = p_dec->p_sys;
 
     bs_t bs;
+    int i_extra = p_dec->fmt_in.i_extra;
+    char *p_extra = p_dec->fmt_in.p_extra;
 
-    if( p_dec->fmt_in.i_extra < 8 + 14 )
+    if (i_extra > 8 && !memcmp(p_extra, "fLaC", 4)) {
+        i_extra -= 8;
+        p_extra += 8;
+    }
+
+    if( p_dec->fmt_in.i_extra < 14 )
         return;
 
-    bs_init( &bs, (uint8_t*)p_dec->fmt_in.p_extra + 8, p_dec->fmt_in.i_extra - 8 );
+    bs_init( &bs, p_extra, i_extra);
 
     p_sys->stream_info.min_blocksize = bs_read( &bs, 16 );
     p_sys->stream_info.max_blocksize = bs_read( &bs, 16 );
@@ -188,11 +195,9 @@ static void ProcessHeader( decoder_t *p_dec )
 
     p_sys->b_stream_info = true;
 
-    p_dec->fmt_out.i_extra = p_dec->fmt_in.i_extra;
-    p_dec->fmt_out.p_extra = xrealloc( 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 );
+    p_dec->fmt_out.i_extra = i_extra;
+    p_dec->fmt_out.p_extra = xrealloc( p_dec->fmt_out.p_extra, i_extra );
+    memcpy( p_dec->fmt_out.p_extra, p_extra, i_extra );
 }
 
 /* */