Package: vlc
Version: 2.1.4-1
Severity: important
Tags: patch
Dear Maintainer,
in modules/codec/avcodec/audio.c one finds:
AVFrame frame;
memset( &frame, 0, sizeof( frame ) );
According to the documentation of libavutil this is wrong:
"sizeof(AVFrame) is not a part of the public ABI, so new fields may be
added to the end with a minor bump."
This code will crash, when used with a different AVFrame at runtime than
was available at compile-time.
The attached patch fixes this problem.
Best regards,
Andreas
Description: Fix the use of AVFrame
AVFrame is not guaranteed to be ABI stable, i.e. new fields can be
added at any time.
Therefore it must be allocated with av_frame_alloc to avoid crashes.
Author: Andreas Cadhalpun <andreas.cadhal...@googlemail.com>
Last-Update: <2014-07-28>
--- vlc-2.1.4.orig/modules/codec/avcodec/audio.c
+++ vlc-2.1.4/modules/codec/avcodec/audio.c
@@ -225,6 +225,7 @@ block_t * DecodeAudio ( decoder_t *p_dec
{
decoder_sys_t *p_sys = p_dec->p_sys;
AVCodecContext *ctx = p_sys->p_context;
+ AVFrame *frame = NULL;
if( !pp_block || !*pp_block )
return NULL;
@@ -271,8 +272,7 @@ block_t * DecodeAudio ( decoder_t *p_dec
p_block->i_flags |= BLOCK_FLAG_PRIVATE_REALLOCATED;
}
- AVFrame frame;
- memset( &frame, 0, sizeof( frame ) );
+ frame = av_frame_alloc();
for( int got_frame = 0; !got_frame; )
{
@@ -284,7 +284,7 @@ block_t * DecodeAudio ( decoder_t *p_dec
pkt.data = p_block->p_buffer;
pkt.size = p_block->i_buffer;
- int used = avcodec_decode_audio4( ctx, &frame, &got_frame, &pkt );
+ int used = avcodec_decode_audio4( ctx, frame, &got_frame, &pkt );
if( used < 0 )
{
msg_Warn( p_dec, "cannot decode one frame (%zu bytes)",
@@ -320,7 +320,7 @@ block_t * DecodeAudio ( decoder_t *p_dec
}
/* NOTE WELL: Beyond this point, p_block now refers to the DECODED block */
- p_block = frame.opaque;
+ p_block = frame->opaque;
SetupOutputFormat( p_dec, true );
/* Silent unwanted samples */
@@ -336,10 +336,10 @@ block_t * DecodeAudio ( decoder_t *p_dec
block_Release( p_block );
if( av_sample_fmt_is_planar( ctx->sample_fmt )
&& ctx->channels > AV_NUM_DATA_POINTERS )
- free( frame.extended_data );
+ free( frame->extended_data );
return NULL;
}
- assert( p_block->i_nb_samples >= (unsigned)frame.nb_samples );
+ assert( p_block->i_nb_samples >= (unsigned)frame->nb_samples );
assert( p_block->i_nb_samples == p_buffer->i_nb_samples );
p_block->i_buffer = p_buffer->i_buffer; /* drop buffer padding */
@@ -348,13 +348,13 @@ block_t * DecodeAudio ( decoder_t *p_dec
{
const void *planes[ctx->channels];
for( int i = 0; i < ctx->channels; i++)
- planes[i] = frame.extended_data[i];
+ planes[i] = frame->extended_data[i];
- aout_Interleave( p_buffer->p_buffer, planes, frame.nb_samples,
+ aout_Interleave( p_buffer->p_buffer, planes, frame->nb_samples,
ctx->channels, p_dec->fmt_out.audio.i_format );
if( ctx->channels > AV_NUM_DATA_POINTERS )
- free( frame.extended_data );
+ free( frame->extended_data );
block_Release( p_block );
p_block = p_buffer;
}
@@ -364,7 +364,7 @@ block_t * DecodeAudio ( decoder_t *p_dec
if (p_sys->b_extract)
{ /* TODO: do not drop channels... at least not here */
p_buffer = block_Alloc( p_dec->fmt_out.audio.i_bytes_per_frame
- * frame.nb_samples );
+ * frame->nb_samples );
if( unlikely(p_buffer == NULL) )
{
block_Release( p_block );
@@ -373,21 +373,23 @@ block_t * DecodeAudio ( decoder_t *p_dec
aout_ChannelExtract( p_buffer->p_buffer,
p_dec->fmt_out.audio.i_channels,
p_block->p_buffer, ctx->channels,
- frame.nb_samples, p_sys->pi_extraction,
+ frame->nb_samples, p_sys->pi_extraction,
p_dec->fmt_out.audio.i_bitspersample );
block_Release( p_block );
p_block = p_buffer;
}
- p_block->i_nb_samples = frame.nb_samples;
- p_block->i_buffer = frame.nb_samples
+ p_block->i_nb_samples = frame->nb_samples;
+ p_block->i_buffer = frame->nb_samples
* p_dec->fmt_out.audio.i_bytes_per_frame;
p_block->i_pts = date_Get( &p_sys->end_date );
- p_block->i_length = date_Increment( &p_sys->end_date, frame.nb_samples )
+ p_block->i_length = date_Increment( &p_sys->end_date, frame->nb_samples )
- p_block->i_pts;
return p_block;
end:
+ if ( frame != NULL )
+ av_frame_free(&frame);
block_Release(p_block);
*pp_block = NULL;
return NULL;