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 */
if( i_size < 36 )
i_size = 0;
}
- else
- {
- i_offset = 0;
- i_size = p_dec->fmt_in.i_extra;
- }
if( i_size > 0 )
{
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;
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 */
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 );
mtime_t i_pts;
};
-#define STREAMINFO_SIZE 38
+#define STREAMINFO_SIZE 34
static block_t *Encode( encoder_t *, block_t * );
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;
#include "../../codec/avcodec/avcommon.h"
-//#define AVFORMAT_DEBUG 1
+#define AVFORMAT_DEBUG 1
static const char *const ppsz_mux_options[] = {
"mux", "options", NULL
int i_cover_score;
};
-#define STREAMINFO_SIZE 38
+#define STREAMINFO_SIZE 34
#define FLAC_PACKET_SIZE 16384
/*****************************************************************************
/* 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;
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;
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 )
}
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,
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" ) )
{
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,
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;
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 );
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 );
}
/* */