From: Rafaël Carré Date: Sun, 23 Jun 2013 21:15:55 +0000 (+0200) Subject: Simplify FLAC extradata (streaminfo) parsing X-Git-Tag: 2.1.0-git~29 X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=9925a34ee91b6debfc2f9f137fe9c77e7e0d6241;p=vlc Simplify FLAC extradata (streaminfo) parsing Prefer the shorter version (avcodec/avformat support both) --- diff --git a/modules/codec/avcodec/audio.c b/modules/codec/avcodec/audio.c index 2dd3a7bb12..b2f70ffe93 100644 --- a/modules/codec/avcodec/audio.c +++ b/modules/codec/avcodec/audio.c @@ -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 ) { diff --git a/modules/codec/avcodec/encoder.c b/modules/codec/avcodec/encoder.c index cbbe13a3a2..9717d099b8 100644 --- a/modules/codec/avcodec/encoder.c +++ b/modules/codec/avcodec/encoder.c @@ -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; diff --git a/modules/codec/flac.c b/modules/codec/flac.c index 215de76d5f..5568fcf155 100644 --- a/modules/codec/flac.c +++ b/modules/codec/flac.c @@ -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; diff --git a/modules/demux/avformat/mux.c b/modules/demux/avformat/mux.c index 58109f939b..5e2225fcff 100644 --- a/modules/demux/avformat/mux.c +++ b/modules/demux/avformat/mux.c @@ -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 diff --git a/modules/demux/flac.c b/modules/demux/flac.c index e6835e446e..28d58090fe 100644 --- a/modules/demux/flac.c +++ b/modules/demux/flac.c @@ -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, diff --git a/modules/demux/mkv/matroska_segment_parse.cpp b/modules/demux/mkv/matroska_segment_parse.cpp index f2f3c2f537..42019f3dd3 100644 --- a/modules/demux/mkv/matroska_segment_parse.cpp +++ b/modules/demux/mkv/matroska_segment_parse.cpp @@ -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" ) ) { diff --git a/modules/demux/ogg.c b/modules/demux/ogg.c index b5750c3d1f..63f3d0dd87 100644 --- a/modules/demux/ogg.c +++ b/modules/demux/ogg.c @@ -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, diff --git a/modules/mux/ogg.c b/modules/mux/ogg.c index 85758a28bb..8d5325b6d5 100644 --- a/modules/mux/ogg.c +++ b/modules/mux/ogg.c @@ -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; diff --git a/modules/packetizer/flac.c b/modules/packetizer/flac.c index 19de0bfc36..090b60160e 100644 --- a/modules/packetizer/flac.c +++ b/modules/packetizer/flac.c @@ -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 ); } /* */