diff --git a/modules/access/live555.cpp b/modules/access/live555.cpp index b219147b09..e90382eeb3 100644 --- a/modules/access/live555.cpp +++ b/modules/access/live555.cpp @@ -1043,11 +1043,13 @@ static int SessionsSetup( demux_t *p_demux ) unsigned char *p_extra; tk->fmt.i_codec = VLC_CODEC_OPUS; OpusHeader header; + opus_header_init(&header); // "The RTP clock rate in "a=rtpmap" MUST be 48000 and the number of channels MUST be 2." // See: https://datatracker.ietf.org/doc/html/draft-ietf-payload-rtp-opus-11#section-7 opus_prepare_header( 2, 48000, &header ); if( opus_write_header( &p_extra, &i_extra, &header, NULL ) ) return VLC_ENOMEM; + opus_header_clean(&header); tk->fmt.i_extra = i_extra; tk->fmt.p_extra = p_extra; } diff --git a/modules/codec/opus.c b/modules/codec/opus.c index a1557cf443..5ae8c7fe5b 100644 --- a/modules/codec/opus.c +++ b/modules/codec/opus.c @@ -178,6 +178,7 @@ static int OpenDecoder( vlc_object_t *p_this ) if( ( p_dec->p_sys = p_sys = malloc(sizeof(decoder_sys_t)) ) == NULL ) return VLC_ENOMEM; p_dec->p_sys->b_has_headers = false; + opus_header_init(&p_sys->header); date_Set( &p_sys->end_date, 0 ); @@ -252,6 +253,7 @@ static block_t *Packetize( decoder_t *p_dec, block_t **pp_block ) *****************************************************************************/ static int ProcessHeaders( decoder_t *p_dec ) { + decoder_sys_t *p_sys = p_dec->p_sys; ogg_packet oggpacket; unsigned pi_size[XIPH_MAX_HEADER_COUNT]; @@ -267,10 +269,13 @@ static int ProcessHeaders( decoder_t *p_dec ) (i_extra > 10 && memcmp( &p_extra[2], "OpusHead", 8 )) ) /* Borked muxers */ { OpusHeader header; + opus_header_init(&header); opus_prepare_header( p_dec->fmt_in.audio.i_channels, p_dec->fmt_in.audio.i_rate, &header ); - if( opus_write_header( &p_alloc, &i_extra, &header, - opus_get_version_string() ) ) + int ret = opus_write_header( &p_alloc, &i_extra, &header, + opus_get_version_string() ); + opus_header_clean(&header); + if(ret != 0) { free( p_alloc ); return VLC_ENOMEM; @@ -296,7 +301,11 @@ static int ProcessHeaders( decoder_t *p_dec ) int ret = ProcessInitialHeader( p_dec, &oggpacket ); if (ret != VLC_SUCCESS) + { msg_Err( p_dec, "initial Opus header is corrupted" ); + opus_header_clean( &p_sys->header ); + opus_header_init( &p_sys->header ); + } free( p_alloc ); @@ -512,6 +521,7 @@ static void CloseDecoder( vlc_object_t *p_this ) if( p_sys->p_st ) opus_multistream_decoder_destroy(p_sys->p_st); + opus_header_clean( &p_sys->header ); free( p_sys ); } @@ -650,6 +660,7 @@ static int OpenEncoder(vlc_object_t *p_this) enc->fmt_out.audio.i_channels = enc->fmt_in.audio.i_channels; OpusHeader header; + opus_header_init(&header); opus_prepare_header(enc->fmt_out.audio.i_channels, enc->fmt_out.audio.i_rate, &header); @@ -724,9 +735,12 @@ static int OpenEncoder(vlc_object_t *p_this) sys->padding = NULL; } + opus_header_clean(&header); + return status; error: + opus_header_clean(&header); if (sys->enc) opus_multistream_encoder_destroy(sys->enc); free(sys->buffer); diff --git a/modules/codec/opus_header.c b/modules/codec/opus_header.c index a19d9c73f7..4d9d1bb50b 100644 --- a/modules/codec/opus_header.c +++ b/modules/codec/opus_header.c @@ -421,3 +421,19 @@ int opus_write_header(uint8_t **p_extra, int *i_extra, OpusHeader *header, const return 0; } +void opus_header_init(OpusHeader *h) +{ + h->version = 0; + h->channels = 0; + h->preskip = 3840; /* default is 80 ms */ + h->input_sample_rate = 0; /* unknown */ + h->gain = 0; + h->channel_mapping = 255; /* unknown */ + h->nb_streams = 0; + h->nb_coupled = 0; +} + +void opus_header_clean(OpusHeader *h) +{ + VLC_UNUSED(h); +} diff --git a/modules/codec/opus_header.h b/modules/codec/opus_header.h index 4b6a4e5d3c..13029ae27b 100644 --- a/modules/codec/opus_header.h +++ b/modules/codec/opus_header.h @@ -43,6 +43,8 @@ typedef struct { unsigned char stream_map[255]; } OpusHeader; +void opus_header_init(OpusHeader *); +void opus_header_clean(OpusHeader *); int opus_header_parse(const unsigned char *header, int len, OpusHeader *h); void opus_prepare_header(unsigned channels, unsigned rate, OpusHeader *header); int opus_write_header(uint8_t **p_extra, int *i_extra, OpusHeader *header, const char *vendor); diff --git a/modules/demux/mpeg/ts_psi.c b/modules/demux/mpeg/ts_psi.c index 46bfd679d9..67ad7fd66b 100644 --- a/modules/demux/mpeg/ts_psi.c +++ b/modules/demux/mpeg/ts_psi.c @@ -850,6 +850,7 @@ static int vlc_ceil_log2( const unsigned int val ) static void OpusSetup(demux_t *demux, uint8_t *p, size_t len, es_format_t *p_fmt) { OpusHeader h; + opus_header_init(&h); /* default mapping */ static const unsigned char map[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; @@ -930,6 +931,7 @@ static void OpusSetup(demux_t *demux, uint8_t *p, size_t len, es_format_t *p_fmt if (!channels) { msg_Err(demux, "Opus channel configuration 0x%.2x not supported yet", p[1]); + opus_header_clean(&h); return; } @@ -952,10 +954,12 @@ static void OpusSetup(demux_t *demux, uint8_t *p, size_t len, es_format_t *p_fmt p_fmt->audio.i_rate = 48000; } } + opus_header_clean(&h); return; explicit_config_too_short: + opus_header_clean(&h); msg_Err(demux, "Opus descriptor too short"); }