From 812c8af9bfb91e65a7c85a4281cc9aa0d047d9a7 Mon Sep 17 00:00:00 2001 From: Torsten Jager Date: Sat, 13 Aug 2011 18:00:54 +0200 Subject: ffmpeg audio crash fix (sse2 alignment) Certain ffmpeg audio decoders use 32 bit float samples internally (wma, eac3, ...). They are then exported to the calling application as 16 bit integer. That conversion is done by faster sse2 code if your processor supports it. However, sse2 instructions require data buffers to be 16 byte aligned, or hit a segfault otherwise. Plain malloc() / realloc() ensures only 8 byte alignment, giving a 50% chance of a crash. FFmpeg internally uses aligned buffers a lot. It seems to be a good idea to do likewise for input buffers as well, even if current version does not strictly need it yet. Libavutil/av_realloc() has a bug that can break the alignment when enlarging an existing buffer. Thus I included a fixed version of it within ff_audio_decoder.c. --- src/combined/ffmpeg/ff_audio_decoder.c | 36 ++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) (limited to 'src/combined') diff --git a/src/combined/ffmpeg/ff_audio_decoder.c b/src/combined/ffmpeg/ff_audio_decoder.c index 60544ad0c..14a908d2f 100644 --- a/src/combined/ffmpeg/ff_audio_decoder.c +++ b/src/combined/ffmpeg/ff_audio_decoder.c @@ -81,13 +81,41 @@ typedef struct ff_audio_decoder_s { #include "ff_audio_list.h" +#define malloc16(s) realloc16(NULL,s) +#define free16(p) realloc16(p,0) + +static void *realloc16 (void *m, size_t s) { + unsigned int diff, diff2; + unsigned char *p = m, *q; + if (p) { + diff = p[-1]; + if (s == 0) { + free (p - diff); + return (NULL); + } + q = realloc (p - diff, s + 16); + if (!q) return (q); + diff2 = 16 - ((unsigned int)q & 15); + if (diff2 != diff) memmove (q + diff2, q + diff, s); + } else { + if (s == 0) return (NULL); + q = malloc (s + 16); + if (!q) return (q); + diff2 = 16 - ((unsigned int)q & 15); + } + q += diff2; + q[-1] = diff2; + return (q); +} + + static void ff_audio_ensure_buffer_size(ff_audio_decoder_t *this, int size) { if (size > this->bufsize) { this->bufsize = size + size / 2; xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("ffmpeg_audio_dec: increasing buffer to %d to avoid overflow.\n"), this->bufsize); - this->buf = realloc( this->buf, this->bufsize ); + this->buf = realloc16 (this->buf, this->bufsize); } } @@ -247,7 +275,7 @@ static void ff_audio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) this->size = 0; - this->decode_buffer = calloc(1, AVCODEC_MAX_AUDIO_FRAME_SIZE); + this->decode_buffer = malloc16 (AVCODEC_MAX_AUDIO_FRAME_SIZE); return; } @@ -455,8 +483,8 @@ static void ff_audio_dispose (audio_decoder_t *this_gen) { this->stream->audio_out->close (this->stream->audio_out, this->stream); this->output_open = 0; - free(this->buf); - free(this->decode_buffer); + free16 (this->buf); + free16 (this->decode_buffer); if(this->context && this->context->extradata) free(this->context->extradata); -- cgit v1.2.3 From 41500b69fd2f67541904bb7b146d5ba3ee472d21 Mon Sep 17 00:00:00 2001 From: Torsten Jager Date: Sat, 13 Aug 2011 18:02:30 +0200 Subject: VP8 support --- src/combined/ffmpeg/xine_video.list | 1 + 1 file changed, 1 insertion(+) (limited to 'src/combined') diff --git a/src/combined/ffmpeg/xine_video.list b/src/combined/ffmpeg/xine_video.list index a3c961d13..546cfff7c 100644 --- a/src/combined/ffmpeg/xine_video.list +++ b/src/combined/ffmpeg/xine_video.list @@ -34,6 +34,7 @@ VP31 VP3 On2 VP3.1 VP5 VP5 On2 VP5 VP6 VP6 On2 VP6 VP6F VP6F On2 VP6 +VP8 VP8 On2 VP8 4XM 4XM 4X Video CINEPAK CINEPAK Cinepak MSVC MSVIDEO1 Microsoft Video 1 -- cgit v1.2.3 From e96bac07aae3a9677661fd581b7c7e4e98964831 Mon Sep 17 00:00:00 2001 From: Torsten Jager Date: Sat, 13 Aug 2011 18:02:30 +0200 Subject: rv30 & rv40 support --- src/combined/ffmpeg/ff_video_decoder.c | 6 ++++++ src/combined/ffmpeg/xine_video.list | 2 ++ 2 files changed, 8 insertions(+) (limited to 'src/combined') diff --git a/src/combined/ffmpeg/ff_video_decoder.c b/src/combined/ffmpeg/ff_video_decoder.c index ad0ee6022..a9c383c48 100644 --- a/src/combined/ffmpeg/ff_video_decoder.c +++ b/src/combined/ffmpeg/ff_video_decoder.c @@ -329,6 +329,10 @@ static void init_video_codec (ff_video_decoder_t *this, unsigned int codec_type) this->context->flags |= CODEC_FLAG_EMU_EDGE; } + /* TJ. without this, it wont work at all on my machine */ + this->context->codec_id = this->codec->id; + this->context->codec_type = this->codec->type; + if (this->class->choose_speed_over_accuracy) this->context->flags2 |= CODEC_FLAG2_FAST; @@ -910,6 +914,8 @@ static void ff_handle_header_buffer (ff_video_decoder_t *this, buf_element_t *bu switch (codec_type) { case BUF_VIDEO_RV10: case BUF_VIDEO_RV20: + case BUF_VIDEO_RV30: + case BUF_VIDEO_RV40: this->bih.biWidth = _X_BE_16(&this->buf[12]); this->bih.biHeight = _X_BE_16(&this->buf[14]); diff --git a/src/combined/ffmpeg/xine_video.list b/src/combined/ffmpeg/xine_video.list index 546cfff7c..bd1238d6f 100644 --- a/src/combined/ffmpeg/xine_video.list +++ b/src/combined/ffmpeg/xine_video.list @@ -24,6 +24,8 @@ I263 H263I ITU H.263 H263 H263 H.263 RV10 RV10 Real Video 1.0 RV20 RV20 Real Video 2.0 +RV30 RV30 Real Video 3.0 +RV40 RV40 Real Video 4.0 IV31 INDEO3 Indeo Video 3.1 IV32 INDEO3 Indeo Video 3.2 SORENSON_V1 SVQ1 Sorenson Video 1 -- cgit v1.2.3